mirror of https://github.com/Icinga/icinga2.git
Cli: 'agent update-config' checks against black/whitelist filters on add/remove
fixes #7501 refs #7253
This commit is contained in:
parent
4fe486c4dd
commit
0ff5cf51b8
|
@ -89,30 +89,28 @@ int AgentUpdateConfigCommand::Run(const boost::program_options::variables_map& v
|
||||||
Dictionary::Ptr repository = agent->Get("repository");
|
Dictionary::Ptr repository = agent->Get("repository");
|
||||||
String zone = agent->Get("zone");
|
String zone = agent->Get("zone");
|
||||||
String endpoint = agent->Get("endpoint");
|
String endpoint = agent->Get("endpoint");
|
||||||
|
String agent_name = endpoint;
|
||||||
|
|
||||||
/* store existing structure in index */
|
/* store existing structure in index */
|
||||||
inventory->Set(endpoint, agent);
|
inventory->Set(endpoint, agent);
|
||||||
|
|
||||||
Dictionary::Ptr host_services = make_shared<Dictionary>();
|
Dictionary::Ptr host_services = make_shared<Dictionary>();
|
||||||
|
|
||||||
/* if there is no health check host for this agent zone, create one */
|
Log(LogInformation, "cli")
|
||||||
if (!repository->Contains(zone)) {
|
<< "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<Dictionary>();
|
Dictionary::Ptr host_attrs = make_shared<Dictionary>();
|
||||||
host_attrs->Set("__name", zone);
|
host_attrs->Set("__name", zone);
|
||||||
host_attrs->Set("name", zone);
|
host_attrs->Set("name", zone);
|
||||||
host_attrs->Set("check_command", "cluster-zone");
|
host_attrs->Set("check_command", "cluster-zone");
|
||||||
host_attrs->Set("zone", zone);
|
host_attrs->Set("zone", zone);
|
||||||
Array::Ptr host_imports = make_shared<Array>();
|
Array::Ptr host_imports = make_shared<Array>();
|
||||||
host_imports->Add("agent-host"); //default host agent template
|
host_imports->Add("agent-host"); //default host agent template
|
||||||
host_attrs->Set("import", host_imports);
|
host_attrs->Set("import", host_imports);
|
||||||
|
|
||||||
if (!RepositoryUtility::AddObject(zone, "Host", host_attrs)) {
|
if (!RepositoryUtility::AddObject(zone, "Host", host_attrs)) {
|
||||||
Log(LogCritical, "cli")
|
Log(LogCritical, "cli")
|
||||||
<< "Cannot add agent host '" << zone << "' to the config repository!\n";
|
<< "Cannot add agent host '" << zone << "' to the config repository!\n";
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectLock olock(repository);
|
ObjectLock olock(repository);
|
||||||
|
@ -123,7 +121,7 @@ int AgentUpdateConfigCommand::Run(const boost::program_options::variables_map& v
|
||||||
|
|
||||||
if (host == "localhost") {
|
if (host == "localhost") {
|
||||||
Log(LogWarning, "cli")
|
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;
|
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) {
|
if (!skip_host) {
|
||||||
/* add a new host to the config repository */
|
/* add a new host to the config repository */
|
||||||
Dictionary::Ptr host_attrs = make_shared<Dictionary>();
|
Dictionary::Ptr host_attrs = make_shared<Dictionary>();
|
||||||
|
@ -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)
|
if (skip_service)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -309,6 +328,14 @@ int AgentUpdateConfigCommand::Run(const boost::program_options::variables_map& v
|
||||||
continue;
|
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)) {
|
if (!new_agent_repository->Contains(old_host)) {
|
||||||
Log(LogInformation, "cli")
|
Log(LogInformation, "cli")
|
||||||
<< "Agent update found old host '" << old_host << "' on agent '" << old_agent_name << "'. Removing it.";
|
<< "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);
|
ObjectLock ylock(old_services);
|
||||||
BOOST_FOREACH(const String& old_service, 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)) {
|
if (!new_services->Contains(old_service)) {
|
||||||
Log(LogInformation, "cli")
|
Log(LogInformation, "cli")
|
||||||
<< "Agent update found old service '" << old_service << "' on host '" << old_host
|
<< "Agent update found old service '" << old_service << "' on host '" << old_host
|
||||||
|
|
|
@ -385,9 +385,14 @@ bool AgentUtility::WriteAgentConfigObjects(const String& filename, const Array::
|
||||||
/*
|
/*
|
||||||
* Black/Whitelist helpers
|
* 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<Dictionary>();
|
Dictionary::Ptr lists = make_shared<Dictionary>();
|
||||||
|
|
||||||
|
@ -395,6 +400,13 @@ int AgentUtility::UpdateBlackAndWhiteList(const String& type, const String& agen
|
||||||
lists = Utility::LoadJsonFile(list_path);
|
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<Dictionary>();
|
Dictionary::Ptr host_service = make_shared<Dictionary>();
|
||||||
|
|
||||||
host_service->Set("host_filter", host_filter);
|
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);
|
lists->Set(agent_filter, host_service);
|
||||||
|
|
||||||
|
String list_path = GetBlackAndWhiteListPath(type);
|
||||||
Utility::SaveJsonFile(list_path, lists);
|
Utility::SaveJsonFile(list_path, lists);
|
||||||
|
|
||||||
return 0;
|
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)
|
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 = GetBlackAndWhiteList(type);
|
||||||
|
|
||||||
Dictionary::Ptr lists = make_shared<Dictionary>();
|
|
||||||
|
|
||||||
if (Utility::PathExists(list_path)) {
|
|
||||||
lists = Utility::LoadJsonFile(list_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lists->Contains(agent_filter)) {
|
if (lists->Contains(agent_filter)) {
|
||||||
Dictionary::Ptr host_service = lists->Get(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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String list_path = GetBlackAndWhiteListPath(type);
|
||||||
Utility::SaveJsonFile(list_path, lists);
|
Utility::SaveJsonFile(list_path, lists);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -463,13 +471,7 @@ int AgentUtility::RemoveBlackAndWhiteList(const String& type, const String& agen
|
||||||
|
|
||||||
int AgentUtility::PrintBlackAndWhiteList(std::ostream& fp, const String& type)
|
int AgentUtility::PrintBlackAndWhiteList(std::ostream& fp, const String& type)
|
||||||
{
|
{
|
||||||
String list_path = AgentUtility::GetRepositoryPath() + "/" + type + ".list";
|
Dictionary::Ptr lists = GetBlackAndWhiteList(type);
|
||||||
|
|
||||||
Dictionary::Ptr lists = make_shared<Dictionary>();
|
|
||||||
|
|
||||||
if (Utility::PathExists(list_path)) {
|
|
||||||
lists = Utility::LoadJsonFile(list_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
fp << "Listing all " << type << " entries:\n";
|
fp << "Listing all " << type << " entries:\n";
|
||||||
|
|
||||||
|
@ -485,6 +487,53 @@ int AgentUtility::PrintBlackAndWhiteList(std::ostream& fp, const String& type)
|
||||||
return 0;
|
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
|
* We generally don't overwrite files without backup before
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -61,12 +61,16 @@ public:
|
||||||
static int GenerateAgentMasterIcingaConfig(const String& nodename);
|
static int GenerateAgentMasterIcingaConfig(const String& nodename);
|
||||||
|
|
||||||
/* black/whitelist */
|
/* 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,
|
static int UpdateBlackAndWhiteList(const String& type, const String& agent_filter,
|
||||||
const String& host_filter, const String& service_filter);
|
const String& host_filter, const String& service_filter);
|
||||||
static int RemoveBlackAndWhiteList(const String& type, const String& agent_filter,
|
static int RemoveBlackAndWhiteList(const String& type, const String& agent_filter,
|
||||||
const String& host_filter, const String& service_filter);
|
const String& host_filter, const String& service_filter);
|
||||||
static int PrintBlackAndWhiteList(std::ostream& fp, const String& type);
|
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:
|
private:
|
||||||
AgentUtility(void);
|
AgentUtility(void);
|
||||||
static bool RemoveAgentFile(const String& path);
|
static bool RemoveAgentFile(const String& path);
|
||||||
|
|
Loading…
Reference in New Issue