mirror of https://github.com/Icinga/icinga2.git
CLI framework: Add support for unrecognized parameters
Required for feature enable command for example. fixes #7371
This commit is contained in:
parent
15bd96aa9a
commit
3513d1f2f9
|
@ -121,7 +121,7 @@ int Main(void)
|
|||
|
||||
LogSeverity logLevel = Logger::GetConsoleLogSeverity();
|
||||
Logger::SetConsoleLogSeverity(LogWarning);
|
||||
|
||||
|
||||
Utility::LoadExtensionLibrary("cli");
|
||||
|
||||
po::options_description visibleDesc("Global options");
|
||||
|
@ -138,13 +138,14 @@ int Main(void)
|
|||
|
||||
hiddenDesc.add_options()
|
||||
("no-stack-rlimit", "used internally, do not specify manually");
|
||||
|
||||
|
||||
String cmdname;
|
||||
CLICommand::Ptr command;
|
||||
po::variables_map vm;
|
||||
std::vector<std::string> ap;
|
||||
|
||||
try {
|
||||
CLICommand::ParseCommand(argc, argv, visibleDesc, hiddenDesc, vm, cmdname, command, autocomplete);
|
||||
CLICommand::ParseCommand(argc, argv, visibleDesc, hiddenDesc, vm, ap, cmdname, command, autocomplete);
|
||||
} catch (const std::exception& ex) {
|
||||
std::ostringstream msgbuf;
|
||||
msgbuf << "Error while parsing command-line options: " << ex.what();
|
||||
|
@ -158,7 +159,7 @@ int Main(void)
|
|||
ConfigCompilerContext::GetInstance()->Reset();
|
||||
ConfigCompiler::CompileFile(initconfig);
|
||||
}
|
||||
|
||||
|
||||
if (vm.count("define")) {
|
||||
BOOST_FOREACH(const String& define, vm["define"].as<std::vector<std::string> >()) {
|
||||
String key, value;
|
||||
|
@ -201,7 +202,7 @@ int Main(void)
|
|||
Log(LogCritical, "cli", msgbuf.str());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
if (setgid(gr->gr_gid) < 0) {
|
||||
std::ostringstream msgbuf;
|
||||
msgbuf << "setgid() failed with error code " << errno << ", \"" << Utility::FormatErrorNumber(errno) << "\"";
|
||||
|
@ -237,7 +238,7 @@ int Main(void)
|
|||
Log(LogCritical, "cli", msgbuf.str());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
if (setuid(pw->pw_uid) < 0) {
|
||||
std::ostringstream msgbuf;
|
||||
msgbuf << "setuid() failed with error code " << errno << ", \"" << Utility::FormatErrorNumber(errno) << "\"";
|
||||
|
@ -258,13 +259,13 @@ int Main(void)
|
|||
ConfigCompiler::AddIncludeSearchDir(includePath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Logger::SetConsoleLogSeverity(logLevel);
|
||||
|
||||
if (!autocomplete) {
|
||||
if (vm.count("log-level")) {
|
||||
String severity = vm["log-level"].as<std::string>();
|
||||
|
||||
|
||||
LogSeverity logLevel = LogInformation;
|
||||
try {
|
||||
logLevel = Logger::StringToSeverity(severity);
|
||||
|
@ -272,42 +273,42 @@ int Main(void)
|
|||
/* use the default */
|
||||
Log(LogWarning, "icinga", "Invalid log level set. Using default 'information'.");
|
||||
}
|
||||
|
||||
|
||||
Logger::SetConsoleLogSeverity(logLevel);
|
||||
}
|
||||
|
||||
|
||||
if (vm.count("library")) {
|
||||
BOOST_FOREACH(const String& libraryName, vm["library"].as<std::vector<std::string> >()) {
|
||||
(void)Utility::LoadExtensionLibrary(libraryName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!command || vm.count("help") || vm.count("version")) {
|
||||
String appName = Utility::BaseName(Application::GetArgV()[0]);
|
||||
|
||||
|
||||
if (appName.GetLength() > 3 && appName.SubStr(0, 3) == "lt-")
|
||||
appName = appName.SubStr(3, appName.GetLength() - 3);
|
||||
|
||||
|
||||
std::cout << appName << " " << "- The Icinga 2 network monitoring daemon.";
|
||||
|
||||
|
||||
if (!command || vm.count("help")) {
|
||||
std::cout << std::endl << std::endl
|
||||
<< "Usage:" << std::endl
|
||||
<< " " << argv[0] << " ";
|
||||
|
||||
|
||||
if (cmdname.IsEmpty())
|
||||
std::cout << "<command>";
|
||||
else
|
||||
std::cout << cmdname;
|
||||
|
||||
|
||||
std::cout << " [<arguments>]";
|
||||
|
||||
|
||||
if (command) {
|
||||
std::cout << std::endl << std::endl
|
||||
<< command->GetDescription();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (vm.count("version")) {
|
||||
std::cout << " (Version: " << Application::GetVersion() << ")";
|
||||
std::cout << std::endl
|
||||
|
@ -316,24 +317,24 @@ int Main(void)
|
|||
<< "This is free software: you are free to change and redistribute it." << std::endl
|
||||
<< "There is NO WARRANTY, to the extent permitted by law.";
|
||||
}
|
||||
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
|
||||
if (vm.count("version")) {
|
||||
std::cout << std::endl;
|
||||
|
||||
|
||||
Application::DisplayInfoMessage(true);
|
||||
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!command || vm.count("help")) {
|
||||
if (!command) {
|
||||
std::cout << std::endl;
|
||||
CLICommand::ShowCommands(argc, argv, NULL);
|
||||
}
|
||||
|
||||
|
||||
std::cout << std::endl
|
||||
<< visibleDesc << std::endl
|
||||
<< "Report bugs at <https://dev.icinga.org/>" << std::endl
|
||||
|
@ -348,7 +349,7 @@ int Main(void)
|
|||
CLICommand::ShowCommands(argc, argv, &visibleDesc, &hiddenDesc, true, autoindex);
|
||||
rc = 0;
|
||||
} else if (command)
|
||||
rc = command->Run(vm);
|
||||
rc = command->Run(vm, ap);
|
||||
|
||||
#ifndef _DEBUG
|
||||
Application::Exit(rc);
|
||||
|
|
|
@ -65,7 +65,8 @@ RegisterCLICommandHelper::RegisterCLICommandHelper(const String& name, const CLI
|
|||
|
||||
bool CLICommand::ParseCommand(int argc, char **argv, po::options_description& visibleDesc,
|
||||
po::options_description& hiddenDesc, po::variables_map& vm,
|
||||
String& cmdname, CLICommand::Ptr& command, bool autocomplete)
|
||||
std::vector<std::string>& ap, String& cmdname,
|
||||
CLICommand::Ptr& command, bool autocomplete)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(l_RegistryMutex);
|
||||
|
||||
|
@ -85,10 +86,10 @@ bool CLICommand::ParseCommand(int argc, char **argv, po::options_description& vi
|
|||
|
||||
if (vname[i] != argv[k])
|
||||
break;
|
||||
|
||||
|
||||
if (i >= best_match.size())
|
||||
best_match.push_back(vname[i]);
|
||||
|
||||
|
||||
if (i == vname.size() - 1) {
|
||||
cmdname = boost::algorithm::join(vname, " ");
|
||||
command = kv.second;
|
||||
|
@ -97,13 +98,13 @@ bool CLICommand::ParseCommand(int argc, char **argv, po::options_description& vi
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
found_command:
|
||||
lock.unlock();
|
||||
|
||||
po::options_description vdesc("Command options");
|
||||
|
||||
if (command)
|
||||
|
||||
if (command)
|
||||
command->InitParameters(vdesc, hiddenDesc);
|
||||
|
||||
visibleDesc.add(vdesc);
|
||||
|
@ -115,7 +116,13 @@ found_command:
|
|||
adesc.add(visibleDesc);
|
||||
adesc.add(hiddenDesc);
|
||||
|
||||
po::store(po::parse_command_line(argc - arg_end, argv + arg_end, adesc), vm);
|
||||
po::parsed_options parsed = po::command_line_parser(argc - arg_end, argv + arg_end).
|
||||
options(adesc).allow_unregistered().run();
|
||||
|
||||
ap = collect_unrecognized(parsed.options,
|
||||
po::include_positional);
|
||||
|
||||
po::store(parsed, vm);
|
||||
po::notify(vm);
|
||||
|
||||
return true;
|
||||
|
@ -136,7 +143,7 @@ void CLICommand::ShowCommands(int argc, char **argv, po::options_description *vi
|
|||
const std::vector<String>& vname = kv.first;
|
||||
|
||||
arg_begin = 0;
|
||||
|
||||
|
||||
for (int i = 0, k = 1; i < vname.size() && k < argc; i++, k++) {
|
||||
if (strcmp(argv[k], "--no-stack-rlimit") == 0 || strcmp(argv[k], "--autocomplete") == 0) {
|
||||
i--;
|
||||
|
@ -146,11 +153,11 @@ void CLICommand::ShowCommands(int argc, char **argv, po::options_description *vi
|
|||
|
||||
if (vname[i] != argv[k])
|
||||
break;
|
||||
|
||||
|
||||
if (i >= best_match.size()) {
|
||||
best_match.push_back(vname[i]);
|
||||
}
|
||||
|
||||
|
||||
if (i == vname.size() - 1) {
|
||||
command = kv.second;
|
||||
break;
|
||||
|
@ -171,16 +178,16 @@ void CLICommand::ShowCommands(int argc, char **argv, po::options_description *vi
|
|||
|
||||
if (vname.size() < best_match.size())
|
||||
continue;
|
||||
|
||||
|
||||
bool match = true;
|
||||
|
||||
|
||||
for (int i = 0; i < best_match.size(); i++) {
|
||||
if (vname[i] != best_match[i]) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!match)
|
||||
continue;
|
||||
|
||||
|
@ -199,10 +206,10 @@ void CLICommand::ShowCommands(int argc, char **argv, po::options_description *vi
|
|||
|
||||
if (command && autocomplete) {
|
||||
po::options_description vdesc("Command options");
|
||||
|
||||
|
||||
if (command)
|
||||
command->InitParameters(vdesc, *hiddenDesc);
|
||||
|
||||
|
||||
visibleDesc->add(vdesc);
|
||||
|
||||
BOOST_FOREACH(const shared_ptr<po::option_description>& odesc, visibleDesc->options()) {
|
||||
|
|
|
@ -42,7 +42,7 @@ public:
|
|||
virtual String GetDescription(void) const = 0;
|
||||
virtual String GetShortDescription(void) const = 0;
|
||||
virtual void InitParameters(boost::program_options::options_description& visibleDesc, boost::program_options::options_description& hiddenDesc) const = 0;
|
||||
virtual int Run(const boost::program_options::variables_map& vm) const = 0;
|
||||
virtual int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const = 0;
|
||||
|
||||
static CLICommand::Ptr GetByName(const std::vector<String>& name);
|
||||
static void Register(const std::vector<String>& name, const CLICommand::Ptr& command);
|
||||
|
@ -50,7 +50,8 @@ public:
|
|||
|
||||
static bool ParseCommand(int argc, char **argv, boost::program_options::options_description& visibleDesc,
|
||||
boost::program_options::options_description& hiddenDesc,
|
||||
boost::program_options::variables_map& vm, String& cmdname, CLICommand::Ptr& command, bool autocomplete);
|
||||
boost::program_options::variables_map& vm, std::vector<std::string>& ap, String& cmdname,
|
||||
CLICommand::Ptr& command, bool autocomplete);
|
||||
static void ShowCommands(int argc, char **argv, boost::program_options::options_description *visibleDesc = NULL,
|
||||
boost::program_options::options_description *hiddenDesc = NULL, bool autocomplete = false, int autoindex = -1);
|
||||
};
|
||||
|
|
|
@ -299,7 +299,7 @@ void DaemonCommand::InitParameters(boost::program_options::options_description&
|
|||
*
|
||||
* @returns An exit status.
|
||||
*/
|
||||
int DaemonCommand::Run(const po::variables_map& vm) const
|
||||
int DaemonCommand::Run(const po::variables_map& vm, const std::vector<std::string>& ap) const
|
||||
{
|
||||
ScriptVariable::Set("UseVfork", true, false, true);
|
||||
|
||||
|
@ -358,7 +358,7 @@ int DaemonCommand::Run(const po::variables_map& vm) const
|
|||
SetDaemonIO(errorLog);
|
||||
Logger::DisableConsoleLog();
|
||||
}
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
struct sigaction sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
|
|
|
@ -36,12 +36,12 @@ class DaemonCommand : public CLICommand
|
|||
{
|
||||
public:
|
||||
DECLARE_PTR_TYPEDEFS(DaemonCommand);
|
||||
|
||||
|
||||
virtual String GetDescription(void) const;
|
||||
virtual String GetShortDescription(void) const;
|
||||
virtual void InitParameters(boost::program_options::options_description& visibleDesc,
|
||||
boost::program_options::options_description& hiddenDesc) const;
|
||||
virtual int Run(const boost::program_options::variables_map& vm) const;
|
||||
virtual int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ void PKINewCACommand::InitParameters(boost::program_options::options_description
|
|||
*
|
||||
* @returns An exit status.
|
||||
*/
|
||||
int PKINewCACommand::Run(const boost::program_options::variables_map& vm) const
|
||||
int PKINewCACommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const
|
||||
{
|
||||
String cadir = Application::GetLocalStateDir() + "/lib/icinga2/ca";
|
||||
|
||||
|
@ -57,18 +57,18 @@ int PKINewCACommand::Run(const boost::program_options::variables_map& vm) const
|
|||
Log(LogCritical, "base", "CA directory '" + cadir + "' already exists.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if (!Utility::MkDirP(cadir, 0700)) {
|
||||
Log(LogCritical, "base", "Could not create CA directory '" + cadir + "'.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
MakeX509CSR("Icinga CA", cadir + "/ca.key", String(), cadir + "/ca.crt", true);
|
||||
|
||||
|
||||
String serialpath = cadir + "/serial.txt";
|
||||
|
||||
Log(LogInformation, "cli", "Initializing serial file in '" + serialpath + "'.");
|
||||
|
||||
|
||||
std::ofstream fp;
|
||||
fp.open(serialpath.CStr());
|
||||
fp << "01";
|
||||
|
|
|
@ -35,12 +35,12 @@ class PKINewCACommand : public CLICommand
|
|||
{
|
||||
public:
|
||||
DECLARE_PTR_TYPEDEFS(PKINewCACommand);
|
||||
|
||||
|
||||
virtual String GetDescription(void) const;
|
||||
virtual String GetShortDescription(void) const;
|
||||
virtual void InitParameters(boost::program_options::options_description& visibleDesc,
|
||||
boost::program_options::options_description& hiddenDesc) const;
|
||||
virtual int Run(const boost::program_options::variables_map& vm) const;
|
||||
virtual int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -52,26 +52,26 @@ void PKINewCertCommand::InitParameters(boost::program_options::options_descripti
|
|||
*
|
||||
* @returns An exit status.
|
||||
*/
|
||||
int PKINewCertCommand::Run(const boost::program_options::variables_map& vm) const
|
||||
int PKINewCertCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const
|
||||
{
|
||||
if (!vm.count("cn")) {
|
||||
Log(LogCritical, "cli", "Common name (--cn) must be specified.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if (!vm.count("keyfile")) {
|
||||
Log(LogCritical, "cli", "Key file path (--keyfile) must be specified.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
String csrfile, certfile;
|
||||
|
||||
|
||||
if (vm.count("csrfile"))
|
||||
csrfile = vm["csrfile"].as<std::string>();
|
||||
|
||||
if (vm.count("certfile"))
|
||||
certfile = vm["certfile"].as<std::string>();
|
||||
|
||||
|
||||
MakeX509CSR(vm["cn"].as<std::string>(), vm["keyfile"].as<std::string>(), csrfile, certfile);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -35,12 +35,12 @@ class PKINewCertCommand : public CLICommand
|
|||
{
|
||||
public:
|
||||
DECLARE_PTR_TYPEDEFS(PKINewCertCommand);
|
||||
|
||||
|
||||
virtual String GetDescription(void) const;
|
||||
virtual String GetShortDescription(void) const;
|
||||
virtual void InitParameters(boost::program_options::options_description& visibleDesc,
|
||||
boost::program_options::options_description& hiddenDesc) const;
|
||||
virtual int Run(const boost::program_options::variables_map& vm) const;
|
||||
virtual int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const;
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue