mirror of https://github.com/Icinga/icinga2.git
Implemented 'services' property for host definitions.
This commit is contained in:
parent
a11a36154f
commit
9b7251abb9
|
@ -6,6 +6,7 @@ SUBDIRS = \
|
|||
cibsync \
|
||||
compat \
|
||||
configfile \
|
||||
convenience \
|
||||
delegation \
|
||||
demo \
|
||||
discovery
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
pkglib_LTLIBRARIES = \
|
||||
convenience.la
|
||||
|
||||
convenience_la_SOURCES = \
|
||||
conveniencecomponent.cpp \
|
||||
conveniencecomponent.h \
|
||||
i2-convenience.h
|
||||
|
||||
convenience_la_CPPFLAGS = \
|
||||
$(BOOST_CPPFLAGS) \
|
||||
-I${top_srcdir}/base \
|
||||
-I${top_srcdir}/dyn \
|
||||
-I${top_srcdir}/jsonrpc \
|
||||
-I${top_srcdir}/icinga \
|
||||
-I${top_srcdir}/cib
|
||||
|
||||
convenience_la_LDFLAGS = \
|
||||
$(BOOST_LDFLAGS) \
|
||||
-module \
|
||||
-no-undefined \
|
||||
@RELEASE_INFO@ \
|
||||
@VERSION_INFO@
|
||||
|
||||
convenience_la_LIBADD = \
|
||||
$(BOOST_SIGNALS_LIB) \
|
||||
$(BOOST_THREAD_LIB) \
|
||||
${top_builddir}/base/libbase.la \
|
||||
${top_builddir}/dyn/libdyn.la \
|
||||
${top_builddir}/jsonrpc/libjsonrpc.la \
|
||||
${top_builddir}/icinga/libicinga.la \
|
||||
${top_builddir}/cib/libcib.la
|
|
@ -0,0 +1,181 @@
|
|||
/******************************************************************************
|
||||
* 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-convenience.h"
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
/**
|
||||
* Returns the name of the component.
|
||||
*
|
||||
* @returns The name.
|
||||
*/
|
||||
string ConvenienceComponent::GetName(void) const
|
||||
{
|
||||
return "convenience";
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the component.
|
||||
*/
|
||||
void ConvenienceComponent::Start(void)
|
||||
{
|
||||
ConfigItem::Set::Ptr itemSet = ConfigItem::GetAllObjects();
|
||||
itemSet->OnObjectAdded.connect(boost::bind(&ConvenienceComponent::HostAddedHandler, this, _2));
|
||||
itemSet->OnObjectCommitted.connect(boost::bind(&ConvenienceComponent::HostCommittedHandler, this, _2));
|
||||
itemSet->OnObjectRemoved.connect(boost::bind(&ConvenienceComponent::HostRemovedHandler, this, _2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the component.
|
||||
*/
|
||||
void ConvenienceComponent::Stop(void)
|
||||
{
|
||||
}
|
||||
|
||||
void ConvenienceComponent::HostAddedHandler(const ConfigItem::Ptr& item)
|
||||
{
|
||||
HostCommittedHandler(item);
|
||||
}
|
||||
|
||||
void ConvenienceComponent::HostCommittedHandler(const ConfigItem::Ptr& item)
|
||||
{
|
||||
if (item->GetType() != "host")
|
||||
return;
|
||||
|
||||
ConfigObject::Ptr host = ConfigObject::GetObject("host", item->GetName());
|
||||
Dictionary::Ptr oldServices;
|
||||
host->GetTag("convenience-services", &oldServices);
|
||||
|
||||
Dictionary::Ptr newServices;
|
||||
newServices = boost::make_shared<Dictionary>();
|
||||
|
||||
Dictionary::Ptr serviceDescs;
|
||||
host->GetProperty("services", &serviceDescs);
|
||||
|
||||
if (serviceDescs) {
|
||||
Dictionary::Iterator it;
|
||||
for (it = serviceDescs->Begin(); it != serviceDescs->End(); it++) {
|
||||
Variant desc = it->second;
|
||||
ConfigItem::Ptr serviceItem;
|
||||
|
||||
string name;
|
||||
|
||||
if (desc.GetType() == VariantString) {
|
||||
stringstream namebuf;
|
||||
namebuf << item->GetName() << "-" << string(desc);
|
||||
name = namebuf.str();
|
||||
|
||||
serviceItem = boost::make_shared<ConfigItem>("service", name, item->GetDebugInfo());
|
||||
serviceItem->AddParent(desc);
|
||||
|
||||
ExpressionList::Ptr exprl = boost::make_shared<ExpressionList>();
|
||||
|
||||
Expression localExpr("__local", OperatorSet, 1, item->GetDebugInfo());
|
||||
exprl->AddExpression(localExpr);
|
||||
|
||||
Expression abstractExpr("__abstract", OperatorSet, 0, item->GetDebugInfo());
|
||||
exprl->AddExpression(abstractExpr);
|
||||
|
||||
Expression typeExpr("__type", OperatorSet, "service", item->GetDebugInfo());
|
||||
exprl->AddExpression(typeExpr);
|
||||
|
||||
Expression nameExpr("__name", OperatorSet, name, item->GetDebugInfo());
|
||||
exprl->AddExpression(nameExpr);
|
||||
|
||||
Expression hostExpr("host_name", OperatorSet, item->GetName(), item->GetDebugInfo());
|
||||
exprl->AddExpression(hostExpr);
|
||||
|
||||
Expression aliasExpr("alias", OperatorSet, string(desc), item->GetDebugInfo());
|
||||
exprl->AddExpression(aliasExpr);
|
||||
|
||||
Dictionary::Ptr macros;
|
||||
if (host->GetProperty("macros", ¯os)) {
|
||||
Expression macrosExpr("macros", OperatorPlus, macros, item->GetDebugInfo());
|
||||
exprl->AddExpression(macrosExpr);
|
||||
}
|
||||
|
||||
long checkInterval;
|
||||
if (host->GetProperty("check_interval", &checkInterval)) {
|
||||
Expression checkExpr("check_interval", OperatorSet, checkInterval, item->GetDebugInfo());
|
||||
exprl->AddExpression(checkExpr);
|
||||
}
|
||||
|
||||
long retryInterval;
|
||||
if (host->GetProperty("retry_interval", &retryInterval)) {
|
||||
Expression retryExpr("retry_interval", OperatorSet, retryInterval, item->GetDebugInfo());
|
||||
exprl->AddExpression(retryExpr);
|
||||
}
|
||||
|
||||
Dictionary::Ptr sgroups;
|
||||
if (host->GetProperty("servicegroups", &sgroups)) {
|
||||
Expression sgroupsExpr("servicegroups", OperatorPlus, sgroups, item->GetDebugInfo());
|
||||
exprl->AddExpression(sgroupsExpr);
|
||||
}
|
||||
|
||||
Dictionary::Ptr checkers;
|
||||
if (host->GetProperty("checkers", &checkers)) {
|
||||
Expression checkersExpr("checkers", OperatorSet, checkers, item->GetDebugInfo());
|
||||
exprl->AddExpression(checkersExpr);
|
||||
}
|
||||
|
||||
serviceItem->SetExpressionList(exprl);
|
||||
ConfigObject::Ptr service = serviceItem->Commit();
|
||||
|
||||
newServices->SetProperty(name, serviceItem);
|
||||
} else {
|
||||
throw runtime_error("Not supported.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (oldServices) {
|
||||
Dictionary::Iterator it;
|
||||
for (it = oldServices->Begin(); it != oldServices->End(); it++) {
|
||||
ConfigItem::Ptr service = static_pointer_cast<ConfigItem>(it->second.GetObject());
|
||||
|
||||
if (!newServices->Contains(service->GetName()))
|
||||
service->Unregister();
|
||||
}
|
||||
}
|
||||
|
||||
//host.GetConfigObject()->SetTag("convenience-services", newServices);
|
||||
}
|
||||
|
||||
void ConvenienceComponent::HostRemovedHandler(const ConfigItem::Ptr& item)
|
||||
{
|
||||
if (item->GetType() != "host")
|
||||
return;
|
||||
|
||||
ConfigObject::Ptr host = item->GetConfigObject();
|
||||
|
||||
Dictionary::Ptr services;
|
||||
host->GetTag("convenience-services", &services);
|
||||
|
||||
if (!services)
|
||||
return;
|
||||
|
||||
Dictionary::Iterator it;
|
||||
for (it = services->Begin(); it != services->End(); it++) {
|
||||
ConfigItem::Ptr service = static_pointer_cast<ConfigItem>(it->second.GetObject());
|
||||
service->Unregister();
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT_COMPONENT(convenience, ConvenienceComponent);
|
|
@ -0,0 +1,44 @@
|
|||
/******************************************************************************
|
||||
* 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 CONVENIENCECOMPONENT_H
|
||||
#define CONVENIENCECOMPONENT_H
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
/**
|
||||
* @ingroup convenience
|
||||
*/
|
||||
class ConvenienceComponent : public Component
|
||||
{
|
||||
public:
|
||||
virtual string GetName(void) const;
|
||||
virtual void Start(void);
|
||||
virtual void Stop(void);
|
||||
|
||||
private:
|
||||
void HostAddedHandler(const ConfigItem::Ptr& item);
|
||||
void HostCommittedHandler(const ConfigItem::Ptr& item);
|
||||
void HostRemovedHandler(const ConfigItem::Ptr& item);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* CONVENIENCECOMPONENT_H */
|
|
@ -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. *
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef I2CONVENIENCE_H
|
||||
#define I2CONVENIENCE_H
|
||||
|
||||
/**
|
||||
* @defgroup convenience Convenience component
|
||||
*
|
||||
* The convenience component takes service definitions from host objects
|
||||
* and creates service objects. Technically this isn't strictly necessary but
|
||||
* makes defining services a lot easier for users.
|
||||
*/
|
||||
|
||||
#include <i2-base.h>
|
||||
#include <i2-dyn.h>
|
||||
#include <i2-jsonrpc.h>
|
||||
#include <i2-icinga.h>
|
||||
#include <i2-cib.h>
|
||||
|
||||
#include "conveniencecomponent.h"
|
||||
|
||||
#endif /* I2CONVENIENCE_H */
|
|
@ -72,6 +72,7 @@ components/checker/Makefile
|
|||
components/cibsync/Makefile
|
||||
components/compat/Makefile
|
||||
components/configfile/Makefile
|
||||
components/convenience/Makefile
|
||||
components/delegation/Makefile
|
||||
components/demo/Makefile
|
||||
components/discovery/Makefile
|
||||
|
|
|
@ -36,6 +36,11 @@ string ConfigItem::GetName(void) const
|
|||
return m_Name;
|
||||
}
|
||||
|
||||
DebugInfo ConfigItem::GetDebugInfo(void) const
|
||||
{
|
||||
return m_DebugInfo;
|
||||
}
|
||||
|
||||
ExpressionList::Ptr ConfigItem::GetExpressionList(void) const
|
||||
{
|
||||
return m_ExpressionList;
|
||||
|
@ -74,7 +79,7 @@ void ConfigItem::CalculateProperties(Dictionary::Ptr dictionary) const
|
|||
m_ExpressionList->Execute(dictionary);
|
||||
}
|
||||
|
||||
ObjectSet<ConfigItem::Ptr>::Ptr ConfigItem::GetAllObjects(void)
|
||||
ConfigItem::Set::Ptr ConfigItem::GetAllObjects(void)
|
||||
{
|
||||
static ObjectSet<ConfigItem::Ptr>::Ptr allObjects;
|
||||
|
||||
|
@ -105,7 +110,7 @@ ConfigItem::TNMap::Ptr ConfigItem::GetObjectsByTypeAndName(void)
|
|||
return tnmap;
|
||||
}
|
||||
|
||||
void ConfigItem::Commit(void)
|
||||
ConfigObject::Ptr ConfigItem::Commit(void)
|
||||
{
|
||||
ConfigObject::Ptr dobj = m_ConfigObject.lock();
|
||||
|
||||
|
@ -127,6 +132,9 @@ void ConfigItem::Commit(void)
|
|||
else
|
||||
dobj->Commit();
|
||||
|
||||
/* TODO: Figure out whether there are any child objects which inherit
|
||||
* from this config item and Commit() them as well */
|
||||
|
||||
ConfigItem::Ptr ci = GetObject(GetType(), GetName());
|
||||
ConfigItem::Ptr self = GetSelf();
|
||||
if (ci && ci != self) {
|
||||
|
@ -134,6 +142,8 @@ void ConfigItem::Commit(void)
|
|||
GetAllObjects()->RemoveObject(ci);
|
||||
}
|
||||
GetAllObjects()->CheckObject(self);
|
||||
|
||||
return dobj;
|
||||
}
|
||||
|
||||
void ConfigItem::Unregister(void)
|
||||
|
@ -146,6 +156,11 @@ void ConfigItem::Unregister(void)
|
|||
GetAllObjects()->RemoveObject(GetSelf());
|
||||
}
|
||||
|
||||
ConfigObject::Ptr ConfigItem::GetConfigObject(void) const
|
||||
{
|
||||
return m_ConfigObject.lock();
|
||||
}
|
||||
|
||||
ConfigItem::Ptr ConfigItem::GetObject(const string& type, const string& name)
|
||||
{
|
||||
ConfigItem::TNMap::Range range;
|
||||
|
|
|
@ -28,6 +28,8 @@ public:
|
|||
typedef shared_ptr<ConfigItem> Ptr;
|
||||
typedef weak_ptr<ConfigItem> WeakPtr;
|
||||
|
||||
typedef ObjectSet<ConfigItem::Ptr> Set;
|
||||
|
||||
typedef ObjectMap<pair<string, string>, ConfigItem::Ptr> TNMap;
|
||||
|
||||
ConfigItem(const string& type, const string& name, const DebugInfo& debuginfo);
|
||||
|
@ -43,10 +45,14 @@ public:
|
|||
|
||||
void CalculateProperties(Dictionary::Ptr dictionary) const;
|
||||
|
||||
void Commit(void);
|
||||
ConfigObject::Ptr Commit(void);
|
||||
void Unregister(void);
|
||||
|
||||
static ObjectSet<ConfigItem::Ptr>::Ptr GetAllObjects(void);
|
||||
ConfigObject::Ptr GetConfigObject(void) const;
|
||||
|
||||
DebugInfo GetDebugInfo(void) const;
|
||||
|
||||
static Set::Ptr GetAllObjects(void);
|
||||
static TNMap::Ptr GetObjectsByTypeAndName(void);
|
||||
static ConfigItem::Ptr GetObject(const string& type, const string& name);
|
||||
|
||||
|
|
|
@ -30,42 +30,52 @@ void Expression::Execute(const Dictionary::Ptr& dictionary) const
|
|||
{
|
||||
Variant oldValue, newValue;
|
||||
|
||||
ExpressionList::Ptr exprl;
|
||||
if (m_Value.GetType() == VariantObject)
|
||||
exprl = dynamic_pointer_cast<ExpressionList>(m_Value.GetObject());
|
||||
ExpressionList::Ptr valueExprl;
|
||||
Dictionary::Ptr valueDict;
|
||||
if (m_Value.GetType() == VariantObject) {
|
||||
valueExprl = dynamic_pointer_cast<ExpressionList>(m_Value.GetObject());
|
||||
valueDict = dynamic_pointer_cast<Dictionary>(m_Value.GetObject());
|
||||
}
|
||||
|
||||
newValue = m_Value;
|
||||
|
||||
Dictionary::Ptr dict;
|
||||
|
||||
switch (m_Operator) {
|
||||
case OperatorSet:
|
||||
if (exprl) {
|
||||
Dictionary::Ptr dict = boost::make_shared<Dictionary>();
|
||||
exprl->Execute(dict);
|
||||
if (valueExprl) {
|
||||
dict = boost::make_shared<Dictionary>();
|
||||
valueExprl->Execute(dict);
|
||||
newValue = dict;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case OperatorPlus:
|
||||
if (exprl) {
|
||||
dictionary->GetProperty(m_Key, &oldValue);
|
||||
dictionary->GetProperty(m_Key, &oldValue);
|
||||
|
||||
Dictionary::Ptr dict;
|
||||
if (oldValue.GetType() == VariantObject)
|
||||
dict = dynamic_pointer_cast<Dictionary>(oldValue.GetObject());
|
||||
if (oldValue.GetType() == VariantObject)
|
||||
dict = dynamic_pointer_cast<Dictionary>(oldValue.GetObject());
|
||||
|
||||
if (!dict) {
|
||||
if (!oldValue.IsEmpty()) {
|
||||
stringstream message;
|
||||
message << "Wrong argument types for += (non-dictionary and dictionary) (" << m_DebugInfo << ")";
|
||||
throw domain_error(message.str());
|
||||
}
|
||||
|
||||
dict = boost::make_shared<Dictionary>();
|
||||
if (!dict) {
|
||||
if (!oldValue.IsEmpty()) {
|
||||
stringstream message;
|
||||
message << "Wrong argument types for += (non-dictionary and dictionary) (" << m_DebugInfo << ")";
|
||||
throw domain_error(message.str());
|
||||
}
|
||||
|
||||
exprl->Execute(dict);
|
||||
newValue = dict;
|
||||
dict = boost::make_shared<Dictionary>();
|
||||
}
|
||||
|
||||
newValue = dict;
|
||||
|
||||
if (valueExprl) {
|
||||
valueExprl->Execute(dict);
|
||||
} else if (valueDict) {
|
||||
Dictionary::Iterator it;
|
||||
for (it = valueDict->Begin(); it != valueDict->End(); it++) {
|
||||
dict->SetProperty(it->first, it->second);
|
||||
}
|
||||
} else {
|
||||
stringstream message;
|
||||
message << "+= only works for dictionaries (" << m_DebugInfo << ")";
|
||||
|
|
|
@ -61,6 +61,11 @@ int IcingaApplication::Main(const vector<string>& args)
|
|||
componentObjects->OnObjectRemoved.connect(boost::bind(&IcingaApplication::DeletedComponentHandler, this, _2));
|
||||
componentObjects->Start();
|
||||
|
||||
/* load convenience config component */
|
||||
ConfigObject::Ptr convenienceComponentConfig = boost::make_shared<ConfigObject>("component", "convenience");
|
||||
convenienceComponentConfig->SetLocal(true);
|
||||
convenienceComponentConfig->Commit();
|
||||
|
||||
/* load config file */
|
||||
ConfigObject::Ptr fileComponentConfig = boost::make_shared<ConfigObject>("component", "configfile");
|
||||
fileComponentConfig->SetLocal(true);
|
||||
|
|
Loading…
Reference in New Issue