Merge branch 'feature/db-endpoints-5636' into next

Fixes #5636
Fixes #5690
Fixes #5810
Fixes #5811
Fixes #5812
This commit is contained in:
Michael Friedrich 2014-03-20 19:34:05 +01:00
commit fee925720d
37 changed files with 693 additions and 50 deletions

View File

@ -16,16 +16,15 @@
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
mkclass_target(clusterlistener.ti clusterlistener.th)
mkclass_target(endpoint.ti endpoint.th)
mkembedconfig_target(cluster-type.conf cluster-type.cpp)
add_library(cluster SHARED
clusterchecktask.cpp clusterlistener.cpp clusterlistener.th
endpoint.cpp endpoint.th jsonrpc.cpp cluster-type.cpp
cluster-type.cpp
)
target_link_libraries(cluster ${Boost_LIBRARIES} base config icinga)
target_link_libraries(cluster ${Boost_LIBRARIES} base config icinga remote)
set_target_properties (
cluster PROPERTIES

View File

@ -36,27 +36,3 @@ type ClusterListener {
%attribute name(Endpoint) "*"
}
}
type Endpoint {
%require "host",
%attribute string "host",
%require "port",
%attribute string "port",
%attribute array "config_files" {
%attribute string "*"
},
%attribute array "config_files_recursive" {
%attribute string "*",
%attribute dictionary "*" {
%attribute string "path",
%attribute string "pattern"
}
},
%attribute array "accept_config" {
%attribute name(Endpoint) "*"
}
}

View File

@ -18,8 +18,8 @@
******************************************************************************/
#include "cluster/clusterchecktask.h"
#include "cluster/endpoint.h"
#include "cluster/clusterlistener.h"
#include "remote/endpoint.h"
#include "icinga/cib.h"
#include "icinga/service.h"
#include "icinga/icingaapplication.h"

View File

@ -18,7 +18,7 @@
******************************************************************************/
#include "cluster/clusterlistener.h"
#include "cluster/endpoint.h"
#include "remote/endpoint.h"
#include "icinga/cib.h"
#include "icinga/domain.h"
#include "icinga/icingaapplication.h"

View File

