Skip to content

Commit 4081b1f

Browse files
authored
Add BSC/Console protocol (#12662)
1 parent f30662e commit 4081b1f

File tree

27 files changed

+1043
-171
lines changed

27 files changed

+1043
-171
lines changed

.github/config/muted_ya.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ ydb/core/kqp/ut/tx KqpSnapshotIsolation.TConflictWriteOltp
6767
ydb/core/kqp/ut/tx KqpSnapshotIsolation.TConflictWriteOltpNoSink
6868
ydb/core/kqp/ut/yql KqpScripting.StreamExecuteYqlScriptScanOperationTmeoutBruteForce
6969
ydb/core/mind/hive/ut THiveTest.TestHiveBalancerNodeRestarts
70+
ydb/core/mind/hive/ut THiveTest.TestReassignUseRelativeSpace
7071
ydb/core/persqueue/ut TPQTest.TestReadAndDeleteConsumer
7172
ydb/core/persqueue/ut [*/*] chunk chunk
7273
ydb/core/quoter/ut QuoterWithKesusTest.PrefetchCoefficient

ydb/core/base/blobstorage.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,14 @@ struct TEvBlobStorage {
841841
EvControllerGroupDecommittedNotify = 0x1003161e,
842842
EvControllerGroupDecommittedResponse = 0x1003161f,
843843
EvControllerGroupMetricsExchange = 0x10031620,
844+
EvControllerProposeConfigRequest = 0x10031621,
845+
EvControllerProposeConfigResponse = 0x10031622,
846+
EvControllerConsoleCommitRequest = 0x10031623,
847+
EvControllerConsoleCommitResponse = 0x10031624,
848+
EvControllerValidateConfigRequest = 0x10031625,
849+
EvControllerValidateConfigResponse = 0x10031626,
850+
EvControllerReplaceConfigRequest = 0x10031627,
851+
EvControllerReplaceConfigResponse = 0x10031628,
844852

845853
// BSC interface result section
846854
EvControllerNodeServiceSetUpdate = 0x10031802,
@@ -2478,6 +2486,14 @@ struct TEvBlobStorage {
24782486
struct TEvControllerGroupDecommittedResponse;
24792487
struct TEvControllerGroupMetricsExchange;
24802488
struct TEvPutVDiskToReadOnly;
2489+
struct TEvControllerProposeConfigRequest;
2490+
struct TEvControllerProposeConfigResponse;
2491+
struct TEvControllerConsoleCommitRequest;
2492+
struct TEvControllerConsoleCommitResponse;
2493+
struct TEvControllerValidateConfigRequest;
2494+
struct TEvControllerValidateConfigResponse;
2495+
struct TEvControllerReplaceConfigRequest;
2496+
struct TEvControllerReplaceConfigResponse;
24812497

24822498
struct TEvMonStreamQuery;
24832499
struct TEvMonStreamActorDeathNote;
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#pragma once
2+
#include "defs.h"
3+
4+
#include <ydb/core/base/blobstorage.h>
5+
#include <ydb/core/protos/blobstorage.pb.h>
6+
7+
namespace NKikimr {
8+
9+
struct TEvBlobStorage::TEvControllerProposeConfigRequest : TEventPB<TEvBlobStorage::TEvControllerProposeConfigRequest,
10+
NKikimrBlobStorage::TEvControllerProposeConfigRequest, TEvBlobStorage::EvControllerProposeConfigRequest> {
11+
TEvControllerProposeConfigRequest() = default;
12+
13+
TEvControllerProposeConfigRequest(const ui32 configHash, const ui32 configVersion) {
14+
Record.SetConfigHash(configHash);
15+
Record.SetConfigVersion(configVersion);
16+
}
17+
18+
TString ToString() const override {
19+
TStringStream str;
20+
str << "{TEvControllerProposeConfigRequest Record# " << Record.DebugString();
21+
str << "}";
22+
return str.Str();
23+
}
24+
};
25+
26+
struct TEvBlobStorage::TEvControllerProposeConfigResponse : TEventPB<TEvBlobStorage::TEvControllerProposeConfigResponse,
27+
NKikimrBlobStorage::TEvControllerProposeConfigResponse, TEvBlobStorage::EvControllerProposeConfigResponse> {
28+
TEvControllerProposeConfigResponse() = default;
29+
};
30+
31+
struct TEvBlobStorage::TEvControllerConsoleCommitRequest : TEventPB<TEvBlobStorage::TEvControllerConsoleCommitRequest,
32+
NKikimrBlobStorage::TEvControllerConsoleCommitRequest, TEvBlobStorage::EvControllerConsoleCommitRequest> {
33+
TEvControllerConsoleCommitRequest() = default;
34+
35+
TEvControllerConsoleCommitRequest(const TString& yamlConfig) {
36+
Record.SetYAML(yamlConfig);
37+
}
38+
39+
TString ToString() const override {
40+
TStringStream str;
41+
str << "{TEvControllerConsoleCommitRequest Record# " << Record.DebugString();
42+
str << "}";
43+
return str.Str();
44+
}
45+
};
46+
47+
struct TEvBlobStorage::TEvControllerConsoleCommitResponse : TEventPB<TEvBlobStorage::TEvControllerConsoleCommitResponse,
48+
NKikimrBlobStorage::TEvControllerConsoleCommitResponse, TEvBlobStorage::EvControllerConsoleCommitResponse> {
49+
TEvControllerConsoleCommitResponse() = default;
50+
};
51+
52+
struct TEvBlobStorage::TEvControllerValidateConfigRequest : TEventPB<TEvBlobStorage::TEvControllerValidateConfigRequest,
53+
NKikimrBlobStorage::TEvControllerValidateConfigRequest, TEvBlobStorage::EvControllerValidateConfigRequest> {
54+
TEvControllerValidateConfigRequest() = default;
55+
56+
TEvControllerValidateConfigRequest(const TString& yamlConfig) {
57+
Record.SetYAML(yamlConfig);
58+
}
59+
60+
TString ToString() const override {
61+
TStringStream str;
62+
str << "{TEvControllerValidateConfigRequest Record# " << Record.DebugString();
63+
str << "}";
64+
return str.Str();
65+
}
66+
};
67+
68+
struct TEvBlobStorage::TEvControllerValidateConfigResponse : TEventPB<TEvBlobStorage::TEvControllerValidateConfigResponse,
69+
NKikimrBlobStorage::TEvControllerValidateConfigResponse, TEvBlobStorage::EvControllerValidateConfigResponse> {
70+
TEvControllerValidateConfigResponse() = default;
71+
};
72+
73+
struct TEvBlobStorage::TEvControllerReplaceConfigRequest : TEventPB<TEvBlobStorage::TEvControllerReplaceConfigRequest,
74+
NKikimrBlobStorage::TEvControllerReplaceConfigRequest, TEvBlobStorage::EvControllerReplaceConfigRequest> {
75+
TEvControllerReplaceConfigRequest() = default;
76+
77+
TEvControllerReplaceConfigRequest(const TString& yamlConfig) {
78+
Record.SetYAML(yamlConfig);
79+
}
80+
81+
TString ToString() const override {
82+
TStringStream str;
83+
str << "{TEvControllerReplaceConfigRequest Record# " << Record.DebugString();
84+
str << "}";
85+
return str.Str();
86+
}
87+
};
88+
89+
struct TEvBlobStorage::TEvControllerReplaceConfigResponse : TEventPB<TEvBlobStorage::TEvControllerReplaceConfigResponse,
90+
NKikimrBlobStorage::TEvControllerReplaceConfigResponse, TEvBlobStorage::EvControllerReplaceConfigResponse> {
91+
TEvControllerReplaceConfigResponse() = default;
92+
};
93+
94+
}

ydb/core/cms/console/console.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,11 @@ void TConsole::ClearState()
161161
Counters->ResetCounters();
162162
}
163163

164+
void TConsole::ForwardFromPipe(TAutoPtr<IEventHandle> &ev, const TActorContext &ctx) {
165+
ev->Rewrite(ev->GetTypeRewrite(), ConfigsManager->SelfId());
166+
ctx.Send(ev.Release());
167+
}
168+
164169
void TConsole::ForwardToConfigsManager(TAutoPtr<IEventHandle> &ev, const TActorContext &ctx)
165170
{
166171
ctx.Forward(ev, ConfigsManager->SelfId());

ydb/core/cms/console/console__replace_yaml_config.cpp

Lines changed: 28 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -64,69 +64,20 @@ class TConfigsManager::TTxReplaceYamlConfig : public TTransactionBase<TConfigsMa
6464
bool Execute(TTransactionContext &txc, const TActorContext &ctx) override
6565
{
6666
NIceDb::TNiceDb db(txc.DB);
67-
67+
TValidateConfigResult result = Self->ValidateConfigAndReplaceMetadata(Config, Force, AllowUnknownFields);
68+
if (result.ErrorReason) {
69+
HandleError(result.ErrorReason.value(), ctx);
70+
return true;
71+
}
6872
try {
69-
if (!Force) {
70-
auto metadata = NYamlConfig::GetMetadata(Config);
71-
Cluster = metadata.Cluster.value_or(TString("unknown"));
72-
Version = metadata.Version.value_or(0);
73-
} else {
74-
Cluster = Self->ClusterName;
75-
Version = Self->YamlVersion;
76-
}
77-
78-
UpdatedConfig = NYamlConfig::ReplaceMetadata(Config, NYamlConfig::TMetadata{
79-
.Version = Version + 1,
80-
.Cluster = Cluster,
81-
});
82-
83-
bool hasForbiddenUnknown = false;
84-
85-
TMap<TString, std::pair<TString, TString>> deprecatedFields;
86-
TMap<TString, std::pair<TString, TString>> unknownFields;
87-
88-
if (UpdatedConfig != Self->YamlConfig || Self->YamlDropped) {
89-
Modify = true;
90-
91-
auto tree = NFyaml::TDocument::Parse(UpdatedConfig);
92-
auto resolved = NYamlConfig::ResolveAll(tree);
93-
94-
if (Self->ClusterName != Cluster) {
95-
ythrow yexception() << "ClusterName mismatch";
96-
}
97-
98-
if (Version != Self->YamlVersion) {
99-
ythrow yexception() << "Version mismatch";
100-
}
10173

102-
UnknownFieldsCollector = new NYamlConfig::TBasicUnknownFieldsCollector;
74+
Version = result.Version;
75+
UpdatedConfig = result.UpdatedConfig;
76+
Cluster = result.Cluster;
77+
Modify = result.Modify;
10378

104-
std::vector<TString> errors;
105-
for (auto& [_, config] : resolved.Configs) {
106-
auto cfg = NYamlConfig::YamlToProto(
107-
config.second,
108-
true,
109-
true,
110-
UnknownFieldsCollector);
111-
NKikimr::NConfig::EValidationResult result = NKikimr::NConfig::ValidateConfig(cfg, errors);
112-
if (result == NKikimr::NConfig::EValidationResult::Error) {
113-
ythrow yexception() << errors.front();
114-
}
115-
}
116-
117-
const auto& deprecatedPaths = NKikimrConfig::TAppConfig::GetReservedChildrenPaths();
118-
119-
for (const auto& [path, info] : UnknownFieldsCollector->GetUnknownKeys()) {
120-
if (deprecatedPaths.contains(path)) {
121-
deprecatedFields[path] = info;
122-
} else {
123-
unknownFields[path] = info;
124-
}
125-
}
126-
127-
hasForbiddenUnknown = !unknownFields.empty() && !AllowUnknownFields;
128-
129-
if (!DryRun && !hasForbiddenUnknown) {
79+
if (result.ValidationFinished) {
80+
if (!DryRun && !result.HasForbiddenUnknown) {
13081
DoInternalAudit(txc, ctx);
13182

13283
db.Table<Schema::YamlConfig>().Key(Version + 1)
@@ -143,13 +94,13 @@ class TConfigsManager::TTxReplaceYamlConfig : public TTransactionBase<TConfigsMa
14394
}
14495

14596
auto fillResponse = [&](auto& ev, auto errorLevel){
146-
for (auto& [path, info] : unknownFields) {
97+
for (auto& [path, info] : result.UnknownFields) {
14798
auto *issue = ev->Record.AddIssues();
14899
issue->set_severity(errorLevel);
149100
issue->set_message(TStringBuilder{} << "Unknown key# " << info.first << " in proto# " << info.second << " found in path# " << path);
150101
}
151102

152-
for (auto& [path, info] : deprecatedFields) {
103+
for (auto& [path, info] : result.DeprecatedFields) {
153104
auto *issue = ev->Record.AddIssues();
154105
issue->set_severity(NYql::TSeverityIds::S_WARNING);
155106
issue->set_message(TStringBuilder{} << "Deprecated key# " << info.first << " in proto# " << info.second << " found in path# " << path);
@@ -158,8 +109,7 @@ class TConfigsManager::TTxReplaceYamlConfig : public TTransactionBase<TConfigsMa
158109
Response = MakeHolder<NActors::IEventHandle>(Sender, ctx.SelfID, ev.Release());
159110
};
160111

161-
162-
if (hasForbiddenUnknown) {
112+
if (result.HasForbiddenUnknown) {
163113
Error = true;
164114
auto ev = MakeHolder<TEvConsole::TEvGenericError>();
165115
ev->Record.SetYdbStatus(Ydb::StatusIds::BAD_REQUEST);
@@ -172,18 +122,10 @@ class TConfigsManager::TTxReplaceYamlConfig : public TTransactionBase<TConfigsMa
172122
auto ev = MakeHolder<TEvConsole::TEvSetYamlConfigResponse>();
173123
fillResponse(ev, NYql::TSeverityIds::S_WARNING);
174124
}
175-
} catch (const yexception& ex) {
176-
Error = true;
177-
178-
auto ev = MakeHolder<TEvConsole::TEvGenericError>();
179-
ev->Record.SetYdbStatus(Ydb::StatusIds::BAD_REQUEST);
180-
auto *issue = ev->Record.AddIssues();
181-
issue->set_severity(NYql::TSeverityIds::S_ERROR);
182-
issue->set_message(ex.what());
183-
ErrorReason = ex.what();
184-
Response = MakeHolder<NActors::IEventHandle>(Sender, ctx.SelfID, ev.Release());
185125
}
186-
126+
catch (const yexception& ex) {
127+
HandleError(ex.what(), ctx);
128+
}
187129
return true;
188130
}
189131

@@ -225,6 +167,17 @@ class TConfigsManager::TTxReplaceYamlConfig : public TTransactionBase<TConfigsMa
225167
Self->TxProcessor->TxCompleted(this, ctx);
226168
}
227169

170+
void HandleError(const TString& error, const TActorContext& ctx) {
171+
Error = true;
172+
auto ev = MakeHolder<TEvConsole::TEvGenericError>();
173+
ev->Record.SetYdbStatus(Ydb::StatusIds::BAD_REQUEST);
174+
auto *issue = ev->Record.AddIssues();
175+
issue->set_severity(NYql::TSeverityIds::S_ERROR);
176+
issue->set_message(error);
177+
ErrorReason = error;
178+
Response = MakeHolder<NActors::IEventHandle>(Sender, ctx.SelfID, ev.Release());
179+
}
180+
228181
private:
229182
const TString Config;
230183
const TString Peer;

ydb/core/cms/console/console_configs_manager.cpp

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "http.h"
88

99
#include <ydb/core/cms/console/validators/registry.h>
10+
#include <ydb/core/config/validation/validators.h>
1011
#include <ydb/core/base/feature_flags.h>
1112

1213
#include <ydb/library/yaml_config/yaml_config.h>
@@ -67,6 +68,72 @@ bool TConfigsManager::CheckConfig(const NKikimrConsole::TConfigsConfig &config,
6768
return true;
6869
}
6970

71+
TConfigsManager::TValidateConfigResult TConfigsManager::ValidateConfigAndReplaceMetadata(const TString &config, bool force, bool allowUnknownFields) {
72+
TValidateConfigResult result;
73+
try {
74+
if (!force) {
75+
auto metadata = NYamlConfig::GetMetadata(config);
76+
result.Cluster = metadata.Cluster.value_or(TString("unknown"));
77+
result.Version = metadata.Version.value_or(0);
78+
} else {
79+
result.Cluster = ClusterName;
80+
result.Version = YamlVersion;
81+
}
82+
83+
result.UpdatedConfig = NYamlConfig::ReplaceMetadata(config, NYamlConfig::TMetadata{
84+
.Version = result.Version + 1,
85+
.Cluster = result.Cluster,
86+
});
87+
88+
result.HasForbiddenUnknown = false;
89+
if (result.UpdatedConfig != YamlConfig || YamlDropped) {
90+
result.Modify = true;
91+
92+
auto tree = NFyaml::TDocument::Parse(result.UpdatedConfig);
93+
auto resolved = NYamlConfig::ResolveAll(tree);
94+
95+
if (ClusterName != result.Cluster) {
96+
ythrow yexception() << "ClusterName mismatch";
97+
}
98+
99+
if (result.Version != YamlVersion) {
100+
ythrow yexception() << "Version mismatch";
101+
}
102+
103+
TSimpleSharedPtr<NYamlConfig::TBasicUnknownFieldsCollector> unknownFieldsCollector = new NYamlConfig::TBasicUnknownFieldsCollector;
104+
105+
std::vector<TString> errors;
106+
for (auto& [_, config] : resolved.Configs) {
107+
auto cfg = NYamlConfig::YamlToProto(
108+
config.second,
109+
true,
110+
true,
111+
unknownFieldsCollector);
112+
NKikimr::NConfig::EValidationResult result = NKikimr::NConfig::ValidateConfig(cfg, errors);
113+
if (result == NKikimr::NConfig::EValidationResult::Error) {
114+
ythrow yexception() << errors.front();
115+
}
116+
}
117+
118+
const auto& deprecatedPaths = NKikimrConfig::TAppConfig::GetReservedChildrenPaths();
119+
120+
for (const auto& [path, info] : unknownFieldsCollector->GetUnknownKeys()) {
121+
if (deprecatedPaths.contains(path)) {
122+
result.DeprecatedFields[path] = info;
123+
} else {
124+
result.UnknownFields[path] = info;
125+
}
126+
}
127+
128+
result.HasForbiddenUnknown = !result.UnknownFields.empty() && !allowUnknownFields;
129+
result.ValidationFinished = true;
130+
}
131+
} catch (const yexception &e) {
132+
result.ErrorReason = e.what();
133+
}
134+
return result;
135+
}
136+
70137
void TConfigsManager::Bootstrap(const TActorContext &ctx)
71138
{
72139
LOG_DEBUG(ctx, NKikimrServices::CMS_CONFIGS, "TConfigsManager::Bootstrap");
@@ -99,6 +166,7 @@ void TConfigsManager::Handle(TEvConsole::TEvConfigNotificationRequest::TPtr &ev,
99166
void TConfigsManager::Detach()
100167
{
101168
Send(ConfigsProvider, new TEvents::TEvPoisonPill);
169+
Send(CommitActor, new TEvents::TEvPoisonPill);
102170
PassAway();
103171
}
104172

@@ -998,4 +1066,12 @@ void TConfigsManager::HandleUnauthorized(TEvConsole::TEvSetYamlConfigRequest::TP
9981066
/* success = */ false);
9991067
}
10001068

1069+
void TConfigsManager::SendInReply(const TActorId& sender, const TActorId& icSession, std::unique_ptr<IEventBase> ev, ui64 cookie) {
1070+
auto h = std::make_unique<IEventHandle>(sender, SelfId(), ev.release(), 0, cookie);
1071+
if (icSession) {
1072+
h->Rewrite(TEvInterconnect::EvForward, icSession);
1073+
}
1074+
TActivationContext::Send(h.release());
1075+
}
1076+
10011077
} // namespace NKikimr::NConsole

0 commit comments

Comments
 (0)