Skip to content

Commit

Permalink
Implement agent settings for "agent set" and "agent list"
Browse files Browse the repository at this point in the history
refs #7248
  • Loading branch information
gunnarbeutner committed Oct 27, 2014
1 parent c010326 commit 3f03269
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 116 deletions.
37 changes: 37 additions & 0 deletions lib/base/utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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));
}
}
3 changes: 3 additions & 0 deletions lib/base/utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ class I2_BASE_API Utility

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);

Expand Down
6 changes: 1 addition & 5 deletions lib/cli/agentaddcommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
12 changes: 2 additions & 10 deletions lib/cli/agentremovecommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
28 changes: 26 additions & 2 deletions lib/cli/agentsetcommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
******************************************************************************/

#include "cli/agentsetcommand.hpp"
#include "cli/agentutility.hpp"
#include "base/logger.hpp"
#include "base/application.hpp"
#include <boost/foreach.hpp>
Expand Down Expand Up @@ -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
Expand All @@ -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;
}
157 changes: 65 additions & 92 deletions lib/cli/agentutility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"));
}
Expand Down Expand Up @@ -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>();
Expand All @@ -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;
Expand Down
11 changes: 4 additions & 7 deletions lib/cli/agentutility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,9 @@ class AgentUtility
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);

Expand All @@ -67,6 +63,7 @@ class AgentUtility
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);
Expand Down

0 comments on commit 3f03269

Please sign in to comment.