@ -31,7 +31,7 @@
#include "base/stdiostream.h"
#include "base/workqueue.h"
#include "icinga/service.h"
#include "cluster/endpoint.h"
#include "remote/endpoint.h"
namespace icinga
{

View File

@ -1376,6 +1376,12 @@ CREATE TABLE IF NOT EXISTS icinga_endpointstatus (
ALTER TABLE icinga_servicestatus ADD COLUMN endpoint_object_id bigint default NULL;
ALTER TABLE icinga_hoststatus ADD COLUMN endpoint_object_id bigint default NULL;
ALTER TABLE icinga_contactstatus ADD COLUMN endpoint_object_id bigint default NULL;
ALTER TABLE icinga_programstatus ADD COLUMN endpoint_object_id bigint default NULL;
ALTER TABLE icinga_comments ADD COLUMN endpoint_object_id bigint default NULL;
ALTER TABLE icinga_scheduleddowntime ADD COLUMN endpoint_object_id bigint default NULL;
ALTER TABLE icinga_runtimevariables ADD COLUMN endpoint_object_id bigint default NULL;
ALTER TABLE icinga_customvariablestatus ADD COLUMN endpoint_object_id bigint default NULL;
ALTER TABLE icinga_acknowledgements ADD COLUMN endpoint_object_id bigint default NULL;
ALTER TABLE icinga_commenthistory ADD COLUMN endpoint_object_id bigint default NULL;
@ -1392,6 +1398,10 @@ ALTER TABLE icinga_servicechecks ADD COLUMN endpoint_object_id bigint default NU
ALTER TABLE icinga_statehistory ADD COLUMN endpoint_object_id bigint default NULL;
ALTER TABLE icinga_systemcommands ADD COLUMN endpoint_object_id bigint default NULL;
ALTER TABLE icinga_servicestatus ADD COLUMN check_source_object_id bigint default NULL;
ALTER TABLE icinga_hoststatus ADD COLUMN check_source_object_id bigint default NULL;
ALTER TABLE icinga_statehistory ADD COLUMN check_source_object_id bigint default NULL;
-- -----------------------------------------
-- add index (delete)

View File

@ -0,0 +1,4 @@
ALTER TABLE icinga_servicestatus ADD COLUMN check_source_object_id bigint default NULL;
ALTER TABLE icinga_hoststatus ADD COLUMN check_source_object_id bigint default NULL;
ALTER TABLE icinga_statehistory ADD COLUMN check_source_object_id bigint default NULL;

View File

@ -1404,6 +1404,12 @@ CREATE TABLE IF NOT EXISTS icinga_endpointstatus (
ALTER TABLE icinga_servicestatus ADD COLUMN endpoint_object_id bigint default NULL;
ALTER TABLE icinga_hoststatus ADD COLUMN endpoint_object_id bigint default NULL;
ALTER TABLE icinga_contactstatus ADD COLUMN endpoint_object_id bigint default NULL;
ALTER TABLE icinga_programstatus ADD COLUMN endpoint_object_id bigint default NULL;
ALTER TABLE icinga_comments ADD COLUMN endpoint_object_id bigint default NULL;
ALTER TABLE icinga_scheduleddowntime ADD COLUMN endpoint_object_id bigint default NULL;
ALTER TABLE icinga_runtimevariables ADD COLUMN endpoint_object_id bigint default NULL;
ALTER TABLE icinga_customvariablestatus ADD COLUMN endpoint_object_id bigint default NULL;
ALTER TABLE icinga_acknowledgements ADD COLUMN endpoint_object_id bigint default NULL;
ALTER TABLE icinga_commenthistory ADD COLUMN endpoint_object_id bigint default NULL;
@ -1420,6 +1426,9 @@ ALTER TABLE icinga_servicechecks ADD COLUMN endpoint_object_id bigint default NU
ALTER TABLE icinga_statehistory ADD COLUMN endpoint_object_id bigint default NULL;
ALTER TABLE icinga_systemcommands ADD COLUMN endpoint_object_id bigint default NULL;
ALTER TABLE icinga_servicestatus ADD COLUMN check_source_object_id bigint default NULL;
ALTER TABLE icinga_hoststatus ADD COLUMN check_source_object_id bigint default NULL;
ALTER TABLE icinga_statehistory ADD COLUMN check_source_object_id bigint default NULL;
-- -----------------------------------------
-- add index (delete)

View File

@ -0,0 +1,5 @@
ALTER TABLE icinga_servicestatus ADD COLUMN check_source_object_id bigint default NULL;
ALTER TABLE icinga_hoststatus ADD COLUMN check_source_object_id bigint default NULL;
ALTER TABLE icinga_statehistory ADD COLUMN check_source_object_id bigint default NULL;

View File

@ -19,9 +19,18 @@ mkclass_target(listener.ti listener.th)
mkembedconfig_target(livestatus-type.conf livestatus-type.cpp)
add_library(livestatus SHARED aggregator.cpp andfilter.cpp attributefilter.cpp avgaggregator.cpp column.cpp combinerfilter.cpp commandstable.cpp commentstable.cpp contactgroupstable.cpp contactstable.cpp countaggregator.cpp downtimestable.cpp filter.cpp historytable.cpp hostgroupstable.cpp hoststable.cpp invavgaggregator.cpp invsumaggregator.cpp listener.cpp listener.th logutility.cpp logtable.cpp maxaggregator.cpp minaggregator.cpp negatefilter.cpp orfilter.cpp query.cpp servicegroupstable.cpp servicestable.cpp statehisttable.cpp statustable.cpp stdaggregator.cpp sumaggregator.cpp table.cpp timeperiodstable.cpp livestatus-type.cpp)
add_library(livestatus SHARED aggregator.cpp andfilter.cpp attributefilter.cpp
avgaggregator.cpp column.cpp combinerfilter.cpp commandstable.cpp
commentstable.cpp contactgroupstable.cpp contactstable.cpp countaggregator.cpp
downtimestable.cpp endpointstable.cpp filter.cpp historytable.cpp
hostgroupstable.cpp hoststable.cpp invavgaggregator.cpp invsumaggregator.cpp
listener.cpp listener.th logutility.cpp logtable.cpp maxaggregator.cpp
minaggregator.cpp negatefilter.cpp orfilter.cpp query.cpp
servicegroupstable.cpp servicestable.cpp statehisttable.cpp
statustable.cpp stdaggregator.cpp sumaggregator.cpp table.cpp
timeperiodstable.cpp livestatus-type.cpp)
target_link_libraries(livestatus ${Boost_LIBRARIES} base config icinga)
target_link_libraries(livestatus ${Boost_LIBRARIES} base config icinga remote)
set_target_properties (
livestatus PROPERTIES

View File

@ -0,0 +1,110 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2014 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 "livestatus/endpointstable.h"
#include "icinga/host.h"
#include "icinga/service.h"
#include "icinga/icingaapplication.h"
#include "remote/endpoint.h"
#include "base/dynamictype.h"
#include "base/objectlock.h"
#include "base/convert.h"
#include "base/utility.h"
#include <boost/algorithm/string/classification.hpp>
#include <boost/foreach.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/split.hpp>
using namespace icinga;
EndpointsTable::EndpointsTable(void)
{
AddColumns(this);
}
void EndpointsTable::AddColumns(Table *table, const String& prefix,
const Column::ObjectAccessor& objectAccessor)
{
table->AddColumn(prefix + "name", Column(&EndpointsTable::NameAccessor, objectAccessor));
table->AddColumn(prefix + "identity", Column(&EndpointsTable::IdentityAccessor, objectAccessor));
table->AddColumn(prefix + "node", Column(&EndpointsTable::NodeAccessor, objectAccessor));
table->AddColumn(prefix + "is_connected", Column(&EndpointsTable::IsConnectedAccessor, objectAccessor));
}
String EndpointsTable::GetName(void) const
{
return "endpoints";
}
void EndpointsTable::FetchRows(const AddRowFunction& addRowFn)
{
BOOST_FOREACH(const Endpoint::Ptr& endpoint, DynamicType::GetObjects<Endpoint>()) {
addRowFn(endpoint);
}
}
Value EndpointsTable::NameAccessor(const Value& row)
{
Endpoint::Ptr endpoint = static_cast<Endpoint::Ptr>(row);
if (!endpoint)
return Empty;
return endpoint->GetName();
}
Value EndpointsTable::IdentityAccessor(const Value& row)
{
Endpoint::Ptr endpoint = static_cast<Endpoint::Ptr>(row);
if (!endpoint)
return Empty;
return endpoint->GetName();
}
Value EndpointsTable::NodeAccessor(const Value& row)
{
Endpoint::Ptr endpoint = static_cast<Endpoint::Ptr>(row);
if (!endpoint)
return Empty;
return IcingaApplication::GetInstance()->GetNodeName();
}
Value EndpointsTable::IsConnectedAccessor(const Value& row)
{
Endpoint::Ptr endpoint = static_cast<Endpoint::Ptr>(row);
if (!endpoint)
return Empty;
unsigned int is_connected = endpoint->IsConnected() ? 1 : 0;
/* if identity is equal to node, fake is_connected */
if (endpoint->GetName() == IcingaApplication::GetInstance()->GetNodeName())
is_connected = 1;
return is_connected;
}

View File

@ -0,0 +1,56 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2014 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 ENDPOINTSTABLE_H
#define ENDPOINTSTABLE_H
#include "livestatus/table.h"
using namespace icinga;
namespace icinga
{
/**
* @ingroup livestatus
*/
class EndpointsTable : public Table
{
public:
DECLARE_PTR_TYPEDEFS(EndpointsTable);
EndpointsTable(void);
static void AddColumns(Table *table, const String& prefix = String(),
const Column::ObjectAccessor& objectAccessor = Column::ObjectAccessor());
virtual String GetName(void) const;
protected:
virtual void FetchRows(const AddRowFunction& addRowFn);
static Value NameAccessor(const Value& row);
static Value IdentityAccessor(const Value& row);
static Value NodeAccessor(const Value& row);
static Value IsConnectedAccessor(const Value& row);
};
}
#endif /* ENDPOINTSTABLE_H */

View File

@ -19,6 +19,7 @@
#include "livestatus/servicestable.h"
#include "livestatus/hoststable.h"
#include "livestatus/endpointstable.h"
#include "icinga/service.h"
#include "icinga/checkcommand.h"
#include "icinga/eventcommand.h"
@ -125,6 +126,7 @@ void ServicesTable::AddColumns(Table *table, const String& prefix,
table->AddColumn(prefix + "custom_variables", Column(&ServicesTable::CustomVariablesAccessor, objectAccessor));
table->AddColumn(prefix + "groups", Column(&ServicesTable::GroupsAccessor, objectAccessor));
table->AddColumn(prefix + "contact_groups", Column(&ServicesTable::ContactGroupsAccessor, objectAccessor));
table->AddColumn(prefix + "check_source", Column(&ServicesTable::CheckSourceAccessor, objectAccessor));
HostsTable::AddColumns(table, "host_", boost::bind(&ServicesTable::HostAccessor, _1, objectAccessor));
}
@ -1158,4 +1160,19 @@ Value ServicesTable::ContactGroupsAccessor(const Value& row)
return contactgroup_names;
}
Value ServicesTable::CheckSourceAccessor(const Value& row)
{
Service::Ptr service = static_cast<Service::Ptr>(row);
if (!service)
return Empty;
CheckResult::Ptr cr = service->GetLastCheckResult();
if (cr)
return cr->GetCheckSource();
return Empty;
}

View File

@ -123,6 +123,7 @@ protected:
static Value CustomVariablesAccessor(const Value& row);
static Value GroupsAccessor(const Value& row);
static Value ContactGroupsAccessor(const Value& row);
static Value CheckSourceAccessor(const Value& row);
};
}

View File

@ -28,6 +28,7 @@
#include "livestatus/commandstable.h"
#include "livestatus/commentstable.h"
#include "livestatus/downtimestable.h"
#include "livestatus/endpointstable.h"
#include "livestatus/timeperiodstable.h"
#include "livestatus/logtable.h"
#include "livestatus/statehisttable.h"
@ -71,6 +72,8 @@ Table::Ptr Table::GetByName(const String& name, const String& compat_log_path, c
return make_shared<LogTable>(compat_log_path, from, until);
else if (name == "statehist")
return make_shared<StateHistTable>(compat_log_path, from, until);
else if (name == "endpoints")
return make_shared<EndpointsTable>();
return Table::Ptr();
}

16
doc/6.12-schemas.md Normal file
View File

@ -0,0 +1,16 @@
### <a id="schemas"></id> Schemas
#### DB IDO
New tables: endpoints, endpointstatus
name, identity, node, is_connected
New columns: endpoint_object_id, check_source_object_id
#### Livestatus
New table: endpoints
name, identity, node, is_connected
New columns: check_source, endpoint

View File

@ -21,3 +21,4 @@ add_subdirectory(icinga)
add_subdirectory(db_ido)
add_subdirectory(methods)
add_subdirectory(hello)
add_subdirectory(remote)

View File

@ -44,7 +44,7 @@ INITIALIZE_ONCE(&DynamicObject::StaticInitialize);
boost::signals2::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnStarted;
boost::signals2::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnStopped;
boost::signals2::signal<void (const DynamicObject::Ptr&)> DynamicObject::OnStateChanged;
boost::signals2::signal<void (const DynamicObject::Ptr&, const String&)> DynamicObject::OnStateChanged;
boost::signals2::signal<void (const DynamicObject::Ptr&, const String&, bool)> DynamicObject::OnAuthorityChanged;
void DynamicObject::StaticInitialize(void)

View File

@ -56,7 +56,7 @@ public:
static boost::signals2::signal<void (const DynamicObject::Ptr&)> OnStarted;
static boost::signals2::signal<void (const DynamicObject::Ptr&)> OnStopped;
static boost::signals2::signal<void (const DynamicObject::Ptr&)> OnStateChanged;
static boost::signals2::signal<void (const DynamicObject::Ptr&, const String&)> OnStateChanged;
static boost::signals2::signal<void (const DynamicObject::Ptr&, const String&, bool)> OnAuthorityChanged;
Value InvokeMethod(const String& method, const std::vector<Value>& arguments);

View File

@ -22,13 +22,13 @@ mkembedconfig_target(db_ido-type.conf db_ido-type.cpp)
add_library(db_ido SHARED
commanddbobject.cpp dbconnection.cpp dbconnection.th dbconnection.th
db_ido-type.cpp dbobject.cpp dbquery.cpp dbreference.cpp dbtype.cpp
dbvalue.cpp hostdbobject.cpp hostgroupdbobject.cpp servicedbobject.cpp
servicegroupdbobject.cpp timeperioddbobject.cpp userdbobject.cpp
usergroupdbobject.cpp
dbvalue.cpp endpointdbobject.cpp hostdbobject.cpp hostgroupdbobject.cpp
servicedbobject.cpp servicegroupdbobject.cpp timeperioddbobject.cpp
userdbobject.cpp usergroupdbobject.cpp
)
include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries(db_ido ${Boost_LIBRARIES} base config icinga)
target_link_libraries(db_ido ${Boost_LIBRARIES} base config icinga remote)
set_target_properties (
db_ido PROPERTIES

View File

@ -326,6 +326,8 @@ void DbConnection::PrepareDatabase(void)
//ClearConfigTable("contactstatus");
ClearConfigTable("customvariables");
ClearConfigTable("customvariablestatus");
ClearConfigTable("endpoints");
ClearConfigTable("endpointstatus");
ClearConfigTable("host_contactgroups");
ClearConfigTable("host_contacts");
ClearConfigTable("host_parenthosts");

View File

@ -21,6 +21,7 @@
#include "db_ido/dbtype.h"
#include "db_ido/dbvalue.h"
#include "icinga/service.h"
#include "remote/endpoint.h"
#include "base/dynamictype.h"
#include "base/objectlock.h"
#include "base/utility.h"
@ -108,7 +109,20 @@ void DbObject::SendStatusUpdate(void)
query.Category = DbCatState;
query.Fields = fields;
query.Fields->Set(GetType()->GetIDColumn(), GetObject());
/* do not override our own endpoint dbobject id */
if (GetType()->GetTable() != "endpoint") {
String node = IcingaApplication::GetInstance()->GetNodeName();
Log(LogDebug, "db_ido", "Endpoint node: '" + node + "' status update for '" + GetObject()->GetName() + "'");
Endpoint::Ptr endpoint = Endpoint::GetByName(node);
if (endpoint)
query.Fields->Set("endpoint_object_id", endpoint);
}
query.Fields->Set("instance_id", 0); /* DbConnection class fills in real ID */
query.Fields->Set("status_update_time", DbValue::FromTimestamp(Utility::GetTime()));
query.WhereCriteria = make_shared<Dictionary>();
query.WhereCriteria->Set(GetType()->GetIDColumn(), GetObject());

View File

@ -49,6 +49,7 @@ enum DbObjectType
DbObjectTypeContact = 10,
DbObjectTypeContactGroup = 11,
DbObjectTypeCommand = 12,
DbObjectTypeEndpoint = 13,
};
/**

View File

@ -0,0 +1,134 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-present Icinga Development Team (http://www.icinga.org) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#include "db_ido/endpointdbobject.h"
#include "db_ido/dbtype.h"
#include "db_ido/dbvalue.h"
#include "icinga/icingaapplication.h"
#include "base/objectlock.h"
#include "base/initialize.h"
#include "base/dynamictype.h"
#include "base/utility.h"
#include "base/convert.h"
#include "base/logger_fwd.h"
#include <boost/foreach.hpp>
using namespace icinga;
REGISTER_DBTYPE(Endpoint, "endpoint", DbObjectTypeEndpoint, "endpoint_object_id", EndpointDbObject);
INITIALIZE_ONCE(&EndpointDbObject::StaticInitialize);
void EndpointDbObject::StaticInitialize(void)
{
Endpoint::OnConnected.connect(boost::bind(&EndpointDbObject::UpdateConnectedStatus, _1));
Endpoint::OnDisconnected.connect(boost::bind(&EndpointDbObject::UpdateDisconnectedStatus, _1));
}
EndpointDbObject::EndpointDbObject(const DbType::Ptr& type, const String& name1, const String& name2)
: DbObject(type, name1, name2)
{ }
Dictionary::Ptr EndpointDbObject::GetConfigFields(void) const
{
Dictionary::Ptr fields = make_shared<Dictionary>();
Endpoint::Ptr endpoint = static_pointer_cast<Endpoint>(GetObject());
fields->Set("identity", endpoint->GetName());
fields->Set("node", IcingaApplication::GetInstance()->GetNodeName());
return fields;
}
Dictionary::Ptr EndpointDbObject::GetStatusFields(void) const
{
Dictionary::Ptr fields = make_shared<Dictionary>();
Endpoint::Ptr endpoint = static_pointer_cast<Endpoint>(GetObject());
Log(LogDebug, "db_ido", "update status for endpoint '" + endpoint->GetName() + "'");
fields->Set("identity", endpoint->GetName());
fields->Set("node", IcingaApplication::GetInstance()->GetNodeName());
fields->Set("is_connected", EndpointIsConnected(endpoint));
return fields;
}
void EndpointDbObject::UpdateConnectedStatus(const Endpoint::Ptr& endpoint)
{
UpdateConnectedStatusInternal(endpoint, true);
}
void EndpointDbObject::UpdateDisconnectedStatus(const Endpoint::Ptr& endpoint)
{
UpdateConnectedStatusInternal(endpoint, false);
}
void EndpointDbObject::UpdateConnectedStatusInternal(const Endpoint::Ptr& endpoint, bool connected)
{
Log(LogDebug, "db_ido", "update is_connected=" + Convert::ToString(connected ? 1 : 0) + " for endpoint '" + endpoint->GetName() + "'");
DbQuery query1;
query1.Table = "endpointstatus";
query1.Type = DbQueryUpdate;
Dictionary::Ptr fields1 = make_shared<Dictionary>();
fields1->Set("is_connected", (connected ? 1 : 0));
fields1->Set("status_update_time", DbValue::FromTimestamp(Utility::GetTime()));
query1.Fields = fields1;
query1.WhereCriteria = make_shared<Dictionary>();
query1.WhereCriteria->Set("endpoint_object_id", endpoint);
query1.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */
OnQuery(query1);
}
int EndpointDbObject::EndpointIsConnected(const Endpoint::Ptr& endpoint)
{
unsigned int is_connected = endpoint->IsConnected() ? 1 : 0;
/* if identity is equal to node, fake is_connected */
if (endpoint->GetName() == IcingaApplication::GetInstance()->GetNodeName())
is_connected = 1;
return is_connected;
}
void EndpointDbObject::OnConfigUpdate(void)
{
/* update current status on config dump once */
Endpoint::Ptr endpoint = static_pointer_cast<Endpoint>(GetObject());
DbQuery query1;
query1.Table = "endpointstatus";
query1.Type = DbQueryInsert;
Dictionary::Ptr fields1 = make_shared<Dictionary>();
fields1->Set("identity", endpoint->GetName());
fields1->Set("node", IcingaApplication::GetInstance()->GetNodeName());
fields1->Set("is_connected", EndpointIsConnected(endpoint));
fields1->Set("status_update_time", DbValue::FromTimestamp(Utility::GetTime()));
fields1->Set("endpoint_object_id", endpoint);
fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
query1.Fields = fields1;
OnQuery(query1);
}

