aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorInnokentii Mokin <innokentii@ydb.tech>2024-03-13 15:04:44 +0300
committerGitHub <noreply@github.com>2024-03-13 15:04:44 +0300
commitd0d041c79c3419ffac59c0e4861a743fd90622ff (patch)
tree27c0ca317357d9c05d4e423a1cf1aa4187463212
parentc0a403cc6b0cd7b86a4e0760eaf47af8493e7cfc (diff)
downloadydb-d0d041c79c3419ffac59c0e4861a743fd90622ff.tar.gz
[Config Validation] add config validate command (#2680)
-rw-r--r--ydb/core/config/init/init.h5
-rw-r--r--ydb/core/config/init/init_impl.h4
-rw-r--r--ydb/core/config/init/init_noop.cpp81
-rw-r--r--ydb/core/config/init/ya.make1
-rw-r--r--ydb/core/driver_lib/cli_base/cli_cmds_db.cpp8
-rw-r--r--ydb/core/driver_lib/cli_base/cli_command.h4
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_cmds.h5
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_cmds_cms.cpp4
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_cmds_console.cpp18
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_cmds_genconfig.cpp4
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_cmds_root.cpp1
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_cmds_tablet.cpp8
-rw-r--r--ydb/core/driver_lib/cli_utils/cli_cmds_validate_config.cpp160
-rw-r--r--ydb/core/driver_lib/cli_utils/ya.make2
-rw-r--r--ydb/core/driver_lib/run/driver.h1
-rw-r--r--ydb/core/driver_lib/run/main.cpp1
-rw-r--r--ydb/public/lib/ydb_cli/common/command.cpp31
-rw-r--r--ydb/public/lib/ydb_cli/common/command.h7
18 files changed, 310 insertions, 35 deletions
diff --git a/ydb/core/config/init/init.h b/ydb/core/config/init/init.h
index 93ec4136c9..1c19c43026 100644
--- a/ydb/core/config/init/init.h
+++ b/ydb/core/config/init/init.h
@@ -179,6 +179,11 @@ std::unique_ptr<INodeBrokerClient> MakeDefaultNodeBrokerClient();
std::unique_ptr<IDynConfigClient> MakeDefaultDynConfigClient();
std::unique_ptr<IInitLogger> MakeDefaultInitLogger();
+std::unique_ptr<IMemLogInitializer> MakeNoopMemLogInitializer();
+std::unique_ptr<INodeBrokerClient> MakeNoopNodeBrokerClient();
+std::unique_ptr<IDynConfigClient> MakeNoopDynConfigClient();
+std::unique_ptr<IInitLogger> MakeNoopInitLogger();
+
std::unique_ptr<IInitialConfigurator> MakeDefaultInitialConfigurator(TInitialConfiguratorDependencies deps);
class TInitialConfigurator {
diff --git a/ydb/core/config/init/init_impl.h b/ydb/core/config/init/init_impl.h
index 70b042e45c..d92100a0b1 100644
--- a/ydb/core/config/init/init_impl.h
+++ b/ydb/core/config/init/init_impl.h
@@ -923,7 +923,7 @@ public:
Option("naming-file", TCfg::TNameserviceConfigFieldTag{});
CommonAppOptions.NodeId = CommonAppOptions.DeduceNodeId(AppConfig, Env);
- Cout << "Determined node ID: " << CommonAppOptions.NodeId << Endl;
+ Logger.Out() << "Determined node ID: " << CommonAppOptions.NodeId << Endl;
CommonAppOptions.ValidateTenant();
@@ -992,7 +992,7 @@ public:
TenantName = FillTenantPoolConfig(CommonAppOptions);
- Cout << "configured" << Endl;
+ Logger.Out() << "configured" << Endl;
FillData(CommonAppOptions);
}
diff --git a/ydb/core/config/init/init_noop.cpp b/ydb/core/config/init/init_noop.cpp
new file mode 100644
index 0000000000..9d6b653745
--- /dev/null
+++ b/ydb/core/config/init/init_noop.cpp
@@ -0,0 +1,81 @@
+#include "init.h"
+
+namespace {
+
+class TNullStream : public IOutputStream {
+ void DoWrite(const void*, size_t) override {}
+};
+
+TNullStream NullStream;
+
+} // anonymous namespace
+
+namespace NKikimr::NConfig {
+
+class TNoopInitLogger
+ : public IInitLogger
+{
+public:
+ IOutputStream& Out() const noexcept override {
+ return NullStream;
+ };
+
+ IOutputStream& Err() const noexcept override {
+ return NullStream;
+ };
+};
+
+class TNoopDynConfigClient
+ : public IDynConfigClient
+{
+public:
+ TMaybe<NKikimr::NClient::TConfigurationResult> GetConfig(
+ const TGrpcSslSettings&,
+ const TVector<TString>&,
+ const TDynConfigSettings&,
+ const IEnv&,
+ IInitLogger&) const override
+ {
+ return {};
+ };
+};
+
+class TNoopNodeBrokerClient
+ : public INodeBrokerClient
+{
+public:
+ std::unique_ptr<INodeRegistrationResult> RegisterDynamicNode(
+ const TGrpcSslSettings&,
+ const TVector<TString>&,
+ const TNodeRegistrationSettings&,
+ const IEnv&,
+ IInitLogger&) const override
+ {
+ return nullptr;
+ };
+};
+
+class TNoopMemLogInitializer
+ : public IMemLogInitializer
+{
+public:
+ void Init(const NKikimrConfig::TMemoryLogConfig&) const override {};
+};
+
+std::unique_ptr<IMemLogInitializer> MakeNoopMemLogInitializer() {
+ return std::make_unique<TNoopMemLogInitializer>();
+}
+
+std::unique_ptr<INodeBrokerClient> MakeNoopNodeBrokerClient() {
+ return std::make_unique<TNoopNodeBrokerClient>();
+}
+
+std::unique_ptr<IDynConfigClient> MakeNoopDynConfigClient() {
+ return std::make_unique<TNoopDynConfigClient>();
+}
+
+std::unique_ptr<IInitLogger> MakeNoopInitLogger() {
+ return std::make_unique<TNoopInitLogger>();
+}
+
+} // namespace NKikimr::NConfig
diff --git a/ydb/core/config/init/ya.make b/ydb/core/config/init/ya.make
index 839da3a53c..c10c6c3e36 100644
--- a/ydb/core/config/init/ya.make
+++ b/ydb/core/config/init/ya.make
@@ -3,6 +3,7 @@ LIBRARY()
SRCS(
init.h
init.cpp
+ init_noop.cpp
dummy.h
dummy.cpp
)
diff --git a/ydb/core/driver_lib/cli_base/cli_cmds_db.cpp b/ydb/core/driver_lib/cli_base/cli_cmds_db.cpp
index 5cc0385bbe..e0b2079c70 100644
--- a/ydb/core/driver_lib/cli_base/cli_cmds_db.cpp
+++ b/ydb/core/driver_lib/cli_base/cli_cmds_db.cpp
@@ -116,10 +116,10 @@ public:
}
};
-class TClientCommandSchemaExec : public TClientCommandConfig {
+class TClientCommandSchemaExec : public TClientCommandBase {
public:
TClientCommandSchemaExec()
- : TClientCommandConfig("execute", { "exec" }, "Execute schema protobuf")
+ : TClientCommandBase("execute", { "exec" }, "Execute schema protobuf")
{}
bool ReturnTxId;
@@ -1265,10 +1265,10 @@ public:
}
};
-class TClientCommandDbExec : public TClientCommandConfig {
+class TClientCommandDbExec : public TClientCommandBase {
public:
TClientCommandDbExec()
- : TClientCommandConfig("minikql", { "execute", "exec", "mkql" }, "Execute Mini-KQL query")
+ : TClientCommandBase("minikql", { "execute", "exec", "mkql" }, "Execute Mini-KQL query")
{}
TString MiniKQL;
diff --git a/ydb/core/driver_lib/cli_base/cli_command.h b/ydb/core/driver_lib/cli_base/cli_command.h
index dd50de9233..49f026ffc7 100644
--- a/ydb/core/driver_lib/cli_base/cli_command.h
+++ b/ydb/core/driver_lib/cli_base/cli_command.h
@@ -10,9 +10,9 @@ namespace NDriverClient {
using namespace NYdb::NConsoleClient;
-class TClientCommandConfig : public TClientCommand {
+class TClientCommandBase : public TClientCommand {
public:
- TClientCommandConfig(
+ TClientCommandBase(
const TString& name,
const std::initializer_list<TString>& aliases = std::initializer_list<TString>(),
const TString& description = TString()
diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds.h b/ydb/core/driver_lib/cli_utils/cli_cmds.h
index b25db5a7be..049e592f96 100644
--- a/ydb/core/driver_lib/cli_utils/cli_cmds.h
+++ b/ydb/core/driver_lib/cli_utils/cli_cmds.h
@@ -46,5 +46,10 @@ public:
TClientCommandCms();
};
+class TClientCommandConfig : public TClientCommandTree {
+public:
+ TClientCommandConfig();
+};
+
}
}
diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds_cms.cpp b/ydb/core/driver_lib/cli_utils/cli_cmds_cms.cpp
index 3206ff8b21..5f7983f16e 100644
--- a/ydb/core/driver_lib/cli_utils/cli_cmds_cms.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_cmds_cms.cpp
@@ -10,7 +10,7 @@
namespace NKikimr {
namespace NDriverClient {
-class TCmsClientCommand : public TClientCommandConfig {
+class TCmsClientCommand : public TClientCommandBase {
public:
TString Domain;
NKikimrClient::TCmsRequest Request;
@@ -18,7 +18,7 @@ public:
TCmsClientCommand(const TString &name,
const std::initializer_list<TString> &aliases,
const TString &description)
- : TClientCommandConfig(name, aliases, description)
+ : TClientCommandBase(name, aliases, description)
{
}
diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds_console.cpp b/ydb/core/driver_lib/cli_utils/cli_cmds_console.cpp
index 2a810bdd20..8388755abe 100644
--- a/ydb/core/driver_lib/cli_utils/cli_cmds_console.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_cmds_console.cpp
@@ -12,7 +12,7 @@
namespace NKikimr {
namespace NDriverClient {
-class TConsoleClientCommand : public TClientCommandConfig {
+class TConsoleClientCommand : public TClientCommandBase {
public:
TString Domain;
ui32 Retries;
@@ -21,7 +21,7 @@ public:
TConsoleClientCommand(const TString &name,
const std::initializer_list<TString> &aliases,
const TString &description)
- : TClientCommandConfig(name, aliases, description)
+ : TClientCommandBase(name, aliases, description)
, Retries(0)
{
}
@@ -348,11 +348,11 @@ public:
}
};
-class TClientCommandConvertToYaml: public TClientCommandConfig {
+class TClientCommandConvertToYaml: public TClientCommandBase {
NKikimrConsole::TConfigureRequest Request;
public:
TClientCommandConvertToYaml()
- : TClientCommandConfig("convert-to-yaml", {}, "Convert config-item to yaml format")
+ : TClientCommandBase("convert-to-yaml", {}, "Convert config-item to yaml format")
{
}
@@ -418,12 +418,12 @@ public:
}
};
-class TClientCommandConvertFromYaml: public TClientCommandConfig {
+class TClientCommandConvertFromYaml: public TClientCommandBase {
TString Request;
TString Domain;
public:
TClientCommandConvertFromYaml()
- : TClientCommandConfig("convert-from-yaml", {}, "Convert config-item from yaml format")
+ : TClientCommandBase("convert-from-yaml", {}, "Convert config-item from yaml format")
{
}
@@ -558,9 +558,9 @@ public:
}
};
-class TClientCommandConsoleConfig : public TClientCommandTree {
+class TClientCommandConsoleConfigTree : public TClientCommandTree {
public:
- TClientCommandConsoleConfig()
+ TClientCommandConsoleConfigTree()
: TClientCommandTree("config", {}, "")
{
AddCommand(std::make_unique<TClientCommandConsoleConfigGet>());
@@ -677,7 +677,7 @@ public:
TClientCommandConsole::TClientCommandConsole()
: TClientCommandTree("console", {}, "Console commands")
{
- AddCommand(std::make_unique<TClientCommandConsoleConfig>());
+ AddCommand(std::make_unique<TClientCommandConsoleConfigTree>());
AddCommand(std::make_unique<TClientCommandConsoleConfigs>());
AddCommand(std::make_unique<TClientCommandConsoleExecute>());
AddCommand(std::make_unique<TClientCommandConsoleValidator>());
diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds_genconfig.cpp b/ydb/core/driver_lib/cli_utils/cli_cmds_genconfig.cpp
index 7bab00d10f..0e111f274b 100644
--- a/ydb/core/driver_lib/cli_utils/cli_cmds_genconfig.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_cmds_genconfig.cpp
@@ -10,7 +10,7 @@
namespace NKikimr {
namespace NDriverClient {
-class TClientCommandGenConfigStatic : public TClientCommandConfig {
+class TClientCommandGenConfigStatic : public TClientCommandBase {
TString ErasureList;
TString ErasureStr;
@@ -86,7 +86,7 @@ class TClientCommandGenConfigStatic : public TClientCommandConfig {
public:
TClientCommandGenConfigStatic()
- : TClientCommandConfig("static", {}, "Generate configuration for static group")
+ : TClientCommandBase("static", {}, "Generate configuration for static group")
{
TStringStream erasureList("{");
for (ui32 species = 0; species < TBlobStorageGroupType::ErasureSpeciesCount; ++species) {
diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds_root.cpp b/ydb/core/driver_lib/cli_utils/cli_cmds_root.cpp
index eb3777cb6f..b782e638c4 100644
--- a/ydb/core/driver_lib/cli_utils/cli_cmds_root.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_cmds_root.cpp
@@ -26,6 +26,7 @@ public:
AddCommand(std::make_unique<TClientCommandWhoAmI>());
AddCommand(std::make_unique<TClientCommandDiscovery>());
AddClientCommandServer(*this, std::move(factories));
+ AddCommand(std::make_unique<TClientCommandConfig>());
}
void Config(TConfig& config) override {
diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds_tablet.cpp b/ydb/core/driver_lib/cli_utils/cli_cmds_tablet.cpp
index 28b686b61c..252bb38aa8 100644
--- a/ydb/core/driver_lib/cli_utils/cli_cmds_tablet.cpp
+++ b/ydb/core/driver_lib/cli_utils/cli_cmds_tablet.cpp
@@ -6,10 +6,10 @@
namespace NKikimr {
namespace NDriverClient {
-class TClientCommandKeyValueRequest : public TClientCommandConfig {
+class TClientCommandKeyValueRequest : public TClientCommandBase {
public:
TClientCommandKeyValueRequest()
- : TClientCommandConfig("request", { "req" }, "Request to KV tablet")
+ : TClientCommandBase("request", { "req" }, "Request to KV tablet")
{}
TString ProtoBuf;
@@ -83,10 +83,10 @@ public:
}
};
-class TClientCommandTabletExec : public TClientCommandConfig {
+class TClientCommandTabletExec : public TClientCommandBase {
public:
TClientCommandTabletExec()
- : TClientCommandConfig("execute", { "exec" })
+ : TClientCommandBase("execute", { "exec" })
{
}
diff --git a/ydb/core/driver_lib/cli_utils/cli_cmds_validate_config.cpp b/ydb/core/driver_lib/cli_utils/cli_cmds_validate_config.cpp
new file mode 100644
index 0000000000..f1a1c108db
--- /dev/null
+++ b/ydb/core/driver_lib/cli_utils/cli_cmds_validate_config.cpp
@@ -0,0 +1,160 @@
+#include "cli_cmds.h"
+
+#include <ydb/core/config/init/init.h>
+#include <ydb/core/config/validation/validators.h>
+
+namespace NKikimr::NDriverClient {
+
+NKikimrConfig::TAppConfig TransformConfig(const std::vector<TString>& args) {
+ auto errorCollector = NConfig::MakeDefaultErrorCollector();
+ auto protoConfigFileProvider = NConfig::MakeDefaultProtoConfigFileProvider();
+ auto configUpdateTracer = NConfig::MakeDefaultConfigUpdateTracer();
+ auto memLogInit = NConfig::MakeNoopMemLogInitializer();
+ auto nodeBrokerClient = NConfig::MakeNoopNodeBrokerClient();
+ auto dynConfigClient = NConfig::MakeNoopDynConfigClient();
+ auto env = NConfig::MakeDefaultEnv();
+ auto logger = NConfig::MakeNoopInitLogger();
+
+ NConfig::TInitialConfiguratorDependencies deps{
+ *errorCollector,
+ *protoConfigFileProvider,
+ *configUpdateTracer,
+ *memLogInit,
+ *nodeBrokerClient,
+ *dynConfigClient,
+ *env,
+ *logger,
+ };
+
+ auto initCfg = NConfig::MakeDefaultInitialConfigurator(deps);
+
+ std::vector<const char*> argv;
+
+ for (const auto& arg : args) {
+ argv.push_back(arg.data());
+ }
+
+ NLastGetopt::TOpts opts;
+ initCfg->RegisterCliOptions(opts);
+ protoConfigFileProvider->RegisterCliOptions(opts);
+
+ NLastGetopt::TOptsParseResult parseResult(&opts, argv.size(), argv.data());
+
+ initCfg->ValidateOptions(opts, parseResult);
+ initCfg->Parse(parseResult.GetFreeArgs());
+
+ NKikimrConfig::TAppConfig appConfig;
+ ui32 nodeId;
+ TKikimrScopeId scopeId;
+ TString tenantName;
+ TBasicKikimrServicesMask servicesMask;
+ TMap<TString, TString> labels;
+ TString clusterName;
+ NKikimrConfig::TAppConfig initialCmsConfig;
+ NKikimrConfig::TAppConfig initialCmsYamlConfig;
+ THashMap<ui32, TConfigItemInfo> configInitInfo;
+
+ initCfg->Apply(
+ appConfig,
+ nodeId,
+ scopeId,
+ tenantName,
+ servicesMask,
+ labels,
+ clusterName,
+ initialCmsConfig,
+ initialCmsYamlConfig,
+ configInitInfo);
+
+ return appConfig;
+}
+
+void PreFillArgs(std::vector<TString>& args) {
+ args.push_back("server");
+
+ args.push_back("--node");
+ args.push_back("1");
+
+ args.push_back("--grpc-port");
+ args.push_back("2135");
+
+ args.push_back("--grpc-port");
+ args.push_back("9001");
+
+ args.push_back("--mon-port");
+ args.push_back("8765");
+}
+
+int ValidateConfigs(const std::vector<TString>& argsCurrent, const std::vector<TString>& argsCandidate) {
+ auto currentConfig = TransformConfig(argsCurrent);
+ auto candidateConfig = TransformConfig(argsCandidate);
+
+ std::vector<TString> msgs;
+ auto res = NConfig::ValidateStaticGroup(currentConfig, candidateConfig, msgs);
+
+ if (res == NConfig::EValidationResult::Warn) {
+ for (const auto& msg : msgs) {
+ Cerr << "Warning: " << msg << Endl;
+ }
+
+ return 2;
+ }
+
+ if (res == NConfig::EValidationResult::Error) {
+ for (const auto& msg : msgs) {
+ Cerr << "Error: " << msg << Endl;
+ }
+
+ return 1;
+ }
+
+ Cerr << "OK" << Endl;
+
+ return 0;
+}
+
+class TClientCommandValidateConfig : public TClientCommand {
+public:
+ TClientCommandValidateConfig()
+ : TClientCommand("validate", {}, "Config validation utils")
+ {}
+
+ void Config(TConfig& config) override {
+ TClientCommand::Config(config);
+
+ config.Opts->AddLongOption("current", "Current config")
+ .Required()
+ .RequiredArgument("PATH")
+ .StoreResult(&CurrentConfig);
+
+ config.Opts->AddLongOption("candidate", "Candidate config")
+ .Required()
+ .RequiredArgument("PATH")
+ .StoreResult(&CandidateConfig);
+ }
+
+ int Run(TConfig& /*config*/) override {
+ std::vector<TString> argsCurrent;
+ PreFillArgs(argsCurrent);
+ argsCurrent.push_back("--yaml-config");
+ argsCurrent.push_back(CurrentConfig);
+
+ std::vector<TString> argsCandidate;
+ PreFillArgs(argsCandidate);
+ argsCandidate.push_back("--yaml-config");
+ argsCandidate.push_back(CandidateConfig);
+
+ return ValidateConfigs(argsCurrent, argsCandidate);
+ }
+private:
+ TString CurrentConfig;
+ TString CandidateConfig;
+};
+
+TClientCommandConfig::TClientCommandConfig()
+ : TClientCommandTree("config", {}, "config utils")
+{
+ AddCommand(std::make_unique<TClientCommandValidateConfig>());
+}
+
+} // NKikimr::NDriverClient
diff --git a/ydb/core/driver_lib/cli_utils/ya.make b/ydb/core/driver_lib/cli_utils/ya.make
index c75f2845d9..fbcd8f7681 100644
--- a/ydb/core/driver_lib/cli_utils/ya.make
+++ b/ydb/core/driver_lib/cli_utils/ya.make
@@ -12,6 +12,7 @@ SRCS(
cli_cmds_cms.cpp
cli_cmds_config.cpp
cli_cmds_console.cpp
+ cli_cmds_validate_config.cpp
cli_cmds_debug.cpp
cli_cmds_disk.cpp
cli_cmds_genconfig.cpp
@@ -43,6 +44,7 @@ PEERDIR(
ydb/core/client/minikql_compile
ydb/core/client/scheme_cache_lib
ydb/core/config/init
+ ydb/core/config/validation
ydb/core/driver_lib/cli_base
ydb/core/engine
ydb/core/erasure
diff --git a/ydb/core/driver_lib/run/driver.h b/ydb/core/driver_lib/run/driver.h
index 15195f74a6..925215bdd3 100644
--- a/ydb/core/driver_lib/run/driver.h
+++ b/ydb/core/driver_lib/run/driver.h
@@ -16,6 +16,7 @@ namespace NKikimr {
#define MODE_MAP(XX) \
XX(EDM_RUN, "run", "run kikimr node") \
XX(EDM_SERVER, "server", "run kikimr node") \
+ XX(EDM_CONFIG, "config", "config utils") \
XX(EDM_ADMIN, "admin", "admin running kikimr") \
XX(EDM_DB, "db", "admin running kikimr") \
XX(EDM_TABLET, "tablet", "admin running kikimr") \
diff --git a/ydb/core/driver_lib/run/main.cpp b/ydb/core/driver_lib/run/main.cpp
index df4f8dd8e8..b9fc7b10a4 100644
--- a/ydb/core/driver_lib/run/main.cpp
+++ b/ydb/core/driver_lib/run/main.cpp
@@ -144,6 +144,7 @@ int MainRun(const TKikimrRunConfig& runConfig, std::shared_ptr<TModuleFactories>
case EDM_CMS:
case EDM_DISCOVERY:
case EDM_WHOAMI:
+ case EDM_CONFIG:
return NDriverClient::NewClient(argc + freeArgsPos, argv - freeArgsPos, factories);
case EDM_FORMAT_INFO:
return MainFormatInfo(cmdConf, argc, argv);
diff --git a/ydb/public/lib/ydb_cli/common/command.cpp b/ydb/public/lib/ydb_cli/common/command.cpp
index 8fc45859a9..7a499de82c 100644
--- a/ydb/public/lib/ydb_cli/common/command.cpp
+++ b/ydb/public/lib/ydb_cli/common/command.cpp
@@ -87,12 +87,17 @@ namespace {
}
}
-TClientCommand::TClientCommand(const TString& name, const std::initializer_list<TString>& aliases, const TString& description)
- : Name(name)
- , Aliases(aliases)
- , Description(description)
- , Parent(nullptr)
- , Opts(NLastGetopt::TOpts::Default())
+TClientCommand::TClientCommand(
+ const TString& name,
+ const std::initializer_list<TString>& aliases,
+ const TString& description,
+ bool visible)
+ : Name(name)
+ , Aliases(aliases)
+ , Description(description)
+ , Visible(visible)
+ , Parent(nullptr)
+ , Opts(NLastGetopt::TOpts::Default())
{
HideOption("svnrevision");
Opts.AddHelpOption('h');
@@ -398,9 +403,17 @@ void TClientCommandTree::RenderCommandsDescription(
const NColorizer::TColors& colors
) {
TClientCommand::RenderOneCommandDescription(stream, colors, BEGIN);
- for (auto it = SubCommands.begin(); it != SubCommands.end(); ++it) {
- bool lastCommand = (std::next(it) == SubCommands.end());
- it->second->RenderOneCommandDescription(stream, colors, lastCommand ? END : MIDDLE);
+
+ TVector<TClientCommand*> VisibleSubCommands;
+ for (auto& [_, command] : SubCommands) {
+ if (command->Visible) {
+ VisibleSubCommands.push_back(command.get());
+ }
+ }
+
+ for (auto it = VisibleSubCommands.begin(); it != VisibleSubCommands.end(); ++it) {
+ bool lastCommand = (std::next(it) == VisibleSubCommands.end());
+ (*it)->RenderOneCommandDescription(stream, colors, lastCommand ? END : MIDDLE);
}
}
diff --git a/ydb/public/lib/ydb_cli/common/command.h b/ydb/public/lib/ydb_cli/common/command.h
index ed06e376c5..fb8b4692bb 100644
--- a/ydb/public/lib/ydb_cli/common/command.h
+++ b/ydb/public/lib/ydb_cli/common/command.h
@@ -23,12 +23,17 @@ public:
TString Name;
TVector<TString> Aliases;
TString Description;
+ bool Visible = true;
const TClientCommand* Parent;
NLastGetopt::TOpts Opts;
TString Argument;
TMap<ui32, TString> Args;
- TClientCommand(const TString& name, const std::initializer_list<TString>& aliases = std::initializer_list<TString>(), const TString& description = TString());
+ TClientCommand(
+ const TString& name,
+ const std::initializer_list<TString>& aliases = std::initializer_list<TString>(),
+ const TString& description = TString(),
+ bool visible = true);
class TConfig {
struct TCommandInfo {