diff options
| -rw-r--r-- | ydb/core/grpc_services/audit_dml_operations.cpp | 15 | ||||
| -rw-r--r-- | ydb/core/grpc_services/base/base.h | 20 | ||||
| -rw-r--r-- | ydb/core/grpc_services/grpc_request_check_actor.h | 2 | ||||
| -rw-r--r-- | ydb/services/ydb/ydb_table.cpp | 20 |
4 files changed, 23 insertions, 34 deletions
diff --git a/ydb/core/grpc_services/audit_dml_operations.cpp b/ydb/core/grpc_services/audit_dml_operations.cpp index d301a38da51..1365430d177 100644 --- a/ydb/core/grpc_services/audit_dml_operations.cpp +++ b/ydb/core/grpc_services/audit_dml_operations.cpp @@ -5,15 +5,6 @@ #include "audit_dml_operations.h" namespace { - static const std::vector<TString> AuditableRequests{ - "Ydb.Table.ExecuteDataQueryRequest", - "Ydb.Table.PrepareDataQueryRequest", - "Ydb.Table.BeginTransactionRequest", - "Ydb.Table.CommitTransactionRequest", - "Ydb.Table.RollbackTransactionRequest", - "Ydb.Table.BulkUpsertRequest", - }; - // Query text could be very large, multilined and formatted with indentations. // It should be prepared and somewhat limited before getting dumped into the logs. const size_t MAX_QUERY_TEXT_LEN = 1024; @@ -31,12 +22,6 @@ namespace { namespace NKikimr::NGRpcService { -// Runtime filtration of requests by their type -bool IsAuditableRequest(const ::google::protobuf::Message& req) { - auto found = std::find(AuditableRequests.begin(), AuditableRequests.end(), req.GetDescriptor()->full_name()); - return (found != AuditableRequests.end()); -} - void AuditContextStart(IRequestCtxBase* ctx, const TString& database, const TString& userSID) { ctx->AddAuditLogPart("remote_address", ctx->GetPeerName()); ctx->AddAuditLogPart("subject", userSID); diff --git a/ydb/core/grpc_services/base/base.h b/ydb/core/grpc_services/base/base.h index bd90fddb08f..ec4929b6561 100644 --- a/ydb/core/grpc_services/base/base.h +++ b/ydb/core/grpc_services/base/base.h @@ -239,9 +239,6 @@ struct TRpcServices { template <class T> void FillYdbStatus(T& resp, const NYql::TIssues& issues, Ydb::StatusIds::StatusCode status); -// Returns true if given request type is subject to audit -bool IsAuditableRequest(const ::google::protobuf::Message& req); - class TProtoResponseHelper { public: template <typename T, typename C> @@ -329,6 +326,11 @@ enum class TRateLimiterMode : ui8 { #define RLSWITCH(mode) \ IsRlAllowed() ? mode : TRateLimiterMode::Off +enum class TAuditMode : bool { + Off = false, + Auditable = true, +}; + class ICheckerIface; // The way to pass some common data to request processing @@ -342,6 +344,7 @@ public: struct TRequestAuxSettings { TRateLimiterMode RlMode = TRateLimiterMode::Off; void (*CustomAttributeProcessor)(const TSchemeBoardEvents::TDescribeSchemeResult& schemeData, ICheckerIface*) = nullptr; + TAuditMode AuditMode = TAuditMode::Off; }; // grpc_request_proxy part @@ -1002,7 +1005,6 @@ public: TGRpcRequestWrapperImpl(NGrpc::IRequestContextBase* ctx) : Ctx_(ctx) - , IsAuditableType(!this->IsInternalCall() && IsAuditableRequest(*GetRequest())) { } const TMaybe<TString> GetYdbToken() const override { @@ -1243,9 +1245,6 @@ public: Y_FAIL("unimplemented"); } - bool IsAuditable() const override { - return IsAuditableType; - } void SetAuditLogHook(TAuditLogHook&& hook) override { AuditLogHook = std::move(hook); } @@ -1307,7 +1306,6 @@ private: IGRpcProxyCounters::TPtr Counters; std::function<TFinishWrapper(std::function<void()>&&)> FinishWrapper = &GetStdFinishWrapper; - const bool IsAuditableType; TAuditLogParts AuditLogParts; TAuditLogHook AuditLogHook; bool RequestFinished = false; @@ -1390,6 +1388,12 @@ public: } } + // IRequestCtxBaseMtSafe + // + bool IsAuditable() const override { + return (AuxSettings.AuditMode == TAuditMode::Auditable) && !this->IsInternalCall(); + } + private: std::function<void(std::unique_ptr<TRequestIface>, const IFacilityProvider&)> PassMethod; const TRequestAuxSettings AuxSettings; diff --git a/ydb/core/grpc_services/grpc_request_check_actor.h b/ydb/core/grpc_services/grpc_request_check_actor.h index 9ede1a768de..558627f4e12 100644 --- a/ydb/core/grpc_services/grpc_request_check_actor.h +++ b/ydb/core/grpc_services/grpc_request_check_actor.h @@ -359,7 +359,7 @@ private: void AuditRequest(IRequestProxyCtx* requestBaseCtx, const TString& databaseName, const TString& userSID) const { const bool dmlAuditEnabled = requestBaseCtx->IsAuditable() && IsAuditEnabledFor(userSID); - + if (dmlAuditEnabled) { AuditContextStart(requestBaseCtx, databaseName, userSID); requestBaseCtx->SetAuditLogHook([requestBaseCtx](ui32 status, const TAuditLogParts& parts) { diff --git a/ydb/services/ydb/ydb_table.cpp b/ydb/services/ydb/ydb_table.cpp index 2a24c431461..400405520dd 100644 --- a/ydb/services/ydb/ydb_table.cpp +++ b/ydb/services/ydb/ydb_table.cpp @@ -40,16 +40,16 @@ void TGRpcYdbTableService::SetupIncomingRequests(NGrpc::TLoggerPtr logger) { #error ADD_STREAM_REQUEST_LIMIT macro already defined #endif -#define ADD_REQUEST_LIMIT(NAME, CB, LIMIT_TYPE) \ +#define ADD_REQUEST_LIMIT(NAME, CB, LIMIT_TYPE, ...) \ for (size_t i = 0; i < HandlersPerCompletionQueue; ++i) { \ for (auto* cq: CQS) { \ MakeIntrusive<TGRpcRequest<Ydb::Table::NAME##Request, Ydb::Table::NAME##Response, TGRpcYdbTableService>> \ (this, &Service_, cq, \ [this, proxyCounter](NGrpc::IRequestContextBase *ctx) { \ NGRpcService::ReportGrpcReqToMon(*ActorSystem_, ctx->GetPeer()); \ - ActorSystem_->Send(GRpcProxies_[proxyCounter % GRpcProxies_.size()], \ + ActorSystem_->Send(GRpcProxies_[proxyCounter % GRpcProxies_.size()], \ new TGrpcRequestOperationCall<Ydb::Table::NAME##Request, Ydb::Table::NAME##Response> \ - (ctx, &CB, TRequestAuxSettings{RLSWITCH(TRateLimiterMode::LIMIT_TYPE), nullptr})); \ + (ctx, &CB, TRequestAuxSettings{RLSWITCH(TRateLimiterMode::LIMIT_TYPE), nullptr __VA_OPT__(, TAuditMode::__VA_ARGS__)})); \ }, &Ydb::Table::V1::TableService::AsyncService::Request ## NAME, \ #NAME, logger, getCounterBlock("table", #NAME))->Run(); \ ++proxyCounter; \ @@ -63,7 +63,7 @@ void TGRpcYdbTableService::SetupIncomingRequests(NGrpc::TLoggerPtr logger) { (this, &Service_, cq, \ [this, proxyCounter](NGrpc::IRequestContextBase *ctx) { \ NGRpcService::ReportGrpcReqToMon(*ActorSystem_, ctx->GetPeer()); \ - ActorSystem_->Send(GRpcProxies_[proxyCounter % GRpcProxies_.size()], \ + ActorSystem_->Send(GRpcProxies_[proxyCounter % GRpcProxies_.size()], \ new TGrpcRequestNoOperationCall<Ydb::Table::IN, Ydb::Table::OUT> \ (ctx, &CB, TRequestAuxSettings{RLSWITCH(TRateLimiterMode::LIMIT_TYPE), nullptr})); \ }, &Ydb::Table::V1::TableService::AsyncService::Request ## NAME, \ @@ -83,16 +83,16 @@ void TGRpcYdbTableService::SetupIncomingRequests(NGrpc::TLoggerPtr logger) { ADD_REQUEST_LIMIT(RenameTables, DoRenameTablesRequest, Rps) ADD_REQUEST_LIMIT(ExplainDataQuery, DoExplainDataQueryRequest, Rps) ADD_REQUEST_LIMIT(ExecuteSchemeQuery, DoExecuteSchemeQueryRequest, Rps) - ADD_REQUEST_LIMIT(BeginTransaction, DoBeginTransactionRequest, Rps) + ADD_REQUEST_LIMIT(BeginTransaction, DoBeginTransactionRequest, Rps, Auditable) ADD_REQUEST_LIMIT(DescribeTableOptions, DoDescribeTableOptionsRequest, Rps) ADD_REQUEST_LIMIT(DeleteSession, DoDeleteSessionRequest, Off) - ADD_REQUEST_LIMIT(CommitTransaction, DoCommitTransactionRequest, Off) - ADD_REQUEST_LIMIT(RollbackTransaction, DoRollbackTransactionRequest, Off) + ADD_REQUEST_LIMIT(CommitTransaction, DoCommitTransactionRequest, Off, Auditable) + ADD_REQUEST_LIMIT(RollbackTransaction, DoRollbackTransactionRequest, Off, Auditable) - ADD_REQUEST_LIMIT(PrepareDataQuery, DoPrepareDataQueryRequest, Ru) - ADD_REQUEST_LIMIT(ExecuteDataQuery, DoExecuteDataQueryRequest, Ru) - ADD_REQUEST_LIMIT(BulkUpsert, DoBulkUpsertRequest, Ru) + ADD_REQUEST_LIMIT(PrepareDataQuery, DoPrepareDataQueryRequest, Ru, Auditable) + ADD_REQUEST_LIMIT(ExecuteDataQuery, DoExecuteDataQueryRequest, Ru, Auditable) + ADD_REQUEST_LIMIT(BulkUpsert, DoBulkUpsertRequest, Ru, Auditable) ADD_STREAM_REQUEST_LIMIT(StreamExecuteScanQuery, ExecuteScanQueryRequest, ExecuteScanQueryPartialResponse, DoExecuteScanQueryRequest, RuOnProgress) ADD_STREAM_REQUEST_LIMIT(StreamReadTable, ReadTableRequest, ReadTableResponse, DoReadTableRequest, RuOnProgress) |
