From 58accea8017809f04e8a33db6c13442a3861351d Mon Sep 17 00:00:00 2001 From: Thomas Gelf Date: Tue, 11 Jul 2017 08:33:03 +0200 Subject: [PATCH] GroupMemberTable: show group members fixes #994 --- .../Web/Controller/ObjectController.php | 23 ++- .../Web/Controller/ObjectsController.php | 3 +- .../Director/Web/Table/GroupMemberTable.php | 145 ++++++++++++++++++ library/Director/Web/Tabs/ObjectTabs.php | 8 + 4 files changed, 176 insertions(+), 3 deletions(-) create mode 100644 library/Director/Web/Table/GroupMemberTable.php diff --git a/library/Director/Web/Controller/ObjectController.php b/library/Director/Web/Controller/ObjectController.php index b515a684..8e442c3c 100644 --- a/library/Director/Web/Controller/ObjectController.php +++ b/library/Director/Web/Controller/ObjectController.php @@ -12,6 +12,7 @@ use Icinga\Module\Director\Forms\IcingaObjectFieldForm; use Icinga\Module\Director\Objects\IcingaObject; use Icinga\Module\Director\Web\Controller\Extension\ObjectRestrictions; use Icinga\Module\Director\Web\Form\DirectorObjectForm; +use Icinga\Module\Director\Web\Table\GroupMemberTable; use Icinga\Module\Director\Web\Tabs\ObjectTabs; use ipl\Html\Html; use ipl\Html\Link; @@ -242,7 +243,7 @@ abstract class ObjectController extends ActionController public function fieldsAction() { - $this->hasPermission('director/admin'); + $this->assertPermission('director/admin'); $object = $this->object; $type = $this->getType(); @@ -278,7 +279,7 @@ abstract class ObjectController extends ActionController public function historyAction() { - $this->hasPermission('director/audit'); + $this->assertPermission('director/audit'); $this->setAutorefreshInterval(10); $db = $this->db(); $type = $this->getType(); @@ -298,6 +299,24 @@ abstract class ObjectController extends ActionController )->addAttributes(['data-base-target' => '_next']); } + public function membershipAction() + { + $this->requireObject(); + if (! $this->object->isGroup()) { + throw new NotFoundError('Not Found'); + } + $type = substr($this->getType(), 0, -5); + + $this->setAutorefreshInterval(15); + $this->tabs()->activate('membership'); + $this->addTitle( + $this->translate('Group membership: %s'), + $this->object->getObjectName() + ); + + GroupMemberTable::create($type, $this->db())->setGroup($this->object)->renderTo($this); + } + protected function getType() { // Strip final 's' and upcase an eventual 'group' diff --git a/library/Director/Web/Controller/ObjectsController.php b/library/Director/Web/Controller/ObjectsController.php index 49aabda8..edbdc027 100644 --- a/library/Director/Web/Controller/ObjectsController.php +++ b/library/Director/Web/Controller/ObjectsController.php @@ -123,7 +123,8 @@ abstract class ObjectsController extends ActionController ['type' => 'apply_rule'], [ 'title' => $this->translate('Create a new Service Apply Rule'), - 'class' => 'icon-plus' + 'class' => 'icon-plus', + 'data-base-target' => '_next' ] ) ); diff --git a/library/Director/Web/Table/GroupMemberTable.php b/library/Director/Web/Table/GroupMemberTable.php new file mode 100644 index 00000000..c1136262 --- /dev/null +++ b/library/Director/Web/Table/GroupMemberTable.php @@ -0,0 +1,145 @@ +type = $type; + return $table; + } + + public function setGroup(IcingaObjectGroup $group) + { + $this->group = $group; + return $this; + } + + public function renderTo(ControlsAndContent $controller) + { + $url = $controller->url(); + $this->initializeOptionalQuickSearch($controller); + $controller->content()->add([ + $this->getPaginator($url), + $this + ]); + + if ($url->getParam('format') === 'sql') { + $controller->content()->prepend($this->dumpSqlQuery($url)); + } + } + + public function getType() + { + return $this->type; + } + + public function getColumnsToBeRendered() + { + if ($this->group === null) { + return [ + $this->translate('Group'), + $this->translate('Member'), + $this->translate('Type') + ]; + } else { + return [ + $this->translate('Member'), + $this->translate('Type') + ]; + } + } + + public function renderRow($row) + { + $type = $this->getType(); + $url = Url::fromPath("director/${type}", [ + 'name' => $row->object_name + ]); + + $tr = $this::tr(); + + if ($this->group === null) { + $tr->add($this::td($row->group_name)); + + } + + $tr->add([ + $this::td(Link::create($row->object_name, $url)), + $this::td($row->membership_type) + ]); + return $tr; + } + + protected function prepareQuery() + { +// select h.object_name, hg.object_name, +// CASE WHEN hgh.host_id IS NULL THEN 'apply' ELSE 'direct' END AS assi +// from icinga_hostgroup_host_resolved hgr join icinga_host h on h.id = hgr.host_id +// join icinga_hostgroup hg on hgr.hostgroup_id = hg.id +// left join icinga_hostgroup_host hgh on hgh.host_id = h.id and hgh.hostgroup_id = hg.id; + + $type = $this->getType(); + $columns = [ + 'o.object_name', + 'membership_type' => "CASE WHEN go.${type}_id IS NULL THEN 'apply' ELSE 'direct' END" + ]; + + if ($this->group === null) { + $columns = ['group_name' => 'g.object_name'] + $columns; + } + + $query = $this->db()->select()->from( + ['gro' => "icinga_${type}group_${type}_resolved"], + $columns + )->join( + ['o' => "icinga_${type}"], + "o.id = gro.${type}_id", + [] + )->join( + ['g' => "icinga_${type}group"], + "gro.${type}group_id = g.id", + [] + )->joinLeft( + ['go' => "icinga_${type}group_${type}"], + "go.${type}_id = o.id AND go.${type}group_id = g.id", + [] + )->order('o.object_name'); + + if ($this->group !== null) { + $query->where('g.id = ?', $this->group->get('id')); + } + + return $query; + } +} diff --git a/library/Director/Web/Tabs/ObjectTabs.php b/library/Director/Web/Tabs/ObjectTabs.php index cae40010..62688cfc 100644 --- a/library/Director/Web/Tabs/ObjectTabs.php +++ b/library/Director/Web/Tabs/ObjectTabs.php @@ -92,6 +92,14 @@ class ObjectTabs extends Tabs 'label' => $this->translate('Fields') )); } + + if ($object->isGroup()) { + $this->add('membership', [ + 'url' => sprintf('director/%s/membership', $type), + 'urlParams' => $params, + 'label' => $this->translate('Members') + ]); + } } protected function hasFields()