diff --git a/components/livestatus/Makefile.am b/components/livestatus/Makefile.am index 97b7acb11..a2c7bee49 100644 --- a/components/livestatus/Makefile.am +++ b/components/livestatus/Makefile.am @@ -6,6 +6,8 @@ pkglib_LTLIBRARIES = \ livestatus_la_SOURCES = \ andfilter.cpp \ andfilter.h \ + column.cpp \ + column.h \ combinerfilter.cpp \ combinerfilter.h \ component.cpp \ diff --git a/components/livestatus/attributefilter.cpp b/components/livestatus/attributefilter.cpp index cc6e93d60..d3eaf4bab 100644 --- a/components/livestatus/attributefilter.cpp +++ b/components/livestatus/attributefilter.cpp @@ -28,12 +28,9 @@ AttributeFilter::AttributeFilter(const String& column, const String& op, const S bool AttributeFilter::Apply(const Table::Ptr& table, const Object::Ptr& object) { - Table::ColumnAccessor accessor = table->GetColumn(m_Column); + Column column = table->GetColumn(m_Column); - if (accessor.empty()) - BOOST_THROW_EXCEPTION(invalid_argument("Filter expression uses unknown column '" + m_Column + "'")); - - Value value = accessor(object); + Value value = column.ExtractValue(object); if (value.IsObjectType()) { if (m_Operator == ">=") { diff --git a/components/livestatus/column.cpp b/components/livestatus/column.cpp new file mode 100644 index 000000000..2de70cead --- /dev/null +++ b/components/livestatus/column.cpp @@ -0,0 +1,39 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software Foundation * + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * + ******************************************************************************/ + +#include "i2-livestatus.h" + +using namespace icinga; +using namespace livestatus; + +Column::Column(const ValueAccessor& valueAccessor, const ObjectAccessor& objectAccessor) + : m_ValueAccessor(valueAccessor), m_ObjectAccessor(objectAccessor) +{ } + +Value Column::ExtractValue(const Object::Ptr& uobject) const +{ + Object::Ptr object; + + if (!m_ObjectAccessor.empty()) + object = m_ObjectAccessor(uobject); + else + object = uobject; + + return m_ValueAccessor(object); +} diff --git a/components/livestatus/column.h b/components/livestatus/column.h new file mode 100644 index 000000000..2f226322a --- /dev/null +++ b/components/livestatus/column.h @@ -0,0 +1,43 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software Foundation * + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * + ******************************************************************************/ + +#ifndef COLUMN_H +#define COLUMN_H + +namespace livestatus +{ + +class Column +{ +public: + typedef function ValueAccessor; + typedef function ObjectAccessor; + + Column(const ValueAccessor& valueAccessor, const ObjectAccessor& objectAccessor); + + Value ExtractValue(const Object::Ptr& uobject) const; + +private: + ValueAccessor m_ValueAccessor; + ObjectAccessor m_ObjectAccessor; +}; + +} + +#endif /* COLUMN_H */ diff --git a/components/livestatus/contactgroupstable.cpp b/components/livestatus/contactgroupstable.cpp index 6db954375..3b9f8a98f 100644 --- a/components/livestatus/contactgroupstable.cpp +++ b/components/livestatus/contactgroupstable.cpp @@ -24,9 +24,15 @@ using namespace livestatus; ContactGroupsTable::ContactGroupsTable(void) { - AddColumn("name", &ContactGroupsTable::NameAccessor); - AddColumn("alias", &ContactGroupsTable::NameAccessor); - AddColumn("members", &ContactGroupsTable::MembersAccessor); + AddColumns(this); +} + +void ContactGroupsTable::AddColumns(Table *table, const String& prefix, + const Column::ObjectAccessor& objectAccessor) +{ + table->AddColumn(prefix + "name", Column(&ContactGroupsTable::NameAccessor, objectAccessor)); + table->AddColumn(prefix + "alias", Column(&ContactGroupsTable::NameAccessor, objectAccessor)); + table->AddColumn(prefix + "members", Column(&ContactGroupsTable::MembersAccessor, objectAccessor)); } String ContactGroupsTable::GetName(void) const diff --git a/components/livestatus/contactgroupstable.h b/components/livestatus/contactgroupstable.h index 94c353f65..c5431d5ae 100644 --- a/components/livestatus/contactgroupstable.h +++ b/components/livestatus/contactgroupstable.h @@ -34,6 +34,9 @@ public: ContactGroupsTable(void); + static void AddColumns(Table *table, const String& prefix = String(), + const Column::ObjectAccessor& objectAccessor = Column::ObjectAccessor()); + virtual String GetName(void) const; protected: diff --git a/components/livestatus/contactstable.cpp b/components/livestatus/contactstable.cpp index ebc216d8f..a0a81fbf9 100644 --- a/components/livestatus/contactstable.cpp +++ b/components/livestatus/contactstable.cpp @@ -24,22 +24,28 @@ using namespace livestatus; ContactsTable::ContactsTable(void) { - AddColumn("name", &ContactsTable::NameAccessor); - AddColumn("alias", &ContactsTable::NameAccessor); - AddColumn("email", &Table::EmptyStringAccessor); - AddColumn("pager", &Table::EmptyStringAccessor); - AddColumn("host_notification_period", &Table::EmptyStringAccessor); - AddColumn("service_notification_period", &Table::EmptyStringAccessor); - AddColumn("can_submit_commands", &Table::OneAccessor); - AddColumn("host_notifications_enabled", &Table::OneAccessor); - AddColumn("service_notifications_enabled", &Table::OneAccessor); - AddColumn("in_host_notification_period", &Table::OneAccessor); - AddColumn("in_service_notification_period", &Table::OneAccessor); - AddColumn("custom_variable_names", &Table::EmptyArrayAccessor); - AddColumn("custom_variable_values", &Table::EmptyArrayAccessor); - AddColumn("custom_variables", &Table::EmptyDictionaryAccessor); - AddColumn("modified_attributes", &Table::ZeroAccessor); - AddColumn("modified_attributes_list", &Table::EmptyArrayAccessor); + AddColumns(this); +} + +void ContactsTable::AddColumns(Table *table, const String& prefix, + const Column::ObjectAccessor& objectAccessor) +{ + table->AddColumn(prefix + "name", Column(&ContactsTable::NameAccessor, objectAccessor)); + table->AddColumn(prefix + "alias", Column(&ContactsTable::NameAccessor, objectAccessor)); + table->AddColumn(prefix + "email", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "pager", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "host_notification_period", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "service_notification_period", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "can_submit_commands", Column(&Table::OneAccessor, objectAccessor)); + table->AddColumn(prefix + "host_notifications_enabled", Column(&Table::OneAccessor, objectAccessor)); + table->AddColumn(prefix + "service_notifications_enabled", Column(&Table::OneAccessor, objectAccessor)); + table->AddColumn(prefix + "in_host_notification_period", Column(&Table::OneAccessor, objectAccessor)); + table->AddColumn(prefix + "in_service_notification_period", Column(&Table::OneAccessor, objectAccessor)); + table->AddColumn(prefix + "custom_variable_names", Column(&Table::EmptyArrayAccessor, objectAccessor)); + table->AddColumn(prefix + "custom_variable_values", Column(&Table::EmptyArrayAccessor, objectAccessor)); + table->AddColumn(prefix + "custom_variables", Column(&Table::EmptyDictionaryAccessor, objectAccessor)); + table->AddColumn(prefix + "modified_attributes", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "modified_attributes_list", Column(&Table::EmptyArrayAccessor, objectAccessor)); } String ContactsTable::GetName(void) const diff --git a/components/livestatus/contactstable.h b/components/livestatus/contactstable.h index 6efe2d536..246127d7b 100644 --- a/components/livestatus/contactstable.h +++ b/components/livestatus/contactstable.h @@ -29,11 +29,14 @@ namespace livestatus class ContactsTable : public Table { public: - typedef shared_ptr Ptr; - typedef weak_ptr WeakPtr; + typedef shared_ptr Ptr; + typedef weak_ptr WeakPtr; ContactsTable(void); + static void AddColumns(Table *table, const String& prefix = String(), + const Column::ObjectAccessor& objectAccessor = Column::ObjectAccessor()); + virtual String GetName(void) const; protected: diff --git a/components/livestatus/hoststable.cpp b/components/livestatus/hoststable.cpp new file mode 100644 index 000000000..32de6681e --- /dev/null +++ b/components/livestatus/hoststable.cpp @@ -0,0 +1,163 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software Foundation * + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * + ******************************************************************************/ + +#include "i2-livestatus.h" + +using namespace icinga; +using namespace livestatus; + +HostsTable::HostsTable(void) +{ + AddColumns(this); +} + +void HostsTable::AddColumns(Table *table, const String& prefix, + const Column::ObjectAccessor& objectAccessor) +{ + table->AddColumn(prefix + "name", Column(&HostsTable::NameAccessor, objectAccessor)); + table->AddColumn(prefix + "display_name", Column(&HostsTable::DisplayNameAccessor, objectAccessor)); + table->AddColumn(prefix + "alias", Column(&HostsTable::NameAccessor, objectAccessor)); + table->AddColumn(prefix + "address", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "check_command", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "check_command_expanded", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "event_handler", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "notification_period", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "check_period", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "notes", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "notes_expanded", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "notes_url", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "notes_url_expanded", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "action_url", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "action_url_expanded", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "plugin_output", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "perf_data", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "icon_image", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "icon_image_expanded", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "icon_image_alt", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "statusmap_image", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "long_plugin_output", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "initial_state", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "max_check_attempts", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "flap_detection_enabled", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "check_freshness", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "process_performance_data", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "accept_passive_checks", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "event_handler_enabled", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "acknowledgement_type", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "check_type", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "last_state", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "last_hard_state", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "current_attempt", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "last_notification", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "next_notification", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "next_check", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "last_hard_state_change", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "has_been_checked", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "current_notification_number", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "pending_flex_downtime", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "total_services", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "checks_enabled", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "notifications_enabled", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "acknowledged", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "state", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "state_type", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "no_more_notifications", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "check_flapping_recovery_notification", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "last_check", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "last_state_change", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "last_time_up", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "last_time_down", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "last_time_unreachable", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "is_flapping", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "scheduled_downtime_depth", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "is_executing", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "active_checks_enabled", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "check_options", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "obsess_over_host", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "modified_attributes", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "modified_attributes_list", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "check_interval", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "retry_interval", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "notification_interval", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "first_notification_delay", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "low_flap_threshold", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "high_flap_threshold", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "x_3d", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "y_3d", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "z_3d", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "latency", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "execution_time", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "percent_state_change", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "in_notification_period", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "in_check_period", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "contacts", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "downtimes", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "downtimes_with_info", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "comments", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "comments_with_info", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "comments_with_extra_info", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "custom_variable_names", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "custom_variable_values", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "custom_variables", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "filename", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "parents", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "childs", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "num_services", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "worst_service_state", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "num_services_ok", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "num_services_warn", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "num_services_crit", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "num_services_unknown", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "num_services_pending", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "worst_service_hard_state", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "num_services_hard_ok", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "num_services_hard_warn", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "num_services_hard_crit", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "num_services_hard_unknown", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "hard_state", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "pnpgraph_present", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "groups", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "contact_groups", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "services", Column(&Table::EmptyStringAccessor, objectAccessor)); + table->AddColumn(prefix + "services_with_state", Column(&Table::EmptyDictionaryAccessor, objectAccessor)); + table->AddColumn(prefix + "services_with_info", Column(&Table::EmptyDictionaryAccessor, objectAccessor)); + table->AddColumn(prefix + "groups", Column(&Table::EmptyArrayAccessor, objectAccessor)); +} + +String HostsTable::GetName(void) const +{ + return "hosts"; +} + +void HostsTable::FetchRows(const function& addRowFn) +{ + BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Host")) { + addRowFn(object); + } +} + +Value HostsTable::NameAccessor(const Object::Ptr& object) +{ + return static_pointer_cast(object)->GetName(); +} + +Value HostsTable::DisplayNameAccessor(const Object::Ptr& object) +{ + return static_pointer_cast(object)->GetDisplayName(); +} diff --git a/components/livestatus/hoststable.h b/components/livestatus/hoststable.h new file mode 100644 index 000000000..bf6ecc01e --- /dev/null +++ b/components/livestatus/hoststable.h @@ -0,0 +1,51 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software Foundation * + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * + ******************************************************************************/ + +#ifndef HOSTSTABLE_H +#define HOSTSTABLE_H + +namespace livestatus +{ + +/** + * @ingroup livestatus + */ +class HostsTable : public Table +{ +public: + typedef shared_ptr Ptr; + typedef weak_ptr WeakPtr; + + HostsTable(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 function& addRowFn); + + static Value NameAccessor(const Object::Ptr& object); + static Value DisplayNameAccessor(const Object::Ptr& object); +}; + +} + +#endif /* HOSTSTABLE_H */ diff --git a/components/livestatus/i2-livestatus.h b/components/livestatus/i2-livestatus.h index 4c7a2fdb6..b44772076 100644 --- a/components/livestatus/i2-livestatus.h +++ b/components/livestatus/i2-livestatus.h @@ -33,6 +33,7 @@ using namespace icinga; #include "connection.h" +#include "column.h" #include "table.h" #include "filter.h" #include "combinerfilter.h" @@ -44,6 +45,7 @@ using namespace icinga; #include "statustable.h" #include "contactgroupstable.h" #include "contactstable.h" +#include "hoststable.h" #include "component.h" #endif /* I2LIVESTATUS_H */ diff --git a/components/livestatus/livestatus.vcxproj b/components/livestatus/livestatus.vcxproj index 2e6c91f97..63878266e 100644 --- a/components/livestatus/livestatus.vcxproj +++ b/components/livestatus/livestatus.vcxproj @@ -21,10 +21,12 @@ + + @@ -37,12 +39,14 @@ + + diff --git a/components/livestatus/livestatus.vcxproj.filters b/components/livestatus/livestatus.vcxproj.filters index 69c5274ca..a4cd2e691 100644 --- a/components/livestatus/livestatus.vcxproj.filters +++ b/components/livestatus/livestatus.vcxproj.filters @@ -51,6 +51,12 @@ Headerdateien + + Headerdateien + + + Headerdateien + @@ -92,5 +98,11 @@ Quelldateien + + Quelldateien + + + Quelldateien + \ No newline at end of file diff --git a/components/livestatus/query.cpp b/components/livestatus/query.cpp index 38762468a..5ebe405bd 100644 --- a/components/livestatus/query.cpp +++ b/components/livestatus/query.cpp @@ -68,6 +68,9 @@ Query::Query(const vector& lines) else if (header == "Filter" || header == "Stats") { vector tokens = params.Split(is_any_of(" ")); + if (tokens.size() == 2) + tokens.push_back(""); + if (tokens.size() < 3) { m_Verb = "ERROR"; m_ErrorCode = 452; @@ -217,16 +220,10 @@ void Query::ExecuteGetHelper(const Stream::Ptr& stream) BOOST_FOREACH(const Object::Ptr& object, objects) { Array::Ptr row = boost::make_shared(); - BOOST_FOREACH(const String& column, columns) { - Table::ColumnAccessor accessor = table->GetColumn(column); + BOOST_FOREACH(const String& columnName, columns) { + Column column = table->GetColumn(columnName); - if (accessor.empty()) { - SendResponse(stream, 450, "Column '" + column + "' does not exist."); - - return; - } - - row->Add(accessor(object)); + row->Add(column.ExtractValue(object)); } rs->Add(row); diff --git a/components/livestatus/statustable.cpp b/components/livestatus/statustable.cpp index 41cdc9a2a..b4e212bd0 100644 --- a/components/livestatus/statustable.cpp +++ b/components/livestatus/statustable.cpp @@ -24,65 +24,71 @@ using namespace livestatus; StatusTable::StatusTable(void) { - AddColumn("neb_callbacks", &Table::ZeroAccessor); - AddColumn("neb_callbacks_rate", &Table::ZeroAccessor); + AddColumns(this); +} - AddColumn("requests", &Table::ZeroAccessor); - AddColumn("requests_rate", &Table::ZeroAccessor); +void StatusTable::AddColumns(Table *table, const String& prefix, + const Column::ObjectAccessor& objectAccessor) +{ + table->AddColumn(prefix + "neb_callbacks", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "neb_callbacks_rate", Column(&Table::ZeroAccessor, objectAccessor)); - AddColumn("connections", &Table::ZeroAccessor); - AddColumn("connections_rate", &Table::ZeroAccessor); + table->AddColumn(prefix + "requests", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "requests_rate", Column(&Table::ZeroAccessor, objectAccessor)); - AddColumn("service_checks", &Table::ZeroAccessor); - AddColumn("service_checks_rate", &Table::ZeroAccessor); + table->AddColumn(prefix + "connections", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "connections_rate", Column(&Table::ZeroAccessor, objectAccessor)); - AddColumn("host_checks", &Table::ZeroAccessor); - AddColumn("host_checks_rate", &Table::ZeroAccessor); + table->AddColumn(prefix + "service_checks", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "service_checks_rate", Column(&Table::ZeroAccessor, objectAccessor)); - AddColumn("forks", &Table::ZeroAccessor); - AddColumn("forks_rate", &Table::ZeroAccessor); + table->AddColumn(prefix + "host_checks", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "host_checks_rate", Column(&Table::ZeroAccessor, objectAccessor)); - AddColumn("log_messages", &Table::ZeroAccessor); - AddColumn("log_messages_rate", &Table::ZeroAccessor); + table->AddColumn(prefix + "forks", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "forks_rate", Column(&Table::ZeroAccessor, objectAccessor)); - AddColumn("external_commands", &Table::ZeroAccessor); - AddColumn("external_commands_rate", &Table::ZeroAccessor); + table->AddColumn(prefix + "log_messages", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "log_messages_rate", Column(&Table::ZeroAccessor, objectAccessor)); - AddColumn("livechecks", &Table::ZeroAccessor); - AddColumn("livechecks_rate", &Table::ZeroAccessor); + table->AddColumn(prefix + "external_commands", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "external_commands_rate", Column(&Table::ZeroAccessor, objectAccessor)); - AddColumn("livecheck_overflows", &Table::ZeroAccessor); - AddColumn("livecheck_overflows_rate", &Table::ZeroAccessor); + table->AddColumn(prefix + "livechecks", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "livechecks_rate", Column(&Table::ZeroAccessor, objectAccessor)); - AddColumn("nagios_pid", &Table::ZeroAccessor); - AddColumn("enable_notifications", &Table::ZeroAccessor); - AddColumn("execute_service_checks", &Table::ZeroAccessor); - AddColumn("accept_passive_service_checks", &Table::ZeroAccessor); - AddColumn("execute_host_checks", &Table::ZeroAccessor); - AddColumn("accept_passive_host_checks", &Table::ZeroAccessor); - AddColumn("enable_event_handlers", &Table::ZeroAccessor); - AddColumn("obsess_over_services", &Table::ZeroAccessor); - AddColumn("obsess_over_hosts", &Table::ZeroAccessor); - AddColumn("check_service_freshness", &Table::ZeroAccessor); - AddColumn("check_host_freshness", &Table::ZeroAccessor); - AddColumn("enable_flap_detection", &Table::ZeroAccessor); - AddColumn("process_performance_data", &Table::ZeroAccessor); - AddColumn("check_external_commands", &Table::ZeroAccessor); - AddColumn("program_start", &Table::ZeroAccessor); - AddColumn("last_command_check", &Table::ZeroAccessor); - AddColumn("last_log_rotation", &Table::ZeroAccessor); - AddColumn("interval_length", &Table::ZeroAccessor); - AddColumn("num_hosts", &Table::ZeroAccessor); - AddColumn("num_services", &Table::ZeroAccessor); - AddColumn("program_version", &Table::ZeroAccessor); - AddColumn("external_command_buffer_slots", &Table::ZeroAccessor); - AddColumn("external_command_buffer_usage", &Table::ZeroAccessor); - AddColumn("external_command_buffer_max", &Table::ZeroAccessor); - AddColumn("cached_log_messages", &Table::ZeroAccessor); - AddColumn("livestatus_version", &Table::ZeroAccessor); - AddColumn("livestatus_active_connections", &Table::ZeroAccessor); - AddColumn("livestatus_queued_connections", &Table::ZeroAccessor); - AddColumn("livestatus_threads", &Table::ZeroAccessor); + table->AddColumn(prefix + "livecheck_overflows", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "livecheck_overflows_rate", Column(&Table::ZeroAccessor, objectAccessor)); + + table->AddColumn(prefix + "nagios_pid", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "enable_notifications", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "execute_service_checks", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "accept_passive_service_checks", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "execute_host_checks", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "accept_passive_host_checks", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "enable_event_handlers", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "obsess_over_services", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "obsess_over_hosts", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "check_service_freshness", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "check_host_freshness", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "enable_flap_detection", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "process_performance_data", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "check_external_commands", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "program_start", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "last_command_check", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "last_log_rotation", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "interval_length", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "num_hosts", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "num_services", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "program_version", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "external_command_buffer_slots", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "external_command_buffer_usage", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "external_command_buffer_max", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "cached_log_messages", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "livestatus_version", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "livestatus_active_connections", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "livestatus_queued_connections", Column(&Table::ZeroAccessor, objectAccessor)); + table->AddColumn(prefix + "livestatus_threads", Column(&Table::ZeroAccessor, objectAccessor)); } String StatusTable::GetName(void) const diff --git a/components/livestatus/statustable.h b/components/livestatus/statustable.h index 5da540064..971d2d5c0 100644 --- a/components/livestatus/statustable.h +++ b/components/livestatus/statustable.h @@ -34,6 +34,9 @@ public: StatusTable(void); + static void AddColumns(Table *table, const String& prefix = String(), + const Column::ObjectAccessor& objectAccessor = Column::ObjectAccessor()); + virtual String GetName(void) const; protected: diff --git a/components/livestatus/table.cpp b/components/livestatus/table.cpp index 6fd00ab9e..9cb48a882 100644 --- a/components/livestatus/table.cpp +++ b/components/livestatus/table.cpp @@ -33,21 +33,28 @@ Table::Ptr Table::GetByName(const String& name) return boost::make_shared(); else if (name == "contacts") return boost::make_shared(); + else if (name == "hosts") + return boost::make_shared(); return Table::Ptr(); } -void Table::AddColumn(const String& name, const ColumnAccessor& accessor) +void Table::AddColumn(const String& name, const Column& column) { - m_Columns[name] = accessor; + pair item = make_pair(name, column); + + pair::iterator, bool> ret = m_Columns.insert(item); + + if (!ret.second) + ret.first->second = column; } -Table::ColumnAccessor Table::GetColumn(const String& name) const +Column Table::GetColumn(const String& name) const { - map::const_iterator it = m_Columns.find(name); + map::const_iterator it = m_Columns.find(name); if (it == m_Columns.end()) - return ColumnAccessor(); + BOOST_THROW_EXCEPTION(invalid_argument("Column '" + name + "' does not exist.")); return it->second; } diff --git a/components/livestatus/table.h b/components/livestatus/table.h index 3f7b0cca7..d5813fd11 100644 --- a/components/livestatus/table.h +++ b/components/livestatus/table.h @@ -36,20 +36,18 @@ public: static Table::Ptr GetByName(const String& name); - typedef function ColumnAccessor; virtual String GetName(void) const = 0; vector FilterRows(const shared_ptr& filter); - ColumnAccessor GetColumn(const String& name) const; + void AddColumn(const String& name, const Column& column); + Column GetColumn(const String& name) const; vector GetColumnNames(void) const; protected: Table(void); - void AddColumn(const String& name, const ColumnAccessor& accessor); - virtual void FetchRows(const function& addRowFn) = 0; static Value ZeroAccessor(const Object::Ptr&); @@ -59,7 +57,7 @@ protected: static Value EmptyDictionaryAccessor(const Object::Ptr&); private: - map m_Columns; + map m_Columns; void FilteredAddRow(vector& rs, const shared_ptr& filter, const Object::Ptr& object); };