]> granicus.if.org Git - icinga2/commitdiff
Implement service shortnames.
authorGunnar Beutner <gunnar.beutner@netways.de>
Fri, 8 Feb 2013 14:38:22 +0000 (15:38 +0100)
committerGunnar Beutner <gunnar.beutner@netways.de>
Fri, 8 Feb 2013 14:38:22 +0000 (15:38 +0100)
Refs #3660

components/checker/checkercomponent.cpp
components/compat/compatcomponent.cpp
itl/types.conf
lib/icinga/externalcommandprocessor.cpp
lib/icinga/host.cpp
lib/icinga/host.h
lib/icinga/service.cpp
lib/icinga/service.h

index f8710b256c567aa1f098c6179b92fd478ab44f63..c08280864e0ce75de530cbe18515f4f929cc6f64 100644 (file)
@@ -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();
index 2fae796f09f92dd0c82f6ac80f8cee89f58f5afd..48a3753cc6ebadcb5f4d52b038ca827f605b7c4d 100644 (file)
@@ -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<String>(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"
index 841a9da663ec1a301f561993124a91c9b13ca988..6ddc8e0f78bf2a20f44ca09be2c220e20d5adbb0 100644 (file)
@@ -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 "*"
index 59efb8aa5602430c5cc74291839157fb93ec96c1..6e72aa23ac46aec298dfb64cb12e095f77f4f5dc 100644 (file)
@@ -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<String>& 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 vector<Strin
        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]);
 
        Logger::Write(LogInformation, "icinga", "Rescheduling next check for service '" + arguments[1] + "'");
        service->SetForceNextCheck(true);
@@ -191,10 +182,7 @@ void ExternalCommandProcessor::EnableSvcCheck(double, const vector<String>& 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<String>& 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 vector<String
 
        bool sticky = Convert::ToBool(arguments[2]);
 
-       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."));
@@ -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 vector<Strin
        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 passive checks for service '" + arguments[1] + "'");
        service->SetEnablePassiveChecks(true);
@@ -494,10 +476,7 @@ void ExternalCommandProcessor::DisablePassiveSvcChecks(double, const vector<Stri
        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 passive checks for service '" + arguments[1] + "'");
        service->SetEnablePassiveChecks(false);
@@ -610,10 +589,7 @@ void ExternalCommandProcessor::ScheduleSvcDowntime(double, const vector<String>&
        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<String>& 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<String>& 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);
 }
-
index ab0dbb0c4facd981e48ab0cd5c1d9e6251bb21a7..8fd90337b6e243c9252e42a48b4790a9216a163e 100644 (file)
@@ -21,7 +21,7 @@
 
 using namespace icinga;
 
-map<String, vector<Service::WeakPtr> > Host::m_ServicesCache;
+map<String, map<String, weak_ptr<Service> > > 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<typename TDict>
-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<Service::Ptr> 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<Service>(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 vector<V
        task->FinishResult(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<String, weak_ptr<Service> >& services = m_ServicesCache[GetName()];
+       map<String, weak_ptr<Service> >::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::Ptr> 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<Service::Ptr> Host::GetParentServices(void) const
@@ -483,10 +480,10 @@ set<Service::Ptr> 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;
 }
-
index 4c73f715aa625fc97b338c83d159273ed88f7764..8e5bfcf0f9b7aee47b0167167b9d21e661adb6d6 100644 (file)
@@ -64,9 +64,9 @@ public:
 
        bool IsReachable(void);
        bool IsInDowntime(void) const;
-       bool IsUp(void);
+       bool IsUp(void) const;
 
-       shared_ptr<Service> ResolveService(const String& name) const;
+       shared_ptr<Service> GetServiceByShortName(const String& name) const;
 
        set<shared_ptr<Service> > GetServices(void) const;
        static void InvalidateServicesCache(void);
@@ -80,7 +80,7 @@ protected:
 private:
        static bool m_InitializerDone;
 
-       static map<String, vector<weak_ptr<Service> > > m_ServicesCache;
+       static map<String, map<String, weak_ptr<Service> > > m_ServicesCache;
        static bool m_ServicesCacheValid;
 
        static void ObjectCommittedHandler(const ConfigItem::Ptr& item);
index 260fd95a47fd70ddac143529cb5a2d8f77567bce..765161387446ef5f983c63a74dcfe8e1025f8d0a 100644 (file)
@@ -91,6 +91,16 @@ Service::Ptr Service::GetByName(const String& name)
        return dynamic_pointer_cast<Service>(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<Dictionary>();
-
-       Value dependency;
-       BOOST_FOREACH(tie(tuples::ignore, dependency), dependencies) {
-               String name;
-
-               if (services && services->Contains(dependency))
-                       name = host->GetName() + "-" + static_cast<String>(dependency);
-               else
-                       name = static_cast<String>(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::Ptr> 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;
index d6c0309c29a2e6d0d4512c0f2d78410cb65a7885..77d9d4299afe7742522504554d90f36236e3146f 100644 (file)
@@ -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<Host::Ptr> GetParentHosts(void) const;
        set<Service::Ptr> 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<void (const Service::Ptr& service, const CheckResultMessage&)> OnCheckResultReceived;
        static boost::signal<void (const Service::Ptr&, const String&)> OnCheckerChanged;
        static boost::signal<void (const Service::Ptr&, const Value&)> OnNextCheckChanged;