]> granicus.if.org Git - icinga2/commitdiff
Implement downtimes.
authorGunnar Beutner <gunnar.beutner@netways.de>
Tue, 29 Jan 2013 13:19:54 +0000 (14:19 +0100)
committerGunnar Beutner <gunnar.beutner@netways.de>
Tue, 29 Jan 2013 13:19:54 +0000 (14:19 +0100)
Fixes #2833

components/compat/compatcomponent.cpp
components/compat/compatcomponent.h
lib/base/i2-base.h
lib/icinga/Makefile.am
lib/icinga/externalcommand.cpp
lib/icinga/externalcommand.h
lib/icinga/host.cpp
lib/icinga/host.h
lib/icinga/i2-icinga.h
lib/icinga/service.cpp
lib/icinga/service.h

index 5ce26b264dfcb6e50bd5cbb05d56dcfc39fe0252..9c1c1747eab82be7db336a94dbfc91628250e920 100644 (file)
@@ -159,6 +159,51 @@ void CompatComponent::ProcessCommand(const String& command)
 }
 #endif /* _WIN32 */
 
+void CompatComponent::DumpDowntimes(ofstream& fp, const DynamicObject::Ptr& owner)
+{
+       Service::Ptr service;
+       Host::Ptr host;
+       Dictionary::Ptr downtimes;
+
+       if (owner->GetType() == DynamicType::GetByName("Service")) {
+               service = dynamic_pointer_cast<Service>(owner);
+               downtimes = service->GetDowntimes();
+
+               host = service->GetHost();
+       } else {
+               host = dynamic_pointer_cast<Host>(owner);
+               downtimes = host->GetDowntimes();
+       }
+
+       if (!downtimes)
+               return;
+
+       String id;
+       Dictionary::Ptr downtime;
+       BOOST_FOREACH(tie(id, downtime), downtimes) {
+               if (!service)
+                       fp << "hostdowntime {" << "\n";
+               else
+                       fp << "servicedowntime {" << "\n"
+                          << "\t" << "service_description=" << service->GetAlias() << "\n";
+
+               fp << "\t" << "host_name=" << host->GetName() << "\n"
+                  << "\t" << "downtime_id=" << id << "\n"
+                  << "\t" << "entry_time=" << static_cast<double>(downtime->Get("entry_time")) << "\n"
+                  << "\t" << "start_time=" << static_cast<double>(downtime->Get("start_time")) << "\n"
+                  << "\t" << "end_time=" << static_cast<double>(downtime->Get("end_time")) << "\n"
+                  << "\t" << "triggered_by=" << static_cast<long>(downtime->Get("triggered_by")) << "\n"
+                  << "\t" << "fixed=" << static_cast<long>(downtime->Get("fixed")) << "\n"
+                  << "\t" << "duration=" << static_cast<long>(downtime->Get("duration")) << "\n"
+                  << "\t" << "is_in_effect=" << (DowntimeProcessor::IsDowntimeActive(downtime) ? 1 : 0) << "\n"
+                  << "\t" << "author=" << static_cast<String>(downtime->Get("author")) << "\n"
+                  << "\t" << "comment=" << static_cast<String>(downtime->Get("comment")) << "\n"
+                  << "\t" << "trigger_time=" << 0 << "\n"
+                  << "\t" << "}" << "\n"
+                  << "\n";
+       }
+}
+
 void CompatComponent::DumpHostStatus(ofstream& fp, const Host::Ptr& host)
 {
        int state;
@@ -187,8 +232,11 @@ void CompatComponent::DumpHostStatus(ofstream& fp, const Host::Ptr& host)
           << "\t" << "problem_has_been_acknowledged=" << (host->GetAcknowledgement() != AcknowledgementNone ? 1 : 0) << "\n"
           << "\t" << "acknowledgement_type=" << static_cast<int>(host->GetAcknowledgement()) << "\n"
           << "\t" << "acknowledgement_end_time=" << host->GetAcknowledgementExpiry() << "\n"
+          << "\t" << "scheduled_downtime_depth=" << (host->IsInDowntime() ? 1 : 0) << "\n"
           << "\t" << "}" << "\n"
           << "\n";
+
+       DumpDowntimes(fp, host);
 }
 
 void CompatComponent::DumpHostObject(ofstream& fp, const Host::Ptr& host)
