From 5f0bec39362b62834d96857660bad532dc6663fd Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Wed, 27 Jun 2012 18:43:34 +0200 Subject: [PATCH] Implemented compat module (WIP). --- base/configobject.cpp | 13 + base/configobject.h | 3 + base/socket.cpp | 2 +- components/Makefile.am | 1 + components/checker/checkercomponent.cpp | 20 +- components/checker/checkercomponent.h | 2 +- components/compat/Makefile.am | 27 ++ components/compat/compatcomponent.cpp | 208 +++++++++++++ .../compat/compatcomponent.h | 36 ++- .../compat/i2-compat.h | 30 +- components/configrpc/configrpccomponent.cpp | 12 +- components/configrpc/configrpccomponent.h | 2 +- components/delegation/delegationcomponent.cpp | 64 +++- components/delegation/delegationcomponent.h | 6 +- components/demo/democomponent.cpp | 13 +- components/demo/democomponent.h | 2 +- components/discovery/discoverycomponent.cpp | 42 +-- components/discovery/discoverycomponent.h | 2 +- configure.ac | 1 + dyn/config_lexer.cc | 215 +++++++------- dyn/config_lexer.ll | 1 + dyn/config_parser.cc | 275 ++++++++++-------- dyn/config_parser.h | 20 +- dyn/config_parser.yy | 9 + dyn/configitem.cpp | 5 +- icinga-app/Makefile.am | 1 + icinga/Makefile.am | 4 +- icinga/cib.cpp | 67 +++++ icinga/cib.h | 30 ++ icinga/endpointmanager.cpp | 9 + icinga/endpointmanager.h | 2 + icinga/i2-icinga.h | 3 +- icinga/icingaapplication.cpp | 26 +- icinga/icingaapplication.h | 4 +- icinga/service.cpp | 138 ++++++++- icinga/service.h | 27 +- 36 files changed, 965 insertions(+), 357 deletions(-) create mode 100644 components/compat/Makefile.am create mode 100644 components/compat/compatcomponent.cpp rename icinga/icingacomponent.cpp => components/compat/compatcomponent.h (72%) rename icinga/icingacomponent.h => components/compat/i2-compat.h (79%) create mode 100644 icinga/cib.cpp create mode 100644 icinga/cib.h diff --git a/base/configobject.cpp b/base/configobject.cpp index 49b7e529f..793882019 100644 --- a/base/configobject.cpp +++ b/base/configobject.cpp @@ -75,6 +75,19 @@ bool ConfigObject::IsLocal(void) const return value; } + +void ConfigObject::SetTemporary(bool value) +{ + GetProperties()->SetProperty("__temporary", value ? 1 : 0); +} + +bool ConfigObject::IsTemporary(void) const +{ + bool value = false; + GetProperties()->GetProperty("__temporary", &value); + return value; +} + void ConfigObject::SetAbstract(bool value) { GetProperties()->SetProperty("__abstract", value ? 1 : 0); diff --git a/base/configobject.h b/base/configobject.h index 05472ed4b..cbd2fc4cd 100644 --- a/base/configobject.h +++ b/base/configobject.h @@ -71,6 +71,9 @@ public: void SetLocal(bool value); bool IsLocal(void) const; + void SetTemporary(bool value); + bool IsTemporary(void) const; + void SetAbstract(bool value); bool IsAbstract(void) const; diff --git a/base/socket.cpp b/base/socket.cpp index 97b46c049..b61036688 100644 --- a/base/socket.cpp +++ b/base/socket.cpp @@ -163,7 +163,7 @@ void Socket::HandleSocketError(const std::exception& ex) { if (!OnError.empty()) { Event::Ptr ev = boost::make_shared(); - ev->OnEventDelivered.connect(boost::bind(boost::ref(OnError), GetSelf(), ex)); + ev->OnEventDelivered.connect(boost::bind(boost::ref(OnError), GetSelf(), runtime_error(ex.what()))); Event::Post(ev); CloseInternal(false); diff --git a/components/Makefile.am b/components/Makefile.am index d2dc2039c..781a6f53f 100644 --- a/components/Makefile.am +++ b/components/Makefile.am @@ -3,6 +3,7 @@ SUBDIRS = \ checker \ + compat \ configfile \ configrpc \ delegation \ diff --git a/components/checker/checkercomponent.cpp b/components/checker/checkercomponent.cpp index 862b7e992..0e414d68e 100644 --- a/components/checker/checkercomponent.cpp +++ b/components/checker/checkercomponent.cpp @@ -34,7 +34,7 @@ void CheckerComponent::Start(void) m_CheckerEndpoint->RegisterTopicHandler("checker::ClearServices", boost::bind(&CheckerComponent::ClearServicesRequestHandler, this, _2, _3)); m_CheckerEndpoint->RegisterPublication("checker::CheckResult"); - GetEndpointManager()->RegisterEndpoint(m_CheckerEndpoint); + EndpointManager::GetInstance()->RegisterEndpoint(m_CheckerEndpoint); m_CheckTimer = boost::make_shared(); m_CheckTimer->SetInterval(5); @@ -51,7 +51,7 @@ void CheckerComponent::Start(void) void CheckerComponent::Stop(void) { - EndpointManager::Ptr mgr = GetEndpointManager(); + EndpointManager::Ptr mgr = EndpointManager::GetInstance(); if (mgr) mgr->UnregisterEndpoint(m_CheckerEndpoint); @@ -134,6 +134,13 @@ void CheckerComponent::ResultTimerHandler(void) /* update service state */ service.ApplyCheckResult(result); + /* figure out when the next check is for this service */ + service.UpdateNextCheck(); + + /* remove the service from the list of pending services */ + m_PendingServices.erase(service.GetConfigObject()); + m_Services.push(service); + RequestMessage rm; rm.SetMethod("checker::CheckResult"); @@ -142,15 +149,12 @@ void CheckerComponent::ResultTimerHandler(void) params.SetProperty("state", static_cast(service.GetState())); params.SetProperty("state_type", static_cast(service.GetStateType())); params.SetProperty("current_attempt", static_cast(service.GetCurrentCheckAttempt())); + params.SetProperty("next_check", static_cast(service.GetNextCheck())); params.SetProperty("result", result.GetDictionary()); rm.SetParams(params); - GetEndpointManager()->SendMulticastMessage(m_CheckerEndpoint, rm); - - service.SetNextCheck(now + service.GetCheckInterval()); - m_PendingServices.erase(service.GetConfigObject()); - m_Services.push(service); + EndpointManager::GetInstance()->SendMulticastMessage(m_CheckerEndpoint, rm); } if (min_latency > 5) { @@ -195,7 +199,7 @@ void CheckerComponent::AssignServiceRequestHandler(const Endpoint::Ptr& sender, MessagePart result; rm.SetResult(result); - GetEndpointManager()->SendUnicastMessage(m_CheckerEndpoint, sender, rm); + EndpointManager::GetInstance()->SendUnicastMessage(m_CheckerEndpoint, sender, rm); } } diff --git a/components/checker/checkercomponent.h b/components/checker/checkercomponent.h index d8ed642da..f3c35f6eb 100644 --- a/components/checker/checkercomponent.h +++ b/components/checker/checkercomponent.h @@ -35,7 +35,7 @@ public: /** * @ingroup checker */ -class CheckerComponent : public IcingaComponent +class CheckerComponent : public Component { public: typedef shared_ptr Ptr; diff --git a/components/compat/Makefile.am b/components/compat/Makefile.am new file mode 100644 index 000000000..ea353d109 --- /dev/null +++ b/components/compat/Makefile.am @@ -0,0 +1,27 @@ +## Process this file with automake to produce Makefile.in + +pkglib_LTLIBRARIES = \ + compat.la + +compat_la_SOURCES = \ + compatcomponent.cpp \ + compatcomponent.h \ + i2-compat.h + +compat_la_CPPFLAGS = \ + $(BOOST_CPPFLAGS) \ + -I${top_srcdir}/base \ + -I${top_srcdir}/jsonrpc \ + -I${top_srcdir}/icinga + +compat_la_LDFLAGS = \ + $(BOOST_LDFLAGS) \ + -module \ + -no-undefined \ + @RELEASE_INFO@ \ + @VERSION_INFO@ + +compat_la_LIBADD = \ + ${top_builddir}/base/libbase.la \ + ${top_builddir}/jsonrpc/libjsonrpc.la \ + ${top_builddir}/icinga/libicinga.la diff --git a/components/compat/compatcomponent.cpp b/components/compat/compatcomponent.cpp new file mode 100644 index 000000000..a32ee47d1 --- /dev/null +++ b/components/compat/compatcomponent.cpp @@ -0,0 +1,208 @@ +/****************************************************************************** + * 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-compat.h" + +using namespace icinga; + +/** + * Returns the name of the component. + * + * @returns The name. + */ +string CompatComponent::GetName(void) const +{ + return "compat"; +} + +/** + * Starts the component. + */ +void CompatComponent::Start(void) +{ + m_StatusTimer = boost::make_shared(); + m_StatusTimer->SetInterval(15); + m_StatusTimer->OnTimerExpired.connect(boost::bind(&CompatComponent::StatusTimerHandler, this)); + m_StatusTimer->Start(); + + CIB::RequireInformation(CIB_ProgramStatus); + CIB::RequireInformation(CIB_ServiceStatus); +} + +/** + * Stops the component. + */ +void CompatComponent::Stop(void) +{ +} + +void CompatComponent::DumpHostStatus(ofstream& fp, Host host) +{ + fp << "hoststatus {" << endl + << "\t" << "host_name=" << host.GetName() << endl + << "\t" << "has_been_checked=1" << endl + << "\t" << "should_be_scheduled=1" << endl + << "\t" << "check_execution_time=0" << endl + << "\t" << "check_latency=0" << endl + << "\t" << "current_state=0" << endl + << "\t" << "last_check=" << time(NULL) << endl + << "\t" << "next_check=" << time(NULL) << endl + << "\t" << "current_attempt=1" << endl + << "\t" << "max_attempts=1" << endl + << "\t" << "active_checks_enabled=1" << endl + << "\t" << "passive_checks_enabled=1" << endl + << "\t" << "}" << endl + << endl; +} + +void CompatComponent::DumpHostObject(ofstream& fp, Host host) +{ + fp << "define host {" << endl + << "\t" << "host_name" << "\t" << host.GetName() << endl + << "\t" << "hostgroups" << "\t" << "all-hosts" << endl + << "\t" << "check_interval" << "\t" << 1 << endl + << "\t" << "retry_interval" << "\t" << 1 << endl + << "\t" << "max_check_attempts" << "\t" << 1 << endl + << "\t" << "active_checks_enabled" << "\t" << 1 << endl + << "\t" << "passive_checks_enabled" << "\t" << 1 << endl + << "\t" << "}" << endl + << endl; +} + +void CompatComponent::DumpServiceStatus(ofstream& fp, Service service) +{ + Dictionary::Ptr cr; + cr = service.GetLastCheckResult(); + + string plugin_output; + long start_time = -1, end_time = -1; + if (cr) { + cr->GetProperty("output", &plugin_output); + cr->GetProperty("start_time", &start_time); + cr->GetProperty("end_time", &end_time); + } + + fp << "servicestatus {" << endl + << "\t" << "host_name=" << service.GetHost().GetName() << endl + << "\t" << "service_description=" << service.GetDisplayName() << endl + << "\t" << "check_interval=" << service.GetCheckInterval() / 60.0 << endl + << "\t" << "retry_interval=" << service.GetRetryInterval() / 60.0 << endl + << "\t" << "has_been_checked=" << (end_time == -1 ? 0 : 1) << endl + << "\t" << "should_be_scheduled=1" << endl + << "\t" << "check_execution_time=" << end_time - start_time << endl + << "\t" << "check_latency=0" << endl + << "\t" << "current_state=" << service.GetState() << endl + << "\t" << "plugin_output=" << plugin_output << endl + << "\t" << "last_check=" << start_time << endl + << "\t" << "next_check=" << service.GetNextCheck() << endl + << "\t" << "current_attempt=" << service.GetCurrentCheckAttempt() << endl + << "\t" << "max_attempts=" << service.GetMaxCheckAttempts() << endl + << "\t" << "last_state_change=" << service.GetLastStateChange() << endl + << "\t" << "last_hard_state_change=" << service.GetLastHardStateChange() << endl + << "\t" << "last_update=" << time(NULL) << endl + << "\t" << "active_checks_enabled=1" << endl + << "\t" << "passive_checks_enabled=1" << endl + << "\t" << "}" << endl + << endl; +} + +void CompatComponent::DumpServiceObject(ofstream& fp, Service service) +{ + fp << "define service {" << endl + << "\t" << "host_name" << "\t" << service.GetHost().GetName() << endl + << "\t" << "service_description" << "\t" << service.GetDisplayName() << endl + << "\t" << "check_command" << "\t" << "check_i2" << endl + << "\t" << "check_interval" << "\t" << service.GetCheckInterval() / 60.0 << endl + << "\t" << "retry_interval" << "\t" << service.GetRetryInterval() / 60.0 << endl + << "\t" << "max_check_attempts" << "\t" << 1 << endl + << "\t" << "active_checks_enabled" << "\t" << 1 << endl + << "\t" << "passive_checks_enabled" << "\t" << 1 << endl + << "\t" << "}" << endl + << endl; +} + +/** + * Periodically writes the status.dat and objects.cache files. + */ +void CompatComponent::StatusTimerHandler(void) +{ + ofstream statusfp; + statusfp.open("status.dat.tmp", ofstream::out | ofstream::trunc); + + statusfp << "# Icinga status file" << endl + << "# This file is auto-generated. Do not modify this file." << endl + << endl; + + statusfp << "info {" << endl + << "\t" << "created=" << time(NULL) << endl + << "\t" << "version=2.0" << endl + << "\t" << "}" << endl + << endl; + + ofstream objectfp; + objectfp.open("objects.cache.tmp", ofstream::out | ofstream::trunc); + + objectfp << "# Icinga object cache file" << endl + << "# This file is auto-generated. Do not modify this file." << endl + << endl; + + objectfp << "define hostgroup {" << endl + << "\t" << "hostgroup_name" << "\t" << "all-hosts" << endl; + + ConfigObject::TMap::Range range; + range = ConfigObject::GetObjects("host"); + + ConfigObject::TMap::Iterator it; + + if (range.first != range.second) { + objectfp << "\t" << "members" << "\t"; + for (it = range.first; it != range.second; it++) { + Host host(it->second); + + objectfp << host.GetName(); + + if (distance(it, range.second) != 1) + objectfp << ","; + } + objectfp << endl; + } + + objectfp << "\t" << "}" << endl + << endl; + + for (it = range.first; it != range.second; it++) { + DumpHostStatus(statusfp, it->second); + DumpHostObject(objectfp, it->second); + } + + range = ConfigObject::GetObjects("service"); + + for (it = range.first; it != range.second; it++) { + DumpServiceStatus(statusfp, it->second); + DumpServiceObject(objectfp, it->second); + } + + statusfp.close(); + rename("status.dat.tmp", "status.dat"); + + objectfp.close(); + rename("objects.cache.tmp", "objects.cache"); +} + +EXPORT_COMPONENT(compat, CompatComponent); diff --git a/icinga/icingacomponent.cpp b/components/compat/compatcomponent.h similarity index 72% rename from icinga/icingacomponent.cpp rename to components/compat/compatcomponent.h index f33f4bb34..ba31359ab 100644 --- a/icinga/icingacomponent.cpp +++ b/components/compat/compatcomponent.h @@ -17,22 +17,34 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * ******************************************************************************/ -#include "i2-icinga.h" +#ifndef COMPATCOMPONENT_H +#define COMPATCOMPONENT_H -using namespace icinga; - -IcingaApplication::Ptr IcingaComponent::GetIcingaApplication(void) const +namespace icinga { - Application::Ptr application = Application::GetInstance(); - return static_pointer_cast(application); -} -EndpointManager::Ptr IcingaComponent::GetEndpointManager(void) const +/** + * @ingroup compat + */ +class CompatComponent : public Component { - IcingaApplication::Ptr app = GetIcingaApplication(); +public: + virtual string GetName(void) const; + virtual void Start(void); + virtual void Stop(void); + +private: + Timer::Ptr m_StatusTimer; - if (!app) - return EndpointManager::Ptr(); + void DumpHostStatus(ofstream& fp, Host host); + void DumpHostObject(ofstream& fp, Host host); + + void DumpServiceStatus(ofstream& fp, Service service); + void DumpServiceObject(ofstream& fp, Service service); + + void StatusTimerHandler(void); +}; - return app->GetEndpointManager(); } + +#endif /* COMPATCOMPONENT_H */ diff --git a/icinga/icingacomponent.h b/components/compat/i2-compat.h similarity index 79% rename from icinga/icingacomponent.h rename to components/compat/i2-compat.h index 700409353..4ca14d47d 100644 --- a/icinga/icingacomponent.h +++ b/components/compat/i2-compat.h @@ -17,24 +17,24 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * ******************************************************************************/ -#ifndef ICINGACOMPONENT_H -#define ICINGACOMPONENT_H - -namespace icinga -{ +#ifndef I2COMPAT_H +#define I2COMPAT_H /** - * A component that can be loaded into the Icinga application at run-time. + * @defgroup compat Compat component * - * @ingroup icinga + * The compat component implements compatibility functionality for Icinga 1.x. */ -class I2_ICINGA_API IcingaComponent : public Component -{ -protected: - IcingaApplication::Ptr GetIcingaApplication(void) const; - EndpointManager::Ptr GetEndpointManager(void) const; -}; -} +#include +#include +#include + +#include + +using std::ofstream; +using std::endl; + +#include "compatcomponent.h" -#endif /* ICINGACOMPONENT_H */ +#endif /* I2COMPAT_H */ diff --git a/components/configrpc/configrpccomponent.cpp b/components/configrpc/configrpccomponent.cpp index 4d9f017cb..3b6412f36 100644 --- a/components/configrpc/configrpccomponent.cpp +++ b/components/configrpc/configrpccomponent.cpp @@ -28,7 +28,7 @@ string ConfigRpcComponent::GetName(void) const void ConfigRpcComponent::Start(void) { - EndpointManager::Ptr endpointManager = GetEndpointManager(); + EndpointManager::Ptr endpointManager = EndpointManager::GetInstance(); m_ConfigRpcEndpoint = boost::make_shared(); @@ -58,7 +58,7 @@ void ConfigRpcComponent::Start(void) void ConfigRpcComponent::Stop(void) { - EndpointManager::Ptr mgr = GetEndpointManager(); + EndpointManager::Ptr mgr = EndpointManager::GetInstance(); if (mgr) mgr->UnregisterEndpoint(m_ConfigRpcEndpoint); @@ -78,7 +78,7 @@ void ConfigRpcComponent::SessionEstablishedHandler(const Endpoint::Ptr& endpoint RequestMessage request; request.SetMethod("config::FetchObjects"); - GetEndpointManager()->SendUnicastMessage(m_ConfigRpcEndpoint, endpoint, request); + EndpointManager::GetInstance()->SendUnicastMessage(m_ConfigRpcEndpoint, endpoint, request); } RequestMessage ConfigRpcComponent::MakeObjectMessage(const ConfigObject::Ptr& object, string method, bool includeProperties) @@ -115,7 +115,7 @@ void ConfigRpcComponent::FetchObjectsHandler(const Endpoint::Ptr& sender) RequestMessage request = MakeObjectMessage(object, "config::ObjectCreated", true); - GetEndpointManager()->SendUnicastMessage(m_ConfigRpcEndpoint, sender, request); + EndpointManager::GetInstance()->SendUnicastMessage(m_ConfigRpcEndpoint, sender, request); } } @@ -124,7 +124,7 @@ void ConfigRpcComponent::LocalObjectCommittedHandler(const ConfigObject::Ptr& ob if (!ShouldReplicateObject(object)) return; - GetEndpointManager()->SendMulticastMessage(m_ConfigRpcEndpoint, + EndpointManager::GetInstance()->SendMulticastMessage(m_ConfigRpcEndpoint, MakeObjectMessage(object, "config::ObjectCreated", true)); } @@ -133,7 +133,7 @@ void ConfigRpcComponent::LocalObjectRemovedHandler(const ConfigObject::Ptr& obje if (!ShouldReplicateObject(object)) return; - GetEndpointManager()->SendMulticastMessage(m_ConfigRpcEndpoint, + EndpointManager::GetInstance()->SendMulticastMessage(m_ConfigRpcEndpoint, MakeObjectMessage(object, "config::ObjectRemoved", false)); } diff --git a/components/configrpc/configrpccomponent.h b/components/configrpc/configrpccomponent.h index ed73370f7..001107ac5 100644 --- a/components/configrpc/configrpccomponent.h +++ b/components/configrpc/configrpccomponent.h @@ -26,7 +26,7 @@ namespace icinga /** * @ingroup configrpc */ -class ConfigRpcComponent : public IcingaComponent +class ConfigRpcComponent : public Component { public: virtual string GetName(void) const; diff --git a/components/delegation/delegationcomponent.cpp b/components/delegation/delegationcomponent.cpp index 95dad7f9f..efc5c9103 100644 --- a/components/delegation/delegationcomponent.cpp +++ b/components/delegation/delegationcomponent.cpp @@ -42,15 +42,17 @@ void DelegationComponent::Start(void) m_DelegationEndpoint = boost::make_shared(); m_DelegationEndpoint->RegisterPublication("checker::AssignService"); m_DelegationEndpoint->RegisterPublication("checker::ClearServices"); - m_DelegationEndpoint->RegisterSubscription("checker::CheckResult"); - GetEndpointManager()->RegisterEndpoint(m_DelegationEndpoint); + m_DelegationEndpoint->RegisterTopicHandler("checker::CheckResult", + boost::bind(&DelegationComponent::CheckResultRequestHandler, this, _2, _3)); + m_DelegationEndpoint->RegisterPublication("delegation::ServiceStatus"); + EndpointManager::GetInstance()->RegisterEndpoint(m_DelegationEndpoint); - GetEndpointManager()->OnNewEndpoint.connect(bind(&DelegationComponent::NewEndpointHandler, this, _2)); + EndpointManager::GetInstance()->OnNewEndpoint.connect(bind(&DelegationComponent::NewEndpointHandler, this, _2)); } void DelegationComponent::Stop(void) { - EndpointManager::Ptr mgr = GetEndpointManager(); + EndpointManager::Ptr mgr = EndpointManager::GetInstance(); if (mgr) mgr->UnregisterEndpoint(m_DelegationEndpoint); @@ -75,7 +77,7 @@ void DelegationComponent::AssignService(const Endpoint::Ptr& checker, const Serv Application::Log(LogDebug, "delegation", "Trying to delegate service '" + service.GetName() + "'"); - GetEndpointManager()->SendUnicastMessage(m_DelegationEndpoint, checker, request); + EndpointManager::GetInstance()->SendUnicastMessage(m_DelegationEndpoint, checker, request); } void DelegationComponent::ClearServices(const Endpoint::Ptr& checker) @@ -86,7 +88,12 @@ void DelegationComponent::ClearServices(const Endpoint::Ptr& checker) MessagePart params; request.SetParams(params); - GetEndpointManager()->SendUnicastMessage(m_DelegationEndpoint, checker, request); + EndpointManager::GetInstance()->SendUnicastMessage(m_DelegationEndpoint, checker, request); +} + +bool DelegationComponent::IsEndpointChecker(const Endpoint::Ptr& endpoint) +{ + return (endpoint->HasSubscription("checker::AssignService")); } vector DelegationComponent::GetCheckerCandidates(const Service& service) const @@ -94,7 +101,7 @@ vector DelegationComponent::GetCheckerCandidates(const Service& s vector candidates; EndpointManager::Iterator it; - for (it = GetEndpointManager()->Begin(); it != GetEndpointManager()->End(); it++) { + for (it = EndpointManager::GetInstance()->Begin(); it != EndpointManager::GetInstance()->End(); it++) { Endpoint::Ptr endpoint = it->second; /* ignore disconnected endpoints */ @@ -102,7 +109,11 @@ vector DelegationComponent::GetCheckerCandidates(const Service& s continue; /* ignore endpoints that aren't running the checker component */ - if (!endpoint->HasSubscription("checker::AssignService")) + if (!IsEndpointChecker(endpoint)) + continue; + + /* ignore endpoints that aren't allowed to check this service */ + if (!service.IsAllowedChecker(it->first)) continue; candidates.push_back(endpoint); @@ -117,6 +128,10 @@ void DelegationComponent::NewEndpointHandler(const Endpoint::Ptr& endpoint) } void DelegationComponent::SessionEstablishedHandler(const Endpoint::Ptr& endpoint) { + /* ignore this endpoint if it's not a checker */ + if (!IsEndpointChecker(endpoint)) + return; + stringstream msgbuf; msgbuf << "Clearing assigned services for endpoint '" << endpoint->GetIdentity() << "'"; Application::Log(LogInformation, "delegation", msgbuf.str()); @@ -139,7 +154,7 @@ void DelegationComponent::DelegationTimerHandler(void) map histogram; EndpointManager::Iterator eit; - for (eit = GetEndpointManager()->Begin(); eit != GetEndpointManager()->End(); eit++) + for (eit = EndpointManager::GetInstance()->Begin(); eit != EndpointManager::GetInstance()->End(); eit++) histogram[eit->second] = 0; vector services; @@ -155,7 +170,7 @@ void DelegationComponent::DelegationTimerHandler(void) if (checker.empty()) continue; - Endpoint::Ptr endpoint = GetEndpointManager()->GetEndpointByIdentity(checker); + Endpoint::Ptr endpoint = EndpointManager::GetInstance()->GetEndpointByIdentity(checker); if (!endpoint) continue; @@ -176,7 +191,7 @@ void DelegationComponent::DelegationTimerHandler(void) Endpoint::Ptr oldEndpoint; if (!checker.empty()) - oldEndpoint = GetEndpointManager()->GetEndpointByIdentity(checker); + oldEndpoint = EndpointManager::GetInstance()->GetEndpointByIdentity(checker); vector candidates = GetCheckerCandidates(service); @@ -249,7 +264,7 @@ void DelegationComponent::DelegationTimerHandler(void) for (sit = services.begin(); sit != services.end(); sit++) { string checker = sit->GetChecker(); - Endpoint::Ptr endpoint = GetEndpointManager()->GetEndpointByIdentity(checker); + Endpoint::Ptr endpoint = EndpointManager::GetInstance()->GetEndpointByIdentity(checker); if (!endpoint) continue; @@ -263,4 +278,29 @@ void DelegationComponent::DelegationTimerHandler(void) Application::Log(LogInformation, "delegation", msgbuf.str()); } +void DelegationComponent::CheckResultRequestHandler(const Endpoint::Ptr& sender, const RequestMessage& request) +{ + MessagePart params; + if (!request.GetParams(¶ms)) + return; + + string svcname; + if (!params.GetProperty("service", &svcname)) + return; + + Service service = Service::GetByName(svcname); + + /* validate that this is an authentic check result */ + if (!service.IsAllowedChecker(sender->GetIdentity())) + return; + + /* TODO: send state update for dependant services */ + + /* send state update */ + RequestMessage rm; + rm.SetMethod("delegation::ServiceStatus"); + rm.SetParams(params); + EndpointManager::GetInstance()->SendMulticastMessage(m_DelegationEndpoint, rm); +} + EXPORT_COMPONENT(delegation, DelegationComponent); diff --git a/components/delegation/delegationcomponent.h b/components/delegation/delegationcomponent.h index 65e573e44..5b998039c 100644 --- a/components/delegation/delegationcomponent.h +++ b/components/delegation/delegationcomponent.h @@ -26,7 +26,7 @@ namespace icinga /** * @ingroup delegation */ -class DelegationComponent : public IcingaComponent +class DelegationComponent : public Component { public: virtual string GetName(void) const; @@ -48,6 +48,10 @@ private: void AssignService(const Endpoint::Ptr& checker, const Service& service); void ClearServices(const Endpoint::Ptr& checker); + + static bool IsEndpointChecker(const Endpoint::Ptr& endpoint); + + void CheckResultRequestHandler(const Endpoint::Ptr& sender, const RequestMessage& request); }; } diff --git a/components/demo/democomponent.cpp b/components/demo/democomponent.cpp index 0fc006692..19d6fa93b 100644 --- a/components/demo/democomponent.cpp +++ b/components/demo/democomponent.cpp @@ -28,7 +28,7 @@ using namespace icinga; */ string DemoComponent::GetName(void) const { - return "democomponent"; + return "demo"; } /** @@ -40,7 +40,7 @@ void DemoComponent::Start(void) m_DemoEndpoint->RegisterTopicHandler("demo::HelloWorld", boost::bind(&DemoComponent::HelloWorldRequestHandler, this, _2, _3)); m_DemoEndpoint->RegisterPublication("demo::HelloWorld"); - GetEndpointManager()->RegisterEndpoint(m_DemoEndpoint); + EndpointManager::GetInstance()->RegisterEndpoint(m_DemoEndpoint); m_DemoTimer = boost::make_shared(); m_DemoTimer->SetInterval(5); @@ -53,12 +53,10 @@ void DemoComponent::Start(void) */ void DemoComponent::Stop(void) { - IcingaApplication::Ptr app = GetIcingaApplication(); + EndpointManager::Ptr endpointManager = EndpointManager::GetInstance(); - if (app) { - EndpointManager::Ptr endpointManager = app->GetEndpointManager(); + if (endpointManager) endpointManager->UnregisterEndpoint(m_DemoEndpoint); - } } /** @@ -73,8 +71,7 @@ void DemoComponent::DemoTimerHandler(void) RequestMessage request; request.SetMethod("demo::HelloWorld"); - EndpointManager::Ptr endpointManager = GetIcingaApplication()->GetEndpointManager(); - endpointManager->SendMulticastMessage(m_DemoEndpoint, request); + EndpointManager::GetInstance()->SendMulticastMessage(m_DemoEndpoint, request); } /** diff --git a/components/demo/democomponent.h b/components/demo/democomponent.h index 92176fdc9..623c6c8b4 100644 --- a/components/demo/democomponent.h +++ b/components/demo/democomponent.h @@ -26,7 +26,7 @@ namespace icinga /** * @ingroup demo */ -class DemoComponent : public IcingaComponent +class DemoComponent : public Component { public: virtual string GetName(void) const; diff --git a/components/discovery/discoverycomponent.cpp b/components/discovery/discoverycomponent.cpp index a841233ae..9c67c1bbc 100644 --- a/components/discovery/discoverycomponent.cpp +++ b/components/discovery/discoverycomponent.cpp @@ -49,10 +49,10 @@ void DiscoveryComponent::Start(void) m_DiscoveryEndpoint->RegisterTopicHandler("discovery::Welcome", boost::bind(&DiscoveryComponent::WelcomeMessageHandler, this, _2, _3)); - GetEndpointManager()->ForEachEndpoint(boost::bind(&DiscoveryComponent::NewEndpointHandler, this, _2)); - GetEndpointManager()->OnNewEndpoint.connect(boost::bind(&DiscoveryComponent::NewEndpointHandler, this, _2)); + EndpointManager::GetInstance()->ForEachEndpoint(boost::bind(&DiscoveryComponent::NewEndpointHandler, this, _2)); + EndpointManager::GetInstance()->OnNewEndpoint.connect(boost::bind(&DiscoveryComponent::NewEndpointHandler, this, _2)); - GetEndpointManager()->RegisterEndpoint(m_DiscoveryEndpoint); + EndpointManager::GetInstance()->RegisterEndpoint(m_DiscoveryEndpoint); /* create the reconnect timer */ m_DiscoveryTimer = boost::make_shared(); @@ -69,7 +69,7 @@ void DiscoveryComponent::Start(void) */ void DiscoveryComponent::Stop(void) { - EndpointManager::Ptr mgr = GetEndpointManager(); + EndpointManager::Ptr mgr = EndpointManager::GetInstance(); if (mgr) mgr->UnregisterEndpoint(m_DiscoveryEndpoint); @@ -94,7 +94,7 @@ void DiscoveryComponent::CheckExistingEndpoint(const Endpoint::Ptr& self, const Application::Log(LogWarning, "discovery", "Detected duplicate identity:" + other->GetIdentity() + " - Disconnecting old endpoint."); other->Stop(); - GetEndpointManager()->UnregisterEndpoint(other); + EndpointManager::GetInstance()->UnregisterEndpoint(other); } } @@ -119,16 +119,16 @@ void DiscoveryComponent::NewEndpointHandler(const Endpoint::Ptr& endpoint) string identity = endpoint->GetIdentity(); - if (identity == GetEndpointManager()->GetIdentity()) { + if (identity == EndpointManager::GetInstance()->GetIdentity()) { Application::Log(LogWarning, "discovery", "Detected loop-back connection - Disconnecting endpoint."); endpoint->Stop(); - GetEndpointManager()->UnregisterEndpoint(endpoint); + EndpointManager::GetInstance()->UnregisterEndpoint(endpoint); return; } - GetEndpointManager()->ForEachEndpoint(boost::bind(&DiscoveryComponent::CheckExistingEndpoint, this, endpoint, _2)); + EndpointManager::GetInstance()->ForEachEndpoint(boost::bind(&DiscoveryComponent::CheckExistingEndpoint, this, endpoint, _2)); // we assume the other component _always_ wants // discovery::RegisterComponent messages from us @@ -137,7 +137,7 @@ void DiscoveryComponent::NewEndpointHandler(const Endpoint::Ptr& endpoint) // send a discovery::RegisterComponent message, if the // other component is a broker this makes sure // the broker knows about our message types - SendDiscoveryMessage("discovery::RegisterComponent", GetEndpointManager()->GetIdentity(), endpoint); + SendDiscoveryMessage("discovery::RegisterComponent", EndpointManager::GetInstance()->GetIdentity(), endpoint); map::iterator ic; @@ -146,7 +146,7 @@ void DiscoveryComponent::NewEndpointHandler(const Endpoint::Ptr& endpoint) endpoint->RegisterSubscription("discovery::NewComponent"); // send discovery::NewComponent message for ourselves - SendDiscoveryMessage("discovery::NewComponent", GetEndpointManager()->GetIdentity(), endpoint); + SendDiscoveryMessage("discovery::NewComponent", EndpointManager::GetInstance()->GetIdentity(), endpoint); // send discovery::NewComponent messages for all components // we know about @@ -203,14 +203,14 @@ void DiscoveryComponent::DiscoveryEndpointHandler(const Endpoint::Ptr& endpoint, */ bool DiscoveryComponent::GetComponentDiscoveryInfo(string component, ComponentDiscoveryInfo::Ptr *info) const { - if (component == GetEndpointManager()->GetIdentity()) { + if (component == EndpointManager::GetInstance()->GetIdentity()) { /* Build fake discovery info for ourselves */ *info = boost::make_shared(); - GetEndpointManager()->ForEachEndpoint(boost::bind(&DiscoveryComponent::DiscoveryEndpointHandler, this, _2, *info)); + EndpointManager::GetInstance()->ForEachEndpoint(boost::bind(&DiscoveryComponent::DiscoveryEndpointHandler, this, _2, *info)); (*info)->LastSeen = 0; - (*info)->Node = GetIcingaApplication()->GetNode(); - (*info)->Service = GetIcingaApplication()->GetService(); + (*info)->Node = IcingaApplication::GetInstance()->GetNode(); + (*info)->Service = IcingaApplication::GetInstance()->GetService(); return true; } @@ -260,7 +260,7 @@ void DiscoveryComponent::FinishDiscoverySetup(const Endpoint::Ptr& endpoint) endpoint->RegisterSubscription("discovery::Welcome"); RequestMessage request; request.SetMethod("discovery::Welcome"); - GetEndpointManager()->SendUnicastMessage(m_DiscoveryEndpoint, endpoint, request); + EndpointManager::GetInstance()->SendUnicastMessage(m_DiscoveryEndpoint, endpoint, request); endpoint->SetSentWelcome(true); @@ -310,9 +310,9 @@ void DiscoveryComponent::SendDiscoveryMessage(const string& method, const string params.SetPublications(publications); if (recipient) - GetEndpointManager()->SendUnicastMessage(m_DiscoveryEndpoint, recipient, request); + EndpointManager::GetInstance()->SendUnicastMessage(m_DiscoveryEndpoint, recipient, request); else - GetEndpointManager()->SendMulticastMessage(m_DiscoveryEndpoint, request); + EndpointManager::GetInstance()->SendMulticastMessage(m_DiscoveryEndpoint, request); } bool DiscoveryComponent::HasMessagePermission(const Dictionary::Ptr& roles, const string& messageType, const string& message) @@ -353,7 +353,7 @@ bool DiscoveryComponent::HasMessagePermission(const Dictionary::Ptr& roles, cons void DiscoveryComponent::ProcessDiscoveryMessage(const string& identity, const DiscoveryMessage& message, bool trusted) { /* ignore discovery messages that are about ourselves */ - if (identity == GetEndpointManager()->GetIdentity()) + if (identity == EndpointManager::GetInstance()->GetIdentity()) return; ComponentDiscoveryInfo::Ptr info = boost::make_shared(); @@ -379,7 +379,7 @@ void DiscoveryComponent::ProcessDiscoveryMessage(const string& identity, const D } } - Endpoint::Ptr endpoint = GetEndpointManager()->GetEndpointByIdentity(identity); + Endpoint::Ptr endpoint = EndpointManager::GetInstance()->GetEndpointByIdentity(identity); MessagePart publications; if (message.GetPublications(&publications)) { @@ -456,7 +456,7 @@ void DiscoveryComponent::RegisterComponentMessageHandler(const Endpoint::Ptr& se */ void DiscoveryComponent::DiscoveryTimerHandler(void) { - EndpointManager::Ptr endpointManager = GetEndpointManager(); + EndpointManager::Ptr endpointManager = EndpointManager::GetInstance(); time_t now; time(&now); @@ -487,7 +487,7 @@ void DiscoveryComponent::DiscoveryTimerHandler(void) i++; /* there's no need to reconnect to ourself */ - if (identity == GetEndpointManager()->GetIdentity()) + if (identity == EndpointManager::GetInstance()->GetIdentity()) continue; /* for explicitly-configured upstream endpoints diff --git a/components/discovery/discoverycomponent.h b/components/discovery/discoverycomponent.h index 3c9bc5fad..ed57447bf 100644 --- a/components/discovery/discoverycomponent.h +++ b/components/discovery/discoverycomponent.h @@ -44,7 +44,7 @@ public: /** * @ingroup discovery */ -class DiscoveryComponent : public IcingaComponent +class DiscoveryComponent : public Component { public: virtual string GetName(void) const; diff --git a/configure.ac b/configure.ac index 0da80ac31..172b88dc7 100644 --- a/configure.ac +++ b/configure.ac @@ -68,6 +68,7 @@ Makefile base/Makefile components/Makefile components/checker/Makefile +components/compat/Makefile components/configfile/Makefile components/configrpc/Makefile components/delegation/Makefile diff --git a/dyn/config_lexer.cc b/dyn/config_lexer.cc index f1fc33e99..94a4330cf 100644 --- a/dyn/config_lexer.cc +++ b/dyn/config_lexer.cc @@ -370,8 +370,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 23 -#define YY_END_OF_BUFFER 24 +#define YY_NUM_RULES 24 +#define YY_END_OF_BUFFER 25 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -379,16 +379,16 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[72] = +static yyconst flex_int16_t yy_accept[81] = { 0, - 0, 0, 0, 0, 24, 22, 21, 21, 22, 22, - 22, 22, 22, 22, 9, 10, 7, 7, 7, 7, - 7, 7, 17, 18, 21, 0, 20, 13, 11, 12, - 15, 0, 14, 9, 7, 7, 7, 7, 7, 7, - 17, 16, 8, 19, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 6, 7, 7, 7, 7, 2, - 7, 7, 7, 7, 3, 7, 4, 7, 1, 5, - 0 + 0, 0, 0, 0, 25, 23, 22, 22, 23, 23, + 23, 23, 23, 23, 10, 11, 8, 8, 8, 8, + 8, 8, 8, 18, 19, 22, 0, 21, 14, 12, + 13, 16, 0, 15, 10, 8, 8, 8, 8, 8, + 8, 8, 18, 17, 9, 20, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 7, 8, 8, + 8, 8, 8, 2, 8, 8, 8, 8, 8, 4, + 8, 8, 5, 8, 8, 1, 6, 8, 3, 0 } ; static yyconst flex_int32_t yy_ec[256] = @@ -404,9 +404,9 @@ static yyconst flex_int32_t yy_ec[256] = 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 1, 1, 1, 1, 12, 1, 13, 14, 15, 16, - 17, 12, 12, 18, 19, 20, 12, 21, 12, 22, - 23, 12, 12, 24, 25, 26, 27, 12, 12, 12, - 12, 12, 1, 1, 1, 1, 1, 1, 1, 1, + 17, 12, 12, 18, 19, 20, 12, 21, 22, 23, + 24, 25, 12, 26, 27, 28, 29, 12, 12, 12, + 30, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -423,78 +423,84 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[28] = +static yyconst flex_int32_t yy_meta[31] = { 0, 1, 1, 2, 3, 1, 4, 1, 5, 1, 5, 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5 + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 } ; -static yyconst flex_int16_t yy_base[78] = +static yyconst flex_int16_t yy_base[87] = { 0, - 0, 0, 93, 92, 97, 100, 26, 28, 0, 0, - 85, 84, 83, 26, 83, 100, 0, 78, 69, 67, - 62, 74, 0, 78, 31, 82, 0, 100, 100, 100, - 100, 0, 100, 75, 0, 59, 21, 68, 61, 61, - 0, 100, 100, 0, 54, 58, 61, 64, 55, 58, - 50, 46, 48, 50, 0, 55, 56, 52, 48, 0, - 40, 50, 44, 32, 0, 25, 0, 22, 0, 0, - 100, 39, 44, 49, 33, 54, 59 + 0, 0, 104, 103, 108, 111, 29, 31, 0, 0, + 96, 95, 94, 29, 94, 111, 0, 89, 79, 77, + 71, 85, 81, 0, 88, 34, 92, 0, 111, 111, + 111, 111, 0, 111, 85, 0, 67, 24, 78, 71, + 71, 68, 0, 111, 111, 0, 61, 67, 70, 73, + 64, 67, 58, 56, 52, 54, 58, 0, 63, 53, + 63, 59, 55, 0, 45, 46, 56, 53, 41, 0, + 55, 36, 0, 34, 28, 0, 0, 20, 0, 111, + 42, 47, 52, 36, 57, 62 } ; -static yyconst flex_int16_t yy_def[78] = +static yyconst flex_int16_t yy_def[87] = { 0, - 71, 1, 72, 72, 71, 71, 71, 71, 73, 74, - 71, 71, 71, 71, 71, 71, 75, 75, 75, 75, - 75, 75, 76, 71, 71, 73, 74, 71, 71, 71, - 71, 77, 71, 71, 75, 75, 75, 75, 75, 75, - 76, 71, 71, 77, 75, 75, 75, 75, 75, 75, - 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, - 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, - 0, 71, 71, 71, 71, 71, 71 + 80, 1, 81, 81, 80, 80, 80, 80, 82, 83, + 80, 80, 80, 80, 80, 80, 84, 84, 84, 84, + 84, 84, 84, 85, 80, 80, 82, 83, 80, 80, + 80, 80, 86, 80, 80, 84, 84, 84, 84, 84, + 84, 84, 85, 80, 80, 86, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, 84, 0, + 80, 80, 80, 80, 80, 80 } ; -static yyconst flex_int16_t yy_nxt[128] = +static yyconst flex_int16_t yy_nxt[142] = { 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 17, 17, 17, 17, 17, 19, 17, - 20, 21, 22, 17, 17, 17, 17, 25, 25, 25, - 25, 31, 25, 25, 32, 46, 33, 35, 47, 23, - 23, 23, 23, 23, 26, 26, 70, 26, 26, 27, - 69, 27, 27, 27, 41, 41, 41, 68, 41, 44, - 67, 44, 44, 44, 66, 65, 64, 63, 62, 61, - 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, - 50, 49, 48, 45, 34, 43, 42, 40, 39, 38, - 37, 36, 34, 30, 29, 28, 71, 24, 24, 5, - - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71 + 20, 17, 21, 22, 17, 17, 17, 23, 17, 17, + 26, 26, 26, 26, 32, 26, 26, 33, 48, 34, + 36, 49, 24, 24, 24, 24, 24, 27, 27, 79, + 27, 27, 28, 78, 28, 28, 28, 43, 43, 43, + 77, 43, 46, 76, 46, 46, 46, 75, 74, 73, + 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, + 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, + 52, 51, 50, 47, 35, 45, 44, 42, 41, 40, + + 39, 38, 37, 35, 31, 30, 29, 80, 25, 25, + 5, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80 } ; -static yyconst flex_int16_t yy_chk[128] = +static yyconst flex_int16_t yy_chk[142] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 7, 7, 8, - 8, 14, 25, 25, 14, 37, 14, 75, 37, 72, - 72, 72, 72, 72, 73, 73, 68, 73, 73, 74, - 66, 74, 74, 74, 76, 76, 76, 64, 76, 77, - 63, 77, 77, 77, 62, 61, 59, 58, 57, 56, - 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, - 40, 39, 38, 36, 34, 26, 24, 22, 21, 20, - 19, 18, 15, 13, 12, 11, 5, 4, 3, 71, - - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 7, 7, 8, 8, 14, 26, 26, 14, 38, 14, + 84, 38, 81, 81, 81, 81, 81, 82, 82, 78, + 82, 82, 83, 75, 83, 83, 83, 85, 85, 85, + 74, 85, 86, 72, 86, 86, 86, 71, 69, 68, + 67, 66, 65, 63, 62, 61, 60, 59, 57, 56, + 55, 54, 53, 52, 51, 50, 49, 48, 47, 42, + 41, 40, 39, 37, 35, 27, 25, 23, 22, 21, + + 20, 19, 18, 15, 13, 12, 11, 5, 4, 3, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80 } ; /* Table of booleans, true if rule could match eol. */ -static yyconst flex_int32_t yy_rule_can_match_eol[24] = +static yyconst flex_int32_t yy_rule_can_match_eol[25] = { 0, -0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, - 0, 1, 0, 0, }; +0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, }; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. @@ -545,7 +551,7 @@ do { \ } while (0) #define YY_NO_UNISTD_H 1 -#line 549 "config_lexer.cc" +#line 555 "config_lexer.cc" #define INITIAL 0 #define IN_C_COMMENT 1 @@ -794,7 +800,7 @@ YY_DECL #line 48 "config_lexer.ll" -#line 798 "config_lexer.cc" +#line 804 "config_lexer.cc" yylval = yylval_param; @@ -851,13 +857,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 72 ) + if ( yy_current_state >= 81 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_current_state != 71 ); + while ( yy_current_state != 80 ); yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; @@ -902,116 +908,121 @@ return T_LOCAL; case 3: YY_RULE_SETUP #line 51 "config_lexer.ll" -return T_OBJECT; +return T_TEMPORARY; YY_BREAK case 4: YY_RULE_SETUP #line 52 "config_lexer.ll" -return T_INCLUDE; +return T_OBJECT; YY_BREAK case 5: YY_RULE_SETUP #line 53 "config_lexer.ll" -return T_INHERITS; +return T_INCLUDE; YY_BREAK case 6: YY_RULE_SETUP #line 54 "config_lexer.ll" -return T_NULL; +return T_INHERITS; YY_BREAK case 7: YY_RULE_SETUP #line 55 "config_lexer.ll" -{ yylval->text = strdup(yytext); return T_IDENTIFIER; } +return T_NULL; YY_BREAK case 8: -/* rule 8 can match eol */ YY_RULE_SETUP #line 56 "config_lexer.ll" -{ yytext[yyleng-1] = '\0'; yylval->text = strdup(yytext + 1); return T_STRING; } +{ yylval->text = strdup(yytext); return T_IDENTIFIER; } YY_BREAK case 9: +/* rule 9 can match eol */ YY_RULE_SETUP #line 57 "config_lexer.ll" -{ yylval->num = atoi(yytext); return T_NUMBER; } +{ yytext[yyleng-1] = '\0'; yylval->text = strdup(yytext + 1); return T_STRING; } YY_BREAK case 10: YY_RULE_SETUP #line 58 "config_lexer.ll" -{ yylval->op = OperatorSet; return T_EQUAL; } +{ yylval->num = atoi(yytext); return T_NUMBER; } YY_BREAK case 11: YY_RULE_SETUP #line 59 "config_lexer.ll" -{ yylval->op = OperatorPlus; return T_PLUS_EQUAL; } +{ yylval->op = OperatorSet; return T_EQUAL; } YY_BREAK case 12: YY_RULE_SETUP #line 60 "config_lexer.ll" -{ yylval->op = OperatorMinus; return T_MINUS_EQUAL; } +{ yylval->op = OperatorPlus; return T_PLUS_EQUAL; } YY_BREAK case 13: YY_RULE_SETUP #line 61 "config_lexer.ll" -{ yylval->op = OperatorMultiply; return T_MULTIPLY_EQUAL; } +{ yylval->op = OperatorMinus; return T_MINUS_EQUAL; } YY_BREAK case 14: YY_RULE_SETUP #line 62 "config_lexer.ll" -{ yylval->op = OperatorDivide; return T_DIVIDE_EQUAL; } +{ yylval->op = OperatorMultiply; return T_MULTIPLY_EQUAL; } YY_BREAK - case 15: YY_RULE_SETUP -#line 65 "config_lexer.ll" -BEGIN(IN_C_COMMENT); +#line 63 "config_lexer.ll" +{ yylval->op = OperatorDivide; return T_DIVIDE_EQUAL; } YY_BREAK - case 16: YY_RULE_SETUP -#line 69 "config_lexer.ll" -BEGIN(INITIAL); +#line 66 "config_lexer.ll" +BEGIN(IN_C_COMMENT); YY_BREAK + + case 17: -/* rule 17 can match eol */ YY_RULE_SETUP #line 70 "config_lexer.ll" -/* ignore comment */ +BEGIN(INITIAL); YY_BREAK case 18: +/* rule 18 can match eol */ YY_RULE_SETUP #line 71 "config_lexer.ll" -/* ignore star */ +/* ignore comment */ YY_BREAK - case 19: YY_RULE_SETUP -#line 74 "config_lexer.ll" -/* ignore C++-style comments */ +#line 72 "config_lexer.ll" +/* ignore star */ YY_BREAK + case 20: YY_RULE_SETUP #line 75 "config_lexer.ll" -/* ignore shell-style comments */ +/* ignore C++-style comments */ YY_BREAK case 21: -/* rule 21 can match eol */ YY_RULE_SETUP #line 76 "config_lexer.ll" -/* ignore whitespace */ +/* ignore shell-style comments */ YY_BREAK case 22: +/* rule 22 can match eol */ YY_RULE_SETUP -#line 78 "config_lexer.ll" -return yytext[0]; +#line 77 "config_lexer.ll" +/* ignore whitespace */ YY_BREAK case 23: YY_RULE_SETUP #line 79 "config_lexer.ll" +return yytext[0]; + YY_BREAK +case 24: +YY_RULE_SETUP +#line 80 "config_lexer.ll" ECHO; YY_BREAK -#line 1015 "config_lexer.cc" +#line 1026 "config_lexer.cc" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(IN_C_COMMENT): yyterminate(); @@ -1307,7 +1318,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 72 ) + if ( yy_current_state >= 81 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1336,11 +1347,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 72 ) + if ( yy_current_state >= 81 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 71); + yy_is_jam = (yy_current_state == 80); return yy_is_jam ? 0 : yy_current_state; } @@ -2199,7 +2210,7 @@ void yyfree (void * ptr , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 79 "config_lexer.ll" +#line 80 "config_lexer.ll" diff --git a/dyn/config_lexer.ll b/dyn/config_lexer.ll index 56166a04e..19c80884d 100644 --- a/dyn/config_lexer.ll +++ b/dyn/config_lexer.ll @@ -48,6 +48,7 @@ do { \ %% abstract return T_ABSTRACT; local return T_LOCAL; +temporary return T_TEMPORARY; object return T_OBJECT; include return T_INCLUDE; inherits return T_INHERITS; diff --git a/dyn/config_parser.cc b/dyn/config_parser.cc index f2bfca17a..52e1aba54 100644 --- a/dyn/config_parser.cc +++ b/dyn/config_parser.cc @@ -139,10 +139,11 @@ using namespace icinga; T_MULTIPLY_EQUAL = 265, T_DIVIDE_EQUAL = 266, T_ABSTRACT = 267, - T_LOCAL = 268, - T_OBJECT = 269, - T_INCLUDE = 270, - T_INHERITS = 271 + T_TEMPORARY = 268, + T_LOCAL = 269, + T_OBJECT = 270, + T_INCLUDE = 271, + T_INHERITS = 272 }; #endif /* Tokens. */ @@ -156,10 +157,11 @@ using namespace icinga; #define T_MULTIPLY_EQUAL 265 #define T_DIVIDE_EQUAL 266 #define T_ABSTRACT 267 -#define T_LOCAL 268 -#define T_OBJECT 269 -#define T_INCLUDE 270 -#define T_INHERITS 271 +#define T_TEMPORARY 268 +#define T_LOCAL 269 +#define T_OBJECT 270 +#define T_INCLUDE 271 +#define T_INHERITS 272 @@ -179,7 +181,7 @@ typedef union YYSTYPE /* Line 293 of yacc.c */ -#line 183 "config_parser.cc" +#line 185 "config_parser.cc" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ @@ -203,7 +205,7 @@ typedef struct YYLTYPE /* Copy the second part of user declarations. */ /* Line 343 of yacc.c */ -#line 66 "config_parser.yy" +#line 67 "config_parser.yy" int yylex(YYSTYPE *lvalp, YYLTYPE *llocp, void *scanner); @@ -226,6 +228,7 @@ static stack m_ExpressionLists; static vector m_Objects; static ConfigItem::Ptr m_Object; static bool m_Abstract; +static bool m_Temporary; static bool m_Local; static Dictionary::Ptr m_Array; @@ -242,7 +245,7 @@ void ConfigCompiler::Compile(void) /* Line 343 of yacc.c */ -#line 246 "config_parser.cc" +#line 249 "config_parser.cc" #ifdef short # undef short @@ -466,17 +469,17 @@ union yyalloc #define YYLAST 47 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 28 +#define YYNTOKENS 29 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 23 /* YYNRULES -- Number of rules. */ -#define YYNRULES 43 +#define YYNRULES 44 /* YYNRULES -- Number of states. */ -#define YYNSTATES 60 +#define YYNSTATES 61 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 271 +#define YYMAXUTOK 272 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -488,15 +491,15 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 26, 27, 19, 17, 21, 18, 2, 20, 2, 2, + 27, 28, 20, 18, 22, 19, 2, 21, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 24, 2, 25, 2, 2, 2, 2, 2, 2, + 2, 25, 2, 26, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 22, 2, 23, 2, 2, 2, 2, + 2, 2, 2, 23, 2, 24, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -511,7 +514,7 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16 + 15, 16, 17 }; #if YYDEBUG @@ -520,36 +523,36 @@ static const yytype_uint8 yytranslate[] = static const yytype_uint8 yyprhs[] = { 0, 0, 3, 4, 7, 9, 11, 14, 15, 16, - 25, 26, 29, 31, 33, 35, 39, 41, 42, 45, - 46, 51, 52, 54, 58, 62, 69, 71, 73, 75, - 77, 79, 81, 83, 85, 87, 89, 91, 93, 94, - 99, 101, 102, 104 + 25, 26, 29, 31, 33, 35, 37, 41, 43, 44, + 47, 48, 53, 54, 56, 60, 64, 71, 73, 75, + 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, + 96, 101, 103, 104, 106 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { - 29, 0, -1, -1, 29, 30, -1, 32, -1, 31, - -1, 15, 3, -1, -1, -1, 33, 35, 14, 6, - 3, 34, 39, 40, -1, -1, 35, 36, -1, 12, - -1, 13, -1, 38, -1, 37, 21, 38, -1, 3, - -1, -1, 16, 37, -1, -1, 22, 41, 42, 23, - -1, -1, 43, -1, 43, 21, 42, -1, 6, 44, - 46, -1, 6, 24, 3, 25, 44, 46, -1, 3, - -1, 7, -1, 8, -1, 9, -1, 10, -1, 11, - -1, 3, -1, 4, -1, 5, -1, 45, -1, 47, - -1, 40, -1, -1, 26, 48, 50, 27, -1, 45, - -1, -1, 49, -1, 49, 21, 50, -1 + 30, 0, -1, -1, 30, 31, -1, 33, -1, 32, + -1, 16, 3, -1, -1, -1, 34, 36, 15, 6, + 3, 35, 40, 41, -1, -1, 36, 37, -1, 12, + -1, 13, -1, 14, -1, 39, -1, 38, 22, 39, + -1, 3, -1, -1, 17, 38, -1, -1, 23, 42, + 43, 24, -1, -1, 44, -1, 44, 22, 43, -1, + 6, 45, 47, -1, 6, 25, 3, 26, 45, 47, + -1, 3, -1, 7, -1, 8, -1, 9, -1, 10, + -1, 11, -1, 3, -1, 4, -1, 5, -1, 46, + -1, 48, -1, 41, -1, -1, 27, 49, 51, 28, + -1, 46, -1, -1, 50, -1, 50, 22, 51, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 104, 104, 105, 108, 108, 111, 115, 120, 115, - 150, 151, 154, 158, 164, 165, 168, 175, 176, 180, - 179, 191, 192, 193, 196, 204, 218, 227, 228, 229, - 230, 231, 237, 242, 246, 252, 253, 254, 261, 260, - 272, 278, 280, 281 + 0, 106, 106, 107, 110, 110, 113, 117, 122, 117, + 155, 156, 159, 163, 167, 173, 174, 177, 184, 185, + 189, 188, 200, 201, 202, 205, 213, 227, 236, 237, + 238, 239, 240, 246, 251, 255, 261, 262, 263, 270, + 269, 281, 287, 289, 290 }; #endif @@ -560,13 +563,14 @@ static const char *const yytname[] = { "$end", "error", "$undefined", "T_STRING", "T_NUMBER", "T_NULL", "T_IDENTIFIER", "T_EQUAL", "T_PLUS_EQUAL", "T_MINUS_EQUAL", - "T_MULTIPLY_EQUAL", "T_DIVIDE_EQUAL", "T_ABSTRACT", "T_LOCAL", - "T_OBJECT", "T_INCLUDE", "T_INHERITS", "'+'", "'-'", "'*'", "'/'", "','", - "'{'", "'}'", "'['", "']'", "'('", "')'", "$accept", "statements", - "statement", "include", "object", "$@1", "$@2", "attributes", - "attribute", "inherits_list", "inherits_item", "inherits_specifier", - "expressionlist", "$@3", "expressions", "expression", "operator", - "simplevalue", "value", "tuple", "$@4", "tupleitem", "tupleitems", 0 + "T_MULTIPLY_EQUAL", "T_DIVIDE_EQUAL", "T_ABSTRACT", "T_TEMPORARY", + "T_LOCAL", "T_OBJECT", "T_INCLUDE", "T_INHERITS", "'+'", "'-'", "'*'", + "'/'", "','", "'{'", "'}'", "'['", "']'", "'('", "')'", "$accept", + "statements", "statement", "include", "object", "$@1", "$@2", + "attributes", "attribute", "inherits_list", "inherits_item", + "inherits_specifier", "expressionlist", "$@3", "expressions", + "expression", "operator", "simplevalue", "value", "tuple", "$@4", + "tupleitem", "tupleitems", 0 }; #endif @@ -576,29 +580,29 @@ static const char *const yytname[] = static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 43, 45, 42, - 47, 44, 123, 125, 91, 93, 40, 41 + 265, 266, 267, 268, 269, 270, 271, 272, 43, 45, + 42, 47, 44, 123, 125, 91, 93, 40, 41 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 28, 29, 29, 30, 30, 31, 33, 34, 32, - 35, 35, 36, 36, 37, 37, 38, 39, 39, 41, - 40, 42, 42, 42, 43, 43, 43, 44, 44, 44, - 44, 44, 45, 45, 45, 46, 46, 46, 48, 47, - 49, 50, 50, 50 + 0, 29, 30, 30, 31, 31, 32, 34, 35, 33, + 36, 36, 37, 37, 37, 38, 38, 39, 40, 40, + 42, 41, 43, 43, 43, 44, 44, 44, 45, 45, + 45, 45, 45, 46, 46, 46, 47, 47, 47, 49, + 48, 50, 51, 51, 51 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 0, 2, 1, 1, 2, 0, 0, 8, - 0, 2, 1, 1, 1, 3, 1, 0, 2, 0, - 4, 0, 1, 3, 3, 6, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 0, 4, - 1, 0, 1, 3 + 0, 2, 1, 1, 1, 1, 3, 1, 0, 2, + 0, 4, 0, 1, 3, 3, 6, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 4, 1, 0, 1, 3 }; /* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. @@ -607,40 +611,42 @@ static const yytype_uint8 yyr2[] = static const yytype_uint8 yydefact[] = { 2, 7, 1, 0, 3, 5, 4, 10, 6, 0, - 12, 13, 0, 11, 0, 8, 17, 0, 0, 16, - 18, 14, 19, 9, 0, 21, 15, 26, 0, 0, - 22, 27, 28, 29, 30, 31, 0, 0, 20, 21, - 0, 32, 33, 34, 38, 37, 35, 24, 36, 23, - 0, 41, 0, 40, 42, 0, 25, 41, 39, 43 + 12, 13, 14, 0, 11, 0, 8, 18, 0, 0, + 17, 19, 15, 20, 9, 0, 22, 16, 27, 0, + 0, 23, 28, 29, 30, 31, 32, 0, 0, 21, + 22, 0, 33, 34, 35, 39, 38, 36, 25, 37, + 24, 0, 42, 0, 41, 43, 0, 26, 42, 40, + 44 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 1, 4, 5, 6, 7, 16, 9, 13, 20, - 21, 18, 45, 25, 29, 30, 37, 46, 47, 48, - 51, 54, 55 + -1, 1, 4, 5, 6, 7, 17, 9, 14, 21, + 22, 19, 46, 26, 30, 31, 38, 47, 48, 49, + 52, 55, 56 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -44 +#define YYPACT_NINF -45 static const yytype_int8 yypact[] = { - -44, 9, -44, 8, -44, -44, -44, -44, -44, 3, - -44, -44, 6, -44, 15, -44, 5, 19, 11, -44, - 13, -44, -44, -44, 19, 7, -44, -44, -4, 12, - 16, -44, -44, -44, -44, -44, 33, -3, -44, 7, - 14, -44, -44, -44, -44, -44, -44, -44, -44, -44, - 18, 27, -3, -44, 17, 20, -44, 27, -44, -44 + -45, 9, -45, 19, -45, -45, -45, -45, -45, -2, + -45, -45, -45, 25, -45, 27, -45, 15, 30, 11, + -45, 13, -45, -45, -45, 30, 20, -45, -45, -4, + 12, 16, -45, -45, -45, -45, -45, 34, -3, -45, + 20, 14, -45, -45, -45, -45, -45, -45, -45, -45, + -45, 8, 24, -3, -45, 17, 18, -45, 24, -45, + -45 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, - 21, -44, 22, -44, 2, -44, -8, -43, -9, -44, - -44, -44, -13 + -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, + 22, -45, 23, -45, 1, -45, -8, -44, -9, -45, + -45, -45, -13 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If @@ -649,38 +655,39 @@ static const yytype_int8 yypgoto[] = #define YYTABLE_NINF -1 static const yytype_uint8 yytable[] = { - 41, 42, 43, 31, 32, 33, 34, 35, 53, 2, - 27, 8, 14, 28, 53, 10, 11, 12, 15, 22, - 36, 17, 19, 44, 3, 31, 32, 33, 34, 35, - 41, 42, 43, 22, 24, 38, 40, 39, 57, 50, - 23, 49, 52, 56, 59, 26, 0, 58 + 42, 43, 44, 32, 33, 34, 35, 36, 54, 2, + 10, 11, 12, 13, 54, 32, 33, 34, 35, 36, + 23, 37, 8, 28, 45, 3, 29, 42, 43, 44, + 16, 15, 18, 20, 23, 25, 39, 41, 40, 58, + 51, 50, 24, 53, 57, 60, 59, 27 }; #define yypact_value_is_default(yystate) \ - ((yystate) == (-44)) + ((yystate) == (-45)) #define yytable_value_is_error(yytable_value) \ YYID (0) -static const yytype_int8 yycheck[] = +static const yytype_uint8 yycheck[] = { - 3, 4, 5, 7, 8, 9, 10, 11, 51, 0, - 3, 3, 6, 6, 57, 12, 13, 14, 3, 22, - 24, 16, 3, 26, 15, 7, 8, 9, 10, 11, - 3, 4, 5, 22, 21, 23, 3, 21, 21, 25, - 18, 39, 50, 52, 57, 24, -1, 27 + 3, 4, 5, 7, 8, 9, 10, 11, 52, 0, + 12, 13, 14, 15, 58, 7, 8, 9, 10, 11, + 23, 25, 3, 3, 27, 16, 6, 3, 4, 5, + 3, 6, 17, 3, 23, 22, 24, 3, 22, 22, + 26, 40, 19, 51, 53, 58, 28, 25 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 29, 0, 15, 30, 31, 32, 33, 3, 35, - 12, 13, 14, 36, 6, 3, 34, 16, 39, 3, - 37, 38, 22, 40, 21, 41, 38, 3, 6, 42, - 43, 7, 8, 9, 10, 11, 24, 44, 23, 21, - 3, 3, 4, 5, 26, 40, 45, 46, 47, 42, - 25, 48, 44, 45, 49, 50, 46, 21, 27, 50 + 0, 30, 0, 16, 31, 32, 33, 34, 3, 36, + 12, 13, 14, 15, 37, 6, 3, 35, 17, 40, + 3, 38, 39, 23, 41, 22, 42, 39, 3, 6, + 43, 44, 7, 8, 9, 10, 11, 25, 45, 24, + 22, 3, 3, 4, 5, 27, 41, 46, 47, 48, + 43, 26, 49, 45, 46, 50, 51, 47, 22, 28, + 51 }; #define yyerrok (yyerrstatus = 0) @@ -1566,7 +1573,7 @@ yyreduce: case 7: /* Line 1806 of yacc.c */ -#line 115 "config_parser.yy" +#line 117 "config_parser.yy" { m_Abstract = false; m_Local = false; @@ -1576,7 +1583,7 @@ yyreduce: case 8: /* Line 1806 of yacc.c */ -#line 120 "config_parser.yy" +#line 122 "config_parser.yy" { m_Object = boost::make_shared((yyvsp[(4) - (5)].text), (yyvsp[(5) - (5)].text), yylloc); free((yyvsp[(4) - (5)].text)); @@ -1587,7 +1594,7 @@ yyreduce: case 9: /* Line 1806 of yacc.c */ -#line 126 "config_parser.yy" +#line 128 "config_parser.yy" { Object::Ptr exprl_object = *(yyvsp[(8) - (8)].variant); delete (yyvsp[(8) - (8)].variant); @@ -1602,6 +1609,9 @@ yyreduce: Expression abstractexpr("__abstract", OperatorSet, m_Abstract ? 1 : 0, yylloc); exprl->AddExpression(abstractexpr); + Expression tempexpr("__temporary", OperatorSet, m_Temporary ? 1 : 0, yylloc); + exprl->AddExpression(tempexpr); + Expression localexpr("__local", OperatorSet, m_Local ? 1 : 0, yylloc); exprl->AddExpression(localexpr); @@ -1615,7 +1625,7 @@ yyreduce: case 12: /* Line 1806 of yacc.c */ -#line 155 "config_parser.yy" +#line 160 "config_parser.yy" { m_Abstract = true; } @@ -1624,45 +1634,54 @@ yyreduce: case 13: /* Line 1806 of yacc.c */ -#line 159 "config_parser.yy" +#line 164 "config_parser.yy" + { + m_Temporary = true; + } + break; + + case 14: + +/* Line 1806 of yacc.c */ +#line 168 "config_parser.yy" { m_Local = true; } break; - case 16: + case 17: /* Line 1806 of yacc.c */ -#line 169 "config_parser.yy" +#line 178 "config_parser.yy" { m_Object->AddParent((yyvsp[(1) - (1)].text)); free((yyvsp[(1) - (1)].text)); } break; - case 19: + case 20: /* Line 1806 of yacc.c */ -#line 180 "config_parser.yy" +#line 189 "config_parser.yy" { m_ExpressionLists.push(boost::make_shared()); } break; - case 20: + case 21: /* Line 1806 of yacc.c */ -#line 185 "config_parser.yy" +#line 194 "config_parser.yy" { (yyval.variant) = new Variant(m_ExpressionLists.top()); m_ExpressionLists.pop(); } break; - case 24: + case 25: /* Line 1806 of yacc.c */ -#line 197 "config_parser.yy" +#line 206 "config_parser.yy" { Expression expr((yyvsp[(1) - (3)].text), (yyvsp[(2) - (3)].op), *(yyvsp[(3) - (3)].variant), yylloc); free((yyvsp[(1) - (3)].text)); @@ -1672,10 +1691,10 @@ yyreduce: } break; - case 25: + case 26: /* Line 1806 of yacc.c */ -#line 205 "config_parser.yy" +#line 214 "config_parser.yy" { Expression subexpr((yyvsp[(3) - (6)].text), (yyvsp[(5) - (6)].op), *(yyvsp[(6) - (6)].variant), yylloc); free((yyvsp[(3) - (6)].text)); @@ -1691,10 +1710,10 @@ yyreduce: } break; - case 26: + case 27: /* Line 1806 of yacc.c */ -#line 219 "config_parser.yy" +#line 228 "config_parser.yy" { Expression expr((yyvsp[(1) - (1)].text), OperatorSet, (yyvsp[(1) - (1)].text), yylloc); free((yyvsp[(1) - (1)].text)); @@ -1703,75 +1722,75 @@ yyreduce: } break; - case 31: + case 32: /* Line 1806 of yacc.c */ -#line 232 "config_parser.yy" +#line 241 "config_parser.yy" { (yyval.op) = (yyvsp[(1) - (1)].op); } break; - case 32: + case 33: /* Line 1806 of yacc.c */ -#line 238 "config_parser.yy" +#line 247 "config_parser.yy" { (yyval.variant) = new Variant((yyvsp[(1) - (1)].text)); free((yyvsp[(1) - (1)].text)); } break; - case 33: + case 34: /* Line 1806 of yacc.c */ -#line 243 "config_parser.yy" +#line 252 "config_parser.yy" { (yyval.variant) = new Variant((yyvsp[(1) - (1)].num)); } break; - case 34: + case 35: /* Line 1806 of yacc.c */ -#line 247 "config_parser.yy" +#line 256 "config_parser.yy" { (yyval.variant) = new Variant(); } break; - case 37: + case 38: /* Line 1806 of yacc.c */ -#line 255 "config_parser.yy" +#line 264 "config_parser.yy" { (yyval.variant) = (yyvsp[(1) - (1)].variant); } break; - case 38: + case 39: /* Line 1806 of yacc.c */ -#line 261 "config_parser.yy" +#line 270 "config_parser.yy" { m_Array = boost::make_shared(); } break; - case 39: + case 40: /* Line 1806 of yacc.c */ -#line 266 "config_parser.yy" +#line 275 "config_parser.yy" { (yyval.variant) = new Variant(m_Array); m_Array.reset(); } break; - case 40: + case 41: /* Line 1806 of yacc.c */ -#line 273 "config_parser.yy" +#line 282 "config_parser.yy" { m_Array->AddUnnamedProperty(*(yyvsp[(1) - (1)].variant)); delete (yyvsp[(1) - (1)].variant); @@ -1781,7 +1800,7 @@ yyreduce: /* Line 1806 of yacc.c */ -#line 1785 "config_parser.cc" +#line 1804 "config_parser.cc" default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -2019,6 +2038,6 @@ yyreturn: /* Line 2067 of yacc.c */ -#line 283 "config_parser.yy" +#line 292 "config_parser.yy" diff --git a/dyn/config_parser.h b/dyn/config_parser.h index 3eb48bf15..4ac314b8c 100644 --- a/dyn/config_parser.h +++ b/dyn/config_parser.h @@ -82,10 +82,11 @@ using namespace icinga; T_MULTIPLY_EQUAL = 265, T_DIVIDE_EQUAL = 266, T_ABSTRACT = 267, - T_LOCAL = 268, - T_OBJECT = 269, - T_INCLUDE = 270, - T_INHERITS = 271 + T_TEMPORARY = 268, + T_LOCAL = 269, + T_OBJECT = 270, + T_INCLUDE = 271, + T_INHERITS = 272 }; #endif /* Tokens. */ @@ -99,10 +100,11 @@ using namespace icinga; #define T_MULTIPLY_EQUAL 265 #define T_DIVIDE_EQUAL 266 #define T_ABSTRACT 267 -#define T_LOCAL 268 -#define T_OBJECT 269 -#define T_INCLUDE 270 -#define T_INHERITS 271 +#define T_TEMPORARY 268 +#define T_LOCAL 269 +#define T_OBJECT 270 +#define T_INCLUDE 271 +#define T_INHERITS 272 @@ -122,7 +124,7 @@ typedef union YYSTYPE /* Line 2068 of yacc.c */ -#line 126 "config_parser.h" +#line 128 "config_parser.h" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ diff --git a/dyn/config_parser.yy b/dyn/config_parser.yy index 58fd273a8..de041a8d6 100644 --- a/dyn/config_parser.yy +++ b/dyn/config_parser.yy @@ -52,6 +52,7 @@ using namespace icinga; %token T_MULTIPLY_EQUAL %token T_DIVIDE_EQUAL %token T_ABSTRACT +%token T_TEMPORARY %token T_LOCAL %token T_OBJECT %token T_INCLUDE @@ -85,6 +86,7 @@ static stack m_ExpressionLists; static vector m_Objects; static ConfigItem::Ptr m_Object; static bool m_Abstract; +static bool m_Temporary; static bool m_Local; static Dictionary::Ptr m_Array; @@ -137,6 +139,9 @@ inherits_specifier expressionlist Expression abstractexpr("__abstract", OperatorSet, m_Abstract ? 1 : 0, yylloc); exprl->AddExpression(abstractexpr); + Expression tempexpr("__temporary", OperatorSet, m_Temporary ? 1 : 0, yylloc); + exprl->AddExpression(tempexpr); + Expression localexpr("__local", OperatorSet, m_Local ? 1 : 0, yylloc); exprl->AddExpression(localexpr); @@ -155,6 +160,10 @@ attribute: T_ABSTRACT { m_Abstract = true; } + | T_TEMPORARY + { + m_Temporary = true; + } | T_LOCAL { m_Local = true; diff --git a/dyn/configitem.cpp b/dyn/configitem.cpp index 96ab331f2..5d45e73ca 100644 --- a/dyn/configitem.cpp +++ b/dyn/configitem.cpp @@ -138,7 +138,10 @@ void ConfigItem::Commit(void) void ConfigItem::Unregister(void) { - // TODO: unregister associated ConfigObject + ConfigObject::Ptr dobj = m_ConfigObject.lock(); + + if (dobj) + dobj->Unregister(); GetAllObjects()->RemoveObject(GetSelf()); } diff --git a/icinga-app/Makefile.am b/icinga-app/Makefile.am index 78b5fd112..e6f97438b 100644 --- a/icinga-app/Makefile.am +++ b/icinga-app/Makefile.am @@ -22,6 +22,7 @@ icinga_LDADD = \ ${top_builddir}/base/libbase.la \ ${top_builddir}/icinga/libicinga.la \ -dlopen ${top_builddir}/components/checker/checker.la \ + -dlopen ${top_builddir}/components/compat/compat.la \ -dlopen ${top_builddir}/components/configfile/configfile.la \ -dlopen ${top_builddir}/components/configrpc/configrpc.la \ -dlopen ${top_builddir}/components/delegation/delegation.la \ diff --git a/icinga/Makefile.am b/icinga/Makefile.am index 3e10318ed..aaade88d0 100644 --- a/icinga/Makefile.am +++ b/icinga/Makefile.am @@ -9,6 +9,8 @@ libicinga_la_SOURCES = \ checkresult.h \ checktask.cpp \ checktask.h \ + cib.cpp \ + cib.h \ configobjectadapter.cpp \ configobjectadapter.h \ endpoint.cpp \ @@ -17,8 +19,6 @@ libicinga_la_SOURCES = \ endpointmanager.h \ icingaapplication.cpp \ icingaapplication.h \ - icingacomponent.cpp \ - icingacomponent.h \ host.cpp \ host.h \ i2-icinga.h \ diff --git a/icinga/cib.cpp b/icinga/cib.cpp new file mode 100644 index 000000000..52fb845c2 --- /dev/null +++ b/icinga/cib.cpp @@ -0,0 +1,67 @@ +#include "i2-icinga.h" + +using namespace icinga; + +int CIB::m_Types; +VirtualEndpoint::Ptr CIB::m_Endpoint; + +void CIB::RequireInformation(InformationType types) +{ + m_Types |= types; +} + +void CIB::Start(void) +{ + m_Endpoint = boost::make_shared(); + if (m_Types & CIB_ServiceStatus) { + m_Endpoint->RegisterTopicHandler("delegation::ServiceStatus", + boost::bind(&CIB::ServiceStatusRequestHandler, _2, _3)); + } + EndpointManager::GetInstance()->RegisterEndpoint(m_Endpoint); +} + +void CIB::ServiceStatusRequestHandler(const Endpoint::Ptr& sender, const RequestMessage& request) +{ + MessagePart params; + if (!request.GetParams(¶ms)) + return; + + string svcname; + if (!params.GetProperty("service", &svcname)) + return; + + Service service = Service::GetByName(svcname); + + long nextCheck; + if (params.GetProperty("next_check", &nextCheck)) + service.SetNextCheck(nextCheck); + + long state, stateType; + if (params.GetProperty("state", &state) && params.GetProperty("state_type", &stateType)) { + long old_state, old_stateType; + old_state = service.GetState(); + old_stateType = service.GetStateType(); + + if (state != old_state) { + time_t now; + time(&now); + + service.SetLastStateChange(now); + + if (old_stateType != stateType) + service.SetLastHardStateChange(now); + } + + service.SetState(static_cast(state)); + service.SetStateType(static_cast(stateType)); + } + + long attempt; + if (params.GetProperty("current_attempt", &attempt)) + service.SetCurrentCheckAttempt(attempt); + + Dictionary::Ptr cr; + if (params.GetProperty("result", &cr)) + service.SetLastCheckResult(cr); +} + diff --git a/icinga/cib.h b/icinga/cib.h new file mode 100644 index 000000000..ab8389ac7 --- /dev/null +++ b/icinga/cib.h @@ -0,0 +1,30 @@ +#ifndef CIB_H +#define CIB_H + +namespace icinga +{ + +enum InformationType +{ + CIB_Configuration = 1<<0, + CIB_ProgramStatus = 1<<1, + CIB_ServiceStatus = 1<<2 +}; + +class CIB +{ +public: + static void RequireInformation(InformationType type); + + static void Start(void); + +private: + static int m_Types; + static VirtualEndpoint::Ptr m_Endpoint; + + static void ServiceStatusRequestHandler(const Endpoint::Ptr& sender, const RequestMessage& request); +}; + +} + +#endif /* CIB_H */ diff --git a/icinga/endpointmanager.cpp b/icinga/endpointmanager.cpp index 84cb4463c..04f1face1 100644 --- a/icinga/endpointmanager.cpp +++ b/icinga/endpointmanager.cpp @@ -379,3 +379,12 @@ EndpointManager::Iterator EndpointManager::End(void) return m_Endpoints.end(); } +EndpointManager::Ptr EndpointManager::GetInstance(void) +{ + static EndpointManager::Ptr instance; + + if (!instance) + instance = boost::make_shared(); + + return instance; +} diff --git a/icinga/endpointmanager.h b/icinga/endpointmanager.h index 82363cbec..7a89c660d 100644 --- a/icinga/endpointmanager.h +++ b/icinga/endpointmanager.h @@ -38,6 +38,8 @@ public: EndpointManager(void); + static EndpointManager::Ptr GetInstance(void); + void SetIdentity(string identity); string GetIdentity(void) const; diff --git a/icinga/i2-icinga.h b/icinga/i2-icinga.h index 635d7fb43..690d40e72 100644 --- a/icinga/i2-icinga.h +++ b/icinga/i2-icinga.h @@ -46,12 +46,13 @@ using boost::unique_future; #include "virtualendpoint.h" #include "endpointmanager.h" #include "icingaapplication.h" -#include "icingacomponent.h" #include "configobjectadapter.h" #include "host.h" #include "service.h" +#include "cib.h" + #include "macroprocessor.h" #include "checkresult.h" #include "checktask.h" diff --git a/icinga/icingaapplication.cpp b/icinga/icingaapplication.cpp index b2f8b5575..e200eacd3 100644 --- a/icinga/icingaapplication.cpp +++ b/icinga/icingaapplication.cpp @@ -49,8 +49,6 @@ int IcingaApplication::Main(const vector& args) return EXIT_FAILURE; } - m_EndpointManager = boost::make_shared(); - string componentDirectory = GetExeDirectory() + "/../lib/icinga2"; AddComponentSearchDir(componentDirectory); @@ -85,32 +83,25 @@ int IcingaApplication::Main(const vector& args) shared_ptr cert = Utility::GetX509Certificate(GetCertificateFile()); string identity = Utility::GetCertificateCN(cert); Application::Log(LogInformation, "icinga", "My identity: " + identity); - m_EndpointManager->SetIdentity(identity); + EndpointManager::GetInstance()->SetIdentity(identity); shared_ptr sslContext = Utility::MakeSSLContext(GetCertificateFile(), GetCertificateFile(), GetCAFile()); - m_EndpointManager->SetSSLContext(sslContext); + EndpointManager::GetInstance()->SetSSLContext(sslContext); } /* create the primary RPC listener */ string service = GetService(); if (!service.empty()) - GetEndpointManager()->AddListener(service); + EndpointManager::GetInstance()->AddListener(service); + + CIB::RequireInformation(CIB_ServiceStatus); + CIB::Start(); RunEventLoop(); return EXIT_SUCCESS; } -/** - * Retrieves Icinga's endpoint manager. - * - * @returns The endpoint manager. - */ -EndpointManager::Ptr IcingaApplication::GetEndpointManager(void) -{ - return m_EndpointManager; -} - void IcingaApplication::NewComponentHandler(const ConfigObject::Ptr& object) { /* don't allow replicated config objects */ @@ -129,6 +120,11 @@ void IcingaApplication::NewComponentHandler(const ConfigObject::Ptr& object) LoadComponent(path, object); } +IcingaApplication::Ptr IcingaApplication::GetInstance(void) +{ + return static_pointer_cast(Application::GetInstance()); +} + void IcingaApplication::DeletedComponentHandler(const ConfigObject::Ptr& object) { Component::Ptr component = GetComponent(object->GetName()); diff --git a/icinga/icingaapplication.h b/icinga/icingaapplication.h index 438a1866c..ac0717408 100644 --- a/icinga/icingaapplication.h +++ b/icinga/icingaapplication.h @@ -36,7 +36,7 @@ public: int Main(const vector& args); - EndpointManager::Ptr GetEndpointManager(void); + static IcingaApplication::Ptr GetInstance(void); string GetCertificateFile(void) const; string GetCAFile(void) const; @@ -44,8 +44,6 @@ public: string GetService(void) const; private: - EndpointManager::Ptr m_EndpointManager; - string m_CertificateFile; string m_CAFile; string m_Node; diff --git a/icinga/service.cpp b/icinga/service.cpp index 9df1c581e..6f64ddd5f 100644 --- a/icinga/service.cpp +++ b/icinga/service.cpp @@ -12,6 +12,16 @@ string Service::GetDisplayName(void) const return GetName(); } +Service Service::GetByName(string name) +{ + ConfigObject::Ptr configObject = ConfigObject::GetObject("service", name); + + if (!configObject) + throw invalid_argument("Service '" + name + "' does not exist."); + + return configObject; +} + Host Service::GetHost(void) const { string hostname; @@ -62,8 +72,17 @@ long Service::GetCheckInterval(void) const long Service::GetRetryInterval(void) const { - long value = 60; - GetConfigObject()->GetProperty("retry_interval", &value); + long value; + if (!GetConfigObject()->GetProperty("retry_interval", &value)) + value = GetCheckInterval() / 5; + + return value; +} + +Dictionary::Ptr Service::GetDependencies(void) const +{ + Dictionary::Ptr value; + GetConfigObject()->GetProperty("dependencies", &value); return value; } @@ -74,15 +93,25 @@ void Service::SetNextCheck(time_t nextCheck) time_t Service::GetNextCheck(void) { - long value = -1; - GetConfigObject()->GetTag("next_check", &value); - if (value == -1) { + long value; + if (!GetConfigObject()->GetTag("next_check", &value)) { value = time(NULL) + rand() % GetCheckInterval(); SetNextCheck(value); } return value; } +void Service::UpdateNextCheck(void) +{ + time_t now; + time(&now); + + if (GetStateType() == StateTypeSoft) + SetNextCheck(now + GetRetryInterval()); + else + SetNextCheck(now + GetCheckInterval()); +} + void Service::SetChecker(string checker) { GetConfigObject()->SetTag("checker", checker); @@ -131,6 +160,42 @@ ServiceStateType Service::GetStateType(void) const return static_cast(value); } +void Service::SetLastCheckResult(const Dictionary::Ptr& result) +{ + GetConfigObject()->SetTag("last_result", result); +} + +Dictionary::Ptr Service::GetLastCheckResult(void) const +{ + Dictionary::Ptr value; + GetConfigObject()->GetTag("last_result", &value); + return value; +} + +void Service::SetLastStateChange(time_t ts) +{ + GetConfigObject()->SetTag("last_state_change", ts); +} + +time_t Service::GetLastStateChange(void) const +{ + long value = 0; + GetConfigObject()->GetTag("last_state_change", &value); + return value; +} + +void Service::SetLastHardStateChange(time_t ts) +{ + GetConfigObject()->SetTag("last_hard_state_change", ts); +} + +time_t Service::GetLastHardStateChange(void) const +{ + long value = 0; + GetConfigObject()->GetTag("last_hard_state_change", &value); + return value; +} + void Service::ApplyCheckResult(const CheckResult& cr) { long attempt = GetCurrentCheckAttempt(); @@ -154,3 +219,66 @@ void Service::ApplyCheckResult(const CheckResult& cr) SetState(cr.GetState()); } +ServiceState Service::StateFromString(string state) +{ + /* TODO: make this thread-safe */ + static map stateLookup; + + if (stateLookup.empty()) { + stateLookup["ok"] = StateOK; + stateLookup["warning"] = StateWarning; + stateLookup["critical"] = StateCritical; + stateLookup["unreachable"] = StateUnreachable; + stateLookup["uncheckable"] = StateUncheckable; + stateLookup["unknown"] = StateUnknown; + } + + map::iterator it; + it = stateLookup.find(state); + + if (it == stateLookup.end()) + return StateUnknown; + else + return it->second; +} + +string Service::StateToString(ServiceState state) +{ + switch (state) { + case StateOK: + return "ok"; + case StateWarning: + return "warning"; + case StateCritical: + return "critical"; + case StateUnreachable: + return "unreachable"; + case StateUncheckable: + return "uncheckable"; + case StateUnknown: + default: + return "unknown"; + } +} + +ServiceStateType Service::StateTypeFromString(string type) +{ + if (type == "soft") + return StateTypeSoft; + else + return StateTypeHard; +} + +string Service::StateTypeToString(ServiceStateType type) +{ + if (type == StateTypeSoft) + return "soft"; + else + return "hard"; +} + +bool Service::IsAllowedChecker(string checker) const +{ + /* TODO: check config */ + return true; +} diff --git a/icinga/service.h b/icinga/service.h index 5cf13e862..511aaa8b6 100644 --- a/icinga/service.h +++ b/icinga/service.h @@ -9,15 +9,15 @@ enum ServiceState StateOK, StateWarning, StateCritical, + StateUnknown, StateUnreachable, StateUncheckable, - StateUnknown }; enum ServiceStateType { - StateTypeHard, - StateTypeSoft + StateTypeSoft, + StateTypeHard }; struct CheckResult; @@ -29,6 +29,8 @@ public: : ConfigObjectAdapter(configObject) { } + static Service GetByName(string name); + string GetDisplayName(void) const; Host GetHost(void) const; Dictionary::Ptr GetMacros(void) const; @@ -37,13 +39,17 @@ public: long GetMaxCheckAttempts(void) const; long GetCheckInterval(void) const; long GetRetryInterval(void) const; + Dictionary::Ptr GetDependencies(void) const; void SetNextCheck(time_t nextCheck); time_t GetNextCheck(void); + void UpdateNextCheck(void); void SetChecker(string checker); string GetChecker(void) const; + bool IsAllowedChecker(string checker) const; + void SetCurrentCheckAttempt(long attempt); long GetCurrentCheckAttempt(void) const; @@ -53,7 +59,22 @@ public: void SetStateType(ServiceStateType type); ServiceStateType GetStateType(void) const; + void SetLastCheckResult(const Dictionary::Ptr& result); + Dictionary::Ptr GetLastCheckResult(void) const; + + void SetLastStateChange(time_t ts); + time_t GetLastStateChange(void) const; + + void SetLastHardStateChange(time_t ts); + time_t GetLastHardStateChange(void) const; + void ApplyCheckResult(const CheckResult& cr); + + static ServiceState StateFromString(string state); + static string StateToString(ServiceState state); + + static ServiceStateType StateTypeFromString(string state); + static string StateTypeToString(ServiceStateType state); }; } -- 2.40.0