mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-22 13:14:32 +02:00
parent
05810f053d
commit
22d53cf3b5
@ -132,6 +132,11 @@ void CheckerComponent::CheckThreadProc(void)
|
|||||||
bool check = true;
|
bool check = true;
|
||||||
|
|
||||||
if (!forced) {
|
if (!forced) {
|
||||||
|
if (!service->IsReachable(DependencyCheckExecution)) {
|
||||||
|
Log(LogDebug, "icinga", "Skipping check for service '" + service->GetName() + "': Dependency failed.");
|
||||||
|
check = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!service->GetEnableActiveChecks() || !IcingaApplication::GetInstance()->GetEnableChecks()) {
|
if (!service->GetEnableActiveChecks() || !IcingaApplication::GetInstance()->GetEnableChecks()) {
|
||||||
Log(LogDebug, "checker", "Skipping check for service '" + service->GetName() + "': active checks are disabled");
|
Log(LogDebug, "checker", "Skipping check for service '" + service->GetName() + "': active checks are disabled");
|
||||||
check = false;
|
check = false;
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "icinga/timeperiod.h"
|
#include "icinga/timeperiod.h"
|
||||||
#include "icinga/notificationcommand.h"
|
#include "icinga/notificationcommand.h"
|
||||||
#include "icinga/compatutility.h"
|
#include "icinga/compatutility.h"
|
||||||
|
#include "icinga/dependency.h"
|
||||||
#include "base/dynamictype.h"
|
#include "base/dynamictype.h"
|
||||||
#include "base/objectlock.h"
|
#include "base/objectlock.h"
|
||||||
#include "base/convert.h"
|
#include "base/convert.h"
|
||||||
@ -508,25 +509,6 @@ void StatusDataWriter::DumpServiceObject(std::ostream& fp, const Service::Ptr& s
|
|||||||
|
|
||||||
fp << "\t" "}" "\n"
|
fp << "\t" "}" "\n"
|
||||||
"\n";
|
"\n";
|
||||||
|
|
||||||
BOOST_FOREACH(const Service::Ptr& parent, service->GetParentServices()) {
|
|
||||||
Host::Ptr host = service->GetHost();
|
|
||||||
|
|
||||||
Host::Ptr parent_host = parent->GetHost();
|
|
||||||
|
|
||||||
if (!parent_host)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
fp << "define servicedependency {" "\n"
|
|
||||||
"\t" "dependent_host_name" "\t" << host->GetName() << "\n"
|
|
||||||
"\t" "dependent_service_description" "\t" << service->GetShortName() << "\n"
|
|
||||||
"\t" "host_name" "\t" << parent_host->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"
|
|
||||||
"\n";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatusDataWriter::DumpCustomAttributes(std::ostream& fp, const DynamicObject::Ptr& object)
|
void StatusDataWriter::DumpCustomAttributes(std::ostream& fp, const DynamicObject::Ptr& object)
|
||||||
@ -673,6 +655,28 @@ void StatusDataWriter::UpdateObjectsCache(void)
|
|||||||
DumpTimePeriod(objectfp, tp);
|
DumpTimePeriod(objectfp, tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_FOREACH(const Dependency::Ptr& dep, DynamicType::GetObjects<Dependency>()) {
|
||||||
|
Service::Ptr parent_service = dep->GetParentService();
|
||||||
|
|
||||||
|
if (!parent_service)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Service::Ptr child_service = dep->GetChildService();
|
||||||
|
|
||||||
|
if (!child_service)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
objectfp << "define servicedependency {" "\n"
|
||||||
|
"\t" "dependent_host_name" "\t" << child_service->GetHost()->GetName() << "\n"
|
||||||
|
"\t" "dependent_service_description" "\t" << child_service->GetShortName() << "\n"
|
||||||
|
"\t" "host_name" "\t" << parent_service->GetHost()->GetName() << "\n"
|
||||||
|
"\t" "service_description" "\t" << parent_service->GetShortName() << "\n"
|
||||||
|
"\t" "execution_failure_criteria" "\t" "n" "\n"
|
||||||
|
"\t" "notification_failure_criteria" "\t" "w,u,c" "\n"
|
||||||
|
"\t" "}" "\n"
|
||||||
|
"\n";
|
||||||
|
}
|
||||||
|
|
||||||
objectfp.close();
|
objectfp.close();
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -17,12 +17,6 @@ Example:
|
|||||||
|
|
||||||
groups = [ "all-hosts" ],
|
groups = [ "all-hosts" ],
|
||||||
|
|
||||||
host_dependencies = [ "router" ],
|
|
||||||
|
|
||||||
service_dependencies = [
|
|
||||||
{ host = "db-server", service = "mysql" }
|
|
||||||
],
|
|
||||||
|
|
||||||
services["ping"] = {
|
services["ping"] = {
|
||||||
templates = [ "ping" ]
|
templates = [ "ping" ]
|
||||||
},
|
},
|
||||||
@ -46,9 +40,8 @@ Attributes:
|
|||||||
display_name |**Optional.** A short description of the host.
|
display_name |**Optional.** A short description of the host.
|
||||||
check |**Optional.** A service that is used to determine whether the host is up or down. This must be a service short name of a service that belongs to the host.
|
check |**Optional.** A service that is used to determine whether the host is up or down. This must be a service short name of a service that belongs to the host.
|
||||||
groups |**Optional.** A list of host groups this host belongs to.
|
groups |**Optional.** A list of host groups this host belongs to.
|
||||||
host_dependencies|**Optional.** A list of host names which this host depends on. These dependencies are used to determine whether the host is unreachable.
|
|
||||||
service_dependencies|**Optional.** A list of services which this host depends on. Each array element must be a dictionary containing the keys "host" and "service". These dependencies are used to determine whether the host is unreachable.
|
|
||||||
services |**Optional.** Inline definition of services. Each dictionary item specifies a service.<br /><br />The `templates` attribute can be used to specify an array of templates that should be inherited by the service.<br /><br />The new service's name is "hostname!service" - where "service" is the dictionary key in the services dictionary.<br /><br />The dictionary key is used as the service's short name.
|
services |**Optional.** Inline definition of services. Each dictionary item specifies a service.<br /><br />The `templates` attribute can be used to specify an array of templates that should be inherited by the service.<br /><br />The new service's name is "hostname!service" - where "service" is the dictionary key in the services dictionary.<br /><br />The dictionary key is used as the service's short name.
|
||||||
|
dependencies |**Optional.** Inline definition of dependencies. Each dictionary item specifies a dependency.<br /><br />The `templates` attribute can be used to specify an array of templates that should be inherited by the dependency object.<br /><br />The new dependency object's name is "hostname:service:dependency" - where "dependency" is the dictionary key in the dependencies dictionary.
|
||||||
macros |**Optional.** A dictionary containing macros that are specific to this host.
|
macros |**Optional.** A dictionary containing macros that are specific to this host.
|
||||||
|
|
||||||
### <a id="objecttype-hostgroup"></a> HostGroup
|
### <a id="objecttype-hostgroup"></a> HostGroup
|
||||||
@ -121,10 +114,9 @@ Attributes:
|
|||||||
event\_command |**Optional.** The name of an event command that should be executed every time the service's state changes.
|
event\_command |**Optional.** The name of an event command that should be executed every time the service's state changes.
|
||||||
flapping\_threshold|**Optional.** The flapping threshold in percent when a service is considered to be flapping.
|
flapping\_threshold|**Optional.** The flapping threshold in percent when a service is considered to be flapping.
|
||||||
volatile |**Optional.** The volatile setting enables always `HARD` state types if `NOT-OK` state changes occur.
|
volatile |**Optional.** The volatile setting enables always `HARD` state types if `NOT-OK` state changes occur.
|
||||||
host_dependencies|**Optional.** A list of host names which this host depends on. These dependencies are used to determine whether the host is unreachable.
|
|
||||||
service_dependencies|**Optional.** A list of services which this host depends on. Each array element must be a dictionary containing the keys "host" and "service". These dependencies are used to determine whether the host is unreachable.
|
|
||||||
groups |**Optional.** The service groups this service belongs to.
|
groups |**Optional.** The service groups this service belongs to.
|
||||||
notifications |**Optional.** Inline definition of notifications. Each dictionary item specifies a notification.<br /><br />The `templates` attribute can be used to specify an array of templates that should be inherited by the notification object.<br /><br />The new notification object's name is "hostname:service:notification" - where "notification" is the dictionary key in the notifications dictionary.
|
notifications |**Optional.** Inline definition of notifications. Each dictionary item specifies a notification.<br /><br />The `templates` attribute can be used to specify an array of templates that should be inherited by the notification object.<br /><br />The new notification object's name is "hostname:service:notification" - where "notification" is the dictionary key in the notifications dictionary.
|
||||||
|
dependencies |**Optional.** Inline definition of dependencies. Each dictionary item specifies a dependency.<br /><br />The `templates` attribute can be used to specify an array of templates that should be inherited by the dependency object.<br /><br />The new dependency object's name is "hostname:service:dependency" - where "dependency" is the dictionary key in the dependencies dictionary.
|
||||||
authorities |**Optional.** A list of Endpoints on which this service check will be executed in a cluster scenario.
|
authorities |**Optional.** A list of Endpoints on which this service check will be executed in a cluster scenario.
|
||||||
|
|
||||||
### <a id="objecttype-servicegroup"></a> ServiceGroup
|
### <a id="objecttype-servicegroup"></a> ServiceGroup
|
||||||
@ -202,6 +194,50 @@ Available notification type and state filters:
|
|||||||
>
|
>
|
||||||
> In order to notify on problem states, you will need the type filter `NotificationFilterProblem`.
|
> In order to notify on problem states, you will need the type filter `NotificationFilterProblem`.
|
||||||
|
|
||||||
|
### <a id="objecttype-dependency"></a> Dependency
|
||||||
|
|
||||||
|
Dependency objects are used to specify dependencies between hosts and services.
|
||||||
|
|
||||||
|
> **Best Practice**
|
||||||
|
>
|
||||||
|
> Rather than creating a `Dependency` object for a specific service it is usually easier
|
||||||
|
> to just create a `Dependency` template and using the `dependencies` attribute in the `Service`
|
||||||
|
> object to associate these templates with a service.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
object Dependency "webserver-internet" {
|
||||||
|
child_host = "webserver",
|
||||||
|
child_service = "ping4",
|
||||||
|
|
||||||
|
parent_host = "internet",
|
||||||
|
parent_service = "ping4",
|
||||||
|
|
||||||
|
state_filter = (StateFilterOK),
|
||||||
|
|
||||||
|
disable_checks = true
|
||||||
|
}
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
|
||||||
|
Name |Description
|
||||||
|
----------------|----------------
|
||||||
|
parent_host |**Required.** The parent host.
|
||||||
|
parent_service |**Optional.** The parent service. When not specified the host's check service is used.
|
||||||
|
child_host |**Required.** The child host.
|
||||||
|
child_service |**Optional.** The child service. When not specified the host's check service is used.
|
||||||
|
disable_checks |**Optional.** Whether to disable checks when this dependency fails. Defaults to false.
|
||||||
|
disable_notifications|**Optional.** Whether to disable notifications when this dependency fails. Defaults to true.
|
||||||
|
period |**Optional.** Time period during which this dependency is enabled.
|
||||||
|
state_filter |**Optional.** A set of type filters when this dependency should be OK. Defaults to (StateFilterOK | StateFilterWarning).
|
||||||
|
|
||||||
|
Available state filters:
|
||||||
|
|
||||||
|
StateFilterOK
|
||||||
|
StateFilterWarning
|
||||||
|
StateFilterCritical
|
||||||
|
StateFilterUnknown
|
||||||
|
|
||||||
### <a id="objecttype-user"></a> User
|
### <a id="objecttype-user"></a> User
|
||||||
|
|
||||||
A user.
|
A user.
|
||||||
|
@ -19,6 +19,7 @@ mkclass_target(checkcommand.ti checkcommand.th)
|
|||||||
mkclass_target(checkresult.ti checkresult.th)
|
mkclass_target(checkresult.ti checkresult.th)
|
||||||
mkclass_target(command.ti command.th)
|
mkclass_target(command.ti command.th)
|
||||||
mkclass_target(comment.ti comment.th)
|
mkclass_target(comment.ti comment.th)
|
||||||
|
mkclass_target(dependency.ti dependency.th)
|
||||||
mkclass_target(domain.ti domain.th)
|
mkclass_target(domain.ti domain.th)
|
||||||
mkclass_target(downtime.ti downtime.th)
|
mkclass_target(downtime.ti downtime.th)
|
||||||
mkclass_target(eventcommand.ti eventcommand.th)
|
mkclass_target(eventcommand.ti eventcommand.th)
|
||||||
@ -40,7 +41,7 @@ mkembedconfig_target(icinga-type.conf icinga-type.cpp)
|
|||||||
|
|
||||||
add_library(icinga SHARED
|
add_library(icinga SHARED
|
||||||
api.cpp api.h checkcommand.cpp checkcommand.th checkresult.cpp checkresult.th
|
api.cpp api.h checkcommand.cpp checkcommand.th checkresult.cpp checkresult.th
|
||||||
cib.cpp command.cpp command.th comment.cpp comment.th compatutility.cpp
|
cib.cpp command.cpp command.th comment.cpp comment.th compatutility.cpp dependency.cpp dependency.th
|
||||||
domain.cpp domain.th downtime.cpp downtime.th eventcommand.cpp eventcommand.th
|
domain.cpp domain.th downtime.cpp downtime.th eventcommand.cpp eventcommand.th
|
||||||
externalcommandprocessor.cpp host.cpp host.th hostgroup.cpp hostgroup.th
|
externalcommandprocessor.cpp host.cpp host.th hostgroup.cpp hostgroup.th
|
||||||
icingaapplication.cpp icingaapplication.th icingastatuswriter.cpp
|
icingaapplication.cpp icingaapplication.th icingastatuswriter.cpp
|
||||||
@ -48,7 +49,7 @@ add_library(icinga SHARED
|
|||||||
macroprocessor.cpp macroresolver.cpp notificationcommand.cpp notificationcommand.th
|
macroprocessor.cpp macroresolver.cpp notificationcommand.cpp notificationcommand.th
|
||||||
notification.cpp notification.th perfdatavalue.cpp perfdatavalue.th
|
notification.cpp notification.th perfdatavalue.cpp perfdatavalue.th
|
||||||
pluginutility.cpp scheduleddowntime.cpp scheduleddowntime.th service-check.cpp
|
pluginutility.cpp scheduleddowntime.cpp scheduleddowntime.th service-check.cpp
|
||||||
service-comment.cpp service.cpp service-downtime.cpp service-event.cpp
|
service-comment.cpp service.cpp service-dependency.cpp service-downtime.cpp service-event.cpp
|
||||||
service-flapping.cpp service.th servicegroup.cpp servicegroup.th
|
service-flapping.cpp service.th servicegroup.cpp servicegroup.th
|
||||||
service-notification.cpp timeperiod.cpp timeperiod.th user.cpp user.th
|
service-notification.cpp timeperiod.cpp timeperiod.th user.cpp user.th
|
||||||
usergroup.cpp usergroup.th icinga-type.cpp
|
usergroup.cpp usergroup.th icinga-type.cpp
|
||||||
|
137
lib/icinga/dependency.cpp
Normal file
137
lib/icinga/dependency.cpp
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Icinga 2 *
|
||||||
|
* Copyright (C) 2012-present 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/dependency.h"
|
||||||
|
#include "base/dynamictype.h"
|
||||||
|
#include "base/objectlock.h"
|
||||||
|
#include "base/logger_fwd.h"
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
|
using namespace icinga;
|
||||||
|
|
||||||
|
REGISTER_TYPE(Dependency);
|
||||||
|
|
||||||
|
void Dependency::OnStateLoaded(void)
|
||||||
|
{
|
||||||
|
DynamicObject::Start();
|
||||||
|
|
||||||
|
ASSERT(!OwnsLock());
|
||||||
|
|
||||||
|
if (!GetChildService())
|
||||||
|
Log(LogWarning, "icinga", "Dependency '" + GetName() + "' references an invalid child service and will be ignored.");
|
||||||
|
else
|
||||||
|
GetChildService()->AddDependency(GetSelf());
|
||||||
|
|
||||||
|
if (!GetParentService())
|
||||||
|
Log(LogWarning, "icinga", "Dependency '" + GetName() + "' references an invalid parent service and will always fail.");
|
||||||
|
else
|
||||||
|
GetParentService()->AddReverseDependency(GetSelf());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dependency::Stop(void)
|
||||||
|
{
|
||||||
|
DynamicObject::Stop();
|
||||||
|
|
||||||
|
if (GetChildService())
|
||||||
|
GetChildService()->RemoveDependency(GetSelf());
|
||||||
|
|
||||||
|
if (GetParentService())
|
||||||
|
GetParentService()->RemoveReverseDependency(GetSelf());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Dependency::IsAvailable(DependencyType dt) const
|
||||||
|
{
|
||||||
|
Service::Ptr service = GetParentService();
|
||||||
|
|
||||||
|
if (!service)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* ignore if it's the same service */
|
||||||
|
if (service == GetChildService()) {
|
||||||
|
Log(LogDebug, "icinga", "Dependency '" + GetName() + "' passed: Parent and child service are identical.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ignore pending services */
|
||||||
|
if (!service->GetLastCheckResult()) {
|
||||||
|
Log(LogDebug, "icinga", "Dependency '" + GetName() + "' passed: Service hasn't been checked yet.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ignore soft states */
|
||||||
|
if (service->GetStateType() == StateTypeSoft) {
|
||||||
|
Log(LogDebug, "icinga", "Dependency '" + GetName() + "' passed: Service is in a soft state.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check state */
|
||||||
|
if ((1 << static_cast<int>(service->GetState())) & GetStateFilter()) {
|
||||||
|
Log(LogDebug, "icinga", "Dependency '" + GetName() + "' passed: Service matches state filter.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ignore if not in time period */
|
||||||
|
TimePeriod::Ptr tp = GetPeriod();
|
||||||
|
if (tp && !tp->IsInside(Utility::GetTime())) {
|
||||||
|
Log(LogDebug, "icinga", "Dependency '" + GetName() + "' passed: Outside time period.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dt == DependencyCheckExecution && !GetDisableChecks()) {
|
||||||
|
Log(LogDebug, "icinga", "Dependency '" + GetName() + "' passed: Checks are not disabled.");
|
||||||
|
return true;
|
||||||
|
} else if (dt == DependencyNotification && !GetDisableNotifications()) {
|
||||||
|
Log(LogDebug, "icinga", "Dependency '" + GetName() + "' passed: Notifications are not disabled");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log(LogDebug, "icinga", "Dependency '" + GetName() + "' failed.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Service::Ptr Dependency::GetChildService(void) const
|
||||||
|
{
|
||||||
|
Host::Ptr host = Host::GetByName(GetChildHostRaw());
|
||||||
|
|
||||||
|
if (!host)
|
||||||
|
return Service::Ptr();
|
||||||
|
|
||||||
|
if (GetChildServiceRaw().IsEmpty())
|
||||||
|
return host->GetCheckService();
|
||||||
|
|
||||||
|
return host->GetServiceByShortName(GetChildServiceRaw());
|
||||||
|
}
|
||||||
|
|
||||||
|
Service::Ptr Dependency::GetParentService(void) const
|
||||||
|
{
|
||||||
|
Host::Ptr host = Host::GetByName(GetParentHostRaw());
|
||||||
|
|
||||||
|
if (!host)
|
||||||
|
return Service::Ptr();
|
||||||
|
|
||||||
|
if (GetParentServiceRaw().IsEmpty())
|
||||||
|
return host->GetCheckService();
|
||||||
|
|
||||||
|
return host->GetServiceByShortName(GetParentServiceRaw());
|
||||||
|
}
|
||||||
|
|
||||||
|
TimePeriod::Ptr Dependency::GetPeriod(void) const
|
||||||
|
{
|
||||||
|
return TimePeriod::GetByName(GetPeriodRaw());
|
||||||
|
}
|
57
lib/icinga/dependency.h
Normal file
57
lib/icinga/dependency.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Icinga 2 *
|
||||||
|
* Copyright (C) 2012-present 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 DEPENDENCY_H
|
||||||
|
#define DEPENDENCY_H
|
||||||
|
|
||||||
|
#include "icinga/i2-icinga.h"
|
||||||
|
#include "icinga/dependency.th"
|
||||||
|
#include "icinga/service.h"
|
||||||
|
#include "base/array.h"
|
||||||
|
#include "base/dictionary.h"
|
||||||
|
|
||||||
|
namespace icinga
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A service dependency..
|
||||||
|
*
|
||||||
|
* @ingroup icinga
|
||||||
|
*/
|
||||||
|
class I2_ICINGA_API Dependency : public ObjectImpl<Dependency>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DECLARE_PTR_TYPEDEFS(Dependency);
|
||||||
|
DECLARE_TYPENAME(Dependency);
|
||||||
|
|
||||||
|
Service::Ptr GetParentService(void) const;
|
||||||
|
Service::Ptr GetChildService(void) const;
|
||||||
|
|
||||||
|
TimePeriod::Ptr GetPeriod(void) const;
|
||||||
|
|
||||||
|
bool IsAvailable(DependencyType dt) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void OnStateLoaded(void);
|
||||||
|
virtual void Stop(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* DEPENDENCY_H */
|
25
lib/icinga/dependency.ti
Normal file
25
lib/icinga/dependency.ti
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#include "base/dynamicobject.h"
|
||||||
|
#include "icinga/service.h"
|
||||||
|
|
||||||
|
namespace icinga
|
||||||
|
{
|
||||||
|
|
||||||
|
class Dependency : DynamicObject
|
||||||
|
{
|
||||||
|
[config] String child_host (ChildHostRaw);
|
||||||
|
[config] String child_service (ChildServiceRaw);
|
||||||
|
|
||||||
|
[config] String parent_host (ParentHostRaw);
|
||||||
|
[config] String parent_service (ParentServiceRaw);
|
||||||
|
|
||||||
|
[config] String period (PeriodRaw);
|
||||||
|
|
||||||
|
[config] int state_filter {
|
||||||
|
default {{{ return (1 << StateOK) | (1 << StateWarning); }}}
|
||||||
|
};
|
||||||
|
|
||||||
|
[config] bool disable_checks;
|
||||||
|
[config] bool disable_notifications;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -84,54 +84,15 @@ void Host::Stop(void)
|
|||||||
// TODO: unregister slave services/notifications?
|
// TODO: unregister slave services/notifications?
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Host::IsReachable(void) const
|
bool Host::IsReachable(DependencyType dt, shared_ptr<Dependency> *failedDependency) const
|
||||||
{
|
{
|
||||||
ASSERT(!OwnsLock());
|
ASSERT(!OwnsLock());
|
||||||
|
|
||||||
std::set<Service::Ptr> parentServices = GetParentServices();
|
Service::Ptr hc = GetCheckService();
|
||||||
|
if (!hc)
|
||||||
|
return true;
|
||||||
|
|
||||||
BOOST_FOREACH(const Service::Ptr& service, parentServices) {
|
return hc->IsReachable(dt, failedDependency);
|
||||||
ObjectLock olock(service);
|
|
||||||
|
|
||||||
/* ignore pending services */
|
|
||||||
if (!service->GetLastCheckResult())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* ignore soft states */
|
|
||||||
if (service->GetStateType() == StateTypeSoft)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* ignore services states OK and Warning */
|
|
||||||
if (service->GetState() == StateOK ||
|
|
||||||
service->GetState() == StateWarning)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::set<Host::Ptr> parentHosts = GetParentHosts();
|
|
||||||
|
|
||||||
BOOST_FOREACH(const Host::Ptr& host, parentHosts) {
|
|
||||||
Service::Ptr hc = host->GetCheckService();
|
|
||||||
|
|
||||||
/* ignore hosts that don't have a check */
|
|
||||||
if (!hc)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ObjectLock olock(hc);
|
|
||||||
|
|
||||||
/* ignore soft states */
|
|
||||||
if (hc->GetStateType() == StateTypeSoft)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* ignore hosts that are up */
|
|
||||||
if (hc->GetState() == StateOK)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Host::UpdateSlaveServices(void)
|
void Host::UpdateSlaveServices(void)
|
||||||
@ -238,7 +199,14 @@ int Host::GetTotalServices(void) const
|
|||||||
|
|
||||||
Service::Ptr Host::GetServiceByShortName(const Value& name) const
|
Service::Ptr Host::GetServiceByShortName(const Value& name) const
|
||||||
{
|
{
|
||||||
if (name.IsScalar()) {
|
if (name.IsEmpty()) {
|
||||||
|
Service::Ptr hc = GetCheckService();
|
||||||
|
|
||||||
|
if (!hc)
|
||||||
|
BOOST_THROW_EXCEPTION(std::invalid_argument("Host does not have a host check service: " + GetName()));
|
||||||
|
|
||||||
|
return hc;
|
||||||
|
} else if (name.IsScalar()) {
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_ServicesMutex);
|
boost::mutex::scoped_lock lock(m_ServicesMutex);
|
||||||
|
|
||||||
@ -259,48 +227,6 @@ Service::Ptr Host::GetServiceByShortName(const Value& name) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<Host::Ptr> Host::GetParentHosts(void) const
|
|
||||||
{
|
|
||||||
std::set<Host::Ptr> parents;
|
|
||||||
|
|
||||||
Array::Ptr dependencies = GetHostDependencies();
|
|
||||||
|
|
||||||
if (dependencies) {
|
|
||||||
ObjectLock olock(dependencies);
|
|
||||||
|
|
||||||
BOOST_FOREACH(const Value& value, dependencies) {
|
|
||||||
if (value == GetName())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Host::Ptr host = GetByName(value);
|
|
||||||
|
|
||||||
parents.insert(host);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return parents;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::set<Host::Ptr> Host::GetChildHosts(void) const
|
|
||||||
{
|
|
||||||
std::set<Host::Ptr> children;
|
|
||||||
|
|
||||||
BOOST_FOREACH(const Host::Ptr& host, DynamicType::GetObjects<Host>()) {
|
|
||||||
Array::Ptr dependencies = host->GetHostDependencies();
|
|
||||||
|
|
||||||
if (dependencies) {
|
|
||||||
ObjectLock olock(dependencies);
|
|
||||||
|
|
||||||
BOOST_FOREACH(const Value& value, dependencies) {
|
|
||||||
if (value == GetName())
|
|
||||||
children.insert(host);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return children;
|
|
||||||
}
|
|
||||||
|
|
||||||
Service::Ptr Host::GetCheckService(void) const
|
Service::Ptr Host::GetCheckService(void) const
|
||||||
{
|
{
|
||||||
String host_check = GetCheck();
|
String host_check = GetCheck();
|
||||||
@ -311,21 +237,48 @@ Service::Ptr Host::GetCheckService(void) const
|
|||||||
return GetServiceByShortName(host_check);
|
return GetServiceByShortName(host_check);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::set<Host::Ptr> Host::GetParentHosts(void) const
|
||||||
|
{
|
||||||
|
std::set<Host::Ptr> result;
|
||||||
|
Service::Ptr hc = GetCheckService();
|
||||||
|
|
||||||
|
if (hc)
|
||||||
|
result = hc->GetParentHosts();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<Host::Ptr> Host::GetChildHosts(void) const
|
||||||
|
{
|
||||||
|
std::set<Host::Ptr> result;
|
||||||
|
Service::Ptr hc = GetCheckService();
|
||||||
|
|
||||||
|
if (hc)
|
||||||
|
result = hc->GetChildHosts();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
std::set<Service::Ptr> Host::GetParentServices(void) const
|
std::set<Service::Ptr> Host::GetParentServices(void) const
|
||||||
{
|
{
|
||||||
std::set<Service::Ptr> parents;
|
std::set<Service::Ptr> result;
|
||||||
|
Service::Ptr hc = GetCheckService();
|
||||||
|
|
||||||
Array::Ptr dependencies = GetServiceDependencies();
|
if (hc)
|
||||||
|
result = hc->GetParentServices();
|
||||||
|
|
||||||
if (dependencies) {
|
return result;
|
||||||
ObjectLock olock(dependencies);
|
}
|
||||||
|
|
||||||
BOOST_FOREACH(const Value& value, dependencies) {
|
std::set<Service::Ptr> Host::GetChildServices(void) const
|
||||||
parents.insert(GetServiceByShortName(value));
|
{
|
||||||
}
|
std::set<Service::Ptr> result;
|
||||||
}
|
Service::Ptr hc = GetCheckService();
|
||||||
|
|
||||||
return parents;
|
if (hc)
|
||||||
|
result = hc->GetChildServices();
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
HostState Host::CalculateState(ServiceState state, bool reachable)
|
HostState Host::CalculateState(ServiceState state, bool reachable)
|
||||||
|
@ -31,6 +31,7 @@ namespace icinga
|
|||||||
{
|
{
|
||||||
|
|
||||||
class Service;
|
class Service;
|
||||||
|
class Dependency;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The state of a host.
|
* The state of a host.
|
||||||
@ -44,6 +45,13 @@ enum HostState
|
|||||||
HostUnreachable = 2
|
HostUnreachable = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum DependencyType
|
||||||
|
{
|
||||||
|
DependencyState,
|
||||||
|
DependencyCheckExecution,
|
||||||
|
DependencyNotification
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An Icinga host.
|
* An Icinga host.
|
||||||
*
|
*
|
||||||
@ -56,11 +64,13 @@ public:
|
|||||||
DECLARE_TYPENAME(Host);
|
DECLARE_TYPENAME(Host);
|
||||||
|
|
||||||
shared_ptr<Service> GetCheckService(void) const;
|
shared_ptr<Service> GetCheckService(void) const;
|
||||||
|
|
||||||
std::set<Host::Ptr> GetParentHosts(void) const;
|
std::set<Host::Ptr> GetParentHosts(void) const;
|
||||||
std::set<Host::Ptr> GetChildHosts(void) const;
|
std::set<Host::Ptr> GetChildHosts(void) const;
|
||||||
std::set<shared_ptr<Service> > GetParentServices(void) const;
|
std::set<shared_ptr<Service> > GetParentServices(void) const;
|
||||||
|
std::set<shared_ptr<Service> > GetChildServices(void) const;
|
||||||
|
|
||||||
bool IsReachable() const;
|
bool IsReachable(DependencyType dt = DependencyState, shared_ptr<Dependency> *failedDependency = NULL) const;
|
||||||
|
|
||||||
shared_ptr<Service> GetServiceByShortName(const Value& name) const;
|
shared_ptr<Service> GetServiceByShortName(const Value& name) const;
|
||||||
|
|
||||||
|
@ -15,10 +15,9 @@ class Host : DynamicObject
|
|||||||
};
|
};
|
||||||
[config] Array::Ptr groups;
|
[config] Array::Ptr groups;
|
||||||
[config] Dictionary::Ptr macros;
|
[config] Dictionary::Ptr macros;
|
||||||
[config] Array::Ptr host_dependencies;
|
|
||||||
[config] Array::Ptr service_dependencies;
|
|
||||||
[config] String check;
|
[config] String check;
|
||||||
[config, protected] Dictionary::Ptr services (ServiceDescriptions);
|
[config, protected] Dictionary::Ptr services (ServiceDescriptions);
|
||||||
|
[config] Dictionary::Ptr dependencies (DependencyDescriptions);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,18 +23,6 @@ type Host {
|
|||||||
%attribute array "groups" {
|
%attribute array "groups" {
|
||||||
%attribute name(HostGroup) "*"
|
%attribute name(HostGroup) "*"
|
||||||
},
|
},
|
||||||
%attribute array "host_dependencies" {
|
|
||||||
%attribute name(Host) "*"
|
|
||||||
},
|
|
||||||
%attribute array "service_dependencies" {
|
|
||||||
%attribute dictionary "*" {
|
|
||||||
%require "host",
|
|
||||||
%attribute name(Host) "host",
|
|
||||||
|
|
||||||
%require "service",
|
|
||||||
%attribute string "service"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
%attribute dictionary "services" {
|
%attribute dictionary "services" {
|
||||||
%attribute dictionary "*" {
|
%attribute dictionary "*" {
|
||||||
%attribute array "templates" {
|
%attribute array "templates" {
|
||||||
@ -45,6 +33,16 @@ type Host {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
%attribute dictionary "dependencies" {
|
||||||
|
%attribute dictionary "*" {
|
||||||
|
%attribute array "templates" {
|
||||||
|
%attribute name(Dependency) "*"
|
||||||
|
},
|
||||||
|
|
||||||
|
%attribute any "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
%attribute dictionary "macros" {
|
%attribute dictionary "macros" {
|
||||||
%attribute string "*"
|
%attribute string "*"
|
||||||
}
|
}
|
||||||
@ -95,18 +93,16 @@ type Service {
|
|||||||
|
|
||||||
%attribute number "volatile",
|
%attribute number "volatile",
|
||||||
|
|
||||||
%attribute array "host_dependencies" {
|
%attribute dictionary "dependencies" {
|
||||||
%attribute name(Host) "*"
|
|
||||||
},
|
|
||||||
%attribute array "service_dependencies" {
|
|
||||||
%attribute dictionary "*" {
|
%attribute dictionary "*" {
|
||||||
%require "host",
|
%attribute array "templates" {
|
||||||
%attribute name(Host) "host",
|
%attribute name(Dependency) "*"
|
||||||
|
},
|
||||||
|
|
||||||
%require "service",
|
%attribute any "*"
|
||||||
%attribute string "service"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
%attribute array "groups" {
|
%attribute array "groups" {
|
||||||
%attribute name(ServiceGroup) "*"
|
%attribute name(ServiceGroup) "*"
|
||||||
},
|
},
|
||||||
@ -285,3 +281,19 @@ type ScheduledDowntime {
|
|||||||
|
|
||||||
%attribute any "templates"
|
%attribute any "templates"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Dependency {
|
||||||
|
%require "parent_host",
|
||||||
|
%attribute name(Host) "parent_host",
|
||||||
|
%attribute string "parent_service",
|
||||||
|
|
||||||
|
%require "child_host",
|
||||||
|
%attribute name(Host) "child_host",
|
||||||
|
%attribute string "child_service",
|
||||||
|
|
||||||
|
%attribute name(TimePeriod) "period",
|
||||||
|
|
||||||
|
%attribute number "state_filter",
|
||||||
|
%attribute number "disable_checks",
|
||||||
|
%attribute number "disable_notifications"
|
||||||
|
}
|
||||||
|
@ -240,6 +240,7 @@ void Service::ProcessCheckResult(const CheckResult::Ptr& cr, const String& autho
|
|||||||
cr->SetCheckSource(authority);
|
cr->SetCheckSource(authority);
|
||||||
|
|
||||||
bool reachable = IsReachable();
|
bool reachable = IsReachable();
|
||||||
|
bool notification_reachable = IsReachable(DependencyNotification);
|
||||||
|
|
||||||
bool host_reachable = GetHost()->IsReachable();
|
bool host_reachable = GetHost()->IsReachable();
|
||||||
|
|
||||||
@ -358,7 +359,7 @@ void Service::ProcessCheckResult(const CheckResult::Ptr& cr, const String& autho
|
|||||||
Service::UpdateStatistics(cr);
|
Service::UpdateStatistics(cr);
|
||||||
|
|
||||||
bool in_downtime = IsInDowntime();
|
bool in_downtime = IsInDowntime();
|
||||||
bool send_notification = hardChange && reachable && !in_downtime && !IsAcknowledged();
|
bool send_notification = hardChange && notification_reachable && !in_downtime && !IsAcknowledged();
|
||||||
|
|
||||||
if (old_state == StateOK && old_stateType == StateTypeSoft)
|
if (old_state == StateOK && old_stateType == StateTypeSoft)
|
||||||
send_notification = false; /* Don't send notifications for SOFT-OK -> HARD-OK. */
|
send_notification = false; /* Don't send notifications for SOFT-OK -> HARD-OK. */
|
||||||
|
240
lib/icinga/service-dependency.cpp
Normal file
240
lib/icinga/service-dependency.cpp
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Icinga 2 *
|
||||||
|
* Copyright (C) 2012-present 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/service.h"
|
||||||
|
#include "icinga/dependency.h"
|
||||||
|
#include "config/configitembuilder.h"
|
||||||
|
#include "base/dynamictype.h"
|
||||||
|
#include "base/objectlock.h"
|
||||||
|
#include "base/logger_fwd.h"
|
||||||
|
#include "base/timer.h"
|
||||||
|
#include "base/utility.h"
|
||||||
|
#include "base/convert.h"
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
|
using namespace icinga;
|
||||||
|
|
||||||
|
void Service::AddDependency(const Dependency::Ptr& dep)
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(m_DependencyMutex);
|
||||||
|
m_Dependencies.insert(dep);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Service::RemoveDependency(const Dependency::Ptr& dep)
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(m_DependencyMutex);
|
||||||
|
m_Dependencies.erase(dep);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<Dependency::Ptr> Service::GetDependencies(void) const
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(m_DependencyMutex);
|
||||||
|
return m_Dependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Service::AddReverseDependency(const Dependency::Ptr& dep)
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(m_DependencyMutex);
|
||||||
|
m_ReverseDependencies.insert(dep);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Service::RemoveReverseDependency(const Dependency::Ptr& dep)
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(m_DependencyMutex);
|
||||||
|
m_ReverseDependencies.erase(dep);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<Dependency::Ptr> Service::GetReverseDependencies(void) const
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(m_DependencyMutex);
|
||||||
|
return m_ReverseDependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Service::IsReachable(DependencyType dt, Dependency::Ptr *failedDependency, int rstack) const
|
||||||
|
{
|
||||||
|
if (rstack > 20) {
|
||||||
|
Log(LogWarning, "icinga", "Too many nested dependencies for service '" + GetName() + "': Dependency failed.");
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FOREACH(const Service::Ptr& service, GetParentServices()) {
|
||||||
|
if (!service->IsReachable(dt, failedDependency, rstack + 1))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* implicit dependency on host's check service */
|
||||||
|
if (dt == DependencyState || dt == DependencyNotification) {
|
||||||
|
Service::Ptr hc = GetHost()->GetCheckService();
|
||||||
|
|
||||||
|
if (hc && hc->GetState() == StateCritical && hc->GetStateType() == StateTypeHard) {
|
||||||
|
if (failedDependency)
|
||||||
|
*failedDependency = Dependency::Ptr();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FOREACH(const Dependency::Ptr& dep, GetDependencies()) {
|
||||||
|
if (!dep->IsAvailable(dt)) {
|
||||||
|
if (failedDependency)
|
||||||
|
*failedDependency = dep;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failedDependency)
|
||||||
|
*failedDependency = Dependency::Ptr();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<Host::Ptr> Service::GetParentHosts(void) const
|
||||||
|
{
|
||||||
|
std::set<Host::Ptr> result;
|
||||||
|
|
||||||
|
BOOST_FOREACH(const Service::Ptr& svc, GetParentServices())
|
||||||
|
result.insert(svc->GetHost());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<Host::Ptr> Service::GetChildHosts(void) const
|
||||||
|
{
|
||||||
|
std::set<Host::Ptr> result;
|
||||||
|
|
||||||
|
BOOST_FOREACH(const Service::Ptr& svc, GetChildServices())
|
||||||
|
result.insert(svc->GetHost());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<Service::Ptr> Service::GetParentServices(void) const
|
||||||
|
{
|
||||||
|
std::set<Service::Ptr> parents;
|
||||||
|
|
||||||
|
BOOST_FOREACH(const Dependency::Ptr& dep, GetDependencies()) {
|
||||||
|
Service::Ptr service = dep->GetParentService();
|
||||||
|
|
||||||
|
if (service)
|
||||||
|
parents.insert(service);
|
||||||
|
}
|
||||||
|
|
||||||
|
return parents;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<Service::Ptr> Service::GetChildServices(void) const
|
||||||
|
{
|
||||||
|
std::set<Service::Ptr> parents;
|
||||||
|
|
||||||
|
BOOST_FOREACH(const Dependency::Ptr& dep, GetReverseDependencies()) {
|
||||||
|
Service::Ptr service = dep->GetChildService();
|
||||||
|
|
||||||
|
if (service)
|
||||||
|
parents.insert(service);
|
||||||
|
}
|
||||||
|
|
||||||
|
return parents;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Service::UpdateSlaveDependencies(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* pass == 0 -> steal host's dependency definitions
|
||||||
|
* pass == 1 -> service's dependencies
|
||||||
|
*/
|
||||||
|
for (int pass = 0; pass < 2; pass++) {
|
||||||
|
/* Service dependency descs */
|
||||||
|
Dictionary::Ptr descs;
|
||||||
|
|
||||||
|
if (pass == 0 && !IsHostCheck())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (pass == 0)
|
||||||
|
descs = GetHost()->GetDependencyDescriptions();
|
||||||
|
else
|
||||||
|
GetDependencyDescriptions();
|
||||||
|
|
||||||
|
if (!descs || descs->GetLength() == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ConfigItem::Ptr item;
|
||||||
|
|
||||||
|
if (pass == 0)
|
||||||
|
item = ConfigItem::GetObject("Host", GetHost()->GetName());
|
||||||
|
else
|
||||||
|
ConfigItem::GetObject("Service", GetName());
|
||||||
|
|
||||||
|
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("dependencies");
|
||||||
|
path.push_back(kv.first);
|
||||||
|
|
||||||
|
ExpressionList::Ptr exprl;
|
||||||
|
|
||||||
|
{
|
||||||
|
ObjectLock ilock(item);
|
||||||
|
|
||||||
|
exprl = item->GetLinkedExpressionList();
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugInfo di;
|
||||||
|
exprl->FindDebugInfoPath(path, di);
|
||||||
|
|
||||||
|
if (di.Path.IsEmpty())
|
||||||
|
di = item->GetDebugInfo();
|
||||||
|
|
||||||
|
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di);
|
||||||
|
builder->SetType("Dependency");
|
||||||
|
builder->SetName(name);
|
||||||
|
builder->AddExpression("child_host", OperatorSet, GetHost()->GetName());
|
||||||
|
builder->AddExpression("child_service", OperatorSet, GetShortName());
|
||||||
|
|
||||||
|
Dictionary::Ptr dependency = kv.second;
|
||||||
|
|
||||||
|
Array::Ptr templates = dependency->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>();
|
||||||
|
exprl->ExtractPath(path, sd_exprl);
|
||||||
|
|
||||||
|
builder->AddExpressionList(sd_exprl);
|
||||||
|
|
||||||
|
ConfigItem::Ptr dependencyItem = builder->Compile();
|
||||||
|
dependencyItem->Register();
|
||||||
|
DynamicObject::Ptr dobj = dependencyItem->Commit();
|
||||||
|
dobj->OnConfigLoaded();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -23,6 +23,7 @@
|
|||||||
#include "icinga/icingaapplication.h"
|
#include "icinga/icingaapplication.h"
|
||||||
#include "icinga/macroprocessor.h"
|
#include "icinga/macroprocessor.h"
|
||||||
#include "icinga/pluginutility.h"
|
#include "icinga/pluginutility.h"
|
||||||
|
#include "icinga/dependency.h"
|
||||||
#include "config/configitembuilder.h"
|
#include "config/configitembuilder.h"
|
||||||
#include "base/dynamictype.h"
|
#include "base/dynamictype.h"
|
||||||
#include "base/objectlock.h"
|
#include "base/objectlock.h"
|
||||||
@ -77,6 +78,7 @@ void Service::OnConfigLoaded(void)
|
|||||||
|
|
||||||
UpdateSlaveNotifications();
|
UpdateSlaveNotifications();
|
||||||
UpdateSlaveScheduledDowntimes();
|
UpdateSlaveScheduledDowntimes();
|
||||||
|
UpdateSlaveDependencies();
|
||||||
|
|
||||||
SetSchedulingOffset(Utility::Random());
|
SetSchedulingOffset(Utility::Random());
|
||||||
}
|
}
|
||||||
@ -138,60 +140,6 @@ bool Service::IsHostCheck(void) const
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Service::IsReachable(void) const
|
|
||||||
{
|
|
||||||
ASSERT(!OwnsLock());
|
|
||||||
|
|
||||||
BOOST_FOREACH(const Service::Ptr& service, GetParentServices()) {
|
|
||||||
/* ignore ourselves */
|
|
||||||
if (service->GetName() == GetName())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ObjectLock olock(service);
|
|
||||||
|
|
||||||
/* ignore pending services */
|
|
||||||
if (!service->GetLastCheckResult())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* ignore soft states */
|
|
||||||
if (service->GetStateType() == StateTypeSoft)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* ignore services states OK and Warning */
|
|
||||||
if (service->GetState() == StateOK ||
|
|
||||||
service->GetState() == StateWarning)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_FOREACH(const Host::Ptr& host, GetParentHosts()) {
|
|
||||||
Service::Ptr hc = host->GetCheckService();
|
|
||||||
|
|
||||||
/* ignore hosts that don't have a hostcheck */
|
|
||||||
if (!hc)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* ignore ourselves */
|
|
||||||
if (hc->GetName() == GetName())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ObjectLock olock(hc);
|
|
||||||
|
|
||||||
/* ignore soft states */
|
|
||||||
if (hc->GetStateType() == StateTypeSoft)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* ignore hosts that are up */
|
|
||||||
if (hc->GetState() == StateOK)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
AcknowledgementType Service::GetAcknowledgement(void)
|
AcknowledgementType Service::GetAcknowledgement(void)
|
||||||
{
|
{
|
||||||
ASSERT(OwnsLock());
|
ASSERT(OwnsLock());
|
||||||
@ -239,51 +187,6 @@ void Service::ClearAcknowledgement(const String& authority)
|
|||||||
OnAcknowledgementCleared(GetSelf(), authority);
|
OnAcknowledgementCleared(GetSelf(), authority);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<Host::Ptr> Service::GetParentHosts(void) const
|
|
||||||
{
|
|
||||||
std::set<Host::Ptr> parents;
|
|
||||||
|
|
||||||
Host::Ptr host = GetHost();
|
|
||||||
|
|
||||||
/* The service's host is implicitly a parent. */
|
|
||||||
parents.insert(host);
|
|
||||||
|
|
||||||
Array::Ptr dependencies = GetHostDependencies();
|
|
||||||
|
|
||||||
if (dependencies) {
|
|
||||||
ObjectLock olock(dependencies);
|
|
||||||
|
|
||||||
BOOST_FOREACH(const String& dependency, dependencies) {
|
|
||||||
parents.insert(Host::GetByName(dependency));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return parents;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::set<Service::Ptr> Service::GetParentServices(void) const
|
|
||||||
{
|
|
||||||
std::set<Service::Ptr> parents;
|
|
||||||
|
|
||||||
Host::Ptr host = GetHost();
|
|
||||||
Array::Ptr dependencies = GetServiceDependencies();
|
|
||||||
|
|
||||||
if (host && dependencies) {
|
|
||||||
ObjectLock olock(dependencies);
|
|
||||||
|
|
||||||
BOOST_FOREACH(const Value& dependency, dependencies) {
|
|
||||||
Service::Ptr service = host->GetServiceByShortName(dependency);
|
|
||||||
|
|
||||||
if (!service || service->GetName() == GetName())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
parents.insert(service);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return parents;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Service::GetEnablePerfdata(void) const
|
bool Service::GetEnablePerfdata(void) const
|
||||||
{
|
{
|
||||||
if (!GetOverrideEnablePerfdata().IsEmpty())
|
if (!GetOverrideEnablePerfdata().IsEmpty())
|
||||||
|
@ -96,11 +96,13 @@ public:
|
|||||||
Host::Ptr GetHost(void) const;
|
Host::Ptr GetHost(void) const;
|
||||||
|
|
||||||
std::set<Host::Ptr> GetParentHosts(void) const;
|
std::set<Host::Ptr> GetParentHosts(void) const;
|
||||||
|
std::set<Host::Ptr> GetChildHosts(void) const;
|
||||||
std::set<Service::Ptr> GetParentServices(void) const;
|
std::set<Service::Ptr> GetParentServices(void) const;
|
||||||
|
std::set<Service::Ptr> GetChildServices(void) const;
|
||||||
|
|
||||||
bool IsHostCheck(void) const;
|
bool IsHostCheck(void) const;
|
||||||
|
|
||||||
bool IsReachable(void) const;
|
bool IsReachable(DependencyType dt = DependencyState, shared_ptr<Dependency> *failedDependency = NULL, int rstack = 0) const;
|
||||||
|
|
||||||
AcknowledgementType GetAcknowledgement(void);
|
AcknowledgementType GetAcknowledgement(void);
|
||||||
|
|
||||||
@ -273,6 +275,17 @@ public:
|
|||||||
bool GetEnablePerfdata(void) const;
|
bool GetEnablePerfdata(void) const;
|
||||||
void SetEnablePerfdata(bool enabled, const String& authority = String());
|
void SetEnablePerfdata(bool enabled, const String& authority = String());
|
||||||
|
|
||||||
|
/* Dependencies */
|
||||||
|
void AddDependency(const shared_ptr<Dependency>& dep);
|
||||||
|
void RemoveDependency(const shared_ptr<Dependency>& dep);
|
||||||
|
std::set<shared_ptr<Dependency> > GetDependencies(void) const;
|
||||||
|
|
||||||
|
void AddReverseDependency(const shared_ptr<Dependency>& dep);
|
||||||
|
void RemoveReverseDependency(const shared_ptr<Dependency>& dep);
|
||||||
|
std::set<shared_ptr<Dependency> > GetReverseDependencies(void) const;
|
||||||
|
|
||||||
|
void UpdateSlaveDependencies(void);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void Start(void);
|
virtual void Start(void);
|
||||||
|
|
||||||
@ -297,6 +310,11 @@ private:
|
|||||||
|
|
||||||
/* Notifications */
|
/* Notifications */
|
||||||
std::set<Notification::Ptr> m_Notifications;
|
std::set<Notification::Ptr> m_Notifications;
|
||||||
|
|
||||||
|
/* Dependencies */
|
||||||
|
mutable boost::mutex m_DependencyMutex;
|
||||||
|
std::set<shared_ptr<Dependency> > m_Dependencies;
|
||||||
|
std::set<shared_ptr<Dependency> > m_ReverseDependencies;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -30,8 +30,6 @@ class Service : DynamicObject
|
|||||||
}}}
|
}}}
|
||||||
};
|
};
|
||||||
[config] Dictionary::Ptr macros;
|
[config] Dictionary::Ptr macros;
|
||||||
[config] Array::Ptr host_dependencies;
|
|
||||||
[config] Array::Ptr service_dependencies;
|
|
||||||
[config] Array::Ptr groups;
|
[config] Array::Ptr groups;
|
||||||
[config, protected] String check_command (CheckCommandRaw);
|
[config, protected] String check_command (CheckCommandRaw);
|
||||||
[config] int max_check_attempts (MaxCheckAttemptsRaw) {
|
[config] int max_check_attempts (MaxCheckAttemptsRaw) {
|
||||||
@ -60,6 +58,7 @@ class Service : DynamicObject
|
|||||||
};
|
};
|
||||||
[config] Dictionary::Ptr notifications (NotificationDescriptions);
|
[config] Dictionary::Ptr notifications (NotificationDescriptions);
|
||||||
[config] Dictionary::Ptr scheduled_downtimes (ScheduledDowntimeDescriptions);
|
[config] Dictionary::Ptr scheduled_downtimes (ScheduledDowntimeDescriptions);
|
||||||
|
[config] Dictionary::Ptr dependencies (DependencyDescriptions);
|
||||||
[config] bool enable_active_checks (EnableActiveChecksRaw) {
|
[config] bool enable_active_checks (EnableActiveChecksRaw) {
|
||||||
default {{{ return true; }}}
|
default {{{ return true; }}}
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user