@@ -264,8 +312,11 @@ void CompatComponent::DumpServiceStatus(ofstream& fp, const Service::Ptr& servic
           << "\t" << "problem_has_been_acknowledged=" << (service->GetAcknowledgement() != AcknowledgementNone ? 1 : 0) << "\n"
           << "\t" << "acknowledgement_type=" << static_cast<int>(service->GetAcknowledgement()) << "\n"
           << "\t" << "acknowledgement_end_time=" << service->GetAcknowledgementExpiry() << "\n"
+          << "\t" << "scheduled_downtime_depth=" << (service->IsInDowntime() ? 1 : 0) << "\n"
           << "\t" << "}" << "\n"
           << "\n";
+
+       DumpDowntimes(fp, service);
 }
 
 void CompatComponent::DumpServiceObject(ofstream& fp, const Service::Ptr& service)
@@ -324,6 +375,7 @@ void CompatComponent::StatusTimerHandler(void)
                 << "\t" << "enable_failure_prediction=0" << "\n"
                 << "\t" << "active_scheduled_service_check_stats=" << CIB::GetActiveChecksStatistics(60) << "," << CIB::GetActiveChecksStatistics(5 * 60) << "," << CIB::GetActiveChecksStatistics(15 * 60) << "\n"
                 << "\t" << "passive_service_check_stats=" << CIB::GetPassiveChecksStatistics(60) << "," << CIB::GetPassiveChecksStatistics(5 * 60) << "," << CIB::GetPassiveChecksStatistics(15 * 60) << "\n"
+                << "\t" << "next_downtime_id=" << DowntimeProcessor::GetNextDowntimeID() << "\n"
                 << "\t" << "}" << "\n"
                 << "\n";
 
index 1f645dc6c685a3a34e90c5913472088e0166564b..693c559e9347de4ed14b3e5a2786f2206b5dd621 100644 (file)
@@ -46,6 +46,7 @@ private:
        String GetObjectsPath(void) const;
        String GetCommandPath(void) const;
 
+       void DumpDowntimes(ofstream& fp, const DynamicObject::Ptr& owner);
        void DumpHostStatus(ofstream& fp, const Host::Ptr& host);
        void DumpHostObject(ofstream& fp, const Host::Ptr& host);
 
index 0ec12ad5b78d303057dcf0fc4e0596b0c96f76c3..85f814864ded991a0df8014fecd1fb4cada7d16e 100644 (file)
@@ -174,6 +174,7 @@ namespace tuples = boost::tuples;
 #include "exception.h"
 #include "event.h"
 #include "value.h"
+#include "convert.h"
 #include "dictionary.h"
 #include "ringbuffer.h"
 #include "timer.h"
index 0650d2e29da805611db243559283a7d15fcc9a2c..281fb0e7ea1c495cb5b08c531fa931a5b7ffdbfa 100644 (file)
@@ -8,6 +8,8 @@ libicinga_la_SOURCES =  \
        acknowledgement.h \
        cib.cpp \
        cib.h \
+       downtimeprocessor.cpp \
+       downtimeprocessor.h \
        externalcommand.cpp \
        externalcommand.h \
        host.cpp \
index dcddf090f4a7c243328ab7f8da034e060d287e6b..7af4c1fc0ed0c38fd86759ec6fc9aa04193ff266 100644 (file)
@@ -85,6 +85,15 @@ void ExternalCommand::Execute(double time, const String& command, const vector<S
                RegisterCommand("ENABLE_HOSTGROUP_PASSIVE_SVC_CHECKS", &ExternalCommand::EnableHostgroupPassiveSvcChecks);
                RegisterCommand("DISABLE_HOSTGROUP_PASSIVE_SVC_CHECKS", &ExternalCommand::DisableHostgroupPassiveSvcChecks);
                RegisterCommand("PROCESS_FILE", &ExternalCommand::ProcessFile);
+               RegisterCommand("SCHEDULE_SVC_DOWNTIME", &ExternalCommand::ScheduleSvcDowntime);
+               RegisterCommand("DEL_SVC_DOWNTIME", &ExternalCommand::DelSvcDowntime);
+               RegisterCommand("SCHEDULE_HOST_DOWNTIME", &ExternalCommand::ScheduleHostDowntime);
+               RegisterCommand("DEL_HOST_DOWNTIME", &ExternalCommand::DelHostDowntime);
+               RegisterCommand("SCHEDULE_HOST_SVC_DOWNTIME", &ExternalCommand::ScheduleHostSvcDowntime);
+               RegisterCommand("SCHEDULE_HOSTGROUP_HOST_DOWNTIME", &ExternalCommand::ScheduleHostgroupHostDowntime);
+               RegisterCommand("SCHEDULE_HOSTGROUP_SVC_DOWNTIME", &ExternalCommand::ScheduleHostgroupSvcDowntime);
+               RegisterCommand("SCHEDULE_SERVICEGROUP_HOST_DOWNTIME", &ExternalCommand::ScheduleServicegroupHostDowntime);
+               RegisterCommand("SCHEDULE_SERVICEGROUP_SVC_DOWNTIME", &ExternalCommand::ScheduleServicegroupSvcDowntime);
 
                m_Initialized = true;
        }
