diff --git a/lib/cli/agentupdateconfigcommand.cpp b/lib/cli/agentupdateconfigcommand.cpp index 39f9c7066..2b3f9ee73 100644 --- a/lib/cli/agentupdateconfigcommand.cpp +++ b/lib/cli/agentupdateconfigcommand.cpp @@ -89,30 +89,28 @@ int AgentUpdateConfigCommand::Run(const boost::program_options::variables_map& v Dictionary::Ptr repository = agent->Get("repository"); String zone = agent->Get("zone"); String endpoint = agent->Get("endpoint"); + String agent_name = endpoint; /* store existing structure in index */ inventory->Set(endpoint, agent); Dictionary::Ptr host_services = make_shared(); - /* if there is no health check host for this agent zone, create one */ - if (!repository->Contains(zone)) { - Log(LogInformation, "cli") - << "Repository for agent '" << endpoint << "' does not contain a health check host. Adding host '" << zone << "'."; + Log(LogInformation, "cli") + << "Repository for agent '" << endpoint << "' does not contain a health check host. Adding host '" << zone << "'."; - Dictionary::Ptr host_attrs = make_shared(); - host_attrs->Set("__name", zone); - host_attrs->Set("name", zone); - host_attrs->Set("check_command", "cluster-zone"); - host_attrs->Set("zone", zone); - Array::Ptr host_imports = make_shared(); - host_imports->Add("agent-host"); //default host agent template - host_attrs->Set("import", host_imports); + Dictionary::Ptr host_attrs = make_shared(); + host_attrs->Set("__name", zone); + host_attrs->Set("name", zone); + host_attrs->Set("check_command", "cluster-zone"); + host_attrs->Set("zone", zone); + Array::Ptr host_imports = make_shared(); + host_imports->Add("agent-host"); //default host agent template + host_attrs->Set("import", host_imports); - if (!RepositoryUtility::AddObject(zone, "Host", host_attrs)) { - Log(LogCritical, "cli") - << "Cannot add agent host '" << zone << "' to the config repository!\n"; - } + if (!RepositoryUtility::AddObject(zone, "Host", host_attrs)) { + Log(LogCritical, "cli") + << "Cannot add agent host '" << zone << "' to the config repository!\n"; } ObjectLock olock(repository); @@ -123,7 +121,7 @@ int AgentUpdateConfigCommand::Run(const boost::program_options::variables_map& v if (host == "localhost") { Log(LogWarning, "cli") - << "Ignoring host '" << host << "'. Please make sure to configure a unique name on your agent '" << endpoint << "'."; + << "Ignoring host '" << host << "'. Please make sure to configure a unique name on your agent '" << agent_name << "'."; continue; } @@ -136,6 +134,18 @@ int AgentUpdateConfigCommand::Run(const boost::program_options::variables_map& v } } + /* host has already been created above */ + if (host == zone) + skip_host = true; + + /* check against black/whitelist before trying to add host */ + if (AgentUtility::CheckAgainstBlackAndWhiteList("blacklist", agent_name, host, Empty) && + !AgentUtility::CheckAgainstBlackAndWhiteList("whitelist", agent_name, host, Empty)) { + Log(LogWarning, "cli") + << "Host '" << host << "' on agent '" << agent_name << "' is blacklisted, but not whitelisted. Skipping."; + skip_host = true; + } + if (!skip_host) { /* add a new host to the config repository */ Dictionary::Ptr host_attrs = make_shared(); @@ -182,6 +192,15 @@ int AgentUpdateConfigCommand::Run(const boost::program_options::variables_map& v } } + /* check against black/whitelist before trying to add service */ + if (AgentUtility::CheckAgainstBlackAndWhiteList("blacklist", endpoint, host, service) && + !AgentUtility::CheckAgainstBlackAndWhiteList("whitelist", endpoint, host, service)) { + Log(LogWarning, "cli") + << "Service '" << service << "' on host '" << host << "' on agent '" + << agent_name << "' is blacklisted, but not whitelisted. Skipping."; + skip_service = true; + } + if (skip_service) continue; @@ -309,6 +328,14 @@ int AgentUpdateConfigCommand::Run(const boost::program_options::variables_map& v continue; } + /* check against black/whitelist before trying to remove host */ + if (AgentUtility::CheckAgainstBlackAndWhiteList("blacklist", old_agent_name, old_host, Empty) && + !AgentUtility::CheckAgainstBlackAndWhiteList("whitelist", old_agent_name, old_host, Empty)) { + Log(LogWarning, "cli") + << "Host '" << old_agent << "' on agent '" << old_agent << "' is blacklisted, but not whitelisted. Skipping."; + 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."; @@ -323,6 +350,15 @@ int AgentUpdateConfigCommand::Run(const boost::program_options::variables_map& v ObjectLock ylock(old_services); BOOST_FOREACH(const String& old_service, old_services) { + /* check against black/whitelist before trying to remove service */ + if (AgentUtility::CheckAgainstBlackAndWhiteList("blacklist", old_agent_name, old_host, old_service) && + !AgentUtility::CheckAgainstBlackAndWhiteList("whitelist", old_agent_name, old_host, old_service)) { + Log(LogWarning, "cli") + << "Service '" << old_service << "' on host '" << old_host << "' on agent '" + << old_agent_name << "' is blacklisted, but not whitelisted. Skipping."; + skip_service = true; + } + if (!new_services->Contains(old_service)) { Log(LogInformation, "cli") << "Agent update found old service '" << old_service << "' on host '" << old_host diff --git a/lib/cli/agentutility.cpp b/lib/cli/agentutility.cpp index 693dd5d79..7a10fc9ec 100644 --- a/lib/cli/agentutility.cpp +++ b/lib/cli/agentutility.cpp @@ -385,9 +385,14 @@ bool AgentUtility::WriteAgentConfigObjects(const String& filename, const Array:: /* * Black/Whitelist helpers */ -int AgentUtility::UpdateBlackAndWhiteList(const String& type, const String& agent_filter, const String& host_filter, const String& service_filter) +String AgentUtility::GetBlackAndWhiteListPath(const String& type) { - String list_path = AgentUtility::GetRepositoryPath() + "/" + type + ".list"; + return AgentUtility::GetRepositoryPath() + "/" + type + ".list"; +} + +Dictionary::Ptr AgentUtility::GetBlackAndWhiteList(const String& type) +{ + String list_path = GetBlackAndWhiteListPath(type); Dictionary::Ptr lists = make_shared(); @@ -395,6 +400,13 @@ int AgentUtility::UpdateBlackAndWhiteList(const String& type, const String& agen lists = Utility::LoadJsonFile(list_path); } + return lists; +} + +int AgentUtility::UpdateBlackAndWhiteList(const String& type, const String& agent_filter, const String& host_filter, const String& service_filter) +{ + Dictionary::Ptr lists = GetBlackAndWhiteList(type); + Dictionary::Ptr host_service = make_shared(); host_service->Set("host_filter", host_filter); @@ -420,6 +432,7 @@ int AgentUtility::UpdateBlackAndWhiteList(const String& type, const String& agen lists->Set(agent_filter, host_service); + String list_path = GetBlackAndWhiteListPath(type); Utility::SaveJsonFile(list_path, lists); return 0; @@ -427,13 +440,7 @@ int AgentUtility::UpdateBlackAndWhiteList(const String& type, const String& agen 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(); - - if (Utility::PathExists(list_path)) { - lists = Utility::LoadJsonFile(list_path); - } + Dictionary::Ptr lists = GetBlackAndWhiteList(type); if (lists->Contains(agent_filter)) { Dictionary::Ptr host_service = lists->Get(agent_filter); @@ -456,6 +463,7 @@ int AgentUtility::RemoveBlackAndWhiteList(const String& type, const String& agen return 1; } + String list_path = GetBlackAndWhiteListPath(type); Utility::SaveJsonFile(list_path, lists); return 0; @@ -463,13 +471,7 @@ int AgentUtility::RemoveBlackAndWhiteList(const String& type, const String& agen int AgentUtility::PrintBlackAndWhiteList(std::ostream& fp, const String& type) { - String list_path = AgentUtility::GetRepositoryPath() + "/" + type + ".list"; - - Dictionary::Ptr lists = make_shared(); - - if (Utility::PathExists(list_path)) { - lists = Utility::LoadJsonFile(list_path); - } + Dictionary::Ptr lists = GetBlackAndWhiteList(type); fp << "Listing all " << type << " entries:\n"; @@ -485,6 +487,53 @@ int AgentUtility::PrintBlackAndWhiteList(std::ostream& fp, const String& type) return 0; } +bool AgentUtility::CheckAgainstBlackAndWhiteList(const String& type, const String& agent, const String& host, const String& service) +{ + Dictionary::Ptr lists = GetBlackAndWhiteList(type); + + Log(LogInformation, "cli") + << "Checking object against " << type << "."; + + ObjectLock olock(lists); + BOOST_FOREACH(const Dictionary::Pair& kv, lists) { + String agent_filter = kv.first; + Dictionary::Ptr host_service = kv.second; + String host_filter = host_service->Get("host_filter"); + String service_filter; + + if (host_service->Contains("service_filter")) + service_filter = host_service->Get("service_filter"); + + Log(LogInformation, "cli") + << "Checking Agent '" << agent << "' =~ '" << agent_filter << "', host '" << host << "' =~ '" << host_filter + << "', service '" << service << "' =~ '" << service_filter << "'."; + + if (Utility::Match(agent_filter, agent)) { + Log(LogNotice, "cli") + << "Agent '" << agent << "' matches filter '" << agent_filter << "'"; + + if (Utility::Match(host_filter, host)) { + Log(LogNotice, "cli") + << "Host '" << host << "' matches filter '" << host_filter << "'"; + + /* no service filter means host match */ + if (service_filter.IsEmpty()) + return true; + + if (Utility::Match(service_filter, service)) { + Log(LogNotice, "cli") + << "Host '" << service << "' matches filter '" << service_filter << "'"; + return true; + } + } + + + } + } + + return false; +} + /* * We generally don't overwrite files without backup before */ diff --git a/lib/cli/agentutility.hpp b/lib/cli/agentutility.hpp index de897e250..6f6f857c6 100644 --- a/lib/cli/agentutility.hpp +++ b/lib/cli/agentutility.hpp @@ -61,12 +61,16 @@ public: static int GenerateAgentMasterIcingaConfig(const String& nodename); /* black/whitelist */ + static String GetBlackAndWhiteListPath(const String& type); + static Dictionary::Ptr GetBlackAndWhiteList(const String& type); 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); + static bool CheckAgainstBlackAndWhiteList(const String& type, const String& agent, const String& host, const String& service); + private: AgentUtility(void); static bool RemoveAgentFile(const String& path);