From 5419d4428c86c488a43124f85e5407d7cbae6541 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 14 Apr 2024 15:17:47 +0200 Subject: Adding upstream version 1.11.1. Signed-off-by: Daniel Baumann --- library/Director/Data/ObjectImporter.php | 168 +++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 library/Director/Data/ObjectImporter.php (limited to 'library/Director/Data/ObjectImporter.php') diff --git a/library/Director/Data/ObjectImporter.php b/library/Director/Data/ObjectImporter.php new file mode 100644 index 0000000..231ad1c --- /dev/null +++ b/library/Director/Data/ObjectImporter.php @@ -0,0 +1,168 @@ +db = $db; + } + + /** + * @param class-string|DbObject $implementation + * @param stdClass $plain + * @return DbObject + * @throws JsonDecodeException + */ + public function import(string $implementation, stdClass $plain): DbObject + { + $this->assertTemplate($implementation, $plain); + $this->fixRelations($implementation, $plain); + $this->applyOtherWorkarounds($implementation, $plain); + $this->fixLegacyBaskets($implementation, $plain); + $this->fixSubObjects($implementation, $plain); + + $object = $this->loadExistingObject($implementation, $plain); + if ($object === null) { + $object = $implementation::create([], $this->db); + } + + $properties = (array) $plain; + unset($properties['fields']); + unset($properties['originalId']); + if ($implementation === Basket::class) { + if (isset($properties['objects']) && is_string($properties['objects'])) { + $properties['objects'] = JsonString::decode($properties['objects']); + } + } + $object->setProperties($properties); + + return $object; + } + + protected function fixLegacyBaskets(string $implementation, stdClass $plain) + { + // TODO: Check, whether current export sets modifiers = [] in case there is none + if ($implementation == ImportSource::class) { + if (!isset($plain->modifiers)) { + $plain->modifiers = []; + } + } + } + + protected function applyOtherWorkarounds(string $implementation, stdClass $plain) + { + if ($implementation === SyncRule::class) { + if (isset($plain->properties)) { + $plain->syncProperties = $plain->properties; + unset($plain->properties); + } + } + } + + protected function fixSubObjects(string $implementation, stdClass $plain) + { + if ($implementation === IcingaServiceSet::class) { + foreach ($plain->services as $service) { + unset($service->fields); + } + // Hint: legacy baskets are carrying service names as object keys, new baskets have arrays + $plain->services = array_values((array) $plain->services); + } + } + + protected function fixRelations(string $implementation, stdClass $plain) + { + if ($implementation === DirectorJob::class) { + $settings = $plain->settings; + $source = $settings->source ?? null; + if ($source && !isset($settings->source_id)) { + $settings->source_id = ImportSource::load($source, $this->db)->get('id'); + unset($settings->source); + } + $rule = $settings->rule ?? null; + if ($rule && !isset($settings->rule_id)) { + $settings->rule_id = SyncRule::load($rule, $this->db)->get('id'); + unset($settings->rule); + } + } + } + + /** + * @param class-string $implementation + * @param stdClass $plain + * @return DbObject|null + */ + protected function loadExistingObject(string $implementation, stdClass $plain): ?DbObject + { + if (isset($plain->uuid) + && $instance = $implementation::loadWithUniqueId(Uuid::fromString($plain->uuid), $this->db) + ) { + return $instance; + } + + if ($implementation === IcingaService::class) { + $key = [ + 'object_type' => 'template', + 'object_name' => $plain->object_name + ]; + } else { + $dummy = $implementation::create(); + $keyColumn = $dummy->getKeyName(); + if (is_array($keyColumn)) { + if (empty($keyColumn)) { + throw new \RuntimeException("$implementation has an empty keyColumn array"); + } + $key = []; + foreach ($keyColumn as $column) { + if (isset($plain->$column)) { + $key[$column] = $plain->$column; + } + } + } else { + $key = $plain->$keyColumn; + } + } + + return $implementation::loadOptional($key, $this->db); + } + + protected function assertTemplate(string $implementation, stdClass $plain) + { + if (! in_array($implementation, self::$templatesOnly)) { + return; + } + if ($plain->object_type !== 'template') { + throw new InvalidArgumentException(sprintf( + 'Can import only Templates, got "%s" for "%s"', + $plain->object_type, + $plain->name + )); + } + } +} -- cgit v1.2.3