@@ -224,13 +233,7 @@ void ExternalCommand::ScheduleForcedHostSvcChecks(double time, const vector<Stri
 
        Host::Ptr host = Host::GetByName(arguments[0]);
 
-       DynamicObject::Ptr object;
-       BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Service")->GetObjects()) {
-               Service::Ptr service = static_pointer_cast<Service>(object);
-
-               if (service->GetHost() != host)
-                       continue;
-
+       BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
                Logger::Write(LogInformation, "icinga", "Rescheduling next check for service '" + service->GetName() + "'");
                service->SetNextCheck(planned_check);
                service->SetForceNextCheck(true);
@@ -249,13 +252,7 @@ void ExternalCommand::ScheduleHostSvcChecks(double time, const vector<String>& a
 
        Host::Ptr host = Host::GetByName(arguments[0]);
 
-       DynamicObject::Ptr object;
-       BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Service")->GetObjects()) {
-               Service::Ptr service = static_pointer_cast<Service>(object);
-
-               if (service->GetHost() != host)
-                       continue;
-
+       BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
                if (planned_check > service->GetNextCheck()) {
                        Logger::Write(LogInformation, "icinga", "Ignoring reschedule request for service '" +
                            service->GetName() + "' (next check is already sooner than requested check time)");
@@ -277,13 +274,7 @@ void ExternalCommand::EnableHostSvcChecks(double time, const vector<String>& arg
 
        Host::Ptr host = Host::GetByName(arguments[0]);
 
-       DynamicObject::Ptr object;
-       BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Service")->GetObjects()) {
-               Service::Ptr service = static_pointer_cast<Service>(object);
-
-               if (service->GetHost() != host)
-                       continue;
-
+       BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
                Logger::Write(LogInformation, "icinga", "Enabling active checks for service '" + service->GetName() + "'");
                service->SetEnableActiveChecks(true);
        }
@@ -299,13 +290,7 @@ void ExternalCommand::DisableHostSvcChecks(double time, const vector<String>& ar
 
        Host::Ptr host = Host::GetByName(arguments[0]);
 
-       DynamicObject::Ptr object;
-       BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Service")->GetObjects()) {
-               Service::Ptr service = static_pointer_cast<Service>(object);
-
-               if (service->GetHost() != host)
-                       continue;
-
+       BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
                Logger::Write(LogInformation, "icinga", "Disabling active checks for service '" + service->GetName() + "'");
                service->SetEnableActiveChecks(false);
        }
@@ -620,3 +605,127 @@ void ExternalCommand::ProcessFile(double time, const vector<String>& arguments)
        if (del)
                (void) unlink(file.CStr());
 }
+
+void ExternalCommand::ScheduleSvcDowntime(double time, const vector<String>& arguments)
+{
+       if (arguments.size() < 9)
+               throw_exception(invalid_argument("Expected 9 arguments."));
+
+       if (!Service::Exists(arguments[1]))
+               throw_exception(invalid_argument("The service '" + arguments[1] + "' does not exist."));
+
+       Service::Ptr service = Service::GetByName(arguments[1]);
+
+       Logger::Write(LogInformation, "icinga", "Creating downtime for service " + service->GetName());
+
+       (void) DowntimeProcessor::AddDowntime(service, arguments[7], arguments[8],
+           Convert::ToDouble(arguments[2]), Convert::ToDouble(arguments[3]),
+           Convert::ToBool(arguments[4]), Convert::ToLong(arguments[5]), Convert::ToDouble(arguments[6]));
+}
+
+void ExternalCommand::DelSvcDowntime(double time, const vector<String>& arguments)
+{
+       if (arguments.size() < 1)
+               throw_exception(invalid_argument("Expected 1 argument."));
+
+       String id = arguments[0];
+       Logger::Write(LogInformation, "icinga", "Removing downtime ID " + id);
+       DowntimeProcessor::RemoveDowntime(Convert::ToLong(id));
+}
+
+void ExternalCommand::ScheduleHostDowntime(double time, const vector<String>& arguments)
+{
+       if (arguments.size() < 8)
+               throw_exception(invalid_argument("Expected 8 arguments."));
+
+       if (!Host::Exists(arguments[0]))
+               throw_exception(invalid_argument("The host '" + arguments[0] + "' does not exist."));
+
+       Host::Ptr host = Host::GetByName(arguments[0]);
+
+       Logger::Write(LogInformation, "icinga", "Creating downtime for host " + host->GetName());
+
+       (void) DowntimeProcessor::AddDowntime(host, arguments[6], arguments[7],
+           Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
+           Convert::ToBool(arguments[3]), Convert::ToLong(arguments[4]), Convert::ToDouble(arguments[5]));
+}
+
+void ExternalCommand::DelHostDowntime(double time, const vector<String>& arguments)
+{
+       if (arguments.size() < 1)
+               throw_exception(invalid_argument("Expected 1 argument."));
+
+       String id = arguments[0];
+       Logger::Write(LogInformation, "icinga", "Removing downtime ID " + id);
+       DowntimeProcessor::RemoveDowntime(Convert::ToLong(id));
+}
+
+void ExternalCommand::ScheduleHostSvcDowntime(double time, const vector<String>& arguments)
+{
+       if (arguments.size() < 8)
+               throw_exception(invalid_argument("Expected 8 argument."));
+
+       if (!Host::Exists(arguments[0]))
+               throw_exception(invalid_argument("The host '" + arguments[0] + "' does not exist."));
+
+       Host::Ptr host = Host::GetByName(arguments[0]);
+
+       Logger::Write(LogInformation, "icinga", "Creating downtime for host " + host->GetName());
+       (void) DowntimeProcessor::AddDowntime(host, arguments[6], arguments[7],
+           Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
+           Convert::ToBool(arguments[3]), Convert::ToLong(arguments[4]), Convert::ToDouble(arguments[5]));
+
+       BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) {
+               Logger::Write(LogInformation, "icinga", "Creating downtime for service " + service->GetName());
+               (void) DowntimeProcessor::AddDowntime(service, arguments[6], arguments[7],
+                   Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
+                   Convert::ToBool(arguments[3]), Convert::ToLong(arguments[4]), Convert::ToDouble(arguments[5]));
+       }
+}
+
+void ExternalCommand::ScheduleHostgroupHostDowntime(double time, const vector<String>& arguments)
+{
+       if (arguments.size() < 8)
+               throw_exception(invalid_argument("Expected 8 arguments."));
+
+       if (!HostGroup::Exists(arguments[0]))
+               throw_exception(invalid_argument("The host group '" + arguments[0] + "' does not exist."));
+
+       HostGroup::Ptr hg = HostGroup::GetByName(arguments[0]);
+
+       BOOST_FOREACH(const Host::Ptr& host, hg->GetMembers()) {
+               Logger::Write(LogInformation, "icinga", "Creating downtime for host " + host->GetName());
+               (void) DowntimeProcessor::AddDowntime(host, arguments[6], arguments[7],
+                   Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
+                   Convert::ToBool(arguments[3]), Convert::ToLong(arguments[4]), Convert::ToDouble(arguments[5]));
+       }
+}
+
+void ExternalCommand::ScheduleHostgroupSvcDowntime(double time, const vector<String>& arguments)
+{
+       // TODO: implement (#3582)
+}
+
+void ExternalCommand::ScheduleServicegroupHostDowntime(double time, const vector<String>& arguments)
+{
+       // TODO: implement (#3582)
+}
+
+void ExternalCommand::ScheduleServicegroupSvcDowntime(double time, const vector<String>& arguments)
+{
+       if (arguments.size() < 8)
+               throw_exception(invalid_argument("Expected 8 arguments."));
+
+       if (!ServiceGroup::Exists(arguments[0]))
+               throw_exception(invalid_argument("The host group '" + arguments[0] + "' does not exist."));
+
+       ServiceGroup::Ptr sg = ServiceGroup::GetByName(arguments[0]);
+
+       BOOST_FOREACH(const Service::Ptr& service, sg->GetMembers()) {
+               Logger::Write(LogInformation, "icinga", "Creating downtime for service " + service->GetName());
+               (void) DowntimeProcessor::AddDowntime(service, arguments[6], arguments[7],
+                   Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
+                   Convert::ToBool(arguments[3]), Convert::ToLong(arguments[4]), Convert::ToDouble(arguments[5]));
+       }
+}
+
index fd24708ee439dbd388d1eb02506f0bb7d24f24ee..70084b45a6de92d1b578256d6a62edc978b12c28 100644 (file)
@@ -56,6 +56,15 @@ public:
        static void EnableHostgroupPassiveSvcChecks(double time, const vector<String>& arguments);
        static void DisableHostgroupPassiveSvcChecks(double time, const vector<String>& arguments);
        static void ProcessFile(double time, const vector<String>& arguments);
+       static void ScheduleSvcDowntime(double time, const vector<String>& arguments);
+       static void DelSvcDowntime(double time, const vector<String>& arguments);
+       static void ScheduleHostDowntime(double time, const vector<String>& arguments);
+       static void DelHostDowntime(double time, const vector<String>& arguments);
+       static void ScheduleHostSvcDowntime(double time, const vector<String>& arguments);
+       static void ScheduleHostgroupHostDowntime(double time, const vector<String>& arguments);
+       static void ScheduleHostgroupSvcDowntime(double time, const vector<String>& arguments);
+       static void ScheduleServicegroupHostDowntime(double time, const vector<String>& arguments);
+       static void ScheduleServicegroupSvcDowntime(double time, const vector<String>& arguments);
 
 private:
        typedef function<void (double time, const vector<String>& arguments)> Callback;
index 63696755406ba9df6eacc13d671f199181a8c88c..4d38481d4d4a4634bb046d48c397ab38c6441f1c 100644 (file)
@@ -30,7 +30,8 @@ static AttributeDescription hostAttributes[] = {
        { "dependencies", Attribute_Config },
        { "hostchecks", Attribute_Config },
        { "acknowledgement", Attribute_Replicated },
-       { "acknowledgement_expiry", Attribute_Replicated }
+       { "acknowledgement_expiry", Attribute_Replicated },
+       { "downtimes", Attribute_Replicated }
 };
 
 REGISTER_TYPE(Host, hostAttributes);
@@ -48,11 +49,13 @@ Host::Host(const Dictionary::Ptr& properties)
        }
 
        HostGroup::InvalidateMembersCache();
