migrate: Also backup roles

Logging is useful, but a backup even more.
This commit is contained in:
Johannes Meyer 2023-11-13 14:53:19 +01:00
parent f1af2c2765
commit 4c7cbfa67d
2 changed files with 75 additions and 13 deletions

View file

@ -239,11 +239,14 @@ class MigrateCommand extends Command
* OPTIONS:
*
* --override Reset any existing Icinga DB Web rules
*
* --no-backup Don't back up roles
*/
public function roleAction(): void
{
/** @var ?bool $override */
$override = $this->params->get('override');
$noBackup = $this->params->get('no-backup');
/** @var ?string $groupName */
$groupName = $this->params->get('group');
@ -257,6 +260,8 @@ class MigrateCommand extends Command
}
$rc = 0;
$changed = false;
$restrictions = Config::$configDir . '/roles.ini';
$rolesConfig = $this->readFromIni($restrictions, $rc);
$monitoringRestriction = 'monitoring/filter/objects';
@ -301,6 +306,7 @@ class MigrateCommand extends Command
if ($transformedFilter) {
$role[$icingadbRestrictions['objects']] = QueryString::render($transformedFilter);
$changed = true;
}
}
@ -320,6 +326,8 @@ class MigrateCommand extends Command
'*',
implode(',', array_unique($icingadbProperties))
);
$changed = true;
}
if (isset($role['permissions'])) {
@ -335,6 +343,7 @@ class MigrateCommand extends Command
if ($monitoringProtection !== null) {
$role['icingadb/protect/variables'] = $monitoringProtection;
$changed = true;
}
}
@ -342,9 +351,11 @@ class MigrateCommand extends Command
if (Str::startsWith($permission, 'icingadb/') || $permission === 'module/icingadb') {
continue;
} elseif (Str::startsWith($permission, 'monitoring/command/')) {
$changed = true;
$updatedPermissions[] = $permission;
$updatedPermissions[] = str_replace('monitoring/', 'icingadb/', $permission);
} elseif ($permission === 'no-monitoring/contacts') {
$changed = true;
$updatedPermissions[] = $permission;
$role['icingadb/denylist/routes'] = 'users,usergroups';
} else {
@ -366,6 +377,7 @@ class MigrateCommand extends Command
if (Str::startsWith($refusal, 'icingadb/') || $refusal === 'module/icingadb') {
continue;
} elseif (Str::startsWith($refusal, 'monitoring/command/')) {
$changed = true;
$updatedRefusals[] = $refusal;
$updatedRefusals[] = str_replace('monitoring/', 'icingadb/', $refusal);
} else {
@ -395,6 +407,7 @@ class MigrateCommand extends Command
);
$role[$icingadbRestriction] = $filter;
$changed = true;
}
}
}
@ -404,23 +417,31 @@ class MigrateCommand extends Command
$rolesConfig->setSection($name, $role);
}
try {
$rolesConfig->saveIni();
} catch (NotWritableError $error) {
Logger::error($error);
if ($this->skipMigration) {
Logger::error('Failed to transform icingadb restrictions');
} else {
Logger::error('Failed to migrate monitoring restrictions');
if ($changed) {
if (! $noBackup) {
$this->createBackupIni(Config::$configDir . '/roles');
}
exit(256);
}
try {
$rolesConfig->saveIni();
} catch (NotWritableError $error) {
Logger::error($error);
if ($this->skipMigration) {
Logger::error('Failed to transform icingadb restrictions');
} else {
Logger::error('Failed to migrate monitoring restrictions');
}
if ($this->skipMigration) {
Logger::info('Successfully transformed all icingadb restrictions');
exit(256);
}
if ($this->skipMigration) {
Logger::info('Successfully transformed all icingadb restrictions');
} else {
Logger::info('Successfully migrated monitoring restrictions and permissions in roles');
}
} else {
Logger::info('Successfully migrated monitoring restrictions and permissions in roles');
Logger::info('Nothing to do');
}
}

View file

@ -1135,6 +1135,10 @@ class MigrateCommandTest extends TestCase
* - Whether refusals are properly migrated
* - Whether restrictions are properly migrated
* - Whether blacklists are properly migrated
* - Whether backups are created
* - Whether a second run changes nothing, if nothing changed
* - Whether a second run keeps the backup, if nothing changed
* - Whether a new backup isn't created, if nothing changed
*/
public function testRoleMigrationMigratesAllRoles()
{
@ -1147,6 +1151,43 @@ class MigrateCommandTest extends TestCase
$config = $this->loadConfig('roles.ini');
$this->assertSame($expected, $config);
$backup = $this->loadConfig('roles.backup.ini');
$this->assertSame($initialConfig, $backup);
$command = $this->createCommandInstance('--role', '*');
$command->roleAction();
$configAfterSecondRun = $this->loadConfig('roles.ini');
$this->assertSame($config, $configAfterSecondRun);
$backupAfterSecondRun = $this->loadConfig('roles.backup.ini');
$this->assertSame($backup, $backupAfterSecondRun);
$backup2 = $this->loadConfig('roles.backup1.ini');
$this->assertEmpty($backup2);
}
/**
* Checks the following:
* - Whether backups are skipped
*
* @depends testRoleMigrationMigratesAllRoles
*/
public function testRoleMigrationSkipsBackupIfRequested()
{
[$initialConfig, $expected] = $this->getConfig('all-roles');
$this->createConfig('roles.ini', $initialConfig);
$command = $this->createCommandInstance('--role', '*', '--no-backup');
$command->roleAction();
$config = $this->loadConfig('roles.ini');
$this->assertSame($expected, $config);
$backup = $this->loadConfig('roles.backup.ini');
$this->assertEmpty($backup);
}
/**