mirror of https://github.com/Icinga/icinga2.git
parent
99f2b0673e
commit
41ded2858c
|
@ -1272,7 +1272,8 @@ void ClusterListener::MessageHandler(const Endpoint::Ptr& sender, const Dictiona
|
|||
service->AddDowntime(downtime->GetAuthor(), downtime->GetComment(),
|
||||
downtime->GetStartTime(), downtime->GetEndTime(),
|
||||
downtime->GetFixed(), downtime->GetTriggeredBy(),
|
||||
downtime->GetDuration(), downtime->GetId(), sender->GetName());
|
||||
downtime->GetDuration(), downtime->GetScheduledBy(),
|
||||
downtime->GetId(), sender->GetName());
|
||||
|
||||
AsyncRelayMessage(sender, message, true);
|
||||
} else if (message->Get("method") == "cluster::RemoveDowntime") {
|
||||
|
|
|
@ -311,6 +311,44 @@ Attributes:
|
|||
The `/etc/icinga2/conf.d/timeperiods.conf` file is usually used to define
|
||||
timeperiods including this one.
|
||||
|
||||
### <a id="objecttype-scheduleddowntime"></a> ScheduledDowntime
|
||||
|
||||
ScheduledDowntime objects can be used to set up recurring downtimes for services.
|
||||
|
||||
> **Best Practice**
|
||||
>
|
||||
> Rather than creating a `ScheduledDowntime` object for a specific service it is usually easier
|
||||
> to just create a `ScheduledDowntime` template and using the `scheduled_downtimes` attribute in the `Service`
|
||||
> object to associate these templates with a service.
|
||||
|
||||
Example:
|
||||
|
||||
object ScheduledDowntime "some-downtime" {
|
||||
host = "localhost",
|
||||
service = "ping4",
|
||||
|
||||
author = "icingaadmin",
|
||||
comment = "Some comment",
|
||||
|
||||
fixed = false,
|
||||
duration = 30m,
|
||||
|
||||
ranges = {
|
||||
"sunday" = "02:00-03:00"
|
||||
}
|
||||
}
|
||||
|
||||
Attributes:
|
||||
|
||||
Name |Description
|
||||
----------------|----------------
|
||||
host |**Required.** The name of the host this notification belongs to.
|
||||
service |**Required.** The short name of the service this notification belongs to.
|
||||
author |**Required.** The author of the downtime.
|
||||
comment |**Required.** A comment for the downtime.
|
||||
fixed |**Optional.** Whether this is a fixed downtime. Defaults to true.
|
||||
duration |**Optional.** How long the downtime lasts. Only has an effect for flexible (non-fixed) downtimes.
|
||||
ranges |**Required.** A dictionary containing information which days and durations apply to this timeperiod.
|
||||
|
||||
### <a id="objecttype-consolelogger"></a> ConsoleLogger
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ include(InstallConfig)
|
|||
configure_file(icinga/icinga-classic-apache.conf.cmake ${CMAKE_CURRENT_BINARY_DIR}/icinga/icinga-classic-apache.conf)
|
||||
|
||||
install_if_not_exists(icinga2/icinga2.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2)
|
||||
install_if_not_exists(icinga2/conf.d/downtimes.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d)
|
||||
install_if_not_exists(icinga2/conf.d/generic-host.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d)
|
||||
install_if_not_exists(icinga2/conf.d/generic-service.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d)
|
||||
install_if_not_exists(icinga2/conf.d/generic-user.conf ${CMAKE_INSTALL_SYSCONFDIR}/icinga2/conf.d)
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
* The example downtime templates.
|
||||
*/
|
||||
|
||||
template ScheduledDowntime "backup-downtime" {
|
||||
author = "icingaadmin",
|
||||
comment = "Scheduled downtime for backup",
|
||||
|
||||
ranges = {
|
||||
monday = "02:00-03:00",
|
||||
tuesday = "02:00-03:00",
|
||||
wednesday = "02:00-03:00",
|
||||
thursday = "02:00-03:00",
|
||||
friday = "02:00-03:00",
|
||||
saturday = "02:00-03:00",
|
||||
sunday = "02:00-03:00"
|
||||
}
|
||||
}
|
||||
|
|
@ -39,7 +39,11 @@ object Host "localhost" inherits "linux-server" {
|
|||
services["load"] = {
|
||||
templates = [ "generic-service" ],
|
||||
|
||||
check_command = "load"
|
||||
check_command = "load",
|
||||
|
||||
scheduled_downtimes["backup"] = {
|
||||
templates = [ "backup-downtime" ]
|
||||
}
|
||||
},
|
||||
|
||||
services["processes"] = {
|
||||
|
|
|
@ -278,7 +278,9 @@ void DynamicObject::RestoreObjects(const String& filename, int attributeTypes)
|
|||
|
||||
if (object) {
|
||||
ASSERT(!object->IsActive());
|
||||
#ifdef _DEBUG
|
||||
Log(LogDebug, "base", "Restoring object '" + name + "' of type '" + type + "'.");
|
||||
#endif /* _DEBUG */
|
||||
Deserialize(object, update, attributeTypes);
|
||||
object->OnStateLoaded();
|
||||
}
|
||||
|
|
|
@ -744,3 +744,28 @@ int Utility::Random(void)
|
|||
|
||||
return rand();
|
||||
}
|
||||
|
||||
tm Utility::LocalTime(time_t ts)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
tm *result = localtime(&ts);
|
||||
|
||||
if (temp == NULL) {
|
||||
BOOST_THROW_EXCEPTION(posix_error()
|
||||
<< boost::errinfo_api_function("localtime")
|
||||
<< boost::errinfo_errno(errno));
|
||||
}
|
||||
|
||||
return *result;
|
||||
#else /* _MSC_VER */
|
||||
tm result;
|
||||
|
||||
if (localtime_r(&ts, &result) == NULL) {
|
||||
BOOST_THROW_EXCEPTION(posix_error()
|
||||
<< boost::errinfo_api_function("localtime_r")
|
||||
<< boost::errinfo_errno(errno));
|
||||
}
|
||||
|
||||
return result;
|
||||
#endif /* _MSC_VER */
|
||||
}
|
|
@ -108,6 +108,8 @@ public:
|
|||
|
||||
static int Random(void);
|
||||
|
||||
static tm LocalTime(time_t ts);
|
||||
|
||||
private:
|
||||
Utility(void);
|
||||
|
||||
|
|
|
@ -157,7 +157,9 @@ DynamicObject::Ptr ConfigItem::Commit(void)
|
|||
{
|
||||
ASSERT(!OwnsLock());
|
||||
|
||||
#ifdef _DEBUG
|
||||
Log(LogDebug, "base", "Commit called for ConfigItem Type=" + GetType() + ", Name=" + GetName());
|
||||
#endif /* _DEBUG */
|
||||
|
||||
/* Make sure the type is valid. */
|
||||
DynamicType::Ptr dtype = DynamicType::GetByName(GetType());
|
||||
|
@ -284,7 +286,9 @@ bool ConfigItem::ActivateItems(bool validateOnly)
|
|||
if (object->IsActive())
|
||||
continue;
|
||||
|
||||
#ifdef _DEBUG
|
||||
Log(LogDebug, "config", "Activating object '" + object->GetName() + "' of type '" + object->GetType()->GetName() + "'");
|
||||
#endif /* _DEBUG */
|
||||
object->Start();
|
||||
|
||||
ASSERT(object->IsActive());
|
||||
|
|
|
@ -28,7 +28,7 @@ add_library(db_ido SHARED
|
|||
)
|
||||
|
||||
include_directories(${Boost_INCLUDE_DIRS})
|
||||
target_link_libraries(db_ido ${Boost_LIBRARIES} base config icinga methods)
|
||||
target_link_libraries(db_ido ${Boost_LIBRARIES} base config icinga)
|
||||
|
||||
set_target_properties (
|
||||
db_ido PROPERTIES
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "db_ido/dbtype.h"
|
||||
#include "db_ido/dbvalue.h"
|
||||
#include "icinga/timeperiod.h"
|
||||
#include "methods/legacytimeperiod.h"
|
||||
#include "icinga/legacytimeperiod.h"
|
||||
#include "base/utility.h"
|
||||
#include "base/exception.h"
|
||||
#include "base/objectlock.h"
|
||||
|
@ -75,25 +75,7 @@ void TimePeriodDbObject::OnConfigUpdate(void)
|
|||
if (wday == -1)
|
||||
continue;
|
||||
|
||||
tm reference;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
tm *temp = localtime(&refts);
|
||||
|
||||
if (temp == NULL) {
|
||||
BOOST_THROW_EXCEPTION(posix_error()
|
||||
<< boost::errinfo_api_function("localtime")
|
||||
<< boost::errinfo_errno(errno));
|
||||
}
|
||||
|
||||
reference = *temp;
|
||||
#else /* _MSC_VER */
|
||||
if (localtime_r(&refts, &reference) == NULL) {
|
||||
BOOST_THROW_EXCEPTION(posix_error()
|
||||
<< boost::errinfo_api_function("localtime_r")
|
||||
<< boost::errinfo_errno(errno));
|
||||
}
|
||||
#endif /* _MSC_VER */
|
||||
tm reference = Utility::LocalTime(refts);
|
||||
|
||||
Array::Ptr segments = make_shared<Array>();
|
||||
LegacyTimePeriod::ProcessTimeRanges(kv.second, &reference, segments);
|
||||
|
|
|
@ -28,6 +28,7 @@ mkclass_target(icingaapplication.ti icingaapplication.th)
|
|||
mkclass_target(notificationcommand.ti notificationcommand.th)
|
||||
mkclass_target(notification.ti notification.th)
|
||||
mkclass_target(perfdatavalue.ti perfdatavalue.th)
|
||||
mkclass_target(scheduleddowntime.ti scheduleddowntime.th)
|
||||
mkclass_target(servicegroup.ti servicegroup.th)
|
||||
mkclass_target(service.ti service.th)
|
||||
mkclass_target(timeperiod.ti timeperiod.th)
|
||||
|
@ -41,9 +42,10 @@ add_library(icinga SHARED
|
|||
cib.cpp command.cpp command.th comment.cpp comment.th compatutility.cpp
|
||||
domain.cpp domain.th downtime.cpp downtime.th eventcommand.cpp eventcommand.th
|
||||
externalcommandprocessor.cpp host.cpp host.th hostgroup.cpp hostgroup.th
|
||||
icingaapplication.cpp icingaapplication.th macroprocessor.cpp macroresolver.cpp
|
||||
notificationcommand.cpp notificationcommand.th notification.cpp notification.th
|
||||
perfdatavalue.cpp perfdatavalue.th pluginutility.cpp service-check.cpp
|
||||
icingaapplication.cpp icingaapplication.th legacytimeperiod.cpp
|
||||
macroprocessor.cpp macroresolver.cpp notificationcommand.cpp notificationcommand.th
|
||||
notification.cpp notification.th perfdatavalue.cpp perfdatavalue.th
|
||||
pluginutility.cpp scheduleddowntime.cpp scheduleddowntime.th service-check.cpp
|
||||
service-comment.cpp service.cpp service-downtime.cpp service-event.cpp
|
||||
service-flapping.cpp service.th servicegroup.cpp servicegroup.th
|
||||
service-notification.cpp timeperiod.cpp timeperiod.th user.cpp user.th
|
||||
|
|
|
@ -13,6 +13,7 @@ class Downtime
|
|||
[state] bool fixed;
|
||||
[state] double duration;
|
||||
[state] String triggered_by;
|
||||
[state] String scheduled_by;
|
||||
[state] Dictionary::Ptr triggers {
|
||||
default {{{ return make_shared<Dictionary>(); }}}
|
||||
};
|
||||
|
|
|
@ -116,6 +116,16 @@ type Service {
|
|||
}
|
||||
},
|
||||
|
||||
%attribute dictionary "scheduled_downtimes" {
|
||||
%attribute dictionary "*" {
|
||||
%attribute array "templates" {
|
||||
%attribute name(ScheduledDowntime) "*"
|
||||
},
|
||||
|
||||
%attribute any "*"
|
||||
}
|
||||
},
|
||||
|
||||
%attribute any "templates"
|
||||
}
|
||||
|
||||
|
@ -126,6 +136,8 @@ type ServiceGroup {
|
|||
type Notification {
|
||||
%require "host",
|
||||
%attribute name(Host) "host",
|
||||
|
||||
%require "service",
|
||||
%attribute string "service",
|
||||
|
||||
%attribute dictionary "macros" {
|
||||
|
@ -237,3 +249,26 @@ type Domain {
|
|||
%attribute number "*"
|
||||
}
|
||||
}
|
||||
|
||||
type ScheduledDowntime {
|
||||
%require "host",
|
||||
%attribute name(Host) "host",
|
||||
%require "service",
|
||||
%attribute string "service",
|
||||
|
||||
%require "author",
|
||||
%attribute string "author",
|
||||
|
||||
%require "comment",
|
||||
%attribute string "comment",
|
||||
|
||||
%attribute number "duration",
|
||||
%attribute number "fixed",
|
||||
|
||||
%require "ranges",
|
||||
%attribute dictionary "ranges" {
|
||||
%attribute string "*"
|
||||
},
|
||||
|
||||
%attribute any "templates"
|
||||
}
|
||||
|
|
|
@ -17,13 +17,14 @@
|
|||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#include "methods/legacytimeperiod.h"
|
||||
#include "icinga/legacytimeperiod.h"
|
||||
#include "base/scriptfunction.h"
|
||||
#include "base/convert.h"
|
||||
#include "base/exception.h"
|
||||
#include "base/objectlock.h"
|
||||
#include "base/logger_fwd.h"
|
||||
#include "base/debug.h"
|
||||
#include "base/utility.h"
|
||||
#include <boost/algorithm/string/split.hpp>
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
@ -141,12 +142,12 @@ void LegacyTimePeriod::ParseTimeSpec(const String& timespec, tm *begin, tm *end,
|
|||
if (timespec.GetLength() == 10 && timespec[4] == '-' && timespec[7] == '-') {
|
||||
int year = Convert::ToLong(timespec.SubStr(0, 4));
|
||||
int month = Convert::ToLong(timespec.SubStr(5, 2));
|
||||
int day = Convert::ToLong(timespec.SubStr(7, 2));
|
||||
int day = Convert::ToLong(timespec.SubStr(8, 2));
|
||||
|
||||
if (begin) {
|
||||
begin->tm_year = year - 1900;
|
||||
begin->tm_mon = month;
|
||||
begin->tm_mday = day;
|
||||
begin->tm_mday = day + 1;
|
||||
begin->tm_hour = 0;
|
||||
begin->tm_min = 0;
|
||||
begin->tm_sec = 0;
|
||||
|
@ -155,7 +156,7 @@ void LegacyTimePeriod::ParseTimeSpec(const String& timespec, tm *begin, tm *end,
|
|||
if (end) {
|
||||
end->tm_year = year - 1900;
|
||||
end->tm_mon = month;
|
||||
end->tm_mday = day;
|
||||
end->tm_mday = day + 1;
|
||||
end->tm_hour = 24;
|
||||
end->tm_min = 0;
|
||||
end->tm_sec = 0;
|
||||
|
@ -380,6 +381,64 @@ void LegacyTimePeriod::ProcessTimeRanges(const String& timeranges, tm *reference
|
|||
}
|
||||
}
|
||||
|
||||
Dictionary::Ptr LegacyTimePeriod::FindNextSegment(const String& daydef, const String& timeranges, tm *reference)
|
||||
{
|
||||
tm begin, end, iter, ref;
|
||||
time_t tsend, tsiter, tsref;
|
||||
int stride;
|
||||
|
||||
for (int pass = 1; pass <= 2; pass++) {
|
||||
if (pass == 1) {
|
||||
ref = *reference;
|
||||
} else {
|
||||
ref = end;
|
||||
ref.tm_mday++;
|
||||
}
|
||||
|
||||
tsref = mktime(&ref);
|
||||
|
||||
ParseTimeRange(daydef, &begin, &end, &stride, &ref);
|
||||
|
||||
iter = begin;
|
||||
|
||||
tsend = mktime(&end);
|
||||
tsiter = mktime(&iter);
|
||||
|
||||
do {
|
||||
if (IsInTimeRange(&begin, &end, stride, &iter)) {
|
||||
Array::Ptr segments = make_shared<Array>();
|
||||
ProcessTimeRanges(timeranges, &iter, segments);
|
||||
|
||||
Dictionary::Ptr bestSegment;
|
||||
double bestBegin;
|
||||
|
||||
BOOST_FOREACH(const Dictionary::Ptr& segment, segments) {
|
||||
double begin = segment->Get("begin");
|
||||
|
||||
if (begin < tsref)
|
||||
continue;
|
||||
|
||||
if (!bestSegment || begin < bestBegin) {
|
||||
bestSegment = segment;
|
||||
bestBegin = begin;
|
||||
}
|
||||
}
|
||||
|
||||
if (bestSegment)
|
||||
return bestSegment;
|
||||
}
|
||||
|
||||
iter.tm_mday++;
|
||||
iter.tm_hour = 0;
|
||||
iter.tm_min = 0;
|
||||
iter.tm_sec = 0;
|
||||
tsiter = mktime(&iter);
|
||||
} while (tsiter < tsend);
|
||||
}
|
||||
|
||||
return Dictionary::Ptr();
|
||||
}
|
||||
|
||||
Array::Ptr LegacyTimePeriod::ScriptFunc(const TimePeriod::Ptr& tp, double begin, double end)
|
||||
{
|
||||
Array::Ptr segments = make_shared<Array>();
|
||||
|
@ -389,36 +448,24 @@ Array::Ptr LegacyTimePeriod::ScriptFunc(const TimePeriod::Ptr& tp, double begin,
|
|||
if (ranges) {
|
||||
for (int i = 0; i <= (end - begin) / (24 * 60 * 60); i++) {
|
||||
time_t refts = begin + i * 24 * 60 * 60;
|
||||
tm reference;
|
||||
tm reference = Utility::LocalTime(refts);
|
||||
|
||||
#ifdef _DEBUG
|
||||
Log(LogDebug, "icinga", "Checking reference time " + Convert::ToString(static_cast<long>(refts)));
|
||||
|
||||
#ifdef _MSC_VER
|
||||
tm *temp = localtime(&refts);
|
||||
|
||||
if (temp == NULL) {
|
||||
BOOST_THROW_EXCEPTION(posix_error()
|
||||
<< boost::errinfo_api_function("localtime")
|
||||
<< boost::errinfo_errno(errno));
|
||||
}
|
||||
|
||||
reference = *temp;
|
||||
#else /* _MSC_VER */
|
||||
if (localtime_r(&refts, &reference) == NULL) {
|
||||
BOOST_THROW_EXCEPTION(posix_error()
|
||||
<< boost::errinfo_api_function("localtime_r")
|
||||
<< boost::errinfo_errno(errno));
|
||||
}
|
||||
#endif /* _MSC_VER */
|
||||
#endif /* _DEBUG */
|
||||
|
||||
ObjectLock olock(ranges);
|
||||
BOOST_FOREACH(const Dictionary::Pair& kv, ranges) {
|
||||
if (!IsInDayDefinition(kv.first, &reference)) {
|
||||
#ifdef _DEBUG
|
||||
Log(LogDebug, "icinga", "Not in day definition '" + kv.first + "'.");
|
||||
#endif /* _DEBUG */
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
Log(LogDebug, "icinga", "In day definition '" + kv.first + "'.");
|
||||
#endif /* _DEBUG */
|
||||
|
||||
ProcessTimeRanges(kv.second, &reference, segments);
|
||||
}
|
|
@ -20,7 +20,7 @@
|
|||
#ifndef LEGACYTIMEPERIOD_H
|
||||
#define LEGACYTIMEPERIOD_H
|
||||
|
||||
#include "methods/i2-methods.h"
|
||||
#include "icinga/i2-icinga.h"
|
||||
#include "icinga/service.h"
|
||||
#include "base/dictionary.h"
|
||||
|
||||
|
@ -32,7 +32,7 @@ namespace icinga
|
|||
*
|
||||
* @ingroup icinga
|
||||
*/
|
||||
class I2_METHODS_API LegacyTimePeriod
|
||||
class I2_ICINGA_API LegacyTimePeriod
|
||||
{
|
||||
public:
|
||||
static Array::Ptr ScriptFunc(const TimePeriod::Ptr& tp, double start, double end);
|
||||
|
@ -47,6 +47,7 @@ public:
|
|||
static void ProcessTimeRangeRaw(const String& timerange, tm *reference, tm *begin, tm *end);
|
||||
static Dictionary::Ptr ProcessTimeRange(const String& timerange, tm *reference);
|
||||
static void ProcessTimeRanges(const String& timeranges, tm *reference, const Array::Ptr& result);
|
||||
static Dictionary::Ptr FindNextSegment(const String& daydef, const String& timeranges, tm *reference);
|
||||
|
||||
private:
|
||||
LegacyTimePeriod(void);
|
|
@ -0,0 +1,146 @@
|
|||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2013 Icinga Development Team (http://www.icinga.org/) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#include "icinga/scheduleddowntime.h"
|
||||
#include "icinga/legacytimeperiod.h"
|
||||
#include "base/timer.h"
|
||||
#include "base/dynamictype.h"
|
||||
#include "base/initialize.h"
|
||||
#include "base/utility.h"
|
||||
#include "base/objectlock.h"
|
||||
#include "base/convert.h"
|
||||
#include "base/logger_fwd.h"
|
||||
#include "base/exception.h"
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
REGISTER_TYPE(ScheduledDowntime);
|
||||
|
||||
INITIALIZE_ONCE(&ScheduledDowntime::StaticInitialize);
|
||||
|
||||
static Timer::Ptr l_Timer;
|
||||
|
||||
void ScheduledDowntime::StaticInitialize(void)
|
||||
{
|
||||
l_Timer = make_shared<Timer>();
|
||||
l_Timer->SetInterval(60);
|
||||
l_Timer->OnTimerExpired.connect(boost::bind(&ScheduledDowntime::TimerProc));
|
||||
l_Timer->Start();
|
||||
}
|
||||
|
||||
void ScheduledDowntime::Start(void)
|
||||
{
|
||||
DynamicObject::Start();
|
||||
|
||||
CreateNextDowntime();
|
||||
}
|
||||
|
||||
void ScheduledDowntime::TimerProc(void)
|
||||
{
|
||||
BOOST_FOREACH(const ScheduledDowntime::Ptr& sd, DynamicType::GetObjects<ScheduledDowntime>()) {
|
||||
sd->CreateNextDowntime();
|
||||
}
|
||||
}
|
||||
|
||||
Service::Ptr ScheduledDowntime::GetService(void) const
|
||||
{
|
||||
Host::Ptr host = Host::GetByName(GetHostRaw());
|
||||
|
||||
if (GetServiceRaw().IsEmpty())
|
||||
return host->GetCheckService();
|
||||
else
|
||||
return host->GetServiceByShortName(GetServiceRaw());
|
||||
}
|
||||
|
||||
std::pair<double, double> ScheduledDowntime::FindNextSegment(void)
|
||||
{
|
||||
time_t refts = Utility::GetTime();
|
||||
tm reference = Utility::LocalTime(refts);
|
||||
|
||||
Log(LogDebug, "icinga", "Finding next scheduled downtime segment for time " + Convert::ToString(static_cast<long>(refts)));
|
||||
|
||||
Dictionary::Ptr ranges = GetRanges();
|
||||
|
||||
Array::Ptr segments = make_shared<Array>();
|
||||
|
||||
Dictionary::Ptr bestSegment;
|
||||
double bestBegin;
|
||||
double now = Utility::GetTime();
|
||||
|
||||
ObjectLock olock(ranges);
|
||||
BOOST_FOREACH(const Dictionary::Pair& kv, ranges) {
|
||||
tm rangeref;
|
||||
|
||||
Dictionary::Ptr segment = LegacyTimePeriod::FindNextSegment(kv.first, kv.second, &reference);
|
||||
|
||||
if (!segment)
|
||||
continue;
|
||||
|
||||
double begin = segment->Get("begin");
|
||||
|
||||
if (begin < now)
|
||||
continue;
|
||||
|
||||
if (!bestSegment || begin < bestBegin) {
|
||||
bestSegment = segment;
|
||||
bestBegin = begin;
|
||||
}
|
||||
}
|
||||
|
||||
if (bestSegment)
|
||||
return std::make_pair(bestSegment->Get("begin"), bestSegment->Get("end"));
|
||||
else
|
||||
return std::make_pair(0, 0);
|
||||
}
|
||||
|
||||
void ScheduledDowntime::CreateNextDowntime(void)
|
||||
{
|
||||
Dictionary::Ptr downtimes = GetService()->GetDowntimes();
|
||||
|
||||
{
|
||||
ObjectLock dlock(downtimes);
|
||||
BOOST_FOREACH(const Dictionary::Pair& kv, downtimes) {
|
||||
Downtime::Ptr downtime = kv.second;
|
||||
|
||||
if (downtime->GetScheduledBy() != GetName() ||
|
||||
downtime->GetStartTime() < Utility::GetTime())
|
||||
continue;
|
||||
|
||||
/* We've found a downtime that is owned by us and that hasn't started yet - we're done. */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<double, double> segment = FindNextSegment();
|
||||
|
||||
if (segment.first == 0 && segment.second == 0) {
|
||||
tm reference = Utility::LocalTime(Utility::GetTime());
|
||||
reference.tm_mday++;
|
||||
reference.tm_hour = 0;
|
||||
reference.tm_min = 0;
|
||||
reference.tm_sec = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
GetService()->AddDowntime(GetAuthor(), GetComment(),
|
||||
segment.first, segment.second,
|
||||
GetFixed(), String(), GetDuration(), GetName());
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2013 Icinga Development Team (http://www.icinga.org/) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SCHEDULEDDOWNTIME_H
|
||||
#define SCHEDULEDDOWNTIME_H
|
||||
|
||||
#include "icinga/i2-icinga.h"
|
||||
#include "icinga/scheduleddowntime.th"
|
||||
#include "icinga/service.h"
|
||||
#include <utility>
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
/**
|
||||
* An Icinga scheduled downtime specification.
|
||||
*
|
||||
* @ingroup icinga
|
||||
*/
|
||||
class I2_ICINGA_API ScheduledDowntime : public ObjectImpl<ScheduledDowntime>
|
||||
{
|
||||
public:
|
||||
DECLARE_PTR_TYPEDEFS(ScheduledDowntime);
|
||||
DECLARE_TYPENAME(ScheduledDowntime);
|
||||
|
||||
static void StaticInitialize(void);
|
||||
|
||||
Service::Ptr GetService(void) const;
|
||||
|
||||
protected:
|
||||
virtual void Start(void);
|
||||
|
||||
private:
|
||||
static void TimerProc(void);
|
||||
|
||||
std::pair<double, double> FindNextSegment(void);
|
||||
void CreateNextDowntime(void);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* SCHEDULEDDOWNTIME_H */
|
|
@ -0,0 +1,22 @@
|
|||
#include "base/dynamicobject.h"
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
class ScheduledDowntime : DynamicObject
|
||||
{
|
||||
[config, protected] String host (HostRaw);
|
||||
[config, protected] String service (ServiceRaw);
|
||||
|
||||
[config] String author;
|
||||
[config] String comment;
|
||||
|
||||
[config] double duration;
|
||||
[config] bool fixed {
|
||||
default {{{ return true; }}}
|
||||
};
|
||||
|
||||
[config] Dictionary::Ptr ranges;
|
||||
};
|
||||
|
||||
}
|
|
@ -163,7 +163,9 @@ Comment::Ptr Service::GetCommentByID(const String& id)
|
|||
|
||||
void Service::AddCommentsToCache(void)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
Log(LogDebug, "icinga", "Updating Service comments cache.");
|
||||
#endif /* _DEBUG */
|
||||
|
||||
Dictionary::Ptr comments = GetComments();
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
******************************************************************************/
|
||||
|
||||
#include "icinga/service.h"
|
||||
#include "config/configitembuilder.h"
|
||||
#include "base/dynamictype.h"
|
||||
#include "base/objectlock.h"
|
||||
#include "base/logger_fwd.h"
|
||||
|
@ -47,7 +48,8 @@ int Service::GetNextDowntimeID(void)
|
|||
|
||||
String Service::AddDowntime(const String& author, const String& comment,
|
||||
double startTime, double endTime, bool fixed,
|
||||
const String& triggeredBy, double duration, const String& id, const String& authority)
|
||||
const String& triggeredBy, double duration, const String& scheduledBy,
|
||||
const String& id, const String& authority)
|
||||
{
|
||||
String uid;
|
||||
|
||||
|
@ -66,6 +68,7 @@ String Service::AddDowntime(const String& author, const String& comment,
|
|||
downtime->SetFixed(fixed);
|
||||
downtime->SetDuration(duration);
|
||||
downtime->SetTriggeredBy(triggeredBy);
|
||||
downtime->SetScheduledBy(scheduledBy);
|
||||
|
||||
int legacy_id;
|
||||
|
||||
|
@ -82,10 +85,7 @@ String Service::AddDowntime(const String& author, const String& comment,
|
|||
Downtime::Ptr otherDowntime = otherDowntimes->Get(triggeredBy);
|
||||
Dictionary::Ptr triggers = otherDowntime->GetTriggers();
|
||||
|
||||
{
|
||||
ObjectLock olock(otherOwner);
|
||||
triggers->Set(triggeredBy, triggeredBy);
|
||||
}
|
||||
triggers->Set(triggeredBy, triggeredBy);
|
||||
}
|
||||
|
||||
GetDowntimes()->Set(uid, downtime);
|
||||
|
@ -96,7 +96,8 @@ String Service::AddDowntime(const String& author, const String& comment,
|
|||
l_DowntimesCache[uid] = GetSelf();
|
||||
}
|
||||
|
||||
Log(LogWarning, "icinga", "added downtime with ID '" + Convert::ToString(downtime->GetLegacyId()) + "'.");
|
||||
Log(LogDebug, "icinga", "Added downtime with ID '" + Convert::ToString(downtime->GetLegacyId()) +
|
||||
"' between '" + Utility::FormatDateTime("%Y-%m-%d %H:%M:%S", startTime) + "' and '" + Utility::FormatDateTime("%Y-%m-%d %H:%M:%S", endTime) + "'.");
|
||||
|
||||
OnDowntimeAdded(GetSelf(), downtime, authority);
|
||||
|
||||
|
@ -129,7 +130,7 @@ void Service::RemoveDowntime(const String& id, bool cancelled, const String& aut
|
|||
|
||||
downtime->SetWasCancelled(cancelled);
|
||||
|
||||
Log(LogWarning, "icinga", "removed downtime with ID '" + Convert::ToString(downtime->GetLegacyId()) + "' from service '" + owner->GetName() + "'.");
|
||||
Log(LogDebug, "icinga", "Removed downtime with ID '" + Convert::ToString(downtime->GetLegacyId()) + "' from service '" + owner->GetName() + "'.");
|
||||
|
||||
OnDowntimeRemoved(owner, downtime, authority);
|
||||
}
|
||||
|
@ -230,7 +231,9 @@ void Service::StartDowntimesExpiredTimer(void)
|
|||
|
||||
void Service::AddDowntimesToCache(void)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
Log(LogDebug, "icinga", "Updating Service downtimes cache.");
|
||||
#endif /* _DEBUG */
|
||||
|
||||
Dictionary::Ptr downtimes = GetDowntimes();
|
||||
|
||||
|
@ -312,3 +315,65 @@ int Service::GetDowntimeDepth(void) const
|
|||
|
||||
return downtime_depth;
|
||||
}
|
||||
|
||||
void Service::UpdateSlaveScheduledDowntimes(void)
|
||||
{
|
||||
ConfigItem::Ptr item = ConfigItem::GetObject("Service", GetName());
|
||||
|
||||
/* Don't create slave scheduled downtimes unless we own this object */
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
/* Service scheduled downtime descs */
|
||||
Dictionary::Ptr descs = GetScheduledDowntimeDescriptions();
|
||||
|
||||
if (!descs)
|
||||
return;
|
||||
|
||||
ObjectLock olock(descs);
|
||||
|
||||
BOOST_FOREACH(const Dictionary::Pair& kv, descs) {
|
||||
std::ostringstream namebuf;
|
||||
namebuf << GetName() << ":" << kv.first;
|
||||
String name = namebuf.str();
|
||||
|
||||
std::vector<String> path;
|
||||
path.push_back("scheduled_downtimes");
|
||||
path.push_back(kv.first);
|
||||
|
||||
DebugInfo di;
|
||||
item->GetLinkedExpressionList()->FindDebugInfoPath(path, di);
|
||||
|
||||
if (di.Path.IsEmpty())
|
||||
di = item->GetDebugInfo();
|
||||
|
||||
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
|
||||
builder->SetType("ScheduledDowntime");
|
||||
builder->SetName(name);
|
||||
builder->AddExpression("host", OperatorSet, GetHost()->GetName());
|
||||
builder->AddExpression("service", OperatorSet, GetShortName());
|
||||
|
||||
Dictionary::Ptr scheduledDowntime = kv.second;
|
||||
|
||||
Array::Ptr templates = scheduledDowntime->Get("templates");
|
||||
|
||||
if (templates) {
|
||||
ObjectLock tlock(templates);
|
||||
|
||||
BOOST_FOREACH(const Value& tmpl, templates) {
|
||||
builder->AddParent(tmpl);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clone attributes from the scheduled downtime expression list. */
|
||||
ExpressionList::Ptr sd_exprl = make_shared<ExpressionList>();
|
||||
item->GetLinkedExpressionList()->ExtractPath(path, sd_exprl);
|
||||
|
||||
builder->AddExpressionList(sd_exprl);
|
||||
|
||||
ConfigItem::Ptr scheduledDowntimeItem = builder->Compile();
|
||||
scheduledDowntimeItem->Register();
|
||||
DynamicObject::Ptr dobj = scheduledDowntimeItem->Commit();
|
||||
dobj->OnConfigLoaded();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,9 +46,6 @@ void Service::Start(void)
|
|||
{
|
||||
VERIFY(GetHost());
|
||||
|
||||
AddDowntimesToCache();
|
||||
AddCommentsToCache();
|
||||
|
||||
StartDowntimesExpiredTimer();
|
||||
|
||||
double now = Utility::GetTime();
|
||||
|
@ -80,10 +77,36 @@ void Service::OnConfigLoaded(void)
|
|||
m_Host->AddService(GetSelf());
|
||||
|
||||
UpdateSlaveNotifications();
|
||||
UpdateSlaveScheduledDowntimes();
|
||||
|
||||
SetSchedulingOffset(Utility::Random());
|
||||
}
|
||||
|
||||
void Service::OnStateLoaded(void)
|
||||
{
|
||||
AddDowntimesToCache();
|
||||
AddCommentsToCache();
|
||||
|
||||
std::vector<String> ids;
|
||||
Dictionary::Ptr downtimes = GetDowntimes();
|
||||
|
||||
{
|
||||
ObjectLock dlock(downtimes);
|
||||
BOOST_FOREACH(const Dictionary::Pair& kv, downtimes) {
|
||||
Downtime::Ptr downtime = kv.second;
|
||||
|
||||
if (downtime->GetScheduledBy().IsEmpty())
|
||||
continue;
|
||||
|
||||
ids.push_back(kv.first);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const String& id, ids) {
|
||||
RemoveDowntime(id, true);
|
||||
}
|
||||
}
|
||||
|
||||
Service::Ptr Service::GetByNamePair(const String& hostName, const String& serviceName)
|
||||
{
|
||||
if (!hostName.IsEmpty()) {
|
||||
|
|
|
@ -192,7 +192,8 @@ public:
|
|||
String AddDowntime(const String& author, const String& comment,
|
||||
double startTime, double endTime, bool fixed,
|
||||
const String& triggeredBy, double duration,
|
||||
const String& id = String(), const String& authority = String());
|
||||
const String& scheduledBy = String(), const String& id = String(),
|
||||
const String& authority = String());
|
||||
|
||||
static void RemoveDowntime(const String& id, bool cancelled, const String& = String());
|
||||
|
||||
|
@ -208,6 +209,8 @@ public:
|
|||
bool IsInDowntime(void) const;
|
||||
bool IsAcknowledged(void);
|
||||
|
||||
void UpdateSlaveScheduledDowntimes(void);
|
||||
|
||||
/* Comments */
|
||||
static int GetNextCommentID(void);
|
||||
|
||||
|
@ -265,6 +268,7 @@ protected:
|
|||
virtual void Start(void);
|
||||
|
||||
virtual void OnConfigLoaded(void);
|
||||
virtual void OnStateLoaded(void);
|
||||
|
||||
private:
|
||||
Host::Ptr m_Host;
|
||||
|
|
|
@ -59,6 +59,7 @@ class Service : DynamicObject
|
|||
default {{{ return 30; }}}
|
||||
};
|
||||
[config] Dictionary::Ptr notifications (NotificationDescriptions);
|
||||
[config] Dictionary::Ptr scheduled_downtimes (ScheduledDowntimeDescriptions);
|
||||
[config] bool enable_active_checks (EnableActiveChecksRaw) {
|
||||
default {{{ return true; }}}
|
||||
};
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
add_library(methods SHARED
|
||||
icingachecktask.cpp legacytimeperiod.cpp nullchecktask.cpp
|
||||
nulleventtask.cpp pluginchecktask.cpp plugineventtask.cpp
|
||||
pluginnotificationtask.cpp randomchecktask.cpp timeperiodtask.cpp
|
||||
icingachecktask.cpp nullchecktask.cpp nulleventtask.cpp
|
||||
pluginchecktask.cpp plugineventtask.cpp pluginnotificationtask.cpp
|
||||
randomchecktask.cpp timeperiodtask.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(methods ${Boost_LIBRARIES} base config icinga)
|
||||
|
|
Loading…
Reference in New Issue