Cli: Parse repository arguments as 'name=...'

Require 'host_name' for service objects
Rename --template to --import

refs #7255
This commit is contained in:
Michael Friedrich 2014-10-24 12:42:57 +02:00
parent 41266aab2f
commit 35c75d95b5
3 changed files with 48 additions and 41 deletions

View File

@ -24,8 +24,6 @@
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/algorithm/string/join.hpp> #include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/case_conv.hpp> #include <boost/algorithm/string/case_conv.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
@ -121,13 +119,7 @@ void RepositoryObjectCommand::InitParameters(boost::program_options::options_des
boost::program_options::options_description& hiddenDesc) const boost::program_options::options_description& hiddenDesc) const
{ {
visibleDesc.add_options() visibleDesc.add_options()
("name", po::value<std::string>(), "The name of the object") ("import", po::value<std::vector<std::string> >(), "Import the defined template(s) into the object. Must be defined and included separately in Icinga 2");
("template", po::value<std::vector<std::string> >(), "Import the defined template(s) into the object. Must be defined and included separately in Icinga 2");
if (m_Type == "Service") {
visibleDesc.add_options()
("host", po::value<std::string>(), "The host name related to this service object");
}
} }
std::vector<String> RepositoryObjectCommand::GetPositionalSuggestions(const String& word) const std::vector<String> RepositoryObjectCommand::GetPositionalSuggestions(const String& word) const
@ -147,53 +139,47 @@ std::vector<String> RepositoryObjectCommand::GetPositionalSuggestions(const Stri
*/ */
int RepositoryObjectCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const int RepositoryObjectCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const
{ {
if (ap.empty()) {
Log(LogCritical, "cli") Dictionary::Ptr attrs = RepositoryUtility::GetArgumentAttributes(ap);
<< "No object name given. Bailing out.";
if (!attrs->Contains("name")) {
Log(LogCritical, "cli", "Object requires a name (Hint: 'name=<objectname>')!");
return 1; return 1;
} }
String name = ap[0]; String name = attrs->Get("name");
std::vector<String> tokens; if (m_Type == "Service") {
Dictionary::Ptr attr = make_shared<Dictionary>(); if (!attrs->Contains("host_name")) {
Log(LogCritical, "cli", "Service objects require the 'host_name' attribute.");
std::vector<std::string> attrs = ap; return 1;
attrs.erase(attrs.begin()); //remove name }
BOOST_FOREACH(const String& kv, attrs) {
boost::algorithm::split(tokens, kv, boost::is_any_of("="));
if (tokens.size() == 2) {
attr->Set(tokens[0], tokens[1]);
} else
Log(LogWarning, "cli")
<< "Cannot parse passed attributes for object '" << name << "': " << boost::algorithm::join(tokens, "=");
} }
if (vm.count("template")) { if (vm.count("import")) {
Array::Ptr templates = make_shared<Array>(); Array::Ptr imports = make_shared<Array>();
BOOST_FOREACH(const String& tmpl, vm["template"].as<std::vector<std::string> >()) { BOOST_FOREACH(const String& import, vm["import"].as<std::vector<std::string> >()) {
templates->Add(tmpl); imports->Add(import);
} }
if (templates->GetLength() > 0) //Update object attributes
attr->Set("templates", templates); if (imports->GetLength() > 0)
attrs->Set("import", imports);
} }
if (m_Command == RepositoryCommandList) { if (m_Command == RepositoryCommandList) {
RepositoryUtility::PrintObjects(std::cout, m_Type); RepositoryUtility::PrintObjects(std::cout, m_Type);
} }
else if (m_Command == RepositoryCommandAdd) { else if (m_Command == RepositoryCommandAdd) {
RepositoryUtility::AddObject(name, m_Type, attr); RepositoryUtility::AddObject(name, m_Type, attrs);
} }
else if (m_Command == RepositoryCommandRemove) { else if (m_Command == RepositoryCommandRemove) {
RepositoryUtility::RemoveObject(name, m_Type); RepositoryUtility::RemoveObject(name, m_Type);
} }
else if (m_Command == RepositoryCommandSet) { else if (m_Command == RepositoryCommandSet) {
Log(LogWarning, "cli") Log(LogWarning, "cli")
<< "Not implemented yet.\n"; << "Not supported yet. Please check the roadmap at https://dev.icinga.org\n";
return 1; return 1;
} else { } else {
Log(LogCritical, "cli") Log(LogCritical, "cli")

View File

@ -31,11 +31,31 @@
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/algorithm/string/join.hpp> #include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/replace.hpp> #include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
using namespace icinga; using namespace icinga;
Dictionary::Ptr RepositoryUtility::GetArgumentAttributes(const std::vector<std::string>& arguments)
{
Dictionary::Ptr attr = make_shared<Dictionary>();
BOOST_FOREACH(const String& kv, arguments) {
std::vector<String> tokens;
boost::algorithm::split(tokens, kv, boost::is_any_of("="));
if (tokens.size() == 2) {
attr->Set(tokens[0], tokens[1]);
} else
Log(LogWarning, "cli")
<< "Cannot parse passed attributes: " << boost::algorithm::join(tokens, "=");
}
return attr;
}
String RepositoryUtility::GetRepositoryDPath(void) String RepositoryUtility::GetRepositoryDPath(void)
{ {
return Application::GetSysconfDir() + "/icinga2/repository.d"; return Application::GetSysconfDir() + "/icinga2/repository.d";
@ -377,17 +397,17 @@ void RepositoryUtility::SerializeObject(std::ostream& fp, const String& name, co
return; return;
} }
if (object->Contains("templates")) { if (object->Contains("import")) {
Array::Ptr templates = object->Get("templates"); Array::Ptr imports = object->Get("import");
ObjectLock olock(templates); ObjectLock olock(imports);
BOOST_FOREACH(const String& tmpl, templates) { BOOST_FOREACH(const String& import, imports) {
fp << "\t" << "import \"" << tmpl << "\"\n"; fp << "\t" << "import \"" << import << "\"\n";
} }
} }
BOOST_FOREACH(const Dictionary::Pair& kv, object) { BOOST_FOREACH(const Dictionary::Pair& kv, object) {
if (kv.first == "templates") { if (kv.first == "import") {
continue; continue;
} else { } else {
fp << "\t" << kv.first << " = "; fp << "\t" << kv.first << " = ";

View File

@ -36,6 +36,7 @@ namespace icinga
class RepositoryUtility class RepositoryUtility
{ {
public: public:
static Dictionary::Ptr GetArgumentAttributes(const std::vector<std::string>& arguments);
static String GetRepositoryDPath(void); static String GetRepositoryDPath(void);
static String GetRepositoryDObjectsPath(const String& type, const String& hostname = Empty); static String GetRepositoryDObjectsPath(const String& type, const String& hostname = Empty);
static String GetRepositoryChangeLogPath(void); static String GetRepositoryChangeLogPath(void);