[icinga-checkins] icinga.org: icingaweb2-module-director/fiddle/mfrosch: FIDDLE: Add advanced purging to sync

git at icinga.org git at icinga.org
Wed May 25 11:25:29 CEST 2016


Module: icingaweb2-module-director
Branch: fiddle/mfrosch
Commit: 71f5521ec24962c1b2d096dea7395826fdd91b1b
URL:    https://git.icinga.org/?p=icingaweb2-module-director.git;a=commit;h=71f5521ec24962c1b2d096dea7395826fdd91b1b

Author: Markus Frosch <lazyfrosch at icinga.org>
Date:   Fri May 13 18:07:47 2016 +0200

FIDDLE: Add advanced purging to sync

So there can be a sync rule that only would purge objects based on a filter.

Attention: This allows templates to be created and synced -> TESTING REQUIRED

---

 application/forms/SyncRuleForm.php     |   23 +++++++++----
 library/Director/Import/Sync.php       |    7 +++-
 library/Director/Objects/SyncRule.php  |   57 ++++++++++++++++++++++++++------
 schema/mysql-migrations/upgrade_XX.sql |    6 ++++
 schema/mysql.sql                       |    1 +
 schema/pgsql-migrations/upgrade_XX.sql |    6 ++++
 schema/pgsql.sql                       |    1 +
 7 files changed, 84 insertions(+), 17 deletions(-)

diff --git a/application/forms/SyncRuleForm.php b/application/forms/SyncRuleForm.php
index 82c664a..349f1fd 100644
--- a/application/forms/SyncRuleForm.php
+++ b/application/forms/SyncRuleForm.php
@@ -51,6 +51,17 @@ class SyncRuleForm extends DirectorObjectForm
             ))
         ));
 
+        $this->addElement('text', 'filter_expression', array(
+            'label'       => $this->translate('Filter Expression'),
+            'description' => sprintf(
+                $this->translate(
+                    'Sync only part of your imported objects with this rule. Icinga Web 2'
+                    . ' filter syntax is allowed, so this could look as follows: %s'
+                ),
+                '(host=a|host=b)&!ip=127.*' # TODO: provide a useful example
+            ),
+        ));
+
         $this->addElement('select', 'purge_existing', array(
             'label' => $this->translate('Purge'),
             'description'  => $this->translate(
@@ -65,15 +76,15 @@ class SyncRuleForm extends DirectorObjectForm
             ))
         ));
 
