From: Gunnar Beutner Date: Sun, 24 Feb 2013 07:26:10 +0000 (+0100) Subject: Implemented the User class. X-Git-Tag: v0.0.2~371 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=77affd3ad6d006d15ebe8ad01c7cc3c36b5a3809;p=icinga2 Implemented the User class. --- diff --git a/itl/types.conf b/itl/types.conf index 9f3956897..0344b3ecd 100644 --- a/itl/types.conf +++ b/itl/types.conf @@ -113,6 +113,10 @@ type Host { %attribute dictionary "macros" { %attribute string "*" + }, + + %attribute dictionary "users" { + %attribute string "*" } } }, @@ -194,11 +198,16 @@ type Service { %attribute dictionary "notifications" { %attribute string "*", %attribute dictionary "*" { - %require "notification", - %attribute string "notification", + %attribute dictionary "templates" { + %attribute string "*" + }, %attribute dictionary "macros" { %attribute string "*" + }, + + %attribute dictionary "users" { + %attribute string "*" } } } @@ -247,3 +256,10 @@ type Script { %require "code", %attribute string "code" } + +type User { + %attribute dictionary "macros" { + %attribute string "*" + } +} + diff --git a/lib/icinga/Makefile.am b/lib/icinga/Makefile.am index 9e09a230c..9dba6e9f5 100644 --- a/lib/icinga/Makefile.am +++ b/lib/icinga/Makefile.am @@ -40,7 +40,9 @@ libicinga_la_SOURCES = \ service-notification.cpp \ service.h \ servicegroup.cpp \ - servicegroup.h + servicegroup.h \ + user.cpp \ + user.h libicinga_la_CPPFLAGS = \ -DI2_ICINGA_BUILD \ diff --git a/lib/icinga/i2-icinga.h b/lib/icinga/i2-icinga.h index d31ac7bd0..cb6f9c66d 100644 --- a/lib/icinga/i2-icinga.h +++ b/lib/icinga/i2-icinga.h @@ -46,6 +46,8 @@ using boost::algorithm::is_any_of; #include "endpointmanager.h" #include "icingaapplication.h" +#include "user.h" + #include "notification.h" #include "notificationrequestmessage.h" diff --git a/lib/icinga/icinga.vcxproj b/lib/icinga/icinga.vcxproj index a81ea70f7..44201f776 100644 --- a/lib/icinga/icinga.vcxproj +++ b/lib/icinga/icinga.vcxproj @@ -44,6 +44,7 @@ + @@ -62,6 +63,7 @@ + {C1FC77E1-04A4-481B-A78B-2F7AF489C2F8} diff --git a/lib/icinga/notification.cpp b/lib/icinga/notification.cpp index dd7d67e98..4e8e574e9 100644 --- a/lib/icinga/notification.cpp +++ b/lib/icinga/notification.cpp @@ -70,6 +70,22 @@ Dictionary::Ptr Notification::GetMacros(void) const return Get("macros"); } +set Notification::GetUsers(void) const +{ + set result; + + Dictionary::Ptr users = Get("users"); + + if (users) { + String name; + BOOST_FOREACH(tie(tuples::ignore, name), users) { + result.insert(User::GetByName(name)); + } + } + + return result; +} + String Notification::NotificationTypeToString(NotificationType type) { switch (type) { @@ -100,11 +116,13 @@ void Notification::BeginExecuteNotification(const Notification::Ptr& self, Notif macroDicts.push_back(notificationMacros); Service::Ptr service; + set users; { ObjectLock olock(self); macroDicts.push_back(self->GetMacros()); service = self->GetService(); + users = self->GetUsers(); } Host::Ptr host; @@ -136,15 +154,45 @@ void Notification::BeginExecuteNotification(const Notification::Ptr& self, Notif Dictionary::Ptr macros = MacroProcessor::MergeMacroDicts(macroDicts); - vector arguments; - arguments.push_back(self); - arguments.push_back(macros); - arguments.push_back(type); + int count = 0; + + BOOST_FOREACH(const User::Ptr& user, users) { + BeginExecuteNotificationHelper(self, macros, type, user); + count++; + } + + if (count == 0) { + /* Send a notification even if there are no users specified. */ + BeginExecuteNotificationHelper(self, macros, type, User::Ptr()); + } +} + +void Notification::BeginExecuteNotificationHelper(const Notification::Ptr& self, const Dictionary::Ptr& notificationMacros, NotificationType type, const User::Ptr& user) +{ + vector macroDicts; + + if (user) { + { + ObjectLock olock(self); + macroDicts.push_back(user->GetMacros()); + } + + macroDicts.push_back(User::CalculateDynamicMacros(user)); + } + + macroDicts.push_back(notificationMacros); + + Dictionary::Ptr macros = MacroProcessor::MergeMacroDicts(macroDicts); ScriptTask::Ptr task; { ObjectLock olock(self); + + vector arguments; + arguments.push_back(self); + arguments.push_back(macros); + arguments.push_back(type); task = self->MakeMethodTask("notify", arguments); if (!task) { diff --git a/lib/icinga/notification.h b/lib/icinga/notification.h index 4aa16a1a2..176fbee8f 100644 --- a/lib/icinga/notification.h +++ b/lib/icinga/notification.h @@ -60,6 +60,7 @@ public: shared_ptr GetService(void) const; Value GetNotificationCommand(void) const; Dictionary::Ptr GetMacros(void) const; + set GetUsers(void) const; static void BeginExecuteNotification(const Notification::Ptr& self, NotificationType type); @@ -72,6 +73,9 @@ private: set m_Tasks; void NotificationCompletedHandler(const ScriptTask::Ptr& task); + + static void BeginExecuteNotificationHelper(const Notification::Ptr& self, + const Dictionary::Ptr& notificationMacros, NotificationType type, const User::Ptr& user); }; } diff --git a/lib/icinga/service-notification.cpp b/lib/icinga/service-notification.cpp index 36ade2b66..e2a97ff6a 100644 --- a/lib/icinga/service-notification.cpp +++ b/lib/icinga/service-notification.cpp @@ -49,7 +49,16 @@ void Service::SendNotifications(NotificationType type) Logger::Write(LogInformation, "icinga", "Service '" + GetName() + "' does not have any notifications."); BOOST_FOREACH(const Notification::Ptr& notification, notifications) { - Notification::BeginExecuteNotification(notification, type); + try { + Notification::BeginExecuteNotification(notification, type); + } catch (const exception& ex) { + stringstream msgbuf; + msgbuf << "Exception occured during notification for service '" + << GetName() << "': " << diagnostic_information(ex); + String message = msgbuf.str(); + + Logger::Write(LogWarning, "icinga", message); + } } SetLastNotification(Utility::GetTime()); @@ -105,6 +114,10 @@ static void CopyNotificationAttributes(TDict notificationDesc, const ConfigItemB if (!macros.IsEmpty()) builder->AddExpression("macros", OperatorPlus, macros); + Value users = notificationDesc->Get("users"); + if (!users.IsEmpty()) + builder->AddExpression("users", OperatorPlus, users); + /*Value notificationInterval = notificationDesc->Get("notification_interval"); if (!notificationInterval.IsEmpty()) builder->AddExpression("notification_interval", OperatorSet, notificationInterval);*/ diff --git a/lib/icinga/user.cpp b/lib/icinga/user.cpp new file mode 100644 index 000000000..5c5ba8502 --- /dev/null +++ b/lib/icinga/user.cpp @@ -0,0 +1,63 @@ +/****************************************************************************** + * 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 "i2-icinga.h" + +using namespace icinga; + +REGISTER_TYPE(User, NULL); + +User::User(const Dictionary::Ptr& properties) + : DynamicObject(properties) +{ } + +bool User::Exists(const String& name) +{ + return (DynamicObject::GetObject("User", name)); +} + +User::Ptr User::GetByName(const String& name) +{ + DynamicObject::Ptr configObject = DynamicObject::GetObject("User", name); + + if (!configObject) + BOOST_THROW_EXCEPTION(invalid_argument("User '" + name + "' does not exist.")); + + return dynamic_pointer_cast(configObject); +} + +Dictionary::Ptr User::GetMacros(void) const +{ + return Get("macros"); +} + +Dictionary::Ptr User::CalculateDynamicMacros(const User::Ptr& self) +{ + Dictionary::Ptr macros = boost::make_shared(); + + { + ObjectLock olock(self); + macros->Set("CONTACTNAME", self->GetName()); + macros->Set("CONTACTALIAS", self->GetName()); + } + + macros->Seal(); + + return macros; +} diff --git a/lib/icinga/user.h b/lib/icinga/user.h new file mode 100644 index 000000000..70dad242f --- /dev/null +++ b/lib/icinga/user.h @@ -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. * + ******************************************************************************/ + +#ifndef USER_H +#define USER_H + +namespace icinga +{ + +/** + * A User. + * + * @ingroup icinga + */ +class I2_ICINGA_API User : public DynamicObject +{ +public: + typedef shared_ptr Ptr; + typedef weak_ptr WeakPtr; + + User(const Dictionary::Ptr& properties); + + static bool Exists(const String& name); + static User::Ptr GetByName(const String& name); + + Dictionary::Ptr GetMacros(void) const; + static Dictionary::Ptr CalculateDynamicMacros(const User::Ptr& self); +}; + +} + +#endif /* USER_H */