From: Gunnar Beutner Date: Thu, 13 Jun 2013 09:33:00 +0000 (+0200) Subject: Refactor commands and implement event handlers. X-Git-Tag: v0.0.2~95 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d042a181bd3973e173065ce89bbf44e0a7d5154c;p=icinga2 Refactor commands and implement event handlers. Fixes #3877 Fixes #4001 --- diff --git a/components/notification/notificationcomponent.cpp b/components/notification/notificationcomponent.cpp index 24a063b0c..bc8b2703a 100644 --- a/components/notification/notificationcomponent.cpp +++ b/components/notification/notificationcomponent.cpp @@ -79,7 +79,10 @@ void NotificationComponent::NotificationTimerHandler(void) Service::Ptr service = notification->GetService(); bool reachable = service->IsReachable(); - notification->SetNextNotification(Utility::GetTime() + notification->GetNotificationInterval()); + { + ObjectLock olock(notification); + notification->SetNextNotification(Utility::GetTime() + notification->GetNotificationInterval()); + } bool send_notification; diff --git a/docs/icinga2-tutorial.adoc b/docs/icinga2-tutorial.adoc index a5e337e22..1ea1273ab 100644 --- a/docs/icinga2-tutorial.adoc +++ b/docs/icinga2-tutorial.adoc @@ -107,8 +107,8 @@ So far our Icinga 2 setup doesn't do much. Lets change that by setting up a serv check for localhost. Modify your 'icinga2.conf' configuration file by adding the following lines: ---- -template Service "my-ping" inherits "plugin-service" { - check_command = [ +object CheckCommand "my-ping" inherits "plugin-check-command" { + command = [ "$plugindir$/check_ping", "-H", "$address$", "-w", "10,5%", @@ -116,6 +116,10 @@ template Service "my-ping" inherits "plugin-service" { ] } +template Service "my-ping" inherits "plugin-service" { + check_command = "my-ping" +} + object Host "localhost" { display_name = "Home, sweet home!", @@ -133,9 +137,9 @@ object Host "localhost" { } ---- -We're defining a service template called "my-ping" which inherits from the -'plugin-service' template. The 'plugin-service' template is provided as part of -the Icinga Template Library and describes how services are checked. +We're defining a command object called "my-ping" which inherits from the +'plugin-check-command' template. The 'plugin-check-command' template is provided as part of +the Icinga Template Library and describes how checks are performed. In the case of plugin-based services this means that the command specified by the 'check_command' property is executed. @@ -154,9 +158,12 @@ By convention the following macros are usually used: |address6 |The IPv6 address of the host. |=== -Note that the 'my-ping' template does not define a value for the 'address' macro. This +Note that the 'my-ping' command object does not define a value for the 'address' macro. This is perfectly fine as long as that macro is defined somewhere else (e.g. in the host). +We're also defining a service template called 'my-ping' which uses the command object +we just created. + Next we're defining a 'Host' object called 'localhost'. We're setting an optional display_name which is used by the CGIs when showing that host in the host overview. @@ -252,7 +259,7 @@ object Host "icinga.org" { Restart your Icinga 2 instance and check the CGIs for your new service's state. Unless you have a low-latency network connection you will note that the service's state is 'CRITICAL'. -This is because in the 'my-ping' template we have hard-coded the timeout as 25 milliseconds. +This is because in the 'my-ping' command object we have hard-coded the timeout as 25 milliseconds. Ideally we'd be able to specify different timeouts for our new service. Using macros we can easily do this. @@ -260,11 +267,11 @@ can easily do this. NOTE: If you've used Icinga 1.x before you're probably familiar with doing this by passing ARGx macros to your check commands. -Start by replacing your 'my-ping' service template with this: +Start by replacing your 'my-ping' command object with this: ---- -template Service "my-ping" inherits "plugin-service" { - check_command = [ +object CheckCommand "my-ping" inherits "plugin-check-command" { + command = [ "$plugindir$/check_ping", "-H", "$address$", "-w", "$wrta$,$wpl$%", @@ -329,12 +336,12 @@ NOTE: Ordinarily you'd use double-quotes for the include path. This way only pat relative to the current configuration file are considered. The angle brackets tell Icinga 2 to search its list of global include directories. -One of the templates in the ITL is the 'ping4' template which is quite similar -to our own 'my-ping' template: +One of the templates in the ITL is the 'ping4' service template which is quite similar +to our example objects: ---- -template Service "ping4" inherits "plugin-service" { - check_command = [ +object CheckCommand "ping4" inherits "plugin-check-command" { + command = [ "$plugindir$/check_ping", "-4", "-H", "$address$", @@ -355,6 +362,10 @@ template Service "ping4" inherits "plugin-service" { timeout = 0 } } + +template Service "ping4" { + check_command = "ping4" +} ---- Lets simplify our configuration file by removing our custom 'my-ping' template and @@ -434,8 +445,8 @@ Next we're going to create a 'Notification' template which tells Icinga how to i the shell script: ---- -template Notification "mail-notification" inherits "plugin-notification" { - notification_command = [ +object NotificationCommand "mail-notification" inherits "plugin-notification-command" { + command = [ "/etc/icinga2/mail-notification.sh", "$email$" ], @@ -451,6 +462,10 @@ template Notification "mail-notification" inherits "plugin-notification" { "SERVICEOUTPUT" ] } + +template Notification "mail-notification" inherits "plugin-notification" { + notification_command = "mail-notification" +} ---- NOTE: Rather than adding these templates to your main configuration file you might want diff --git a/itl/Makefile.am b/itl/Makefile.am index c77a66b1d..501de7dd4 100644 --- a/itl/Makefile.am +++ b/itl/Makefile.am @@ -1,6 +1,8 @@ icinga2itldir = ${pkgdatadir}/itl icinga2itl_DATA = \ cluster.conf \ + command.conf \ + command-common.conf \ itl.conf \ host.conf \ notification.conf \ diff --git a/itl/command-common.conf b/itl/command-common.conf new file mode 100644 index 000000000..7d0f6784c --- /dev/null +++ b/itl/command-common.conf @@ -0,0 +1,224 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012 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. * + ******************************************************************************/ + +object CheckCommand "ping4" inherits "plugin-check-command" { + command = [ + "$plugindir$/check_ping", + "-4", + "-H", "$address$", + "-w", "$wrta$,$wpl$%", + "-c", "$crta$,$cpl$%", + "-p", "$packets$", + "-t", "$timeout$" + ], + + macros = { + wrta = 100, + wpl = 5, + + crta = 200, + cpl = 15, + + packets = 5, + timeout = 0 + } +} + +object CheckCommand "ping6" inherits "plugin-check-command" { + command = [ + "$plugindir$/check_ping", + "-6", + "-H", "$address6$", + "-w", "$wrta$,$wpl$%", + "-c", "$crta$,$cpl$%", + "-p", "$packets$", + "-t", "$timeout$" + ], + + macros = { + wrta = 100, + wpl = 5, + + crta = 200, + cpl = 15, + + packets = 5, + timeout = 0 + } +} + +object CheckCommand "dummy" inherits "plugin-check-command" { + command = [ + "$plugindir$/check_dummy", + "$state$", + "$text$" + ], + + macros = { + state = 0, + text = "Check was successful." + } +} + +object CheckCommand "tcp" inherits "plugin-check-command" { + command = [ + "$plugindir$/check_tcp", + "-H", "$address$", + "-p", "$port$" + ] +} + +object CheckCommand "udp" inherits "plugin-check-command" { + command = [ + "$plugindir$/check_udp", + "-H", "$address$", + "-p", "$port$" + ] +} + +object CheckCommand "http_vhost" inherits "plugin-check-command" { + command = [ + "$plugindir$/check_http", + "-H", "$vhost$" + ] +} + +object CheckCommand "http_ip" inherits "plugin-check-command" { + command = [ + "$plugindir$/check_ip", + "-H", "$address$" + ] +} + +object CheckCommand "https_vhost" inherits "plugin-check-command" { + command = [ + "$plugindir$/check_http", + "-H", "$vhost", "-S" + ] +} + +object CheckCommand "https_ip" inherits "plugin-check-command" { + command = [ + "$plugindir$/check_http", + "-I", "$address$", "-S" + ] +} + +object CheckCommand "smtp" inherits "plugin-check-command" { + command = [ + "$plugindir$/check_smtp", + "-H", "$address$" + ] +} + +object CheckCommand "ssmtp" inherits "plugin-check-command" { + command = [ + "$plugindir$/check_ssmtp", + "-H", "$address$", + "-p", "$port$" + ], + + macros += { + port = 465 + } +} + +object CheckCommand "ntp_time" inherits "plugin-check-command" { + command = [ + "$plugindir$/check_ntp_time", + "-H", "$address$" + ] +} + +object CheckCommand "ssh" inherits "plugin-check-command" { + command = [ + "$plugindir$/check_ssh", + "$address$" + ] +} + +object CheckCommand "disk" inherits "plugin-check-command" { + command = [ + "$plugindir$/check_disk", + "-w", "$wfree$", + "-c", "$cfree$" + ], + + macros += { + wfree = "20%", + cfree = "10%", + } +} + +object CheckCommand "users" inherits "plugin-check-command" { + command = [ + "$plugindir$/check_users", + "-w", "$wgreater$", + "-c", "$cgreater$" + ], + + macros += { + wgreater = 20, + cgreater = 50, + } +} + +object CheckCommand "processes" inherits "plugin-check-command" { + command = [ + "$plugindir$/check_procs", + "-w", "$wgreater$", + "-c", "$cgreater$" + ], + + macros += { + wgreater = 250, + cgreater = 400, + } +} + +object CheckCommand "load" inherits "plugin-check-command" { + command = [ + "$plugindir$/check_load", + "-w", "$wload1$,$wload5$,$wload15$", + "-c", "$cload1$,$cload5$,$cload15$" + ], + + macros = { + wload1 = 5.0, + wload5 = 4.0, + wload15 = 3.0, + + cload1 = 10.0, + cload5 = 6.0, + cload15 = 4.0 + } +} + +object CheckCommand "snmp" inherits "plugin-check-command" { + command = [ + "$plugindir$/check_snmp", + "-H", "$address$", + "-o", "$oid$", + "-C", "$community$" + ], + + macros = { + community = "public" + } +} \ No newline at end of file diff --git a/itl/command.conf b/itl/command.conf new file mode 100644 index 000000000..34d49be71 --- /dev/null +++ b/itl/command.conf @@ -0,0 +1,36 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012 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. * + ******************************************************************************/ + +template CheckCommand "plugin-check-command" { + methods = { + execute = "PluginCheck" + } +} + +template NotificationCommand "plugin-notification-command" { + methods = { + execute = "PluginNotification" + } +} + +template EventCommand "plugin-event-command" { + methods = { + execute = "PluginEvent" + } +} diff --git a/itl/itl.conf b/itl/itl.conf index 60a0cc708..54d8e8429 100644 --- a/itl/itl.conf +++ b/itl/itl.conf @@ -23,6 +23,8 @@ */ include "host.conf" +include "command.conf" +include "command-common.conf" include "service.conf" include "service-common.conf" include "notification.conf" diff --git a/itl/service-common.conf b/itl/service-common.conf index 3403ffbc0..0d1a0af13 100644 --- a/itl/service-common.conf +++ b/itl/service-common.conf @@ -16,212 +16,77 @@ * along with this program; if not, write to the Free Software Foundation * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * ******************************************************************************/ - -template Service "ping4" inherits "plugin-service" { - check_command = [ - "$plugindir$/check_ping", - "-4", - "-H", "$address$", - "-w", "$wrta$,$wpl$%", - "-c", "$crta$,$cpl$%", - "-p", "$packets$", - "-t", "$timeout$" - ], - - macros = { - wrta = 100, - wpl = 5, - - crta = 200, - cpl = 15, - - packets = 5, - timeout = 0 - } -} -template Service "ping6" inherits "plugin-service" { - check_command = [ - "$plugindir$/check_ping", - "-6", - "-H", "$address6$", - "-w", "$wrta$,$wpl$%", - "-c", "$crta$,$cpl$%", - "-p", "$packets$", - "-t", "$timeout$" - ], - - macros = { - wrta = 100, - wpl = 5, - - crta = 200, - cpl = 15, - - packets = 5, - timeout = 0 - } +template Service "ping4" { + check_command = "ping4" } -template Service "dummy" inherits "plugin-service" { - check_command = [ - "$plugindir$/check_dummy", - "$state$", - "$text$" - ], - - macros = { - state = 0, - text = "Check was successful." - } +template Service "ping6" { + check_command = "ping6" } -template Service "tcp" inherits "plugin-service" { - check_command = [ - "$plugindir$/check_tcp", - "-H", "$address$", - "-p", "$port$" - ] +template Service "dummy" { + check_command = "dummy" } -template Service "udp" inherits "plugin-service" { - check_command = [ - "$plugindir$/check_udp", - "-H", "$address$", - "-p", "$port$" - ] +template Service "tcp" { + check_command = "tcp" } -template Service "http_vhost" inherits "plugin-service" { - check_command = [ - "$plugindir$/check_http", - "-H", "$vhost$" - ], +template Service "udp" { + check_command = "udp" } -template Service "http_ip" inherits "plugin-service" { - check_command = [ - "$plugindir$/check_http", - "-I", "$address$" - ] +template Service "http_vhost" { + check_command = "http_vhost" } -template Service "https_vhost" inherits "plugin-service" { - check_command = [ - "$plugindir$/check_http", - "-H", "$vhost", "-S" - ], +template Service "http_ip" { + check_command = "http_ip" } -template Service "https_ip" inherits "plugin-service" { - check_command = [ - "$plugindir$/check_http", - "-I", "$address$", "-S" - ], +template Service "https_vhost" { + check_command = "https_vhost" } -template Service "smtp" inherits "plugin-service" { - check_command = [ - "$plugindir$/check_smtp", - "-H", "$address$" - ] +template Service "https_ip" { + check_command = "https_ip" } -template Service "ssmtp" inherits "plugin-service" { - check_command = [ - "$plugindir$/check_ssmtp", - "-H", "$address$", - "-p", "$port$" - ], - - macros += { - port = 465 - } +template Service "smtp" { + check_command = "smtp" } -template Service "ntp_time" inherits "plugin-service" { - check_command = [ - "$plugindir$/check_ntp_time", - "-H", "$address$" - ] +template Service "ssmtp" { + check_command = "ssmtp" } -template Service "ssh" inherits "plugin-service" { - check_command = [ - "$plugindir$/check_ssh", - "$address$" - ] +template Service "ntp_time" { + check_command = "ntp_time" } -template Service "disk" inherits "plugin-service" { - check_command = [ - "$plugindir$/check_disk", - "-w", "$wfree$", - "-c", "$cfree$" - ], - - macros += { - wfree = "20%", - cfree = "10%", - } +template Service "ssh" { + check_command = "ssh" } -template Service "users" inherits "plugin-service" { - check_command = [ - "$plugindir$/check_users", - "-w", "$wgreater$", - "-c", "$cgreater$" - ], - - macros += { - wgreater = 20, - cgreater = 50, - } +template Service "disk" { + check_command = "disk" } -template Service "processes" inherits "plugin-service" { - check_command = [ - "$plugindir$/check_procs", - "-w", "$wgreater$", - "-c", "$cgreater$" - ], - - macros += { - wgreater = 250, - cgreater = 400, - } +template Service "users" { + check_command = "users" } - -template Service "load" inherits "plugin-service" { - check_command = [ - "$plugindir$/check_load", - "-w", "$wload1$,$wload5$,$wload15$", - "-c", "$cload1$,$cload5$,$cload15$" - ], - - macros = { - wload1 = 5.0, - wload5 = 4.0, - wload15 = 3.0, - - cload1 = 10.0, - cload5 = 6.0, - cload15 = 4.0 - } +template Service "processes" { + check_command = "processes" } -template Service "snmp" inherits "plugin-service" { - check_command = [ - "$plugindir$/check_snmp", - "-H", "$address$", - "-o", "$oid$", - "-C", "$community$" - ], +template Service "load" { + check_command = "load" +} - macros = { - community = "public" - } +template Service "snmp" { + check_command = "snmp" } template Service "snmp-uptime" inherits "snmp" { diff --git a/lib/base/object.cpp b/lib/base/object.cpp index 9ef756944..025962d2d 100644 --- a/lib/base/object.cpp +++ b/lib/base/object.cpp @@ -18,6 +18,7 @@ ******************************************************************************/ #include "base/object.h" +#include "base/value.h" using namespace icinga; @@ -63,3 +64,8 @@ bool Object::OwnsLock(void) const return (m_Locked && m_LockOwner == boost::this_thread::get_id()); } #endif /* _DEBUG */ + +Object::SharedPtrHolder::operator Value(void) const +{ + return m_Object; +} diff --git a/lib/base/object.h b/lib/base/object.h index 278b2365a..2fcf8d240 100644 --- a/lib/base/object.h +++ b/lib/base/object.h @@ -42,7 +42,7 @@ using boost::static_pointer_cast; namespace icinga { -class SharedPtrHolder; +class Value; /** * Base class for all heap-allocated objects. At least one of its methods @@ -108,6 +108,8 @@ public: return static_cast >(*this); } + operator Value(void) const; + private: Object::Ptr m_Object; /**< The object that belongs to this holder instance */ diff --git a/lib/icinga/Makefile.am b/lib/icinga/Makefile.am index 59f8bccf1..a513ad038 100644 --- a/lib/icinga/Makefile.am +++ b/lib/icinga/Makefile.am @@ -13,10 +13,16 @@ EXTRA_DIST = \ libicinga_la_SOURCES = \ api.cpp \ api.h \ + checkcommand.cpp \ + checkcommand.h \ checkresultmessage.cpp \ checkresultmessage.h \ cib.cpp \ cib.h \ + command.cpp \ + command.h \ + eventcommand.cpp \ + eventcommand.h \ externalcommandprocessor.cpp \ externalcommandprocessor.h \ host.cpp \ @@ -35,20 +41,27 @@ libicinga_la_SOURCES = \ macroresolver.h \ notification.cpp \ notification.h \ + notificationcommand.cpp \ + notificationcommand.h \ notificationrequestmessage.cpp \ notificationrequestmessage.h \ nullchecktask.cpp \ nullchecktask.h \ + nulleventtask.cpp \ + nulleventtask.h \ perfdatawriter.cpp \ perfdatawriter.h \ pluginchecktask.cpp \ pluginchecktask.h \ + plugineventtask.cpp \ + plugineventtask.h \ pluginnotificationtask.cpp \ pluginnotificationtask.h \ service.cpp \ service-check.cpp \ service-comment.cpp \ service-downtime.cpp \ + service-event.cpp \ service-notification.cpp \ service.h \ servicegroup.cpp \ diff --git a/lib/icinga/checkcommand.cpp b/lib/icinga/checkcommand.cpp new file mode 100644 index 000000000..f0c494639 --- /dev/null +++ b/lib/icinga/checkcommand.cpp @@ -0,0 +1,48 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012 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/checkcommand.h" +#include "base/dynamictype.h" + +using namespace icinga; + +REGISTER_TYPE(CheckCommand); + +/** + * Constructor for the CheckCommand class. + * + * @param serializedUpdate A serialized dictionary containing attributes. + */ +CheckCommand::CheckCommand(const Dictionary::Ptr& serializedUpdate) + : Command(serializedUpdate) +{ } + +CheckCommand::Ptr CheckCommand::GetByName(const String& name) +{ + DynamicObject::Ptr configObject = DynamicObject::GetObject("CheckCommand", name); + + return dynamic_pointer_cast(configObject); +} + +Dictionary::Ptr CheckCommand::Execute(const Service::Ptr& service) +{ + std::vector arguments; + arguments.push_back(service); + return InvokeMethod("execute", arguments); +} diff --git a/lib/icinga/checkcommand.h b/lib/icinga/checkcommand.h new file mode 100644 index 000000000..2df7db5c3 --- /dev/null +++ b/lib/icinga/checkcommand.h @@ -0,0 +1,49 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012 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 CHECKCOMMAND_H +#define CHECKCOMMAND_H + +#include "icinga/command.h" +#include "icinga/service.h" + +namespace icinga +{ + +/** + * A command. + * + * @ingroup base + */ +class I2_BASE_API CheckCommand : public Command +{ +public: + typedef shared_ptr Ptr; + typedef weak_ptr WeakPtr; + + explicit CheckCommand(const Dictionary::Ptr& serializedUpdate); + + static CheckCommand::Ptr GetByName(const String& name); + + virtual Dictionary::Ptr Execute(const Service::Ptr& service); +}; + +} + +#endif /* CHECKCOMMAND_H */ diff --git a/lib/icinga/command.cpp b/lib/icinga/command.cpp new file mode 100644 index 000000000..6eb00c1a2 --- /dev/null +++ b/lib/icinga/command.cpp @@ -0,0 +1,56 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012 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/command.h" + +using namespace icinga; + +/** + * Constructor for the Command class. + * + * @param serializedUpdate A serialized dictionary containing attributes. + */ +Command::Command(const Dictionary::Ptr& serializedUpdate) + : DynamicObject(serializedUpdate) +{ + RegisterAttribute("macros", Attribute_Config, &m_Macros); + RegisterAttribute("export_macros", Attribute_Config, &m_ExportMacros); +} + +Dictionary::Ptr Command::GetMacros(void) const +{ + return m_Macros; +} + +Array::Ptr Command::GetExportMacros(void) const +{ + return m_ExportMacros; +} + +bool Command::ResolveMacro(const String& macro, const Dictionary::Ptr& cr, String *result) const +{ + Dictionary::Ptr macros = GetMacros(); + + if (macros && macros->Contains(macro)) { + *result = macros->Get(macro); + return true; + } + + return false; +} diff --git a/lib/icinga/command.h b/lib/icinga/command.h new file mode 100644 index 000000000..d796e6b43 --- /dev/null +++ b/lib/icinga/command.h @@ -0,0 +1,59 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012 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 COMMAND_H +#define COMMAND_H + +#include "icinga/macroresolver.h" +#include "base/i2-base.h" +#include "base/array.h" +#include "base/dynamicobject.h" +#include "base/logger_fwd.h" +#include + +namespace icinga +{ + +/** + * A command. + * + * @ingroup base + */ +class I2_BASE_API Command : public DynamicObject, public MacroResolver +{ +public: + typedef shared_ptr Ptr; + typedef weak_ptr WeakPtr; + + explicit Command(const Dictionary::Ptr& serializedUpdate); + + //virtual Dictionary::Ptr Execute(const Object::Ptr& context) = 0; + + Dictionary::Ptr GetMacros(void) const; + Array::Ptr GetExportMacros(void) const; + virtual bool ResolveMacro(const String& macro, const Dictionary::Ptr& cr, String *result) const; + +private: + Attribute m_Macros; + Attribute m_ExportMacros; +}; + +} + +#endif /* COMMAND_H */ diff --git a/lib/icinga/eventcommand.cpp b/lib/icinga/eventcommand.cpp new file mode 100644 index 000000000..a6d6540fa --- /dev/null +++ b/lib/icinga/eventcommand.cpp @@ -0,0 +1,48 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012 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/eventcommand.h" +#include "base/dynamictype.h" + +using namespace icinga; + +REGISTER_TYPE(EventCommand); + +/** + * Constructor for the EventCommand class. + * + * @param serializedUpdate A serialized dictionary containing attributes. + */ +EventCommand::EventCommand(const Dictionary::Ptr& serializedUpdate) + : Command(serializedUpdate) +{ } + +EventCommand::Ptr EventCommand::GetByName(const String& name) +{ + DynamicObject::Ptr configObject = DynamicObject::GetObject("EventCommand", name); + + return dynamic_pointer_cast(configObject); +} + +void EventCommand::Execute(const Service::Ptr& service) +{ + std::vector arguments; + arguments.push_back(service); + InvokeMethod("execute", arguments); +} diff --git a/lib/icinga/eventcommand.h b/lib/icinga/eventcommand.h new file mode 100644 index 000000000..0c2d6e0b8 --- /dev/null +++ b/lib/icinga/eventcommand.h @@ -0,0 +1,49 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012 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 EVENTCOMMAND_H +#define EVENTCOMMAND_H + +#include "icinga/command.h" +#include "icinga/service.h" + +namespace icinga +{ + +/** + * An event handler command. + * + * @ingroup base + */ +class I2_BASE_API EventCommand : public Command +{ +public: + typedef shared_ptr Ptr; + typedef weak_ptr WeakPtr; + + explicit EventCommand(const Dictionary::Ptr& serializedUpdate); + + static EventCommand::Ptr GetByName(const String& name); + + virtual void Execute(const Service::Ptr& context); +}; + +} + +#endif /* EVENTCOMMAND_H */ diff --git a/lib/icinga/icinga-type.conf b/lib/icinga/icinga-type.conf index 16aa0fa8e..1e0c3fb3b 100644 --- a/lib/icinga/icinga-type.conf +++ b/lib/icinga/icinga-type.conf @@ -50,8 +50,6 @@ type Host { %attribute string "*" }, - %attribute array "export_macros", - %attribute name(TimePeriod) "check_period", %attribute number "check_interval", %attribute number "retry_interval", @@ -88,10 +86,6 @@ type Host { %attribute string "*" }, - %attribute array "export_macros" { - %attribute string "*" - }, - %attribute array "users" { %attribute name(User) "*" }, @@ -118,10 +112,6 @@ type Host { %attribute string "*" }, - %attribute array "export_macros" { - %attribute string "*" - }, - %attribute array "users" { %attribute name(User) "*" }, @@ -149,10 +139,6 @@ type Host { %attribute string "*" }, - %attribute array "export_macros" { - %attribute string "*" - }, - %attribute array "servicegroups" { %attribute name(ServiceGroup) "*" }, @@ -190,19 +176,15 @@ type Service { %attribute string "*" }, - %attribute array "export_macros" { - %attribute string "*" - }, - - %attribute array "check_command" { - %attribute string "*" - }, - %attribute string "check_command", + %require "check_command", + %attribute name(CheckCommand) "check_command", %attribute number "max_check_attempts", %attribute name(TimePeriod) "check_period", %attribute number "check_interval", %attribute number "retry_interval", + %attribute name(EventCommand) "event_command", + %attribute number "notification_interval", %attribute name(TimePeriod) "notification_period", @@ -225,12 +207,6 @@ type Service { %attribute string "*" }, - %require "methods", - %attribute dictionary "methods" { - %require "check", - %attribute string "check" - }, - %attribute dictionary "notifications" { %attribute dictionary "*" { %attribute array "templates" { @@ -241,10 +217,6 @@ type Service { %attribute string "*" }, - %attribute array "export_macros" { - %attribute string "*" - }, - %attribute array "users" { %attribute name(User) "*" }, @@ -268,12 +240,6 @@ type ServiceGroup { } type Notification { - %require "methods", - %attribute dictionary "methods" { - %require "notify", - %attribute string "notify" - }, - %require "host_name", %attribute string "host_name", %attribute string "service", @@ -282,10 +248,6 @@ type Notification { %attribute string "*" }, - %attribute array "export_macros" { - %attribute string "*" - }, - %attribute array "users" { %attribute name(User) "*" }, @@ -298,10 +260,7 @@ type Notification { %attribute number "end", }, - %attribute array "notification_command" { - %attribute string "*" - }, - %attribute string "notification_command", + %attribute name(NotificationCommand) "notification_command", %attribute number "notification_interval", %attribute name(TimePeriod) "notification_period" @@ -338,3 +297,37 @@ type PerfdataWriter { %attribute string "format_template", %attribute number "rotation_interval" } + +type Command { + %require "methods", + %attribute dictionary "methods" { + %require "execute", + %attribute string "execute" + }, + +/* %if (methods.execute == "PluginNotification" || methods.execute == "PluginCheck" || methods.execute == "PluginEvent") { */ +// %require "command", + %attribute string "command", + %attribute array "command" { + %attribute string "*" + }, + %attribute array "export_macros" { + %attribute string "*" + }, + %attribute dictionary "macros" { + %attribute string "*" + } +/* } */ +} + +type CheckCommand inherits Command { + +} + +type NotificationCommand inherits Command { + +} + +type EventCommand inherits Command { + +} \ No newline at end of file diff --git a/lib/icinga/legacytimeperiod.cpp b/lib/icinga/legacytimeperiod.cpp index 71621fe11..b9bcdaeb0 100644 --- a/lib/icinga/legacytimeperiod.cpp +++ b/lib/icinga/legacytimeperiod.cpp @@ -384,8 +384,6 @@ Array::Ptr LegacyTimePeriod::ScriptFunc(const TimePeriod::Ptr& tp, double begin, Dictionary::Ptr ranges = tp->Get("ranges"); - - if (ranges) { for (int i = 0; i <= (end - begin) / (24 * 60 * 60); i++) { time_t refts = begin + i * 24 * 60 * 60; diff --git a/lib/icinga/notification.cpp b/lib/icinga/notification.cpp index 1698877a4..3034845cf 100644 --- a/lib/icinga/notification.cpp +++ b/lib/icinga/notification.cpp @@ -18,6 +18,7 @@ ******************************************************************************/ #include "icinga/notification.h" +#include "icinga/notificationcommand.h" #include "icinga/macroprocessor.h" #include "icinga/service.h" #include "base/dynamictype.h" @@ -74,9 +75,9 @@ Service::Ptr Notification::GetService(void) const return host->GetServiceByShortName(m_Service); } -Value Notification::GetNotificationCommand(void) const +NotificationCommand::Ptr Notification::GetNotificationCommand(void) const { - return m_NotificationCommand; + return NotificationCommand::GetByName(m_NotificationCommand); } Dictionary::Ptr Notification::GetMacros(void) const @@ -252,7 +253,7 @@ void Notification::BeginExecuteNotification(NotificationType type, const Diction } BOOST_FOREACH(const User::Ptr& user, allUsers) { - Log(LogDebug, "icinga", "Sending notification for user " + user->GetName()); + Log(LogDebug, "icinga", "Sending notification for user '" + user->GetName() + "'"); Utility::QueueAsyncCallback(boost::bind(&Notification::ExecuteNotificationHelper, this, type, user, cr, force)); } } @@ -271,16 +272,8 @@ void Notification::ExecuteNotificationHelper(NotificationType type, const User:: } } - Notification::Ptr self = GetSelf(); - - std::vector arguments; - arguments.push_back(self); - arguments.push_back(user); - arguments.push_back(cr); - arguments.push_back(type); - try { - InvokeMethod("notify", arguments); + GetNotificationCommand()->Execute(GetSelf(), user, cr, type); Log(LogInformation, "icinga", "Completed sending notification for service '" + GetService()->GetName() + "'"); } catch (const std::exception& ex) { diff --git a/lib/icinga/notification.h b/lib/icinga/notification.h index 4188c0f0e..62e9d805a 100644 --- a/lib/icinga/notification.h +++ b/lib/icinga/notification.h @@ -46,6 +46,7 @@ enum NotificationType }; class Service; +class NotificationCommand; /** * An Icinga notification specification. @@ -64,7 +65,7 @@ public: static Notification::Ptr GetByName(const String& name); shared_ptr GetService(void) const; - Value GetNotificationCommand(void) const; + shared_ptr GetNotificationCommand(void) const; double GetNotificationInterval(void) const; TimePeriod::Ptr GetNotificationPeriod(void) const; Dictionary::Ptr GetMacros(void) const; @@ -89,7 +90,7 @@ protected: void OnAttributeChanged(const String& name); private: - Attribute m_NotificationCommand; + Attribute m_NotificationCommand; Attribute m_NotificationInterval; Attribute m_NotificationPeriod; Attribute m_LastNotification; diff --git a/lib/icinga/notificationcommand.cpp b/lib/icinga/notificationcommand.cpp new file mode 100644 index 000000000..d9bb54eae --- /dev/null +++ b/lib/icinga/notificationcommand.cpp @@ -0,0 +1,52 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012 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/notificationcommand.h" +#include "base/dynamictype.h" + +using namespace icinga; + +REGISTER_TYPE(NotificationCommand); + +/** + * Constructor for the NotificationCommand class. + * + * @param serializedUpdate A serialized dictionary containing attributes. + */ +NotificationCommand::NotificationCommand(const Dictionary::Ptr& serializedUpdate) + : Command(serializedUpdate) +{ } + +NotificationCommand::Ptr NotificationCommand::GetByName(const String& name) +{ + DynamicObject::Ptr configObject = DynamicObject::GetObject("NotificationCommand", name); + + return dynamic_pointer_cast(configObject); +} + +Dictionary::Ptr NotificationCommand::Execute(const Notification::Ptr& notification, + const User::Ptr& user, const Dictionary::Ptr& cr, const NotificationType& type) +{ + std::vector arguments; + arguments.push_back(notification); + arguments.push_back(user); + arguments.push_back(cr); + arguments.push_back(type); + return InvokeMethod("execute", arguments); +} diff --git a/lib/icinga/notificationcommand.h b/lib/icinga/notificationcommand.h new file mode 100644 index 000000000..41ed80d37 --- /dev/null +++ b/lib/icinga/notificationcommand.h @@ -0,0 +1,52 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012 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 NOTIFICATIONCOMMAND_H +#define NOTIFICATIONCOMMAND_H + +#include "icinga/command.h" +#include "icinga/notification.h" + +namespace icinga +{ + +class Notification; + +/** + * A notification command. + * + * @ingroup base + */ +class I2_BASE_API NotificationCommand : public Command +{ +public: + typedef shared_ptr Ptr; + typedef weak_ptr WeakPtr; + + explicit NotificationCommand(const Dictionary::Ptr& serializedUpdate); + + static NotificationCommand::Ptr GetByName(const String& name); + + virtual Dictionary::Ptr Execute(const shared_ptr& notification, + const User::Ptr& user, const Dictionary::Ptr& cr, const NotificationType& type); +}; + +} + +#endif /* NOTIFICATIONCOMMAND_H */ diff --git a/lib/icinga/nullchecktask.cpp b/lib/icinga/nullchecktask.cpp index e6ec05ae1..1f7534130 100644 --- a/lib/icinga/nullchecktask.cpp +++ b/lib/icinga/nullchecktask.cpp @@ -19,13 +19,14 @@ #include "icinga/nullchecktask.h" #include "base/scriptfunction.h" +#include "base/logger_fwd.h" #include using namespace icinga; REGISTER_SCRIPTFUNCTION(NullCheck, &NullCheckTask::ScriptFunc); -Dictionary::Ptr NullCheckTask::ScriptFunc(const Service::Ptr&) +Dictionary::Ptr NullCheckTask::ScriptFunc(const Service::Ptr& service) { Dictionary::Ptr cr = boost::make_shared(); cr->Set("state", StateUnknown); diff --git a/lib/icinga/nulleventtask.cpp b/lib/icinga/nulleventtask.cpp new file mode 100644 index 000000000..0ae744009 --- /dev/null +++ b/lib/icinga/nulleventtask.cpp @@ -0,0 +1,31 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012 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/nulleventtask.h" +#include "base/scriptfunction.h" +#include "base/logger_fwd.h" +#include + +using namespace icinga; + +REGISTER_SCRIPTFUNCTION(NullEvent, &NullEventTask::ScriptFunc); + +void NullEventTask::ScriptFunc(const Service::Ptr& service) +{ +} diff --git a/lib/icinga/nulleventtask.h b/lib/icinga/nulleventtask.h new file mode 100644 index 000000000..af581febe --- /dev/null +++ b/lib/icinga/nulleventtask.h @@ -0,0 +1,46 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012 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 NULLEVENTTASK_H +#define NULLEVENTTASK_H + +#include "icinga/i2-icinga.h" +#include "icinga/service.h" +#include "base/dictionary.h" + +namespace icinga +{ + +/** + * Test class for additional event handler types. Implements the "null" event handler type. + * + * @ingroup icinga + */ +class I2_ICINGA_API NullEventTask +{ +public: + static void ScriptFunc(const Service::Ptr& service); + +private: + NullEventTask(void); +}; + +} + +#endif /* NULLEVENTTASK_H */ diff --git a/lib/icinga/pluginchecktask.cpp b/lib/icinga/pluginchecktask.cpp index 2c8ccc299..f1dc932f1 100644 --- a/lib/icinga/pluginchecktask.cpp +++ b/lib/icinga/pluginchecktask.cpp @@ -18,6 +18,7 @@ ******************************************************************************/ #include "icinga/pluginchecktask.h" +#include "icinga/checkcommand.h" #include "icinga/macroprocessor.h" #include "icinga/icingaapplication.h" #include "base/dynamictype.h" @@ -36,9 +37,11 @@ REGISTER_SCRIPTFUNCTION(PluginCheck, &PluginCheckTask::ScriptFunc); Dictionary::Ptr PluginCheckTask::ScriptFunc(const Service::Ptr& service) { - Value raw_command = service->GetCheckCommand(); + CheckCommand::Ptr commandObj = service->GetCheckCommand(); + Value raw_command = commandObj->Get("command"); std::vector resolvers; + resolvers.push_back(commandObj); resolvers.push_back(service); resolvers.push_back(service->GetHost()); resolvers.push_back(IcingaApplication::GetInstance()); @@ -47,7 +50,7 @@ Dictionary::Ptr PluginCheckTask::ScriptFunc(const Service::Ptr& service) Dictionary::Ptr envMacros = boost::make_shared(); - Array::Ptr export_macros = service->GetExportMacros(); + Array::Ptr export_macros = commandObj->GetExportMacros(); if (export_macros) { BOOST_FOREACH(const String& macro, export_macros) { diff --git a/lib/icinga/plugineventtask.cpp b/lib/icinga/plugineventtask.cpp new file mode 100644 index 000000000..54cafcdf3 --- /dev/null +++ b/lib/icinga/plugineventtask.cpp @@ -0,0 +1,69 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012 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/plugineventtask.h" +#include "icinga/eventcommand.h" +#include "icinga/macroprocessor.h" +#include "icinga/icingaapplication.h" +#include "base/dynamictype.h" +#include "base/logger_fwd.h" +#include "base/scriptfunction.h" +#include "base/utility.h" +#include "base/process.h" +#include +#include + +using namespace icinga; + +REGISTER_SCRIPTFUNCTION(PluginEvent, &PluginEventTask::ScriptFunc); + +void PluginEventTask::ScriptFunc(const Service::Ptr& service) +{ + EventCommand::Ptr commandObj = service->GetEventCommand(); + Value raw_command = commandObj->Get("command"); + + std::vector resolvers; + resolvers.push_back(commandObj); + resolvers.push_back(service); + resolvers.push_back(service->GetHost()); + resolvers.push_back(IcingaApplication::GetInstance()); + + Value command = MacroProcessor::ResolveMacros(raw_command, resolvers, Dictionary::Ptr(), Utility::EscapeShellCmd); + + Dictionary::Ptr envMacros = boost::make_shared(); + + Array::Ptr export_macros = commandObj->GetExportMacros(); + + if (export_macros) { + BOOST_FOREACH(const String& macro, export_macros) { + String value; + + if (!MacroProcessor::ResolveMacro(macro, resolvers, Dictionary::Ptr(), &value)) { + Log(LogWarning, "icinga", "export_macros for command '" + commandObj->GetName() + "' refers to unknown macro '" + macro + "'"); + continue; + } + + envMacros->Set(macro, value); + } + } + + Process::Ptr process = boost::make_shared(Process::SplitCommand(command), envMacros); + + process->Run(); +} diff --git a/lib/icinga/plugineventtask.h b/lib/icinga/plugineventtask.h new file mode 100644 index 000000000..e2e8607ea --- /dev/null +++ b/lib/icinga/plugineventtask.h @@ -0,0 +1,45 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012 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 PLUGINEVENTTASK_H +#define PLUGINEVENTTASK_H + +#include "icinga/i2-icinga.h" +#include "icinga/service.h" + +namespace icinga +{ + +/** + * Implements event handlers based on external plugins. + * + * @ingroup icinga + */ +class I2_ICINGA_API PluginEventTask +{ +public: + static void ScriptFunc(const Service::Ptr& service); + +private: + PluginEventTask(void); +}; + +} + +#endif /* PLUGINEVENTTASK_H */ diff --git a/lib/icinga/pluginnotificationtask.cpp b/lib/icinga/pluginnotificationtask.cpp index fedddabd4..7e4084270 100644 --- a/lib/icinga/pluginnotificationtask.cpp +++ b/lib/icinga/pluginnotificationtask.cpp @@ -19,6 +19,7 @@ #include "icinga/pluginnotificationtask.h" #include "icinga/notification.h" +#include "icinga/notificationcommand.h" #include "icinga/service.h" #include "icinga/macroprocessor.h" #include "icinga/icingaapplication.h" @@ -36,11 +37,13 @@ REGISTER_SCRIPTFUNCTION(PluginNotification, &PluginNotificationTask::ScriptFunc) void PluginNotificationTask::ScriptFunc(const Notification::Ptr& notification, const User::Ptr& user, const Dictionary::Ptr& cr, int itype) { + NotificationCommand::Ptr commandObj = notification->GetNotificationCommand(); + NotificationType type = static_cast(itype); Service::Ptr service = notification->GetService(); - Value raw_command = notification->GetNotificationCommand(); + Value raw_command = commandObj->Get("command"); StaticMacroResolver::Ptr notificationMacroResolver = boost::make_shared(); notificationMacroResolver->Add("NOTIFICATIONTYPE", Notification::NotificationTypeToString(type)); @@ -48,6 +51,7 @@ void PluginNotificationTask::ScriptFunc(const Notification::Ptr& notification, c std::vector resolvers; resolvers.push_back(user); resolvers.push_back(notificationMacroResolver); + resolvers.push_back(commandObj); resolvers.push_back(notification); resolvers.push_back(service); resolvers.push_back(service->GetHost()); diff --git a/lib/icinga/service-check.cpp b/lib/icinga/service-check.cpp index 5076b3cff..48e8823a1 100644 --- a/lib/icinga/service-check.cpp +++ b/lib/icinga/service-check.cpp @@ -18,6 +18,7 @@ ******************************************************************************/ #include "icinga/service.h" +#include "icinga/checkcommand.h" #include "icinga/icingaapplication.h" #include "icinga/checkresultmessage.h" #include "icinga/cib.h" @@ -38,9 +39,9 @@ const double Service::CheckIntervalDivisor = 5.0; boost::signals2::signal Service::OnCheckerChanged; boost::signals2::signal Service::OnNextCheckChanged; -Value Service::GetCheckCommand(void) const +CheckCommand::Ptr Service::GetCheckCommand(void) const { - return m_CheckCommand; + return CheckCommand::GetByName(m_CheckCommand); } long Service::GetMaxCheckAttempts(void) const @@ -365,6 +366,8 @@ void Service::ProcessCheckResult(const Dictionary::Ptr& cr) int state = cr->Get("state"); SetState(static_cast(state)); + bool call_eventhandler = false; + if (old_state != GetState()) { SetLastStateChange(now); @@ -390,6 +393,8 @@ void Service::ProcessCheckResult(const Dictionary::Ptr& cr) service->SetNextCheck(Utility::GetTime()); } } + + call_eventhandler = true; } bool hardChange = (GetStateType() == StateTypeHard && old_stateType == StateTypeSoft); @@ -451,6 +456,9 @@ void Service::ProcessCheckResult(const Dictionary::Ptr& cr) EndpointManager::GetInstance()->SendMulticastMessage(rm); + if (call_eventhandler) + ExecuteEventHandler(); + if (send_downtime_notification) RequestNotifications(in_downtime ? NotificationDowntimeStart : NotificationDowntimeEnd, cr); @@ -549,13 +557,10 @@ void Service::ExecuteCheck(void) Service::Ptr self = GetSelf(); - std::vector arguments; - arguments.push_back(self); - Dictionary::Ptr result; try { - result = InvokeMethod("check", arguments); + result = GetCheckCommand()->Execute(GetSelf()); } catch (const std::exception& ex) { std::ostringstream msgbuf; msgbuf << "Exception occured during check for service '" diff --git a/lib/icinga/service-event.cpp b/lib/icinga/service-event.cpp new file mode 100644 index 000000000..0a52477d3 --- /dev/null +++ b/lib/icinga/service-event.cpp @@ -0,0 +1,39 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012 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/eventcommand.h" + +using namespace icinga; + +EventCommand::Ptr Service::GetEventCommand(void) const +{ + return EventCommand::GetByName(m_EventCommand); +} + +void Service::ExecuteEventHandler(void) +{ + EventCommand::Ptr ec = GetEventCommand(); + + if (!ec) + return; + + Log(LogDebug, "icinga", "Executing event handler for service '" + GetName() + "'"); + ec->Execute(GetSelf()); +} \ No newline at end of file diff --git a/lib/icinga/service.cpp b/lib/icinga/service.cpp index 49cf19e75..e257eec92 100644 --- a/lib/icinga/service.cpp +++ b/lib/icinga/service.cpp @@ -19,6 +19,7 @@ #include "icinga/service.h" #include "icinga/servicegroup.h" +#include "icinga/checkcommand.h" #include "icinga/icingaapplication.h" #include "icinga/macroprocessor.h" #include "config/configitembuilder.h" @@ -39,7 +40,6 @@ Service::Service(const Dictionary::Ptr& serializedObject) RegisterAttribute("display_name", Attribute_Config, &m_DisplayName); RegisterAttribute("macros", Attribute_Config, &m_Macros); - RegisterAttribute("export_macros", Attribute_Config, &m_ExportMacros); RegisterAttribute("hostdependencies", Attribute_Config, &m_HostDependencies); RegisterAttribute("servicedependencies", Attribute_Config, &m_ServiceDependencies); RegisterAttribute("servicegroups", Attribute_Config, &m_ServiceGroups); @@ -51,6 +51,8 @@ Service::Service(const Dictionary::Ptr& serializedObject) RegisterAttribute("retry_interval", Attribute_Config, &m_RetryInterval); RegisterAttribute("checkers", Attribute_Config, &m_Checkers); + RegisterAttribute("event_command", Attribute_Config, &m_EventCommand); + RegisterAttribute("next_check", Attribute_Replicated, &m_NextCheck); RegisterAttribute("current_checker", Attribute_Replicated, &m_CurrentChecker); RegisterAttribute("check_attempt", Attribute_Replicated, &m_CheckAttempt); @@ -139,11 +141,6 @@ Dictionary::Ptr Service::GetMacros(void) const return m_Macros; } -Array::Ptr Service::GetExportMacros(void) const -{ - return m_ExportMacros; -} - Array::Ptr Service::GetHostDependencies(void) const { return m_HostDependencies; @@ -386,7 +383,13 @@ bool Service::ResolveMacro(const String& macro, const Dictionary::Ptr& cr, Strin *result = GetDisplayName(); return true; } else if (macro == "SERVICECHECKCOMMAND") { - *result = "check_i2"; + CheckCommand::Ptr commandObj = GetCheckCommand(); + + if (commandObj) + *result = commandObj->GetName(); + else + *result = ""; + return true; } diff --git a/lib/icinga/service.h b/lib/icinga/service.h index 119739407..d6b0ab02f 100644 --- a/lib/icinga/service.h +++ b/lib/icinga/service.h @@ -57,7 +57,8 @@ enum CommentType CommentAcknowledgement = 4 }; -class CheckResultMessage; +class CheckCommand; +class EventCommand; /** * An Icinga service. @@ -84,7 +85,6 @@ public: String GetDisplayName(void) const; Host::Ptr GetHost(void) const; Dictionary::Ptr GetMacros(void) const; - Array::Ptr GetExportMacros(void) const; Array::Ptr GetHostDependencies(void) const; Array::Ptr GetServiceDependencies(void) const; Array::Ptr GetGroups(void) const; @@ -101,7 +101,7 @@ public: /* Checks */ Array::Ptr GetCheckers(void) const; - Value GetCheckCommand(void) const; + shared_ptr GetCheckCommand(void) const; long GetMaxCheckAttempts(void) const; TimePeriod::Ptr GetCheckPeriod(void) const; double GetCheckInterval(void) const; @@ -241,6 +241,10 @@ public: void UpdateSlaveNotifications(void); + /* Event Handler */ + void ExecuteEventHandler(void); + shared_ptr GetEventCommand(void) const; + protected: virtual void OnRegistrationCompleted(void); virtual void OnAttributeChanged(const String& name); @@ -250,7 +254,6 @@ private: Attribute m_DisplayName; Attribute m_Macros; - Attribute m_ExportMacros; Attribute m_HostDependencies; Attribute m_ServiceDependencies; Attribute m_ServiceGroups; @@ -260,7 +263,7 @@ private: Attribute m_HostName; /* Checks */ - Attribute m_CheckCommand; + Attribute m_CheckCommand; Attribute m_MaxCheckAttempts; Attribute m_CheckPeriod; Attribute m_CheckInterval; @@ -309,6 +312,9 @@ private: Attribute m_ForceNextNotification; static void RefreshNotificationsCache(void); + + /* Event Handler */ + Attribute m_EventCommand; }; }