]> granicus.if.org Git - icinga2/commitdiff
Implement agent settings for "agent set" and "agent list"
authorGunnar Beutner <gunnar.beutner@netways.de>
Mon, 27 Oct 2014 14:12:19 +0000 (15:12 +0100)
committerGunnar Beutner <gunnar.beutner@netways.de>
Mon, 27 Oct 2014 14:12:19 +0000 (15:12 +0100)
refs #7248

lib/base/utility.cpp
lib/base/utility.hpp
lib/cli/agentaddcommand.cpp
lib/cli/agentremovecommand.cpp
lib/cli/agentsetcommand.cpp
lib/cli/agentutility.cpp
lib/cli/agentutility.hpp

index 728414401531e1645fdf542255f93946455115b9..14eeb5bb591e2b54f442ccbe4345fb868fa46066 100644 (file)
@@ -24,6 +24,7 @@
 #include "base/exception.hpp"
 #include "base/socket.hpp"
 #include "base/utility.hpp"
+#include "base/json.hpp"
 #include <mmatch.h>
 #include <boost/lexical_cast.hpp>
 #include <boost/foreach.hpp>
@@ -1088,3 +1089,39 @@ bool Utility::PathExists(const String& path)
        return (_stat(path.CStr(), &statbuf) >= 0);
 #endif /* _WIN32 */
 }
+
+Value Utility::LoadJsonFile(const String& path)
+{
+       std::ifstream fp;
+       fp.open(path.CStr());
+
+       String json((std::istreambuf_iterator<char>(fp)), std::istreambuf_iterator<char>());
+
+       fp.close();
+
+       if (fp.fail())
+               BOOST_THROW_EXCEPTION(std::runtime_error("Could not read JSON file '" + path + "'."));
+
+       return JsonDecode(json);
+}
+
+void Utility::SaveJsonFile(const String& path, const Value& value)
+{
+       String tempPath = path + ".tmp";
+
+       std::ofstream fp(tempPath.CStr(), std::ofstream::out | std::ostream::trunc);
+       fp.exceptions(std::ofstream::failbit | std::ofstream::badbit);
+       fp << JsonEncode(value);
+       fp.close();
+
+#ifdef _WIN32
+       _unlink(path.CStr());
+#endif /* _WIN32 */
+
+       if (rename(tempPath.CStr(), path.CStr()) < 0) {
+               BOOST_THROW_EXCEPTION(posix_error()
+                   << boost::errinfo_api_function("rename")
+                   << boost::errinfo_errno(errno)
+                   << boost::errinfo_file_name(tempPath));
+       }
+}
index eab224aeb607219dc99632f768c85593d667ecf9..de4e332b7fe13186774f093706ee005155fcf901 100644 (file)
@@ -139,6 +139,9 @@ public:
 
        static bool CopyFile(const String& source, const String& target);
 
+       static Value LoadJsonFile(const String& path);
+       static void SaveJsonFile(const String& path, const Value& value);
+
 private:
        Utility(void);
 
index 3226dd864a06529a4f7eeddc9cf96e5000595796..034e425b4ebf83a75a9504eb20ec8a8f9b9db4c6 100644 (file)
@@ -55,11 +55,7 @@ int AgentAddCommand::GetMinArguments(void) const
  */
 int AgentAddCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const
 {
-       if (!AgentUtility::AddAgent(ap[0])) {
-               Log(LogCritical, "cli")
-                   << "Cannot add agent '" << ap[0] << "'.";
-               return 1;
-       }
+       AgentUtility::AddAgent(ap[0]);
 
        return 0;
 }
index 28187c83631b29a05deb3b373eafa832e50104e1..d8f9394d9bee8028903758af92257e77ab3b6234 100644 (file)
@@ -65,17 +65,9 @@ int AgentRemoveCommand::GetMaxArguments(void) const
  */
 int AgentRemoveCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const
 {
-       bool failed = false;
-
        BOOST_FOREACH(const String& agent, ap) {
-               if (!AgentUtility::RemoveAgent(agent)) {
-                       Log(LogCritical, "cli", "Cannot remove agent '" + ap[0] + "'.");
-                       failed = true;
-               }
+               AgentUtility::RemoveAgent(agent);
        }
 
-       if (failed)
-               return 1;
-       else
-               return 0;
+       return 0;
 }
