aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorijon <ijon@ydb.tech>2023-09-27 17:10:40 +0300
committerijon <ijon@ydb.tech>2023-09-27 17:55:00 +0300
commit9472c1bd8bbcdca676da3dcc72772ab13d8d7857 (patch)
tree9c69a073222dec8815fd06749973830574f7e1e1
parent54ce98c42f381b12614dd327dc58a129a661c70b (diff)
downloadydb-9472c1bd8bbcdca676da3dcc72772ab13d8d7857.tar.gz
auditlog, schemeshard: add DML audit settings
Support DML audit settings at a database level (Create/Alter *Subdomain). KIKIMR-18697
-rw-r--r--.mapping.json5
-rw-r--r--ydb/core/protos/flat_tx_scheme.proto3
-rw-r--r--ydb/core/protos/subdomains.proto3
-rw-r--r--ydb/core/tx/schemeshard/CMakeLists.darwin-x86_64.txt1
-rw-r--r--ydb/core/tx/schemeshard/CMakeLists.linux-aarch64.txt1
-rw-r--r--ydb/core/tx/schemeshard/CMakeLists.linux-x86_64.txt1
-rw-r--r--ydb/core/tx/schemeshard/CMakeLists.windows-x86_64.txt1
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__init.cpp6
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__init_root.cpp4
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__operation_alter_extsubdomain.cpp7
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__operation_alter_subdomain.cpp7
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__operation_common_subdomain.h3
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__operation_create_extsubdomain.cpp5
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__operation_create_subdomain.cpp4
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__sync_update_tenants.cpp6
-rw-r--r--ydb/core/tx/schemeshard/schemeshard_impl.cpp30
-rw-r--r--ydb/core/tx/schemeshard/schemeshard_impl.h2
-rw-r--r--ydb/core/tx/schemeshard/schemeshard_info_types.cpp24
-rw-r--r--ydb/core/tx/schemeshard/schemeshard_info_types.h17
-rw-r--r--ydb/core/tx/schemeshard/schemeshard_path_describer.cpp4
-rw-r--r--ydb/core/tx/schemeshard/schemeshard_schema.h8
-rw-r--r--ydb/core/tx/schemeshard/ut_auditsettings/CMakeLists.darwin-x86_64.txt83
-rw-r--r--ydb/core/tx/schemeshard/ut_auditsettings/CMakeLists.linux-aarch64.txt86
-rw-r--r--ydb/core/tx/schemeshard/ut_auditsettings/CMakeLists.linux-x86_64.txt88
-rw-r--r--ydb/core/tx/schemeshard/ut_auditsettings/CMakeLists.txt17
-rw-r--r--ydb/core/tx/schemeshard/ut_auditsettings/CMakeLists.windows-x86_64.txt76
-rw-r--r--ydb/core/tx/schemeshard/ut_auditsettings/ut_auditsettings.cpp344
-rw-r--r--ydb/core/tx/schemeshard/ut_auditsettings/ya.make30
-rw-r--r--ydb/core/tx/schemeshard/ut_extsubdomain/ut_extsubdomain.cpp2
-rw-r--r--ydb/core/tx/schemeshard/ya.make1
-rw-r--r--ydb/tests/functional/scheme_tests/canondata/tablet_scheme_tests.TestTabletSchemes.test_tablet_schemes_flat_schemeshard_/flat_schemeshard.schema28
31 files changed, 878 insertions, 19 deletions
diff --git a/.mapping.json b/.mapping.json
index 3f36dbd246..83359369f1 100644
--- a/.mapping.json
+++ b/.mapping.json
@@ -5686,6 +5686,11 @@
"ydb/core/tx/schemeshard/CMakeLists.linux-x86_64.txt":"",
"ydb/core/tx/schemeshard/CMakeLists.txt":"",
"ydb/core/tx/schemeshard/CMakeLists.windows-x86_64.txt":"",
+ "ydb/core/tx/schemeshard/ut_auditsettings/CMakeLists.darwin-x86_64.txt":"",
+ "ydb/core/tx/schemeshard/ut_auditsettings/CMakeLists.linux-aarch64.txt":"",
+ "ydb/core/tx/schemeshard/ut_auditsettings/CMakeLists.linux-x86_64.txt":"",
+ "ydb/core/tx/schemeshard/ut_auditsettings/CMakeLists.txt":"",
+ "ydb/core/tx/schemeshard/ut_auditsettings/CMakeLists.windows-x86_64.txt":"",
"ydb/core/tx/schemeshard/ut_backup/CMakeLists.darwin-x86_64.txt":"",
"ydb/core/tx/schemeshard/ut_backup/CMakeLists.linux-aarch64.txt":"",
"ydb/core/tx/schemeshard/ut_backup/CMakeLists.linux-x86_64.txt":"",
diff --git a/ydb/core/protos/flat_tx_scheme.proto b/ydb/core/protos/flat_tx_scheme.proto
index eab789772c..ca31a4039d 100644
--- a/ydb/core/protos/flat_tx_scheme.proto
+++ b/ydb/core/protos/flat_tx_scheme.proto
@@ -211,6 +211,7 @@ message TEvInitTenantSchemeShard {
optional NKikimrSubDomains.TSchemeQuotas DeclaredSchemeQuotas = 16;
optional Ydb.Cms.DatabaseQuotas DatabaseQuotas = 17;
+ optional NKikimrSubDomains.TAuditSettings AuditSettings = 18;
}
message TEvInitTenantSchemeShardResult {
@@ -378,6 +379,8 @@ message TEvUpdateTenantSchemeShard {
optional Ydb.Cms.DatabaseQuotas DatabaseQuotas = 14;
optional string UpdateTenantRootACL = 13;
+
+ optional NKikimrSubDomains.TAuditSettings AuditSettings = 15;
}
message TEvFindTabletSubDomainPathId {
diff --git a/ydb/core/protos/subdomains.proto b/ydb/core/protos/subdomains.proto
index cd51c78e2a..83490ca6d2 100644
--- a/ydb/core/protos/subdomains.proto
+++ b/ydb/core/protos/subdomains.proto
@@ -22,6 +22,7 @@ message TSubDomainSettings {
optional bool ExternalSysViewProcessor = 10 [default = false];
optional TSchemeQuotas DeclaredSchemeQuotas = 11;
optional Ydb.Cms.DatabaseQuotas DatabaseQuotas = 12;
+ optional TAuditSettings AuditSettings = 13;
}
message TProcessingParams {
@@ -66,7 +67,7 @@ message TDomainState {
}
message TAuditSettings {
- optional bool EnableDmlAudit = 1;
+ optional bool EnableDmlAudit = 1 [default = false];
repeated string ExpectedSubjects = 2;
}
diff --git a/ydb/core/tx/schemeshard/CMakeLists.darwin-x86_64.txt b/ydb/core/tx/schemeshard/CMakeLists.darwin-x86_64.txt
index 36b49b2cb7..e69d303b7a 100644
--- a/ydb/core/tx/schemeshard/CMakeLists.darwin-x86_64.txt
+++ b/ydb/core/tx/schemeshard/CMakeLists.darwin-x86_64.txt
@@ -6,6 +6,7 @@
# original buildsystem will not be accepted.
+add_subdirectory(ut_auditsettings)
add_subdirectory(ut_backup)
add_subdirectory(ut_base)
add_subdirectory(ut_base_reboots)
diff --git a/ydb/core/tx/schemeshard/CMakeLists.linux-aarch64.txt b/ydb/core/tx/schemeshard/CMakeLists.linux-aarch64.txt
index e68f7ce937..2a9e71ef80 100644
--- a/ydb/core/tx/schemeshard/CMakeLists.linux-aarch64.txt
+++ b/ydb/core/tx/schemeshard/CMakeLists.linux-aarch64.txt
@@ -6,6 +6,7 @@
# original buildsystem will not be accepted.
+add_subdirectory(ut_auditsettings)
add_subdirectory(ut_backup)
add_subdirectory(ut_base)
add_subdirectory(ut_base_reboots)
diff --git a/ydb/core/tx/schemeshard/CMakeLists.linux-x86_64.txt b/ydb/core/tx/schemeshard/CMakeLists.linux-x86_64.txt
index e68f7ce937..2a9e71ef80 100644
--- a/ydb/core/tx/schemeshard/CMakeLists.linux-x86_64.txt
+++ b/ydb/core/tx/schemeshard/CMakeLists.linux-x86_64.txt
@@ -6,6 +6,7 @@
# original buildsystem will not be accepted.
+add_subdirectory(ut_auditsettings)
add_subdirectory(ut_backup)
add_subdirectory(ut_base)
add_subdirectory(ut_base_reboots)
diff --git a/ydb/core/tx/schemeshard/CMakeLists.windows-x86_64.txt b/ydb/core/tx/schemeshard/CMakeLists.windows-x86_64.txt
index e41a3f675b..b27ba39942 100644
--- a/ydb/core/tx/schemeshard/CMakeLists.windows-x86_64.txt
+++ b/ydb/core/tx/schemeshard/CMakeLists.windows-x86_64.txt
@@ -6,6 +6,7 @@
# original buildsystem will not be accepted.
+add_subdirectory(ut_auditsettings)
add_subdirectory(ut_backup)
add_subdirectory(ut_base)
add_subdirectory(ut_base_reboots)
diff --git a/ydb/core/tx/schemeshard/schemeshard__init.cpp b/ydb/core/tx/schemeshard/schemeshard__init.cpp
index 36b3c78eee..ab83c052a6 100644
--- a/ydb/core/tx/schemeshard/schemeshard__init.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard__init.cpp
@@ -1524,6 +1524,12 @@ struct TSchemeShard::TTxInit : public TTransactionBase<TSchemeShard> {
if (domainInfo->GetDiskQuotaExceeded()) {
Self->ChangeDiskSpaceQuotaExceeded(+1);
}
+
+ if (rowset.HaveValue<Schema::SubDomains::AuditSettings>()) {
+ NKikimrSubDomains::TAuditSettings value;
+ Y_VERIFY(ParseFromStringNoSizeLimit(value, rowset.GetValue<Schema::SubDomains::AuditSettings>()));
+ domainInfo->SetAuditSettings(value);
+ }
}
if (!rowset.Next())
diff --git a/ydb/core/tx/schemeshard/schemeshard__init_root.cpp b/ydb/core/tx/schemeshard/schemeshard__init_root.cpp
index 6d37d4f2e7..4660444414 100644
--- a/ydb/core/tx/schemeshard/schemeshard__init_root.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard__init_root.cpp
@@ -392,6 +392,10 @@ struct TSchemeShard::TTxInitTenantSchemeShard : public TSchemeShard::TRwTxBase {
subdomain->SetDatabaseQuotas(record.GetDatabaseQuotas(), Self);
}
+ if (record.HasAuditSettings()) {
+ subdomain->SetAuditSettings(record.GetAuditSettings());
+ }
+
RegisterShard(db, subdomain, processingParams.GetCoordinators(), TTabletTypes::Coordinator);
RegisterShard(db, subdomain, processingParams.GetMediators(), TTabletTypes::Mediator);
RegisterShard(db, subdomain, TVector<ui64>{processingParams.GetSchemeShard()}, TTabletTypes::SchemeShard);
diff --git a/ydb/core/tx/schemeshard/schemeshard__operation_alter_extsubdomain.cpp b/ydb/core/tx/schemeshard/schemeshard__operation_alter_extsubdomain.cpp
index cdb070e4f0..a690454a47 100644
--- a/ydb/core/tx/schemeshard/schemeshard__operation_alter_extsubdomain.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard__operation_alter_extsubdomain.cpp
@@ -794,6 +794,13 @@ public:
alter->SetDatabaseQuotas(inputSettings.GetDatabaseQuotas());
}
+ if (const auto& auditSettings = subdomainInfo->GetAuditSettings()) {
+ alter->SetAuditSettings(*auditSettings);
+ }
+ if (inputSettings.HasAuditSettings()) {
+ alter->ApplyAuditSettings(inputSettings.GetAuditSettings());
+ }
+
LOG_D("TAlterExtSubDomain Propose"
<< ", opId: " << OperationId
<< ", subdomain ver " << subdomainInfo->GetVersion()
diff --git a/ydb/core/tx/schemeshard/schemeshard__operation_alter_subdomain.cpp b/ydb/core/tx/schemeshard/schemeshard__operation_alter_subdomain.cpp
index 39000ffb62..c4f30ba670 100644
--- a/ydb/core/tx/schemeshard/schemeshard__operation_alter_subdomain.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard__operation_alter_subdomain.cpp
@@ -290,6 +290,13 @@ public:
alterData->SetDatabaseQuotas(settings.GetDatabaseQuotas());
}
+ if (const auto& auditSettings = subDomainInfo->GetAuditSettings()) {
+ alterData->SetAuditSettings(*auditSettings);
+ }
+ if (settings.HasAuditSettings()) {
+ alterData->ApplyAuditSettings(settings.GetAuditSettings());
+ }
+
NIceDb::TNiceDb db(context.GetDB());
subDomain->LastTxId = OperationId.GetTxId();
diff --git a/ydb/core/tx/schemeshard/schemeshard__operation_common_subdomain.h b/ydb/core/tx/schemeshard/schemeshard__operation_common_subdomain.h
index f94c27897f..9e9eee08f6 100644
--- a/ydb/core/tx/schemeshard/schemeshard__operation_common_subdomain.h
+++ b/ydb/core/tx/schemeshard/schemeshard__operation_common_subdomain.h
@@ -232,6 +232,9 @@ public:
if (alterData->GetDatabaseQuotas()) {
event->Record.MutableDatabaseQuotas()->CopyFrom(*alterData->GetDatabaseQuotas());
}
+ if (alterData->GetAuditSettings()) {
+ event->Record.MutableAuditSettings()->CopyFrom(*alterData->GetAuditSettings());
+ }
LOG_DEBUG_S(context.Ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
"Send configure request to schemeshard: " << tabletID <<
" opId: " << OperationId <<
diff --git a/ydb/core/tx/schemeshard/schemeshard__operation_create_extsubdomain.cpp b/ydb/core/tx/schemeshard/schemeshard__operation_create_extsubdomain.cpp
index 19ece7b117..0c61d6c8b5 100644
--- a/ydb/core/tx/schemeshard/schemeshard__operation_create_extsubdomain.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard__operation_create_extsubdomain.cpp
@@ -156,7 +156,6 @@ public:
return result;
}
-
bool requestedStoragePools = !settings.GetStoragePools().empty();
if (requestedStoragePools) {
return paramErrorResult("only declaration at creation is allowed, do not set up storage");
@@ -228,6 +227,10 @@ public:
alter->SetDatabaseQuotas(settings.GetDatabaseQuotas());
}
+ if (settings.HasAuditSettings()) {
+ alter->SetAuditSettings(settings.GetAuditSettings());
+ }
+
Y_VERIFY(!context.SS->SubDomains.contains(newNode->PathId));
auto& subDomainInfo = context.SS->SubDomains[newNode->PathId];
subDomainInfo = new TSubDomainInfo();
diff --git a/ydb/core/tx/schemeshard/schemeshard__operation_create_subdomain.cpp b/ydb/core/tx/schemeshard/schemeshard__operation_create_subdomain.cpp
index f5a58df674..56af6981bf 100644
--- a/ydb/core/tx/schemeshard/schemeshard__operation_create_subdomain.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard__operation_create_subdomain.cpp
@@ -298,6 +298,10 @@ public:
alter->SetDatabaseQuotas(settings.GetDatabaseQuotas());
}
+ if (settings.HasAuditSettings()) {
+ alter->SetAuditSettings(settings.GetAuditSettings());
+ }
+
Y_VERIFY(!context.SS->SubDomains.contains(newNode->PathId));
auto& subDomainInfo = context.SS->SubDomains[newNode->PathId];
subDomainInfo = new TSubDomainInfo();
diff --git a/ydb/core/tx/schemeshard/schemeshard__sync_update_tenants.cpp b/ydb/core/tx/schemeshard/schemeshard__sync_update_tenants.cpp
index a74b28a6be..58455f5f41 100644
--- a/ydb/core/tx/schemeshard/schemeshard__sync_update_tenants.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard__sync_update_tenants.cpp
@@ -8,7 +8,6 @@ namespace NSchemeShard {
using namespace NTabletFlatExecutor;
-
struct TSchemeShard::TTxSyncTenant : public TSchemeShard::TRwTxBase {
TPathId PathId;
TSideEffects SideEffects;
@@ -114,6 +113,11 @@ struct TSchemeShard::TTxUpdateTenant : public TSchemeShard::TRwTxBase {
Self->PersistSubDomainDatabaseQuotas(db, Self->RootPathId(), *subdomain);
}
+ if (record.HasAuditSettings()) {
+ subdomain->SetAuditSettings(record.GetAuditSettings());
+ Self->PersistSubDomainAuditSettings(db, Self->RootPathId(), *subdomain);
+ }
+
Self->PersistStoragePools(db, Self->RootPathId(), *subdomain);
SideEffects.PublishToSchemeBoard(InvalidOperationId, Self->RootPathId());
MakeSync();
diff --git a/ydb/core/tx/schemeshard/schemeshard_impl.cpp b/ydb/core/tx/schemeshard/schemeshard_impl.cpp
index 5c2c98b036..4c9d406e4d 100644
--- a/ydb/core/tx/schemeshard/schemeshard_impl.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard_impl.cpp
@@ -54,7 +54,7 @@ bool ResolvePoolNames(
return true;
}
-} // namespace
+} // anonymous namespace
const TSchemeLimits TSchemeShard::DefaultLimits = {};
@@ -1878,6 +1878,8 @@ void TSchemeShard::PersistSubDomainAlter(NIceDb::TNiceDb& db, const TPathId& pat
NIceDb::TNull<Schema::SubDomainsAlterData::DatabaseQuotas>());
}
+ PersistSubDomainAuditSettingsAlter(db, pathId, subDomain);
+
for (auto shardIdx: subDomain.GetPrivateShards()) {
db.Table<Schema::SubDomainShardsAlterData>().Key(pathId.LocalPathId, shardIdx.GetLocalId()).Update();
}
@@ -1939,6 +1941,8 @@ void TSchemeShard::PersistSubDomain(NIceDb::TNiceDb& db, const TPathId& pathId,
PersistSubDomainDatabaseQuotas(db, pathId, subDomain);
PersistSubDomainState(db, pathId, subDomain);
+ PersistSubDomainAuditSettings(db, pathId, subDomain);
+
db.Table<Schema::SubDomainsAlterData>().Key(pathId.LocalPathId).Delete();
for (auto shardIdx: subDomain.GetPrivateShards()) {
@@ -2040,6 +2044,26 @@ void TSchemeShard::PersistRemoveSubDomain(NIceDb::TNiceDb& db, const TPathId& pa
}
}
+template <class Table>
+void PersistSubDomainAuditSettingsImpl(NIceDb::TNiceDb& db, const TPathId& pathId, const TSubDomainInfo::TMaybeAuditSettings& value) {
+ using Field = typename Table::AuditSettings;
+ if (value) {
+ TString serialized;
+ Y_VERIFY(value->SerializeToString(&serialized));
+ db.Table<Table>().Key(pathId.LocalPathId).Update(NIceDb::TUpdate<Field>(serialized));
+ } else {
+ db.Table<Table>().Key(pathId.LocalPathId).template UpdateToNull<Field>();
+ }
+}
+
+void TSchemeShard::PersistSubDomainAuditSettings(NIceDb::TNiceDb& db, const TPathId& pathId, const TSubDomainInfo& subDomain) {
+ PersistSubDomainAuditSettingsImpl<Schema::SubDomains>(db, pathId, subDomain.GetAuditSettings());
+}
+
+void TSchemeShard::PersistSubDomainAuditSettingsAlter(NIceDb::TNiceDb& db, const TPathId& pathId, const TSubDomainInfo& subDomain) {
+ PersistSubDomainAuditSettingsImpl<Schema::SubDomainsAlterData>(db, pathId, subDomain.GetAuditSettings());
+}
+
void TSchemeShard::PersistACL(NIceDb::TNiceDb& db, const TPathElement::TPtr path) {
if (path->PathId.OwnerId == TabletID()) {
db.Table<Schema::Paths>().Key(path->PathId.LocalPathId).Update(
@@ -6060,8 +6084,8 @@ void TSchemeShard::Handle(TEvSchemeShard::TEvNotifyTxCompletionResult::TPtr& ev,
"Message:\n" << ev->Get()->Record.ShortDebugString());
const auto txId = TTxId(ev->Get()->Record.GetTxId());
- bool executed = false;
-
+ bool executed = false;
+
if (TxIdToExport.contains(txId) || TxIdToDependentExport.contains(txId)) {
Execute(CreateTxProgressExport(txId), ctx);
executed = true;
diff --git a/ydb/core/tx/schemeshard/schemeshard_impl.h b/ydb/core/tx/schemeshard/schemeshard_impl.h
index 49a1ce4e40..a73da994ec 100644
--- a/ydb/core/tx/schemeshard/schemeshard_impl.h
+++ b/ydb/core/tx/schemeshard/schemeshard_impl.h
@@ -659,6 +659,8 @@ public:
void PersistSubDomainSecurityStateVersion(NIceDb::TNiceDb& db, const TPathId& pathId, const TSubDomainInfo& subDomain);
void PersistSubDomainPrivateShards(NIceDb::TNiceDb& db, const TPathId& pathId, const TSubDomainInfo& subDomain);
void PersistDeleteSubDomainAlter(NIceDb::TNiceDb& db, const TPathId& pathId, const TSubDomainInfo& subDomain);
+ void PersistSubDomainAuditSettings(NIceDb::TNiceDb& db, const TPathId& pathId, const TSubDomainInfo& subDomain);
+ void PersistSubDomainAuditSettingsAlter(NIceDb::TNiceDb& db, const TPathId& pathId, const TSubDomainInfo& subDomain);
void PersistKesusInfo(NIceDb::TNiceDb& db, TPathId pathId, const TKesusInfo::TPtr);
void PersistKesusVersion(NIceDb::TNiceDb& db, TPathId pathId, const TKesusInfo::TPtr);
void PersistAddKesusAlter(NIceDb::TNiceDb& db, TPathId pathId, const TKesusInfo::TPtr);
diff --git a/ydb/core/tx/schemeshard/schemeshard_info_types.cpp b/ydb/core/tx/schemeshard/schemeshard_info_types.cpp
index ff64a0c82e..6499a34226 100644
--- a/ydb/core/tx/schemeshard/schemeshard_info_types.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard_info_types.cpp
@@ -20,6 +20,30 @@
namespace NKikimr {
namespace NSchemeShard {
+void TSubDomainInfo::ApplyAuditSettings(const TSubDomainInfo::TMaybeAuditSettings& diff) {
+ if (diff.Defined()) {
+ const auto& input = diff.GetRef();
+ if (AuditSettings.Defined()) {
+ NKikimrSubDomains::TAuditSettings next = AuditSettings.GetRef();
+ if (input.HasEnableDmlAudit()) {
+ next.SetEnableDmlAudit(input.GetEnableDmlAudit());
+ }
+ if (input.ExpectedSubjectsSize() > 0) {
+ next.ClearExpectedSubjects();
+ // instead of CopyFrom, manually copy all but empty elements
+ for (const auto& i : input.GetExpectedSubjects()) {
+ if (!i.empty()) {
+ next.AddExpectedSubjects(i);
+ }
+ }
+ }
+ AuditSettings = next;
+ } else {
+ AuditSettings = input;
+ }
+ }
+}
+
TTableInfo::TAlterDataPtr TTableInfo::CreateAlterData(
TPtr source,
NKikimrSchemeOp::TTableDescription& op,
diff --git a/ydb/core/tx/schemeshard/schemeshard_info_types.h b/ydb/core/tx/schemeshard/schemeshard_info_types.h
index 7648ab37c7..b1323ab699 100644
--- a/ydb/core/tx/schemeshard/schemeshard_info_types.h
+++ b/ydb/core/tx/schemeshard/schemeshard_info_types.h
@@ -1684,7 +1684,6 @@ struct TSubDomainInfo: TSimpleRefCount<TSubDomainInfo> {
CountDiskSpaceQuotas(counters, GetDiskSpaceQuotas(), AlterData->GetDiskSpaceQuotas());
CountStreamShardsQuota(counters, GetStreamShardsQuota(), AlterData->GetStreamShardsQuota());
CountStreamReservedStorageQuota(counters, GetStreamReservedStorageQuota(), AlterData->GetStreamReservedStorageQuota());
-
}
ui64 GetStreamShardsQuota() const {
@@ -2105,6 +2104,18 @@ struct TSubDomainInfo: TSimpleRefCount<TSubDomainInfo> {
++SecurityStateVersion;
}
+ using TMaybeAuditSettings = TMaybe<NKikimrSubDomains::TAuditSettings, NMaybe::TPolicyUndefinedFail>;
+
+ void SetAuditSettings(const NKikimrSubDomains::TAuditSettings& value) {
+ AuditSettings.ConstructInPlace(value);
+ }
+
+ const TMaybeAuditSettings& GetAuditSettings() const {
+ return AuditSettings;
+ }
+
+ void ApplyAuditSettings(const TMaybeAuditSettings& diff);
+
private:
bool InitiatedAsGlobal = false;
NKikimrSubDomains::TProcessingParams ProcessingParams;
@@ -2138,6 +2149,8 @@ private:
NLoginProto::TSecurityState SecurityState;
ui64 SecurityStateVersion = 0;
+ TMaybeAuditSettings AuditSettings;
+
TVector<TTabletId> FilterPrivateTablets(TTabletTypes::EType type, const THashMap<TShardIdx, TShardInfo>& allShards) const {
TVector<TTabletId> tablets;
for (auto shardId: PrivateShards) {
@@ -2985,7 +2998,7 @@ struct TIndexBuildInfo: public TSimpleRefCount<TIndexBuildInfo> {
TString IndexName;
TVector<TString> IndexColumns;
TVector<TString> DataColumns;
-
+
TVector<TColumnBuildInfo> BuildColumns;
TString ImplTablePath;
diff --git a/ydb/core/tx/schemeshard/schemeshard_path_describer.cpp b/ydb/core/tx/schemeshard/schemeshard_path_describer.cpp
index 0c58a0e3be..fdba0a3e56 100644
--- a/ydb/core/tx/schemeshard/schemeshard_path_describer.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard_path_describer.cpp
@@ -708,6 +708,10 @@ void TPathDescriber::DescribeDomainRoot(TPathElement::TPtr pathEl) {
if (subDomainInfo->GetDiskQuotaExceeded()) {
entry->MutableDomainState()->SetDiskQuotaExceeded(true);
}
+
+ if (const auto& auditSettings = subDomainInfo->GetAuditSettings()) {
+ entry->MutableAuditSettings()->CopyFrom(*auditSettings);
+ }
}
void TPathDescriber::DescribeDomainExtra(TPathElement::TPtr pathEl) {
diff --git a/ydb/core/tx/schemeshard/schemeshard_schema.h b/ydb/core/tx/schemeshard/schemeshard_schema.h
index 46d38614af..009229dbac 100644
--- a/ydb/core/tx/schemeshard/schemeshard_schema.h
+++ b/ydb/core/tx/schemeshard/schemeshard_schema.h
@@ -734,6 +734,7 @@ struct Schema : NIceDb::Schema {
struct TableCdcStreamsLimit : Column<27, NScheme::NTypeIds::Uint64> {};
struct ExportsLimit : Column<28, NScheme::NTypeIds::Uint64> {};
struct ImportsLimit : Column<29, NScheme::NTypeIds::Uint64> {};
+ struct AuditSettings : Column<30, NScheme::NTypeIds::String> {};
using TKey = TableKey<PathId>;
using TColumns = TableColumns<
@@ -765,7 +766,8 @@ struct Schema : NIceDb::Schema {
SecurityStateVersion,
TableCdcStreamsLimit,
ExportsLimit,
- ImportsLimit
+ ImportsLimit,
+ AuditSettings
>;
};
@@ -787,6 +789,7 @@ struct Schema : NIceDb::Schema {
struct SharedHiveId : Column<7, NScheme::NTypeIds::Uint64> { using Type = TTabletId; static constexpr Type Default = InvalidTabletId; };
struct DeclaredSchemeQuotas : Column<8, NScheme::NTypeIds::String> {};
struct DatabaseQuotas : Column<9, NScheme::NTypeIds::String> {};
+ struct AuditSettings : Column<10, NScheme::NTypeIds::String> {};
using TKey = TableKey<PathId>;
using TColumns = TableColumns<
@@ -798,7 +801,8 @@ struct Schema : NIceDb::Schema {
ResourcesDomainLocalPathId,
SharedHiveId,
DeclaredSchemeQuotas,
- DatabaseQuotas
+ DatabaseQuotas,
+ AuditSettings
>;
};
diff --git a/ydb/core/tx/schemeshard/ut_auditsettings/CMakeLists.darwin-x86_64.txt b/ydb/core/tx/schemeshard/ut_auditsettings/CMakeLists.darwin-x86_64.txt
new file mode 100644
index 0000000000..d6cb0d8415
--- /dev/null
+++ b/ydb/core/tx/schemeshard/ut_auditsettings/CMakeLists.darwin-x86_64.txt
@@ -0,0 +1,83 @@
+
+# This file was generated by the build system used internally in the Yandex monorepo.
+# Only simple modifications are allowed (adding source-files to targets, adding simple properties
+# like target_include_directories). These modifications will be ported to original
+# ya.make files by maintainers. Any complex modifications which can't be ported back to the
+# original buildsystem will not be accepted.
+
+
+
+add_executable(ydb-core-tx-schemeshard-ut_auditsettings)
+target_compile_options(ydb-core-tx-schemeshard-ut_auditsettings PRIVATE
+ -DUSE_CURRENT_UDF_ABI_VERSION
+)
+target_include_directories(ydb-core-tx-schemeshard-ut_auditsettings PRIVATE
+ ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard
+)
+target_link_libraries(ydb-core-tx-schemeshard-ut_auditsettings PUBLIC
+ contrib-libs-cxxsupp
+ yutil
+ library-cpp-cpuid_check
+ cpp-testing-unittest_main
+ core-tx-schemeshard
+ library-cpp-getopt
+ cpp-regex-pcre
+ library-cpp-svnversion
+ core-testlib-default
+ ydb-core-tx
+ tx-schemeshard-ut_helpers
+)
+target_link_options(ydb-core-tx-schemeshard-ut_auditsettings PRIVATE
+ -Wl,-platform_version,macos,11.0,11.0
+ -fPIC
+ -fPIC
+ -framework
+ CoreFoundation
+)
+target_sources(ydb-core-tx-schemeshard-ut_auditsettings PRIVATE
+ ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/ut_auditsettings/ut_auditsettings.cpp
+)
+set_property(
+ TARGET
+ ydb-core-tx-schemeshard-ut_auditsettings
+ PROPERTY
+ SPLIT_FACTOR
+ 10
+)
+add_yunittest(
+ NAME
+ ydb-core-tx-schemeshard-ut_auditsettings
+ TEST_TARGET
+ ydb-core-tx-schemeshard-ut_auditsettings
+ TEST_ARG
+ --print-before-suite
+ --print-before-test
+ --fork-tests
+ --print-times
+ --show-fails
+)
+set_yunittest_property(
+ TEST
+ ydb-core-tx-schemeshard-ut_auditsettings
+ PROPERTY
+ LABELS
+ MEDIUM
+)
+set_yunittest_property(
+ TEST
+ ydb-core-tx-schemeshard-ut_auditsettings
+ PROPERTY
+ PROCESSORS
+ 1
+)
+set_yunittest_property(
+ TEST
+ ydb-core-tx-schemeshard-ut_auditsettings
+ PROPERTY
+ TIMEOUT
+ 60
+)
+target_allocator(ydb-core-tx-schemeshard-ut_auditsettings
+ system_allocator
+)
+vcs_info(ydb-core-tx-schemeshard-ut_auditsettings)
diff --git a/ydb/core/tx/schemeshard/ut_auditsettings/CMakeLists.linux-aarch64.txt b/ydb/core/tx/schemeshard/ut_auditsettings/CMakeLists.linux-aarch64.txt
new file mode 100644
index 0000000000..d89d672282
--- /dev/null
+++ b/ydb/core/tx/schemeshard/ut_auditsettings/CMakeLists.linux-aarch64.txt
@@ -0,0 +1,86 @@
+
+# This file was generated by the build system used internally in the Yandex monorepo.
+# Only simple modifications are allowed (adding source-files to targets, adding simple properties
+# like target_include_directories). These modifications will be ported to original
+# ya.make files by maintainers. Any complex modifications which can't be ported back to the
+# original buildsystem will not be accepted.
+
+
+
+add_executable(ydb-core-tx-schemeshard-ut_auditsettings)
+target_compile_options(ydb-core-tx-schemeshard-ut_auditsettings PRIVATE
+ -DUSE_CURRENT_UDF_ABI_VERSION
+)
+target_include_directories(ydb-core-tx-schemeshard-ut_auditsettings PRIVATE
+ ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard
+)
+target_link_libraries(ydb-core-tx-schemeshard-ut_auditsettings PUBLIC
+ contrib-libs-linux-headers
+ contrib-libs-cxxsupp
+ yutil
+ cpp-testing-unittest_main
+ core-tx-schemeshard
+ library-cpp-getopt
+ cpp-regex-pcre
+ library-cpp-svnversion
+ core-testlib-default
+ ydb-core-tx
+ tx-schemeshard-ut_helpers
+)
+target_link_options(ydb-core-tx-schemeshard-ut_auditsettings PRIVATE
+ -ldl
+ -lrt
+ -Wl,--no-as-needed
+ -fPIC
+ -fPIC
+ -lpthread
+ -lrt
+ -ldl
+)
+target_sources(ydb-core-tx-schemeshard-ut_auditsettings PRIVATE
+ ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/ut_auditsettings/ut_auditsettings.cpp
+)
+set_property(
+ TARGET
+ ydb-core-tx-schemeshard-ut_auditsettings
+ PROPERTY
+ SPLIT_FACTOR
+ 10
+)
+add_yunittest(
+ NAME
+ ydb-core-tx-schemeshard-ut_auditsettings
+ TEST_TARGET
+ ydb-core-tx-schemeshard-ut_auditsettings
+ TEST_ARG
+ --print-before-suite
+ --print-before-test
+ --fork-tests
+ --print-times
+ --show-fails
+)
+set_yunittest_property(
+ TEST
+ ydb-core-tx-schemeshard-ut_auditsettings
+ PROPERTY
+ LABELS
+ MEDIUM
+)
+set_yunittest_property(
+ TEST
+ ydb-core-tx-schemeshard-ut_auditsettings
+ PROPERTY
+ PROCESSORS
+ 1
+)
+set_yunittest_property(
+ TEST
+ ydb-core-tx-schemeshard-ut_auditsettings
+ PROPERTY
+ TIMEOUT
+ 60
+)
+target_allocator(ydb-core-tx-schemeshard-ut_auditsettings
+ cpp-malloc-jemalloc
+)
+vcs_info(ydb-core-tx-schemeshard-ut_auditsettings)
diff --git a/ydb/core/tx/schemeshard/ut_auditsettings/CMakeLists.linux-x86_64.txt b/ydb/core/tx/schemeshard/ut_auditsettings/CMakeLists.linux-x86_64.txt
new file mode 100644
index 0000000000..b152b4143d
--- /dev/null
+++ b/ydb/core/tx/schemeshard/ut_auditsettings/CMakeLists.linux-x86_64.txt
@@ -0,0 +1,88 @@
+
+# This file was generated by the build system used internally in the Yandex monorepo.
+# Only simple modifications are allowed (adding source-files to targets, adding simple properties
+# like target_include_directories). These modifications will be ported to original
+# ya.make files by maintainers. Any complex modifications which can't be ported back to the
+# original buildsystem will not be accepted.
+
+
+
+add_executable(ydb-core-tx-schemeshard-ut_auditsettings)
+target_compile_options(ydb-core-tx-schemeshard-ut_auditsettings PRIVATE
+ -DUSE_CURRENT_UDF_ABI_VERSION
+)
+target_include_directories(ydb-core-tx-schemeshard-ut_auditsettings PRIVATE
+ ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard
+)
+target_link_libraries(ydb-core-tx-schemeshard-ut_auditsettings PUBLIC
+ contrib-libs-linux-headers
+ contrib-libs-cxxsupp
+ yutil
+ library-cpp-cpuid_check
+ cpp-testing-unittest_main
+ core-tx-schemeshard
+ library-cpp-getopt
+ cpp-regex-pcre
+ library-cpp-svnversion
+ core-testlib-default
+ ydb-core-tx
+ tx-schemeshard-ut_helpers
+)
+target_link_options(ydb-core-tx-schemeshard-ut_auditsettings PRIVATE
+ -ldl
+ -lrt
+ -Wl,--no-as-needed
+ -fPIC
+ -fPIC
+ -lpthread
+ -lrt
+ -ldl
+)
+target_sources(ydb-core-tx-schemeshard-ut_auditsettings PRIVATE
+ ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/ut_auditsettings/ut_auditsettings.cpp
+)
+set_property(
+ TARGET
+ ydb-core-tx-schemeshard-ut_auditsettings
+ PROPERTY
+ SPLIT_FACTOR
+ 10
+)
+add_yunittest(
+ NAME
+ ydb-core-tx-schemeshard-ut_auditsettings
+ TEST_TARGET
+ ydb-core-tx-schemeshard-ut_auditsettings
+ TEST_ARG
+ --print-before-suite
+ --print-before-test
+ --fork-tests
+ --print-times
+ --show-fails
+)
+set_yunittest_property(
+ TEST
+ ydb-core-tx-schemeshard-ut_auditsettings
+ PROPERTY
+ LABELS
+ MEDIUM
+)
+set_yunittest_property(
+ TEST
+ ydb-core-tx-schemeshard-ut_auditsettings
+ PROPERTY
+ PROCESSORS
+ 1
+)
+set_yunittest_property(
+ TEST
+ ydb-core-tx-schemeshard-ut_auditsettings
+ PROPERTY
+ TIMEOUT
+ 60
+)
+target_allocator(ydb-core-tx-schemeshard-ut_auditsettings
+ cpp-malloc-tcmalloc
+ libs-tcmalloc-no_percpu_cache
+)
+vcs_info(ydb-core-tx-schemeshard-ut_auditsettings)
diff --git a/ydb/core/tx/schemeshard/ut_auditsettings/CMakeLists.txt b/ydb/core/tx/schemeshard/ut_auditsettings/CMakeLists.txt
new file mode 100644
index 0000000000..f8b31df0c1
--- /dev/null
+++ b/ydb/core/tx/schemeshard/ut_auditsettings/CMakeLists.txt
@@ -0,0 +1,17 @@
+
+# This file was generated by the build system used internally in the Yandex monorepo.
+# Only simple modifications are allowed (adding source-files to targets, adding simple properties
+# like target_include_directories). These modifications will be ported to original
+# ya.make files by maintainers. Any complex modifications which can't be ported back to the
+# original buildsystem will not be accepted.
+
+
+if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" AND NOT HAVE_CUDA)
+ include(CMakeLists.linux-aarch64.txt)
+elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
+ include(CMakeLists.darwin-x86_64.txt)
+elseif (WIN32 AND CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" AND NOT HAVE_CUDA)
+ include(CMakeLists.windows-x86_64.txt)
+elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT HAVE_CUDA)
+ include(CMakeLists.linux-x86_64.txt)
+endif()
diff --git a/ydb/core/tx/schemeshard/ut_auditsettings/CMakeLists.windows-x86_64.txt b/ydb/core/tx/schemeshard/ut_auditsettings/CMakeLists.windows-x86_64.txt
new file mode 100644
index 0000000000..deae92b8dd
--- /dev/null
+++ b/ydb/core/tx/schemeshard/ut_auditsettings/CMakeLists.windows-x86_64.txt
@@ -0,0 +1,76 @@
+
+# This file was generated by the build system used internally in the Yandex monorepo.
+# Only simple modifications are allowed (adding source-files to targets, adding simple properties
+# like target_include_directories). These modifications will be ported to original
+# ya.make files by maintainers. Any complex modifications which can't be ported back to the
+# original buildsystem will not be accepted.
+
+
+
+add_executable(ydb-core-tx-schemeshard-ut_auditsettings)
+target_compile_options(ydb-core-tx-schemeshard-ut_auditsettings PRIVATE
+ -DUSE_CURRENT_UDF_ABI_VERSION
+)
+target_include_directories(ydb-core-tx-schemeshard-ut_auditsettings PRIVATE
+ ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard
+)
+target_link_libraries(ydb-core-tx-schemeshard-ut_auditsettings PUBLIC
+ contrib-libs-cxxsupp
+ yutil
+ library-cpp-cpuid_check
+ cpp-testing-unittest_main
+ core-tx-schemeshard
+ library-cpp-getopt
+ cpp-regex-pcre
+ library-cpp-svnversion
+ core-testlib-default
+ ydb-core-tx
+ tx-schemeshard-ut_helpers
+)
+target_sources(ydb-core-tx-schemeshard-ut_auditsettings PRIVATE
+ ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/ut_auditsettings/ut_auditsettings.cpp
+)
+set_property(
+ TARGET
+ ydb-core-tx-schemeshard-ut_auditsettings
+ PROPERTY
+ SPLIT_FACTOR
+ 10
+)
+add_yunittest(
+ NAME
+ ydb-core-tx-schemeshard-ut_auditsettings
+ TEST_TARGET
+ ydb-core-tx-schemeshard-ut_auditsettings
+ TEST_ARG
+ --print-before-suite
+ --print-before-test
+ --fork-tests
+ --print-times
+ --show-fails
+)
+set_yunittest_property(
+ TEST
+ ydb-core-tx-schemeshard-ut_auditsettings
+ PROPERTY
+ LABELS
+ MEDIUM
+)
+set_yunittest_property(
+ TEST
+ ydb-core-tx-schemeshard-ut_auditsettings
+ PROPERTY
+ PROCESSORS
+ 1
+)
+set_yunittest_property(
+ TEST
+ ydb-core-tx-schemeshard-ut_auditsettings
+ PROPERTY
+ TIMEOUT
+ 60
+)
+target_allocator(ydb-core-tx-schemeshard-ut_auditsettings
+ system_allocator
+)
+vcs_info(ydb-core-tx-schemeshard-ut_auditsettings)
diff --git a/ydb/core/tx/schemeshard/ut_auditsettings/ut_auditsettings.cpp b/ydb/core/tx/schemeshard/ut_auditsettings/ut_auditsettings.cpp
new file mode 100644
index 0000000000..ec1ac722a5
--- /dev/null
+++ b/ydb/core/tx/schemeshard/ut_auditsettings/ut_auditsettings.cpp
@@ -0,0 +1,344 @@
+#include <ydb/core/tx/schemeshard/ut_helpers/helpers.h>
+
+using namespace NKikimr;
+using namespace NSchemeShard;
+using namespace NSchemeShardUT_Private;
+
+namespace {
+
+template <class T>
+T MessageFromText(const TString& text) {
+ T msg;
+ UNIT_ASSERT_C(google::protobuf::TextFormat::ParseFromString(text, &msg), "Invalid protobuf message text");
+ return msg;
+}
+
+bool AuditSettingsCompare(TString* diff, const NKikimrSubDomains::TAuditSettings& a, const NKikimrSubDomains::TAuditSettings& b) {
+ google::protobuf::util::MessageDifferencer d;
+ d.ReportDifferencesToString(diff);
+ d.TreatAsSet(NKikimrSubDomains::TAuditSettings::GetDescriptor()->FindFieldByName("ExpectedSubjects"));
+ return d.Compare(a, b);
+}
+
+} // anonymous namespace
+
+Y_UNIT_TEST_SUITE(TSchemeShardAuditSettings) {
+
+ const std::vector<TString> CreateTestParams = {
+ R"()",
+ R"(AuditSettings { EnableDmlAudit: false })",
+ R"(AuditSettings { EnableDmlAudit: true })",
+ R"(AuditSettings { EnableDmlAudit: false ExpectedSubjects: ["A", "B"] })",
+ R"(AuditSettings { EnableDmlAudit: true ExpectedSubjects: ["A", "B"] })",
+ R"(AuditSettings { EnableDmlAudit: true ExpectedSubjects: ["A", "A"] })",
+ };
+
+ Y_UNIT_TEST(CreateExtSubdomain) {
+ TTestBasicRuntime runtime;
+ TTestEnv env(runtime);
+ ui64 txId = 100;
+
+ auto test = [&](const TStringBuf& auditSettingsFragment, const NKikimrSubDomains::TAuditSettings& expected) {
+ TestCreateExtSubDomain(runtime, ++txId, "/MyRoot", TString::Join(
+ R"(
+ Name: "USER_0"
+ )",
+ auditSettingsFragment
+ ));
+ env.TestWaitNotification(runtime, txId);
+
+ auto actual = DescribePath(runtime, "/MyRoot/USER_0")
+ .GetPathDescription()
+ .GetDomainDescription()
+ .GetAuditSettings()
+ ;
+
+ TString diff;
+ UNIT_ASSERT_C(AuditSettingsCompare(&diff, expected, actual), "FAILED for '" << auditSettingsFragment << "': " << diff);
+
+ TestForceDropExtSubDomain(runtime, ++txId, "/MyRoot", "USER_0");
+ env.TestWaitNotification(runtime, txId);
+ };
+
+ // for all variations expect returned TAuditSettings equal (or equivalent) to the original input
+ for (const auto& i : CreateTestParams) {
+ Cerr << "TEST CreateExtSubdomain, '" << i << "'" << Endl;
+ test(i, MessageFromText<NKikimrSubDomains::TDomainDescription>(i).GetAuditSettings());
+ }
+ }
+
+ Y_UNIT_TEST(CreateSubdomain) {
+ TTestBasicRuntime runtime;
+ TTestEnv env(runtime);
+ ui64 txId = 100;
+
+ auto test = [&](const TStringBuf& auditSettingsFragment, const NKikimrSubDomains::TAuditSettings& expected) {
+ TestCreateSubDomain(runtime, ++txId, "/MyRoot", TString::Join(
+ R"(
+ Name: "USER_0"
+ )",
+ auditSettingsFragment
+ ));
+ env.TestWaitNotification(runtime, txId);
+
+ auto actual = DescribePath(runtime, "/MyRoot/USER_0")
+ .GetPathDescription()
+ .GetDomainDescription()
+ .GetAuditSettings()
+ ;
+
+ TString diff;
+ UNIT_ASSERT_C(AuditSettingsCompare(&diff, expected, actual), "FAILED for '" << auditSettingsFragment << "': " << diff);
+
+ TestForceDropSubDomain(runtime, ++txId, "/MyRoot", "USER_0");
+ env.TestWaitNotification(runtime, txId);
+ };
+
+ // for all variations expect returned TAuditSettings equal (or equivalent) to the original input
+ for (const auto& i : CreateTestParams) {
+ Cerr << "TEST CreateSubdomain, '" << i << "'" << Endl;
+ test(i, MessageFromText<NKikimrSubDomains::TDomainDescription>(i).GetAuditSettings());
+ }
+ }
+
+ struct TAlterTestParam {
+ TString AtCreate;
+ TString AtAlter;
+ TString Expected;
+ };
+ std::vector<TAlterTestParam> AlterTestParams = {
+ // Alter can set AuditSettings
+ {
+ .AtCreate = R"()",
+ .AtAlter = R"()",
+ .Expected = R"()",
+ },
+ {
+ .AtCreate = R"()",
+ .AtAlter = R"(AuditSettings { EnableDmlAudit: false })",
+ .Expected = R"(AuditSettings { EnableDmlAudit: false })",
+ },
+ {
+ .AtCreate = R"()",
+ .AtAlter = R"(AuditSettings { EnableDmlAudit: true })",
+ .Expected = R"(AuditSettings { EnableDmlAudit: true })",
+ },
+ {
+ .AtCreate = R"()",
+ .AtAlter = R"(AuditSettings { EnableDmlAudit: false ExpectedSubjects: ["A", "B"] })",
+ .Expected = R"(AuditSettings { EnableDmlAudit: false ExpectedSubjects: ["A", "B"] })",
+ },
+ {
+ .AtCreate = R"()",
+ .AtAlter = R"(AuditSettings { EnableDmlAudit: true ExpectedSubjects: ["A", "B"] })",
+ .Expected = R"(AuditSettings { EnableDmlAudit: true ExpectedSubjects: ["A", "B"] })",
+ },
+ {
+ .AtCreate = R"()",
+ .AtAlter = R"(AuditSettings { EnableDmlAudit: true ExpectedSubjects: ["A", "A"] })",
+ .Expected = R"(AuditSettings { EnableDmlAudit: true ExpectedSubjects: ["A", "A"] })",
+ },
+ // Alter doesn't drop existing AuditSettings
+ {
+ .AtCreate = R"(AuditSettings { EnableDmlAudit: false })",
+ .AtAlter = R"()",
+ .Expected = R"(AuditSettings { EnableDmlAudit: false })",
+ },
+ {
+ .AtCreate = R"(AuditSettings { EnableDmlAudit: true })",
+ .AtAlter = R"()",
+ .Expected = R"(AuditSettings { EnableDmlAudit: true })",
+ },
+ {
+ .AtCreate = R"(AuditSettings { EnableDmlAudit: false ExpectedSubjects: ["A", "B"] })",
+ .AtAlter = R"()",
+ .Expected = R"(AuditSettings { EnableDmlAudit: false ExpectedSubjects: ["A", "B"] })",
+ },
+ {
+ .AtCreate = R"(AuditSettings { EnableDmlAudit: true ExpectedSubjects: ["A", "B"] })",
+ .AtAlter = R"()",
+ .Expected = R"(AuditSettings { EnableDmlAudit: true ExpectedSubjects: ["A", "B"] })",
+ },
+ // EnableDmlAudit changes independently of ExpectedSubjects
+ {
+ .AtCreate = R"(AuditSettings { EnableDmlAudit: false })",
+ .AtAlter = R"(AuditSettings { EnableDmlAudit: true })",
+ .Expected = R"(AuditSettings { EnableDmlAudit: true })",
+ },
+ {
+ .AtCreate = R"(AuditSettings { EnableDmlAudit: true })",
+ .AtAlter = R"(AuditSettings { EnableDmlAudit: false })",
+ .Expected = R"(AuditSettings { EnableDmlAudit: false })",
+ },
+ {
+ .AtCreate = R"(AuditSettings { EnableDmlAudit: false ExpectedSubjects: ["A", "B"] })",
+ .AtAlter = R"(AuditSettings { EnableDmlAudit: true })",
+ .Expected = R"(AuditSettings { EnableDmlAudit: true ExpectedSubjects: ["A", "B"] })",
+ },
+ {
+ .AtCreate = R"(AuditSettings { EnableDmlAudit: true ExpectedSubjects: ["A", "B"] })",
+ .AtAlter = R"(AuditSettings { EnableDmlAudit: false })",
+ .Expected = R"(AuditSettings { EnableDmlAudit: false ExpectedSubjects: ["A", "B"] })",
+ },
+ // ExpectedSubjects can be added independently of EnableDmlAudit
+ {
+ .AtCreate = R"(AuditSettings { EnableDmlAudit: false })",
+ .AtAlter = R"(AuditSettings { ExpectedSubjects: ["A", "B"] })",
+ .Expected = R"(AuditSettings { EnableDmlAudit: false ExpectedSubjects: ["A", "B"] })",
+ },
+ {
+ .AtCreate = R"(AuditSettings { EnableDmlAudit: true })",
+ .AtAlter = R"(AuditSettings { ExpectedSubjects: ["A", "B"] })",
+ .Expected = R"(AuditSettings { EnableDmlAudit: true ExpectedSubjects: ["A", "B"] })",
+ },
+ // ExpectedSubjects can be removed independently of EnableDmlAudit
+ {
+ .AtCreate = R"(AuditSettings { EnableDmlAudit: false ExpectedSubjects: ["A", "B"] })",
+ .AtAlter = R"(AuditSettings { ExpectedSubjects: [""] })",
+ .Expected = R"(AuditSettings { EnableDmlAudit: false })",
+ },
+ {
+ .AtCreate = R"(AuditSettings { EnableDmlAudit: true ExpectedSubjects: ["A", "B"] })",
+ .AtAlter = R"(AuditSettings { ExpectedSubjects: [""] })",
+ .Expected = R"(AuditSettings { EnableDmlAudit: true })",
+ },
+ // ExpectedSubjects can be changed independently of EnableDmlAudit
+ {
+ .AtCreate = R"(AuditSettings { EnableDmlAudit: false ExpectedSubjects: ["A", "B"] })",
+ .AtAlter = R"(AuditSettings { ExpectedSubjects: ["A"] })",
+ .Expected = R"(AuditSettings { EnableDmlAudit: false ExpectedSubjects: ["A"] })",
+ },
+ {
+ .AtCreate = R"(AuditSettings { EnableDmlAudit: true ExpectedSubjects: ["A", "B"] })",
+ .AtAlter = R"(AuditSettings { ExpectedSubjects: ["A"] })",
+ .Expected = R"(AuditSettings { EnableDmlAudit: true ExpectedSubjects: ["A"] })",
+ },
+ {
+ .AtCreate = R"(AuditSettings { EnableDmlAudit: false ExpectedSubjects: ["A"] })",
+ .AtAlter = R"(AuditSettings { ExpectedSubjects: ["A", "B"] })",
+ .Expected = R"(AuditSettings { EnableDmlAudit: false ExpectedSubjects: ["A", "B"] })",
+ },
+ {
+ .AtCreate = R"(AuditSettings { EnableDmlAudit: true ExpectedSubjects: ["A"] })",
+ .AtAlter = R"(AuditSettings { ExpectedSubjects: ["A", "B"] })",
+ .Expected = R"(AuditSettings { EnableDmlAudit: true ExpectedSubjects: ["A", "B"] })",
+ },
+ // Empty subjects are removed
+ {
+ .AtCreate = R"(AuditSettings { ExpectedSubjects: ["A"] })",
+ .AtAlter = R"(AuditSettings { ExpectedSubjects: ["", "B"] })",
+ .Expected = R"(AuditSettings { ExpectedSubjects: ["B"] })",
+ },
+ {
+ .AtCreate = R"(AuditSettings { ExpectedSubjects: ["A", "B"] })",
+ .AtAlter = R"(AuditSettings { ExpectedSubjects: ["", "", "C", ""] })",
+ .Expected = R"(AuditSettings { ExpectedSubjects: ["C"] })",
+ },
+ // EnableDmlAudit and ExpectedSubjects could be changed both
+ {
+ .AtCreate = R"(AuditSettings { EnableDmlAudit: false ExpectedSubjects: ["A", "B"] })",
+ .AtAlter = R"(AuditSettings { EnableDmlAudit: true ExpectedSubjects: ["C", "D"] })",
+ .Expected = R"(AuditSettings { EnableDmlAudit: true ExpectedSubjects: ["C", "D"] })",
+ },
+ };
+
+ Y_UNIT_TEST_FLAG(AlterExtSubdomain, ExternalSchemeShard) {
+ TTestBasicRuntime runtime;
+ TTestEnv env(runtime);
+ ui64 txId = 100;
+
+ TString externalSchemeshard;
+ if (ExternalSchemeShard) {
+ externalSchemeshard = R"(
+ ExternalSchemeShard: true
+ PlanResolution: 50
+ Coordinators: 1
+ Mediators: 1
+ TimeCastBucketsPerMediator: 2
+ StoragePools {
+ Name: "pool-1"
+ Kind: "hdd"
+ }
+ )";
+ }
+
+ auto test = [&](const TStringBuf& atCreate, const TStringBuf& atAlter, const NKikimrSubDomains::TAuditSettings& expected) {
+ TestCreateExtSubDomain(runtime, ++txId, "/MyRoot", TString::Join(
+ R"(
+ Name: "USER_0"
+ )",
+ atCreate
+ ));
+ TestAlterExtSubDomain(runtime, ++txId, "/MyRoot", TString::Join(
+ R"(
+ Name: "USER_0"
+ )",
+ externalSchemeshard,
+ atAlter
+ ));
+ env.TestWaitNotification(runtime, {txId, txId - 1});
+
+ const auto& describe = DescribePath(runtime, "/MyRoot/USER_0");
+
+ auto actual = describe.GetPathDescription().GetDomainDescription().GetAuditSettings();
+ TString diff;
+ UNIT_ASSERT_C(AuditSettingsCompare(&diff, expected, actual), "(at root) FAILED for '" << atCreate << "' + '" << atAlter << "': " << diff);
+
+ if (ExternalSchemeShard) {
+ // check auditSettings at tenant schemeshard also
+ ui64 tenantSchemeShard = describe.GetPathDescription().GetDomainDescription().GetProcessingParams().GetSchemeShard();
+ const auto& describe = DescribePath(runtime, tenantSchemeShard, "/MyRoot/USER_0");
+
+ auto actual = describe.GetPathDescription().GetDomainDescription().GetAuditSettings();
+ TString diff;
+ UNIT_ASSERT_C(AuditSettingsCompare(&diff, expected, actual), "(at tenant) FAILED for '" << atCreate << "' + '" << atAlter << "': " << diff);
+ }
+
+ TestForceDropExtSubDomain(runtime, ++txId, "/MyRoot", "USER_0");
+ env.TestWaitNotification(runtime, txId);
+ };
+
+ // for all variations match actual returned TAuditSettings to expected
+ for (const auto& [atCreate, atAlter, expected] : AlterTestParams) {
+ Cerr << "TEST AlterExtSubdomain, '" << atCreate << "' + '" << atAlter << "'" << Endl;
+ test(atCreate, atAlter, MessageFromText<NKikimrSubDomains::TDomainDescription>(expected).GetAuditSettings());
+ }
+ }
+
+ Y_UNIT_TEST(AlterSubdomain) {
+ TTestBasicRuntime runtime;
+ TTestEnv env(runtime);
+ ui64 txId = 100;
+
+ auto test = [&](const TStringBuf& atCreate, const TStringBuf& atAlter, const NKikimrSubDomains::TAuditSettings& expected) {
+ TestCreateSubDomain(runtime, ++txId, "/MyRoot", TString::Join(
+ R"(
+ Name: "USER_0"
+ )",
+ atCreate
+ ));
+ TestAlterSubDomain(runtime, ++txId, "/MyRoot", TString::Join(
+ R"(
+ Name: "USER_0"
+ )",
+ atAlter
+ ));
+ env.TestWaitNotification(runtime, {txId, txId - 1});
+
+ const auto& describe = DescribePath(runtime, "/MyRoot/USER_0");
+
+ auto actual = describe.GetPathDescription().GetDomainDescription().GetAuditSettings();
+ TString diff;
+ UNIT_ASSERT_C(AuditSettingsCompare(&diff, expected, actual), "(at root) FAILED for '" << atCreate << "' + '" << atAlter << "': " << diff);
+
+ TestForceDropSubDomain(runtime, ++txId, "/MyRoot", "USER_0");
+ env.TestWaitNotification(runtime, txId);
+ };
+
+ // for all variations match actual returned TAuditSettings to expected
+ for (const auto& [atCreate, atAlter, expected] : AlterTestParams) {
+ Cerr << "TEST AlterSubdomain, '" << atCreate << "' + '" << atAlter << "'" << Endl;
+ test(atCreate, atAlter, MessageFromText<NKikimrSubDomains::TDomainDescription>(expected).GetAuditSettings());
+ }
+ }
+}
diff --git a/ydb/core/tx/schemeshard/ut_auditsettings/ya.make b/ydb/core/tx/schemeshard/ut_auditsettings/ya.make
new file mode 100644
index 0000000000..3136e829b4
--- /dev/null
+++ b/ydb/core/tx/schemeshard/ut_auditsettings/ya.make
@@ -0,0 +1,30 @@
+UNITTEST_FOR(ydb/core/tx/schemeshard)
+
+FORK_SUBTESTS()
+
+IF (SANITIZER_TYPE OR WITH_VALGRIND)
+ TIMEOUT(3600)
+ SIZE(LARGE)
+ TAG(ya:fat)
+ELSE()
+ TIMEOUT(60)
+ SIZE(MEDIUM)
+ENDIF()
+
+PEERDIR(
+ library/cpp/getopt
+ library/cpp/regex/pcre
+ library/cpp/svnversion
+ ydb/core/testlib/default
+ ydb/core/tx
+ ydb/core/tx/schemeshard/ut_helpers
+ # ydb/library/yql/public/udf/service/exception_policy
+)
+
+YQL_LAST_ABI_VERSION()
+
+SRCS(
+ ut_auditsettings.cpp
+)
+
+END()
diff --git a/ydb/core/tx/schemeshard/ut_extsubdomain/ut_extsubdomain.cpp b/ydb/core/tx/schemeshard/ut_extsubdomain/ut_extsubdomain.cpp
index 2fe6db2a71..bf39bfe9cc 100644
--- a/ydb/core/tx/schemeshard/ut_extsubdomain/ut_extsubdomain.cpp
+++ b/ydb/core/tx/schemeshard/ut_extsubdomain/ut_extsubdomain.cpp
@@ -1489,4 +1489,4 @@ Y_UNIT_TEST_SUITE(TSchemeShardExtSubDomainTest) {
KeyColumnNames: ["key"]
)", {NKikimrScheme::StatusQuotaExceeded});
}
-}
+} \ No newline at end of file
diff --git a/ydb/core/tx/schemeshard/ya.make b/ydb/core/tx/schemeshard/ya.make
index 5f662cdef4..1240b5ce21 100644
--- a/ydb/core/tx/schemeshard/ya.make
+++ b/ydb/core/tx/schemeshard/ya.make
@@ -1,4 +1,5 @@
RECURSE_FOR_TESTS(
+ ut_auditsettings
ut_backup
ut_base
ut_base_reboots
diff --git a/ydb/tests/functional/scheme_tests/canondata/tablet_scheme_tests.TestTabletSchemes.test_tablet_schemes_flat_schemeshard_/flat_schemeshard.schema b/ydb/tests/functional/scheme_tests/canondata/tablet_scheme_tests.TestTabletSchemes.test_tablet_schemes_flat_schemeshard_/flat_schemeshard.schema
index e67b0083cd..94b09951bf 100644
--- a/ydb/tests/functional/scheme_tests/canondata/tablet_scheme_tests.TestTabletSchemes.test_tablet_schemes_flat_schemeshard_/flat_schemeshard.schema
+++ b/ydb/tests/functional/scheme_tests/canondata/tablet_scheme_tests.TestTabletSchemes.test_tablet_schemes_flat_schemeshard_/flat_schemeshard.schema
@@ -1265,11 +1265,6 @@
],
"ColumnsAdded": [
{
- "ColumnId": 29,
- "ColumnName": "ImportsLimit",
- "ColumnType": "Uint64"
- },
- {
"ColumnId": 1,
"ColumnName": "PathId",
"ColumnType": "Uint64"
@@ -1408,13 +1403,22 @@
"ColumnId": 28,
"ColumnName": "ExportsLimit",
"ColumnType": "Uint64"
+ },
+ {
+ "ColumnId": 29,
+ "ColumnName": "ImportsLimit",
+ "ColumnType": "Uint64"
+ },
+ {
+ "ColumnId": 30,
+ "ColumnName": "AuditSettings",
+ "ColumnType": "String"
}
],
"ColumnsDropped": [],
"ColumnFamilies": {
"0": {
"Columns": [
- 29,
1,
2,
3,
@@ -1442,7 +1446,9 @@
25,
26,
27,
- 28
+ 28,
+ 29,
+ 30
],
"RoomID": 0,
"Codec": 0,
@@ -2153,6 +2159,11 @@
"ColumnId": 9,
"ColumnName": "DatabaseQuotas",
"ColumnType": "String"
+ },
+ {
+ "ColumnId": 10,
+ "ColumnName": "AuditSettings",
+ "ColumnType": "String"
}
],
"ColumnsDropped": [],
@@ -2167,7 +2178,8 @@
6,
7,
8,
- 9
+ 9,
+ 10
],
"RoomID": 0,
"Codec": 0,