Livestatus: Add GroupBy tables: hostsbygroup, servicesbygroup, servicesbyhostgroup

fixes #7361

Signed-off-by: Michael Friedrich <michael.friedrich@gmail.com>
This commit is contained in:
Michael Friedrich 2015-02-13 15:50:20 +01:00
parent 7f368c0e18
commit 70c750250c
63 changed files with 199 additions and 61 deletions

View File

@ -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;

View File

@ -28,15 +28,21 @@ using namespace icinga;
namespace icinga
{
enum LivestatusGroupByType {
LivestatusGroupByNone,
LivestatusGroupByHostGroup,
LivestatusGroupByServiceGroup
};
class Column
{
public:
typedef boost::function<Value (const Value&)> ValueAccessor;
typedef boost::function<Value (const Value&)> ObjectAccessor;
typedef boost::function<Value (const Value&, LivestatusGroupByType, const Object::Ptr&)> 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;

View File

@ -61,27 +61,27 @@ String CommandsTable::GetPrefix(void) const
void CommandsTable::FetchRows(const AddRowFunction& addRowFn)
{
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjectsByType<CheckCommand>()) {
addRowFn(object);
addRowFn(object, LivestatusGroupByNone, Empty);
}
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjectsByType<EventCommand>()) {
addRowFn(object);
addRowFn(object, LivestatusGroupByNone, Empty);
}
BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjectsByType<NotificationCommand>()) {
addRowFn(object);
addRowFn(object, LivestatusGroupByNone, Empty);
}
}
Value CommandsTable::NameAccessor(const Value& row)
{
Command::Ptr command = static_cast<Command::Ptr>(row);
return CompatUtility::GetCommandName(command);
}
Value CommandsTable::LineAccessor(const Value& row)
{
Command::Ptr command = static_cast<Command::Ptr>(row);
if (!command)
return Empty;

View File

@ -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);
}
}
}

View File

@ -50,7 +50,7 @@ String ContactGroupsTable::GetPrefix(void) const
void ContactGroupsTable::FetchRows(const AddRowFunction& addRowFn)
{
BOOST_FOREACH(const UserGroup::Ptr& ug, DynamicType::GetObjectsByType<UserGroup>()) {
addRowFn(ug);
addRowFn(ug, LivestatusGroupByNone, Empty);
}
}

View File

@ -71,7 +71,7 @@ String ContactsTable::GetPrefix(void) const
void ContactsTable::FetchRows(const AddRowFunction& addRowFn)
{
BOOST_FOREACH(const User::Ptr& user, DynamicType::GetObjectsByType<User>()) {
addRowFn(user);
addRowFn(user, LivestatusGroupByNone, Empty);
}
}

View File

@ -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);
}
}
}

View File

@ -61,7 +61,7 @@ String EndpointsTable::GetPrefix(void) const
void EndpointsTable::FetchRows(const AddRowFunction& addRowFn)
{
BOOST_FOREACH(const Endpoint::Ptr& endpoint, DynamicType::GetObjectsByType<Endpoint>()) {
addRowFn(endpoint);
addRowFn(endpoint, LivestatusGroupByNone, Empty);
}
}
@ -110,6 +110,3 @@ Value EndpointsTable::IsConnectedAccessor(const Value& row)
return is_connected;
}

View File

@ -74,7 +74,7 @@ String HostGroupsTable::GetPrefix(void) const
void HostGroupsTable::FetchRows(const AddRowFunction& addRowFn)
{
BOOST_FOREACH(const HostGroup::Ptr& hg, DynamicType::GetObjectsByType<HostGroup>()) {
addRowFn(hg);
addRowFn(hg, LivestatusGroupByNone, Empty);
}
}

View File

@ -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 <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;
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<Host>()) {
addRowFn(host);
if (GetGroupByType() == LivestatusGroupByHostGroup) {
BOOST_FOREACH(const HostGroup::Ptr& hg, DynamicType::GetObjectsByType<HostGroup>()) {
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<Host>()) {
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<Host::Ptr>(row);
@ -208,7 +239,6 @@ Value HostsTable::AddressAccessor(const Value& row)
if (!host)
return Empty;
return host->GetAddress();
}

View File

@ -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);

View File

@ -495,7 +495,7 @@ void LivestatusQuery::ExecuteGetHelper(const Stream::Ptr& stream)
return;
}
std::vector<Value> objects = table->FilterRows(m_Filter);
std::vector<LivestatusRowValue> objects = table->FilterRows(m_Filter);
std::vector<String> 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));
}
}

