Skip to content

Commit

Permalink
Render pending migration overview as child of Status nav
Browse files Browse the repository at this point in the history
  • Loading branch information
yhabteab committed Jul 26, 2023
1 parent f6b92ca commit f00b9d6
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 4 deletions.
154 changes: 153 additions & 1 deletion application/controllers/StatusController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,22 @@

namespace Icinga\Controllers;

use Icinga\Application\Hook;
use Icinga\Application\Hook\HealthHook;
use Icinga\Application\Hook\MigrationHook;
use Icinga\Web\Notification;
use Icinga\Web\View\AppHealth;
use Icinga\Web\Widget\Migrations;
use Icinga\Web\Widget\Tabextension\OutputFormat;
use ipl\Html\Form;
use ipl\Html\Html;
use ipl\Html\HtmlElement;
use ipl\Html\HtmlString;
use ipl\Html\Text;
use ipl\Web\Compat\CompatController;
use ipl\Web\Url;
use ipl\Web\Widget\ActionLink;
use ipl\Web\Widget\StateBadge;

class StatusController extends CompatController
{
Expand Down Expand Up @@ -46,11 +56,127 @@ public function indexAction()
]));
$this->addControl(HtmlString::create((string) $this->view->filterEditor));

$this->addTitleTab($this->translate('Health'));
$this->initTabs();
$this->getTabs()->activate('health');

$this->setAutorefreshInterval(10);
$this->addContent(new AppHealth($query));
}

public function migrationListAction()
{
$migrations = MigrationHook::collectMigrations()
->select();

$this->setupSortControl(
[
'name' => $this->translate('Name'),
'module' => $this->translate('Module'),
'count' => $this->translate('Migration Counts'),
],
$migrations,
['name' => 'DESC']
);
$this->setupLimitControl();
$this->setupPaginationControl($migrations);
$this->setupFilterControl($migrations, [
'name' => $this->translate('Name'),
'state' => $this->translate('State'),
], ['name']);

$this->addControl(HtmlString::create((string) $this->view->paginator));
$this->addControl(HtmlElement::create('div', ['class' => 'sort-controls-container'], [
HtmlString::create((string) $this->view->limiter),
HtmlString::create((string) $this->view->sortBox)
]));
$this->addControl(HtmlString::create((string) $this->view->filterEditor));

$this->controls->getAttributes()->add('class', 'separated');

$this->initTabs();
$this->getTabs()->activate('migrations');
$this->getTabs()->disableLegacyExtensions();

$this->setAutorefreshInterval(30);
$this->addContent(new Migrations($migrations, function (Form $form) {
$form->on(Form::ON_SUCCESS, function (Form $form) {
$this->assertPermission('application/migrations');

$name = $form->getValue(MigrationHook::MIGRATE_PARAM);
if ($name !== MigrationHook::ALL_MODULES) {
$migration = MigrationHook::getMigration($name);
if ($migration->apply()) {
Notification::success($this->translate('Applied pending migrations successfully'));
} else {
Notification::error(
$this->translate('Failed to apply pending migration(s). See logs for details')
);
}
} else {
$succeeded = true;
/** @var MigrationHook $hook */
foreach (Hook::all('migration') as $hook) {
if (! $hook->isModule()) {
continue;
}

if (! $hook->apply() && $succeeded) {
$succeeded = false;
}
}

if (! $succeeded) {
Notification::error($this->translate(
'Applied migrations successfully. Though, one or more migration hooks failed to run.'
. ' See logs for details'
));
} else {
Notification::success($this->translate('Applied all migrations successfully'));
}
}

$this->redirectNow(Url::fromRequest());
})
->handleRequest($this->getServerRequest());
}));
}

public function migrationHintAction()
{
$name = $this->getRequest()->getParam(MigrationHook::MIGRATE_PARAM);
$hook = MigrationHook::getMigration($name);

$hint = HtmlElement::create('div', ['class' => 'pending-migrations-hint']);
$hint->addHtml(HtmlElement::create('h2', null, Text::create($this->translate('Error!'))));
$hint->addHtml(
HtmlElement::create(
'p',
null,
Text::create(
sprintf(
$this->translatePlural(
'%s has %d pending migration.',
'%s has %d pending migrations.',
$hook->count()
),
$hook->getName(),
$hook->count()
)
)
)
);

$hint->addHtml(
HtmlElement::create('p', null, Text::create($this->translate('Please apply the migrations first.'))),
new ActionLink($this->translate('View pending Migrations'), Url::fromPath('status/migration-list'))
);

$this->addTitleTab($this->translate('Error'));
$this->getTabs()->disableLegacyExtensions();

$this->addContent($hint);
}

protected function handleFormatRequest($query)
{
$formatJson = $this->params->get('format') === 'json';
Expand All @@ -63,4 +189,30 @@ protected function handleFormatRequest($query)
->setSuccessData($query->fetchAll())
->sendResponse();
}

protected function initTabs()
{
[$state, $_, $healthCount] = HealthHook::getHealthCount();
$healthTab = [
'label' => $this->translate('Health'),
'url' => Url::fromPath('status'),
];
if ($state) {
$healthTab['stateBadge'] = new StateBadge($healthCount, $state);
}

$migrationsTab = [
'label' => $this->translate('Migrations'),
'url' => Url::fromPath('status/migration-list'),
];

$migrationCount = MigrationHook::countAll();
if ($migrationCount > 0) {
$migrationsTab['stateBadge'] = new StateBadge($migrationCount, 'warning');
}

$this->getTabs()
->add('health', $healthTab)
->add('migrations', $migrationsTab);
}
}
6 changes: 4 additions & 2 deletions library/Icinga/Web/Navigation/ConfigMenu.php
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,10 @@ protected function createHealthBadge()
[$state, $_, $healthCount] = HealthHook::getHealthCount();
$this->state = $state;

if ($healthCount > 0) {
$stateBadge = new StateBadge($healthCount, $this->state);
$migrationsCount = MigrationHook::countAll();
$total = $healthCount + $migrationsCount;
if ($total > 0) {
$stateBadge = new StateBadge($total, $healthCount > 0 ? $this->state : static::STATE_WARNING);
$stateBadge->addAttributes(['class' => 'disabled']);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
namespace Icinga\Web\Navigation\Renderer;

use Icinga\Application\Hook\HealthHook;
use Icinga\Application\Hook\MigrationHook;

class StatusNavigationRenderer extends BadgeNavigationItemRenderer
{
Expand All @@ -14,6 +15,12 @@ public function getCount()
$this->title = $title;
$this->state = $state;

return $count;
$migrationCount = MigrationHook::countAll();
if ($count === 0 && $migrationCount > 0) {
$this->state = static::STATE_WARNING;
$this->title = t('Pending migrations');
}

return $count + $migrationCount;
}
}

0 comments on commit f00b9d6

Please sign in to comment.