mirror of https://github.com/Icinga/icinga2.git
Implement the --file and --syntax-only options for "icinga2 console"
fixes #12554 fixes #10675
This commit is contained in:
parent
30762e5330
commit
1236495dd3
|
@ -214,7 +214,9 @@ Once connected you can inspect variables and execute other expressions by enteri
|
||||||
<3> =>
|
<3> =>
|
||||||
|
|
||||||
|
|
||||||
You can use the `--eval` parameter to evaluate a single expression in batch mode. The output format for batch mode is JSON.
|
You can use the `--eval` parameter to evaluate a single expression in batch mode. Using the `--file` option you can specify a file which should be evaluated. The output format for batch mode is JSON.
|
||||||
|
|
||||||
|
The `--syntax-only` option can be used in combination with `--eval` or `--file` to check a script for syntax errors. In this mode the script is parsed to identify syntax errors but not evaluated.
|
||||||
|
|
||||||
Here's an example that retrieves the command that was used by Icinga to check the `example.localdomain` host:
|
Here's an example that retrieves the command that was used by Icinga to check the `example.localdomain` host:
|
||||||
|
|
||||||
|
|
|
@ -138,6 +138,8 @@ void ConsoleCommand::InitParameters(boost::program_options::options_description&
|
||||||
visibleDesc.add_options()
|
visibleDesc.add_options()
|
||||||
("connect,c", po::value<std::string>(), "connect to an Icinga 2 instance")
|
("connect,c", po::value<std::string>(), "connect to an Icinga 2 instance")
|
||||||
("eval,e", po::value<std::string>(), "evaluate expression and terminate")
|
("eval,e", po::value<std::string>(), "evaluate expression and terminate")
|
||||||
|
("file,r", po::value<std::string>(), "evaluate a file and terminate")
|
||||||
|
("syntax-only", "only validate syntax (requires --eval or --file)")
|
||||||
("sandbox", "enable sandbox mode")
|
("sandbox", "enable sandbox mode")
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
@ -204,7 +206,7 @@ int ConsoleCommand::Run(const po::variables_map& vm, const std::vector<std::stri
|
||||||
|
|
||||||
scriptFrame.Self = scriptFrame.Locals;
|
scriptFrame.Self = scriptFrame.Locals;
|
||||||
|
|
||||||
if (!vm.count("eval"))
|
if (!vm.count("eval") && !vm.count("file"))
|
||||||
std::cout << "Icinga 2 (version: " << Application::GetAppVersion() << ")\n";
|
std::cout << "Icinga 2 (version: " << Application::GetAppVersion() << ")\n";
|
||||||
|
|
||||||
const char *addrEnv = getenv("ICINGA2_API_URL");
|
const char *addrEnv = getenv("ICINGA2_API_URL");
|
||||||
|
@ -215,14 +217,36 @@ int ConsoleCommand::Run(const po::variables_map& vm, const std::vector<std::stri
|
||||||
addr = vm["connect"].as<std::string>();
|
addr = vm["connect"].as<std::string>();
|
||||||
|
|
||||||
String command;
|
String command;
|
||||||
|
bool syntaxOnly = false;
|
||||||
|
|
||||||
|
if (vm.count("syntax-only")) {
|
||||||
|
if (vm.count("eval") || vm.count("file"))
|
||||||
|
syntaxOnly = true;
|
||||||
|
else {
|
||||||
|
std::cerr << "The option --syntax-only can only be used in combination with --eval or --file." << std::endl;
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (vm.count("eval"))
|
if (vm.count("eval"))
|
||||||
command = vm["eval"].as<std::string>();
|
command = vm["eval"].as<std::string>();
|
||||||
|
else if (vm.count("file")) {
|
||||||
|
std::string fname = vm["file"].as<std::string>();
|
||||||
|
|
||||||
return RunScriptConsole(scriptFrame, addr, session, command);;
|
try {
|
||||||
|
std::ifstream fp(fname.c_str());
|
||||||
|
fp.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||||
|
command = String(std::istreambuf_iterator<char>(fp), std::istreambuf_iterator<char>());
|
||||||
|
} catch (const std::exception&) {
|
||||||
|
std::cerr << "Could not read file '" << fname << "'." << std::endl;
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return RunScriptConsole(scriptFrame, addr, session, command, syntaxOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ConsoleCommand::RunScriptConsole(ScriptFrame& scriptFrame, const String& addr, const String& session, const String& commandOnce)
|
int ConsoleCommand::RunScriptConsole(ScriptFrame& scriptFrame, const String& addr, const String& session, const String& commandOnce, bool syntaxOnly)
|
||||||
{
|
{
|
||||||
std::map<String, String> lines;
|
std::map<String, String> lines;
|
||||||
int next_line = 1;
|
int next_line = 1;
|
||||||
|
@ -341,7 +365,15 @@ incomplete:
|
||||||
|
|
||||||
if (!l_ApiClient) {
|
if (!l_ApiClient) {
|
||||||
expr = ConfigCompiler::CompileText(fileName, command);
|
expr = ConfigCompiler::CompileText(fileName, command);
|
||||||
result = Serialize(expr->Evaluate(scriptFrame), 0);
|
|
||||||
|
/* This relies on the fact that - for syntax errors - CompileText()
|
||||||
|
* returns an AST where the top-level expression is a 'throw'. */
|
||||||
|
if (!syntaxOnly || dynamic_cast<ThrowExpression *>(expr)) {
|
||||||
|
if (syntaxOnly)
|
||||||
|
std::cerr << " => " << command << std::endl;
|
||||||
|
result = Serialize(expr->Evaluate(scriptFrame), 0);
|
||||||
|
} else
|
||||||
|
result = true;
|
||||||
} else {
|
} else {
|
||||||
boost::mutex mutex;
|
boost::mutex mutex;
|
||||||
boost::condition_variable cv;
|
boost::condition_variable cv;
|
||||||
|
@ -373,7 +405,7 @@ incomplete:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (const ScriptError& ex) {
|
} catch (const ScriptError& ex) {
|
||||||
if (ex.IsIncompleteExpression()) {
|
if (ex.IsIncompleteExpression() && commandOnce.IsEmpty()) {
|
||||||
continuation = true;
|
continuation = true;
|
||||||
goto incomplete;
|
goto incomplete;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ public:
|
||||||
virtual int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const override;
|
virtual int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const override;
|
||||||
|
|
||||||
static int RunScriptConsole(ScriptFrame& scriptFrame, const String& addr = String(),
|
static int RunScriptConsole(ScriptFrame& scriptFrame, const String& addr = String(),
|
||||||
const String& session = String(), const String& commandOnce = String());
|
const String& session = String(), const String& commandOnce = String(), bool syntaxOnly = false);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable boost::mutex m_Mutex;
|
mutable boost::mutex m_Mutex;
|
||||||
|
|
Loading…
Reference in New Issue