index 6238f832a6853dccb9b94c8dc96082d4ea8d2e05..60ad59256725a2caa40d09efdab5d0aec901985d 100644 (file)
@@ -18,6 +18,7 @@
  ******************************************************************************/
 
 #include "cli/agentsetcommand.hpp"
+#include "cli/agentutility.hpp"
 #include "base/logger.hpp"
 #include "base/application.hpp"
 #include <boost/foreach.hpp>
@@ -45,7 +46,10 @@ String AgentSetCommand::GetShortDescription(void) const
 void AgentSetCommand::InitParameters(boost::program_options::options_description& visibleDesc,
     boost::program_options::options_description& hiddenDesc) const
 {
-
+       visibleDesc.add_options()
+               ("host", po::value<std::string>(), "Icinga 2 host")
+               ("port", po::value<std::string>(), "Icinga 2 port")
+               ("log_duration", po::value<double>(), "Log duration (in seconds)");
 }
 
 int AgentSetCommand::GetMinArguments(void) const
@@ -60,7 +64,27 @@ int AgentSetCommand::GetMinArguments(void) const
  */
 int AgentSetCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const
 {
-       Log(LogWarning, "cli", "TODO: Not implemented yet.");
+       String repoFile = AgentUtility::GetAgentRepositoryFile(ap[0]);
+
+       if (!Utility::PathExists(repoFile)) {
+               Log(LogCritical, "cli")
+                   << "Agent '" << ap[0] << "' does not exist.";
+               return 1;
+       }
+
+       String host, port = "5665";
+       double log_duration = 24 * 60 * 60;
+
+       if (vm.count("host"))
+               host = vm["host"].as<std::string>();
+
+       if (vm.count("port"))
+               port = vm["port"].as<std::string>();
+
+       if (vm.count("log_duration"))
+               log_duration = vm["log_duration"].as<double>();
+
+       AgentUtility::AddAgentSettings(ap[0], host, port, log_duration);
 
        return 0;
 }
index 94ac0d17d51709863783c9576e47b9a3b7c1b860..a378309ef65d12b1fdf8971f85ea254d0be7341c 100644 (file)
@@ -23,6 +23,7 @@
 #include "base/application.hpp"
 #include "base/tlsutility.hpp"
 #include "base/convert.hpp"
+#include "base/utility.hpp"
 #include "base/json.hpp"
 #include "base/netstring.hpp"
 #include "base/stdiostream.hpp"
@@ -80,7 +81,22 @@ void AgentUtility::PrintAgents(std::ostream& fp)
 
                fp << "Agent '"
                   << ConsoleColorTag(Console_ForegroundBlue | Console_Bold) << agent->Get("endpoint") << ConsoleColorTag(Console_Normal)
-                  << "' (last seen: " << Utility::FormatDateTime("%c", agent->Get("seen")) << ")\n";
+                  << "' (";
+
+               Dictionary::Ptr settings = agent->Get("settings");
+
+               if (settings) {
+                       String host = settings->Get("host");
+                       String port = settings->Get("port");
+                       double log_duration = settings->Get("log_duration");
+
+                       if (!host.IsEmpty() && !port.IsEmpty())
+                               fp << "host: " << host << ", port: " << port << ", ";
+
+                       fp << "log duration: " << Utility::FormatDuration(log_duration) << ", ";
+               }
+
+               fp << "last seen: " << Utility::FormatDateTime("%c", agent->Get("seen")) << ")\n";
 
                PrintAgentRepository(fp, agent->Get("repository"));
        }
@@ -115,14 +131,13 @@ void AgentUtility::PrintAgentsJson(std::ostream& fp)
        fp << JsonEncode(result);
 }
 