View File

@ -0,0 +1,59 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-present Icinga Development Team (http://www.icinga.org) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#ifndef ENDPOINTDBOBJECT_H
#define ENDPOINTDBOBJECT_H
#include "db_ido/dbobject.h"
#include "base/dynamicobject.h"
#include "remote/endpoint.h"
namespace icinga
{
/**
* A Command database object.
*
* @ingroup ido
*/
class EndpointDbObject : public DbObject
{
public:
DECLARE_PTR_TYPEDEFS(EndpointDbObject);
EndpointDbObject(const shared_ptr<DbType>& type, const String& name1, const String& name2);
static void StaticInitialize(void);
virtual Dictionary::Ptr GetConfigFields(void) const;
virtual Dictionary::Ptr GetStatusFields(void) const;
protected:
virtual void OnConfigUpdate(void);
private:
static void UpdateConnectedStatus(const Endpoint::Ptr& endpoint);
static void UpdateDisconnectedStatus(const Endpoint::Ptr& endpoint);
static void UpdateConnectedStatusInternal(const Endpoint::Ptr& endpoint, bool connected);
static int EndpointIsConnected(const Endpoint::Ptr& endpoint);
};
}
#endif /* ENDPOINTDBOBJECT_H */

View File

@ -25,6 +25,7 @@
#include "base/initialize.h"
#include "base/dynamictype.h"
#include "base/utility.h"
#include "remote/endpoint.h"
#include "icinga/notification.h"
#include "icinga/checkcommand.h"
#include "icinga/eventcommand.h"
@ -144,7 +145,14 @@ Dictionary::Ptr ServiceDbObject::GetStatusFields(void) const
fields->Set("output", CompatUtility::GetCheckResultOutput(cr));
fields->Set("long_output", CompatUtility::GetCheckResultLongOutput(cr));
fields->Set("perfdata", CompatUtility::GetCheckResultPerfdata(cr));
fields->Set("check_source", cr->GetCheckSource());
String check_source = cr->GetCheckSource();
fields->Set("check_source", check_source);
Endpoint::Ptr check_endpoint = Endpoint::GetByName(check_source);
if(check_endpoint)
fields->Set("check_source_object_id", check_endpoint);
}
fields->Set("current_state", CompatUtility::GetServiceCurrentState(service));
@ -398,6 +406,12 @@ void ServiceDbObject::AddCommentByType(const DynamicObject::Ptr& object, const C
fields1->Set("expiration_time", DbValue::FromTimestamp(comment->GetExpireTime()));
fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
String node = IcingaApplication::GetInstance()->GetNodeName();
Endpoint::Ptr endpoint = Endpoint::GetByName(node);
if (endpoint)
fields1->Set("endpoint_object_id", endpoint);
DbQuery query1;
if (!historical) {
query1.Table = "comments";
@ -563,6 +577,12 @@ void ServiceDbObject::AddDowntimeByType(const DynamicObject::Ptr& object, const
fields1->Set("trigger_time", DbValue::FromTimestamp(downtime->GetTriggerTime()));
fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
String node = IcingaApplication::GetInstance()->GetNodeName();
Endpoint::Ptr endpoint = Endpoint::GetByName(node);
if (endpoint)
fields1->Set("endpoint_object_id", endpoint);
DbQuery query1;
if (!historical) {
query1.Table = "scheduleddowntime";
@ -746,6 +766,12 @@ void ServiceDbObject::AddAcknowledgementHistory(const Service::Ptr& service, con
fields1->Set("end_time", DbValue::FromTimestamp(end_time));
fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
String node = IcingaApplication::GetInstance()->GetNodeName();
Endpoint::Ptr endpoint = Endpoint::GetByName(node);
if (endpoint)
fields1->Set("endpoint_object_id", endpoint);
query1.Fields = fields1;
OnQuery(query1);
@ -796,6 +822,12 @@ void ServiceDbObject::AddNotificationHistory(const Notification::Ptr& notificati
fields1->Set("contacts_notified", static_cast<long>(users.size()));
fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
String node = IcingaApplication::GetInstance()->GetNodeName();
Endpoint::Ptr endpoint = Endpoint::GetByName(node);
if (endpoint)
fields1->Set("endpoint_object_id", endpoint);
query1.Fields = fields1;
OnQuery(query1);
@ -862,11 +894,24 @@ void ServiceDbObject::AddStateChangeHistory(const Service::Ptr& service, const C
if (cr) {
fields1->Set("output", CompatUtility::GetCheckResultOutput(cr));
fields1->Set("long_output", CompatUtility::GetCheckResultLongOutput(cr));
fields1->Set("check_source", cr->GetCheckSource());
String check_source = cr->GetCheckSource();
fields1->Set("check_source", check_source);
Endpoint::Ptr check_endpoint = Endpoint::GetByName(check_source);
if(check_endpoint)
fields1->Set("check_source_object_id", check_endpoint);
}
fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
String node = IcingaApplication::GetInstance()->GetNodeName();
Endpoint::Ptr endpoint = Endpoint::GetByName(node);
if (endpoint)
fields1->Set("endpoint_object_id", endpoint);
query1.Fields = fields1;
OnQuery(query1);
@ -1170,6 +1215,12 @@ void ServiceDbObject::AddLogHistory(const Service::Ptr& service, String buffer,
fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
String node = IcingaApplication::GetInstance()->GetNodeName();
Endpoint::Ptr endpoint = Endpoint::GetByName(node);
if (endpoint)
fields1->Set("endpoint_object_id", endpoint);
query1.Fields = fields1;
OnQuery(query1);
@ -1226,6 +1277,12 @@ void ServiceDbObject::AddFlappingHistory(const Service::Ptr& service, FlappingSt
fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
String node = IcingaApplication::GetInstance()->GetNodeName();
Endpoint::Ptr endpoint = Endpoint::GetByName(node);
if (endpoint)
fields1->Set("endpoint_object_id", endpoint);
query1.Fields = fields1;
OnQuery(query1);
@ -1285,6 +1342,12 @@ void ServiceDbObject::AddServiceCheckHistory(const Service::Ptr& service, const
fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
fields1->Set("service_object_id", service);
String node = IcingaApplication::GetInstance()->GetNodeName();
Endpoint::Ptr endpoint = Endpoint::GetByName(node);
if (endpoint)
fields1->Set("endpoint_object_id", endpoint);
query1.Fields = fields1;
OnQuery(query1);
@ -1331,6 +1394,12 @@ void ServiceDbObject::AddEventHandlerHistory(const Service::Ptr& service)
fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
String node = IcingaApplication::GetInstance()->GetNodeName();
Endpoint::Ptr endpoint = Endpoint::GetByName(node);
if (endpoint)
fields1->Set("endpoint_object_id", endpoint);
query1.Fields = fields1;
OnQuery(query1);
@ -1364,6 +1433,12 @@ void ServiceDbObject::AddExternalCommandHistory(double time, const String& comma
fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */
String node = IcingaApplication::GetInstance()->GetNodeName();
Endpoint::Ptr endpoint = Endpoint::GetByName(node);
if (endpoint)
fields1->Set("endpoint_object_id", endpoint);
query1.Fields = fields1;
OnQuery(query1);
}

View File

@ -417,7 +417,7 @@ void Service::ProcessCheckResult(const CheckResult::Ptr& cr, const String& autho
OnNewCheckResult(GetSelf(), cr, authority);
/* signal status updates to for example db_ido */
OnStateChanged(GetSelf());
OnStateChanged(GetSelf(), authority);
if (hardChange)
OnStateChange(GetSelf(), cr, StateTypeHard, authority);

42
lib/remote/CMakeLists.txt Normal file
View File

@ -0,0 +1,42 @@
# Icinga 2
# Copyright (C) 2012-present Icinga Development Team (http://www.icinga.org)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
mkclass_target(endpoint.ti endpoint.th)
mkembedconfig_target(remote-type.conf remote-type.cpp)
add_library(remote SHARED
endpoint.cpp endpoint.th jsonrpc.cpp remote-type.cpp
)
include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries(remote ${Boost_LIBRARIES} base config)
set_target_properties (
remote PROPERTIES
INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR}/icinga2
DEFINE_SYMBOL I2_REMOTE_BUILD
FOLDER Lib
)
install(
TARGETS remote
RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/icinga2
)

View File

@ -17,8 +17,8 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#include "cluster/endpoint.h"
#include "cluster/jsonrpc.h"
#include "remote/endpoint.h"
#include "remote/jsonrpc.h"
#include "base/application.h"
#include "base/dynamictype.h"
#include "base/objectlock.h"
@ -32,6 +32,7 @@ using namespace icinga;
REGISTER_TYPE(Endpoint);
boost::signals2::signal<void (const Endpoint::Ptr&)> Endpoint::OnConnected;
boost::signals2::signal<void (const Endpoint::Ptr&)> Endpoint::OnDisconnected;
boost::signals2::signal<void (const Endpoint::Ptr&, const Dictionary::Ptr&)> Endpoint::OnMessageReceived;
/**
@ -61,6 +62,10 @@ void Endpoint::SetClient(const Stream::Ptr& client)
thread.detach();
OnConnected(GetSelf());
Log(LogWarning, "remote", "Endpoint connected: " + GetName());
} else {
OnDisconnected(GetSelf());
Log(LogWarning, "remote", "Endpoint disconnected: " + GetName());
}
}
@ -76,9 +81,12 @@ void Endpoint::SendMessage(const Dictionary::Ptr& message)
} catch (const std::exception& ex) {
std::ostringstream msgbuf;
msgbuf << "Error while sending JSON-RPC message for endpoint '" << GetName() << "': " << DiagnosticInformation(ex);
Log(LogWarning, "cluster", msgbuf.str());
Log(LogWarning, "remote", msgbuf.str());
m_Client.reset();
OnDisconnected(GetSelf());
Log(LogWarning, "remote", "Endpoint disconnected: " + GetName());
}
}
@ -92,10 +100,13 @@ void Endpoint::MessageThreadProc(const Stream::Ptr& stream)
try {
message = JsonRpc::ReadMessage(stream);
} catch (const std::exception& ex) {
Log(LogWarning, "cluster", "Error while reading JSON-RPC message for endpoint '" + GetName() + "': " + DiagnosticInformation(ex));
Log(LogWarning, "remote", "Error while reading JSON-RPC message for endpoint '" + GetName() + "': " + DiagnosticInformation(ex));
m_Client.reset();
OnDisconnected(GetSelf());
Log(LogWarning, "remote", "Endpoint disconnected: " + GetName());
return;
}

View File

@ -20,9 +20,10 @@
#ifndef ENDPOINT_H
#define ENDPOINT_H
#include "cluster/endpoint.th"
#include "remote/endpoint.th"
#include "base/stream.h"
#include "base/array.h"
#include "remote/i2-remote.h"
#include <boost/signals2.hpp>
namespace icinga
@ -35,13 +36,14 @@ class EndpointManager;
*
* @ingroup cluster
*/
class Endpoint : public ObjectImpl<Endpoint>
class I2_REMOTE_API Endpoint : public ObjectImpl<Endpoint>
{
public:
DECLARE_PTR_TYPEDEFS(Endpoint);
DECLARE_TYPENAME(Endpoint);
static boost::signals2::signal<void (const Endpoint::Ptr&)> OnConnected;
static boost::signals2::signal<void (const Endpoint::Ptr&)> OnDisconnected;
static boost::signals2::signal<void (const Endpoint::Ptr&, const Dictionary::Ptr&)> OnMessageReceived;
Stream::Ptr GetClient(void) const;

37
lib/remote/i2-remote.h Normal file
View File

@ -0,0 +1,37 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-present Icinga Development Team (http://www.icinga.org) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#ifndef I2REMOTE_H
#define I2REMOTE_H
/**
* @defgroup remote Remote library
*
* The Icinga library implements remote cluster functionality.
*/
#include "base/i2-base.h"
#ifdef I2_REMOTE_BUILD
# define I2_REMOTE_API I2_EXPORT
#else /* I2_REMOTE_BUILD */
# define I2_REMOTE_API I2_IMPORT
#endif /* I2_REMOTE_BUILD */
#endif /* I2REMOTE_H */

View File

@ -17,7 +17,7 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#include "cluster/jsonrpc.h"
#include "remote/jsonrpc.h"
#include "base/netstring.h"
#include "base/objectlock.h"
#include "base/logger_fwd.h"

View File

@ -22,6 +22,7 @@
#include "base/stream.h"
#include "base/dictionary.h"
#include "remote/i2-remote.h"
namespace icinga
{
@ -29,9 +30,9 @@ namespace icinga
/**
* A JSON-RPC connection.
*
* @ingroup cluster
* @ingroup remote
*/
class JsonRpc
class I2_REMOTE_API JsonRpc
{
public:
static void SendMessage(const Stream::Ptr& stream, const Dictionary::Ptr& message);

View File

@ -0,0 +1,42 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-present Icinga Development Team (http://www.icinga.org) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
type Endpoint {
%require "host",
%attribute string "host",
%require "port",
%attribute string "port",
%attribute array "config_files" {
%attribute string "*"
},
%attribute array "config_files_recursive" {
%attribute string "*",
%attribute dictionary "*" {
%attribute string "path",
%attribute string "pattern"
}
},
%attribute array "accept_config" {
%attribute name(Endpoint) "*"
}
}

View File

@ -0,0 +1,3 @@
GET endpoints
ResponseHeader: fixed16

View File

@ -0,0 +1,4 @@
GET services
Columns: description host_name plugin_output check_source
ResponseHeader: fixed16