Skip to content

Commit

Permalink
migrate: Deprecate navigation command (#5148)
Browse files Browse the repository at this point in the history
  • Loading branch information
nilmerg committed Nov 13, 2023
2 parents a1cd968 + c88c1ba commit f676685
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 209 deletions.
183 changes: 4 additions & 179 deletions modules/migrate/application/clicommands/NavigationCommand.php
Expand Up @@ -4,192 +4,17 @@

namespace Icinga\Module\Migrate\Clicommands;

use Icinga\Application\Config;
use Icinga\Application\Icinga;
use Icinga\Application\Logger;
use Icinga\Cli\Command;
use Icinga\Data\ConfigObject;
use Icinga\Exception\NotReadableError;
use Icinga\Exception\NotWritableError;
use Icinga\Module\Icingadb\Compat\UrlMigrator;
use Icinga\Util\DirectoryIterator;
use Icinga\Web\Request;
use ipl\Web\Filter\QueryString;
use ipl\Web\Url;

class NavigationCommand extends Command
{
/**
* Migrate local user monitoring navigation items to the Icinga DB Web actions
*
* USAGE
*
* icingacli migrate navigation [options]
*
* OPTIONS:
*
* --user=<username> Migrate monitoring navigation items only for
* the given user. (Default *)
*
* --delete Remove the legacy files after successfully
* migrated the navigation items.
* Deprecated. Use `icingacli icingadb migrate navigation` instead.
*/
public function indexAction()
public function indexAction(): void
{
$moduleManager = Icinga::app()->getModuleManager();
if (! $moduleManager->hasEnabled('icingadb')) {
Logger::error('Icinga DB module is not enabled. Please verify that the module is installed and enabled.');
return;
}

$preferencesPath = Config::resolvePath('preferences');
$sharedNavigation = Config::resolvePath('navigation');
if (! file_exists($preferencesPath) && ! file_exists($sharedNavigation)) {
Logger::info('There are no local user navigation items to migrate');
return;
}

$rc = 0;
$user = $this->params->get('user');
$directories = new DirectoryIterator($preferencesPath);

foreach ($directories as $directory) {
$username = $user;
if ($username !== null && $directories->key() !== $username) {
continue;
}

if ($username === null) {
$username = $directories->key();
}

$hostActions = $this->readFromIni($directory . '/host-actions.ini', $rc);
$serviceActions = $this->readFromIni($directory . '/service-actions.ini', $rc);

Logger::info('Migrating monitoring navigation items for user "%s" to the Icinga DB Web actions', $username);

if (! $hostActions->isEmpty()) {
$this->migrateNavigationItems($hostActions, $directory . '/icingadb-host-actions.ini', $rc);
}

if (! $serviceActions->isEmpty()) {
$this->migrateNavigationItems($serviceActions, $directory . '/icingadb-service-actions.ini', $rc);
}
}

// Start migrating shared navigation items
$hostActions = $this->readFromIni($sharedNavigation . '/host-actions.ini', $rc);
$serviceActions = $this->readFromIni($sharedNavigation . '/service-actions.ini', $rc);

Logger::info('Migrating shared monitoring navigation items to the Icinga DB Web actions');

if (! $hostActions->isEmpty()) {
$this->migrateNavigationItems($hostActions, $sharedNavigation . '/icingadb-host-actions.ini', $rc);
}

if (! $serviceActions->isEmpty()) {
$this->migrateNavigationItems($serviceActions, $sharedNavigation . '/icingadb-service-actions.ini', $rc);
}

if ($rc > 0) {
Logger::error('Failed to migrate some monitoring navigation items');
exit($rc);
}

Logger::info('Successfully migrated all local user monitoring navigation items');
}

/**
* Migrate the given config to the given new config path
*
* @param Config $config
* @param string $path
* @param int $rc
*/
private function migrateNavigationItems($config, $path, &$rc)
{
$deleteLegacyFiles = $this->params->get('delete');
$newConfig = $this->readFromIni($path, $rc);
$counter = 1;

/** @var ConfigObject $configObject */
foreach ($config->getConfigObject() as $configObject) {
// Change the config type from "host-action" to icingadb's new action
if (strpos($path, 'icingadb-host-actions') !== false) {
$configObject->type = 'icingadb-host-action';
} else {
$configObject->type = 'icingadb-service-action';
}

$urlString = $configObject->get('url');
if ($urlString !== null) {
$url = Url::fromPath($urlString, [], new Request());

try {
$urlString = UrlMigrator::transformUrl($url)->getAbsoluteUrl();
$configObject->url = rawurldecode($urlString);
} catch (\InvalidArgumentException $err) {
// Do nothing
}
}

$legacyFilter = $configObject->get('filter');
if ($legacyFilter !== null) {
$filter = QueryString::parse($legacyFilter);
$filter = UrlMigrator::transformFilter($filter);
if ($filter !== false) {
$configObject->filter = rawurldecode(QueryString::render($filter));
} else {
unset($configObject->filter);
}
}

$section = $config->key();
while ($newConfig->hasSection($section)) {
$section = $config->key() . $counter++;
}

$newConfig->setSection($section, $configObject);
}

try {
if (! $newConfig->isEmpty()) {
$newConfig->saveIni();

// Remove the legacy file only if explicitly requested
if ($deleteLegacyFiles) {
unlink($config->getConfigFile());
}
}
} catch (NotWritableError $error) {
Logger::error('%s: %s', $error->getMessage(), $error->getPrevious()->getMessage());
$rc = 256;
}
}

/**
* Get the navigation items config from the given ini path
*
* @param string $path Absolute path of the ini file
* @param int $rc The return code used to exit the action
*
* @return Config
*/
private function readFromIni($path, &$rc)
{
try {
$config = Config::fromIni($path);
} catch (NotReadableError $error) {
if ($error->getPrevious() !== null) {
Logger::error('%s: %s', $error->getMessage(), $error->getPrevious()->getMessage());
} else {
Logger::error($error->getMessage());
}

$config = new Config();
$rc = 128;
}

return $config;
Logger::error('Deprecated. Use `icingacli icingadb migrate navigation` instead.');
exit(1);
}
}
30 changes: 0 additions & 30 deletions phpstan-baseline.neon
Expand Up @@ -11620,11 +11620,6 @@ parameters:
count: 1
path: library/Icinga/Util/Format.php

-
message: "#^Parameter \\#1 \\$timestamp of method DateTime\\:\\:setTimestamp\\(\\) expects int, DateTime\\|int given\\.$#"
count: 2
path: library/Icinga/Util/Format.php

-
message: "#^Property Icinga\\\\Util\\\\Format\\:\\:\\$bitBase has no type specified\\.$#"
count: 1
Expand Down Expand Up @@ -16865,31 +16860,6 @@ parameters:
count: 1
path: modules/migrate/application/clicommands/ConfigCommand.php

-
message: "#^Cannot call method getMessage\\(\\) on Throwable\\|null\\.$#"
count: 1
path: modules/migrate/application/clicommands/NavigationCommand.php

-
message: "#^Method Icinga\\\\Module\\\\Migrate\\\\Clicommands\\\\NavigationCommand\\:\\:indexAction\\(\\) has no return type specified\\.$#"
count: 1
path: modules/migrate/application/clicommands/NavigationCommand.php

-
message: "#^Method Icinga\\\\Module\\\\Migrate\\\\Clicommands\\\\NavigationCommand\\:\\:migrateNavigationItems\\(\\) has no return type specified\\.$#"
count: 1
path: modules/migrate/application/clicommands/NavigationCommand.php

-
message: "#^Parameter \\#1 \\$string of static method ipl\\\\Web\\\\Filter\\\\QueryString\\:\\:parse\\(\\) expects string, mixed given\\.$#"
count: 1
path: modules/migrate/application/clicommands/NavigationCommand.php

-
message: "#^Parameter \\#1 \\$url of static method Icinga\\\\Web\\\\Url\\:\\:fromPath\\(\\) expects string, mixed given\\.$#"
count: 1
path: modules/migrate/application/clicommands/NavigationCommand.php

-
message: "#^Cannot call method getMessage\\(\\) on Throwable\\|null\\.$#"
count: 1
Expand Down

0 comments on commit f676685

Please sign in to comment.