parent
2b094067a5
commit
66e5158ccc
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Controllers;
|
||||
|
||||
use Icinga\Exception\NotFoundError;
|
||||
use Icinga\Module\Director\Acl;
|
||||
use Icinga\Module\Director\Dashboard\Dashboard;
|
||||
use Icinga\Module\Director\Web\Controller\ActionController;
|
||||
|
||||
class DashboardController extends ActionController
|
||||
{
|
||||
public function indexAction()
|
||||
{
|
||||
if ($this->getRequest()->isGet()) {
|
||||
$this->setAutorefreshInterval(10);
|
||||
}
|
||||
|
||||
$this->view->title = $this->translate('Icinga Director');
|
||||
$this->singleTab($this->translate('Overview'));
|
||||
$dashboards = array();
|
||||
foreach (array('Objects', 'Deployment', 'Data') as $name) {
|
||||
$dashboard = Dashboard::loadByName($name, $this->db(), $this->view);
|
||||
if ($dashboard->isAvailable()) {
|
||||
$dashboards[$name] = $dashboard;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($dashboards)) {
|
||||
throw new NotFoundError('Got no "%s" dashboard for you', $name);
|
||||
}
|
||||
|
||||
$this->view->dashboards = $dashboards;
|
||||
}
|
||||
}
|
|
@ -4,125 +4,38 @@ namespace Icinga\Module\Director\Controllers;
|
|||
|
||||
use Exception;
|
||||
use Icinga\Module\Director\Db\Migrations;
|
||||
use Icinga\Module\Director\Objects\DirectorJob;
|
||||
use Icinga\Module\Director\Objects\ImportSource;
|
||||
use Icinga\Module\Director\Objects\SyncRule;
|
||||
use Icinga\Module\Director\Web\Controller\ActionController;
|
||||
|
||||
class IndexController extends ActionController
|
||||
class IndexController extends DashboardController
|
||||
{
|
||||
public function indexAction()
|
||||
{
|
||||
if ($this->getRequest()->isGet()) {
|
||||
$this->setAutorefreshInterval(10);
|
||||
}
|
||||
|
||||
if (! $this->Config()->get('db', 'resource')
|
||||
|| !$this->fetchStats()
|
||||
|| !$this->hasDeploymentEndpoint()
|
||||
) {
|
||||
$this->getTabs()->add('overview', array(
|
||||
'url' => $this->getRequest()->getUrl(),
|
||||
'label' => $this->translate('Configuration')
|
||||
))->activate('overview');
|
||||
$this->view->title = $this->translate('Configuration');
|
||||
$this->view->form = $this->loadForm('kickstart')->handleRequest();
|
||||
|
||||
} else {
|
||||
$this->getTabs()->add('overview', array(
|
||||
'url' => $this->getRequest()->getUrl(),
|
||||
'label' => $this->translate('Overview')
|
||||
))->activate('overview');
|
||||
$this->view->dashboards = array();
|
||||
|
||||
if ($this->Config()->get('db', 'resource')) {
|
||||
$migrations = new Migrations($this->db());
|
||||
|
||||
if ($migrations->hasPendingMigrations()) {
|
||||
$this->view->migrationsForm = $this
|
||||
if (! $migrations->hasSchema() || !$this->hasDeploymentEndpoint()) {
|
||||
$this->showKickstartForm();
|
||||
} elseif ($migrations->hasPendingMigrations()) {
|
||||
$this->view->form = $this
|
||||
->loadForm('applyMigrations')
|
||||
->setMigrations($migrations)
|
||||
->handleRequest();
|
||||
parent::indexAction();
|
||||
} else {
|
||||
parent::indexAction();
|
||||
}
|
||||
|
||||
try {
|
||||
$this->fetchSyncState()
|
||||
->fetchImportState()
|
||||
->fetchJobState();
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
} else {
|
||||
$this->showKickstartForm();
|
||||
}
|
||||
|
||||
$this->setViewScript('dashboard/index');
|
||||
}
|
||||
|
||||
protected function fetchSyncState()
|
||||
protected function showKickstartForm()
|
||||
{
|
||||
$syncs = SyncRule::loadAll($this->db());
|
||||
if (count($syncs) > 0) {
|
||||
$state = 'ok';
|
||||
} else {
|
||||
$state = null;
|
||||
}
|
||||
|
||||
foreach ($syncs as $sync) {
|
||||
if ($sync->sync_state !== 'in-sync') {
|
||||
if ($sync->sync_state === 'failing') {
|
||||
$state = 'critical';
|
||||
break;
|
||||
} else {
|
||||
$state = 'warning';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->view->syncState = $state;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function fetchImportState()
|
||||
{
|
||||
$srcs = ImportSource::loadAll($this->db());
|
||||
if (count($srcs) > 0) {
|
||||
$state = 'ok';
|
||||
} else {
|
||||
$state = null;
|
||||
}
|
||||
|
||||
foreach ($srcs as $src) {
|
||||
if ($src->import_state !== 'in-sync') {
|
||||
if ($src->import_state === 'failing') {
|
||||
$state = 'critical';
|
||||
break;
|
||||
} else {
|
||||
$state = 'warning';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->view->importState = $state;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function fetchJobState()
|
||||
{
|
||||
$jobs = DirectorJob::loadAll($this->db());
|
||||
if (count($jobs) > 0) {
|
||||
$state = 'ok';
|
||||
} else {
|
||||
$state = null;
|
||||
}
|
||||
|
||||
foreach ($jobs as $job) {
|
||||
if ($job->isPending()) {
|
||||
$state = 'pending';
|
||||
} elseif (! $job->lastAttemptSucceeded()) {
|
||||
$state = 'critical';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$this->view->jobState = $state;
|
||||
|
||||
return $this;
|
||||
$this->singleTab($this->translate('Kickstart'));
|
||||
$this->view->form = $this->loadForm('kickstart')->handleRequest();
|
||||
}
|
||||
|
||||
protected function hasDeploymentEndpoint()
|
||||
|
@ -135,16 +48,4 @@ class IndexController extends ActionController
|
|||
|
||||
return $this->view->hasDeploymentEndpoint;
|
||||
}
|
||||
|
||||
protected function fetchStats()
|
||||
{
|
||||
try {
|
||||
$this->view->stats = $this->db()->getObjectSummary();
|
||||
$this->view->undeployedActivities = $this->db()->countActivitiesSinceLastDeployedConfig();
|
||||
} catch (Exception $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,23 @@ class ApplyMigrationsForm extends QuickForm
|
|||
|
||||
public function setup()
|
||||
{
|
||||
$this->setSubmitLabel($this->translate('Apply schema migrations'));
|
||||
if ($this->migrations->hasSchema()) {
|
||||
$count = $this->migrations->countPendingMigrations();
|
||||
if ($count === 1) {
|
||||
$this->setSubmitLabel(
|
||||
$this->translate('Apply a pending schema migration')
|
||||
);
|
||||
} else {
|
||||
$this->setSubmitLabel(
|
||||
sprintf(
|
||||
$this->translate('Apply %d pending schema migrations'),
|
||||
$count
|
||||
)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$this->setSubmitLabel($this->translate('Create schema'));
|
||||
}
|
||||
}
|
||||
|
||||
public function onSuccess()
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<div class="controls">
|
||||
<?= $this->tabs ?>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<?php if ($this->errorMessage): ?>
|
||||
<p class="error"><?= $this->errorMessage ?></p>
|
||||
<?php endif ?>
|
||||
<?= $this->form ?>
|
||||
<?php foreach ($this->dashboards as $dashboard): ?>
|
||||
<h1><?= $this->escape($dashboard->getTitle()) ?></h1>
|
||||
<ul class="main-actions" data-base-target="_next">
|
||||
<?php foreach ($dashboard->dashlets() as $dashlet): ?>
|
||||
<li>
|
||||
<?= $dashlet->render() ?>
|
||||
</li>
|
||||
<?php endforeach ?>
|
||||
</ul>
|
||||
<?php endforeach ?>
|
||||
</div>
|
|
@ -0,0 +1,5 @@
|
|||
<a<?= $dashlet->renderClassAttribute()?> href="<?= $this->url($dashlet->getUrl()) ?>">
|
||||
<?= $this->escape($dashlet->getTitle()) ?>
|
||||
<?= $this->icon($this->dashlet->getIconName()) ?>
|
||||
<p><?= $dashlet->getEscapedSummary() ?></p>
|
||||
</a>
|
|
@ -1,17 +0,0 @@
|
|||
<h1 style="clear: both"><?= $this->escape($title) ?></h1>
|
||||
<ul class="main-actions" data-base-target="_next">
|
||||
<?php foreach ($actions as $a): ?>
|
||||
<li>
|
||||
<a<?php
|
||||
if (array_key_exists(4, $a)) {
|
||||
echo ' class="state-' . $a[4] . '"';
|
||||
}
|
||||
?> href="<?= $this->url($a[2]) ?>">
|
||||
<?= $this->icon($a[0]) ?>
|
||||
<?= $this->escape($a[1]) ?>
|
||||
<p><?= $a[3] ?></p>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach ?>
|
||||
</ul>
|
||||
|
|
@ -1,127 +0,0 @@
|
|||
<div class="controls">
|
||||
<?= $this->tabs ?>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<?php if ($this->errorMessage): ?>
|
||||
<p class="error"><?= $this->errorMessage ?></p>
|
||||
<?php endif ?>
|
||||
<?php if (! $this->stats): ?>
|
||||
<?= $this->form ?>
|
||||
</div>
|
||||
<?php return; endif ?>
|
||||
<?php
|
||||
|
||||
function statSummary($self, $type) {
|
||||
$stat = $self->stats[$type];
|
||||
|
||||
if ((int) $stat->cnt_total === 0) {
|
||||
return $self->translate('No object has been defined yet');
|
||||
}
|
||||
|
||||
if ((int) $stat->cnt_total === 1) {
|
||||
if ($stat->cnt_template > 0) {
|
||||
$msg = $self->translate('One template has been defined');
|
||||
} elseif ($stat->cnt_external > 0) {
|
||||
$msg = $self->translate('One external object has been defined, it will not be deployed');
|
||||
} else {
|
||||
$msg = $self->translate('One object has been defined');
|
||||
}
|
||||
|
||||
} else {
|
||||
$msg = sprintf(
|
||||
$self->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(
|
||||
$self->translate('%d of them are templates'),
|
||||
$stat->cnt_template
|
||||
);
|
||||
}
|
||||
if ($stat->cnt_external > 0) {
|
||||
$extra[] = sprintf(
|
||||
$self->translate('%d have been externally defined and will not be deployed'),
|
||||
$stat->cnt_external
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists($type . 'group', $self->stats)) {
|
||||
$groupstat = $self->stats[$type . 'group'];
|
||||
if ((int) $groupstat->cnt_total === 0) {
|
||||
$extra[] = $self->translate('no related group exists');
|
||||
} elseif ((int) $groupstat->cnt_total === 1) {
|
||||
$extra[] = $self->translate('one related group exists');
|
||||
} else {
|
||||
$extra[] = sprintf(
|
||||
$self->translate('%s related group objects have been created'),
|
||||
$groupstat->cnt_total
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($extra)) {
|
||||
return $msg;
|
||||
}
|
||||
|
||||
return $msg . ', ' . implode(', ', $extra);
|
||||
}
|
||||
|
||||
function pendingDeployments($self) {
|
||||
if ($self->undeployedActivities === 0) return '';
|
||||
return '. <span class="error">' . sprintf(
|
||||
$self->translate('A total of %d config changes happened since your last deployed config has been rendered'),
|
||||
$self->undeployedActivities
|
||||
) . '</span>';
|
||||
}
|
||||
if (!$this->hasDeploymentEndpoint) {
|
||||
echo $this->form;
|
||||
}
|
||||
|
||||
if ($this->migrationsForm) {
|
||||
echo '<h1>' . $this->translate('There are pending database schema migrations') . "</h2>\n";
|
||||
echo $this->migrationsForm;
|
||||
}
|
||||
|
||||
$all = array(
|
||||
$this->translate('Define whatever you want to be monitored') => array(
|
||||
array('host', $this->translate('Host objects'), 'director/hosts', statSummary($this, 'host')),
|
||||
array('services', $this->translate('Monitored Services'), 'director/services', statSummary($this, 'service')),
|
||||
array('wrench', $this->translate('Commands'), 'director/commands', statSummary($this, 'command')),
|
||||
array('users', $this->translate('Users / Contacts'), 'director/users', statSummary($this, 'user')),
|
||||
array('megaphone', $this->translate('Notifications'), 'director/notifications', $this->translate('Schedule your notifications.') . ' ' . statSummary($this, 'notification')),
|
||||
array('calendar', $this->translate('Timeperiods'), 'director/timeperiods', statSummary($this, 'timeperiod')),
|
||||
),
|
||||
$this->translate('Deploy configuration to your Icinga nodes') => array(
|
||||
array('wrench', $this->translate('Deployment'), 'director/config/deployments', $this->translate('Config deployment') . pendingDeployments($this), $this->undeployedActivities ? 'warning' : 'ok'),
|
||||
array('book', $this->translate('Activity Log'), 'director/config/activities', $this->translate('Wondering about what changed why? Track your changes!'), 'ok'),
|
||||
array('lock-open-alt', $this->translate('Api users'), 'director/apiusers', statSummary($this, 'apiuser')),
|
||||
array('cloud', $this->translate('Endpoints'), 'director/endpoints', statSummary($this, 'endpoint') . ( $this->hasDeploymentEndpoint ? '' : '. ' . $this->translate('None could be used for deployments right now')), $this->hasDeploymentEndpoint ? '' : 'critical'),
|
||||
array('globe', $this->translate('Zones'), 'director/zones', statSummary($this, 'zone')),
|
||||
),
|
||||
$this->translate('Do more with your data') => array(
|
||||
array('database', $this->translate('Import data sources'), 'director/list/importsource', $this->translate('Define and manage imports from various data sources'), $this->importState),
|
||||
array('flapping', $this->translate('Synchronize'), 'director/list/syncrule', $this->translate('Define how imported data should be synchronized with Icinga'), $this->syncState),
|
||||
array('clock', $this->translate('Jobs'), 'director/jobs', $this->translate('Schedule and automate Import, Syncronization, Config Deployment, Housekeeping and more'), $this->jobState),
|
||||
array('edit', $this->translate('Define data fields'), 'director/data/fields', $this->translate('Data fields make sure that configuration fits your rules')),
|
||||
array('sort-name-up', $this->translate('Provide data lists'), 'director/data/lists', $this->translate('Provide data lists to make life easier for your users')),
|
||||
)
|
||||
);
|
||||
?>
|
||||
|
||||
<?php foreach ($all as $title => $actions): ?>
|
||||
<?= $this->partial(
|
||||
'index/actions.phtml',
|
||||
array(
|
||||
'actions' => $actions,
|
||||
'title' => $title,
|
||||
)
|
||||
) ?>
|
||||
<?php endforeach ?>
|
||||
</div>
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Director;
|
||||
|
||||
use Icinga\Authentication\Auth;
|
||||
use Icinga\Exception\AuthenticationException;
|
||||
|
||||
class Acl
|
||||
{
|
||||
protected $auth;
|
||||
|
||||
private static $instance;
|
||||
|
||||
public static function instance()
|
||||
{
|
||||
if (self::$instance === null) {
|
||||
self::$instance = new static(Auth::getInstance());
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
public function __construct(Auth $auth)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
}
|
||||
|
||||
public function hasPermission($name)
|
||||
{
|
||||
return $this->auth->hasPermission($name);
|
||||
}
|
||||
|
||||
protected function getUser()
|
||||
{
|
||||
if (null === ($user = $this->auth->getUser())) {
|
||||
throw new AuthenticationException('Authenticated user required');
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
public function listRoleNames()
|
||||
{
|
||||
return array_map(
|
||||
array($this, 'getNameForRole'),
|
||||
$this->getUser()->getRoles()
|
||||
);
|
||||
}
|
||||
|
||||
protected function getNameForRole($role)
|
||||
{
|
||||
return $role->getName();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Dashboard;
|
||||
|
||||
use Countable;
|
||||
use Exception;
|
||||
use Icinga\Web\View;
|
||||
use Icinga\Module\Director\Dashboard\Dashlet\Dashlet;
|
||||
use Icinga\Module\Director\Db;
|
||||
use Zend_Db_Select as ZfSelect;
|
||||
|
||||
abstract class Dashboard implements Countable
|
||||
{
|
||||
protected $name;
|
||||
|
||||
protected $dashlets;
|
||||
|
||||
protected $dashletNames;
|
||||
|
||||
protected $db;
|
||||
|
||||
protected $view;
|
||||
|
||||
final private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public static function loadByName($name, Db $db, View $view)
|
||||
{
|
||||
$class = __NAMESPACE__ . '\\' . ucfirst($name) . 'Dashboard';
|
||||
$dashboard = new $class();
|
||||
$dashboard->db = $db;
|
||||
$dashboard->name = $name;
|
||||
$dashboard->view = $view;
|
||||
return $dashboard;
|
||||
}
|
||||
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
abstract public function getTitle();
|
||||
|
||||
abstract public function getDescription();
|
||||
|
||||
public function count()
|
||||
{
|
||||
return count($this->dashlets());
|
||||
}
|
||||
|
||||
public function isAvailable()
|
||||
{
|
||||
return $this->count() > 0;
|
||||
}
|
||||
|
||||
public function getDb()
|
||||
{
|
||||
return $this->db;
|
||||
}
|
||||
|
||||
public function getView()
|
||||
{
|
||||
return $this->view;
|
||||
}
|
||||
|
||||
protected function translate($msg)
|
||||
{
|
||||
return $this->view->translate($msg);
|
||||
}
|
||||
|
||||
public function dashlets()
|
||||
{
|
||||
if ($this->dashlets === null) {
|
||||
if ($this->dashletNames === null) {
|
||||
$this->dashlets = Dashlet::loadAll($this);
|
||||
} else {
|
||||
$this->dashlets = Dashlet::loadByNames(
|
||||
$this->dashletNames,
|
||||
$this
|
||||
);
|
||||
}
|
||||
$this->fetchDashletSummaries();
|
||||
}
|
||||
|
||||
return $this->dashlets;
|
||||
}
|
||||
|
||||
protected function fetchDashletSummaries()
|
||||
{
|
||||
$types = array();
|
||||
foreach ($this->dashlets as $dashlet) {
|
||||
foreach ($dashlet->listRequiredStats() as $objectType) {
|
||||
$types[$objectType] = $objectType;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($types)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$stats = $this->getObjectSummary($types);
|
||||
} catch (Exception $e) {
|
||||
$stats = array();
|
||||
}
|
||||
|
||||
$failing = array();
|
||||
foreach ($this->dashlets as $key => $dashlet) {
|
||||
foreach ($dashlet->listRequiredStats() as $objectType) {
|
||||
if (array_key_exists($objectType, $stats)) {
|
||||
$dashlet->addStats($objectType, $stats[$objectType]);
|
||||
} else {
|
||||
$failing[] = $key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($failing as $key) {
|
||||
unset($this->dashlets[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
public function getObjectSummary($types)
|
||||
{
|
||||
$queries = array();
|
||||
|
||||
foreach ($types as $type) {
|
||||
$queries[] = $this->makeSummaryQuery($type);
|
||||
}
|
||||
|
||||
$query = $this->db->select()->union($queries, ZfSelect::SQL_UNION_ALL);
|
||||
$result = array();
|
||||
foreach ($this->db->fetchAll($query) as $row) {
|
||||
$result[$row->icinga_type] = $row;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function makeSummaryQuery($type)
|
||||
{
|
||||
return $this->db->select()->from(
|
||||
array('o' => 'icinga_' . $type),
|
||||
array(
|
||||
'icinga_type' => "('" . $type . "')",
|
||||
'cnt_object' => $this->getCntSql('object'),
|
||||
'cnt_template' => $this->getCntSql('template'),
|
||||
'cnt_external' => $this->getCntSql('external_object'),
|
||||
'cnt_total' => 'COUNT(*)',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
protected function getCntSql($objectType)
|
||||
{
|
||||
return sprintf(
|
||||
"COALESCE(SUM(CASE WHEN o.object_type = '%s' THEN 1 ELSE 0 END), 0)",
|
||||
$objectType
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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 getEscapedSummary()
|
||||
{
|
||||
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/activitylog');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?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('Api users');
|
||||
}
|
||||
|
||||
public function getUrl()
|
||||
{
|
||||
return 'director/apiusers';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Dashboard\Dashlet;
|
||||
|
||||
class CommandObjectDashlet extends Dashlet
|
||||
{
|
||||
protected $icon = 'wrench';
|
||||
|
||||
protected $requiredStats = array('command');
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->view->translate('Commands');
|
||||
}
|
||||
|
||||
public function getUrl()
|
||||
{
|
||||
return 'director/commands';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,239 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Dashboard\Dashlet;
|
||||
|
||||
use DirectoryIterator;
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
use Icinga\Web\View;
|
||||
use Icinga\Module\Director\Acl;
|
||||
use Icinga\Module\Director\Dashboard\Dashboard;
|
||||
|
||||
abstract class Dashlet
|
||||
{
|
||||
protected $sectionName;
|
||||
|
||||
protected $icon = 'help';
|
||||
|
||||
protected $supportsLegacyConfig;
|
||||
|
||||
protected $view;
|
||||
|
||||
protected $db;
|
||||
|
||||
protected $stats;
|
||||
|
||||
protected $requiredStats = array();
|
||||
|
||||
public function __construct(Dashboard $dashboard)
|
||||
{
|
||||
$this->view = $dashboard->getView();
|
||||
$this->db = $dashboard->getDb();
|
||||
}
|
||||
|
||||
public function listRequiredStats()
|
||||
{
|
||||
return $this->requiredStats;
|
||||
}
|
||||
|
||||
public function addStats($type, $stats)
|
||||
{
|
||||
$this->stats[$type] = $stats;
|
||||
}
|
||||
|
||||
public static function loadAll(Dashboard $dashboard)
|
||||
{
|
||||
$dashlets = array();
|
||||
|
||||
foreach (new DirectoryIterator(__DIR__) as $file) {
|
||||
if ($file->isDot()) {
|
||||
continue;
|
||||
}
|
||||
$filename = $file->getFilename();
|
||||
if (preg_match('/^(\w+)Dashlet\.php$/', $filename, $match)) {
|
||||
$dashlet = static::loadByName($match[1], $dashboard);
|
||||
|
||||
if ($dashlet->isAllowed()) {
|
||||
$dashlets[] = $dashlet;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $dashlets;
|
||||
}
|
||||
|
||||
public static function loadByName($name, Dashboard $dashboard)
|
||||
{
|
||||
$class = __NAMESPACE__ . '\\' . $name . 'Dashlet';
|
||||
return new $class($dashboard);
|
||||
}
|
||||
|
||||
public static function loadByNames(array $names, Dashboard $dashboard)
|
||||
{
|
||||
$prefix = __NAMESPACE__ . '\\';
|
||||
$dashlets = array();
|
||||
foreach ($names as $name) {
|
||||
$class = $prefix . $name . 'Dashlet';
|
||||
$dashlet = new $class($dashboard);
|
||||
|
||||
if ($dashlet->isAllowed()) {
|
||||
$dashlets[] = $dashlet;
|
||||
}
|
||||
}
|
||||
|
||||
return $dashlets;
|
||||
}
|
||||
|
||||
public function renderClassAttribute()
|
||||
{
|
||||
$classes = $this->listCssClasses();
|
||||
if (empty($classes)) {
|
||||
return '';
|
||||
} else {
|
||||
if (! is_array($classes)) {
|
||||
$classes = array($classes);
|
||||
}
|
||||
|
||||
return ' class="' . implode(' ', $classes) . '"';
|
||||
}
|
||||
}
|
||||
|
||||
public function listCssClasses()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
public function getSectionName()
|
||||
{
|
||||
if ($this->sectionName === null) {
|
||||
throw new ProgrammingError(
|
||||
'Dashlets without a sectionName are not allowed'
|
||||
);
|
||||
}
|
||||
|
||||
return $this->sectionName;
|
||||
}
|
||||
|
||||
public function getIconName()
|
||||
{
|
||||
return $this->icon;
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return $this->view->partial(
|
||||
'dashlets/' . $this->getViewScript() . '.phtml',
|
||||
array('dashlet' => $this)
|
||||
);
|
||||
}
|
||||
|
||||
public function listRequiredPermissions()
|
||||
{
|
||||
return array($this->getUrl());
|
||||
}
|
||||
|
||||
public function getViewScript()
|
||||
{
|
||||
return 'default';
|
||||
}
|
||||
|
||||
public function isAllowed()
|
||||
{
|
||||
$acl = Acl::instance();
|
||||
foreach ($this->listRequiredPermissions() as $perm) {
|
||||
if (! $acl->hasPermission($perm)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getSummary()
|
||||
{
|
||||
$result = '';
|
||||
if (! empty($this->requiredStats)) {
|
||||
$result .= $this->statSummary(current($this->requiredStats));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getEscapedSummary()
|
||||
{
|
||||
return $this->view->escape(
|
||||
$this->getSummary()
|
||||
);
|
||||
}
|
||||
|
||||
protected function translate($msg)
|
||||
{
|
||||
return $this->view->translate($msg);
|
||||
}
|
||||
|
||||
protected function statSummary($type)
|
||||
{
|
||||
$view = $this->view;
|
||||
$stat = $this->stats[$type];
|
||||
|
||||
if ((int) $stat->cnt_total === 0) {
|
||||
return $view->translate('No object has been defined yet');
|
||||
}
|
||||
|
||||
if ((int) $stat->cnt_total === 1) {
|
||||
if ($stat->cnt_template > 0) {
|
||||
$msg = $view->translate('One template has been defined');
|
||||
} elseif ($stat->cnt_external > 0) {
|
||||
$msg = $view->translate(
|
||||
'One external object has been defined, it will not be deployed'
|
||||
);
|
||||
} else {
|
||||
$msg = $view->translate('One object has been defined');
|
||||
}
|
||||
|
||||
} else {
|
||||
$msg = sprintf(
|
||||
$view->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(
|
||||
$view->translate('%d of them are templates'),
|
||||
$stat->cnt_template
|
||||
);
|
||||
}
|
||||
if ($stat->cnt_external > 0) {
|
||||
$extra[] = sprintf(
|
||||
$view->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[] = $view->translate('no related group exists');
|
||||
} elseif ((int) $groupstat->cnt_total === 1) {
|
||||
$extra[] = $view->translate('one related group exists');
|
||||
} else {
|
||||
$extra[] = sprintf(
|
||||
$view->translate('%s related group objects have been created'),
|
||||
$groupstat->cnt_total
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($extra)) {
|
||||
return $msg;
|
||||
}
|
||||
|
||||
return $msg . ', ' . implode(', ', $extra);
|
||||
}
|
||||
}
|
|
@ -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 getEscapedSummary()
|
||||
{
|
||||
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/data');
|
||||
}
|
||||
}
|
|
@ -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 getEscapedSummary()
|
||||
{
|
||||
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/data');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Dashboard\Dashlet;
|
||||
|
||||
use DirectoryIterator;
|
||||
use Exception;
|
||||
use Icinga\Module\Director\Objects\DirectorDeploymentLog;
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
|
||||
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');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
<?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';
|
||||
}
|
||||
|
||||
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';
|
||||
}
|
||||
}
|
||||
|
||||
public function getSummary()
|
||||
{
|
||||
$msg = parent::getSummary();
|
||||
if (! $this->hasDeploymentEndpoint()) {
|
||||
$msg .= '. ' . $this->translate(
|
||||
'None could be used for deployments right now'
|
||||
);
|
||||
}
|
||||
|
||||
return $msg;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Dashboard\Dashlet;
|
||||
|
||||
use DirectoryIterator;
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
|
||||
class HostObjectDashlet extends Dashlet
|
||||
{
|
||||
protected $icon = 'host';
|
||||
|
||||
protected $requiredStats = array('host', 'hostgroup');
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->translate('Host objects');
|
||||
}
|
||||
|
||||
public function getUrl()
|
||||
{
|
||||
return 'director/hosts';
|
||||
}
|
||||
}
|
|
@ -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/list/importsource';
|
||||
}
|
||||
|
||||
public function listRequiredPermissions()
|
||||
{
|
||||
return array('director/sync');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
<?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()
|
||||
{
|
||||
$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';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Dashboard\Dashlet;
|
||||
|
||||
use DirectoryIterator;
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
|
||||
class NotificationObjectDashlet extends Dashlet
|
||||
{
|
||||
protected $icon = 'megaphone';
|
||||
|
||||
protected $requiredStats = array('notification');
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->translate('Notifications.');
|
||||
}
|
||||
|
||||
public function getSummary()
|
||||
{
|
||||
return $this->translate('Schedule your notifications.')
|
||||
. ' ' . parent::getSummary();
|
||||
}
|
||||
|
||||
public function getUrl()
|
||||
{
|
||||
return 'director/notifications';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Dashboard\Dashlet;
|
||||
|
||||
use DirectoryIterator;
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
|
||||
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/services';
|
||||
}
|
||||
}
|
|
@ -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/list/syncrule';
|
||||
}
|
||||
|
||||
public function listRequiredPermissions()
|
||||
{
|
||||
return array('director/sync');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<?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';
|
||||
}
|
||||
}
|
|
@ -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';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?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';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Dashboard;
|
||||
|
||||
use Icinga\Module\Director\Dashboard\Dashlet\Dashlet;
|
||||
|
||||
class DataDashboard extends Dashboard
|
||||
{
|
||||
protected $name;
|
||||
|
||||
protected $dashletNames = array(
|
||||
'ImportSource',
|
||||
'Sync',
|
||||
'Job',
|
||||
'Datafield',
|
||||
'Datalist',
|
||||
);
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->translate('Do more with your data');
|
||||
}
|
||||
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->translate('...');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Dashboard;
|
||||
|
||||
use Icinga\Module\Director\Dashboard\Dashlet\Dashlet;
|
||||
|
||||
class DeploymentDashboard extends Dashboard
|
||||
{
|
||||
protected $name;
|
||||
|
||||
protected $dashletNames = array(
|
||||
'Deployment',
|
||||
'ActivityLog',
|
||||
'ApiUserObject',
|
||||
'EndpointObject',
|
||||
'ZoneObject',
|
||||
);
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->translate('Deploy configuration to your Icinga nodes');
|
||||
}
|
||||
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->translate('...');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Dashboard;
|
||||
|
||||
use Countable;
|
||||
|
||||
use Icinga\Module\Director\Dashboard\Dashlet\Dashlet;
|
||||
|
||||
class ObjectsDashboard extends Dashboard
|
||||
{
|
||||
protected $name;
|
||||
|
||||
protected $dashletNames = array(
|
||||
'HostObject',
|
||||
'ServiceObject',
|
||||
'CommandObject',
|
||||
'UserObject',
|
||||
'NotificationObject',
|
||||
'TimeperiodObject',
|
||||
);
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->translate('Define whatever you want to be monitored');
|
||||
}
|
||||
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->translate('...');
|
||||
}
|
||||
}
|
|
@ -50,6 +50,16 @@ class DirectorDeploymentLog extends DbObject
|
|||
return $this->config;
|
||||
}
|
||||
|
||||
public function isPending()
|
||||
{
|
||||
return $this->dump_succeeded === 'y' && $this->startup_log === null;
|
||||
}
|
||||
|
||||
public function succeeded()
|
||||
{
|
||||
return $this->startup_succeeded === 'y';
|
||||
}
|
||||
|
||||
public function configEquals(IcingaConfig $config)
|
||||
{
|
||||
return $this->config_checksum === $config->getChecksum();
|
||||
|
|
Loading…
Reference in New Issue