View File

@ -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<Dictionary::Ptr>(row)->Get("command_name");
}

View File

@ -65,7 +65,7 @@ String ServiceGroupsTable::GetPrefix(void) const
void ServiceGroupsTable::FetchRows(const AddRowFunction& addRowFn)
{
BOOST_FOREACH(const ServiceGroup::Ptr& sg, DynamicType::GetObjectsByType<ServiceGroup>()) {
addRowFn(sg);
addRowFn(sg, LivestatusGroupByNone, Empty);
}
}

View File

@ -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<Service>()) {
addRowFn(service);
if (GetGroupByType() == LivestatusGroupByServiceGroup) {
BOOST_FOREACH(const ServiceGroup::Ptr& sg, DynamicType::GetObjectsByType<ServiceGroup>()) {
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<HostGroup>()) {
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<Service>()) {
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<Service::Ptr>(row);

View File

@ -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);

View File

@ -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);
}
}
}

View File

@ -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&)

View File

@ -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<String> Table::GetColumnNames(void) const
return names;
}
std::vector<Value> Table::FilterRows(const Filter::Ptr& filter)
std::vector<LivestatusRowValue> Table::FilterRows(const Filter::Ptr& filter)
{
std::vector<Value> rs;
std::vector<LivestatusRowValue> 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<Value>& rs, const Filter::Ptr& filter, const Value& row)
void Table::FilteredAddRow(std::vector<LivestatusRowValue>& 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;
}

View File

@ -23,12 +23,20 @@
#include "livestatus/column.hpp"
#include "base/object.hpp"
#include "base/dictionary.hpp"
#include "base/array.hpp"
#include <vector>
namespace icinga
{
typedef boost::function<void (const Value&)> AddRowFunction;
struct LivestatusRowValue {
Value Row;
LivestatusGroupByType GroupByType;
Value GroupByObject;
};
typedef boost::function<void (const Value&, LivestatusGroupByType, const Object::Ptr&)> AddRowFunction;
class Filter;
@ -45,14 +53,16 @@ public:
virtual String GetName(void) const = 0;
virtual String GetPrefix(void) const = 0;
std::vector<Value> FilterRows(const intrusive_ptr<Filter>& filter);
std::vector<LivestatusRowValue> FilterRows(const intrusive_ptr<Filter>& filter);
void AddColumn(const String& name, const Column& column);
Column GetColumn(const String& name) const;
std::vector<String> 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<String, Column> m_Columns;
void FilteredAddRow(std::vector<Value>& rs, const intrusive_ptr<Filter>& filter, const Value& row);
void FilteredAddRow(std::vector<LivestatusRowValue>& rs, const intrusive_ptr<Filter>& filter, const Value& row, LivestatusGroupByType groupByType, const Object::Ptr& groupByObject);
};
}

View File

@ -55,7 +55,7 @@ String TimePeriodsTable::GetPrefix(void) const
void TimePeriodsTable::FetchRows(const AddRowFunction& addRowFn)
{
BOOST_FOREACH(const TimePeriod::Ptr& tp, DynamicType::GetObjectsByType<TimePeriod>()) {
addRowFn(tp);
addRowFn(tp, LivestatusGroupByNone, Empty);
}
}
@ -73,5 +73,3 @@ Value TimePeriodsTable::InAccessor(const Value& row)
{
return (static_cast<TimePeriod::Ptr>(row)->IsInside(Utility::GetTime()) ? 1 : 0);
}

View File

@ -0,0 +1,4 @@
GET hostsbygroup
Columns: hostgroup_name host_name
ResponseHeader: fixed16

View File

@ -0,0 +1,4 @@
GET servicesbygroup
Columns: servicegroup_name host_name service_description
ResponseHeader: fixed16

View File

@ -0,0 +1,4 @@
GET servicesbyhostgroup
Columns: hostgroup_name host_name service_description
ResponseHeader: fixed16