diff --git a/library/Director/Objects/IcingaCommand.php b/library/Director/Objects/IcingaCommand.php index 76b57860..d953086b 100644 --- a/library/Director/Objects/IcingaCommand.php +++ b/library/Director/Objects/IcingaCommand.php @@ -2,12 +2,15 @@ namespace Icinga\Module\Director\Objects; +use Icinga\Module\Director\Db; +use Icinga\Module\Director\DirectorObject\Automation\ExportInterface; +use Icinga\Module\Director\Exception\DuplicateKeyException; use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c; use Icinga\Module\Director\IcingaConfig\IcingaLegacyConfigHelper as c1; use Icinga\Module\Director\Objects\Extension\Arguments; use Zend_Db_Select as DbSelect; -class IcingaCommand extends IcingaObject implements ObjectWithArguments +class IcingaCommand extends IcingaObject implements ObjectWithArguments, ExportInterface { use Arguments; @@ -197,6 +200,59 @@ class IcingaCommand extends IcingaObject implements ObjectWithArguments return $this->countDirectUses() > 0; } + public function getUniqueIdentifier() + { + return $this->getObjectName(); + } + + /** + * @return object + * @throws \Icinga\Exception\NotFoundError + */ + public function export() + { + $object = $this->toPlainObject(); + if (property_exists($object, 'arguments')) { + foreach ($object->arguments as $key => $argument) { + if (property_exists($argument, 'command_id')) { + unset($argument->command_id); + } + } + } + + return $object; + } + + /** + * @param $plain + * @param Db $db + * @param bool $replace + * @return IcingaCommand + * @throws DuplicateKeyException + * @throws \Icinga\Exception\NotFoundError + */ + public static function import($plain, Db $db, $replace = false) + { + $properties = (array) $plain; + $name = $properties['object_name']; + $key = $name; + + if ($replace && static::exists($key, $db)) { + $object = static::load($key, $db); + } elseif (static::exists($key, $db)) { + throw new DuplicateKeyException( + 'Command "%s" already exists', + $name + ); + } else { + $object = static::create([], $db); + } + + $object->setProperties($properties); + + return $object; + } + protected function renderCommand() { $command = $this->get('command'); diff --git a/library/Director/Objects/IcingaHost.php b/library/Director/Objects/IcingaHost.php index db1ea00e..05ff6fff 100644 --- a/library/Director/Objects/IcingaHost.php +++ b/library/Director/Objects/IcingaHost.php @@ -6,9 +6,12 @@ use Icinga\Data\Db\DbConnection; use Icinga\Exception\NotFoundError; use Icinga\Module\Director\Data\PropertiesFilter; use Icinga\Module\Director\Db; +use Icinga\Module\Director\Exception\DuplicateKeyException; use Icinga\Module\Director\IcingaConfig\IcingaConfig; use Icinga\Module\Director\IcingaConfig\IcingaLegacyConfigHelper as c1; use Icinga\Module\Director\Objects\Extension\FlappingSupport; +use InvalidArgumentException; +use RuntimeException; class IcingaHost extends IcingaObject { @@ -253,6 +256,93 @@ class IcingaHost extends IcingaObject } } + public function getUniqueIdentifier() + { + if ($this->isTemplate()) { + return $this->getObjectName(); + } else { + throw new RuntimeException( + 'getUniqueIdentifier() is supported by Host Templates only' + ); + } + } + + /** + * @return object + * @throws \Icinga\Exception\NotFoundError + */ + public function export() + { + // TODO: ksort in toPlainObject? + $props = (array) $this->toPlainObject(); + $props['fields'] = $this->loadFieldReferences(); + ksort($props); + + return (object) $props; + } + + /** + * @param $plain + * @param Db $db + * @param bool $replace + * @return IcingaHost + * @throws DuplicateKeyException + * @throws \Icinga\Exception\NotFoundError + */ + public static function import($plain, Db $db, $replace = false) + { + $properties = (array) $plain; + $name = $properties['object_name']; + if ($properties['object_type'] !== 'template') { + throw new InvalidArgumentException(sprintf( + 'Can import only Templates, got "%s" for "%s"', + $properties['object_type'], + $name + )); + } + $key = $name; + + if ($replace && static::exists($key, $db)) { + $object = static::load($key, $db); + } elseif (static::exists($key, $db)) { + throw new DuplicateKeyException( + 'Service Template "%s" already exists', + $name + ); + } else { + $object = static::create([], $db); + } + + // $object->newFields = $properties['fields']; + unset($properties['fields']); + $object->setProperties($properties); + + return $object; + } + + protected function loadFieldReferences() + { + $db = $this->getDb(); + + $res = $db->fetchAll( + $db->select()->from([ + 'hf' => 'icinga_host_field' + ], [ + 'hf.datafield_id', + 'hf.is_required', + 'hf.var_filter', + ])->join(['df' => 'director_datafield'], 'df.id = hf.datafield_id', []) + ->where('host_id = ?', $this->get('id')) + ->order('varname ASC') + ); + + if (empty($res)) { + return []; + } else { + return $res; + } + } + public function hasAnyOverridenServiceVars() { $varname = $this->getServiceOverrivesVarname(); diff --git a/library/Director/Objects/IcingaObjectGroup.php b/library/Director/Objects/IcingaObjectGroup.php index ef2486fe..af18c12b 100644 --- a/library/Director/Objects/IcingaObjectGroup.php +++ b/library/Director/Objects/IcingaObjectGroup.php @@ -2,7 +2,11 @@ namespace Icinga\Module\Director\Objects; -abstract class IcingaObjectGroup extends IcingaObject +use Icinga\Module\Director\Db; +use Icinga\Module\Director\DirectorObject\Automation\ExportInterface; +use Icinga\Module\Director\Exception\DuplicateKeyException; + +abstract class IcingaObjectGroup extends IcingaObject implements ExportInterface { protected $supportsImports = true; @@ -17,6 +21,50 @@ abstract class IcingaObjectGroup extends IcingaObject 'assign_filter' => null, ]; + public function getUniqueIdentifier() + { + return $this->getObjectName(); + } + + /** + * @return object + * @throws \Icinga\Exception\NotFoundError + */ + public function export() + { + return $this->toPlainObject(); + } + + /** + * @param $plain + * @param Db $db + * @param bool $replace + * @return IcingaObjectGroup + * @throws DuplicateKeyException + * @throws \Icinga\Exception\NotFoundError + */ + public static function import($plain, Db $db, $replace = false) + { + $properties = (array) $plain; + $name = $properties['object_name']; + $key = $name; + + if ($replace && static::exists($key, $db)) { + $object = static::load($key, $db); + } elseif (static::exists($key, $db)) { + throw new DuplicateKeyException( + 'Group "%s" already exists', + $name + ); + } else { + $object = static::create([], $db); + } + + $object->setProperties($properties); + + return $object; + } + protected function prefersGlobalZone() { return true; diff --git a/library/Director/Objects/IcingaService.php b/library/Director/Objects/IcingaService.php index 3d5dabb5..038c67d0 100644 --- a/library/Director/Objects/IcingaService.php +++ b/library/Director/Objects/IcingaService.php @@ -7,6 +7,7 @@ use Icinga\Exception\IcingaException; use Icinga\Module\Director\Data\PropertiesFilter; use Icinga\Module\Director\Db; use Icinga\Module\Director\Db\Cache\PrefetchCache; +use Icinga\Module\Director\Exception\DuplicateKeyException; use Icinga\Module\Director\IcingaConfig\IcingaConfig; use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c; use Icinga\Module\Director\IcingaConfig\IcingaLegacyConfigHelper as c1; @@ -150,6 +151,96 @@ class IcingaService extends IcingaObject return $this->get('use_var_overrides') === 'y'; } + public function getUniqueIdentifier() + { + if ($this->isTemplate()) { + return $this->getObjectName(); + } else { + throw new RuntimeException( + 'getUniqueIdentifier() is supported by Service Templates only' + ); + } + } + + /** + * @return object + * @throws \Icinga\Exception\NotFoundError + */ + public function export() + { + // TODO: ksort in toPlainObject? + $props = (array) $this->toPlainObject(); + $props['fields'] = $this->loadFieldReferences(); + ksort($props); + + return (object) $props; + } + + /** + * @param $plain + * @param Db $db + * @param bool $replace + * @return IcingaService + * @throws DuplicateKeyException + * @throws \Icinga\Exception\NotFoundError + */ + public static function import($plain, Db $db, $replace = false) + { + $properties = (array) $plain; + $name = $properties['object_name']; + if ($properties['object_type'] !== 'template') { + throw new InvalidArgumentException(sprintf( + 'Can import only Templates, got "%s" for "%s"', + $properties['object_type'], + $name + )); + } + $key = [ + 'object_type' => 'template', + 'object_name' => $name + ]; + + if ($replace && static::exists($key, $db)) { + $object = static::load($key, $db); + } elseif (static::exists($key, $db)) { + throw new DuplicateKeyException( + 'Service Template "%s" already exists', + $name + ); + } else { + $object = static::create([], $db); + } + + // $object->newFields = $properties['fields']; + unset($properties['fields']); + $object->setProperties($properties); + + return $object; + } + + protected function loadFieldReferences() + { + $db = $this->getDb(); + + $res = $db->fetchAll( + $db->select()->from([ + 'sf' => 'icinga_service_field' + ], [ + 'sf.datafield_id', + 'sf.is_required', + 'sf.var_filter', + ])->join(['df' => 'director_datafield'], 'df.id = sf.datafield_id', []) + ->where('service_id = ?', $this->get('id')) + ->order('varname ASC') + ); + + if (empty($res)) { + return []; + } else { + return $res; + } + } + /** * @param string $key * @return $this diff --git a/library/Director/Objects/IcingaServiceSet.php b/library/Director/Objects/IcingaServiceSet.php index 706f496a..82d55a6f 100644 --- a/library/Director/Objects/IcingaServiceSet.php +++ b/library/Director/Objects/IcingaServiceSet.php @@ -6,6 +6,7 @@ use Exception; use Icinga\Data\Filter\Filter; use Icinga\Module\Director\Exception\DuplicateKeyException; use Icinga\Module\Director\IcingaConfig\IcingaConfig; +use Icinga\Module\Director\Web\Form\IcingaObjectFieldLoader; use InvalidArgumentException; class IcingaServiceSet extends IcingaObject @@ -110,6 +111,39 @@ class IcingaServiceSet extends IcingaObject return $services; } + public function export() + { + if ($this->get('host_id')) { + return $this->exportSetOnHost(); + } else { + return $this->exportTemplate(); + } + } + + protected function exportSetOnHost() + { + // TODO. + throw new \RuntimeException('Not yet'); + } + + protected function exportTemplate() + { + $props = $this->getProperties(); + unset($props['id'], $props['host_id']); + $props['services'] = []; + $props['service_templates'] = []; + foreach ($this->getServiceObjects() as $serviceObject) { + $props['services'][$serviceObject->getObjectName()] = $serviceObject->export(); + foreach ($serviceObject->imports()->getObjects() as $import) { + $name = $import->getObjectName(); + $props['service_templates'][$name] = $import->export(); + } + } + ksort($props); + + return (object) $props; + } + public function onDelete() { $hostId = $this->get('host_id'); diff --git a/library/Director/Objects/IcingaTemplateChoice.php b/library/Director/Objects/IcingaTemplateChoice.php index 1f203541..31cc3d93 100644 --- a/library/Director/Objects/IcingaTemplateChoice.php +++ b/library/Director/Objects/IcingaTemplateChoice.php @@ -3,9 +3,12 @@ namespace Icinga\Module\Director\Objects; use Icinga\Exception\ProgrammingError; +use Icinga\Module\Director\Db; +use Icinga\Module\Director\DirectorObject\Automation\ExportInterface; +use Icinga\Module\Director\Exception\DuplicateKeyException; use Icinga\Module\Director\Web\Form\QuickForm; -class IcingaTemplateChoice extends IcingaObject +class IcingaTemplateChoice extends IcingaObject implements ExportInterface { protected $objectTable; @@ -28,6 +31,47 @@ class IcingaTemplateChoice extends IcingaObject return substr(substr($this->table, 0, -16), 7); } + public function getUniqueIdentifier() + { + return $this->getObjectName(); + } + + /** + * @param $plain + * @param Db $db + * @param bool $replace + * @return IcingaTemplateChoice + * @throws DuplicateKeyException + * @throws \Icinga\Exception\NotFoundError + */ + public static function import($plain, Db $db, $replace = false) + { + $properties = (array) $plain; + if (isset($properties['originalId'])) { + $id = $properties['originalId']; + unset($properties['originalId']); + } else { + $id = null; + } + $name = $properties['object_name']; + $key = $name; + + if ($replace && static::exists($key, $db)) { + $object = static::load($key, $db); + } elseif (static::exists($key, $db)) { + throw new DuplicateKeyException( + 'Template Choice "%s" already exists', + $name + ); + } else { + $object = static::create([], $db); + } + + $object->setProperties($properties); + + return $object; + } + public function export() { $plain = (object) $this->getProperties();