diff --git a/lib/base/utility.cpp b/lib/base/utility.cpp index d9ab7a154..58c902606 100644 --- a/lib/base/utility.cpp +++ b/lib/base/utility.cpp @@ -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 diff --git a/lib/base/utility.hpp b/lib/base/utility.hpp index de4e332b7..361dbb035 100644 --- a/lib/base/utility.hpp +++ b/lib/base/utility.hpp @@ -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); diff --git a/lib/cli/agentblackandwhitelistcommand.cpp b/lib/cli/agentblackandwhitelistcommand.cpp index c9bd29645..7cb204e38 100644 --- a/lib/cli/agentblackandwhitelistcommand.cpp +++ b/lib/cli/agentblackandwhitelistcommand.cpp @@ -142,49 +142,20 @@ int BlackAndWhitelistCommand::Run(const boost::program_options::variables_map& v return 1; } - Dictionary::Ptr host_service = make_shared(); - - String agent_filter = vm["agent"].as(); - String host_filter = vm["host"].as(); String service_filter; - host_service->Set("host_filter", host_filter); - - if (vm.count("service")) { + if (vm.count("service")) service_filter = vm["service"].as(); - 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(), vm["host"].as(), 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(); } - 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(), vm["host"].as(), service_filter); } diff --git a/lib/cli/agentupdateconfigcommand.cpp b/lib/cli/agentupdateconfigcommand.cpp index 28032283f..39f9c7066 100644 --- a/lib/cli/agentupdateconfigcommand.cpp +++ b/lib/cli/agentupdateconfigcommand.cpp @@ -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."; diff --git a/lib/cli/agentutility.cpp b/lib/cli/agentutility.cpp index ee00c7ee4..693dd5d79 100644 --- a/lib/cli/agentutility.cpp +++ b/lib/cli/agentutility.cpp @@ -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(); + + if (Utility::PathExists(list_path)) { + lists = Utility::LoadJsonFile(list_path); + } + + Dictionary::Ptr host_service = make_shared(); + + 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(); + + 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(); + + 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) { diff --git a/lib/cli/agentutility.hpp b/lib/cli/agentutility.hpp index b1e37a04a..de897e250 100644 --- a/lib/cli/agentutility.hpp +++ b/lib/cli/agentutility.hpp @@ -60,6 +60,13 @@ public: static int GenerateAgentIcingaConfig(const std::vector& 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);