mirror of https://github.com/Icinga/icinga2.git
parent
c0103268e1
commit
3f032692ce
|
@ -24,6 +24,7 @@
|
||||||
#include "base/exception.hpp"
|
#include "base/exception.hpp"
|
||||||
#include "base/socket.hpp"
|
#include "base/socket.hpp"
|
||||||
#include "base/utility.hpp"
|
#include "base/utility.hpp"
|
||||||
|
#include "base/json.hpp"
|
||||||
#include <mmatch.h>
|
#include <mmatch.h>
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
@ -1088,3 +1089,39 @@ bool Utility::PathExists(const String& path)
|
||||||
return (_stat(path.CStr(), &statbuf) >= 0);
|
return (_stat(path.CStr(), &statbuf) >= 0);
|
||||||
#endif /* _WIN32 */
|
#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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -139,6 +139,9 @@ public:
|
||||||
|
|
||||||
static bool CopyFile(const String& source, const String& target);
|
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:
|
private:
|
||||||
Utility(void);
|
Utility(void);
|
||||||
|
|
||||||
|
|
|
@ -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
|
int AgentAddCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const
|
||||||
{
|
{
|
||||||
if (!AgentUtility::AddAgent(ap[0])) {
|
AgentUtility::AddAgent(ap[0]);
|
||||||
Log(LogCritical, "cli")
|
|
||||||
<< "Cannot add agent '" << ap[0] << "'.";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
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) {
|
BOOST_FOREACH(const String& agent, ap) {
|
||||||
if (!AgentUtility::RemoveAgent(agent)) {
|
AgentUtility::RemoveAgent(agent);
|
||||||
Log(LogCritical, "cli", "Cannot remove agent '" + ap[0] + "'.");
|
|
||||||
failed = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (failed)
|
return 0;
|
||||||
return 1;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#include "cli/agentsetcommand.hpp"
|
#include "cli/agentsetcommand.hpp"
|
||||||
|
#include "cli/agentutility.hpp"
|
||||||
#include "base/logger.hpp"
|
#include "base/logger.hpp"
|
||||||
#include "base/application.hpp"
|
#include "base/application.hpp"
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
@ -45,7 +46,10 @@ String AgentSetCommand::GetShortDescription(void) const
|
||||||
void AgentSetCommand::InitParameters(boost::program_options::options_description& visibleDesc,
|
void AgentSetCommand::InitParameters(boost::program_options::options_description& visibleDesc,
|
||||||
boost::program_options::options_description& hiddenDesc) const
|
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
|
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
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "base/application.hpp"
|
#include "base/application.hpp"
|
||||||
#include "base/tlsutility.hpp"
|
#include "base/tlsutility.hpp"
|
||||||
#include "base/convert.hpp"
|
#include "base/convert.hpp"
|
||||||
|
#include "base/utility.hpp"
|
||||||
#include "base/json.hpp"
|
#include "base/json.hpp"
|
||||||
#include "base/netstring.hpp"
|
#include "base/netstring.hpp"
|
||||||
#include "base/stdiostream.hpp"
|
#include "base/stdiostream.hpp"
|
||||||
|
@ -80,7 +81,22 @@ void AgentUtility::PrintAgents(std::ostream& fp)
|
||||||
|
|
||||||
fp << "Agent '"
|
fp << "Agent '"
|
||||||
<< ConsoleColorTag(Console_ForegroundBlue | Console_Bold) << agent->Get("endpoint") << ConsoleColorTag(Console_Normal)
|
<< 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"));
|
PrintAgentRepository(fp, agent->Get("repository"));
|
||||||
}
|
}
|
||||||
|
@ -115,14 +131,13 @@ void AgentUtility::PrintAgentsJson(std::ostream& fp)
|
||||||
fp << JsonEncode(result);
|
fp << JsonEncode(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AgentUtility::AddAgent(const String& name)
|
void AgentUtility::AddAgent(const String& name)
|
||||||
{
|
{
|
||||||
String path = GetAgentRepositoryFile(name);
|
String path = GetAgentRepositoryFile(name);
|
||||||
|
|
||||||
if (Utility::PathExists(path) ) {
|
if (Utility::PathExists(path) ) {
|
||||||
Log(LogCritical, "cli")
|
Log(LogInformation, "cli")
|
||||||
<< "Cannot add agent repo. '" << path << "' already exists.\n";
|
<< "Agent '" << name << "' exists already.";
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary::Ptr agent = make_shared<Dictionary>();
|
Dictionary::Ptr agent = make_shared<Dictionary>();
|
||||||
|
@ -132,110 +147,51 @@ bool AgentUtility::AddAgent(const String& name)
|
||||||
agent->Set("zone", name);
|
agent->Set("zone", name);
|
||||||
agent->Set("repository", Empty);
|
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);
|
Utility::SaveJsonFile(GetAgentSettingsFile(name), settings);
|
||||||
peer->Set("agent_port", port);
|
|
||||||
|
|
||||||
return WriteAgentToRepository(path, peer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AgentUtility::RemoveAgent(const String& name)
|
void AgentUtility::RemoveAgent(const String& name)
|
||||||
{
|
{
|
||||||
if (!RemoveAgentFile(GetAgentRepositoryFile(name))) {
|
String repoPath = GetAgentRepositoryFile(name);
|
||||||
|
|
||||||
|
if (!Utility::PathExists(repoPath))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (unlink(repoPath.CStr()) < 0) {
|
||||||
Log(LogCritical, "cli")
|
Log(LogCritical, "cli")
|
||||||
<< "Cannot remove agent repo. '" << GetAgentRepositoryFile(name) << "' does not exist.\n";
|
<< "Cannot remove file '" << repoPath
|
||||||
return false;
|
<< "'. 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(repoPath));
|
||||||
|
}
|
||||||
|
|
||||||
if (Utility::PathExists(GetAgentSettingsFile(name))) {
|
String settingsPath = GetAgentSettingsFile(name);
|
||||||
if (!RemoveAgentFile(GetAgentSettingsFile(name))) {
|
|
||||||
Log(LogWarning, "cli")
|
if (Utility::PathExists(settingsPath)) {
|
||||||
<< "Cannot remove agent settings. '" << GetAgentSettingsFile(name) << "' does not exist.\n";
|
if (unlink(settingsPath.CStr()) < 0) {
|
||||||
return false;
|
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 true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AgentUtility::RemoveAgentFile(const String& path)
|
|
||||||
{
|
|
||||||
if (!Utility::PathExists(path)) {
|
|
||||||
Log(LogCritical, "cli")
|
|
||||||
<< "Cannot remove '" << path << "'. Does not exist.";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unlink(path.CStr()) < 0) {
|
|
||||||
Log(LogCritical, "cli")
|
|
||||||
<< "Cannot remove file '" << path
|
|
||||||
<< "'. Failed with error code " << errno << ", \"" << Utility::FormatErrorNumber(errno) + "\".";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AgentUtility::SetAgentAttribute(const String& name, const String& attr, const Value& val)
|
|
||||||
{
|
|
||||||
String repo_path = GetAgentRepositoryFile(name);
|
|
||||||
Dictionary::Ptr repo = GetAgentFromRepository(repo_path);
|
|
||||||
|
|
||||||
if (repo) {
|
|
||||||
repo->Set(attr, val);
|
|
||||||
WriteAgentToRepository(repo_path, repo);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AgentUtility::WriteAgentToRepository(const String& filename, const Dictionary::Ptr& item)
|
|
||||||
{
|
|
||||||
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 */
|
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Dictionary::Ptr AgentUtility::GetAgentFromRepository(const String& filename)
|
|
||||||
{
|
|
||||||
std::fstream fp;
|
|
||||||
fp.open(filename.CStr(), std::ifstream::in);
|
|
||||||
|
|
||||||
if (!fp)
|
|
||||||
return Dictionary::Ptr();
|
|
||||||
|
|
||||||
String content((std::istreambuf_iterator<char>(fp)), std::istreambuf_iterator<char>());
|
|
||||||
|
|
||||||
fp.close();
|
|
||||||
|
|
||||||
return JsonDecode(content);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Dictionary::Ptr> AgentUtility::GetAgents(void)
|
std::vector<Dictionary::Ptr> AgentUtility::GetAgents(void)
|
||||||
|
@ -248,9 +204,26 @@ std::vector<Dictionary::Ptr> AgentUtility::GetAgents(void)
|
||||||
return agents;
|
return agents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Dictionary::Ptr AgentUtility::LoadAgentFile(const String& agent_file)
|
||||||
|
{
|
||||||
|
Dictionary::Ptr agent = Utility::LoadJsonFile(agent_file);
|
||||||
|
|
||||||
|
if (!agent)
|
||||||
|
return Dictionary::Ptr();
|
||||||
|
|
||||||
|
String settingsFile = GetAgentSettingsFile(agent->Get("endpoint"));
|
||||||
|
|
||||||
|
if (Utility::PathExists(settingsFile))
|
||||||
|
agent->Set("settings", Utility::LoadJsonFile(settingsFile));
|
||||||
|
else
|
||||||
|
agent->Remove("settings");
|
||||||
|
|
||||||
|
return agent;
|
||||||
|
}
|
||||||
|
|
||||||
void AgentUtility::CollectAgents(const String& agent_file, std::vector<Dictionary::Ptr>& agents)
|
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)
|
if (!agent)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -44,13 +44,9 @@ public:
|
||||||
static void PrintAgents(std::ostream& fp);
|
static void PrintAgents(std::ostream& fp);
|
||||||
static void PrintAgentsJson(std::ostream& fp);
|
static void PrintAgentsJson(std::ostream& fp);
|
||||||
static void PrintAgentRepository(std::ostream& fp, const Dictionary::Ptr& repository);
|
static void PrintAgentRepository(std::ostream& fp, const Dictionary::Ptr& repository);
|
||||||
static bool AddAgent(const String& name);
|
static void AddAgent(const String& name);
|
||||||
static bool AddAgentSettings(const String& name, const String& host, const String& port);
|
static void AddAgentSettings(const String& name, const String& host, const String& port, double log_duration);
|
||||||
static bool RemoveAgent(const String& name);
|
static void 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 std::vector<Dictionary::Ptr> GetAgents(void);
|
static std::vector<Dictionary::Ptr> GetAgents(void);
|
||||||
|
|
||||||
|
@ -67,6 +63,7 @@ public:
|
||||||
private:
|
private:
|
||||||
AgentUtility(void);
|
AgentUtility(void);
|
||||||
static bool RemoveAgentFile(const String& path);
|
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 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);
|
static void SerializeObject(std::ostream& fp, const String& name, const String& type, const Dictionary::Ptr& object);
|
||||||
|
|
Loading…
Reference in New Issue