+       DowntimeProcessor::InvalidateDowntimeCache();
 }
 
 Host::~Host(void)
 {
        HostGroup::InvalidateMembersCache();
+       DowntimeProcessor::InvalidateDowntimeCache();
 }
 
 String Host::GetAlias(void) const
@@ -114,6 +117,11 @@ Dictionary::Ptr Host::GetMacros(void) const
        return Get("macros");
 }
 
+Dictionary::Ptr Host::GetDowntimes(void) const
+{
+       return Get("downtimes");
+}
+
 bool Host::IsReachable(void)
 {
        Dictionary::Ptr dependencies = Get("dependencies");
@@ -134,6 +142,22 @@ bool Host::IsReachable(void)
        return true;
 }
 
+bool Host::IsInDowntime(void) const
+{
+       Dictionary::Ptr downtimes = GetDowntimes();
+
+       if (!downtimes)
+               return false;
+
+       Dictionary::Ptr downtime;
+       BOOST_FOREACH(tie(tuples::ignore, downtime), downtimes) {
+               if (DowntimeProcessor::IsDowntimeActive(downtime))
+                       return true;
+       }
+
+       return false;
+}
+
 bool Host::IsUp(void)
 {
        Dictionary::Ptr hostchecks = Get("hostchecks");
@@ -291,6 +315,8 @@ void Host::OnAttributeChanged(const String& name, const Value& oldValue)
 {
        if (name == "hostgroups")
                HostGroup::InvalidateMembersCache();
+       else if (name == "downtimes")
+               DowntimeProcessor::InvalidateDowntimeCache();
 }
 
 set<Service::Ptr> Host::GetServices(void) const
index a3797b5d3568168cce9e2f96e7220992304184b6..8ebc67d85062badb33bae49104b2e355708ca104 100644 (file)
@@ -47,6 +47,7 @@ public:
 
        set<Host::Ptr> GetParents(void);
        Dictionary::Ptr GetMacros(void) const;
+       Dictionary::Ptr GetDowntimes(void) const;
 
        AcknowledgementType GetAcknowledgement(void);
        void SetAcknowledgement(AcknowledgementType acknowledgement);
@@ -55,6 +56,7 @@ public:
        void SetAcknowledgementExpiry(double timestamp);
 
        bool IsReachable(void);
+       bool IsInDowntime(void) const;
        bool IsUp(void);
 
        set<shared_ptr<Service> > GetServices(void) const;
index bfb6a0ba20ce6fd167d6a13a6dfac61a65525b26..e2ba50273d81d01b9c563a0e9cd7722769f3e38c 100644 (file)
@@ -49,6 +49,7 @@ using boost::algorithm::is_any_of;
 #include "timeperiod.h"
 
 #include "acknowledgement.h"
+#include "downtimeprocessor.h"
 
 #include "host.h"
 #include "hostgroup.h"
index 56c4d0e9f2e3472b1e60dfc48ab9a226990a2b95..e517851612a815fed422a63e8eed89c1247a5a92 100644 (file)
@@ -47,7 +47,8 @@ static AttributeDescription serviceAttributes[] = {
        { "enable_passive_checks", Attribute_Replicated },
        { "force_next_check", Attribute_Replicated },
        { "acknowledgement", Attribute_Replicated },
-       { "acknowledgement_expiry", Attribute_Replicated }
+       { "acknowledgement_expiry", Attribute_Replicated },
+       { "downtimes", Attribute_Replicated }
 };
 
 REGISTER_TYPE(Service, serviceAttributes);
@@ -66,12 +67,14 @@ Service::Service(const Dictionary::Ptr& serializedObject)
 {
        ServiceGroup::InvalidateMembersCache();
        Host::InvalidateServicesCache();
+       DowntimeProcessor::InvalidateDowntimeCache();
 }
 
 Service::~Service(void)
 {
        ServiceGroup::InvalidateMembersCache();
        Host::InvalidateServicesCache();
+       DowntimeProcessor::InvalidateDowntimeCache();
 }
 
 String Service::GetAlias(void) const
@@ -114,6 +117,11 @@ Dictionary::Ptr Service::GetMacros(void) const
        return Get("macros");
 }
 
