From: Gunnar Beutner Date: Fri, 8 Feb 2013 14:38:22 +0000 (+0100) Subject: Implement service shortnames. X-Git-Tag: v0.0.2~501 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3458b7d9d133f720f8e825c98ea702bd8b8cff42;p=icinga2 Implement service shortnames. Refs #3660 --- diff --git a/components/checker/checkercomponent.cpp b/components/checker/checkercomponent.cpp index f8710b256..c08280864 100644 --- a/components/checker/checkercomponent.cpp +++ b/components/checker/checkercomponent.cpp @@ -127,7 +127,7 @@ void CheckerComponent::CheckTimerHandler(void) if (tasks > 0) { stringstream msgbuf; msgbuf << "CheckTimerHandler: created " << tasks << " task(s)"; - Logger::Write(LogInformation, "checker", msgbuf.str()); + Logger::Write(LogDebug, "checker", msgbuf.str()); } RescheduleCheckTimer(); diff --git a/components/compat/compatcomponent.cpp b/components/compat/compatcomponent.cpp index 2fae796f0..48a3753cc 100644 --- a/components/compat/compatcomponent.cpp +++ b/components/compat/compatcomponent.cpp @@ -200,7 +200,7 @@ void CompatComponent::DumpComments(ofstream& fp, const DynamicObject::Ptr& owner fp << "hostcomment {" << "\n"; else fp << "servicecomment {" << "\n" - << "\t" << "service_description=" << service->GetAlias() << "\n"; + << "\t" << "service_description=" << service->GetShortName() << "\n"; fp << "\t" << "host_name=" << host->GetName() << "\n" << "\t" << "comment_id=" << static_cast(comment->Get("legacy_id")) << "\n" @@ -245,7 +245,7 @@ void CompatComponent::DumpDowntimes(ofstream& fp, const DynamicObject::Ptr& owne fp << "hostdowntime {" << "\n"; else fp << "servicedowntime {" << "\n" - << "\t" << "service_description=" << service->GetAlias() << "\n"; + << "\t" << "service_description=" << service->GetShortName() << "\n"; Dictionary::Ptr triggeredByObj = DowntimeProcessor::GetDowntimeByID(downtime->Get("triggered_by")); int triggeredByLegacy = 0; @@ -381,7 +381,7 @@ void CompatComponent::DumpServiceStatus(ofstream& fp, const Service::Ptr& servic { fp << "servicestatus {" << "\n" << "\t" << "host_name=" << service->GetHost()->GetName() << "\n" - << "\t" << "service_description=" << service->GetName() << "\n"; + << "\t" << "service_description=" << service->GetShortName() << "\n"; DumpServiceStatusAttrs(fp, service, CompatStateService); @@ -400,7 +400,7 @@ void CompatComponent::DumpServiceObject(ofstream& fp, const Service::Ptr& servic { fp << "define service {" << "\n" << "\t" << "host_name" << "\t" << service->GetHost()->GetName() << "\n" - << "\t" << "service_description" << "\t" << service->GetName() << "\n" + << "\t" << "service_description" << "\t" << service->GetShortName() << "\n" << "\t" << "display_name" << "\t" << service->GetAlias() << "\n" << "\t" << "check_command" << "\t" << "check_i2" << "\n" << "\t" << "check_interval" << "\t" << service->GetCheckInterval() / 60.0 << "\n" @@ -414,9 +414,9 @@ void CompatComponent::DumpServiceObject(ofstream& fp, const Service::Ptr& servic BOOST_FOREACH(const Service::Ptr& parent, service->GetParentServices()) { fp << "define servicedependency {" << "\n" << "\t" << "dependent_host_name" << "\t" << service->GetHost()->GetName() << "\n" - << "\t" << "dependent_service_description" << "\t" << service->GetName() << "\n" + << "\t" << "dependent_service_description" << "\t" << service->GetShortName() << "\n" << "\t" << "host_name" << "\t" << parent->GetHost()->GetName() << "\n" - << "\t" << "service_description" << "\t" << parent->GetName() << "\n" + << "\t" << "service_description" << "\t" << parent->GetShortName() << "\n" << "\t" << "execution_failure_criteria" << "\t" << "n" << "\n" << "\t" << "notification_failure_criteria" << "\t" << "w,u,c" << "\n" << "\t" << "}" << "\n" diff --git a/itl/types.conf b/itl/types.conf index 841a9da66..6ddc8e0f7 100644 --- a/itl/types.conf +++ b/itl/types.conf @@ -124,6 +124,8 @@ type Service { %require "host_name", %attribute string "host_name", + %attribute string "short_name", + %attribute string "alias", %attribute dictionary "macros" { %attribute string "*" diff --git a/lib/icinga/externalcommandprocessor.cpp b/lib/icinga/externalcommandprocessor.cpp index 59efb8aa5..6e72aa23a 100644 --- a/lib/icinga/externalcommandprocessor.cpp +++ b/lib/icinga/externalcommandprocessor.cpp @@ -122,10 +122,7 @@ void ExternalCommandProcessor::ProcessServiceCheckResult(double time, const vect if (arguments.size() < 4) BOOST_THROW_EXCEPTION(invalid_argument("Expected 4 arguments.")); - if (!Service::Exists(arguments[1])) - BOOST_THROW_EXCEPTION(invalid_argument("The service '" + arguments[1] + "' does not exist.")); - - Service::Ptr service = Service::GetByName(arguments[1]); + Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]); if (!service->GetEnablePassiveChecks()) BOOST_THROW_EXCEPTION(invalid_argument("Got passive check result for service '" + arguments[1] + "' which has passive checks disabled.")); @@ -154,10 +151,7 @@ void ExternalCommandProcessor::ScheduleSvcCheck(double, const vector& ar if (arguments.size() < 3) BOOST_THROW_EXCEPTION(invalid_argument("Expected 3 arguments.")); - if (!Service::Exists(arguments[1])) - BOOST_THROW_EXCEPTION(invalid_argument("The service '" + arguments[1] + "' does not exist.")); - - Service::Ptr service = Service::GetByName(arguments[1]); + Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]); double planned_check = Convert::ToDouble(arguments[2]); @@ -176,10 +170,7 @@ void ExternalCommandProcessor::ScheduleForcedSvcCheck(double, const vectorSetForceNextCheck(true); @@ -191,10 +182,7 @@ void ExternalCommandProcessor::EnableSvcCheck(double, const vector& argu if (arguments.size() < 2) BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments.")); - if (!Service::Exists(arguments[1])) - BOOST_THROW_EXCEPTION(invalid_argument("The service '" + arguments[1] + "' does not exist.")); - - Service::Ptr service = Service::GetByName(arguments[1]); + Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]); Logger::Write(LogInformation, "icinga", "Enabling active checks for service '" + arguments[1] + "'"); service->SetEnableActiveChecks(true); @@ -205,10 +193,7 @@ void ExternalCommandProcessor::DisableSvcCheck(double, const vector& arg if (arguments.size() < 2) BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments.")); - if (!Service::Exists(arguments[1])) - BOOST_THROW_EXCEPTION(invalid_argument("The service '" + arguments[1] + "' does not exist.")); - - Service::Ptr service = Service::GetByName(arguments[1]); + Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]); Logger::Write(LogInformation, "icinga", "Disabling active checks for service '" + arguments[1] + "'"); service->SetEnableActiveChecks(false); @@ -305,7 +290,7 @@ void ExternalCommandProcessor::AcknowledgeSvcProblem(double, const vectorGetState() == StateOK) BOOST_THROW_EXCEPTION(invalid_argument("The service '" + arguments[1] + "' is OK.")); @@ -326,7 +311,7 @@ void ExternalCommandProcessor::AcknowledgeSvcProblemExpire(double, const vector< bool sticky = Convert::ToBool(arguments[2]); double timestamp = Convert::ToDouble(arguments[5]); - Service::Ptr service = Service::GetByName(arguments[1]); + Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]); if (service->GetState() == StateOK) BOOST_THROW_EXCEPTION(invalid_argument("The service '" + arguments[1] + "' is OK.")); @@ -480,10 +465,7 @@ void ExternalCommandProcessor::EnablePassiveSvcChecks(double, const vectorSetEnablePassiveChecks(true); @@ -494,10 +476,7 @@ void ExternalCommandProcessor::DisablePassiveSvcChecks(double, const vectorSetEnablePassiveChecks(false); @@ -610,10 +589,7 @@ void ExternalCommandProcessor::ScheduleSvcDowntime(double, const vector& if (arguments.size() < 9) BOOST_THROW_EXCEPTION(invalid_argument("Expected 9 arguments.")); - if (!Service::Exists(arguments[1])) - BOOST_THROW_EXCEPTION(invalid_argument("The service '" + arguments[1] + "' does not exist.")); - - Service::Ptr service = Service::GetByName(arguments[1]); + Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]); String triggeredBy; int triggeredByLegacy = Convert::ToLong(arguments[5]); @@ -844,7 +820,7 @@ void ExternalCommandProcessor::AddSvcComment(double, const vector& argum if (!Service::Exists(arguments[1])) BOOST_THROW_EXCEPTION(invalid_argument("The service '" + arguments[1] + "' does not exist.")); - Service::Ptr service = Service::GetByName(arguments[1]); + Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]); Logger::Write(LogInformation, "icinga", "Creating comment for service " + service->GetName()); (void) CommentProcessor::AddComment(service, Comment_User, arguments[3], arguments[4], 0); @@ -884,9 +860,8 @@ void ExternalCommandProcessor::DelAllSvcComments(double, const vector& a if (!Service::Exists(arguments[1])) BOOST_THROW_EXCEPTION(invalid_argument("The service '" + arguments[1] + "' does not exist.")); - Service::Ptr service = Service::GetByName(arguments[1]); + Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]); Logger::Write(LogInformation, "icinga", "Removing all comments for service " + service->GetName()); CommentProcessor::RemoveAllComments(service); } - diff --git a/lib/icinga/host.cpp b/lib/icinga/host.cpp index ab0dbb0c4..8fd90337b 100644 --- a/lib/icinga/host.cpp +++ b/lib/icinga/host.cpp @@ -21,7 +21,7 @@ using namespace icinga; -map > Host::m_ServicesCache; +map > > Host::m_ServicesCache; bool Host::m_ServicesCacheValid = true; REGISTER_SCRIPTFUNCTION("native::ValidateServiceDictionary", &Host::ValidateServiceDictionary); @@ -166,28 +166,14 @@ bool Host::IsInDowntime(void) const return false; } -bool Host::IsUp(void) +bool Host::IsUp(void) const { - Dictionary::Ptr hostchecks = Get("hostchecks"); - if (hostchecks) { - hostchecks = Service::ResolveDependencies(GetSelf(), hostchecks); - - Value hostcheck; - BOOST_FOREACH(tie(tuples::ignore, hostcheck), hostchecks) { - Service::Ptr service = Service::GetByName(hostcheck); - - if (service->GetState() != StateOK && service->GetState() != StateWarning) { - return false; - } - } - } - - return true; + Service::Ptr service = GetHostCheckService(); + return (!service || service->GetState() == StateOK || service->GetState() == StateWarning); } template -static void CopyServiceAttributes(const Host::Ptr& host, TDict serviceDesc, - const ConfigItemBuilder::Ptr& builder) +static void CopyServiceAttributes(TDict serviceDesc, const ConfigItemBuilder::Ptr& builder) { /* TODO: we only need to copy macros if this is an inline definition, * i.e. host->GetProperties() != service, however for now we just @@ -244,8 +230,9 @@ void Host::ObjectCommittedHandler(const ConfigItem::Ptr& item) builder->SetName(name); builder->AddExpression("host_name", OperatorSet, item->GetName()); builder->AddExpression("alias", OperatorSet, svcname); + builder->AddExpression("short_name", OperatorSet, svcname); - CopyServiceAttributes(host, host, builder); + CopyServiceAttributes(host, builder); if (svcdesc.IsScalar()) { builder->AddParent(svcdesc); @@ -258,7 +245,7 @@ void Host::ObjectCommittedHandler(const ConfigItem::Ptr& item) builder->AddParent(parent); - CopyServiceAttributes(host, service, builder); + CopyServiceAttributes(service, builder); } else { BOOST_THROW_EXCEPTION(invalid_argument("Service description must be either a string or a dictionary.")); } @@ -319,8 +306,10 @@ set Host::GetServices(void) const ValidateServicesCache(); - BOOST_FOREACH(const Service::WeakPtr& svc, m_ServicesCache[GetName()]) { - Service::Ptr service = svc.lock(); + String key; + Service::WeakPtr wservice; + BOOST_FOREACH(tie(key, wservice), m_ServicesCache[GetName()]) { + Service::Ptr service = wservice.lock(); if (!service) continue; @@ -391,7 +380,9 @@ void Host::ValidateServicesCache(void) BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Service")->GetObjects()) { const Service::Ptr& service = static_pointer_cast(object); - m_ServicesCache[service->GetHost()->GetName()].push_back(service); + // TODO: assert for duplicate short_names + + m_ServicesCache[service->GetHost()->GetName()][service->GetShortName()] = service; } m_ServicesCacheValid = true; @@ -435,14 +426,20 @@ void Host::ValidateServiceDictionary(const ScriptTask::Ptr& task, const vectorFinishResult(Empty); } -Service::Ptr Host::ResolveService(const String& name) const +Service::Ptr Host::GetServiceByShortName(const String& name) const { - String combinedName = GetName() + "-" + name; + ValidateServicesCache(); - if (Service::Exists(combinedName)) - return Service::GetByName(combinedName); - else - return Service::GetByName(name); + map >& services = m_ServicesCache[GetName()]; + map >::iterator it = services.find(name); + + if (it != services.end()) { + Service::Ptr service = it->second.lock(); + assert(service); + return service; + } + + return Service::GetByName(name); } set Host::GetParentHosts(void) const @@ -471,7 +468,7 @@ Service::Ptr Host::GetHostCheckService(void) const if (hostcheck.IsEmpty()) return Service::Ptr(); - return ResolveService(hostcheck); + return GetServiceByShortName(hostcheck); } set Host::GetParentServices(void) const @@ -483,10 +480,10 @@ set Host::GetParentServices(void) const if (dependencies) { String key; BOOST_FOREACH(tie(key, tuples::ignore), dependencies) { - parents.insert(ResolveService(key)); + // TODO(#3660): look up { host = "name", service = "name" } pairs + parents.insert(GetServiceByShortName(key)); } } return parents; } - diff --git a/lib/icinga/host.h b/lib/icinga/host.h index 4c73f715a..8e5bfcf0f 100644 --- a/lib/icinga/host.h +++ b/lib/icinga/host.h @@ -64,9 +64,9 @@ public: bool IsReachable(void); bool IsInDowntime(void) const; - bool IsUp(void); + bool IsUp(void) const; - shared_ptr ResolveService(const String& name) const; + shared_ptr GetServiceByShortName(const String& name) const; set > GetServices(void) const; static void InvalidateServicesCache(void); @@ -80,7 +80,7 @@ protected: private: static bool m_InitializerDone; - static map > > m_ServicesCache; + static map > > m_ServicesCache; static bool m_ServicesCacheValid; static void ObjectCommittedHandler(const ConfigItem::Ptr& item); diff --git a/lib/icinga/service.cpp b/lib/icinga/service.cpp index 260fd95a4..765161387 100644 --- a/lib/icinga/service.cpp +++ b/lib/icinga/service.cpp @@ -91,6 +91,16 @@ Service::Ptr Service::GetByName(const String& name) return dynamic_pointer_cast(configObject); } +Service::Ptr Service::GetByNamePair(const String& hostName, const String& serviceName) +{ + if (!hostName.IsEmpty()) { + Host::Ptr host = Host::GetByName(hostName); + return host->GetServiceByShortName(serviceName); + } else { + return Service::GetByName(serviceName); + } +} + Host::Ptr Service::GetHost(void) const { String hostname = Get("host_name"); @@ -175,6 +185,16 @@ Dictionary::Ptr Service::GetCheckers(void) const return Get("checkers"); } +String Service::GetShortName(void) const +{ + Value value = Get("short_name"); + + if (value.IsEmpty()) + return GetName(); + + return value; +} + bool Service::IsReachable(void) const { BOOST_FOREACH(const Service::Ptr& service, GetParentServices()) { @@ -529,11 +549,10 @@ void Service::ApplyCheckResult(const Dictionary::Ptr& cr) /* reschedule host dependencies */ BOOST_FOREACH(const Host::Ptr& parent, GetParentHosts()) { - String hostcheck = parent->GetHostCheck(); - if (!hostcheck.IsEmpty()) { - Service::Ptr service = parent->ResolveService(hostcheck); + Service::Ptr service = parent->GetHostCheckService(); + + if (service) service->SetNextCheck(Utility::GetTime()); - } } // TODO: notify our child services/hosts that our state has changed @@ -606,27 +625,6 @@ bool Service::IsAllowedChecker(const String& checker) const return false; } -Dictionary::Ptr Service::ResolveDependencies(const Host::Ptr& host, const Dictionary::Ptr& dependencies) -{ - Dictionary::Ptr services = host->Get("services"); - - Dictionary::Ptr result = boost::make_shared(); - - Value dependency; - BOOST_FOREACH(tie(tuples::ignore, dependency), dependencies) { - String name; - - if (services && services->Contains(dependency)) - name = host->GetName() + "-" + static_cast(dependency); - else - name = static_cast(dependency); - - result->Set(name, name); - } - - return result; -} - void Service::OnAttributeChanged(const String& name, const Value& oldValue) { if (name == "checker") @@ -635,7 +633,7 @@ void Service::OnAttributeChanged(const String& name, const Value& oldValue) OnNextCheckChanged(GetSelf(), oldValue); else if (name == "servicegroups") ServiceGroup::InvalidateMembersCache(); - else if (name == "host_name") + else if (name == "host_name" || name == "short_name") Host::InvalidateServicesCache(); else if (name == "downtimes") DowntimeProcessor::InvalidateDowntimeCache(); @@ -780,7 +778,8 @@ set Service::GetParentServices(void) const if (dependencies) { String key; BOOST_FOREACH(tie(key, tuples::ignore), dependencies) { - Service::Ptr service = GetHost()->ResolveService(key); + // TODO(#3660): look up { host = "name", service = "name" } pairs + Service::Ptr service = GetHost()->GetServiceByShortName(key); if (service->GetName() == GetName()) continue; diff --git a/lib/icinga/service.h b/lib/icinga/service.h index d6c0309c2..77d9d4299 100644 --- a/lib/icinga/service.h +++ b/lib/icinga/service.h @@ -67,6 +67,8 @@ public: static bool Exists(const String& name); static Service::Ptr GetByName(const String& name); + static Service::Ptr GetByNamePair(const String& hostName, const String& serviceName); + static const int DefaultMaxCheckAttempts; static const int DefaultCheckInterval; static const int CheckIntervalDivisor; @@ -84,6 +86,7 @@ public: Dictionary::Ptr GetServiceDependencies(void) const; Dictionary::Ptr GetGroups(void) const; Dictionary::Ptr GetCheckers(void) const; + String GetShortName(void) const; set GetParentHosts(void) const; set GetParentServices(void) const; @@ -150,8 +153,6 @@ public: static ServiceStateType StateTypeFromString(const String& state); static String StateTypeToString(ServiceStateType state); - static Dictionary::Ptr ResolveDependencies(const Host::Ptr& host, const Dictionary::Ptr& dependencies); - static boost::signal OnCheckResultReceived; static boost::signal OnCheckerChanged; static boost::signal OnNextCheckChanged;