From: Michael Friedrich Date: Fri, 13 Feb 2015 14:50:20 +0000 (+0100) Subject: Livestatus: Add GroupBy tables: hostsbygroup, servicesbygroup, servicesbyhostgroup X-Git-Tag: v2.3.0~181 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=70c750250c18c3239fb3f339f8710e765df3c325;p=icinga2 Livestatus: Add GroupBy tables: hostsbygroup, servicesbygroup, servicesbyhostgroup fixes #7361 Signed-off-by: Michael Friedrich --- diff --git a/lib/livestatus/column.cpp b/lib/livestatus/column.cpp index 664e88caf..44f70f12b 100644 --- a/lib/livestatus/column.cpp +++ b/lib/livestatus/column.cpp @@ -25,12 +25,12 @@ Column::Column(const ValueAccessor& valueAccessor, const ObjectAccessor& objectA : m_ValueAccessor(valueAccessor), m_ObjectAccessor(objectAccessor) { } -Value Column::ExtractValue(const Value& urow) const +Value Column::ExtractValue(const Value& urow, LivestatusGroupByType groupByType, const Object::Ptr& groupByObject) const { Value row; if (!m_ObjectAccessor.empty()) - row = m_ObjectAccessor(urow); + row = m_ObjectAccessor(urow, groupByType, groupByObject); else row = urow; diff --git a/lib/livestatus/column.hpp b/lib/livestatus/column.hpp index c9fb516ae..74618dac1 100644 --- a/lib/livestatus/column.hpp +++ b/lib/livestatus/column.hpp @@ -28,15 +28,21 @@ using namespace icinga; namespace icinga { +enum LivestatusGroupByType { + LivestatusGroupByNone, + LivestatusGroupByHostGroup, + LivestatusGroupByServiceGroup +}; + class Column { public: typedef boost::function ValueAccessor; - typedef boost::function ObjectAccessor; + typedef boost::function ObjectAccessor; Column(const ValueAccessor& valueAccessor, const ObjectAccessor& objectAccessor); - Value ExtractValue(const Value& urow) const; + Value ExtractValue(const Value& urow, LivestatusGroupByType groupByType = LivestatusGroupByNone, const Object::Ptr& groupByObject = Empty) const; private: ValueAccessor m_ValueAccessor; diff --git a/lib/livestatus/commandstable.cpp b/lib/livestatus/commandstable.cpp index 756f1d322..b36a8bd0d 100644 --- a/lib/livestatus/commandstable.cpp +++ b/lib/livestatus/commandstable.cpp @@ -61,27 +61,27 @@ String CommandsTable::GetPrefix(void) const void CommandsTable::FetchRows(const AddRowFunction& addRowFn) { BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjectsByType()) { - addRowFn(object); + addRowFn(object, LivestatusGroupByNone, Empty); } BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjectsByType()) { - addRowFn(object); + addRowFn(object, LivestatusGroupByNone, Empty); } BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjectsByType()) { - addRowFn(object); + addRowFn(object, LivestatusGroupByNone, Empty); } } Value CommandsTable::NameAccessor(const Value& row) { Command::Ptr command = static_cast(row); - + return CompatUtility::GetCommandName(command); } Value CommandsTable::LineAccessor(const Value& row) { Command::Ptr command = static_cast(row); - + if (!command) return Empty; diff --git a/lib/livestatus/commentstable.cpp b/lib/livestatus/commentstable.cpp index 475415983..4feb6b534 100644 --- a/lib/livestatus/commentstable.cpp +++ b/lib/livestatus/commentstable.cpp @@ -74,7 +74,7 @@ void CommentsTable::FetchRows(const AddRowFunction& addRowFn) Comment::Ptr comment; BOOST_FOREACH(tie(id, comment), comments) { if (Host::GetOwnerByCommentID(id) == host) - addRowFn(comment); + addRowFn(comment, LivestatusGroupByNone, Empty); } } @@ -87,7 +87,7 @@ void CommentsTable::FetchRows(const AddRowFunction& addRowFn) Comment::Ptr comment; BOOST_FOREACH(tie(id, comment), comments) { if (Service::GetOwnerByCommentID(id) == service) - addRowFn(comment); + addRowFn(comment, LivestatusGroupByNone, Empty); } } } diff --git a/lib/livestatus/contactgroupstable.cpp b/lib/livestatus/contactgroupstable.cpp index 43ef038f1..604aa73b7 100644 --- a/lib/livestatus/contactgroupstable.cpp +++ b/lib/livestatus/contactgroupstable.cpp @@ -50,7 +50,7 @@ String ContactGroupsTable::GetPrefix(void) const void ContactGroupsTable::FetchRows(const AddRowFunction& addRowFn) { BOOST_FOREACH(const UserGroup::Ptr& ug, DynamicType::GetObjectsByType()) { - addRowFn(ug); + addRowFn(ug, LivestatusGroupByNone, Empty); } } diff --git a/lib/livestatus/contactstable.cpp b/lib/livestatus/contactstable.cpp index 35a61d5be..e6400e5ee 100644 --- a/lib/livestatus/contactstable.cpp +++ b/lib/livestatus/contactstable.cpp @@ -71,7 +71,7 @@ String ContactsTable::GetPrefix(void) const void ContactsTable::FetchRows(const AddRowFunction& addRowFn) { BOOST_FOREACH(const User::Ptr& user, DynamicType::GetObjectsByType()) { - addRowFn(user); + addRowFn(user, LivestatusGroupByNone, Empty); } } diff --git a/lib/livestatus/downtimestable.cpp b/lib/livestatus/downtimestable.cpp index 742ff8206..49bdd3933 100644 --- a/lib/livestatus/downtimestable.cpp +++ b/lib/livestatus/downtimestable.cpp @@ -74,7 +74,7 @@ void DowntimesTable::FetchRows(const AddRowFunction& addRowFn) Downtime::Ptr downtime; BOOST_FOREACH(boost::tie(id, downtime), downtimes) { if (Host::GetOwnerByDowntimeID(id) == host) - addRowFn(downtime); + addRowFn(downtime, LivestatusGroupByNone, Empty); } } @@ -87,7 +87,7 @@ void DowntimesTable::FetchRows(const AddRowFunction& addRowFn) Downtime::Ptr downtime; BOOST_FOREACH(boost::tie(id, downtime), downtimes) { if (Service::GetOwnerByDowntimeID(id) == service) - addRowFn(downtime); + addRowFn(downtime, LivestatusGroupByNone, Empty); } } } diff --git a/lib/livestatus/endpointstable.cpp b/lib/livestatus/endpointstable.cpp index c206ecd5d..be546685f 100644 --- a/lib/livestatus/endpointstable.cpp +++ b/lib/livestatus/endpointstable.cpp @@ -61,7 +61,7 @@ String EndpointsTable::GetPrefix(void) const void EndpointsTable::FetchRows(const AddRowFunction& addRowFn) { BOOST_FOREACH(const Endpoint::Ptr& endpoint, DynamicType::GetObjectsByType()) { - addRowFn(endpoint); + addRowFn(endpoint, LivestatusGroupByNone, Empty); } } @@ -110,6 +110,3 @@ Value EndpointsTable::IsConnectedAccessor(const Value& row) return is_connected; } - - - diff --git a/lib/livestatus/hostgroupstable.cpp b/lib/livestatus/hostgroupstable.cpp index db46c5c21..ee1f6c4c0 100644 --- a/lib/livestatus/hostgroupstable.cpp +++ b/lib/livestatus/hostgroupstable.cpp @@ -74,7 +74,7 @@ String HostGroupsTable::GetPrefix(void) const void HostGroupsTable::FetchRows(const AddRowFunction& addRowFn) { BOOST_FOREACH(const HostGroup::Ptr& hg, DynamicType::GetObjectsByType()) { - addRowFn(hg); + addRowFn(hg, LivestatusGroupByNone, Empty); } } diff --git a/lib/livestatus/hoststable.cpp b/lib/livestatus/hoststable.cpp index b477bbc80..f99549034 100644 --- a/lib/livestatus/hoststable.cpp +++ b/lib/livestatus/hoststable.cpp @@ -18,8 +18,11 @@ ******************************************************************************/ #include "livestatus/hoststable.hpp" +#include "livestatus/hostgroupstable.hpp" +#include "livestatus/endpointstable.hpp" #include "icinga/host.hpp" #include "icinga/service.hpp" +#include "icinga/hostgroup.hpp" #include "icinga/checkcommand.hpp" #include "icinga/eventcommand.hpp" #include "icinga/timeperiod.hpp" @@ -31,15 +34,14 @@ #include "base/json.hpp" #include "base/convert.hpp" #include "base/utility.hpp" -#include #include #include #include -#include using namespace icinga; -HostsTable::HostsTable(void) +HostsTable::HostsTable(LivestatusGroupByType type) + :Table(type) { AddColumns(this); } @@ -162,6 +164,14 @@ void HostsTable::AddColumns(Table *table, const String& prefix, table->AddColumn(prefix + "check_source", Column(&HostsTable::CheckSourceAccessor, objectAccessor)); table->AddColumn(prefix + "is_reachable", Column(&HostsTable::IsReachableAccessor, objectAccessor)); table->AddColumn(prefix + "cv_is_json", Column(&HostsTable::CVIsJsonAccessor, objectAccessor)); + + /* add additional group by values received through the object accessor */ + if (table->GetGroupByType() == LivestatusGroupByHostGroup) { + /* _1 = row, _2 = groupByType, _3 = groupByObject */ + Log(LogDebug, "Livestatus") + << "Processing hosts group by hostgroup table."; + HostGroupsTable::AddColumns(table, "hostgroup_", boost::bind(&HostsTable::HostGroupAccessor, _1, _2, _3)); + } } String HostsTable::GetName(void) const @@ -176,11 +186,32 @@ String HostsTable::GetPrefix(void) const void HostsTable::FetchRows(const AddRowFunction& addRowFn) { - BOOST_FOREACH(const Host::Ptr& host, DynamicType::GetObjectsByType()) { - addRowFn(host); + if (GetGroupByType() == LivestatusGroupByHostGroup) { + BOOST_FOREACH(const HostGroup::Ptr& hg, DynamicType::GetObjectsByType()) { + BOOST_FOREACH(const Host::Ptr& host, hg->GetMembers()) { + /* the caller must know which groupby type and value are set for this row */ + addRowFn(host, LivestatusGroupByHostGroup, hg); + } + } + } else { + BOOST_FOREACH(const Host::Ptr& host, DynamicType::GetObjectsByType()) { + addRowFn(host, LivestatusGroupByNone, Empty); + } } } +Object::Ptr HostsTable::HostGroupAccessor(const Value& row, LivestatusGroupByType groupByType, const Object::Ptr& groupByObject) +{ + /* return the current group by value set from within FetchRows() + * this is the hostgrouo object used for the table join inside + * in AddColumns() + */ + if (groupByType == LivestatusGroupByHostGroup) + return groupByObject; + + return Object::Ptr(); +} + Value HostsTable::NameAccessor(const Value& row) { Host::Ptr host = static_cast(row); @@ -208,7 +239,6 @@ Value HostsTable::AddressAccessor(const Value& row) if (!host) return Empty; - return host->GetAddress(); } diff --git a/lib/livestatus/hoststable.hpp b/lib/livestatus/hoststable.hpp index 8fb8b01c0..8b6c61cda 100644 --- a/lib/livestatus/hoststable.hpp +++ b/lib/livestatus/hoststable.hpp @@ -35,7 +35,7 @@ class HostsTable : public Table public: DECLARE_PTR_TYPEDEFS(HostsTable); - HostsTable(void); + HostsTable(LivestatusGroupByType type = LivestatusGroupByNone); static void AddColumns(Table *table, const String& prefix = String(), const Column::ObjectAccessor& objectAccessor = Column::ObjectAccessor()); @@ -46,6 +46,8 @@ public: protected: virtual void FetchRows(const AddRowFunction& addRowFn); + static Object::Ptr HostGroupAccessor(const Value& row, LivestatusGroupByType groupByType, const Object::Ptr& groupByObject); + static Value NameAccessor(const Value& row); static Value DisplayNameAccessor(const Value& row); static Value AddressAccessor(const Value& row); diff --git a/lib/livestatus/livestatusquery.cpp b/lib/livestatus/livestatusquery.cpp index ad9290119..604ed110f 100644 --- a/lib/livestatus/livestatusquery.cpp +++ b/lib/livestatus/livestatusquery.cpp @@ -495,7 +495,7 @@ void LivestatusQuery::ExecuteGetHelper(const Stream::Ptr& stream) return; } - std::vector objects = table->FilterRows(m_Filter); + std::vector objects = table->FilterRows(m_Filter); std::vector columns; if (m_Columns.size() > 0) @@ -508,7 +508,7 @@ void LivestatusQuery::ExecuteGetHelper(const Stream::Ptr& stream) if (m_Aggregators.empty()) { Array::Ptr header = new Array(); - BOOST_FOREACH(const Value& object, objects) { + BOOST_FOREACH(const LivestatusRowValue& object, objects) { Array::Ptr row = new Array(); BOOST_FOREACH(const String& columnName, columns) { @@ -517,7 +517,7 @@ void LivestatusQuery::ExecuteGetHelper(const Stream::Ptr& stream) if (m_ColumnHeaders) header->Add(columnName); - row->Add(column.ExtractValue(object)); + row->Add(column.ExtractValue(object.Row, object.GroupByType, object.GroupByObject)); } if (m_ColumnHeaders) { @@ -533,8 +533,8 @@ void LivestatusQuery::ExecuteGetHelper(const Stream::Ptr& stream) /* add aggregated stats */ BOOST_FOREACH(const Aggregator::Ptr aggregator, m_Aggregators) { - BOOST_FOREACH(const Value& object, objects) { - aggregator->Apply(table, object); + BOOST_FOREACH(const LivestatusRowValue& object, objects) { + aggregator->Apply(table, object.Row); } stats[index] = aggregator->GetResult(); @@ -566,7 +566,9 @@ void LivestatusQuery::ExecuteGetHelper(const Stream::Ptr& stream) BOOST_FOREACH(const String& columnName, m_Columns) { Column column = table->GetColumn(columnName); - row->Add(column.ExtractValue(objects[0])); // first object wins + LivestatusRowValue object = objects[0]; //first object wins + + row->Add(column.ExtractValue(object.Row, object.GroupByType, object.GroupByObject)); } } diff --git a/lib/livestatus/logtable.cpp b/lib/livestatus/logtable.cpp index 6bc8d90cd..cf53c29e9 100644 --- a/lib/livestatus/logtable.cpp +++ b/lib/livestatus/logtable.cpp @@ -57,8 +57,6 @@ LogTable::LogTable(const String& compat_log_path, time_t from, time_t until) AddColumns(this); } - - void LogTable::AddColumns(Table *table, const String& prefix, const Column::ObjectAccessor& objectAccessor) { @@ -112,7 +110,7 @@ void LogTable::UpdateLogEntries(const Dictionary::Ptr& log_entry_attrs, int line /* additional attributes only for log table */ log_entry_attrs->Set("lineno", lineno); - addRowFn(log_entry_attrs); + addRowFn(log_entry_attrs, LivestatusGroupByNone, Empty); } Object::Ptr LogTable::HostAccessor(const Value& row, const Column::ObjectAccessor&) @@ -244,6 +242,3 @@ Value LogTable::CommandNameAccessor(const Value& row) { return static_cast(row)->Get("command_name"); } - - - diff --git a/lib/livestatus/servicegroupstable.cpp b/lib/livestatus/servicegroupstable.cpp index 0a3c8ee8e..a7c4ac64c 100644 --- a/lib/livestatus/servicegroupstable.cpp +++ b/lib/livestatus/servicegroupstable.cpp @@ -65,7 +65,7 @@ String ServiceGroupsTable::GetPrefix(void) const void ServiceGroupsTable::FetchRows(const AddRowFunction& addRowFn) { BOOST_FOREACH(const ServiceGroup::Ptr& sg, DynamicType::GetObjectsByType()) { - addRowFn(sg); + addRowFn(sg, LivestatusGroupByNone, Empty); } } diff --git a/lib/livestatus/servicestable.cpp b/lib/livestatus/servicestable.cpp index e4240f564..b4576c527 100644 --- a/lib/livestatus/servicestable.cpp +++ b/lib/livestatus/servicestable.cpp @@ -19,8 +19,12 @@ #include "livestatus/servicestable.hpp" #include "livestatus/hoststable.hpp" +#include "livestatus/servicegroupstable.hpp" +#include "livestatus/hostgroupstable.hpp" #include "livestatus/endpointstable.hpp" #include "icinga/service.hpp" +#include "icinga/servicegroup.hpp" +#include "icinga/hostgroup.hpp" #include "icinga/checkcommand.hpp" #include "icinga/eventcommand.hpp" #include "icinga/timeperiod.hpp" @@ -38,11 +42,13 @@ using namespace icinga; -ServicesTable::ServicesTable(void) +ServicesTable::ServicesTable(LivestatusGroupByType type) + : Table(type) { AddColumns(this); } + void ServicesTable::AddColumns(Table *table, const String& prefix, const Column::ObjectAccessor& objectAccessor) { @@ -133,6 +139,19 @@ void ServicesTable::AddColumns(Table *table, const String& prefix, table->AddColumn(prefix + "cv_is_json", Column(&ServicesTable::CVIsJsonAccessor, objectAccessor)); HostsTable::AddColumns(table, "host_", boost::bind(&ServicesTable::HostAccessor, _1, objectAccessor)); + + /* add additional group by values received through the object accessor */ + if (table->GetGroupByType() == LivestatusGroupByServiceGroup) { + /* _1 = row, _2 = groupByType, _3 = groupByObject */ + Log(LogDebug, "Livestatus") + << "Processing services group by servicegroup table."; + ServiceGroupsTable::AddColumns(table, "servicegroup_", boost::bind(&ServicesTable::ServiceGroupAccessor, _1, _2, _3)); + } else if (table->GetGroupByType() == LivestatusGroupByHostGroup) { + /* _1 = row, _2 = groupByType, _3 = groupByObject */ + Log(LogDebug, "Livestatus") + << "Processing services group by hostgroup table."; + HostGroupsTable::AddColumns(table, "hostgroup_", boost::bind(&ServicesTable::HostGroupAccessor, _1, _2, _3)); + } } String ServicesTable::GetName(void) const @@ -147,8 +166,28 @@ String ServicesTable::GetPrefix(void) const void ServicesTable::FetchRows(const AddRowFunction& addRowFn) { - BOOST_FOREACH(const Service::Ptr& service, DynamicType::GetObjectsByType()) { - addRowFn(service); + if (GetGroupByType() == LivestatusGroupByServiceGroup) { + BOOST_FOREACH(const ServiceGroup::Ptr& sg, DynamicType::GetObjectsByType()) { + BOOST_FOREACH(const Service::Ptr& service, sg->GetMembers()) { + /* the caller must know which groupby type and value are set for this row */ + addRowFn(service, LivestatusGroupByServiceGroup, sg); + } + } + } else if (GetGroupByType() == LivestatusGroupByHostGroup) { + BOOST_FOREACH(const HostGroup::Ptr& hg, DynamicType::GetObjectsByType()) { + ObjectLock ylock(hg); + BOOST_FOREACH(const Host::Ptr& host, hg->GetMembers()) { + ObjectLock ylock(host); + BOOST_FOREACH(const Service::Ptr& service, host->GetServices()) { + /* the caller must know which groupby type and value are set for this row */ + addRowFn(service, LivestatusGroupByHostGroup, hg); + } + } + } + } else { + BOOST_FOREACH(const Service::Ptr& service, DynamicType::GetObjectsByType()) { + addRowFn(service, LivestatusGroupByNone, Empty); + } } } @@ -157,7 +196,7 @@ Object::Ptr ServicesTable::HostAccessor(const Value& row, const Column::ObjectAc Value service; if (parentObjectAccessor) - service = parentObjectAccessor(row); + service = parentObjectAccessor(row, LivestatusGroupByNone, Empty); else service = row; @@ -169,6 +208,30 @@ Object::Ptr ServicesTable::HostAccessor(const Value& row, const Column::ObjectAc return svc->GetHost(); } +Object::Ptr ServicesTable::ServiceGroupAccessor(const Value& row, LivestatusGroupByType groupByType, const Object::Ptr& groupByObject) +{ + /* return the current group by value set from within FetchRows() + * this is the servicegroup object used for the table join inside + * in AddColumns() + */ + if (groupByType == LivestatusGroupByServiceGroup) + return groupByObject; + + return Object::Ptr(); +} + +Object::Ptr ServicesTable::HostGroupAccessor(const Value& row, LivestatusGroupByType groupByType, const Object::Ptr& groupByObject) +{ + /* return the current group by value set from within FetchRows() + * this is the servicegroup object used for the table join inside + * in AddColumns() + */ + if (groupByType == LivestatusGroupByHostGroup) + return groupByObject; + + return Object::Ptr(); +} + Value ServicesTable::ShortNameAccessor(const Value& row) { Service::Ptr service = static_cast(row); diff --git a/lib/livestatus/servicestable.hpp b/lib/livestatus/servicestable.hpp index a222fa568..f0f99ca79 100644 --- a/lib/livestatus/servicestable.hpp +++ b/lib/livestatus/servicestable.hpp @@ -35,7 +35,7 @@ class ServicesTable : public Table public: DECLARE_PTR_TYPEDEFS(ServicesTable); - ServicesTable(void); + ServicesTable(LivestatusGroupByType type = LivestatusGroupByNone); static void AddColumns(Table *table, const String& prefix = String(), const Column::ObjectAccessor& objectAccessor = Column::ObjectAccessor()); @@ -47,6 +47,8 @@ protected: virtual void FetchRows(const AddRowFunction& addRowFn); static Object::Ptr HostAccessor(const Value& row, const Column::ObjectAccessor& parentObjectAccessor); + static Object::Ptr ServiceGroupAccessor(const Value& row, LivestatusGroupByType groupByType, const Object::Ptr& groupByObject); + static Object::Ptr HostGroupAccessor(const Value& row, LivestatusGroupByType groupByType, const Object::Ptr& groupByObject); static Value ShortNameAccessor(const Value& row); static Value DisplayNameAccessor(const Value& row); diff --git a/lib/livestatus/statehisttable.cpp b/lib/livestatus/statehisttable.cpp index 99a1183cf..a9008512c 100644 --- a/lib/livestatus/statehisttable.cpp +++ b/lib/livestatus/statehisttable.cpp @@ -271,7 +271,7 @@ void StateHistTable::FetchRows(const AddRowFunction& addRowFn) BOOST_FOREACH(boost::tie(checkable, boost::tuples::ignore), m_CheckablesCache) { BOOST_FOREACH(const Dictionary::Ptr& state_hist_bag, m_CheckablesCache[checkable]) { /* pass a dictionary from state history array */ - addRowFn(state_hist_bag); + addRowFn(state_hist_bag, LivestatusGroupByNone, Empty); } } } diff --git a/lib/livestatus/statustable.cpp b/lib/livestatus/statustable.cpp index 84a9cc56b..2a2078256 100644 --- a/lib/livestatus/statustable.cpp +++ b/lib/livestatus/statustable.cpp @@ -118,7 +118,7 @@ void StatusTable::FetchRows(const AddRowFunction& addRowFn) Object::Ptr obj = new Object(); /* Return a fake row. */ - addRowFn(obj); + addRowFn(obj, LivestatusGroupByNone, Empty); } Value StatusTable::ConnectionsAccessor(const Value&) diff --git a/lib/livestatus/table.cpp b/lib/livestatus/table.cpp index 20c606591..15e5e3c38 100644 --- a/lib/livestatus/table.cpp +++ b/lib/livestatus/table.cpp @@ -42,7 +42,8 @@ using namespace icinga; -Table::Table(void) +Table::Table(LivestatusGroupByType type) + : m_GroupByType(type), m_GroupByObject(Empty) { } Table::Ptr Table::GetByName(const String& name, const String& compat_log_path, const unsigned long& from, const unsigned long& until) @@ -57,10 +58,16 @@ Table::Ptr Table::GetByName(const String& name, const String& compat_log_path, c return new HostGroupsTable(); else if (name == "hosts") return new HostsTable(); + else if (name == "hostsbygroup") + return new HostsTable(LivestatusGroupByHostGroup); else if (name == "servicegroups") return new ServiceGroupsTable(); else if (name == "services") return new ServicesTable(); + else if (name == "servicesbygroup") + return new ServicesTable(LivestatusGroupByServiceGroup); + else if (name == "servicesbyhostgroup") + return new ServicesTable(LivestatusGroupByHostGroup); else if (name == "commands") return new CommandsTable(); else if (name == "comments") @@ -117,19 +124,25 @@ std::vector Table::GetColumnNames(void) const return names; } -std::vector Table::FilterRows(const Filter::Ptr& filter) +std::vector Table::FilterRows(const Filter::Ptr& filter) { - std::vector rs; + std::vector rs; - FetchRows(boost::bind(&Table::FilteredAddRow, this, boost::ref(rs), filter, _1)); + FetchRows(boost::bind(&Table::FilteredAddRow, this, boost::ref(rs), filter, _1, _2, _3)); return rs; } -void Table::FilteredAddRow(std::vector& rs, const Filter::Ptr& filter, const Value& row) +void Table::FilteredAddRow(std::vector& rs, const Filter::Ptr& filter, const Value& row, LivestatusGroupByType groupByType, const Object::Ptr& groupByObject) { - if (!filter || filter->Apply(this, row)) - rs.push_back(row); + if (!filter || filter->Apply(this, row)) { + LivestatusRowValue rval; + rval.Row = row; + rval.GroupByType = groupByType; + rval.GroupByObject = groupByObject; + + rs.push_back(rval); + } } Value Table::ZeroAccessor(const Value&) @@ -156,3 +169,8 @@ Value Table::EmptyDictionaryAccessor(const Value&) { return new Dictionary(); } + +LivestatusGroupByType Table::GetGroupByType(void) const +{ + return m_GroupByType; +} diff --git a/lib/livestatus/table.hpp b/lib/livestatus/table.hpp index fb348e18c..e27ed0201 100644 --- a/lib/livestatus/table.hpp +++ b/lib/livestatus/table.hpp @@ -23,12 +23,20 @@ #include "livestatus/column.hpp" #include "base/object.hpp" #include "base/dictionary.hpp" +#include "base/array.hpp" #include namespace icinga { -typedef boost::function AddRowFunction; +struct LivestatusRowValue { + Value Row; + LivestatusGroupByType GroupByType; + Value GroupByObject; +}; + + +typedef boost::function AddRowFunction; class Filter; @@ -45,14 +53,16 @@ public: virtual String GetName(void) const = 0; virtual String GetPrefix(void) const = 0; - std::vector FilterRows(const intrusive_ptr& filter); + std::vector FilterRows(const intrusive_ptr& filter); void AddColumn(const String& name, const Column& column); Column GetColumn(const String& name) const; std::vector GetColumnNames(void) const; + virtual LivestatusGroupByType GetGroupByType(void) const; + protected: - Table(void); + Table(LivestatusGroupByType type = LivestatusGroupByNone); virtual void FetchRows(const AddRowFunction& addRowFn) = 0; @@ -62,10 +72,13 @@ protected: static Value EmptyArrayAccessor(const Value&); static Value EmptyDictionaryAccessor(const Value&); + LivestatusGroupByType m_GroupByType; + Value m_GroupByObject; + private: std::map m_Columns; - void FilteredAddRow(std::vector& rs, const intrusive_ptr& filter, const Value& row); + void FilteredAddRow(std::vector& rs, const intrusive_ptr& filter, const Value& row, LivestatusGroupByType groupByType, const Object::Ptr& groupByObject); }; } diff --git a/lib/livestatus/timeperiodstable.cpp b/lib/livestatus/timeperiodstable.cpp index 479a07086..66de70bb2 100644 --- a/lib/livestatus/timeperiodstable.cpp +++ b/lib/livestatus/timeperiodstable.cpp @@ -55,7 +55,7 @@ String TimePeriodsTable::GetPrefix(void) const void TimePeriodsTable::FetchRows(const AddRowFunction& addRowFn) { BOOST_FOREACH(const TimePeriod::Ptr& tp, DynamicType::GetObjectsByType()) { - addRowFn(tp); + addRowFn(tp, LivestatusGroupByNone, Empty); } } @@ -73,5 +73,3 @@ Value TimePeriodsTable::InAccessor(const Value& row) { return (static_cast(row)->IsInside(Utility::GetTime()) ? 1 : 0); } - - diff --git a/test/livestatus/queries/command/command b/test/livestatus/queries/commands/command similarity index 100% rename from test/livestatus/queries/command/command rename to test/livestatus/queries/commands/command diff --git a/test/livestatus/queries/command/modattr b/test/livestatus/queries/commands/modattr similarity index 100% rename from test/livestatus/queries/command/modattr rename to test/livestatus/queries/commands/modattr diff --git a/test/livestatus/queries/comment/comment b/test/livestatus/queries/comments/comment similarity index 100% rename from test/livestatus/queries/comment/comment rename to test/livestatus/queries/comments/comment diff --git a/test/livestatus/queries/comment/comment_short b/test/livestatus/queries/comments/comment_short similarity index 100% rename from test/livestatus/queries/comment/comment_short rename to test/livestatus/queries/comments/comment_short diff --git a/test/livestatus/queries/contact/contacts b/test/livestatus/queries/contacts/contacts similarity index 100% rename from test/livestatus/queries/contact/contacts rename to test/livestatus/queries/contacts/contacts diff --git a/test/livestatus/queries/contact/group b/test/livestatus/queries/contacts/group similarity index 100% rename from test/livestatus/queries/contact/group rename to test/livestatus/queries/contacts/group diff --git a/test/livestatus/queries/contact/modattr b/test/livestatus/queries/contacts/modattr similarity index 100% rename from test/livestatus/queries/contact/modattr rename to test/livestatus/queries/contacts/modattr diff --git a/test/livestatus/queries/downtime/downtime b/test/livestatus/queries/downtimes/downtime similarity index 100% rename from test/livestatus/queries/downtime/downtime rename to test/livestatus/queries/downtimes/downtime diff --git a/test/livestatus/queries/downtime/downtime_short b/test/livestatus/queries/downtimes/downtime_short similarity index 100% rename from test/livestatus/queries/downtime/downtime_short rename to test/livestatus/queries/downtimes/downtime_short diff --git a/test/livestatus/queries/hosts/bygroup b/test/livestatus/queries/hosts/bygroup new file mode 100644 index 000000000..7485efc35 --- /dev/null +++ b/test/livestatus/queries/hosts/bygroup @@ -0,0 +1,4 @@ +GET hostsbygroup +Columns: hostgroup_name host_name +ResponseHeader: fixed16 + diff --git a/test/livestatus/queries/host/check b/test/livestatus/queries/hosts/check similarity index 100% rename from test/livestatus/queries/host/check rename to test/livestatus/queries/hosts/check diff --git a/test/livestatus/queries/host/command b/test/livestatus/queries/hosts/command similarity index 100% rename from test/livestatus/queries/host/command rename to test/livestatus/queries/hosts/command diff --git a/test/livestatus/queries/host/comment b/test/livestatus/queries/hosts/comment similarity index 100% rename from test/livestatus/queries/host/comment rename to test/livestatus/queries/hosts/comment diff --git a/test/livestatus/queries/host/contact b/test/livestatus/queries/hosts/contact similarity index 100% rename from test/livestatus/queries/host/contact rename to test/livestatus/queries/hosts/contact diff --git a/test/livestatus/queries/host/customvar b/test/livestatus/queries/hosts/customvar similarity index 100% rename from test/livestatus/queries/host/customvar rename to test/livestatus/queries/hosts/customvar diff --git a/test/livestatus/queries/host/downtime b/test/livestatus/queries/hosts/downtime similarity index 100% rename from test/livestatus/queries/host/downtime rename to test/livestatus/queries/hosts/downtime diff --git a/test/livestatus/queries/host/extra b/test/livestatus/queries/hosts/extra similarity index 100% rename from test/livestatus/queries/host/extra rename to test/livestatus/queries/hosts/extra diff --git a/test/livestatus/queries/host/group b/test/livestatus/queries/hosts/group similarity index 100% rename from test/livestatus/queries/host/group rename to test/livestatus/queries/hosts/group diff --git a/test/livestatus/queries/host/host b/test/livestatus/queries/hosts/host similarity index 100% rename from test/livestatus/queries/host/host rename to test/livestatus/queries/hosts/host diff --git a/test/livestatus/queries/host/host_nagvis b/test/livestatus/queries/hosts/host_nagvis similarity index 100% rename from test/livestatus/queries/host/host_nagvis rename to test/livestatus/queries/hosts/host_nagvis diff --git a/test/livestatus/queries/host/legacy b/test/livestatus/queries/hosts/legacy similarity index 100% rename from test/livestatus/queries/host/legacy rename to test/livestatus/queries/hosts/legacy diff --git a/test/livestatus/queries/host/modattr b/test/livestatus/queries/hosts/modattr similarity index 100% rename from test/livestatus/queries/host/modattr rename to test/livestatus/queries/hosts/modattr diff --git a/test/livestatus/queries/host/notification b/test/livestatus/queries/hosts/notification similarity index 100% rename from test/livestatus/queries/host/notification rename to test/livestatus/queries/hosts/notification diff --git a/test/livestatus/queries/host/services b/test/livestatus/queries/hosts/services similarity index 100% rename from test/livestatus/queries/host/services rename to test/livestatus/queries/hosts/services diff --git a/test/livestatus/queries/host/state b/test/livestatus/queries/hosts/state similarity index 100% rename from test/livestatus/queries/host/state rename to test/livestatus/queries/hosts/state diff --git a/test/livestatus/queries/host/stats_sum b/test/livestatus/queries/hosts/stats_sum similarity index 100% rename from test/livestatus/queries/host/stats_sum rename to test/livestatus/queries/hosts/stats_sum diff --git a/test/livestatus/queries/services/bygroup b/test/livestatus/queries/services/bygroup new file mode 100644 index 000000000..668e5f170 --- /dev/null +++ b/test/livestatus/queries/services/bygroup @@ -0,0 +1,4 @@ +GET servicesbygroup +Columns: servicegroup_name host_name service_description +ResponseHeader: fixed16 + diff --git a/test/livestatus/queries/services/byhostgroup b/test/livestatus/queries/services/byhostgroup new file mode 100644 index 000000000..ddcdbe8aa --- /dev/null +++ b/test/livestatus/queries/services/byhostgroup @@ -0,0 +1,4 @@ +GET servicesbyhostgroup +Columns: hostgroup_name host_name service_description +ResponseHeader: fixed16 + diff --git a/test/livestatus/queries/service/check b/test/livestatus/queries/services/check similarity index 100% rename from test/livestatus/queries/service/check rename to test/livestatus/queries/services/check diff --git a/test/livestatus/queries/service/command b/test/livestatus/queries/services/command similarity index 100% rename from test/livestatus/queries/service/command rename to test/livestatus/queries/services/command diff --git a/test/livestatus/queries/service/comment b/test/livestatus/queries/services/comment similarity index 100% rename from test/livestatus/queries/service/comment rename to test/livestatus/queries/services/comment diff --git a/test/livestatus/queries/service/contact b/test/livestatus/queries/services/contact similarity index 100% rename from test/livestatus/queries/service/contact rename to test/livestatus/queries/services/contact diff --git a/test/livestatus/queries/service/customvar b/test/livestatus/queries/services/customvar similarity index 100% rename from test/livestatus/queries/service/customvar rename to test/livestatus/queries/services/customvar diff --git a/test/livestatus/queries/service/downtime b/test/livestatus/queries/services/downtime similarity index 100% rename from test/livestatus/queries/service/downtime rename to test/livestatus/queries/services/downtime diff --git a/test/livestatus/queries/service/extra b/test/livestatus/queries/services/extra similarity index 100% rename from test/livestatus/queries/service/extra rename to test/livestatus/queries/services/extra diff --git a/test/livestatus/queries/service/group b/test/livestatus/queries/services/group similarity index 100% rename from test/livestatus/queries/service/group rename to test/livestatus/queries/services/group diff --git a/test/livestatus/queries/service/legacy b/test/livestatus/queries/services/legacy similarity index 100% rename from test/livestatus/queries/service/legacy rename to test/livestatus/queries/services/legacy diff --git a/test/livestatus/queries/service/modattr b/test/livestatus/queries/services/modattr similarity index 100% rename from test/livestatus/queries/service/modattr rename to test/livestatus/queries/services/modattr diff --git a/test/livestatus/queries/service/notification b/test/livestatus/queries/services/notification similarity index 100% rename from test/livestatus/queries/service/notification rename to test/livestatus/queries/services/notification diff --git a/test/livestatus/queries/service/services b/test/livestatus/queries/services/services similarity index 100% rename from test/livestatus/queries/service/services rename to test/livestatus/queries/services/services diff --git a/test/livestatus/queries/service/state b/test/livestatus/queries/services/state similarity index 100% rename from test/livestatus/queries/service/state rename to test/livestatus/queries/services/state diff --git a/test/livestatus/queries/timeperiod/timeperiod b/test/livestatus/queries/timeperiods/timeperiod similarity index 100% rename from test/livestatus/queries/timeperiod/timeperiod rename to test/livestatus/queries/timeperiods/timeperiod