diff options
author | andrew-rykov <[email protected]> | 2023-03-22 13:31:13 +0300 |
---|---|---|
committer | andrew-rykov <[email protected]> | 2023-03-22 13:31:13 +0300 |
commit | 558102e9d11075acd943599473439d7961a8830d (patch) | |
tree | 6a0f86acc7f8540a105911372aa8ec1db801bf5c | |
parent | 874c62c0c6c0e6a3ec5f252bb1d58c4ee80dd3e3 (diff) |
create-user-audit-log
remove usings
create-user-audit-log
-rw-r--r-- | ydb/core/tx/schemeshard/CMakeLists.darwin-x86_64.txt | 1 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/CMakeLists.linux-aarch64.txt | 1 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/CMakeLists.linux-x86_64.txt | 1 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/CMakeLists.windows-x86_64.txt | 1 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/schemeshard__operation.cpp | 108 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/schemeshard_audit_log.cpp | 121 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/schemeshard_audit_log.h | 16 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/schemeshard_audit_log_fragment.cpp | 71 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/schemeshard_audit_log_fragment.h | 3 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/ya.make | 1 |
10 files changed, 214 insertions, 110 deletions
diff --git a/ydb/core/tx/schemeshard/CMakeLists.darwin-x86_64.txt b/ydb/core/tx/schemeshard/CMakeLists.darwin-x86_64.txt index 7cdb345fb8a..390da8bdb1c 100644 --- a/ydb/core/tx/schemeshard/CMakeLists.darwin-x86_64.txt +++ b/ydb/core/tx/schemeshard/CMakeLists.darwin-x86_64.txt @@ -225,6 +225,7 @@ target_sources(core-tx-schemeshard PRIVATE ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard__upgrade_access_database.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard__make_access_database_no_inheritable.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_audit_log_fragment.cpp + ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_audit_log.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_impl.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_billing_helpers.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_cdc_stream_scan.cpp diff --git a/ydb/core/tx/schemeshard/CMakeLists.linux-aarch64.txt b/ydb/core/tx/schemeshard/CMakeLists.linux-aarch64.txt index a10c709ecd5..cbcd3fa7598 100644 --- a/ydb/core/tx/schemeshard/CMakeLists.linux-aarch64.txt +++ b/ydb/core/tx/schemeshard/CMakeLists.linux-aarch64.txt @@ -226,6 +226,7 @@ target_sources(core-tx-schemeshard PRIVATE ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard__upgrade_access_database.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard__make_access_database_no_inheritable.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_audit_log_fragment.cpp + ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_audit_log.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_impl.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_billing_helpers.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_cdc_stream_scan.cpp diff --git a/ydb/core/tx/schemeshard/CMakeLists.linux-x86_64.txt b/ydb/core/tx/schemeshard/CMakeLists.linux-x86_64.txt index a10c709ecd5..cbcd3fa7598 100644 --- a/ydb/core/tx/schemeshard/CMakeLists.linux-x86_64.txt +++ b/ydb/core/tx/schemeshard/CMakeLists.linux-x86_64.txt @@ -226,6 +226,7 @@ target_sources(core-tx-schemeshard PRIVATE ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard__upgrade_access_database.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard__make_access_database_no_inheritable.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_audit_log_fragment.cpp + ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_audit_log.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_impl.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_billing_helpers.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_cdc_stream_scan.cpp diff --git a/ydb/core/tx/schemeshard/CMakeLists.windows-x86_64.txt b/ydb/core/tx/schemeshard/CMakeLists.windows-x86_64.txt index b066e2c3017..12108caa6f5 100644 --- a/ydb/core/tx/schemeshard/CMakeLists.windows-x86_64.txt +++ b/ydb/core/tx/schemeshard/CMakeLists.windows-x86_64.txt @@ -225,6 +225,7 @@ target_sources(core-tx-schemeshard PRIVATE ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard__upgrade_access_database.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard__make_access_database_no_inheritable.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_audit_log_fragment.cpp + ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_audit_log.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_impl.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_billing_helpers.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_cdc_stream_scan.cpp diff --git a/ydb/core/tx/schemeshard/schemeshard__operation.cpp b/ydb/core/tx/schemeshard/schemeshard__operation.cpp index 4fb08611b4f..41761d4653f 100644 --- a/ydb/core/tx/schemeshard/schemeshard__operation.cpp +++ b/ydb/core/tx/schemeshard/schemeshard__operation.cpp @@ -5,9 +5,7 @@ #include "schemeshard__operation_memory_changes.h" #include "schemeshard__operation_db_changes.h" -#include "schemeshard_audit_log_fragment.h" -#include "ydb/core/audit/audit_log.h" - +#include "schemeshard_audit_log.h" #include "schemeshard_impl.h" #include <ydb/core/tablet/tablet_exception.h> @@ -36,110 +34,6 @@ std::tuple<TMaybe<NACLib::TUserToken>, bool> ParseUserToken(const TString& token return std::make_tuple(result, parseError); } -TString GeneralStatus(NKikimrScheme::EStatus actualStatus) { - switch(actualStatus) { - case NKikimrScheme::EStatus::StatusAlreadyExists: - case NKikimrScheme::EStatus::StatusSuccess: - return "SUCCESS"; - case NKikimrScheme::EStatus::StatusAccepted: - //TODO: reclassify StatusAccepted as IN-PROCCESS when - // logging of operation completion points will be added - // return "IN-PROCCESS"; - return "SUCCESS"; - default: - return "ERROR"; - } -} - -TString RenderList(const TVector<TString>& list) { - auto result = TStringBuilder(); - result << "[" << JoinStrings(list.begin(), list.end(), ", ") << "]"; - return result; -} - -std::tuple<TString, TString, TString> GetDatabaseCloudIds(const TPath &databasePath) { - if (databasePath.IsEmpty()) { - return {}; - } - Y_VERIFY(databasePath->IsDomainRoot()); - auto getAttr = [&databasePath](const TString &name) -> TString { - if (databasePath.Base()->UserAttrs->Attrs.contains(name)) { - return databasePath.Base()->UserAttrs->Attrs.at(name); - } - return {}; - }; - return std::make_tuple( - getAttr("cloud_id"), - getAttr("folder_id"), - getAttr("database_id") - ); -} - -TPath DatabasePathFromWorkingDir(TSchemeShard* SS, const TString &opWorkingDir) { - auto databasePath = TPath::Resolve(opWorkingDir, SS); - if (!databasePath.IsResolved()) { - databasePath.RiseUntilFirstResolvedParent(); - } - //NOTE: operation working dir is usually set to a path of some database/subdomain, - // so the next lines is only a safety measure - if (!databasePath.IsEmpty() && !databasePath->IsDomainRoot()) { - databasePath = TPath::Init(databasePath.GetPathIdForDomain(), SS); - } - return databasePath; -} - -void AuditLogModifySchemeTransaction(const NKikimrScheme::TEvModifySchemeTransaction& request, const NKikimrScheme::TEvModifySchemeTransactionResult& response, TSchemeShard* SS, const TString& userSID) { - static const TString SchemeshardComponentName = "schemeshard"; - - //NOTE: EmptyValue couldn't be an empty string as AUDIT_PART() skips parts with an empty values - static const TString EmptyValue = "{none}"; - - // Each TEvModifySchemeTransaction.Transaction is a self sufficient operation and should be logged independently - // (even if it was packed into a single TxProxy transaction with some other operations). - for (const auto& operation : request.GetTransaction()) { - auto logEntry = MakeAuditLogFragment(operation); - - TPath databasePath = DatabasePathFromWorkingDir(SS, operation.GetWorkingDir()); - auto [cloud_id, folder_id, database_id] = GetDatabaseCloudIds(databasePath); - auto peerName = request.GetPeerName(); - - AUDIT_LOG( - AUDIT_PART("component", SchemeshardComponentName) - AUDIT_PART("tx_id", std::to_string(request.GetTxId())) - AUDIT_PART("remote_address", (!peerName.empty() ? peerName : EmptyValue) ) - AUDIT_PART("subject", (!userSID.empty() ? userSID : EmptyValue)) - AUDIT_PART("database", (!databasePath.IsEmpty() ? databasePath.GetDomainPathString() : EmptyValue)) - AUDIT_PART("operation", logEntry.Operation) - AUDIT_PART("paths", RenderList(logEntry.Paths), !logEntry.Paths.empty()) - AUDIT_PART("status", GeneralStatus(response.GetStatus())) - AUDIT_PART("detailed_status", NKikimrScheme::EStatus_Name(response.GetStatus())) - AUDIT_PART("reason", response.GetReason(), response.HasReason()) - - AUDIT_PART("cloud_id", cloud_id, !cloud_id.empty()); - AUDIT_PART("folder_id", folder_id, !folder_id.empty()); - AUDIT_PART("resource_id", database_id, !database_id.empty()); - - // Additionally: - - // ModifyACL. - // Technically, non-empty ModifyACL field could come with any ModifyScheme operation. - // In practice, ModifyACL will get processed only by: - // 1. explicit operation ESchemeOpModifyACL -- to modify ACL on a path - // 2. ESchemeOpMkDir or ESchemeOpCreate* operations -- to set rights to newly created paths/entities - // 3. ESchemeOpCopyTable -- to be checked against acl size limit, not to be applied in any way - AUDIT_PART("new_owner", logEntry.NewOwner, !logEntry.NewOwner.empty()); - AUDIT_PART("acl_add", RenderList(logEntry.ACLAdd), !logEntry.ACLAdd.empty()); - AUDIT_PART("acl_remove", RenderList(logEntry.ACLRemove), !logEntry.ACLRemove.empty()); - - // AlterUserAttributes. - // 1. explicit operation ESchemeOpAlterUserAttributes -- to modify user attributes on a path - // 2. ESchemeOpMkDir or some ESchemeOpCreate* operations -- to set user attributes for newly created paths/entities - AUDIT_PART("user_attrs_add", RenderList(logEntry.UserAttrsAdd), !logEntry.UserAttrsAdd.empty()); - AUDIT_PART("user_attrs_remove", RenderList(logEntry.UserAttrsRemove), !logEntry.UserAttrsRemove.empty()); - ); - } -} - struct TSchemeShard::TTxOperationProposeCancelTx: public NTabletFlatExecutor::TTransactionBase<TSchemeShard> { TEvSchemeShard::TEvCancelTx::TPtr Ev; diff --git a/ydb/core/tx/schemeshard/schemeshard_audit_log.cpp b/ydb/core/tx/schemeshard/schemeshard_audit_log.cpp new file mode 100644 index 00000000000..a0a0145ac90 --- /dev/null +++ b/ydb/core/tx/schemeshard/schemeshard_audit_log.cpp @@ -0,0 +1,121 @@ +#include "schemeshard_audit_log.h" +#include "schemeshard_path.h" +#include "schemeshard_audit_log_fragment.h" + +#include <ydb/core/audit/audit_log.h> +#include <ydb/core/protos/flat_tx_scheme.pb.h> +#include <util/string/vector.h> + +namespace NKikimr::NSchemeShard { + +TString GeneralStatus(NKikimrScheme::EStatus actualStatus) { + switch(actualStatus) { + case NKikimrScheme::EStatus::StatusAlreadyExists: + case NKikimrScheme::EStatus::StatusSuccess: + return "SUCCESS"; + case NKikimrScheme::EStatus::StatusAccepted: + //TODO: reclassify StatusAccepted as IN-PROCCESS when + // logging of operation completion points will be added + // return "IN-PROCCESS"; + return "SUCCESS"; + default: + return "ERROR"; + } +} + +TString RenderList(const TVector<TString>& list) { + auto result = TStringBuilder(); + result << "[" << JoinStrings(list.begin(), list.end(), ", ") << "]"; + return result; +} + +std::tuple<TString, TString, TString> GetDatabaseCloudIds(const TPath &databasePath) { + if (databasePath.IsEmpty()) { + return {}; + } + Y_VERIFY(databasePath->IsDomainRoot()); + auto getAttr = [&databasePath](const TString &name) -> TString { + if (databasePath.Base()->UserAttrs->Attrs.contains(name)) { + return databasePath.Base()->UserAttrs->Attrs.at(name); + } + return {}; + }; + return std::make_tuple( + getAttr("cloud_id"), + getAttr("folder_id"), + getAttr("database_id") + ); +} + +TPath DatabasePathFromWorkingDir(TSchemeShard* SS, const TString &opWorkingDir) { + auto databasePath = TPath::Resolve(opWorkingDir, SS); + if (!databasePath.IsResolved()) { + databasePath.RiseUntilFirstResolvedParent(); + } + //NOTE: operation working dir is usually set to a path of some database/subdomain, + // so the next lines is only a safety measure + if (!databasePath.IsEmpty() && !databasePath->IsDomainRoot()) { + databasePath = TPath::Init(databasePath.GetPathIdForDomain(), SS); + } + return databasePath; +} + +void AuditLogModifySchemeTransaction(const NKikimrScheme::TEvModifySchemeTransaction& request, const NKikimrScheme::TEvModifySchemeTransactionResult& response, TSchemeShard* SS, const TString& userSID) { + static const TString SchemeshardComponentName = "schemeshard"; + + //NOTE: EmptyValue couldn't be an empty string as AUDIT_PART() skips parts with an empty values + static const TString EmptyValue = "{none}"; + + // Each TEvModifySchemeTransaction.Transaction is a self sufficient operation and should be logged independently + // (even if it was packed into a single TxProxy transaction with some other operations). + for (const auto& operation : request.GetTransaction()) { + auto logEntry = MakeAuditLogFragment(operation); + + TPath databasePath = DatabasePathFromWorkingDir(SS, operation.GetWorkingDir()); + auto [cloud_id, folder_id, database_id] = GetDatabaseCloudIds(databasePath); + auto peerName = request.GetPeerName(); + + AUDIT_LOG( + AUDIT_PART("component", SchemeshardComponentName) + AUDIT_PART("tx_id", std::to_string(request.GetTxId())) + AUDIT_PART("remote_address", (!peerName.empty() ? peerName : EmptyValue) ) + AUDIT_PART("subject", (!userSID.empty() ? userSID : EmptyValue)) + AUDIT_PART("database", (!databasePath.IsEmpty() ? databasePath.GetDomainPathString() : EmptyValue)) + AUDIT_PART("operation", logEntry.Operation) + AUDIT_PART("paths", RenderList(logEntry.Paths), !logEntry.Paths.empty()) + AUDIT_PART("status", GeneralStatus(response.GetStatus())) + AUDIT_PART("detailed_status", NKikimrScheme::EStatus_Name(response.GetStatus())) + AUDIT_PART("reason", response.GetReason(), response.HasReason()) + + AUDIT_PART("cloud_id", cloud_id, !cloud_id.empty()); + AUDIT_PART("folder_id", folder_id, !folder_id.empty()); + AUDIT_PART("resource_id", database_id, !database_id.empty()); + + // Additionally: + + // ModifyACL. + // Technically, non-empty ModifyACL field could come with any ModifyScheme operation. + // In practice, ModifyACL will get processed only by: + // 1. explicit operation ESchemeOpModifyACL -- to modify ACL on a path + // 2. ESchemeOpMkDir or ESchemeOpCreate* operations -- to set rights to newly created paths/entities + // 3. ESchemeOpCopyTable -- to be checked against acl size limit, not to be applied in any way + AUDIT_PART("new_owner", logEntry.NewOwner, !logEntry.NewOwner.empty()); + AUDIT_PART("acl_add", RenderList(logEntry.ACLAdd), !logEntry.ACLAdd.empty()); + AUDIT_PART("acl_remove", RenderList(logEntry.ACLRemove), !logEntry.ACLRemove.empty()); + + // AlterUserAttributes. + // 1. explicit operation ESchemeOpAlterUserAttributes -- to modify user attributes on a path + // 2. ESchemeOpMkDir or some ESchemeOpCreate* operations -- to set user attributes for newly created paths/entities + AUDIT_PART("user_attrs_add", RenderList(logEntry.UserAttrsAdd), !logEntry.UserAttrsAdd.empty()); + AUDIT_PART("user_attrs_remove", RenderList(logEntry.UserAttrsRemove), !logEntry.UserAttrsRemove.empty()); + + // AlterLogin. + // explicit operation ESchemeOpAlterLogin -- to modify user and groups + AUDIT_PART("login_user", logEntry.LoginUser); + AUDIT_PART("login_group", logEntry.LoginGroup); + AUDIT_PART("login_member", logEntry.LoginMember); + ); + } +} + +} diff --git a/ydb/core/tx/schemeshard/schemeshard_audit_log.h b/ydb/core/tx/schemeshard/schemeshard_audit_log.h new file mode 100644 index 00000000000..f9db15179f7 --- /dev/null +++ b/ydb/core/tx/schemeshard/schemeshard_audit_log.h @@ -0,0 +1,16 @@ +#pragma once + +#include <util/generic/string.h> + +namespace NKikimrScheme { +class TEvModifySchemeTransaction; +class TEvModifySchemeTransactionResult; +} + +namespace NKikimr::NSchemeShard { + +class TSchemeShard; + +void AuditLogModifySchemeTransaction(const NKikimrScheme::TEvModifySchemeTransaction& request, const NKikimrScheme::TEvModifySchemeTransactionResult& response, TSchemeShard* SS, const TString& userSID); + +} diff --git a/ydb/core/tx/schemeshard/schemeshard_audit_log_fragment.cpp b/ydb/core/tx/schemeshard/schemeshard_audit_log_fragment.cpp index a5181c88d3a..7ff867f8fad 100644 --- a/ydb/core/tx/schemeshard/schemeshard_audit_log_fragment.cpp +++ b/ydb/core/tx/schemeshard/schemeshard_audit_log_fragment.cpp @@ -8,7 +8,8 @@ namespace { -TString DefineUserOperationName(NKikimrSchemeOp::EOperationType type) { +TString DefineUserOperationName(const NKikimrSchemeOp::TModifyScheme& tx) { + NKikimrSchemeOp::EOperationType type = tx.GetOperationType(); switch (type) { // common case NKikimrSchemeOp::EOperationType::ESchemeOpModifyACL: @@ -21,8 +22,27 @@ TString DefineUserOperationName(NKikimrSchemeOp::EOperationType type) { return "CREATE LOCK"; case NKikimrSchemeOp::EOperationType::ESchemeOpDropLock: return "DROP LOCK"; + // specify ESchemeOpAlterLogin with each separate case + // it looks a bit out of the scheme, but improve reading of audit logs case NKikimrSchemeOp::EOperationType::ESchemeOpAlterLogin: - return "ALTER LOGIN"; + switch (tx.GetAlterLogin().GetAlterCase()) { + case NKikimrSchemeOp::TAlterLogin::kCreateUser: + return "CREATE USER"; + case NKikimrSchemeOp::TAlterLogin::kModifyUser: + return "MODIFY USER"; + case NKikimrSchemeOp::TAlterLogin::kRemoveUser: + return "REMOVE USER"; + case NKikimrSchemeOp::TAlterLogin::kCreateGroup: + return "CREATE GROUP"; + case NKikimrSchemeOp::TAlterLogin::kAddGroupMembership: + return "ADD GROUP MEMBERSHIP"; + case NKikimrSchemeOp::TAlterLogin::kRemoveGroupMembership: + return "REMOVE GROUP MEMBERSHIP"; + case NKikimrSchemeOp::TAlterLogin::kRemoveGroup: + return "REMOVE GROUP"; + default: + Y_FAIL("switch should cover all operation types"); + } case NKikimrSchemeOp::EOperationType::ESchemeOp_DEPRECATED_35: return "ESchemeOp_DEPRECATED_35"; // dir @@ -540,6 +560,46 @@ TChange ExtractUserAttrChange(const NKikimrSchemeOp::TModifyScheme& tx) { return {}; } +struct TChangeLogin { + TString LoginUser; + TString LoginGroup; + TString LoginMember; +}; + +TChangeLogin ExtractLoginChange(const NKikimrSchemeOp::TModifyScheme& tx) { + if (tx.HasAlterLogin()) { + TChangeLogin result; + switch (tx.GetAlterLogin().GetAlterCase()) { + case NKikimrSchemeOp::TAlterLogin::kCreateUser: + result.LoginUser = tx.GetAlterLogin().GetCreateUser().GetUser(); + break; + case NKikimrSchemeOp::TAlterLogin::kModifyUser: + result.LoginUser = tx.GetAlterLogin().GetModifyUser().GetUser(); + break; + case NKikimrSchemeOp::TAlterLogin::kRemoveUser: + result.LoginUser = tx.GetAlterLogin().GetRemoveUser().GetUser(); + break; + case NKikimrSchemeOp::TAlterLogin::kCreateGroup: + result.LoginGroup = tx.GetAlterLogin().GetCreateGroup().GetGroup(); + break; + case NKikimrSchemeOp::TAlterLogin::kAddGroupMembership: + result.LoginGroup = tx.GetAlterLogin().GetAddGroupMembership().GetGroup(); + result.LoginMember = tx.GetAlterLogin().GetAddGroupMembership().GetMember(); + break; + case NKikimrSchemeOp::TAlterLogin::kRemoveGroupMembership: + result.LoginGroup = tx.GetAlterLogin().GetRemoveGroupMembership().GetGroup(); + result.LoginMember = tx.GetAlterLogin().GetRemoveGroupMembership().GetMember(); + break; + case NKikimrSchemeOp::TAlterLogin::kRemoveGroup: + result.LoginGroup = tx.GetAlterLogin().GetRemoveGroup().GetGroup(); + break; + default: + Y_FAIL("switch should cover all operation types"); + } + return result; + } + return {}; +} } // anonymous namespace @@ -548,14 +608,19 @@ namespace NKikimr::NSchemeShard { TAuditLogFragment MakeAuditLogFragment(const NKikimrSchemeOp::TModifyScheme& tx) { auto [aclAdd, aclRemove] = ExtractACLChange(tx); auto [userAttrsAdd, userAttrsRemove] = ExtractUserAttrChange(tx); + auto [loginUser, loginGroup, loginMember] = ExtractLoginChange(tx); + return { - .Operation = DefineUserOperationName(tx.GetOperationType()), + .Operation = DefineUserOperationName(tx), .Paths = ExtractChangingPaths(tx), .NewOwner = ExtractNewOwner(tx), .ACLAdd = aclAdd, .ACLRemove = aclRemove, .UserAttrsAdd = userAttrsAdd, .UserAttrsRemove = userAttrsRemove, + .LoginUser = loginUser, + .LoginGroup = loginGroup, + .LoginMember = loginMember, }; } diff --git a/ydb/core/tx/schemeshard/schemeshard_audit_log_fragment.h b/ydb/core/tx/schemeshard/schemeshard_audit_log_fragment.h index af93dc15c80..e6347fb7325 100644 --- a/ydb/core/tx/schemeshard/schemeshard_audit_log_fragment.h +++ b/ydb/core/tx/schemeshard/schemeshard_audit_log_fragment.h @@ -18,6 +18,9 @@ struct TAuditLogFragment { TVector<TString> ACLRemove; TVector<TString> UserAttrsAdd; TVector<TString> UserAttrsRemove; + TString LoginUser; + TString LoginGroup; + TString LoginMember; }; TAuditLogFragment MakeAuditLogFragment(const NKikimrSchemeOp::TModifyScheme& tx); diff --git a/ydb/core/tx/schemeshard/ya.make b/ydb/core/tx/schemeshard/ya.make index 3db90118558..816120aecb1 100644 --- a/ydb/core/tx/schemeshard/ya.make +++ b/ydb/core/tx/schemeshard/ya.make @@ -170,6 +170,7 @@ SRCS( schemeshard__upgrade_access_database.cpp schemeshard__make_access_database_no_inheritable.cpp schemeshard_audit_log_fragment.cpp + schemeshard_audit_log.cpp schemeshard_impl.cpp schemeshard_impl.h schemeshard_billing_helpers.cpp |