mirror of
				https://github.com/Icinga/icinga2.git
				synced 2025-11-04 05:34:12 +01:00 
			
		
		
		
	CLI: Add basic agent command functionality (add, remove)
Prepare for set, setup, wizard, *list. Change repository files to .repo, rename .peer to .settings refs #7248 refs #7255
This commit is contained in:
		
							parent
							
								
									45187165ed
								
							
						
					
					
						commit
						e293092bdc
					
				@ -68,13 +68,13 @@ if cn == None:
 | 
			
		||||
 | 
			
		||||
ssl_sock.close()
 | 
			
		||||
 | 
			
		||||
repository_file = "@CMAKE_INSTALL_FULL_LOCALSTATEDIR@/lib/icinga2/api/repository/" + hashlib.sha256(cn).hexdigest()
 | 
			
		||||
repository_file = "@CMAKE_INSTALL_FULL_LOCALSTATEDIR@/lib/icinga2/api/repository/" + hashlib.sha256(cn).hexdigest() + ".repo"
 | 
			
		||||
fp = open(repository_file, "w")
 | 
			
		||||
repository_info = { "endpoint": cn, "seen": time.time(), "zone": cn, "repository": {} }
 | 
			
		||||
json.dump(repository_info, fp)
 | 
			
		||||
fp.close()
 | 
			
		||||
 | 
			
		||||
peer_file = "@CMAKE_INSTALL_FULL_LOCALSTATEDIR@/lib/icinga2/agent/repository/" + hashlib.sha256(cn).hexdigest() + ".peer"
 | 
			
		||||
peer_file = "@CMAKE_INSTALL_FULL_LOCALSTATEDIR@/lib/icinga2/agent/repository/" + hashlib.sha256(cn).hexdigest() + ".settings"
 | 
			
		||||
fp = open(peer_file, "w")
 | 
			
		||||
peer_info = { "agent_host": host, "agent_port": port }
 | 
			
		||||
json.dump(peer_info, fp)
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,7 @@ for root, dirs, files in os.walk(repository_dir):
 | 
			
		||||
        if len(file) != 64:
 | 
			
		||||
            continue
 | 
			
		||||
 | 
			
		||||
        fp = open(root + file, "r")
 | 
			
		||||
        fp = open(root + file + ".repo", "r")
 | 
			
		||||
        repository_info = json.load(fp)
 | 
			
		||||
        fp.close()
 | 
			
		||||
 | 
			
		||||
@ -41,7 +41,7 @@ for root, dirs, files in os.walk(repository_dir):
 | 
			
		||||
        repository[repository_info["endpoint"]] = repository_info
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            fp = open(root + file + ".peer", "r")
 | 
			
		||||
            fp = open(root + file + ".settings", "r")
 | 
			
		||||
            peer_info = json.load(fp)
 | 
			
		||||
            fp.close()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -18,11 +18,13 @@
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
#include "cli/agentaddcommand.hpp"
 | 
			
		||||
#include "cli/agentutility.hpp"
 | 
			
		||||
#include "base/logger.hpp"
 | 
			
		||||
#include "base/application.hpp"
 | 
			
		||||
#include <boost/foreach.hpp>
 | 
			
		||||
#include <boost/algorithm/string/join.hpp>
 | 
			
		||||