-bool AgentUtility::AddAgent(const String& name)
+void AgentUtility::AddAgent(const String& name)
 {
        String path = GetAgentRepositoryFile(name);
 
        if (Utility::PathExists(path) ) {
-               Log(LogCritical, "cli")
-                   << "Cannot add agent repo. '" << path << "' already exists.\n";
-               return false;
+               Log(LogInformation, "cli")
+                   << "Agent '" << name << "' exists already.";
        }
 
        Dictionary::Ptr agent = make_shared<Dictionary>();
@@ -132,125 +147,83 @@ bool AgentUtility::AddAgent(const String& name)
        agent->Set("zone", name);
        agent->Set("repository", Empty);
 
-       return WriteAgentToRepository(path, agent);
+       Utility::SaveJsonFile(path, agent);
 }
 
-bool AgentUtility::AddAgentSettings(const String& name, const String& host, const String& port)
+void AgentUtility::AddAgentSettings(const String& name, const String& host,
+    const String& port, double log_duration)
 {
-       String path = GetAgentSettingsFile(name);
+       Dictionary::Ptr settings = make_shared<Dictionary>();
 
-       Dictionary::Ptr peer = make_shared<Dictionary>();
+       settings->Set("host", host);
+       settings->Set("port", port);
+       settings->Set("log_duration", log_duration);
 
-       peer->Set("agent_host", host);
-       peer->Set("agent_port", port);
-
-       return WriteAgentToRepository(path, peer);
+       Utility::SaveJsonFile(GetAgentSettingsFile(name), settings);
 }
 
-bool AgentUtility::RemoveAgent(const String& name)
+void AgentUtility::RemoveAgent(const String& name)
 {
-       if (!RemoveAgentFile(GetAgentRepositoryFile(name))) {
-               Log(LogCritical, "cli")
-                   << "Cannot remove agent repo. '" << GetAgentRepositoryFile(name) << "' does not exist.\n";
-               return false;
-       }
-
-       if (Utility::PathExists(GetAgentSettingsFile(name))) {
-               if (!RemoveAgentFile(GetAgentSettingsFile(name))) {
-                       Log(LogWarning, "cli")
-                           << "Cannot remove agent settings. '" << GetAgentSettingsFile(name) << "' does not exist.\n";
-                           return false;
-               }
-       }
+       String repoPath = GetAgentRepositoryFile(name);
 
-       return true;
-}
-
-bool AgentUtility::RemoveAgentFile(const String& path)
-{
-       if (!Utility::PathExists(path)) {
-               Log(LogCritical, "cli")
-                   << "Cannot remove '" << path << "'. Does not exist.";
-               return false;
-       }
+       if (!Utility::PathExists(repoPath))
+               return;
 
-       if (unlink(path.CStr()) < 0) {
+       if (unlink(repoPath.CStr()) < 0) {
                Log(LogCritical, "cli")
-                   << "Cannot remove file '" << path
+                   << "Cannot remove file '" << repoPath
                    << "'. Failed with error code " << errno << ", \"" << Utility::FormatErrorNumber(errno) + "\".";
-               return false;
-       }
-
-       return true;
-}
+               BOOST_THROW_EXCEPTION(posix_error()
+                   << boost::errinfo_api_function("unlink")
+                   << boost::errinfo_errno(errno)
+                   << boost::errinfo_file_name(repoPath));
+        }
 
