From 548aec4233c7c233be232d2b8d449dc84bda95f8 Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Mon, 15 Jun 2015 15:08:04 +0200 Subject: [PATCH] DataView\Contactgroup: Add support for object restrictions refs #9009 --- .../Backend/Ido/Query/ContactgroupQuery.php | 155 +++++++++++++----- .../Monitoring/DataView/Contactgroup.php | 41 +++-- 2 files changed, 140 insertions(+), 56 deletions(-) diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/ContactgroupQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ContactgroupQuery.php index 152e964f8..8394668a4 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/ContactgroupQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ContactgroupQuery.php @@ -3,8 +3,19 @@ namespace Icinga\Module\Monitoring\Backend\Ido\Query; +/** + * Query for contact groups + */ class ContactgroupQuery extends IdoQuery { + /** + * {@inheritdoc} + */ + protected $allowCustomVars = true; + + /** + * {@inheritdoc} + */ protected $columnMap = array( 'contactgroups' => array( 'contactgroup' => 'cgo.name1 COLLATE latin1_general_ci', @@ -12,11 +23,13 @@ class ContactgroupQuery extends IdoQuery 'contactgroup_alias' => 'cg.alias COLLATE latin1_general_ci' ), 'contacts' => array( + 'contact_id' => 'c.contact_id', 'contact' => 'co.name1 COLLATE latin1_general_ci', 'contact_name' => 'co.name1', 'contact_alias' => 'c.alias COLLATE latin1_general_ci', 'contact_email' => 'c.email_address COLLATE latin1_general_ci', 'contact_pager' => 'c.pager_address', + 'contact_object_id' => 'c.contact_object_id', 'contact_has_host_notfications' => 'c.host_notifications_enabled', 'contact_has_service_notfications' => 'c.service_notifications_enabled', 'contact_can_submit_commands' => 'c.can_submit_commands', @@ -30,22 +43,35 @@ class ContactgroupQuery extends IdoQuery 'contact_notify_host_down' => 'c.notify_host_down', 'contact_notify_host_unreachable' => 'c.notify_host_unreachable', 'contact_notify_host_flapping' => 'c.notify_host_flapping', - 'contact_notify_host_downtime' => 'c.notify_host_downtime', + 'contact_notify_host_downtime' => 'c.notify_host_downtime' + ), + 'hostgroups' => array( + 'hostgroup' => 'hgo.name1 COLLATE latin1_general_ci', + 'hostgroup_alias' => 'hg.alias COLLATE latin1_general_ci', + 'hostgroup_name' => 'hgo.name1' ), 'hosts' => array( - 'host' => 'ho.name1 COLLATE latin1_general_ci', - 'host_name' => 'ho.name1' + 'host' => 'ho.name1 COLLATE latin1_general_ci', + 'host_name' => 'ho.name1', + 'host_alias' => 'h.alias', + 'host_display_name' => 'h.display_name COLLATE latin1_general_ci' + ), + 'servicegroups' => array( + 'servicegroup' => 'sgo.name1 COLLATE latin1_general_ci', + 'servicegroup_name' => 'sgo.name1', + 'servicegroup_alias' => 'sg.alias COLLATE latin1_general_ci' ), 'services' => array( 'service' => 'so.name2 COLLATE latin1_general_ci', 'service_description' => 'so.name2', - 'service_host' => 'so.name1 COLLATE latin1_general_ci', + 'service_display_name' => 's.display_name COLLATE latin1_general_ci', 'service_host_name' => 'so.name1' ) ); - protected $useSubqueryCount = true; - + /** + * {@inheritdoc} + */ protected function joinBaseTables() { $this->select->from( @@ -53,81 +79,124 @@ class ContactgroupQuery extends IdoQuery array() )->join( array('cgo' => $this->prefix . 'objects'), - 'cg.contactgroup_object_id = cgo.' . $this->object_id . ' AND cgo.is_active = 1', + 'cgo.object_id = cg.contactgroup_object_id AND cgo.is_active = 1 AND cgo.objecttype_id = 11', array() ); - - $this->joinedVirtualTables = array('contactgroups' => true); + $this->joinedVirtualTables['contactgroups'] = true; } + /** + * Join contacts + */ protected function joinContacts() { - $this->select->distinct()->join( + $this->select->joinLeft( array('cgm' => $this->prefix . 'contactgroup_members'), 'cgm.contactgroup_id = cg.contactgroup_id', array() - )->join( + )->joinLeft( array('co' => $this->prefix . 'objects'), - 'cgm.contact_object_id = co.object_id AND co.is_active = 1', + 'co.object_id = cgm.contact_object_id AND co.is_active = 1 AND co.objecttype_id = 10', array() - )->join( + )->joinLeft( array('c' => $this->prefix . 'contacts'), 'c.contact_object_id = co.object_id', array() ); + $this->group(array('cg.contactgroup_id', 'c.contact_id')); } + /** + * Join host groups + */ + protected function joinHostgroups() + { + $this->requireVirtualTable('hosts'); + $this->select->joinLeft( + array('hgm' => $this->prefix . 'hostgroup_members'), + 'hgm.host_object_id = ho.object_id', + array() + )->joinLeft( + array('hg' => $this->prefix . 'hostgroups'), + 'hg.hostgroup_id = hgm.hostgroup_id', + array() + )->joinLeft( + array('hgo' => $this->prefix . 'objects'), + 'hgo.object_id = hg.hostgroup_object_id AND hgo.is_active = 1 AND hgo.objecttype_id = 3', + array() + ); + } + + /** + * Join hosts + */ protected function joinHosts() { - $this->select->distinct()->join( + $this->select->joinLeft( array('hcg' => $this->prefix . 'host_contactgroups'), 'hcg.contactgroup_object_id = cg.contactgroup_object_id', array() - )->join( + )->joinLeft( array('h' => $this->prefix . 'hosts'), - 'hcg.host_id = h.host_id', + 'h.host_id = hcg.host_id', array() - )->join( + )->joinLeft( array('ho' => $this->prefix . 'objects'), - 'h.host_object_id = ho.' . $this->object_id . ' AND ho.is_active = 1', + 'ho.object_id = h.host_object_id AND ho.is_active = 1 AND ho.objecttype_id = 1', + array() + ); + + if ($this->hasJoinedVirtualTable('contacts')) { + $this->group(array('cg.contactgroup_id', 'c.contact_id')); + } else { + $this->group(array('cg.contactgroup_id')); + } + } + + /** + * Join service groups + */ + protected function joinServicegroups() + { + $this->requireVirtualTable('services'); + $this->select->joinLeft( + array('sgm' => $this->prefix . 'servicegroup_members'), + 'sgm.service_object_id = s.service_object_id', + array() + )->joinLeft( + array('sg' => $this->prefix . 'servicegroups'), + 'sg.servicegroup_id = sgm.servicegroup_id', + array() + )->joinLeft( + array('sgo' => $this->prefix . 'objects'), + 'sgo.object_id = sg.servicegroup_object_id AND sgo.is_active = 1 AND sgo.objecttype_id = 4', array() ); } + /** + * Join services + */ protected function joinServices() { -// $scgSub = $this->db->select()->distinct()->from( -// $this->prefix . 'service_contactgroups', -// array('contactgroup_object_id', 'service_id') -// ); - - /* - This subselect is a workaround for a fucking stupid bug. Other tables - may be affected too. We absolutely need uniqueness here. - - mysql> SELECT * FROM icinga_service_contactgroups WHERE - contactgroup_object_id = 143 AND service_id = 2079564; - +-------------------------+-------------+------------+------------------------+ - | service_contactgroup_id | instance_id | service_id | contactgroup_object_id | - +-------------------------+-------------+------------+------------------------+ - | 4904240 | 1 | 2079564 | 143 | - | 4904244 | 1 | 2079564 | 143 | - +-------------------------+-------------+------------+------------------------+ - */ - - $this->select->distinct()->join( + $this->select->joinLeft( array('scg' => $this->prefix . 'service_contactgroups'), - // array('scg' => $scgSub), 'scg.contactgroup_object_id = cg.contactgroup_object_id', array() - )->join( + )->joinLeft( array('s' => $this->prefix . 'services'), - 'scg.service_id = s.service_id', + 's.service_id = scg.service_id', array() - )->join( + )->joinLeft( array('so' => $this->prefix . 'objects'), - 's.service_object_id = so.' . $this->object_id . ' AND so.is_active = 1', + 'so.object_id = s.service_object_id AND so.is_active = 1 AND so.objecttype_id = 2', array() ); + + if ($this->hasJoinedVirtualTable('contacts')) { + $this->group(array('cg.contactgroup_id', 'c.contact_id')); + } else { + $this->group(array('cg.contactgroup_id')); + } } } diff --git a/modules/monitoring/library/Monitoring/DataView/Contactgroup.php b/modules/monitoring/library/Monitoring/DataView/Contactgroup.php index 0c432c2dc..f95c5abd7 100644 --- a/modules/monitoring/library/Monitoring/DataView/Contactgroup.php +++ b/modules/monitoring/library/Monitoring/DataView/Contactgroup.php @@ -3,21 +3,30 @@ namespace Icinga\Module\Monitoring\DataView; -/** - * Describes the data needed by the Contactgroup DataView - */ class Contactgroup extends DataView { /** - * Retrieve columns provided by this view - * - * @return array + * {@inheritdoc} + */ + public function isValidFilterTarget($column) + { + if ($column[0] === '_' && preg_match('/^_(?:host|service)_/', $column)) { + return true; + } + + return parent::isValidFilterTarget($column); + } + + /** + * {@inheritdoc} */ public function getColumns() { return array( 'contactgroup_name', 'contactgroup_alias', + 'contact_object_id', + 'contact_id', 'contact_name', 'contact_alias', 'contact_email', @@ -36,16 +45,13 @@ class Contactgroup extends DataView 'contact_notify_host_unreachable', 'contact_notify_host_flapping', 'contact_notify_host_downtime', - 'host_name', - 'service_description', - 'service_host_name' + 'contact_notify_host_timeperiod', + 'contact_notify_service_timeperiod' ); } /** - * Retrieve default sorting rules for particular columns. These involve sort order and potential additional to sort - * - * @return array + * {@inheritdoc} */ public function getSortRules() { @@ -59,8 +65,17 @@ class Contactgroup extends DataView ); } + /** + * {@inheritdoc} + */ public function getFilterColumns() { - return array('contactgroup', 'contact', 'host', 'service', 'service_host'); + return array( + 'contactgroup', 'contact', + 'host', 'host_name', 'host_display_name', 'host_alias', + 'hostgroup', 'hostgroup_alias', 'hostgroup_name', + 'service', 'service_description', 'service_display_name', + 'servicegroup', 'servicegroup_alias', 'servicegroup_name' + ); } }