#include <boost/algorithm/string/replace.hpp>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <fstream>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
@ -53,7 +55,10 @@ int AgentAddCommand::Run(const boost::program_options::variables_map& vm, const
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//ap[0] must contain name
 | 
			
		||||
	if (!AgentUtility::AddAgent(ap[0])) {
 | 
			
		||||
		Log(LogCritical, "cli", "Cannot add agent '" + ap[0] + "'.");
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -21,6 +21,7 @@
 | 
			
		||||
#include "base/logger.hpp"
 | 
			
		||||
#include "base/application.hpp"
 | 
			
		||||
#include <boost/algorithm/string/case_conv.hpp>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <fstream>
 | 
			
		||||
 | 
			
		||||
using namespace icinga;
 | 
			
		||||
@ -119,5 +120,6 @@ void BlackAndWhitelistCommand::InitParameters(boost::program_options::options_de
 | 
			
		||||
 */
 | 
			
		||||
int BlackAndWhitelistCommand::Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const
 | 
			
		||||
{
 | 
			
		||||
	Log(LogWarning, "cli", "TODO: Not implemented yet.");
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -18,11 +18,14 @@
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
#include "cli/agentlistcommand.hpp"
 | 
			
		||||
#include "cli/agentutility.hpp"
 | 
			
		||||
#include "base/logger.hpp"
 | 
			
		||||
#include "base/application.hpp"
 | 
			
		||||
#include "base/console.hpp"
 | 
			
		||||
#include <boost/foreach.hpp>
 | 
			
		||||
#include <boost/algorithm/string/join.hpp>
 | 
			
		||||
#include <boost/algorithm/string/replace.hpp>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <fstream>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
@ -41,6 +44,13 @@ String AgentListCommand::GetShortDescription(void) const
 | 
			
		||||
	return "lists all agents";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AgentListCommand::InitParameters(boost::program_options::options_description& visibleDesc,
 | 
			
		||||
    boost::program_options::options_description& hiddenDesc) const
 | 
			
		||||
{
 | 
			
		||||
	visibleDesc.add_options()
 | 
			
		||||
		("batch", "list agents in json");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The entry point for the "agent list" CLI command.
 | 
			
		||||
 *
 | 
			
		||||
@ -53,5 +63,15 @@ int AgentListCommand::Run(const boost::program_options::variables_map& vm, const
 | 
			
		||||
		    << "Ignoring parameters: " << boost::algorithm::join(ap, " ");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (vm.count("batch")) {
 | 
			
		||||
		AgentUtility::PrintAgentsJson(std::cout);
 | 
			
		||||
		std::cout << "\n";
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	std::cout << "Configured agents: \n";
 | 
			
		||||
	AgentUtility::PrintAgents(std::cout);
 | 
			
		||||
	std::cout << "\n";
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -37,6 +37,8 @@ public:
 | 
			
		||||
 | 
			
		||||
	virtual String GetDescription(void) const;
 | 
			
		||||
	virtual String GetShortDescription(void) const;
 | 
			
		||||
	virtual void InitParameters(boost::program_options::options_description& visibleDesc,
 | 
			
		||||
	    boost::program_options::options_description& hiddenDesc) const;
 | 
			
		||||
	virtual int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -18,11 +18,13 @@
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
#include "cli/agentremovecommand.hpp"
 | 
			
		||||
#include "cli/agentutility.hpp"
 | 
			
		||||
#include "base/logger.hpp"
 | 
			
		||||
#include "base/application.hpp"
 | 
			
		||||
#include <boost/foreach.hpp>
 | 
			
		||||
#include <boost/algorithm/string/join.hpp>
 | 
			
		||||
#include <boost/algorithm/string/replace.hpp>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <fstream>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
@ -33,12 +35,17 @@ REGISTER_CLICOMMAND("agent/remove", AgentRemoveCommand);
 | 
			
		||||
 | 
			
		||||
String AgentRemoveCommand::GetDescription(void) const
 | 
			
		||||
{
 | 
			
		||||
	return "Remove Icinga 2 agent.";
 | 
			
		||||
	return "Removes Icinga 2 agent.";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
String AgentRemoveCommand::GetShortDescription(void) const
 | 
			
		||||
{
 | 
			
		||||
	return "remove agent";
 | 
			
		||||
	return "removes agent";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<String> AgentRemoveCommand::GetPositionalSuggestions(const String& word) const
 | 
			
		||||
{
 | 
			
		||||
	return AgentUtility::GetFieldCompletionSuggestions(word);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -53,7 +60,10 @@ int AgentRemoveCommand::Run(const boost::program_options::variables_map& vm, con
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//ap[0] must contain name
 | 
			
		||||
	if (!AgentUtility::RemoveAgent(ap[0])) {
 | 
			
		||||
		Log(LogCritical, "cli", "Cannot remove agent '" + ap[0] + "'.");
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -37,6 +37,7 @@ public:
 | 
			
		||||
 | 
			
		||||
	virtual String GetDescription(void) const;
 | 
			
		||||
	virtual String GetShortDescription(void) const;
 | 
			
		||||
	virtual std::vector<String> GetPositionalSuggestions(const String& word) const;
 | 
			
		||||
	virtual int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -23,6 +23,7 @@
 | 
			
		||||
#include <boost/foreach.hpp>
 | 
			
		||||
#include <boost/algorithm/string/join.hpp>
 | 
			
		||||
#include <boost/algorithm/string/replace.hpp>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <fstream>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
@ -33,18 +34,18 @@ REGISTER_CLICOMMAND("agent/set", AgentSetCommand);
 | 
			
		||||
 | 
			
		||||
String AgentSetCommand::GetDescription(void) const
 | 
			
		||||
{
 | 
			
		||||
	return "Lists all Icinga 2 agents.";
 | 
			
		||||
	return "Set agent attribute(s).";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
String AgentSetCommand::GetShortDescription(void) const
 | 
			
		||||
{
 | 
			
		||||
	return "lists all agents";
 | 
			
		||||
	return "set agent attributes";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AgentSetCommand::InitParameters(boost::program_options::options_description& visibleDesc,
 | 
			
		||||
    boost::program_options::options_description& hiddenDesc) const
 | 
			
		||||
{
 | 
			
		||||
	/* Command doesn't support any parameters. */
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -59,9 +60,7 @@ int AgentSetCommand::Run(const boost::program_options::variables_map& vm, const
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//ap[0] must contain name
 | 
			
		||||
	//ap[1] must contain attr
 | 
			
		||||
	//ap[2] must contain val
 | 
			
		||||
	Log(LogWarning, "cli", "TODO: Not implemented yet.");
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -23,6 +23,7 @@
 | 
			
		||||
#include <boost/foreach.hpp>
 | 
			
		||||
#include <boost/algorithm/string/join.hpp>
 | 
			
		||||
#include <boost/algorithm/string/replace.hpp>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <fstream>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
@ -45,9 +46,14 @@ void AgentSetupCommand::InitParameters(boost::program_options::options_descripti
 | 
			
		||||
    boost::program_options::options_description& hiddenDesc) const
 | 
			
		||||
{
 | 
			
		||||
	visibleDesc.add_options()
 | 
			
		||||
		("master", po::value<std::string>(), "The name of the Icinga 2 master")
 | 
			
		||||
		("zone", po::value<std::string>(), "The name of the local zone")
 | 
			
		||||
		("master_zone", po::value<std::string>(), "The name of the master zone")
 | 
			
		||||
		("listen", po::value<std::string>(), "Listen on host:port");
 | 
			
		||||
		("endpoint", po::value<std::vector<std::string> >(), "Connect to remote endpoint(s) on host,port")
 | 
			
		||||
		("listen", po::value<std::string>(), "Listen on host,port")
 | 
			
		||||
		("ticket", po::value<std::string>(), "Generated ticket number for this request")
 | 
			
		||||
		("trustedcert", po::value<std::string>(), "Trusted master certificate file")
 | 
			
		||||
		("cn", po::value<std::string>(), "The certificate's common name")
 | 
			
		||||
		("master", po::value<std::string>(), "Use setup for a master instance");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -62,5 +68,23 @@ int AgentSetupCommand::Run(const boost::program_options::variables_map& vm, cons
 | 
			
		||||
		    << "Ignoring parameters: " << boost::algorithm::join(ap, " ");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Log(LogWarning, "cli", "TODO: Not implemented yet.");
 | 
			
		||||
 | 
			
		||||
	if (vm.count("master")) {
 | 
			
		||||
		SetupMaster(vm, ap);
 | 
			
		||||
	} else {
 | 
			
		||||
		SetupAgent(vm, ap);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool AgentSetupCommand::SetupMaster(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap)
 | 
			
		||||
{
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool AgentSetupCommand::SetupAgent(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap)
 | 
			
		||||
{
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -40,6 +40,10 @@ public:
 | 
			
		||||
	virtual void InitParameters(boost::program_options::options_description& visibleDesc,
 | 
			
		||||
	    boost::program_options::options_description& hiddenDesc) const;
 | 
			
		||||
	virtual int Run(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap) const;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	static bool SetupMaster(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap);
 | 
			
		||||
	static bool SetupAgent(const boost::program_options::variables_map& vm, const std::vector<std::string>& ap);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -23,6 +23,7 @@
 | 
			
		||||
#include <boost/foreach.hpp>
 | 
			
		||||
#include <boost/algorithm/string/join.hpp>
 | 
			
		||||
#include <boost/algorithm/string/replace.hpp>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <fstream>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
@ -53,5 +54,7 @@ int AgentUpdateConfigCommand::Run(const boost::program_options::variables_map& v
 | 
			
		||||
		    << "Ignoring parameters: " << boost::algorithm::join(ap, " ");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Log(LogWarning, "cli", "TODO: Not implemented yet.");
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -18,25 +18,237 @@
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
#include "cli/agentutility.hpp"
 | 
			
		||||
#include "cli/clicommand.hpp"
 | 
			
		||||
#include "base/logger.hpp"
 | 
			
		||||
#include "base/application.hpp"
 | 
			
		||||
#include "base/tlsutility.hpp"
 | 
			
		||||
#include "base/convert.hpp"
 | 
			
		||||
#include "base/serializer.hpp"
 | 
			
		||||
#include "base/netstring.hpp"
 | 
			
		||||
#include "base/stdiostream.hpp"
 | 
			
		||||
#include "base/debug.hpp"
 | 
			
		||||
#include "base/objectlock.hpp"
 | 
			
		||||
#include "base/console.hpp"
 | 
			
		||||
#include <boost/foreach.hpp>
 | 
			
		||||
#include <boost/algorithm/string/join.hpp>
 | 
			
		||||
#include <fstream>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
using namespace icinga;
 | 
			
		||||
 | 
			
		||||
void AgentUtility::ListAgents(void)
 | 
			
		||||
String AgentUtility::GetRepositoryPath(void)
 | 
			
		||||
{
 | 
			
		||||
	return Application::GetLocalStateDir() + "/lib/icinga2/api/repository";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
String AgentUtility::GetAgentRepositoryFile(const String& name)
 | 
			
		||||
{
 | 
			
		||||
	return GetRepositoryPath() + "/" + SHA256(name) + ".repo";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
String AgentUtility::GetAgentSettingsFile(const String& name)
 | 
			
		||||
{
 | 
			
		||||
	return GetRepositoryPath() + "/" + SHA256(name) + ".settings";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
std::vector<String> AgentUtility::GetFieldCompletionSuggestions(const String& word)
 | 
			
		||||
{
 | 
			
		||||
	std::vector<String> cache;
 | 
			
		||||
	std::vector<String> suggestions;
 | 
			
		||||
 | 
			
		||||
	GetAgents(cache);
 | 
			
		||||
 | 
			
		||||
	std::sort(cache.begin(), cache.end());
 | 
			
		||||
 | 
			
		||||
	BOOST_FOREACH(const String& suggestion, cache) {
 | 
			
		||||
		if (suggestion.Find(word) == 0)
 | 
			
		||||
			suggestions.push_back(suggestion);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return suggestions;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AgentUtility::PrintAgents(std::ostream& fp)
 | 
			
		||||
{
 | 
			
		||||
	std::vector<String> agents;
 | 
			
		||||
	GetAgents(agents);
 | 
			
		||||
 | 
			
		||||
	BOOST_FOREACH(const String& agent, agents) {
 | 
			
		||||
		Dictionary::Ptr agent_obj = GetAgentFromRepository(GetAgentRepositoryFile(agent));
 | 
			
		||||
		fp << "Agent Name: " << agent << "\n";
 | 
			
		||||
 | 
			
		||||
		if (agent_obj) {
 | 
			
		||||
			fp << "Endpoint: " << agent_obj->Get("endpoint") << "\n";
 | 
			
		||||
			fp << "Zone: " << agent_obj->Get("zone") << "\n";
 | 
			
		||||
			fp << "Repository: ";
 | 
			
		||||
			fp << std::setw(4);
 | 
			
		||||
			PrintAgentRepository(fp, agent_obj->Get("repository"));
 | 
			
		||||
			fp << std::setw(0) << "\n";
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fp << "All agents: " << boost::algorithm::join(agents, " ") << "\n";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AgentUtility::PrintAgentRepository(std::ostream& fp, const Dictionary::Ptr& repository)
 | 
			
		||||
{
 | 
			
		||||
	//TODO better formatting
 | 
			
		||||
	fp << JsonSerialize(repository);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AgentUtility::PrintAgentsJson(std::ostream& fp)
 | 
			
		||||
{
 | 
			
		||||
	std::vector<String> agents;
 | 
			
		||||
	GetAgents(agents);
 | 
			
		||||
 | 
			
		||||
	BOOST_FOREACH(const String& agent, agents) {
 | 
			
		||||
		Dictionary::Ptr agent_obj = GetAgentFromRepository(GetAgentRepositoryFile(agent));
 | 
			
		||||
		if (agent_obj) {
 | 
			
		||||
			fp << JsonSerialize(agent_obj);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool AgentUtility::AddAgent(const String& name)
 | 
			
		||||
{
 | 
			
		||||
	return true;
 | 
			
		||||
	String path = GetAgentRepositoryFile(name);
 | 
			
		||||
 | 
			
		||||
	if (Utility::PathExists(path) ) {
 | 
			
		||||
		Log(LogCritical, "cli")
 | 
			
		||||
		    << "Cannot add agent repo. '" + path + "' already exists.\n";
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Dictionary::Ptr agent = make_shared<Dictionary>();
 | 
			
		||||
 | 
			
		||||
	agent->Set("seen", Utility::GetTime());
 | 
			
		||||
	agent->Set("endpoint", name);
 | 
			
		||||
	agent->Set("zone", name);
 | 
			
		||||
	agent->Set("repository", Empty);
 | 
			
		||||
 | 
			
		||||
	return WriteAgentToRepository(path, agent);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool AgentUtility::AddAgentSettings(const String& name, const String& host, const String& port)
 | 
			
		||||
{
 | 
			
		||||
	String path = GetAgentSettingsFile(name);
 | 
			
		||||
 | 
			
		||||
	Dictionary::Ptr peer = make_shared<Dictionary>();
 | 
			
		||||
 | 
			
		||||
	peer->Set("agent_host", host);
 | 
			
		||||
	peer->Set("agent_port", port);
 | 
			
		||||
 | 
			
		||||
	return WriteAgentToRepository(path, peer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool 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;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool AgentUtility::SetAgentAttribute(const String& attr, const Value& val)
 | 
			
		||||
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 " + Convert::ToString(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 << JsonSerialize(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>());
 | 
			
		||||
 | 
			
		||||
	std::cout << "Content: " << content << "\n";
 | 
			
		||||
 | 
			
		||||
	fp.close();
 | 
			
		||||
 | 
			
		||||
	return JsonDeserialize(content);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool AgentUtility::GetAgents(std::vector<String>& agents)
 | 
			
		||||
{
 | 
			
		||||
	String path = GetRepositoryPath();
 | 
			
		||||
 | 
			
		||||
	if (!Utility::Glob(path + "/*.repo",
 | 
			
		||||
	    boost::bind(&AgentUtility::CollectAgents, _1, boost::ref(agents)), GlobFile)) {
 | 
			
		||||
		Log(LogCritical, "cli", "Cannot access path '" + path + "'.");
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AgentUtility::CollectAgents(const String& agent_file, std::vector<String>& agents)
 | 
			
		||||
{
 | 
			
		||||
	String agent = Utility::BaseName(agent_file);
 | 
			
		||||
	boost::algorithm::replace_all(agent, ".repo", "");
 | 
			
		||||
 | 
			
		||||
	Log(LogDebug, "cli", "Adding agent: " + agent);
 | 
			
		||||
	agents.push_back(agent);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -21,7 +21,8 @@
 | 
			
		||||
#define AGENTUTILITY_H
 | 
			
		||||
 | 
			
		||||
#include "base/i2-base.hpp"
 | 
			
		||||
#include "base/value.hpp"
 | 
			
		||||
#include "base/dictionary.hpp"
 | 
			
		||||
#include "base/string.hpp"
 | 
			
		||||
 | 
			
		||||
namespace icinga
 | 
			
		||||
{
 | 
			
		||||
@ -32,13 +33,28 @@ namespace icinga
 | 
			
		||||
class AgentUtility
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	static void ListAgents(void);
 | 
			
		||||
	static String GetRepositoryPath(void);
 | 
			
		||||
	static String GetAgentRepositoryFile(const String& name);
 | 
			
		||||
	static String GetAgentSettingsFile(const String& name);
 | 
			
		||||
	static std::vector<String> GetFieldCompletionSuggestions(const String& word);
 | 
			
		||||
 | 
			
		||||
	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& attr, const Value& val);
 | 
			
		||||
	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 bool GetAgents(std::vector<String>& agents);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	AgentUtility(void);
 | 
			
		||||
	static bool RemoveAgentFile(const String& path);
 | 
			
		||||
	static void CollectAgents(const String& agent_file, std::vector<String>& agents);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -23,6 +23,7 @@
 | 
			
		||||
#include <boost/foreach.hpp>
 | 
			
		||||
#include <boost/algorithm/string/join.hpp>
 | 
			
		||||
#include <boost/algorithm/string/replace.hpp>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <fstream>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
@ -53,5 +54,7 @@ int AgentWizardCommand::Run(const boost::program_options::variables_map& vm, con
 | 
			
		||||
		    << "Ignoring parameters: " << boost::algorithm::join(ap, " ");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Log(LogWarning, "cli", "TODO: Not implemented yet.");
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1535,7 +1535,7 @@ Value ApiEvents::UpdateRepositoryAPIHandler(const MessageOrigin& origin, const D
 | 
			
		||||
		repository->Set(origin.FromZone->GetName(), hostInfo);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	String repositoryFile = GetRepositoryDir() + SHA256(params->Get("endpoint"));
 | 
			
		||||
	String repositoryFile = GetRepositoryDir() + SHA256(params->Get("endpoint")) + ".repo";
 | 
			
		||||
	String repositoryTempFile = repositoryFile + ".tmp";
 | 
			
		||||
 | 
			
		||||
	std::ofstream fp(repositoryTempFile.CStr(), std::ofstream::out | std::ostream::trunc);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user