+Dictionary::Ptr Service::GetDowntimes(void) const
+{
+       return Get("downtimes");
+}
+
 String Service::GetCheckCommand(void) const
 {
        return Get("check_command");
@@ -219,6 +227,22 @@ bool Service::IsReachable(void) const
        return true;
 }
 
+bool Service::IsInDowntime(void) const
+{
+       Dictionary::Ptr downtimes = GetDowntimes();
+
+       if (!downtimes)
+               return false;
+
+       Dictionary::Ptr downtime;
+       BOOST_FOREACH(tie(tuples::ignore, downtime), downtimes) {
+               if (DowntimeProcessor::IsDowntimeActive(downtime))
+                       return true;
+       }
+
+       return false;
+}
+
 void Service::SetSchedulingOffset(long offset)
 {
        Set("scheduling_offset", offset);
@@ -626,6 +650,8 @@ void Service::OnAttributeChanged(const String& name, const Value& oldValue)
                ServiceGroup::InvalidateMembersCache();
        else if (name == "host_name")
                Host::InvalidateServicesCache();
+       else if (name == "downtimes")
+               DowntimeProcessor::InvalidateDowntimeCache();
 }
 
 void Service::BeginExecuteCheck(const function<void (void)>& callback)
index a9a5980c452c35d9bb9460eaddfb93250f8ebe30..489f886c25fc3254c3a560929b67a8e67136e7c1 100644 (file)
@@ -76,6 +76,7 @@ public:
        String GetAlias(void) const;
        Host::Ptr GetHost(void) const;
        Dictionary::Ptr GetMacros(void) const;
+       Dictionary::Ptr GetDowntimes(void) const;
        String GetCheckCommand(void) const;
        long GetMaxCheckAttempts(void) const;
        long GetCheckInterval(void) const;
@@ -86,6 +87,7 @@ public:
        Dictionary::Ptr GetCheckers(void) const;
 
        bool IsReachable(void) const;
+       bool IsInDowntime(void) const;
 
        long GetSchedulingOffset(void);
        void SetSchedulingOffset(long offset);