aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlnaz Nizametdinov <ilnaz@ydb.tech>2025-02-19 02:38:38 +0300
committerGitHub <noreply@github.com>2025-02-18 23:38:38 +0000
commit0402fc0225de7587fb71303b66a54f2716820e96 (patch)
treef908208240b343b17ae859b02122bbc48f33c925
parenta48e9482272a322871b01f751ec853fd5efaf60f (diff)
downloadydb-0402fc0225de7587fb71303b66a54f2716820e96.tar.gz
Mark options that are allowed to be used in the database configuration (#14761)
-rw-r--r--ydb/core/cms/console/console_configs_manager.cpp22
-rw-r--r--ydb/core/config/protos/marker.proto3
-rw-r--r--ydb/core/config/validation/validators.cpp36
-rw-r--r--ydb/core/config/validation/validators.h4
-rw-r--r--ydb/core/config/validation/validators_ut.cpp25
-rw-r--r--ydb/core/config/validation/ya.make1
-rw-r--r--ydb/core/protos/config.proto4
7 files changed, 90 insertions, 5 deletions
diff --git a/ydb/core/cms/console/console_configs_manager.cpp b/ydb/core/cms/console/console_configs_manager.cpp
index dab31011e1..6c0ffa9ee1 100644
--- a/ydb/core/cms/console/console_configs_manager.cpp
+++ b/ydb/core/cms/console/console_configs_manager.cpp
@@ -148,14 +148,30 @@ void TConfigsManager::ValidateDatabaseConfig(TUpdateDatabaseConfigOpContext& opC
currentConfig = it->second.Config;
}
if (opCtx.UpdatedConfig != currentConfig) {
- auto tree = NFyaml::TDocument::Parse(MainYamlConfig);
auto databaseTree = NFyaml::TDocument::Parse(opCtx.UpdatedConfig);
- NYamlConfig::AppendDatabaseConfig(tree, databaseTree);
- auto resolved = NYamlConfig::ResolveAll(tree);
+ auto databaseConfig = NYamlConfig::ParseConfig(databaseTree);
TSimpleSharedPtr<NYamlConfig::TBasicUnknownFieldsCollector> unknownFieldsCollector = new NYamlConfig::TBasicUnknownFieldsCollector;
+ auto databaseCfg = NYamlConfig::YamlToProto(
+ databaseConfig.Config,
+ true,
+ false,
+ unknownFieldsCollector);
+
std::vector<TString> errors;
+ NKikimr::NConfig::EValidationResult result = NKikimr::NConfig::ValidateDatabaseConfig(databaseCfg, errors);
+ if (result == NKikimr::NConfig::EValidationResult::Error) {
+ ythrow yexception() << errors.front();
+ }
+
+ // TODO: validate databaseConfig.AllowedLabels & databaseConfig.Selectors too
+
+ auto tree = NFyaml::TDocument::Parse(MainYamlConfig);
+ NYamlConfig::AppendDatabaseConfig(tree, databaseTree);
+ auto resolved = NYamlConfig::ResolveAll(tree);
+
+ errors.clear();
for (auto& [_, config] : resolved.Configs) {
auto cfg = NYamlConfig::YamlToProto(
config.second,
diff --git a/ydb/core/config/protos/marker.proto b/ydb/core/config/protos/marker.proto
index 5397d46962..55f30a4aa5 100644
--- a/ydb/core/config/protos/marker.proto
+++ b/ydb/core/config/protos/marker.proto
@@ -50,5 +50,8 @@ extend google.protobuf.FieldOptions {
repeated string CopyTo = 82001;
repeated string AsMap = 82002;
repeated TAdvancedCopyTo AdvancedCopyTo = 82003;
+
+ // **Top-level** options marked with that label are allowed to be used in the database configuration.
+ optional bool AllowInDatabaseConfig = 82004;
}
diff --git a/ydb/core/config/validation/validators.cpp b/ydb/core/config/validation/validators.cpp
index 2f805e6cf0..33c6c34e2b 100644
--- a/ydb/core/config/validation/validators.cpp
+++ b/ydb/core/config/validation/validators.cpp
@@ -1,8 +1,13 @@
#include "validators.h"
+#include <ydb/core/config/protos/marker.pb.h>
#include <ydb/core/protos/blobstorage.pb.h>
#include <ydb/core/protos/blobstorage_disk.pb.h>
+#include <library/cpp/protobuf/json/util.h>
+
+#include <util/string/builder.h>
+
#include <map>
#include <set>
@@ -161,6 +166,37 @@ EValidationResult ValidateStaticGroup(const NKikimrConfig::TAppConfig& current,
return EValidationResult::Ok;
}
+EValidationResult ValidateDatabaseConfig(const NKikimrConfig::TAppConfig& config, std::vector<TString>& msg) {
+ const auto* desc = config.GetDescriptor();
+ const auto* reflection = config.GetReflection();
+
+ for (int i = 0; i < desc->field_count(); i++) {
+ const auto* field = desc->field(i);
+
+ if (field->options().GetExtension(NKikimrConfig::NMarkers::AllowInDatabaseConfig)) {
+ continue;
+ }
+
+ if (!field->is_repeated()) {
+ if (!reflection->HasField(config, field)) {
+ continue;
+ }
+ } else {
+ if (!reflection->FieldSize(config, field)) {
+ continue;
+ }
+ }
+
+ auto fieldName = field->name();
+ NProtobufJson::ToSnakeCaseDense(&fieldName);
+ msg.push_back(TStringBuilder() << "'" << fieldName << "' "
+ << "is not allowed to be used in the database configuration");
+ return EValidationResult::Error;
+ }
+
+ return EValidationResult::Ok;
+}
+
EValidationResult ValidateConfig(const NKikimrConfig::TAppConfig& config, std::vector<TString>& msg) {
if (config.HasAuthConfig()) {
NKikimr::NConfig::EValidationResult result = NKikimr::NConfig::ValidateAuthConfig(config.GetAuthConfig(), msg);
diff --git a/ydb/core/config/validation/validators.h b/ydb/core/config/validation/validators.h
index 677dfb462a..6ae27342b9 100644
--- a/ydb/core/config/validation/validators.h
+++ b/ydb/core/config/validation/validators.h
@@ -46,6 +46,10 @@ EValidationResult ValidateColumnShardConfig(
const NKikimrConfig::TColumnShardConfig& columnShardConfig,
std::vector<TString>& msg);
+EValidationResult ValidateDatabaseConfig(
+ const NKikimrConfig::TAppConfig& config,
+ std::vector<TString>& msg);
+
EValidationResult ValidateConfig(
const NKikimrConfig::TAppConfig& config,
std::vector<TString>& msg);
diff --git a/ydb/core/config/validation/validators_ut.cpp b/ydb/core/config/validation/validators_ut.cpp
index 2d6bb566a9..8a97c4125b 100644
--- a/ydb/core/config/validation/validators_ut.cpp
+++ b/ydb/core/config/validation/validators_ut.cpp
@@ -2,6 +2,8 @@
#include <ydb/core/protos/blobstorage.pb.h>
#include <ydb/core/protos/blobstorage_disk.pb.h>
+#include <ydb/core/protos/feature_flags.pb.h>
+#include <ydb/core/protos/table_service_config.pb.h>
#include <library/cpp/testing/unittest/registar.h>
@@ -406,3 +408,26 @@ Y_UNIT_TEST_SUITE(ConfigValidation) {
UNIT_ASSERT_EQUAL(res, EValidationResult::Error);
}
}
+
+Y_UNIT_TEST_SUITE(DatabaseConfigValidation) {
+ Y_UNIT_TEST(AllowedFields) {
+ NKikimrConfig::TAppConfig config;
+ config.MutableFeatureFlags()->SetEnablePgSyntax(true);
+ config.MutableTableServiceConfig()->SetEnableStreamWrite(true);
+
+ std::vector<TString> err;
+ auto res = ValidateDatabaseConfig(config, err);
+ UNIT_ASSERT_VALUES_EQUAL(err.size(), 0);
+ UNIT_ASSERT_EQUAL(res, EValidationResult::Ok);
+ }
+
+ Y_UNIT_TEST(NotAllowedFields) {
+ auto [config, _] = PrepareStaticStorageTest();
+
+ std::vector<TString> err;
+ auto res = ValidateDatabaseConfig(config, err);
+ UNIT_ASSERT_VALUES_EQUAL(err.size(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(err[0], "'blob_storage_config' is not allowed to be used in the database configuration");
+ UNIT_ASSERT_EQUAL(res, EValidationResult::Error);
+ }
+}
diff --git a/ydb/core/config/validation/ya.make b/ydb/core/config/validation/ya.make
index 3616418960..87a8666f82 100644
--- a/ydb/core/config/validation/ya.make
+++ b/ydb/core/config/validation/ya.make
@@ -10,6 +10,7 @@ SRCS(
PEERDIR(
ydb/core/protos
ydb/core/formats/arrow/serializer
+ library/cpp/protobuf/json
)
END()
diff --git a/ydb/core/protos/config.proto b/ydb/core/protos/config.proto
index d17eeaa8bc..92b4c57401 100644
--- a/ydb/core/protos/config.proto
+++ b/ydb/core/protos/config.proto
@@ -2173,7 +2173,7 @@ message TAppConfig {
//optional TLocalConfig LocalConfig = 23; DEPRECATED
optional TDynamicNodeConfig DynamicNodeConfig = 24;
optional NKikimrCms.TCmsConfig CmsConfig = 25;
- optional TFeatureFlags FeatureFlags = 26;
+ optional TFeatureFlags FeatureFlags = 26 [(NMarkers.AllowInDatabaseConfig) = true];
optional TSqsConfig SqsConfig = 27;
optional NKikimrPQ.TPQConfig PQConfig = 28;
optional NKikimrTenantPool.TTenantPoolConfig TenantPoolConfig = 29;
@@ -2184,7 +2184,7 @@ message TAppConfig {
optional NKikimrProto.TKeyConfig KeyConfig = 35;
optional NKikimrProto.TKeyConfig PDiskKeyConfig = 51;
optional NKikimrNodeBroker.TConfig NodeBrokerConfig = 36;
- optional TTableServiceConfig TableServiceConfig = 37;
+ optional TTableServiceConfig TableServiceConfig = 37 [(NMarkers.AllowInDatabaseConfig) = true];
optional NKikimrSharedCache.TSharedCacheConfig SharedCacheConfig = 38; // dynamic configuration via cms
optional TImmediateControlsConfig ImmediateControlsConfig = 39;
optional TAllocatorConfig AllocatorConfig = 40;