-        $this->addElement('text', 'filter_expression', array(
-            'label'       => $this->translate('Filter Expression'),
+        $this->addElement('text', 'purge_filter_expression', array(
+            'label' => $this->translate('Purge Filter'),
             'description' => sprintf(
                 $this->translate(
-                    'Sync only part of your imported objects with this rule. Icinga Web 2'
-                    . ' filter syntax is allowed, so this could look as follows: %s'
+                    'Only purge objects in Icinga Director, that are not synced by this rule and match this filter.'
+                    . 'Icinga Web 2 filter syntax is allowed, so this could look as follows: %s'
                 ),
-                '(host=a|host=b)&!ip=127.*'
-            ),
+                '(host=a|host=b)&!ip=127.*' # TODO: provide a useful example
+            )
         ));
 
         $this->setButtons();
diff --git a/library/Director/Import/Sync.php b/library/Director/Import/Sync.php
index 575429e..0d1032d 100644
--- a/library/Director/Import/Sync.php
+++ b/library/Director/Import/Sync.php
@@ -652,7 +652,10 @@ class Sync
                 // Stats?
 
             } elseif ($object->hasBeenLoadedFromDb() && $this->rule->purge_existing === 'y') {
-                $object->markForRemoval();
+                // mark the object for removal, when the purge filter matches
+                if ($this->rule->purgeMatches($object)) {
+                    $object->markForRemoval();
+                }
 
                 // TODO: this is for stats, preview, summary:
                 // $this->remove[] = $object;
@@ -688,6 +691,7 @@ class Sync
         $modified = 0;
         $deleted = 0;
         foreach ($objects as $object) {
+            /* TODO: replace this block, and check that the object_type must not be changed
             if ($object instanceof IcingaObject && $object->isTemplate()) {
                 // TODO: allow to sync templates
                 if ($object->hasBeenModified()) {
@@ -698,6 +702,7 @@ class Sync
                 }
                 continue;
             }
+            */
 
             if ($object instanceof IcingaObject && $object->shouldBeRemoved()) {
                 $object->delete($db);
diff --git a/library/Director/Objects/SyncRule.php b/library/Director/Objects/SyncRule.php
index d5b7d72..6514f53 100644
--- a/library/Director/Objects/SyncRule.php
+++ b/library/Director/Objects/SyncRule.php
@@ -17,20 +17,22 @@ class SyncRule extends DbObject
     protected $autoincKeyName = 'id';
 
     protected $defaultProperties = array(
-        'id'                 => null,
-        'rule_name'          => null,
-        'object_type'        => null,
-        'update_policy'      => null,
-        'purge_existing'     => null,
-        'filter_expression'  => null,
-        'sync_state'         => 'unknown',
-        'last_error_message' => null,
-        'last_attempt'       => null,
+        'id'                      => null,
+        'rule_name'               => null,
+        'object_type'             => null,
+        'update_policy'           => null,
+        'purge_existing'          => null,
+        'filter_expression'       => null,
+        'purge_filter_expression' => null,
+        'sync_state'              => 'unknown',
+        'last_error_message'      => null,
+        'last_attempt'            => null,
     );
 
     private $sync;
 
     private $filter;
+    private $purge_filter;
 
     public function listInvolvedSourceIds()
     {
@@ -55,7 +57,7 @@ class SyncRule extends DbObject
         if (! $this->hasBeenLoadedFromDb()) {
             return 1;
         }
-        
+
         $db = $this->getDb();
         return $db->fetchOne(
             $db->select()
@@ -124,6 +126,11 @@ class SyncRule extends DbObject
         return $this->sync;
     }
 
+    /**
+     * Builds and returns the configured filter for imported data.
+     *
+     * @return Filter
+     */
     protected function filter()
     {
         if ($this->filter === null) {
@@ -133,6 +140,36 @@ class SyncRule extends DbObject
         return $this->filter;
     }
 
+    /**
+     * Checks if the object in question matches the purge rule, so it would be deleted if it is not in imported data.
+     *
+     * @param  DbObject  $row
+     *
+     * @return bool
+     */
+    public function purgeMatches($row)
+    {
+        if ($this->purge_filter_expression === null) {
+            return true;
+        }
+
+        return $this->purgeFilter()->matches($row);
+    }
+
+    /**
+     * Builds and returns the configured filter for purging data.
+     *
+     * @return Filter
+     */
+    protected function purgeFilter()
+    {
+        if ($this->purge_filter === null) {
+            $this->purge_filter = Filter::fromQueryString($this->purge_filter_expression);
+        }
+
+        return $this->purge_filter;
+    }
+
     public function fetchSyncProperties()
     {
         $db = $this->getDb();
diff --git a/schema/mysql-migrations/upgrade_XX.sql b/schema/mysql-migrations/upgrade_XX.sql
new file mode 100644
index 0000000..5a42383
--- /dev/null
+++ b/schema/mysql-migrations/upgrade_XX.sql
@@ -0,0 +1,6 @@
+ALTER TABLE sync_rule
+  ADD purge_filter_expression TEXT DEFAULT NULL;
+
+-- INSERT INTO director_schema_migration
+--   (schema_version, migration_time)
+--   VALUES (XX, NOW());
diff --git a/schema/mysql.sql b/schema/mysql.sql
index e8a1bac..1013d70 100644
--- a/schema/mysql.sql
+++ b/schema/mysql.sql
@@ -1255,6 +1255,7 @@ CREATE TABLE sync_rule (
   update_policy ENUM('merge', 'override', 'ignore') NOT NULL,
   purge_existing ENUM('y', 'n') NOT NULL DEFAULT 'n',
   filter_expression TEXT DEFAULT NULL,
+  purge_filter_expression TEXT DEFAULT NULL,
   sync_state ENUM(
     'unknown',
     'in-sync',
diff --git a/schema/pgsql-migrations/upgrade_XX.sql b/schema/pgsql-migrations/upgrade_XX.sql
new file mode 100644
index 0000000..5a42383
--- /dev/null
+++ b/schema/pgsql-migrations/upgrade_XX.sql
@@ -0,0 +1,6 @@
+ALTER TABLE sync_rule
+  ADD purge_filter_expression TEXT DEFAULT NULL;
+
+-- INSERT INTO director_schema_migration
+--   (schema_version, migration_time)
+--   VALUES (XX, NOW());
diff --git a/schema/pgsql.sql b/schema/pgsql.sql
index fc5df15..dd057a4 100644
--- a/schema/pgsql.sql
+++ b/schema/pgsql.sql
@@ -1408,6 +1408,7 @@ CREATE TABLE sync_rule (
   update_policy enum_sync_rule_update_policy NOT NULL,
   purge_existing enum_boolean NOT NULL DEFAULT 'n',
   filter_expression text DEFAULT NULL,
+  purge_filter_expression TEXT DEFAULT NULL,
   sync_state enum_sync_state NOT NULL DEFAULT 'unknown',
   last_error_message character varying(255) NULL DEFAULT NULL,
   last_attempt timestamp with time zone NULL DEFAULT NULL,



More information about the icinga-checkins mailing list