From 36681bb55ac226bc871730df9882897ffe82cd24 Mon Sep 17 00:00:00 2001 From: Alexander Fuhr Date: Mon, 6 Oct 2014 11:30:48 +0200 Subject: [PATCH 1/4] Add new QueryException --- library/Icinga/Exception/QueryException.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 library/Icinga/Exception/QueryException.php diff --git a/library/Icinga/Exception/QueryException.php b/library/Icinga/Exception/QueryException.php new file mode 100644 index 000000000..beab3fe53 --- /dev/null +++ b/library/Icinga/Exception/QueryException.php @@ -0,0 +1,12 @@ + Date: Mon, 6 Oct 2014 11:32:15 +0200 Subject: [PATCH 2/4] Implement validation for filter and sort columns --- .../library/Monitoring/DataView/DataView.php | 44 +++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/modules/monitoring/library/Monitoring/DataView/DataView.php b/modules/monitoring/library/Monitoring/DataView/DataView.php index 2b91c1673..661412c43 100644 --- a/modules/monitoring/library/Monitoring/DataView/DataView.php +++ b/modules/monitoring/library/Monitoring/DataView/DataView.php @@ -6,12 +6,14 @@ namespace Icinga\Module\Monitoring\DataView; use Countable; use Icinga\Data\Filter\Filter; +use Icinga\Data\Filter\FilterMatch; use Icinga\Data\SimpleQuery; use Icinga\Data\Browsable; use Icinga\Data\PivotTable; use Icinga\Data\Sortable; use Icinga\Data\ConnectionInterface; use Icinga\Data\Filterable; +use Icinga\Exception\QueryException; use Icinga\Web\Request; use Icinga\Web\Url; use Icinga\Module\Monitoring\Backend; @@ -206,13 +208,13 @@ public function dump() if ($sortRules !== null) { if ($column === null) { $sortColumns = reset($sortRules); - if (!isset($sortColumns['columns'])) { + if (! isset($sortColumns['columns'])) { $sortColumns['columns'] = array(key($sortRules)); } } else { if (isset($sortRules[$column])) { $sortColumns = $sortRules[$column]; - if (!isset($sortColumns['columns'])) { + if (! isset($sortColumns['columns'])) { $sortColumns['columns'] = array($column); } } else { @@ -227,6 +229,13 @@ public function dump() $order = (strtoupper($order) === self::SORT_ASC) ? 'ASC' : 'DESC'; foreach ($sortColumns['columns'] as $column) { + if (! $this->isValidFilterTarget($column)) { + throw new QueryException( + t('The sort column "%s" is not allowed in "%s".'), + $column, + get_class($this) + ); + } $this->query->order($column, $order); } $this->isSorted = true; @@ -289,15 +298,44 @@ public function dump() */ public function getQuery() { - if (! $this->isSorted) { $this->sort(); } + if (! $this->isSorted) { + $this->order(); + } return $this->query; } public function applyFilter(Filter $filter) { + $this->validateFilterColumns($filter); + return $this->addFilter($filter); } + /** + * Validates recursive the Filter columns against the isValidFilterTarget() method + * + * @param Filter $filter + * + * @throws \Icinga\Data\Filter\FilterException + */ + public function validateFilterColumns(Filter $filter) + { + if ($filter instanceof FilterMatch) { + if (! $this->isValidFilterTarget($filter->getColumn())) { + throw new QueryException( + t('The filter column "%s" is not allowed here.'), + $filter->getColumn() + ); + } + } + + if (method_exists($filter, 'filters')) { + foreach ($filter->filters() as $filter) { + $this->validateFilterColumns($filter); + } + } + } + public function clearFilter() { $this->query->clearFilter(); From 97d2a920db4e59fdaa9bbe4623ca0ab3015f80d9 Mon Sep 17 00:00:00 2001 From: Alexander Fuhr Date: Mon, 6 Oct 2014 11:34:04 +0200 Subject: [PATCH 3/4] Implement GROUP BY clause functionality --- library/Icinga/Data/Db/DbQuery.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/library/Icinga/Data/Db/DbQuery.php b/library/Icinga/Data/Db/DbQuery.php index a759da6b5..c50049ee7 100644 --- a/library/Icinga/Data/Db/DbQuery.php +++ b/library/Icinga/Data/Db/DbQuery.php @@ -59,6 +59,13 @@ class DbQuery extends SimpleQuery */ protected $count; + /** + * GROUP BY clauses + * + * @var string|array + */ + protected $group; + protected function init() { $this->db = $this->ds->getDbAdapter(); @@ -100,6 +107,10 @@ class DbQuery extends SimpleQuery } } + if ($this->group) { + $select->group($this->group); + } + $select->columns($this->columns); $this->applyFilterSql($select); @@ -300,4 +311,17 @@ class DbQuery extends SimpleQuery { return (string) $this->getSelectQuery(); } + + /** + * Add a GROUP BY clause + * + * @param string|array $group + * + * @return $this + */ + public function group($group) + { + $this->group = $group; + return $this; + } } From a0122763a676be970ce017421e3b1053e1838e3b Mon Sep 17 00:00:00 2001 From: Alexander Fuhr Date: Mon, 6 Oct 2014 11:37:33 +0200 Subject: [PATCH 4/4] Fix Queries: Summaries, Host, Service --- .../Monitoring/Backend/Ido/Query/GroupsummaryQuery.php | 4 +++- .../monitoring/library/Monitoring/DataView/HostStatus.php | 5 +++-- .../monitoring/library/Monitoring/DataView/ServiceStatus.php | 1 + modules/monitoring/library/Monitoring/Object/Service.php | 3 ++- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/GroupsummaryQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/GroupsummaryQuery.php index c1e12a1ee..ec79ef63c 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/GroupsummaryQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/GroupsummaryQuery.php @@ -44,7 +44,6 @@ class GroupSummaryQuery extends IdoQuery $columns = array( 'object_type', 'host_state', - 'host_name' ); // Prepend group column since we'll use columns index 0 later for grouping @@ -61,6 +60,9 @@ class GroupSummaryQuery extends IdoQuery 'in_downtime' => 'host_in_downtime' ) ); + if (in_array('servicegroup', $this->desiredColumns)) { + $hosts->group(array('sgo.name1', 'ho.object_id', 'state', 'acknowledged', 'in_downtime')); + } $services = $this->createSubQuery( 'Status', $columns + array( diff --git a/modules/monitoring/library/Monitoring/DataView/HostStatus.php b/modules/monitoring/library/Monitoring/DataView/HostStatus.php index 60f224264..ff2ecaf91 100644 --- a/modules/monitoring/library/Monitoring/DataView/HostStatus.php +++ b/modules/monitoring/library/Monitoring/DataView/HostStatus.php @@ -64,7 +64,8 @@ class HostStatus extends DataView 'host_percent_state_change', 'host_modified_host_attributes', 'host_severity', - 'host_problem' + 'host_problem', + 'host_ipv4' ); } @@ -105,7 +106,7 @@ class HostStatus extends DataView public function getFilterColumns() { - return array('hostgroup', 'service_problems'); + return array('hostgroup', 'service_problems', 'servicegroup'); } public function isValidFilterTarget($column) diff --git a/modules/monitoring/library/Monitoring/DataView/ServiceStatus.php b/modules/monitoring/library/Monitoring/DataView/ServiceStatus.php index b81b56764..45cde745f 100644 --- a/modules/monitoring/library/Monitoring/DataView/ServiceStatus.php +++ b/modules/monitoring/library/Monitoring/DataView/ServiceStatus.php @@ -101,6 +101,7 @@ class ServiceStatus extends DataView 'service_flap_detection_enabled', 'service_flap_detection_enabled_changed', 'service_modified_service_attributes', + 'service_host_name' ); } diff --git a/modules/monitoring/library/Monitoring/Object/Service.php b/modules/monitoring/library/Monitoring/Object/Service.php index ac6957eab..36a763101 100644 --- a/modules/monitoring/library/Monitoring/Object/Service.php +++ b/modules/monitoring/library/Monitoring/Object/Service.php @@ -191,7 +191,8 @@ class Service extends MonitoredObject 'service_flap_detection_enabled_changed', 'service_modified_service_attributes', 'service_process_performance_data', - 'service_percent_state_change' + 'service_percent_state_change', + 'service_host_name' )) ->where('host_name', $this->host->getName()) ->where('service_description', $this->service);