mirror of
				https://github.com/Icinga/icinga2.git
				synced 2025-11-03 21:25:56 +01:00 
			
		
		
		
	Cli: Fix overwriting api.conf; Move black/whitelist functionality into AgentUtility class
refs #7253 fixes #7481
This commit is contained in:
		
							parent
							
								
									ceca27e25b
								
							
						
					
					
						commit
						4fe486c4dd
					
				@ -642,20 +642,12 @@ bool Utility::MkDirP(const String& path, int flags)
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Utility::CopyFile(const String& source, const String& target)
 | 
			
		||||
void Utility::CopyFile(const String& source, const String& target)
 | 
			
		||||
{
 | 
			
		||||
	if (Utility::PathExists(target)) {
 | 
			
		||||
		Log(LogWarning, "Utility")
 | 
			
		||||
		    << "Target file '" << target << "' already exists.";
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	std::ifstream ifs(source.CStr(), std::ios::binary);
 | 
			
		||||
	std::ofstream ofs(target.CStr(), std::ios::binary);
 | 
			
		||||
	std::ofstream ofs(target.CStr(), std::ios::binary | std::ios::trunc);
 | 
			
		||||
 | 
			
		||||
	ofs << ifs.rdbuf();
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifndef _WIN32
 | 
			
		||||
 | 
			
		||||
@ -137,7 +137,7 @@ public:
 | 
			
		||||
 | 
			
		||||
	static bool PathExists(const String& path);
 | 
			
		||||
 | 
			
		||||
	static bool CopyFile(const String& source, const String& target);
 | 
			
		||||
	static void CopyFile(const String& source, const String& target);
 | 
			
		||||
 | 
			
		||||
	static Value LoadJsonFile(const String& path);
 | 
			
		||||
	static void SaveJsonFile(const String& path, const Value& value);
 | 
			
		||||
 | 
			
		||||
@ -142,49 +142,20 @@ int BlackAndWhitelistCommand::Run(const boost::program_options::variables_map& v
 | 
			
		||||
			return 1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Dictionary::Ptr host_service = make_shared<Dictionary>();
 | 
			
		||||
 | 
			
		||||
		String agent_filter = vm["agent"].as<std::string>();
 | 
			
		||||
		String host_filter = vm["host"].as<std::string>();
 | 
			
		||||
		String service_filter;
 | 
			
		||||
 | 
			
		||||
		host_service->Set("host_filter", host_filter);
 | 
			
		||||
 | 
			
		||||
		if (vm.count("service")) {
 | 
			
		||||
		if (vm.count("service"))
 | 
			
		||||
			service_filter = vm["service"].as<std::string>();
 | 
			
		||||
			host_service->Set("service_filter", service_filter);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (lists->Contains(agent_filter)) {
 | 
			
		||||
			Dictionary::Ptr stored_host_service = lists->Get(agent_filter);
 | 
			
		||||
 | 
			
		||||
			if (stored_host_service->Get("host_filter") == host_filter && !vm.count("service")) {
 | 
			
		||||
				Log(LogWarning, "cli")
 | 
			
		||||
				    << "Found agent filter '" << agent_filter << "' with host filter '" << host_filter << "'. Bailing out.";
 | 
			
		||||
				return 1;
 | 
			
		||||
			} else if (stored_host_service->Get("host_filter") == host_filter && stored_host_service->Get("service_filter") == service_filter) {
 | 
			
		||||
				Log(LogWarning, "cli")
 | 
			
		||||
				    << "Found agent filter '" << agent_filter << "' with host filter '" << host_filter << "' and service filter '"
 | 
			
		||||
				    << service_filter << "'. Bailing out.";
 | 
			
		||||
				return 1;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		lists->Set(agent_filter, host_service);
 | 
			
		||||
 | 
			
		||||
		Utility::SaveJsonFile(list_path, lists);
 | 
			
		||||
 | 
			
		||||
		return AgentUtility::UpdateBlackAndWhiteList(m_Type, vm["agent"].as<std::string>(), vm["host"].as<std::string>(), service_filter);
 | 
			
		||||
	} else if (m_Command == BlackAndWhitelistCommandList) {
 | 
			
		||||
		std::cout << "Listing all " << m_Type << " entries:\n";
 | 
			
		||||
 | 
			
		||||
		ObjectLock olock(lists);
 | 
			
		||||
		BOOST_FOREACH(const Dictionary::Pair& kv, lists) {
 | 
			
		||||
			String agent_filter = kv.first;
 | 
			
		||||
			Dictionary::Ptr host_service = kv.second;
 | 
			
		||||
 | 
			
		||||
			std::cout << "Agent " << m_Type << ": '" << agent_filter << "' Host: '"
 | 
			
		||||
			    << host_service->Get("host_filter") << "' Service: '" << host_service->Get("service_filter") << "'.\n";
 | 
			
		||||
		if (vm.count("agent") || vm.count("host") || vm.count("service")) {
 | 
			
		||||
			Log(LogCritical, "cli", "List command does not take any arguments!");
 | 
			
		||||
			return 1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return AgentUtility::PrintBlackAndWhiteList(std::cout, m_Type);
 | 
			
		||||
	} else if (m_Command == BlackAndWhitelistCommandRemove) {
 | 
			
		||||
		if (!vm.count("agent")) {
 | 
			
		||||
			Log(LogCritical, "cli", "At least the agent name filter is required!");
 | 
			
		||||
@ -203,29 +174,7 @@ int BlackAndWhitelistCommand::Run(const boost::program_options::variables_map& v
 | 
			
		||||
			service_filter = vm["service"].as<std::string>();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (lists->Contains(agent_filter)) {
 | 
			
		||||
 | 
			
		||||
			Dictionary::Ptr host_service = lists->Get(agent_filter);
 | 
			
		||||
 | 
			
		||||
			if (host_service->Get("host_filter") == host_filter && !vm.count("service")) {
 | 
			
		||||
				Log(LogInformation, "cli")
 | 
			
		||||
				    << "Found agent filter '" << agent_filter << "' with host filter '" << host_filter << "'. Removing from " << m_Type << ".";
 | 
			
		||||
				lists->Remove(agent_filter);
 | 
			
		||||
			} else if (host_service->Get("host_filter") == host_filter && host_service->Get("service_filter") == service_filter) {
 | 
			
		||||
				Log(LogInformation, "cli")
 | 
			
		||||
				    << "Found agent filter '" << agent_filter << "' with host filter '" << host_filter << "' and service filter '"
 | 
			
		||||
				    << service_filter << "'. Removing from " << m_Type << ".";
 | 
			
		||||
				lists->Remove(agent_filter);
 | 
			
		||||
			} else {
 | 
			
		||||
				Log(LogCritical, "cli", "Cannot remove filter!");
 | 
			
		||||
				return 1;
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			Log(LogCritical, "cli", "Cannot remove filter!");
 | 
			
		||||
			return 1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Utility::SaveJsonFile(list_path, lists);
 | 
			
		||||
		return AgentUtility::RemoveBlackAndWhiteList(m_Type, vm["agent"].as<std::string>(), vm["host"].as<std::string>(), service_filter);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -303,13 +303,13 @@ int AgentUpdateConfigCommand::Run(const boost::program_options::variables_map& v
 | 
			
		||||
			BOOST_FOREACH(const Dictionary::Pair& kv, old_agent_repository) {
 | 
			
		||||
				String old_host = kv.first;
 | 
			
		||||
 | 
			
		||||
				if (!new_agent_repository->Contains(old_host)) {
 | 
			
		||||
					if (old_host == "localhost") {
 | 
			
		||||
						Log(LogWarning, "cli")
 | 
			
		||||
						    << "Ignoring host '" << old_host << "'. Please make sure to configure a unique name on your agent '" << old_agent << "'.";
 | 
			
		||||
						continue;
 | 
			
		||||
					}
 | 
			
		||||
				if (old_host == "localhost") {
 | 
			
		||||
					Log(LogWarning, "cli")
 | 
			
		||||
					    << "Ignoring host '" << old_host << "'. Please make sure to configure a unique name on your agent '" << old_agent << "'.";
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if (!new_agent_repository->Contains(old_host)) {
 | 
			
		||||
					Log(LogInformation, "cli")
 | 
			
		||||
					    << "Agent update found old host '" << old_host << "' on agent '" << old_agent_name << "'. Removing it.";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -382,29 +382,130 @@ bool AgentUtility::WriteAgentConfigObjects(const String& filename, const Array::
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Black/Whitelist helpers
 | 
			
		||||
 */
 | 
			
		||||
int AgentUtility::UpdateBlackAndWhiteList(const String& type, const String& agent_filter, const String& host_filter, const String& service_filter)
 | 
			
		||||
{
 | 
			
		||||
	String list_path = AgentUtility::GetRepositoryPath() + "/" + type + ".list";
 | 
			
		||||
 | 
			
		||||
	Dictionary::Ptr lists = make_shared<Dictionary>();
 | 
			
		||||
 | 
			
		||||
	if (Utility::PathExists(list_path)) {
 | 
			
		||||
		lists = Utility::LoadJsonFile(list_path);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Dictionary::Ptr host_service = make_shared<Dictionary>();
 | 
			
		||||
 | 
			
		||||
	host_service->Set("host_filter", host_filter);
 | 
			
		||||
 | 
			
		||||
	if (!service_filter.IsEmpty()) {
 | 
			
		||||
		host_service->Set("service_filter", service_filter);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (lists->Contains(agent_filter)) {
 | 
			
		||||
		Dictionary::Ptr stored_host_service = lists->Get(agent_filter);
 | 
			
		||||
 | 
			
		||||
		if (stored_host_service->Get("host_filter") == host_filter && service_filter.IsEmpty()) {
 | 
			
		||||
			Log(LogWarning, "cli")
 | 
			
		||||
			    << "Found agent filter '" << agent_filter << "' with host filter '" << host_filter << "'. Bailing out.";
 | 
			
		||||
			return 1;
 | 
			
		||||
		} else if (stored_host_service->Get("host_filter") == host_filter && stored_host_service->Get("service_filter") == service_filter) {
 | 
			
		||||
			Log(LogWarning, "cli")
 | 
			
		||||
			    << "Found agent filter '" << agent_filter << "' with host filter '" << host_filter << "' and service filter '"
 | 
			
		||||
			    << service_filter << "'. Bailing out.";
 | 
			
		||||
			return 1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	lists->Set(agent_filter, host_service);
 | 
			
		||||
 | 
			
		||||
	Utility::SaveJsonFile(list_path, lists);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int AgentUtility::RemoveBlackAndWhiteList(const String& type, const String& agent_filter, const String& host_filter, const String& service_filter)
 | 
			
		||||
{
 | 
			
		||||
	String list_path = AgentUtility::GetRepositoryPath() + "/" + type + ".list";
 | 
			
		||||
 | 
			
		||||
	Dictionary::Ptr lists = make_shared<Dictionary>();
 | 
			
		||||
 | 
			
		||||
	if (Utility::PathExists(list_path)) {
 | 
			
		||||
		lists = Utility::LoadJsonFile(list_path);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (lists->Contains(agent_filter)) {
 | 
			
		||||
		Dictionary::Ptr host_service = lists->Get(agent_filter);
 | 
			
		||||
 | 
			
		||||
		if (host_service->Get("host_filter") == host_filter && service_filter.IsEmpty()) {
 | 
			
		||||
			Log(LogInformation, "cli")
 | 
			
		||||
			    << "Found agent filter '" << agent_filter << "' with host filter '" << host_filter << "'. Removing from " << type << ".";
 | 
			
		||||
			lists->Remove(agent_filter);
 | 
			
		||||
		} else if (host_service->Get("host_filter") == host_filter && host_service->Get("service_filter") == service_filter) {
 | 
			
		||||
			Log(LogInformation, "cli")
 | 
			
		||||
			    << "Found agent filter '" << agent_filter << "' with host filter '" << host_filter << "' and service filter '"
 | 
			
		||||
			    << service_filter << "'. Removing from " << type << ".";
 | 
			
		||||
			lists->Remove(agent_filter);
 | 
			
		||||
		} else {
 | 
			
		||||
			Log(LogCritical, "cli", "Cannot remove filter!");
 | 
			
		||||
			return 1;
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		Log(LogCritical, "cli", "Cannot remove filter!");
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Utility::SaveJsonFile(list_path, lists);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int AgentUtility::PrintBlackAndWhiteList(std::ostream& fp, const String& type)
 | 
			
		||||
{
 | 
			
		||||
	String list_path = AgentUtility::GetRepositoryPath() + "/" + type + ".list";
 | 
			
		||||
 | 
			
		||||
	Dictionary::Ptr lists = make_shared<Dictionary>();
 | 
			
		||||
 | 
			
		||||
	if (Utility::PathExists(list_path)) {
 | 
			
		||||
		lists = Utility::LoadJsonFile(list_path);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fp << "Listing all " << type << " entries:\n";
 | 
			
		||||
 | 
			
		||||
	ObjectLock olock(lists);
 | 
			
		||||
	BOOST_FOREACH(const Dictionary::Pair& kv, lists) {
 | 
			
		||||
		String agent_filter = kv.first;
 | 
			
		||||
		Dictionary::Ptr host_service = kv.second;
 | 
			
		||||
 | 
			
		||||
		fp << "Agent " << type << ": '" << agent_filter << "' Host: '"
 | 
			
		||||
		    << host_service->Get("host_filter") << "' Service: '" << host_service->Get("service_filter") << "'.\n";
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * We generally don't overwrite files without backup before
 | 
			
		||||
 */
 | 
			
		||||
bool AgentUtility::CreateBackupFile(const String& target)
 | 
			
		||||
{
 | 
			
		||||
	if (Utility::PathExists(target)) {
 | 
			
		||||
		String backup = target + ".orig";
 | 
			
		||||
	if (!Utility::PathExists(target))
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
		_unlink(backup.CStr());
 | 
			
		||||
#endif /* _WIN32 */
 | 
			
		||||
	String backup = target + ".orig";
 | 
			
		||||
 | 
			
		||||
		if (rename(target.CStr(), backup.CStr()) < 0) {
 | 
			
		||||
			BOOST_THROW_EXCEPTION(posix_error()
 | 
			
		||||
			    << boost::errinfo_api_function("rename")
 | 
			
		||||
			    << boost::errinfo_errno(errno)
 | 
			
		||||
			    << boost::errinfo_file_name(target));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Log(LogInformation, "cli")
 | 
			
		||||
		    << "Created backup file '" << backup << "'.";
 | 
			
		||||
	if (Utility::PathExists(backup)) {
 | 
			
		||||
		Log(LogWarning, "cli")
 | 
			
		||||
		    << "Backup file '" << backup << "' already exists. Skipping backup.";
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Utility::CopyFile(target, backup);
 | 
			
		||||
 | 
			
		||||
	Log(LogInformation, "cli")
 | 
			
		||||
	    << "Created backup file '" << backup << "'.";
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -472,6 +573,9 @@ void AgentUtility::UpdateConstant(const String& name, const String& value)
 | 
			
		||||
 | 
			
		||||
	bool found = false;
 | 
			
		||||
 | 
			
		||||
	Log(LogInformation, "cli")
 | 
			
		||||
	    << "Updating constants file '" << constantsFile << "'.";
 | 
			
		||||
 | 
			
		||||
	std::string line;
 | 
			
		||||
	while (std::getline(ifp, line)) {
 | 
			
		||||
		if (line.find("const " + name + " = ") != std::string::npos) {
 | 
			
		||||
 | 
			
		||||
@ -60,6 +60,13 @@ public:
 | 
			
		||||
	static int GenerateAgentIcingaConfig(const std::vector<std::string>& endpoints, const String& nodename);
 | 
			
		||||
	static int GenerateAgentMasterIcingaConfig(const String& nodename);
 | 
			
		||||
 | 
			
		||||
	/* black/whitelist */
 | 
			
		||||
	static int UpdateBlackAndWhiteList(const String& type, const String& agent_filter,
 | 
			
		||||
	    const String& host_filter, const String& service_filter);
 | 
			
		||||
	static int RemoveBlackAndWhiteList(const String& type, const String& agent_filter,
 | 
			
		||||
	    const String& host_filter, const String& service_filter);
 | 
			
		||||
	static int PrintBlackAndWhiteList(std::ostream& fp, const String& type);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	AgentUtility(void);
 | 
			
		||||
	static bool RemoveAgentFile(const String& path);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user