Merge branch 'feature/centralized-exporter-2549'

This commit is contained in:
Thomas Gelf 2022-06-24 12:53:14 +02:00
commit aacfd88df5
26 changed files with 437 additions and 41 deletions

View File

@ -10,6 +10,7 @@ use gipfl\Web\Table\NameValueTable;
use gipfl\Web\Widget\Hint;
use Icinga\Date\DateFormatter;
use Icinga\Module\Director\Core\Json;
use Icinga\Module\Director\Data\Exporter;
use Icinga\Module\Director\Db;
use Icinga\Module\Director\DirectorObject\Automation\Basket;
use Icinga\Module\Director\DirectorObject\Automation\BasketSnapshot;
@ -247,6 +248,7 @@ class BasketController extends ActionController
$json = $snapshot->getJsonDump();
$this->addSingleTab($this->translate('Snapshot'));
$all = Json::decode($json);
$exporter = new Exporter($this->db());
$fieldResolver = new BasketSnapshotFieldResolver($all, $connection);
foreach ($all as $type => $objects) {
if ($type === 'Datafield') {
@ -284,7 +286,7 @@ class BasketController extends ActionController
);
continue;
}
$currentExport = $current->export();
$currentExport = $exporter->export($current);
$fieldResolver->tweakTargetIds($currentExport);
// Ignore originalId
@ -366,7 +368,7 @@ class BasketController extends ActionController
)
*/
]);
$exporter = new Exporter($this->db());
$json = $snapshot->getJsonDump();
$this->addSingleTab($this->translate('Snapshot'));
$objects = Json::decode($json);
@ -385,7 +387,7 @@ class BasketController extends ActionController
if ($current === null) {
$current = '';
} else {
$exported = $current->export();
$exported = $exporter->export($current);
$fieldResolver->tweakTargetIds($exported);
unset($exported->originalId);
CompareBasketObject::normalize($exported);

View File

@ -4,6 +4,7 @@ namespace Icinga\Module\Director\Controllers;
use Exception;
use gipfl\Web\Widget\Hint;
use Icinga\Module\Director\Data\Exporter;
use Icinga\Module\Director\Db\Branch\Branch;
use Icinga\Module\Director\Forms\ImportRowModifierForm;
use Icinga\Module\Director\Forms\ImportSourceForm;
@ -84,7 +85,7 @@ class ImportsourceController extends ActionController
$this->addMainActions();
$source = $this->getImportSource();
if ($this->params->get('format') === 'json') {
$this->sendJson($this->getResponse(), $source->export());
$this->sendJson($this->getResponse(), (new Exporter($this->db()))->export($source));
return;
}
$this->addTitle(

View File

@ -17,6 +17,10 @@ v1.10.0 (unreleased)
### Import and Sync
* FEATURE: clone a row for nested Dictionary/Hash entries (#2555)
### Configuration Baskets
* BREAKING: configuration baskets no longer contain originalId (#2549)
* FEATURE: exporting/snapshot-logic has been centralized (#2549)
### REST API
* FIX: addressing service templates by name has been fixed (#2487)

View File

@ -0,0 +1,254 @@
<?php
namespace Icinga\Module\Director\Data;
use gipfl\ZfDb\Adapter\Adapter;
use Icinga\Module\Director\Data\Db\DbObject;
use Icinga\Module\Director\Data\Db\DbObjectWithSettings;
use Icinga\Module\Director\Db;
use Icinga\Module\Director\Objects\DirectorDatafield;
use Icinga\Module\Director\Objects\DirectorDatalist;
use Icinga\Module\Director\Objects\DirectorDatalistEntry;
use Icinga\Module\Director\Objects\DirectorJob;
use Icinga\Module\Director\Objects\IcingaCommand;
use Icinga\Module\Director\Objects\IcingaObject;
use Icinga\Module\Director\Objects\IcingaServiceSet;
use Icinga\Module\Director\Objects\IcingaTemplateChoice;
use Icinga\Module\Director\Objects\ImportRowModifier;
use Icinga\Module\Director\Objects\ImportSource;
use Icinga\Module\Director\Objects\InstantiatedViaHook;
use Icinga\Module\Director\Objects\SyncRule;
use RuntimeException;
class Exporter
{
protected static $denyProperties = [
DirectorJob::class => [
'last_attempt_succeeded',
'last_error_message',
'ts_last_attempt',
'ts_last_error',
],
ImportSource::class => [
// No state export
'import_state',
'last_error_message',
'last_attempt',
],
ImportRowModifier::class => [
// Not state, but to be removed:
'source_id',
],
SyncRule::class => [
'sync_state',
'last_error_message',
'last_attempt',
],
];
/** @var Adapter|\Zend_Db_Adapter_Abstract */
protected $db;
/** @var FieldReferenceLoader */
protected $fieldReferenceLoader;
public function __construct(Db $connection)
{
$this->db = $connection->getDbAdapter();
$this->fieldReferenceLoader = new FieldReferenceLoader($connection);
}
public function export(DbObject $object)
{
$props = $object instanceof IcingaObject
? $this->exportIcingaObject($object)
: $this->exportDbObject($object);
$this->stripDeniedProperties($props, $object);
$this->appendTypeSpecificRelations($props, $object);
ksort($props);
return (object) $props;
}
protected function appendTypeSpecificRelations(array &$props, DbObject $object)
{
if ($object instanceof DirectorDatalist) {
$props['entries'] = $this->exportDatalistEntries($object);
} elseif ($object instanceof DirectorDatafield) {
if (isset($props['settings']->datalist_id)) {
$props['settings']->datalist = $this->getDatalistNameForId($props['settings']->datalist_id);
unset($props['settings']->datalist_id);
}
$props['category'] = isset($props['category_id'])
? $this->getDatafieldCategoryNameForId($props['category_id'])
: null;
unset($props['category_id']);
} elseif ($object instanceof ImportSource) {
$props['modifiers'] = $this->exportRowModifiers($object);
} elseif ($object instanceof SyncRule) {
$props['properties'] = $this->exportSyncProperties($object);
} elseif ($object instanceof IcingaCommand) {
if (isset($props['arguments'])) {
foreach ($props['arguments'] as $key => $argument) {
if (property_exists($argument, 'command_id')) {
unset($props['arguments'][$key]->command_id);
}
}
}
} elseif ($object instanceof DirectorJob) {
if ($object->hasTimeperiod()) {
$props['timeperiod'] = $object->timeperiod()->getObjectName();
}
unset($props['timeperiod_id']);
} elseif ($object instanceof IcingaTemplateChoice) {
if (isset($props['required_template_id'])) {
$requiredId = $props['required_template_id'];
unset($props['required_template_id']);
$props = $this->loadTemplateName($object->getObjectTableName(), $requiredId);
}
$props['members'] = array_values($object->getMembers());
} elseif ($object instanceof IcingaServiceSet) {
if ($object->get('host_id')) {
// Sets on Host
throw new RuntimeException('Not yet');
}
$props['services'] = [];
foreach ($object->getServiceObjects() as $serviceObject) {
$props['services'][$serviceObject->getObjectName()] = $this->export($serviceObject);
}
ksort($props['services']);
}
}
protected function loadTemplateName($table, $id)
{
$db = $this->db;
$query = $db->select()
->from(['o' => $table], 'o.object_name')->where("o.object_type = 'template'")
->where('o.id = ?', $id);
return $db->fetchOne($query);
}
protected function getDatalistNameForId($id)
{
$db = $this->db;
$query = $db->select()->from('director_datalist', 'list_name')->where('id = ?', (int) $id);
return $db->fetchOne($query);
}
protected function getDatafieldCategoryNameForId($id)
{
$db = $this->db;
$query = $db->select()->from('director_datafield_category', 'category_name')->where('id = ?', (int) $id);
return $db->fetchOne($query);
}
protected function stripDeniedProperties(array &$props, DbObject $object)
{
// TODO: this used to exist. Double-check all imports to verify it's not in use
// $originalId = $props['id'];
unset($props['id']);
$class = get_class($object);
if (isset(self::$denyProperties[$class])) {
foreach (self::$denyProperties[$class] as $key) {
unset($props[$key]);
}
}
}
protected function exportRowModifiers(ImportSource $object)
{
$modifiers = [];
// Hint: they're sorted by priority
foreach ($object->fetchRowModifiers() as $modifier) {
$modifiers[] = $this->export($modifier);
}
return $modifiers;
}
public function exportSyncProperties(SyncRule $object)
{
$all = [];
$db = $this->db;
$sourceNames = $db->fetchPairs(
$db->select()->from('import_source', ['id', 'source_name'])
);
foreach ($object->getSyncProperties() as $property) {
$properties = $property->getProperties();
$properties['source'] = $sourceNames[$properties['source_id']];
unset($properties['id']);
unset($properties['rule_id']);
unset($properties['source_id']);
ksort($properties);
$all[] = (object) $properties;
}
return $all;
}
/**
* @param DbObject $object
* @return array
*/
protected function exportDbObject(DbObject $object)
{
$props = $object->getProperties();
if ($object instanceof DbObjectWithSettings) {
if ($object instanceof InstantiatedViaHook) {
$props['settings'] = (object) $object->getInstance()->exportSettings();
} else {
$props['settings'] = (object) $object->getSettings(); // Already sorted
}
}
return $props;
}
/**
* @param IcingaObject $object
* @return array
* @throws \Icinga\Exception\NotFoundError
*/
protected function exportIcingaObject(IcingaObject $object)
{
$props = (array) $object->toPlainObject();
if ($object->supportsFields()) {
$props['fields'] = $this->fieldReferenceLoader->loadFor($object);
}
return $props;
}
protected function exportDatalistEntries(DirectorDatalist $list)
{
$entries = [];
$id = $list->get('id');
if ($id === null) {
return $entries;
}
$dbEntries = DirectorDatalistEntry::loadAllForList($list);
// Hint: they are loaded with entry_name key
ksort($dbEntries);
foreach ($dbEntries as $entry) {
if ($entry->shouldBeRemoved()) {
continue;
}
$plainEntry = $entry->getProperties();
unset($plainEntry['list_id']);
$entries[] = $plainEntry;
}
return $entries;
}
}

View File

@ -0,0 +1,51 @@
<?php
namespace Icinga\Module\Director\Data;
use gipfl\ZfDb\Adapter\Adapter;
use Icinga\Module\Director\Db;
use Icinga\Module\Director\Objects\IcingaObject;
class FieldReferenceLoader
{
/** @var Adapter|\Zend_Db_Adapter_Abstract */
protected $db;
public function __construct(Db $connection)
{
$this->db = $connection->getDbAdapter();
}
/**
* @param int $id
* @return array
*/
public function loadFor(IcingaObject $object)
{
$db = $this->db;
$id = $object->get('id');
if ($id === null) {
return [];
}
$type = $object->getShortTableName();
$res = $db->fetchAll(
$db->select()->from(['f' => "icinga_${type}_field"], [
'f.datafield_id',
'f.is_required',
'f.var_filter',
])->join(['df' => 'director_datafield'], 'df.id = f.datafield_id', [])
->where("${type}_id = ?", (int) $id)
->order('varname ASC')
);
if (empty($res)) {
return [];
}
foreach ($res as $field) {
$field->datafield_id = (int) $field->datafield_id;
}
return $res;
}
}

View File

@ -3,6 +3,7 @@
namespace Icinga\Module\Director\DirectorObject\Automation;
use Icinga\Module\Director\Core\Json;
use Icinga\Module\Director\Data\Exporter;
use Icinga\Module\Director\Db;
use Icinga\Module\Director\Data\Db\DbObject;
use Icinga\Module\Director\Objects\DirectorDatafield;
@ -423,10 +424,11 @@ class BasketSnapshot extends DbObject
protected function addAll($typeName)
{
list($class, $filter) = static::getClassAndObjectTypeForType($typeName);
$connection = $this->getConnection();
assert($connection instanceof Db);
/** @var IcingaObject $dummy */
$dummy = $class::create();
/** @var ExportInterface $object */
if ($dummy instanceof IcingaObject && $dummy->supportsImports()) {
$db = $this->getDb();
$select = $db->select()->from($dummy->getTableName());
@ -441,12 +443,13 @@ class BasketSnapshot extends DbObject
) {
$select->where('object_type = ?', 'template');
}
$all = $class::loadAll($this->getConnection(), $select);
$all = $class::loadAll($connection, $select);
} else {
$all = $class::loadAll($this->getConnection());
$all = $class::loadAll($connection);
}
$exporter = new Exporter($connection);
foreach ($all as $object) {
$this->objects[$typeName][$object->getUniqueIdentifier()] = $object->export();
$this->objects[$typeName][$object->getUniqueIdentifier()] = $exporter->export($object);
}
}
@ -461,7 +464,7 @@ class BasketSnapshot extends DbObject
* @param $typeName
* @param $identifier
* @param Db $connection
* @return ExportInterface|null
* @return ExportInterface|DbObject|null
*/
public static function instanceByIdentifier($typeName, $identifier, Db $connection)
{
@ -490,13 +493,14 @@ class BasketSnapshot extends DbObject
{
/** @var Db $connection */
$connection = $this->getConnection();
$exporter = new Exporter($connection);
$object = static::instanceByIdentifier(
$typeName,
$identifier,
$connection
);
if ($object !== null) {
$this->objects[$typeName][$identifier] = $object->export();
$this->objects[$typeName][$identifier] = $exporter->export($object);
}
}
}

View File

@ -7,6 +7,7 @@ use Icinga\Module\Director\Db;
interface ExportInterface
{
/**
* @deprecated
* @return \stdClass
*/
public function export();

View File

@ -2,6 +2,7 @@
namespace Icinga\Module\Director\DirectorObject\Automation;
use Icinga\Module\Director\Data\Exporter;
use Icinga\Module\Director\Db;
use Icinga\Module\Director\Objects\DirectorDatafield;
use Icinga\Module\Director\Objects\DirectorDatalist;
@ -15,23 +16,26 @@ use Icinga\Module\Director\Objects\SyncRule;
class ImportExport
{
/** @var Db */
protected $connection;
/** @var Exporter */
protected $exporter;
public function __construct(Db $connection)
{
$this->connection = $connection;
$this->exporter = new Exporter($connection);
}
public function serializeAllServiceSets()
{
// TODO: Export host templates in Inheritance order
$res = [];
$related = [];
foreach (IcingaServiceSet::loadAll($this->connection) as $object) {
$res[] = $object->export();
foreach ($object->exportRelated() as $key => $relatedObject) {
$related[$key] = $relatedObject;
if ($object->get('host_id')) {
continue;
}
$res[] = $this->exporter->export($object);
}
return $res;
@ -41,7 +45,7 @@ class ImportExport
{
$res = [];
foreach (IcingaTemplateChoiceHost::loadAll($this->connection) as $object) {
$res[] = $object->export();
$res[] = $this->exporter->export($object);
}
return $res;
@ -71,7 +75,7 @@ class ImportExport
{
$res = [];
foreach (DirectorDatafield::loadAll($this->connection) as $object) {
$res[] = $object->export();
$res[] = $this->exporter->export($object);
}
return $res;
@ -81,7 +85,7 @@ class ImportExport
{
$res = [];
foreach (DirectorDatalist::loadAll($this->connection) as $object) {
$res[] = $object->export();
$res[] = $this->exporter->export($object);
}
return $res;
@ -91,7 +95,7 @@ class ImportExport
{
$res = [];
foreach (DirectorJob::loadAll($this->connection) as $object) {
$res[] = $object->export();
$res[] = $this->exporter->export($object);
}
return $res;
@ -101,7 +105,7 @@ class ImportExport
{
$res = [];
foreach (ImportSource::loadAll($this->connection) as $object) {
$res[] = $object->export();
$res[] = $this->exporter->export($object);
}
return $res;
@ -111,7 +115,7 @@ class ImportExport
{
$res = [];
foreach (SyncRule::loadAll($this->connection) as $object) {
$res[] = $object->export();
$res[] = $this->exporter->export($object);
}
return $res;

View File

@ -21,6 +21,7 @@ class DirectorDatafieldCategory extends DbObject
];
/**
* @deprecated please use \Icinga\Module\Director\Data\Exporter
* @return object
*/
public function export()

View File

@ -185,6 +185,10 @@ class DirectorDatalist extends DbObject implements ExportInterface
}
}
/**
* @deprecated please use \Icinga\Module\Director\Data\Exporter
* @return object
*/
public function export()
{
$plain = (object) $this->getProperties();

View File

@ -12,7 +12,7 @@ use Icinga\Module\Director\Hook\JobHook;
use Exception;
use InvalidArgumentException;
class DirectorJob extends DbObjectWithSettings implements ExportInterface
class DirectorJob extends DbObjectWithSettings implements ExportInterface, InstantiatedViaHook
{
/** @var JobHook */
protected $job;
@ -55,9 +55,18 @@ class DirectorJob extends DbObjectWithSettings implements ExportInterface
}
/**
* @deprecated please use JobHook::getInstance()
* @return JobHook
*/
public function job()
{
return $this->getInstance();
}
/**
* @return JobHook
*/
public function getInstance()
{
if ($this->job === null) {
$class = $this->get('job_class');
@ -74,7 +83,7 @@ class DirectorJob extends DbObjectWithSettings implements ExportInterface
*/
public function run()
{
$job = $this->job();
$job = $this->getInstance();
$this->set('ts_last_attempt', date('Y-m-d H:i:s'));
try {
@ -186,6 +195,7 @@ class DirectorJob extends DbObjectWithSettings implements ExportInterface
/**
* @return object
* @deprecated please use \Icinga\Module\Director\Data\Exporter
* @throws \Icinga\Exception\NotFoundError
*/
public function export()
@ -201,7 +211,7 @@ class DirectorJob extends DbObjectWithSettings implements ExportInterface
foreach ($this->stateProperties as $key) {
unset($plain->$key);
}
$plain->settings = $this->job()->exportSettings();
$plain->settings = $this->getInstance()->exportSettings();
return $plain;
}
@ -272,9 +282,10 @@ class DirectorJob extends DbObjectWithSettings implements ExportInterface
}
/**
* @api internal Exporter only
* @return IcingaTimePeriod
*/
protected function timeperiod()
public function timeperiod()
{
try {
return IcingaTimePeriod::loadWithAutoIncId($this->get('timeperiod_id'), $this->connection);

View File

@ -215,6 +215,7 @@ class IcingaCommand extends IcingaObject implements ObjectWithArguments, ExportI
/**
* @return object
* @deprecated please use \Icinga\Module\Director\Data\Exporter
* @throws \Icinga\Exception\NotFoundError
*/
public function export()
@ -264,6 +265,10 @@ class IcingaCommand extends IcingaObject implements ObjectWithArguments, ExportI
return $object;
}
/**
* @deprecated please use \Icinga\Module\Director\Data\FieldReferenceLoader
* @return array
*/
protected function loadFieldReferences()
{
$db = $this->getDb();

View File

@ -82,6 +82,7 @@ class IcingaDependency extends IcingaObject implements ExportInterface
/**
* @return object
* @deprecated please use \Icinga\Module\Director\Data\Exporter
* @throws \Icinga\Exception\NotFoundError
*/
public function export()

View File

@ -312,6 +312,7 @@ class IcingaHost extends IcingaObject implements ExportInterface
/**
* @return object
* @deprecated please use \Icinga\Module\Director\Data\Exporter
* @throws \Icinga\Exception\NotFoundError
*/
public function export()
@ -363,6 +364,10 @@ class IcingaHost extends IcingaObject implements ExportInterface
return $object;
}
/**
* @deprecated please use \Icinga\Module\Director\Data\FieldReferenceLoader
* @return array
*/
protected function loadFieldReferences()
{
$db = $this->getDb();

View File

@ -98,6 +98,7 @@ class IcingaNotification extends IcingaObject implements ExportInterface
/**
* @return \stdClass
* @deprecated please use \Icinga\Module\Director\Data\Exporter
* @throws \Icinga\Exception\NotFoundError
*/
public function export()
@ -142,6 +143,10 @@ class IcingaNotification extends IcingaObject implements ExportInterface
return $object;
}
/**
* @deprecated please use \Icinga\Module\Director\Data\FieldReferenceLoader
* @return array
*/
protected function loadFieldReferences()
{
$db = $this->getDb();

View File

@ -31,6 +31,7 @@ abstract class IcingaObjectGroup extends IcingaObject implements ExportInterface
/**
* @return object
* @deprecated please use \Icinga\Module\Director\Data\Exporter
* @throws \Icinga\Exception\NotFoundError
*/
public function export()

View File

@ -171,6 +171,7 @@ class IcingaService extends IcingaObject implements ExportInterface
/**
* @return object
* @deprecated please use \Icinga\Module\Director\Data\Exporter
* @throws \Icinga\Exception\NotFoundError
*/
public function export()
@ -225,6 +226,10 @@ class IcingaService extends IcingaObject implements ExportInterface
return $object;
}
/**
* @deprecated please use \Icinga\Module\Director\Data\FieldReferenceLoader
* @return array
*/
protected function loadFieldReferences()
{
$db = $this->getDb();

View File

@ -135,6 +135,7 @@ class IcingaServiceSet extends IcingaObject implements ExportInterface
/**
* @return object
* @deprecated please use \Icinga\Module\Director\Data\Exporter
* @throws \Icinga\Exception\NotFoundError
*/
public function export()
@ -157,6 +158,7 @@ class IcingaServiceSet extends IcingaObject implements ExportInterface
/**
* @return object
* @deprecated
* @throws \Icinga\Exception\NotFoundError
*/
protected function exportTemplate()

View File

@ -69,6 +69,10 @@ class IcingaTemplateChoice extends IcingaObject implements ExportInterface
return $object;
}
/**
* @deprecated please use \Icinga\Module\Director\Data\Exporter
* @return array|object|\stdClass
*/
public function export()
{
$plain = (object) $this->getProperties();
@ -78,14 +82,10 @@ class IcingaTemplateChoice extends IcingaObject implements ExportInterface
unset($plain->required_template_id);
if ($requiredId) {
$db = $this->getDb();
$query = $db->select()->from(
['o' => $this->getObjectTableName()],
['o.id', 'o.object_name']
)->where("o.object_type = 'template'")
->where('o.template_choice_id = ?', $this->get('id'))
->order('o.object_name');
return $db->fetchPairs($query);
$query = $db->select()
->from(['o' => $this->getObjectTableName()], 'o.object_name')->where("o.object_type = 'template'")
->where('o.id = ?', $this->get('id'));
$plain->required_template = $db->fetchOne($query);
}
$plain->members = array_values($this->getMembers());

View File

@ -56,6 +56,7 @@ class IcingaTimePeriod extends IcingaObject implements ExportInterface
}
/**
* @deprecated please use \Icinga\Module\Director\Data\Exporter
* @return object
* @throws \Icinga\Exception\NotFoundError
*/

View File

@ -7,7 +7,7 @@ use Icinga\Module\Director\Hook\PropertyModifierHook;
use Icinga\Module\Director\Objects\Extension\PriorityColumn;
use RuntimeException;
class ImportRowModifier extends DbObjectWithSettings
class ImportRowModifier extends DbObjectWithSettings implements InstantiatedViaHook
{
use PriorityColumn;
@ -56,6 +56,7 @@ class ImportRowModifier extends DbObjectWithSettings
}
/**
* @deprecated please use \Icinga\Module\Director\Data\Exporter
* @return \stdClass
*/
public function export()

View File

@ -53,6 +53,7 @@ class ImportSource extends DbObjectWithSettings implements ExportInterface
private $newRowModifiers;
/**
* @deprecated please use \Icinga\Module\Director\Data\FieldReferenceLoader
* @return \stdClass
*/
public function export()
@ -203,6 +204,10 @@ class ImportSource extends DbObjectWithSettings implements ExportInterface
);
}
/**
* @deprecated please use \Icinga\Module\Director\Data\FieldReferenceLoader
* @return array
*/
protected function exportRowModifiers()
{
$modifiers = [];

View File

@ -0,0 +1,14 @@
<?php
namespace Icinga\Module\Director\Objects;
use Icinga\Module\Director\Hook\JobHook;
use Icinga\Module\Director\Hook\PropertyModifierHook;
interface InstantiatedViaHook
{
/**
* @return mixed|PropertyModifierHook|JobHook
*/
public function getInstance();
}

View File

@ -256,6 +256,10 @@ class SyncRule extends DbObject implements ExportInterface
}
}
/**
* @deprecated please use \Icinga\Module\Director\Data\Exporter
* @return object
*/
public function export()
{
$plain = $this->getProperties();
@ -347,7 +351,11 @@ class SyncRule extends DbObject implements ExportInterface
}
}
public function exportSyncProperties()
/**
* @deprecated
* @return array
*/
protected function exportSyncProperties()
{
$all = [];
$db = $this->getDb();

View File

@ -2,6 +2,7 @@
namespace Icinga\Module\Director\Web\Form;
use Icinga\Module\Director\Data\Exporter;
use ipl\Html\Form;
use ipl\Html\FormDecorator\DdDtDecorator;
use gipfl\Translation\TranslationHelper;
@ -48,14 +49,15 @@ class CloneImportSourceForm extends Form
*/
public function onSuccess()
{
$export = $this->source->export();
$db = $this->getTargetDb();
$export = (new Exporter($db))->export($this->source);
$newName = $this->getElement('source_name')->getValue();
$export->source_name = $newName;
unset($export->originalId);
if (ImportSource::existsWithName($newName, $this->source->getConnection())) {
if (ImportSource::existsWithName($newName, $db)) {
$this->getElement('source_name')->addMessage('Name already exists');
}
$this->newSource = ImportSource::import($export, $this->getTargetDb());
$this->newSource = ImportSource::import($export, $db);
$this->newSource->store();
}

View File

@ -2,6 +2,7 @@
namespace Icinga\Module\Director\Web\Form;
use Icinga\Module\Director\Data\Exporter;
use ipl\Html\Form;
use ipl\Html\FormDecorator\DdDtDecorator;
use gipfl\Translation\TranslationHelper;
@ -49,15 +50,18 @@ class CloneSyncRuleForm extends Form
*/
public function onSuccess()
{
$export = $this->rule->export();
$db = $this->getTargetDb();
$exporter = new Exporter($db);
$export = $exporter->export($this->rule);
$newName = $this->getValue('rule_name');
$export->rule_name = $newName;
unset($export->originalId);
if (SyncRule::existsWithName($newName, $this->getTargetDb())) {
if (SyncRule::existsWithName($newName, $db)) {
$this->getElement('rule_name')->addMessage('Name already exists');
}
$this->newRule = SyncRule::import($export, $this->getTargetDb());
$this->newRule = SyncRule::import($export, $db);
$this->newRule->store();
}