summaryrefslogtreecommitdiffstats
path: root/library/Director/DirectorObject/ObjectPurgeHelper.php
diff options
context:
space:
mode:
Diffstat (limited to 'library/Director/DirectorObject/ObjectPurgeHelper.php')
-rw-r--r--library/Director/DirectorObject/ObjectPurgeHelper.php149
1 files changed, 149 insertions, 0 deletions
diff --git a/library/Director/DirectorObject/ObjectPurgeHelper.php b/library/Director/DirectorObject/ObjectPurgeHelper.php
new file mode 100644
index 0000000..a043965
--- /dev/null
+++ b/library/Director/DirectorObject/ObjectPurgeHelper.php
@@ -0,0 +1,149 @@
+<?php
+
+namespace Icinga\Module\Director\DirectorObject;
+
+use Icinga\Module\Director\Db;
+use Icinga\Module\Director\Objects\IcingaObject;
+use InvalidArgumentException;
+
+class ObjectPurgeHelper
+{
+ protected $db;
+
+ protected $force = false;
+
+ public function __construct(Db $db)
+ {
+ $this->db = $db;
+ }
+
+ public function force($force = true)
+ {
+ $this->force = $force;
+ return $this;
+ }
+
+ public function purge(array $keep, $class, $objectType = null)
+ {
+ if (empty($keep) && ! $this->force) {
+ throw new InvalidArgumentException('I will NOT purge all object unless being forced to do so');
+ }
+ $db = $this->db->getDbAdapter();
+ /** @var IcingaObject $class cheating, it's a class name, not an object */
+ $dummy = $class::create();
+ assert($dummy instanceof IcingaObject);
+ $keyCols = (array) $dummy->getKeyName();
+ if ($objectType !== null) {
+ $keyCols[] = 'object_type';
+ }
+
+ $keepKeys = [];
+ foreach ($keep as $object) {
+ if ($object instanceof \stdClass) {
+ $properties = (array) $object;
+ // TODO: this is object-specific and to be found in the ::import() function!
+ unset($properties['fields']);
+ $object = $class::fromPlainObject($properties);
+ } elseif (\get_class($object) !== $class) {
+ throw new InvalidArgumentException(
+ 'Can keep only matching objects, expected "%s", got "%s',
+ $class,
+ \get_class($keep)
+ );
+ }
+ $key = [];
+ foreach ($keyCols as $col) {
+ $key[$col] = $object->get($col);
+ }
+ $keepKeys[$this->makeRowKey($key)] = true;
+ }
+
+ $query = $db->select()->from(['o' => $dummy->getTableName()], $keyCols);
+ if ($objectType !== null) {
+ $query->where('object_type = ?', $objectType);
+ }
+ $allExisting = [];
+ foreach ($db->fetchAll($query) as $row) {
+ $allExisting[$this->makeRowKey($row)] = $row;
+ }
+ $remove = [];
+ foreach ($allExisting as $key => $keyProperties) {
+ if (! isset($keepKeys[$key])) {
+ $remove[] = $keyProperties;
+ }
+ }
+ $db->beginTransaction();
+ foreach ($remove as $keyProperties) {
+ $keyColumn = $class::getKeyColumnName();
+ if (is_array($keyColumn)) {
+ $object = $class::load((array) $keyProperties, $this->db);
+ } else {
+ $object = $class::load($keyProperties->$keyColumn, $this->db);
+ }
+ $object->delete();
+ }
+ $db->commit();
+ }
+
+ public static function listObjectTypesAvailableForPurge()
+ {
+ return [
+ 'Basket',
+ 'Command',
+ 'CommandTemplate',
+ 'Dependency',
+ 'DirectorJob',
+ 'ExternalCommand',
+ 'HostGroup',
+ 'HostTemplate',
+ 'IcingaTemplateChoiceHost',
+ 'IcingaTemplateChoiceService',
+ 'ImportSource',
+ 'Notification',
+ 'NotificationTemplate',
+ 'ServiceGroup',
+ 'ServiceSet',
+ 'ServiceTemplate',
+ 'SyncRule',
+ 'TimePeriod',
+ ];
+ }
+
+ public static function objectTypeIsEligibleForPurge($type)
+ {
+ return in_array($type, static::listObjectTypesAvailableForPurge(), true);
+ }
+
+ public static function assertObjectTypesAreEligibleForPurge($types)
+ {
+ $invalid = [];
+ foreach ($types as $type) {
+ if (! static::objectTypeIsEligibleForPurge($type)) {
+ $invalid[] = $type;
+ }
+ }
+
+ if (empty($invalid)) {
+ return;
+ }
+
+ if (count($invalid) === 1) {
+ $message = sprintf('"%s" is not eligible for purge', $invalid[0]);
+ } else {
+ $message = 'The following types are not eligible for purge: '
+ . implode(', ', $invalid);
+ }
+
+ throw new InvalidArgumentException(
+ "$message. Valid types: "
+ . implode(', ', static::listObjectTypesAvailableForPurge())
+ );
+ }
+
+ protected function makeRowKey($row)
+ {
+ $row = (array) $row;
+ ksort($row);
+ return json_encode($row, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
+ }
+}