diff options
Diffstat (limited to 'library/Director/Dashboard/Dashlet')
49 files changed, 1827 insertions, 0 deletions
diff --git a/library/Director/Dashboard/Dashlet/ActivityLogDashlet.php b/library/Director/Dashboard/Dashlet/ActivityLogDashlet.php new file mode 100644 index 0000000..9794986 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/ActivityLogDashlet.php @@ -0,0 +1,35 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class ActivityLogDashlet extends Dashlet +{ + protected $icon = 'book'; + + public function getTitle() + { + return $this->translate('Activity Log'); + } + + public function getSummary() + { + return $this->translate( + 'Wondering about what changed why? Track your changes!' + ); + } + + public function listCssClasses() + { + return 'state-ok'; + } + + public function getUrl() + { + return 'director/config/activities'; + } + + public function listRequiredPermissions() + { + return array('director/audit'); + } +} diff --git a/library/Director/Dashboard/Dashlet/ApiUserObjectDashlet.php b/library/Director/Dashboard/Dashlet/ApiUserObjectDashlet.php new file mode 100644 index 0000000..419859d --- /dev/null +++ b/library/Director/Dashboard/Dashlet/ApiUserObjectDashlet.php @@ -0,0 +1,25 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class ApiUserObjectDashlet extends Dashlet +{ + protected $icon = 'lock-open-alt'; + + protected $requiredStats = array('apiuser'); + + public function getTitle() + { + return $this->translate('Icinga Api users'); + } + + public function getUrl() + { + return 'director/apiusers'; + } + + public function listRequiredPermissions() + { + return array('director/admin'); + } +} diff --git a/library/Director/Dashboard/Dashlet/BasketDashlet.php b/library/Director/Dashboard/Dashlet/BasketDashlet.php new file mode 100644 index 0000000..10f2b81 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/BasketDashlet.php @@ -0,0 +1,30 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class BasketDashlet extends Dashlet +{ + protected $icon = 'tag'; + + public function getTitle() + { + return $this->translate('Configuration Baskets'); + } + + public function getSummary() + { + return $this->translate( + 'Preserve specific configuration objects in a specific state' + ); + } + + public function getUrl() + { + return 'director/baskets'; + } + + public function listRequiredPermissions() + { + return array('director/admin'); + } +} diff --git a/library/Director/Dashboard/Dashlet/CheckCommandsDashlet.php b/library/Director/Dashboard/Dashlet/CheckCommandsDashlet.php new file mode 100644 index 0000000..65d8c8c --- /dev/null +++ b/library/Director/Dashboard/Dashlet/CheckCommandsDashlet.php @@ -0,0 +1,31 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class CheckCommandsDashlet extends Dashlet +{ + protected $icon = 'wrench'; + + public function getSummary() + { + return $this->translate( + 'Manage definitions for your Commands that should be executed as' + . ' Check Plugins, Notifications or based on Events' + ); + } + + public function getTitle() + { + return $this->translate('Commands'); + } + + public function listRequiredPermissions() + { + return array('director/admin'); + } + + public function getUrl() + { + return 'director/commands'; + } +} diff --git a/library/Director/Dashboard/Dashlet/ChoicesDashlet.php b/library/Director/Dashboard/Dashlet/ChoicesDashlet.php new file mode 100644 index 0000000..efdbba5 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/ChoicesDashlet.php @@ -0,0 +1,41 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +abstract class ChoicesDashlet extends Dashlet +{ + protected $icon = 'flapping'; + + public function getTitle() + { + return $this->translate('Choices'); + } + + public function getSummary() + { + return $this->translate( + 'Combine multiple templates into meaningful Choices, making life' + . ' easier for your users' + ); + } + + protected function getType() + { + return strtolower(substr( + substr(get_called_class(), strlen(__NAMESPACE__) + 1), + 0, + - strlen('ChoicesDashlet') + )); + } + + public function getUrl() + { + + return 'director/templatechoices/' . $this->getType(); + } + + public function listRequiredPermissions() + { + return array('director/admin'); + } +} diff --git a/library/Director/Dashboard/Dashlet/CommandObjectDashlet.php b/library/Director/Dashboard/Dashlet/CommandObjectDashlet.php new file mode 100644 index 0000000..083172e --- /dev/null +++ b/library/Director/Dashboard/Dashlet/CommandObjectDashlet.php @@ -0,0 +1,25 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class CommandObjectDashlet extends Dashlet +{ + protected $icon = 'wrench'; + + protected $requiredStats = array('command'); + + public function getTitle() + { + return $this->translate('Commands'); + } + + public function getUrl() + { + return 'director/dashboard?name=commands'; + } + + public function listRequiredPermissions() + { + return array('director/admin'); + } +} diff --git a/library/Director/Dashboard/Dashlet/CommandTemplatesDashlet.php b/library/Director/Dashboard/Dashlet/CommandTemplatesDashlet.php new file mode 100644 index 0000000..512298a --- /dev/null +++ b/library/Director/Dashboard/Dashlet/CommandTemplatesDashlet.php @@ -0,0 +1,26 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class CommandTemplatesDashlet extends CheckCommandsDashlet +{ + protected $icon = 'cubes'; + + public function getSummary() + { + return $this->translate( + 'External Notification Commands have been defined in your local Icinga 2' + . ' Configuration.' + ); + } + + public function getTitle() + { + return $this->translate('Command Templates'); + } + + public function getUrl() + { + return 'director/commands/templates'; + } +} diff --git a/library/Director/Dashboard/Dashlet/CustomvarDashlet.php b/library/Director/Dashboard/Dashlet/CustomvarDashlet.php new file mode 100644 index 0000000..919c06b --- /dev/null +++ b/library/Director/Dashboard/Dashlet/CustomvarDashlet.php @@ -0,0 +1,30 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class CustomvarDashlet extends Dashlet +{ + protected $icon = 'keyboard'; + + public function getTitle() + { + return $this->translate('CustomVar Overview'); + } + + public function getSummary() + { + return $this->translate( + 'Get an overview of used CustomVars and their variants' + ); + } + + public function getUrl() + { + return 'director/data/vars'; + } + + public function listRequiredPermissions() + { + return array('director/admin'); + } +} diff --git a/library/Director/Dashboard/Dashlet/Dashlet.php b/library/Director/Dashboard/Dashlet/Dashlet.php new file mode 100644 index 0000000..f8bc708 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/Dashlet.php @@ -0,0 +1,239 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +use Icinga\Module\Director\Acl; +use Icinga\Module\Director\Db; +use ipl\Html\BaseHtmlElement; +use ipl\Html\Html; +use gipfl\IcingaWeb2\Icon; +use gipfl\IcingaWeb2\Link; +use gipfl\Translation\TranslationHelper; + +abstract class Dashlet extends BaseHtmlElement +{ + use TranslationHelper; + + /** @var Db */ + protected $db; + + protected $tag = 'li'; + + protected $icon = 'help'; + + protected $stats; + + protected $requiredStats = []; + + public function __construct(Db $db) + { + $this->db = $db; + } + + /** + * @return string[] + */ + public function listRequiredStats() + { + return $this->requiredStats; + } + + public function addStats($type, $stats) + { + $this->stats[$type] = $stats; + } + + /** + * @param $name + * @param Db $db + * @return Dashlet + */ + public static function loadByName($name, Db $db) + { + /** @var Dashlet */ + $class = __NAMESPACE__ . '\\' . $name . 'Dashlet'; + return new $class($db); + } + + public static function loadByNames(array $names, Db $db) + { + $dashlets = []; + foreach ($names as $name) { + $dashlet = static::loadByName($name, $db); + + if ($dashlet->isAllowed()) { + $dashlets[] = $dashlet; + } + } + + return $dashlets; + } + + public function listCssClasses() + { + return []; + } + + public function getIconName() + { + return $this->icon; + } + + abstract public function getTitle(); + + abstract public function getUrl(); + + protected function assemble() + { + $this->add(Link::create([ + $this->getTitle(), + Icon::create($this->getIconName()), + Html::tag('p', null, $this->getSummary()) + ], $this->getUrl(), null, [ + 'class' => $this->listCssClasses() + ])); + } + + public function listRequiredPermissions() + { + return array($this->getUrl()); + } + + public function isAllowed() + { + $acl = Acl::instance(); + foreach ($this->listRequiredPermissions() as $perm) { + if (! $acl->hasPermission($perm)) { + return false; + } + } + + return true; + } + + public function shouldBeShown() + { + return true; + } + + public function getSummary() + { + $result = ''; + if (! empty($this->requiredStats)) { + reset($this->requiredStats); + $result .= $this->statSummary(current($this->requiredStats)); + } + + return $result; + } + + public function getStats($type, $name = null) + { + if ($name === null) { + return $this->stats[$type]; + } else { + return $this->stats[$type]->{'cnt_' . $name}; + } + } + + protected function getTemplateSummaryText($type) + { + $cnt = (int) $this->stats[$type]->cnt_template; + + if ($cnt === 0) { + return $this->translate('No template has been defined yet'); + } + + if ($cnt === 1) { + return $this->translate('One template has been defined'); + } + + return sprintf( + $this->translate('%d templates have been defined'), + $cnt + ); + } + + protected function getApplySummaryText($type) + { + $cnt = (int) $this->stats[$type]->cnt_apply; + + if ($cnt === 0) { + return $this->translate('No apply rule has been defined yet'); + } + + if ($cnt === 1) { + return $this->translate('One apply rule has been defined'); + } + + return sprintf( + $this->translate('%d apply rules have been defined'), + $cnt + ); + } + + protected function statSummary($type) + { + $stat = $this->stats[$type]; + + if ((int) $stat->cnt_total === 0) { + return $this->translate('No object has been defined yet'); + } + + if ((int) $stat->cnt_total === 1) { + if ($stat->cnt_template > 0) { + $msg = $this->translate('One template has been defined'); + } elseif ($stat->cnt_external > 0) { + $msg = $this->translate( + 'One external object has been defined, it will not be deployed' + ); + } else { + $msg = $this->translate('One object has been defined'); + } + } else { + $msg = sprintf( + $this->translate('%d objects have been defined'), + $stat->cnt_total + ); + } + + $extra = array(); + if ($stat->cnt_total !== $stat->cnt_object) { + if ($stat->cnt_template > 0) { + $extra[] = sprintf( + $this->translate('%d of them are templates'), + $stat->cnt_template + ); + } + + if ($stat->cnt_external > 0) { + $extra[] = sprintf( + $this->translate( + '%d have been externally defined and will not be deployed' + ), + $stat->cnt_external + ); + } + } + + if (array_key_exists($type . 'group', $this->stats)) { + $groupstat = $this->stats[$type . 'group']; + if ((int) $groupstat->cnt_total === 0) { + $extra[] = $this->translate('no related group exists'); + } elseif ((int) $groupstat->cnt_total === 1) { + $extra[] = $this->translate('one related group exists'); + } else { + $extra[] = sprintf( + $this->translate('%s related group objects have been created'), + $groupstat->cnt_total + ); + } + } + + if (empty($extra)) { + return $msg; + } + + return $msg . ', ' . implode(', ', $extra); + } +} diff --git a/library/Director/Dashboard/Dashlet/DatafieldCategoryDashlet.php b/library/Director/Dashboard/Dashlet/DatafieldCategoryDashlet.php new file mode 100644 index 0000000..6efb4ca --- /dev/null +++ b/library/Director/Dashboard/Dashlet/DatafieldCategoryDashlet.php @@ -0,0 +1,30 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class DatafieldCategoryDashlet extends Dashlet +{ + protected $icon = 'th-list'; + + public function getTitle() + { + return $this->translate('Data Field Categories'); + } + + public function getSummary() + { + return $this->translate( + 'Categories bring structure to your Data Fields' + ); + } + + public function getUrl() + { + return 'director/data/fieldcategories'; + } + + public function listRequiredPermissions() + { + return array('director/admin'); + } +} diff --git a/library/Director/Dashboard/Dashlet/DatafieldDashlet.php b/library/Director/Dashboard/Dashlet/DatafieldDashlet.php new file mode 100644 index 0000000..03f2d8d --- /dev/null +++ b/library/Director/Dashboard/Dashlet/DatafieldDashlet.php @@ -0,0 +1,30 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class DatafieldDashlet extends Dashlet +{ + protected $icon = 'edit'; + + public function getTitle() + { + return $this->translate('Define Data Fields'); + } + + public function getSummary() + { + return $this->translate( + 'Data fields make sure that configuration fits your rules' + ); + } + + public function getUrl() + { + return 'director/data/fields'; + } + + public function listRequiredPermissions() + { + return array('director/admin'); + } +} diff --git a/library/Director/Dashboard/Dashlet/DatalistDashlet.php b/library/Director/Dashboard/Dashlet/DatalistDashlet.php new file mode 100644 index 0000000..bdf179f --- /dev/null +++ b/library/Director/Dashboard/Dashlet/DatalistDashlet.php @@ -0,0 +1,30 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class DatalistDashlet extends Dashlet +{ + protected $icon = 'sort-name-up'; + + public function getTitle() + { + return $this->translate('Provide Data Lists'); + } + + public function getSummary() + { + return $this->translate( + 'Provide data lists to make life easier for your users' + ); + } + + public function getUrl() + { + return 'director/data/lists'; + } + + public function listRequiredPermissions() + { + return array('director/admin'); + } +} diff --git a/library/Director/Dashboard/Dashlet/DependencyObjectDashlet.php b/library/Director/Dashboard/Dashlet/DependencyObjectDashlet.php new file mode 100644 index 0000000..47a18aa --- /dev/null +++ b/library/Director/Dashboard/Dashlet/DependencyObjectDashlet.php @@ -0,0 +1,26 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class DependencyObjectDashlet extends Dashlet +{ + protected $icon = 'sitemap'; + + protected $requiredStats = array('dependency'); + + public function getTitle() + { + return $this->translate('Dependencies'); + } + + public function getSummary() + { + return $this->translate('Object dependency relationships.') + . ' ' . parent::getSummary(); + } + + public function getUrl() + { + return 'director/dependencies/applyrules'; + } +} diff --git a/library/Director/Dashboard/Dashlet/DeploymentDashlet.php b/library/Director/Dashboard/Dashlet/DeploymentDashlet.php new file mode 100644 index 0000000..7a52793 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/DeploymentDashlet.php @@ -0,0 +1,114 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +use Exception; +use Icinga\Module\Director\Objects\DirectorDeploymentLog; + +class DeploymentDashlet extends Dashlet +{ + protected $icon = 'wrench'; + + protected $undeployedActivities; + + protected $lastDeployment; + + public function getTitle() + { + return $this->translate('Config Deployment'); + } + + public function hasUndeployedActivities() + { + return $this->undeployedActivities() > 0; + } + + public function undeployedActivities() + { + if ($this->undeployedActivities === null) { + try { + $this->undeployedActivities = $this->db + ->countActivitiesSinceLastDeployedConfig(); + } catch (Exception $e) { + $this->undeployedActivities = 0; + } + } + + return $this->undeployedActivities; + } + + public function lastDeploymentFailed() + { + return ! $this->lastDeployment()->succeeded(); + } + + public function lastDeploymentPending() + { + return $this->lastDeployment()->isPending(); + } + + public function listCssClasses() + { + try { + if ($this->lastDeploymentFailed()) { + return array('state-critical'); + } elseif ($this->lastDeploymentPending()) { + return array('state-pending'); + } elseif ($this->hasUndeployedActivities()) { + return array('state-warning'); + } else { + return array('state-ok'); + } + } catch (Exception $e) { + return null; + } + } + + protected function lastDeployment() + { + if ($this->lastDeployment === null) { + $this->lastDeployment = DirectorDeploymentLog::loadLatest($this->db); + } + + return $this->lastDeployment; + } + + public function getSummary() + { + $msgs = array(); + $cnt = $this->undeployedActivities(); + + try { + if ($this->lastDeploymentFailed()) { + $msgs[] = $this->translate('The last deployment did not succeed'); + } elseif ($this->lastDeploymentPending()) { + $msgs[] = $this->translate('The last deployment is currently pending'); + } + } catch (Exception $e) { + } + + if ($cnt === 0) { + $msgs[] = $this->translate('There are no pending changes'); + } else { + $msgs[] = sprintf( + $this->translate( + 'A total of %d config changes happened since your last' + . ' deployed config has been rendered' + ), + $cnt + ); + } + + return implode('. ', $msgs) . '.'; + } + + public function getUrl() + { + return 'director/config/deployments'; + } + + public function listRequiredPermissions() + { + return array('director/deploy'); + } +} diff --git a/library/Director/Dashboard/Dashlet/EndpointObjectDashlet.php b/library/Director/Dashboard/Dashlet/EndpointObjectDashlet.php new file mode 100644 index 0000000..9dd9467 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/EndpointObjectDashlet.php @@ -0,0 +1,63 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +use Exception; + +class EndpointObjectDashlet extends Dashlet +{ + protected $icon = 'cloud'; + + protected $requiredStats = array('endpoint'); + + protected $hasDeploymentEndpoint; + + public function getTitle() + { + return $this->translate('Endpoints'); + } + + public function getUrl() + { + return 'director/endpoints'; + } + + public function listRequiredPermissions() + { + return array('director/admin'); + } + + protected function hasDeploymentEndpoint() + { + if ($this->hasDeploymentEndpoint === null) { + try { + $this->hasDeploymentEndpoint = $this->db->hasDeploymentEndpoint(); + } catch (Exception $e) { + return false; + } + } + + return $this->hasDeploymentEndpoint; + } + + public function listCssClasses() + { + if (! $this->hasDeploymentEndpoint()) { + return 'state-critical'; + } + + return null; + } + + public function getSummary() + { + $msg = parent::getSummary(); + if (! $this->hasDeploymentEndpoint()) { + $msg .= '. ' . $this->translate( + 'None could be used for deployments right now' + ); + } + + return $msg; + } +} diff --git a/library/Director/Dashboard/Dashlet/ExternalCheckCommandsDashlet.php b/library/Director/Dashboard/Dashlet/ExternalCheckCommandsDashlet.php new file mode 100644 index 0000000..2711fb9 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/ExternalCheckCommandsDashlet.php @@ -0,0 +1,26 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class ExternalCheckCommandsDashlet extends CheckCommandsDashlet +{ + protected $icon = 'download'; + + public function getSummary() + { + return $this->translate( + 'External Commands have been defined in your local Icinga 2' + . ' Configuration.' + ); + } + + public function getTitle() + { + return $this->translate('External Commands'); + } + + public function getUrl() + { + return 'director/commands?type=external_object'; + } +} diff --git a/library/Director/Dashboard/Dashlet/ExternalNotificationCommandsDashlet.php b/library/Director/Dashboard/Dashlet/ExternalNotificationCommandsDashlet.php new file mode 100644 index 0000000..435d0cb --- /dev/null +++ b/library/Director/Dashboard/Dashlet/ExternalNotificationCommandsDashlet.php @@ -0,0 +1,21 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class ExternalNotificationCommandsDashlet extends CheckCommandsDashlet +{ + protected $icon = 'wrench'; + + public function getSummary() + { + return $this->translate( + 'External Notification Commands have been defined in your local Icinga 2' + . ' Configuration.' + ); + } + + public function getTitle() + { + return $this->translate('External Notification Commands'); + } +} diff --git a/library/Director/Dashboard/Dashlet/HostChoicesDashlet.php b/library/Director/Dashboard/Dashlet/HostChoicesDashlet.php new file mode 100644 index 0000000..98bfe32 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/HostChoicesDashlet.php @@ -0,0 +1,7 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class HostChoicesDashlet extends ChoicesDashlet +{ +} diff --git a/library/Director/Dashboard/Dashlet/HostGroupsDashlet.php b/library/Director/Dashboard/Dashlet/HostGroupsDashlet.php new file mode 100644 index 0000000..5d3b25f --- /dev/null +++ b/library/Director/Dashboard/Dashlet/HostGroupsDashlet.php @@ -0,0 +1,31 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class HostGroupsDashlet extends Dashlet +{ + protected $icon = 'tags'; + + public function getTitle() + { + return $this->translate('Host Groups'); + } + + public function getSummary() + { + return $this->translate( + 'Define Host Groups to give your configuration more structure. They' + . ' are useful for Dashboards, Notifications or Restrictions' + ); + } + + public function getUrl() + { + return 'director/hostgroups'; + } + + public function listRequiredPermissions() + { + return array('director/hostgroups'); + } +} diff --git a/library/Director/Dashboard/Dashlet/HostObjectDashlet.php b/library/Director/Dashboard/Dashlet/HostObjectDashlet.php new file mode 100644 index 0000000..10cff94 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/HostObjectDashlet.php @@ -0,0 +1,25 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class HostObjectDashlet extends Dashlet +{ + protected $icon = 'host'; + + protected $requiredStats = array('host', 'hostgroup'); + + public function getTitle() + { + return $this->translate('Host objects'); + } + + public function listRequiredPermissions() + { + return ['director/hosts']; + } + + public function getUrl() + { + return 'director/dashboard?name=hosts'; + } +} diff --git a/library/Director/Dashboard/Dashlet/HostTemplatesDashlet.php b/library/Director/Dashboard/Dashlet/HostTemplatesDashlet.php new file mode 100644 index 0000000..09bed17 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/HostTemplatesDashlet.php @@ -0,0 +1,31 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class HostTemplatesDashlet extends Dashlet +{ + protected $icon = 'cubes'; + + public function getTitle() + { + return $this->translate('Host Templates'); + } + + public function getSummary() + { + return $this->translate( + 'Manage your Host Templates. Use Fields to make it easy for' + . ' your users to get them customized.' + ); + } + + public function getUrl() + { + return 'director/hosts/templates'; + } + + public function listRequiredPermissions() + { + return array('director/admin'); + } +} diff --git a/library/Director/Dashboard/Dashlet/HostsDashlet.php b/library/Director/Dashboard/Dashlet/HostsDashlet.php new file mode 100644 index 0000000..39c1421 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/HostsDashlet.php @@ -0,0 +1,32 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class HostsDashlet extends Dashlet +{ + protected $icon = 'host'; + + public function getTitle() + { + return $this->translate('Hosts'); + } + + public function getSummary() + { + return $this->translate( + 'This is where you add all your servers, containers, network or' + . ' sensor devices - and much more. Every subject worth to be' + . ' monitored' + ); + } + + public function getUrl() + { + return 'director/hosts'; + } + + public function listRequiredPermissions() + { + return ['director/hosts']; + } +} diff --git a/library/Director/Dashboard/Dashlet/ImportSourceDashlet.php b/library/Director/Dashboard/Dashlet/ImportSourceDashlet.php new file mode 100644 index 0000000..302c1ed --- /dev/null +++ b/library/Director/Dashboard/Dashlet/ImportSourceDashlet.php @@ -0,0 +1,65 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +use Exception; +use Icinga\Module\Director\Objects\ImportSource; + +class ImportSourceDashlet extends Dashlet +{ + protected $icon = 'database'; + + public function getTitle() + { + return $this->translate('Import data sources'); + } + + public function listCssClasses() + { + try { + return $this->fetchStateClass(); + } catch (Exception $e) { + return 'state-critical'; + } + } + + public function getSummary() + { + return $this->translate( + 'Define and manage imports from various data sources' + ); + } + + protected function fetchStateClass() + { + $srcs = ImportSource::loadAll($this->db); + if (count($srcs) > 0) { + $state = 'state-ok'; + } else { + $state = null; + } + + foreach ($srcs as $src) { + if ($src->import_state !== 'in-sync') { + if ($src->import_state === 'failing') { + $state = 'state-critical'; + break; + } else { + $state = 'state-warning'; + } + } + } + + return $state; + } + + public function getUrl() + { + return 'director/importsources'; + } + + public function listRequiredPermissions() + { + return array('director/admin'); + } +} diff --git a/library/Director/Dashboard/Dashlet/InfrastructureDashlet.php b/library/Director/Dashboard/Dashlet/InfrastructureDashlet.php new file mode 100644 index 0000000..328df72 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/InfrastructureDashlet.php @@ -0,0 +1,30 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class InfrastructureDashlet extends Dashlet +{ + protected $icon = 'cloud'; + + public function getTitle() + { + return $this->translate('Icinga Infrastructure'); + } + + public function getSummary() + { + return $this->translate( + 'Manage your Icinga 2 infrastructure: Masters, Zones, Satellites and more' + ); + } + + public function getUrl() + { + return 'director/dashboard?name=infrastructure'; + } + + public function listRequiredPermissions() + { + return array('director/admin'); + } +} diff --git a/library/Director/Dashboard/Dashlet/JobDashlet.php b/library/Director/Dashboard/Dashlet/JobDashlet.php new file mode 100644 index 0000000..d7452e0 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/JobDashlet.php @@ -0,0 +1,65 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +use Exception; +use Icinga\Module\Director\Objects\DirectorJob; + +class JobDashlet extends Dashlet +{ + protected $icon = 'clock'; + + public function getTitle() + { + return $this->translate('Jobs'); + } + + public function listCssClasses() + { + try { + return $this->fetchStateClass(); + } catch (Exception $e) { + return 'state-critical'; + } + } + + public function getSummary() + { + return $this->translate( + 'Schedule and automate Import, Syncronization, Config Deployment,' + . ' Housekeeping and more' + ); + } + + protected function fetchStateClass() + { + /** @var DirectorJob[] $jobs */ + $jobs = DirectorJob::loadAll($this->db); + if (count($jobs) > 0) { + $state = 'state-ok'; + } else { + $state = null; + } + + foreach ($jobs as $job) { + if ($job->isPending()) { + $state = 'state-pending'; + } elseif (! $job->lastAttemptSucceeded()) { + $state = 'state-critical'; + break; + } + } + + return $state; + } + + public function getUrl() + { + return 'director/jobs'; + } + + public function listRequiredPermissions() + { + return array('director/admin'); + } +} diff --git a/library/Director/Dashboard/Dashlet/KickstartDashlet.php b/library/Director/Dashboard/Dashlet/KickstartDashlet.php new file mode 100644 index 0000000..09801f5 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/KickstartDashlet.php @@ -0,0 +1,31 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class KickstartDashlet extends Dashlet +{ + protected $icon = 'gauge'; + + public function getTitle() + { + return $this->translate('Kickstart Wizard'); + } + + public function getSummary() + { + return $this->translate( + 'This synchronizes Icinga Director to your Icinga 2 infrastructure.' + . ' A new run should be triggered on infrastructure changes' + ); + } + + public function getUrl() + { + return 'director/kickstart'; + } + + public function listRequiredPermissions() + { + return array('director/admin'); + } +} diff --git a/library/Director/Dashboard/Dashlet/NotificationApplyDashlet.php b/library/Director/Dashboard/Dashlet/NotificationApplyDashlet.php new file mode 100644 index 0000000..e0b0443 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/NotificationApplyDashlet.php @@ -0,0 +1,37 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class NotificationApplyDashlet extends Dashlet +{ + protected $icon = 'bell'; + + protected $requiredStats = array('notification'); + + public function getTitle() + { + return $this->translate('Notifications'); + } + + public function getSummary() + { + return $this->translate( + 'Apply notifications with specific properties according to given rules.' + ) . ' ' . $this->getApplySummaryText('notification'); + } + + public function shouldBeShown() + { + return $this->getStats('notification', 'template') > 0; + } + + public function listRequiredPermissions() + { + return array('director/notifications'); + } + + public function getUrl() + { + return 'director/notifications/applyrules'; + } +} diff --git a/library/Director/Dashboard/Dashlet/NotificationCommandsDashlet.php b/library/Director/Dashboard/Dashlet/NotificationCommandsDashlet.php new file mode 100644 index 0000000..0a640ae --- /dev/null +++ b/library/Director/Dashboard/Dashlet/NotificationCommandsDashlet.php @@ -0,0 +1,21 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class NotificationCommandsDashlet extends CheckCommandsDashlet +{ + protected $icon = 'wrench'; + + public function getSummary() + { + return $this->translate( + 'Notification Commands allow you to trigger any action you want when' + . ' a notification takes place' + ); + } + + public function getTitle() + { + return $this->translate('Notification Commands'); + } +} diff --git a/library/Director/Dashboard/Dashlet/NotificationTemplateDashlet.php b/library/Director/Dashboard/Dashlet/NotificationTemplateDashlet.php new file mode 100644 index 0000000..a58b5d0 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/NotificationTemplateDashlet.php @@ -0,0 +1,31 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class NotificationTemplateDashlet extends Dashlet +{ + protected $icon = 'cubes'; + + protected $requiredStats = array('notification'); + + public function getTitle() + { + return $this->translate('Notification templates'); + } + + public function getSummary() + { + return $this->translate('Provide templates for your notifications.') + . ' ' . $this->getTemplateSummaryText('notification'); + } + + public function listRequiredPermissions() + { + return array('director/admin'); + } + + public function getUrl() + { + return 'director/notifications/templates'; + } +} diff --git a/library/Director/Dashboard/Dashlet/NotificationsDashlet.php b/library/Director/Dashboard/Dashlet/NotificationsDashlet.php new file mode 100644 index 0000000..85610f0 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/NotificationsDashlet.php @@ -0,0 +1,33 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class NotificationsDashlet extends Dashlet +{ + protected $icon = 'bell'; + + protected $requiredStats = array('notification'); + + public function getTitle() + { + return $this->translate('Notifications'); + } + + public function getSummary() + { + return $this->translate( + 'Schedule your notifications. Define who should be notified, when,' + . ' and for which kind of problem' + ); + } + + public function listRequiredPermissions() + { + return array('director/notifications'); + } + + public function getUrl() + { + return 'director/dashboard?name=notifications'; + } +} diff --git a/library/Director/Dashboard/Dashlet/ScheduledDowntimeApplyDashlet.php b/library/Director/Dashboard/Dashlet/ScheduledDowntimeApplyDashlet.php new file mode 100644 index 0000000..45bcfa2 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/ScheduledDowntimeApplyDashlet.php @@ -0,0 +1,25 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class ScheduledDowntimeApplyDashlet extends Dashlet +{ + protected $icon = 'plug'; + + protected $requiredStats = ['scheduled_downtime']; + + public function getTitle() + { + return $this->translate('Scheduled Downtimes'); + } + + public function listRequiredPermissions() + { + return array('director/scheduled-downtimes'); + } + + public function getUrl() + { + return 'director/scheduled-downtimes/applyrules'; + } +} diff --git a/library/Director/Dashboard/Dashlet/SelfServiceDashlet.php b/library/Director/Dashboard/Dashlet/SelfServiceDashlet.php new file mode 100644 index 0000000..32b1cfa --- /dev/null +++ b/library/Director/Dashboard/Dashlet/SelfServiceDashlet.php @@ -0,0 +1,31 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class SelfServiceDashlet extends Dashlet +{ + protected $icon = 'chat'; + + public function getTitle() + { + return $this->translate('Self Service API'); + } + + public function getSummary() + { + return $this->translate( + 'Icinga Director offers a Self Service API, allowing new Icinga' + . ' nodes to register themselves' + ); + } + + public function getUrl() + { + return 'director/settings/self-service'; + } + + public function listRequiredPermissions() + { + return array('director/admin'); + } +} diff --git a/library/Director/Dashboard/Dashlet/ServiceApplyRulesDashlet.php b/library/Director/Dashboard/Dashlet/ServiceApplyRulesDashlet.php new file mode 100644 index 0000000..b4bee04 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/ServiceApplyRulesDashlet.php @@ -0,0 +1,31 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class ServiceApplyRulesDashlet extends Dashlet +{ + protected $icon = 'resize-full-alt'; + + public function getTitle() + { + return $this->translate('Service Apply Rules'); + } + + public function getSummary() + { + return $this->translate( + 'Using Apply Rules a Service can be applied to multiple hosts at once,' + . ' based on filters dealing with any combination of their properties' + ); + } + + public function getUrl() + { + return 'director/services/applyrules'; + } + + public function listRequiredPermissions() + { + return array('director/admin'); + } +} diff --git a/library/Director/Dashboard/Dashlet/ServiceChoicesDashlet.php b/library/Director/Dashboard/Dashlet/ServiceChoicesDashlet.php new file mode 100644 index 0000000..ff23321 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/ServiceChoicesDashlet.php @@ -0,0 +1,7 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class ServiceChoicesDashlet extends ChoicesDashlet +{ +} diff --git a/library/Director/Dashboard/Dashlet/ServiceGroupsDashlet.php b/library/Director/Dashboard/Dashlet/ServiceGroupsDashlet.php new file mode 100644 index 0000000..ad47768 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/ServiceGroupsDashlet.php @@ -0,0 +1,31 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class ServiceGroupsDashlet extends Dashlet +{ + protected $icon = 'tags'; + + public function getTitle() + { + return $this->translate('Service Groups'); + } + + public function getSummary() + { + return $this->translate( + 'Defining Service Groups get more structure. Great for Dashboards.' + . ' Notifications and Permissions might be based on groups.' + ); + } + + public function getUrl() + { + return 'director/servicegroups'; + } + + public function listRequiredPermissions() + { + return array('director/admin'); + } +} diff --git a/library/Director/Dashboard/Dashlet/ServiceObjectDashlet.php b/library/Director/Dashboard/Dashlet/ServiceObjectDashlet.php new file mode 100644 index 0000000..01fb800 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/ServiceObjectDashlet.php @@ -0,0 +1,34 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +use Icinga\Module\Director\Acl; + +class ServiceObjectDashlet extends Dashlet +{ + protected $icon = 'services'; + + protected $requiredStats = array('service', 'servicegroup'); + + public function getTitle() + { + return $this->translate('Monitored Services'); + } + + public function getUrl() + { + return 'director/dashboard?name=services'; + } + + public function listRequiredPermissions() + { + return ['director/services']; + } + + public function isAllowed() + { + $acl = Acl::instance(); + return $acl->hasPermission('director/services') + || $acl->hasPermission('director/service_sets'); + } +} diff --git a/library/Director/Dashboard/Dashlet/ServiceSetsDashlet.php b/library/Director/Dashboard/Dashlet/ServiceSetsDashlet.php new file mode 100644 index 0000000..f971d42 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/ServiceSetsDashlet.php @@ -0,0 +1,31 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class ServiceSetsDashlet extends Dashlet +{ + protected $icon = 'services'; + + public function getTitle() + { + return $this->translate('Service Sets'); + } + + public function getSummary() + { + return $this->translate( + 'Grouping your Services into Sets allow you to quickly assign services' + . ' often used together in a single operation all at once' + ); + } + + public function getUrl() + { + return 'director/services/sets'; + } + + public function listRequiredPermissions() + { + return array('director/servicesets'); + } +} diff --git a/library/Director/Dashboard/Dashlet/ServiceTemplatesDashlet.php b/library/Director/Dashboard/Dashlet/ServiceTemplatesDashlet.php new file mode 100644 index 0000000..62d1b41 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/ServiceTemplatesDashlet.php @@ -0,0 +1,31 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class ServiceTemplatesDashlet extends Dashlet +{ + protected $icon = 'cubes'; + + public function getTitle() + { + return $this->translate('Service Templates'); + } + + public function getSummary() + { + return $this->translate( + 'Manage your Service Templates. Use Fields to make it easy for' + . ' your users to get them customized.' + ); + } + + public function getUrl() + { + return 'director/services/templates'; + } + + public function listRequiredPermissions() + { + return array('director/admin'); + } +} diff --git a/library/Director/Dashboard/Dashlet/SettingsDashlet.php b/library/Director/Dashboard/Dashlet/SettingsDashlet.php new file mode 100644 index 0000000..716e565 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/SettingsDashlet.php @@ -0,0 +1,30 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class SettingsDashlet extends Dashlet +{ + protected $icon = 'edit'; + + public function getTitle() + { + return $this->translate('Director Settings'); + } + + public function getSummary() + { + return $this->translate( + 'Tweak some global Director settings' + ); + } + + public function getUrl() + { + return 'director/config/settings'; + } + + public function listRequiredPermissions() + { + return array('director/admin'); + } +} diff --git a/library/Director/Dashboard/Dashlet/SingleServicesDashlet.php b/library/Director/Dashboard/Dashlet/SingleServicesDashlet.php new file mode 100644 index 0000000..297b3f8 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/SingleServicesDashlet.php @@ -0,0 +1,31 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class SingleServicesDashlet extends Dashlet +{ + protected $icon = 'service'; + + public function getTitle() + { + return $this->translate('Single Services'); + } + + public function getSummary() + { + return $this->translate( + 'Here you can find all single services directly attached to single' + . ' hosts' + ); + } + + public function getUrl() + { + return 'director/services'; + } + + public function listRequiredPermissions() + { + return array('director/services'); + } +} diff --git a/library/Director/Dashboard/Dashlet/SyncDashlet.php b/library/Director/Dashboard/Dashlet/SyncDashlet.php new file mode 100644 index 0000000..4ac689a --- /dev/null +++ b/library/Director/Dashboard/Dashlet/SyncDashlet.php @@ -0,0 +1,65 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +use Exception; +use Icinga\Module\Director\Objects\SyncRule; + +class SyncDashlet extends Dashlet +{ + protected $icon = 'flapping'; + + public function getTitle() + { + return $this->translate('Synchronize'); + } + + public function listCssClasses() + { + try { + return $this->fetchStateClass(); + } catch (Exception $e) { + return 'state-critical'; + } + } + + public function getSummary() + { + return $this->translate( + 'Define how imported data should be synchronized with Icinga' + ); + } + + protected function fetchStateClass() + { + $syncs = SyncRule::loadAll($this->db); + if (count($syncs) > 0) { + $state = 'state-ok'; + } else { + $state = null; + } + + foreach ($syncs as $sync) { + if ($sync->sync_state !== 'in-sync') { + if ($sync->sync_state === 'failing') { + $state = 'state-critical'; + break; + } else { + $state = 'state-warning'; + } + } + } + + return $state; + } + + public function getUrl() + { + return 'director/syncrules'; + } + + public function listRequiredPermissions() + { + return array('director/admin'); + } +} diff --git a/library/Director/Dashboard/Dashlet/TimeperiodObjectDashlet.php b/library/Director/Dashboard/Dashlet/TimeperiodObjectDashlet.php new file mode 100644 index 0000000..ba4c1db --- /dev/null +++ b/library/Director/Dashboard/Dashlet/TimeperiodObjectDashlet.php @@ -0,0 +1,28 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +use DirectoryIterator; +use Icinga\Exception\ProgrammingError; + +class TimeperiodObjectDashlet extends Dashlet +{ + protected $icon = 'calendar'; + + protected $requiredStats = array('timeperiod'); + + public function getTitle() + { + return $this->translate('Timeperiods'); + } + + public function getUrl() + { + return 'director/timeperiods'; + } + + public function listRequiredPermissions() + { + return array('director/admin'); + } +} diff --git a/library/Director/Dashboard/Dashlet/TimeperiodTemplateDashlet.php b/library/Director/Dashboard/Dashlet/TimeperiodTemplateDashlet.php new file mode 100644 index 0000000..26339e4 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/TimeperiodTemplateDashlet.php @@ -0,0 +1,31 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class TimeperiodTemplateDashlet extends Dashlet +{ + protected $icon = 'cubes'; + + protected $requiredStats = array('timeperiod'); + + public function getTitle() + { + return $this->translate('Timeperiod Templates'); + } + + public function getSummary() + { + return $this->translate('Provide templates for your TimePeriod objects.') + . ' ' . $this->getTemplateSummaryText('timeperiod'); + } + + public function listRequiredPermissions() + { + return array('director/admin'); + } + + public function getUrl() + { + return 'director/timeperiods/templates'; + } +} diff --git a/library/Director/Dashboard/Dashlet/TimeperiodsDashlet.php b/library/Director/Dashboard/Dashlet/TimeperiodsDashlet.php new file mode 100644 index 0000000..5a54bec --- /dev/null +++ b/library/Director/Dashboard/Dashlet/TimeperiodsDashlet.php @@ -0,0 +1,25 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class TimeperiodsDashlet extends Dashlet +{ + protected $icon = 'calendar'; + + protected $requiredStats = array('timeperiod'); + + public function getTitle() + { + return $this->translate('Timeperiods'); + } + + public function getUrl() + { + return 'director/dashboard?name=timeperiods'; + } + + public function listRequiredPermissions() + { + return array('director/admin'); + } +} diff --git a/library/Director/Dashboard/Dashlet/UserGroupsDashlet.php b/library/Director/Dashboard/Dashlet/UserGroupsDashlet.php new file mode 100644 index 0000000..3fba4ba --- /dev/null +++ b/library/Director/Dashboard/Dashlet/UserGroupsDashlet.php @@ -0,0 +1,31 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class UserGroupsDashlet extends Dashlet +{ + protected $icon = 'tags'; + + public function getTitle() + { + return $this->translate('User Groups'); + } + + public function getSummary() + { + return $this->translate( + 'Defining Notifications for User Groups instead of single Users' + . ' gives more flexibility' + ); + } + + public function getUrl() + { + return 'director/usergroups'; + } + + public function listRequiredPermissions() + { + return array('director/admin'); + } +} diff --git a/library/Director/Dashboard/Dashlet/UserObjectDashlet.php b/library/Director/Dashboard/Dashlet/UserObjectDashlet.php new file mode 100644 index 0000000..463b84c --- /dev/null +++ b/library/Director/Dashboard/Dashlet/UserObjectDashlet.php @@ -0,0 +1,23 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +use DirectoryIterator; +use Icinga\Exception\ProgrammingError; + +class UserObjectDashlet extends Dashlet +{ + protected $icon = 'users'; + + protected $requiredStats = array('user', 'usergroup'); + + public function getTitle() + { + return $this->translate('Users / Contacts'); + } + + public function getUrl() + { + return 'director/users'; + } +} diff --git a/library/Director/Dashboard/Dashlet/UserTemplateDashlet.php b/library/Director/Dashboard/Dashlet/UserTemplateDashlet.php new file mode 100644 index 0000000..291ab05 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/UserTemplateDashlet.php @@ -0,0 +1,31 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class UserTemplateDashlet extends Dashlet +{ + protected $icon = 'cubes'; + + protected $requiredStats = array('user'); + + public function getTitle() + { + return $this->translate('User Templates'); + } + + public function getSummary() + { + return $this->translate('Provide templates for your User objects.') + . ' ' . $this->getTemplateSummaryText('user'); + } + + public function listRequiredPermissions() + { + return array('director/admin'); + } + + public function getUrl() + { + return 'director/users/templates'; + } +} diff --git a/library/Director/Dashboard/Dashlet/UsersDashlet.php b/library/Director/Dashboard/Dashlet/UsersDashlet.php new file mode 100644 index 0000000..43ddc26 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/UsersDashlet.php @@ -0,0 +1,25 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class UsersDashlet extends Dashlet +{ + protected $icon = 'users'; + + protected $requiredStats = array('user', 'usergroup'); + + public function getTitle() + { + return $this->translate('Users / Contacts'); + } + + public function listRequiredPermissions() + { + return array('director/users'); + } + + public function getUrl() + { + return 'director/dashboard?name=users'; + } +} diff --git a/library/Director/Dashboard/Dashlet/ZoneObjectDashlet.php b/library/Director/Dashboard/Dashlet/ZoneObjectDashlet.php new file mode 100644 index 0000000..ee789f2 --- /dev/null +++ b/library/Director/Dashboard/Dashlet/ZoneObjectDashlet.php @@ -0,0 +1,25 @@ +<?php + +namespace Icinga\Module\Director\Dashboard\Dashlet; + +class ZoneObjectDashlet extends Dashlet +{ + protected $icon = 'globe'; + + protected $requiredStats = array('zone'); + + public function getTitle() + { + return $this->translate('Zones'); + } + + public function getUrl() + { + return 'director/zones'; + } + + public function listRequiredPermissions() + { + return array('director/admin'); + } +} |