<< "\t" << "active_checks_enabled" << "\t" << 1 << "\n"
<< "\t" << "passive_checks_enabled" << "\t" << 1 << "\n";
- set<String> parents = host->GetParents();
+ set<Host::Ptr> parents = host->GetParents();
if (!parents.empty()) {
fp << "\t" << "parents" << "\t";
- DumpStringList(fp, parents);
+ DumpNameList(fp, parents);
fp << "\n";
}
<< "# This file is auto-generated. Do not modify this file." << "\n"
<< "\n";
- map<String, vector<String> > hostgroups;
-
DynamicObject::Ptr object;
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Host")->GetObjects()) {
const Host::Ptr& host = static_pointer_cast<Host>(object);
- Dictionary::Ptr dict;
- dict = host->GetGroups();
-
- if (dict) {
- Value hostgroup;
- BOOST_FOREACH(tie(tuples::ignore, hostgroup), dict) {
- hostgroups[hostgroup].push_back(host->GetName());
- }
- }
-
DumpHostStatus(statusfp, host);
DumpHostObject(objectfp, host);
}
- pair<String, vector<String > > hgt;
- BOOST_FOREACH(hgt, hostgroups) {
- const String& name = hgt.first;
- const vector<String>& hosts = hgt.second;
+ BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("HostGroup")->GetObjects()) {
+ const HostGroup::Ptr& hg = static_pointer_cast<HostGroup>(object);
objectfp << "define hostgroup {" << "\n"
- << "\t" << "hostgroup_name" << "\t" << name << "\n";
-
- if (HostGroup::Exists(name)) {
- HostGroup::Ptr hg = HostGroup::GetByName(name);
- objectfp << "\t" << "alias" << "\t" << hg->GetAlias() << "\n"
- << "\t" << "notes_url" << "\t" << hg->GetNotesUrl() << "\n"
- << "\t" << "action_url" << "\t" << hg->GetActionUrl() << "\n";
- }
+ << "\t" << "hostgroup_name" << "\t" << hg->GetName() << "\n"
+ << "\t" << "alias" << "\t" << hg->GetAlias() << "\n"
+ << "\t" << "notes_url" << "\t" << hg->GetNotesUrl() << "\n"
+ << "\t" << "action_url" << "\t" << hg->GetActionUrl() << "\n";
objectfp << "\t" << "members" << "\t";
-
- DumpStringList(objectfp, hosts);
-
+ DumpNameList(objectfp, hg->GetMembers());
objectfp << "\n"
<< "}" << "\n";
}
- map<String, vector<Service::Ptr> > servicegroups;
-
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Service")->GetObjects()) {
- Service::Ptr service = static_pointer_cast<Service>(object);
-
- Dictionary::Ptr dict;
-
- dict = service->GetGroups();
-
- if (dict) {
- Value servicegroup;
- BOOST_FOREACH(tie(tuples::ignore, servicegroup), dict) {
- servicegroups[servicegroup].push_back(service);
- }
- }
+ const Service::Ptr& service = static_pointer_cast<Service>(object);
DumpServiceStatus(statusfp, service);
DumpServiceObject(objectfp, service);
}
- pair<String, vector<Service::Ptr> > sgt;
- BOOST_FOREACH(sgt, servicegroups) {
- const String& name = sgt.first;
- const vector<Service::Ptr>& services = sgt.second;
+ BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("ServiceGroup")->GetObjects()) {
+ const ServiceGroup::Ptr& sg = static_pointer_cast<ServiceGroup>(object);
objectfp << "define servicegroup {" << "\n"
- << "\t" << "servicegroup_name" << "\t" << name << "\n";
-
- if (ServiceGroup::Exists(name)) {
- ServiceGroup::Ptr sg = ServiceGroup::GetByName(name);
- objectfp << "\t" << "alias" << "\t" << sg->GetAlias() << "\n"
- << "\t" << "notes_url" << "\t" << sg->GetNotesUrl() << "\n"
- << "\t" << "action_url" << "\t" << sg->GetActionUrl() << "\n";
- }
+ << "\t" << "servicegroup_name" << "\t" << sg->GetName() << "\n"
+ << "\t" << "alias" << "\t" << sg->GetAlias() << "\n"
+ << "\t" << "notes_url" << "\t" << sg->GetNotesUrl() << "\n"
+ << "\t" << "action_url" << "\t" << sg->GetActionUrl() << "\n";
objectfp << "\t" << "members" << "\t";
vector<String> sglist;
- vector<Service::Ptr>::iterator vt;
-
- BOOST_FOREACH(const Service::Ptr& service, services) {
+ BOOST_FOREACH(const Service::Ptr& service, sg->GetMembers()) {
sglist.push_back(service->GetHost()->GetName());
sglist.push_back(service->GetAlias());
}
void DumpHostStatus(ofstream& fp, const Host::Ptr& host);
void DumpHostObject(ofstream& fp, const Host::Ptr& host);
+ template<typename T>
+ void DumpNameList(ofstream& fp, const T& list)
+ {
+ typename T::const_iterator it;
+ bool first = true;
+ for (it = list.begin(); it != list.end(); it++) {
+ if (!first)
+ fp << ",";
+ else
+ first = false;
+
+ fp << (*it)->GetName();
+ }
+ }
+
template<typename T>
void DumpStringList(ofstream& fp, const T& list)
{
}
}
-
void DumpServiceStatus(ofstream& fp, const Service::Ptr& service);
void DumpServiceObject(ofstream& fp, const Service::Ptr& service);
m_InitializerDone = true;
}
+
+ HostGroup::InvalidateMembersCache();
}
String Host::GetAlias(void) const
return Get("hostgroups");
}
-set<String> Host::GetParents(void)
+set<Host::Ptr> Host::GetParents(void)
{
- set<String> parents;
+ set<Host::Ptr> parents;
Dictionary::Ptr dependencies = Get("dependencies");
if (dependencies) {
BOOST_FOREACH(tie(tuples::ignore, dependency), dependencies) {
Service::Ptr service = Service::GetByName(dependency);
- String parent = service->GetHost()->GetName();
+ Host::Ptr parent = service->GetHost();
/* ignore ourselves */
- if (parent == GetName())
+ if (parent->GetName() == GetName())
continue;
parents.insert(parent);
}
}
+void Host::OnAttributeChanged(const String& name, const Value& oldValue)
+{
+ if (name == "hostgroups")
+ HostGroup::InvalidateMembersCache();
+}
+
String GetAlias(void) const;
Dictionary::Ptr GetGroups(void) const;
- set<String> GetParents(void);
+ set<Host::Ptr> GetParents(void);
Dictionary::Ptr GetMacros(void) const;
bool IsReachable(void);
bool IsUp(void);
+protected:
+ void OnAttributeChanged(const String& name, const Value& oldValue);
+
private:
static bool m_InitializerDone;
using namespace icinga;
+map<String, vector<String> > HostGroup::m_MembersCache;
+bool HostGroup::m_MembersCacheValid = true;
+
static AttributeDescription hostGroupAttributes[] = {
{ "alias", Attribute_Config },
{ "notes_url", Attribute_Config },
return dynamic_pointer_cast<HostGroup>(configObject);
}
+set<Host::Ptr> HostGroup::GetMembers(void) const
+{
+ set<Host::Ptr> hosts;
+
+ ValidateMembersCache();
+
+ BOOST_FOREACH(const String& hst, m_MembersCache[GetName()]) {
+ if (!Host::Exists(hst))
+ continue;
+
+ Host::Ptr host = Host::GetByName(hst);
+ hosts.insert(host);
+ }
+
+ return hosts;
+}
+
+void HostGroup::InvalidateMembersCache(void)
+{
+ m_MembersCacheValid = false;
+ m_MembersCache.clear();
+}
+
+void HostGroup::ValidateMembersCache(void)
+{
+ if (m_MembersCacheValid)
+ return;
+
+ m_MembersCache.clear();
+
+ DynamicObject::Ptr object;
+ BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Host")->GetObjects()) {
+ const Host::Ptr& host = static_pointer_cast<Host>(object);
+
+ Dictionary::Ptr dict;
+ dict = host->GetGroups();
+
+ if (dict) {
+ Value hostgroup;
+ BOOST_FOREACH(tie(tuples::ignore, hostgroup), dict) {
+ if (!HostGroup::Exists(hostgroup))
+ Logger::Write(LogWarning, "icinga", "Host group '" + hostgroup + "' used but not defined.");
+
+ m_MembersCache[hostgroup].push_back(host->GetName());
+ }
+ }
+ }
+
+ m_MembersCacheValid = true;
+}
+
String GetAlias(void) const;
String GetNotesUrl(void) const;
String GetActionUrl(void) const;
+
+ set<Host::Ptr> GetMembers(void) const;
+ static void InvalidateMembersCache(void);
+
+private:
+ static map<String, vector<String> > m_MembersCache;
+ static bool m_MembersCacheValid;
+
+ static void ValidateMembersCache(void);
};
}
Service::Service(const Dictionary::Ptr& serializedObject)
: DynamicObject(serializedObject)
-{ }
+{
+ ServiceGroup::InvalidateMembersCache();
+}
String Service::GetAlias(void) const
{
OnCheckerChanged(GetSelf(), oldValue);
else if (name == "next_check")
OnNextCheckChanged(GetSelf(), oldValue);
+ else if (name == "servicegroups")
+ ServiceGroup::InvalidateMembersCache();
}
void Service::BeginExecuteCheck(const function<void (void)>& callback)
using namespace icinga;
+map<String, vector<String> > ServiceGroup::m_MembersCache;
+bool ServiceGroup::m_MembersCacheValid;
+
static AttributeDescription serviceGroupAttributes[] = {
{ "alias", Attribute_Config },
{ "notes_url", Attribute_Config },
return dynamic_pointer_cast<ServiceGroup>(configObject);
}
+set<Service::Ptr> ServiceGroup::GetMembers(void) const
+{
+ set<Service::Ptr> services;
+
+ ValidateMembersCache();
+
+ BOOST_FOREACH(const String& svc, m_MembersCache[GetName()]) {
+ if (!Service::Exists(svc))
+ continue;
+
+ Service::Ptr service = Service::GetByName(svc);
+ services.insert(service);
+ }
+
+ return services;
+}
+
+void ServiceGroup::InvalidateMembersCache(void)
+{
+ m_MembersCacheValid = false;
+ m_MembersCache.clear();
+}
+
+void ServiceGroup::ValidateMembersCache(void)
+{
+ if (m_MembersCacheValid)
+ return;
+
+ m_MembersCache.clear();
+
+ DynamicObject::Ptr object;
+ BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Service")->GetObjects()) {
+ const Service::Ptr& service = static_pointer_cast<Service>(object);
+
+ Dictionary::Ptr dict;
+ dict = service->GetGroups();
+
+ if (dict) {
+ Value servicegroup;
+ BOOST_FOREACH(tie(tuples::ignore, servicegroup), dict) {
+ if (!ServiceGroup::Exists(servicegroup))
+ Logger::Write(LogWarning, "icinga", "Service group '" + servicegroup + "' used but not defined.");
+
+ m_MembersCache[servicegroup].push_back(service->GetName());
+ }
+ }
+ }
+
+ m_MembersCacheValid = true;
+}
+
String GetAlias(void) const;
String GetNotesUrl(void) const;
String GetActionUrl(void) const;
+
+ set<Service::Ptr> GetMembers(void) const;
+ static void InvalidateMembersCache(void);
+
+private:
+ static map<String, vector<String> > m_MembersCache;
+ static bool m_MembersCacheValid;
+
+ static void ValidateMembersCache(void);
};
}