Sync: implement update-only policy

fixes #2059
This commit is contained in:
Thomas Gelf 2020-01-16 16:31:50 +01:00
parent f0b96674c9
commit c12a6baeea
5 changed files with 26 additions and 14 deletions

View File

@ -54,13 +54,15 @@ class SyncRuleForm extends DirectorObjectForm
'Define what should happen when an object with a matching key' 'Define what should happen when an object with a matching key'
. " already exists. You could merge its properties (import source" . " already exists. You could merge its properties (import source"
. ' wins), replace it completely with the imported object or ignore' . ' wins), replace it completely with the imported object or ignore'
. ' it (helpful for one-time imports)' . ' it (helpful for one-time imports). "Update only" means that this'
. ' Rule would never create (or delete) full Objects.'
), ),
'required' => true, 'required' => true,
'multiOptions' => $this->optionalEnum([ 'multiOptions' => $this->optionalEnum([
'merge' => $this->translate('Merge'), 'merge' => $this->translate('Merge'),
'override' => $this->translate('Replace'), 'override' => $this->translate('Replace'),
'ignore' => $this->translate('Ignore'), 'ignore' => $this->translate('Ignore'),
'update-only' => $this->translate('Update only'),
]) ])
]); ]);

View File

@ -18,6 +18,9 @@ next (will be 1.8.0)
* FEATURE: Allow to disable the Director frontend / UI (#2007) * FEATURE: Allow to disable the Director frontend / UI (#2007)
* FEATURE: Endpoints table now shows the object type (e.g. external) (#2050) * FEATURE: Endpoints table now shows the object type (e.g. external) (#2050)
### Import and Sync
* FEATURE: allow to define update-only Sync Rules (#2059)
### REST API ### REST API
* FEATURE: Self Service API ignores empty/missing properties (e.g. no address) * FEATURE: Self Service API ignores empty/missing properties (e.g. no address)

View File

@ -106,10 +106,14 @@ class Sync
{ {
$modified = []; $modified = [];
$objects = $this->prepare(); $objects = $this->prepare();
$updateOnly = $this->rule->get('update_policy') === 'update-only';
$allowCreate = ! $updateOnly;
foreach ($objects as $object) { foreach ($objects as $object) {
if ($object->hasBeenModified()) { if ($object->hasBeenModified()) {
$modified[] = $object; if ($allowCreate || $object->hasBeenLoadedFromDb()) {
} elseif ($object->shouldBeRemoved()) { $modified[] = $object;
}
} elseif (! $updateOnly && $object->shouldBeRemoved()) {
$modified[] = $object; $modified[] = $object;
} }
} }
@ -691,6 +695,7 @@ class Sync
break; break;
case 'merge': case 'merge':
case 'update-only':
// TODO: re-evaluate merge settings. vars.x instead of // TODO: re-evaluate merge settings. vars.x instead of
// just "vars" might suffice. // just "vars" might suffice.
$this->objects[$key]->merge($object, $this->replaceVars); $this->objects[$key]->merge($object, $this->replaceVars);
@ -738,6 +743,8 @@ class Sync
$dba->beginTransaction(); $dba->beginTransaction();
$object = null; $object = null;
$updateOnly = $this->rule->get('update_policy') === 'update-only';
$allowCreate = ! $updateOnly;
try { try {
$formerActivityChecksum = hex2bin( $formerActivityChecksum = hex2bin(
@ -750,7 +757,7 @@ class Sync
// $failed = 0; // $failed = 0;
foreach ($objects as $object) { foreach ($objects as $object) {
$this->setResolver($object); $this->setResolver($object);
if ($object->shouldBeRemoved()) { if (! $updateOnly && $object->shouldBeRemoved()) {
$object->delete(); $object->delete();
$deleted++; $deleted++;
continue; continue;
@ -758,11 +765,11 @@ class Sync
if ($object->hasBeenModified()) { if ($object->hasBeenModified()) {
$existing = $object->hasBeenLoadedFromDb(); $existing = $object->hasBeenLoadedFromDb();
$object->store($db);
if ($existing) { if ($existing) {
$object->store($db);
$modified++; $modified++;
} else { } elseif ($allowCreate) {
$object->store($db);
$created++; $created++;
} }
} }

View File

@ -1524,7 +1524,7 @@ CREATE TABLE sync_rule (
'notification', 'notification',
'dependency' 'dependency'
) NOT NULL, ) NOT NULL,
update_policy ENUM('merge', 'override', 'ignore') NOT NULL, update_policy ENUM('merge', 'override', 'ignore', 'update-only') NOT NULL,
purge_existing ENUM('y', 'n') NOT NULL DEFAULT 'n', purge_existing ENUM('y', 'n') NOT NULL DEFAULT 'n',
filter_expression TEXT DEFAULT NULL, filter_expression TEXT DEFAULT NULL,
sync_state ENUM( sync_state ENUM(
@ -1883,4 +1883,4 @@ CREATE TABLE icinga_scheduled_downtime_range (
INSERT INTO director_schema_migration INSERT INTO director_schema_migration
(schema_version, migration_time) (schema_version, migration_time)
VALUES (168, NOW()); VALUES (170, NOW());

View File

@ -36,7 +36,7 @@ CREATE TYPE enum_sync_rule_object_type AS ENUM(
'notification', 'notification',
'dependency' 'dependency'
); );
CREATE TYPE enum_sync_rule_update_policy AS ENUM('merge', 'override', 'ignore'); CREATE TYPE enum_sync_rule_update_policy AS ENUM('merge', 'override', 'ignore', 'update-only');
CREATE TYPE enum_sync_property_merge_policy AS ENUM('override', 'merge'); CREATE TYPE enum_sync_property_merge_policy AS ENUM('override', 'merge');
CREATE TYPE enum_sync_state AS ENUM( CREATE TYPE enum_sync_state AS ENUM(
'unknown', 'unknown',
@ -2199,4 +2199,4 @@ COMMENT ON COLUMN icinga_scheduled_downtime_range.merge_behaviour IS 'set -> = {
INSERT INTO director_schema_migration INSERT INTO director_schema_migration
(schema_version, migration_time) (schema_version, migration_time)
VALUES (169, NOW()); VALUES (170, NOW());