-bool AgentUtility::SetAgentAttribute(const String& name, const String& attr, const Value& val)
-{
-       String repo_path = GetAgentRepositoryFile(name);
-       Dictionary::Ptr repo = GetAgentFromRepository(repo_path);
+       String settingsPath = GetAgentSettingsFile(name);
 
-       if (repo) {
-               repo->Set(attr, val);
-               WriteAgentToRepository(repo_path, repo);
-               return true;
+       if (Utility::PathExists(settingsPath)) {
+               if (unlink(settingsPath.CStr()) < 0) {
+                       Log(LogCritical, "cli")
+                           << "Cannot remove file '" << settingsPath
+                           << "'. Failed with error code " << errno << ", \"" << Utility::FormatErrorNumber(errno) + "\".";
+                       BOOST_THROW_EXCEPTION(posix_error()
+                           << boost::errinfo_api_function("unlink")
+                           << boost::errinfo_errno(errno)
+                           << boost::errinfo_file_name(settingsPath));
+               }
        }
-
-       return false;
 }
 
-bool AgentUtility::WriteAgentToRepository(const String& filename, const Dictionary::Ptr& item)
+std::vector<Dictionary::Ptr> AgentUtility::GetAgents(void)
 {
-       Log(LogInformation, "cli")
-           << "Dumping agent to file '" << filename << "'";
-
-       String tempFilename = filename + ".tmp";
-
-       std::ofstream fp(tempFilename.CStr(), std::ofstream::out | std::ostream::trunc);
-       fp << JsonEncode(item);
-       fp.close();
-
-#ifdef _WIN32
-       _unlink(filename.CStr());
-#endif /* _WIN32 */
+       std::vector<Dictionary::Ptr> agents;
 
-       if (rename(tempFilename.CStr(), filename.CStr()) < 0) {
-               BOOST_THROW_EXCEPTION(posix_error()
-                   << boost::errinfo_api_function("rename")
-                   << boost::errinfo_errno(errno)
-                   << boost::errinfo_file_name(tempFilename));
-       }
+       Utility::Glob(GetRepositoryPath() + "/*.repo",
+           boost::bind(&AgentUtility::CollectAgents, _1, boost::ref(agents)), GlobFile);
 
-       return true;
+       return agents;
 }
 
-Dictionary::Ptr AgentUtility::GetAgentFromRepository(const String& filename)
+Dictionary::Ptr AgentUtility::LoadAgentFile(const String& agent_file)
 {
-       std::fstream fp;
-       fp.open(filename.CStr(), std::ifstream::in);
+       Dictionary::Ptr agent = Utility::LoadJsonFile(agent_file);
 
-       if (!fp)
+       if (!agent)
                return Dictionary::Ptr();
 
-       String content((std::istreambuf_iterator<char>(fp)), std::istreambuf_iterator<char>());
-
-       fp.close();
+       String settingsFile = GetAgentSettingsFile(agent->Get("endpoint"));
 
-       return JsonDecode(content);
-}
+       if (Utility::PathExists(settingsFile))
+               agent->Set("settings", Utility::LoadJsonFile(settingsFile));
+       else
+               agent->Remove("settings");
 
-std::vector<Dictionary::Ptr> AgentUtility::GetAgents(void)
-{
-       std::vector<Dictionary::Ptr> agents;
-
-       Utility::Glob(GetRepositoryPath() + "/*.repo",
-           boost::bind(&AgentUtility::CollectAgents, _1, boost::ref(agents)), GlobFile);
-
-       return agents;
+       return agent;
 }
 
 void AgentUtility::CollectAgents(const String& agent_file, std::vector<Dictionary::Ptr>& agents)
 {
-       Dictionary::Ptr agent = GetAgentFromRepository(agent_file);
+       Dictionary::Ptr agent = LoadAgentFile(agent_file);
 
        if (!agent)
                return;
index dae441d9a84013bcb95c35a3a47de3015c26f3ac..b1e37a04a7c9472e239a0e87ccb42e75ddbed6b5 100644 (file)
@@ -44,13 +44,9 @@ public:
        static void PrintAgents(std::ostream& fp);
        static void PrintAgentsJson(std::ostream& fp);
        static void PrintAgentRepository(std::ostream& fp, const Dictionary::Ptr& repository);
-       static bool AddAgent(const String& name);
-       static bool AddAgentSettings(const String& name, const String& host, const String& port);
-       static bool RemoveAgent(const String& name);
-       static bool SetAgentAttribute(const String& name, const String& attr, const Value& val);
-
-       static bool WriteAgentToRepository(const String& filename, const Dictionary::Ptr& item);
-       static Dictionary::Ptr GetAgentFromRepository(const String& filename);
+       static void AddAgent(const String& name);
+       static void AddAgentSettings(const String& name, const String& host, const String& port, double log_duration);
+       static void RemoveAgent(const String& name);
 
        static std::vector<Dictionary::Ptr> GetAgents(void);
 
@@ -67,6 +63,7 @@ public:
 private:
        AgentUtility(void);
        static bool RemoveAgentFile(const String& path);
+       static Dictionary::Ptr LoadAgentFile(const String& agent_file);
        static void CollectAgents(const String& agent_file, std::vector<Dictionary::Ptr>& agents);
 
        static void SerializeObject(std::ostream& fp, const String& name, const String& type, const Dictionary::Ptr& object);