Skip to content

Commit 6df892b

Browse files
authored
Fix the inability to replace config on v2 (#29534)
2 parents 08c5238 + 6fceb5c commit 6df892b

File tree

4 files changed

+55
-3
lines changed

4 files changed

+55
-3
lines changed

ydb/core/blobstorage/nodewarden/distconf_console.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ namespace NKikimr::NStorage {
120120
case NKikimrBlobStorage::TEvControllerProposeConfigResponse::CommitIsNotNeeded:
121121
// it's okay, just wait for another configuration change or something like that
122122
ConfigCommittedToConsole = true;
123+
ProposedConfigHashVersion.reset();
123124
break;
124125

125126
case NKikimrBlobStorage::TEvControllerProposeConfigResponse::ReverseCommit:

ydb/core/blobstorage/nodewarden/distconf_invoke_storage_config.cpp

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,53 @@
11
#include "distconf_invoke.h"
22
#include "node_warden_impl.h"
33

4+
#include <ydb/core/config/validation/validators.h>
45
#include <ydb/core/mind/bscontroller/bsc.h>
56

7+
#include <ydb/library/yaml_config/yaml_config.h>
68
#include <ydb/library/yaml_config/yaml_config_parser.h>
79
#include <ydb/library/yaml_json/yaml_to_json.h>
810

911
namespace NKikimr::NStorage {
1012

1113
using TInvokeRequestHandlerActor = TDistributedConfigKeeper::TInvokeRequestHandlerActor;
1214

15+
namespace {
16+
static std::optional<TString> LocalYamlValidate(const TString& yaml, bool allowUnknown = true) {
17+
try {
18+
auto doc = NFyaml::TDocument::Parse(yaml);
19+
auto resolved = NYamlConfig::ResolveAll(doc);
20+
21+
TSimpleSharedPtr<NYamlConfig::TBasicUnknownFieldsCollector> unknownCollector =
22+
new NYamlConfig::TBasicUnknownFieldsCollector;
23+
24+
std::vector<TString> errors;
25+
for (auto& [_, config] : resolved.Configs) {
26+
auto appCfg = NYamlConfig::YamlToProto(
27+
config.second,
28+
true, // strict
29+
true, // merge database config (if any)
30+
unknownCollector);
31+
if (NKikimr::NConfig::ValidateConfig(appCfg, errors) == NKikimr::NConfig::EValidationResult::Error) {
32+
if (!errors.empty()) {
33+
return errors.front();
34+
} else {
35+
return TString("unknown validation error");
36+
}
37+
}
38+
}
39+
40+
if (!allowUnknown && !unknownCollector->GetUnknownKeys().empty()) {
41+
return TString("has forbidden unknown fields");
42+
}
43+
44+
return std::nullopt;
45+
} catch (const std::exception& ex) {
46+
return TString(ex.what());
47+
}
48+
}
49+
}
50+
1351
void TInvokeRequestHandlerActor::FetchStorageConfig(bool manual, bool fetchMain, bool fetchStorage) {
1452
if (!Self->StorageConfig) {
1553
FinishWithError(TResult::ERROR, "no agreed StorageConfig");
@@ -484,7 +522,15 @@ namespace NKikimr::NStorage {
484522
Y_ABORT_UNLESS(prevState == ERootState::IN_PROGRESS);
485523
return error;
486524
},
487-
[&](NKikimrBlobStorage::TStorageConfig& proposedConfig) {
525+
[&](NKikimrBlobStorage::TStorageConfig& proposedConfig) -> std::optional<TString> {
526+
// config validation, which is basically done in Console
527+
TString mainYaml;
528+
if (auto err = DecomposeConfig(proposedConfig.GetConfigComposite(), &mainYaml, /*mainConfigVersion=*/ nullptr, /*mainConfigFetchYaml=*/ nullptr)) {
529+
return TString(TStringBuilder() << "Failed to decompose composite config: " << *err);
530+
}
531+
if (auto err = LocalYamlValidate(mainYaml, /*allowUnknown=*/ true)) {
532+
return TString(TStringBuilder() << "YAML validation failed: " << *err);
533+
}
488534
StartProposition(&proposedConfig, false);
489535
return std::nullopt;
490536
}

ydb/core/blobstorage/nodewarden/ya.make

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ PEERDIR(
4646
ydb/core/blobstorage/crypto
4747
ydb/core/blobstorage/groupinfo
4848
ydb/core/blobstorage/pdisk
49+
ydb/core/config/validation
4950
ydb/core/control
5051
ydb/library/pdisk_io
5152
ydb/library/yaml_config

ydb/core/cms/console/console__replace_yaml_config.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,9 @@ class TConfigsManager::TTxReplaceMainYamlConfig
118118

119119
TUpdateConfigOpContext opCtx;
120120
Self->ReplaceMainConfigMetadata(Config, false, opCtx);
121-
Self->ValidateMainConfig(opCtx);
121+
if (!Force) {
122+
Self->ValidateMainConfig(opCtx);
123+
}
122124

123125
bool hasForbiddenUnknown = !opCtx.UnknownFields.empty() && !AllowUnknownFields;
124126
if (opCtx.Error) {
@@ -264,7 +266,9 @@ class TConfigsManager::TTxReplaceDatabaseYamlConfig
264266

265267
TUpdateDatabaseConfigOpContext opCtx;
266268
Self->ReplaceDatabaseConfigMetadata(Config, false, opCtx);
267-
Self->ValidateDatabaseConfig(opCtx);
269+
if (!Force) {
270+
Self->ValidateDatabaseConfig(opCtx);
271+
}
268272

269273
bool hasForbiddenUnknown = !opCtx.UnknownFields.empty() && !AllowUnknownFields;
270274
if (opCtx.Error) {

0 commit comments

Comments
 (0)