BranchController: refactored, use new classes

This commit is contained in:
Thomas Gelf 2021-10-05 22:39:00 +02:00
parent ce13200832
commit 30bbf0836d
1 changed files with 56 additions and 93 deletions

View File

@ -5,18 +5,15 @@ namespace Icinga\Module\Director\Controllers;
use gipfl\Diff\HtmlRenderer\SideBySideDiff;
use gipfl\Diff\PhpDiff;
use gipfl\IcingaWeb2\Widget\NameValueTable;
use Icinga\Module\Director\Data\Db\DbObject;
use Icinga\Module\Director\Data\Json;
use Icinga\Module\Director\Db\Branch\IcingaObjectModification;
use Icinga\Module\Director\Db\Branch\ObjectModification;
use Icinga\Module\Director\Data\Db\DbObjectTypeRegistry;
use Icinga\Module\Director\Db\Branch\BranchActivity;
use Icinga\Module\Director\IcingaConfig\IcingaConfig;
use Icinga\Module\Director\Objects\IcingaObject;
use Icinga\Module\Director\PlainObjectRenderer;
use Icinga\Module\Director\Web\Controller\ActionController;
use Icinga\Module\Director\Web\Controller\BranchHelper;
use Icinga\Module\Director\Web\Widget\IcingaConfigDiff;
use ipl\Html\Html;
use ipl\Html\ValidHtml;
use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\UuidInterface;
class BranchController extends ActionController
{
@ -29,66 +26,75 @@ class BranchController extends ActionController
public function activityAction()
{
$this->assertPermission('director/showconfig');
$uuid = Uuid::fromString($this->params->getRequired('uuid'));
$ts = $this->params->getRequired('ts');
$this->addSingleTab($this->translate('Activity'));
$this->addTitle($this->translate('Branch Activity'));
$activity = $this->loadBranchActivity($uuid);
$activity = BranchActivity::load($ts, $this->db());
$this->content()->add($this->prepareActivityInfo($activity));
$this->showActivity($activity);
}
protected function prepareActivityInfo($activity)
protected function prepareActivityInfo(BranchActivity $activity)
{
$modification = ObjectModification::fromSerialization(json_decode($activity->change_set));
/** @var IcingaObject $class IDE hint, it's a string */
$class = $modification->getClassName();
$keyParams = (array) $modification->getKeyParams(); // TODO: verify type
$dummy = $class::create($keyParams);
$table = new NameValueTable();
$table->addNameValuePairs([
$this->translate('Author') => 'branch owner',
$this->translate('Date') => date('Y-m-d H:i:s', $activity->change_time / 1000),
$this->translate('Action') => $modification->getAction()
. ' ' . $dummy->getShortTableName()
. ' ' . $dummy->getObjectName(),
$this->translate('Change UUID') => Uuid::fromBytes($activity->uuid)->toString(),
$this->translate('Author') => $activity->getAuthor(),
$this->translate('Date') => date('Y-m-d H:i:s', $activity->getTimestamp()),
$this->translate('Action') => $activity->getAction()
. ' ' . preg_replace('/^icinga_/', '', $activity->getObjectTable())
. ' ' . $activity->getObjectName(),
// $this->translate('Actions') => ['Undo form'],
]);
return $table;
}
protected function showActivity($activity)
protected function leftFromActivity(BranchActivity $activity)
{
$modification = ObjectModification::fromSerialization(Json::decode($activity->change_set));
/** @var string|DbObject $class */
$class = $modification->getClassName();
// TODO: Show JSON-Diff for non-IcingaObject's
$keyParams = (array) $modification->getKeyParams(); // TODO: verify type
$dummy = $class::create($keyParams, $this->db());
if ($modification->isCreation()) {
$left = $this->createEmptyConfig();
$right = $dummy->setProperties(
(array) $modification->getProperties()->jsonSerialize()
)->toSingleIcingaConfig();
} elseif ($modification->isDeletion()) {
$left = $class::load($keyParams, $this->db())->toSingleIcingaConfig();
$right = $this->createEmptyConfig();
} else {
// TODO: highlight properties that have been changed in the meantime
// TODO: Deal with missing $existing
$existing = $class::load($keyParams, $this->db());
$left = $existing->toSingleIcingaConfig();
$right = clone($existing);
IcingaObjectModification::applyModification($modification, $right, $this->db());
$right = $right->toSingleIcingaConfig();
if ($activity->isActionCreate()) {
return null;
}
$changes = $this->getConfigDiffs($left, $right);
foreach ($changes as $filename => $diff) {
$object = DbObjectTypeRegistry::newObject($activity->getObjectTable(), [], $this->db());
foreach ($activity->getFormerProperties()->jsonSerialize() as $key => $value) {
$object->set($key, $value);
}
return $object;
}
protected function rightFromActivity(BranchActivity $activity)
{
if ($activity->isActionDelete()) {
return null;
}
$object = DbObjectTypeRegistry::newObject($activity->getObjectTable(), [], $this->db());
if (! $activity->isActionCreate()) {
foreach ($activity->getFormerProperties()->jsonSerialize() as $key => $value) {
$object->set($key, $value);
}
}
foreach ($activity->getModifiedProperties()->jsonSerialize() as $key => $value) {
$object->set($key, $value);
}
return $object;
}
protected function showActivity(BranchActivity $activity)
{
$left = $this->leftFromActivity($activity);
$right = $this->rightFromActivity($activity);
if ($left instanceof IcingaObject || $right instanceof IcingaObject) {
$this->content()->add(new IcingaConfigDiff(
$left ? $left->toSingleIcingaConfig() : $this->createEmptyConfig(),
$right ? $right->toSingleIcingaConfig() : $this->createEmptyConfig()
));
} else {
$this->content()->add([
Html::tag('h3', $filename),
$diff
Html::tag('h3', $this->translate('Modification')),
new SideBySideDiff(new PhpDiff(
PlainObjectRenderer::render($left->getProperties()),
PlainObjectRenderer::render($right->getProperties())
))
]);
}
}
@ -97,47 +103,4 @@ class BranchController extends ActionController
{
return new IcingaConfig($this->db());
}
/**
* @param IcingaConfig $oldConfig
* @param IcingaConfig $newConfig
* @return ValidHtml[]
*/
protected function getConfigDiffs(IcingaConfig $oldConfig, IcingaConfig $newConfig)
{
$oldFileNames = $oldConfig->getFileNames();
$newFileNames = $newConfig->getFileNames();
$fileNames = array_merge($oldFileNames, $newFileNames);
$diffs = [];
foreach ($fileNames as $filename) {
if (in_array($filename, $oldFileNames)) {
$left = $oldConfig->getFile($filename)->getContent();
} else {
$left = '';
}
if (in_array($filename, $newFileNames)) {
$right = $newConfig->getFile($filename)->getContent();
} else {
$right = '';
}
if ($left === $right) {
continue;
}
$diffs[$filename] = new SideBySideDiff(new PhpDiff($left, $right));
}
return $diffs;
}
protected function loadBranchActivity(UuidInterface $uuid)
{
$db = $this->db()->getDbAdapter();
return $db->fetchRow(
$db->select()->from('director_branch_activity')->where('uuid = ?', $uuid->getBytes())
);
}
}