Skip to content

SyncRule: Changing Host object_name after successful import, will lead to duplicates, with no chance to revert. #1140

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
mkayontour opened this issue Aug 30, 2017 · 11 comments

Comments

@mkayontour
Copy link
Member

I tried to change all host object_name to lowercase, after a successfull sync.

And now, I imported about 2500 Hosts and I'm not able to change or remove them because I can't find any identifier at the database which includes the import source or syncrule where it came from.

This Sync Rule failed when last checked at 2017-08-30 10:28:34: Exception while syncing Icinga\Module\Director\Objects\IcingaHost teest-host2: Trying to recreate icinga_host (teest-host2)

Expected Behavior

The expected behaviour was that he will overwrite all existing hosts with the lowercase name - cause it's the same name just as lowercase.

Current Behavior

Instead he tries to create all of them again.

Repoduce

  1. Add import source with with hostnames (contain uppercase and lowercase)
  2. Import those hosts and add a modifier lowercase to the hostname
  3. Create Objects without defining the object_name field
  4. Modify object_name to the lowercase field
  5. Try the sync rule which should fail
  • Director version 1.3.2
  • Icinga Web 2 version 2.4.1
  • Icinga 2 version 2.7
  • OS RHEL 6
  • Apache, PHP 5.3.3
@lazyfrosch
Copy link
Contributor

I guess the sync should match them case-insensitive, then they would be updated...

@mkayontour
Copy link
Member Author

This would be more accurate as an expected behaviour.

I guess the sync should match them case-insensitive, then they would be updated...

@mkayontour mkayontour changed the title SyncRule: Changing Host object_name after successful import, will lead to duplicates, with no change to revert. SyncRule: Changing Host object_name after successful import, will lead to duplicates, with no chance to revert. Aug 30, 2017
@lazyfrosch
Copy link
Contributor

The diff is not too crazy, but not sure if we want this:

diff --git a/library/Director/Import/Sync.php b/library/Director/Import/Sync.php
index 4a85e356..8420e507 100644
--- a/library/Director/Import/Sync.php
+++ b/library/Director/Import/Sync.php
@@ -283,12 +283,6 @@ class Sync
                     $filterColumns[$column] = $column;
                 }
             }
-            if (($ruleFilter = $this->rule->filter()) !== null) {
-                foreach ($ruleFilter->listFilteredColumns() as $column) {
-                    $filterColumns[$column] = $column;
-                }
-            }
-
             if (! empty($filterColumns)) {
                 foreach (SyncUtils::getRootVariables($filterColumns) as $column) {
                     $usedColumns[$column] = $column;
@@ -391,6 +385,9 @@ class Sync
                     $object
                 );
 
+                // ensure lowercase for matching
+                $key = strtolower($key);
+
                 if (array_key_exists($key, $this->objects)) {
                     throw new IcingaException(
                         'Combined destination key "%s" is not unique, got "%s" twice',
@@ -402,10 +399,15 @@ class Sync
                 $this->objects[$key] = $object;
             }
         } else {
-            $this->objects = IcingaObject::loadAllByType(
+            $objects = IcingaObject::loadAllByType(
                 $this->rule->object_type,
                 $this->db
             );
+
+            foreach ($objects as $key => $object) {
+                // ensure lowercase for matching
+                $this->objects[strtolower($key)] = $object;
+            }
         }
 
         // TODO: should be obsoleted by a better "loadFiltered" method
@@ -426,6 +428,10 @@ class Sync
             foreach ($this->imported[$sourceId] as $key => $row) {
                 $newProps = array();
 
+                // ensure lowercase for matching
+                $object_name = $key; // used when object_name is not set in properties
+                $key = strtolower($key);
+
                 $newVars = array();
                 $imports = array();
 
@@ -482,7 +488,7 @@ class Sync
                     if (! array_key_exists('object_name', $newProps)
                         || $newProps['object_name'] === null
                     ) {
-                        $newProps['object_name'] = $key;
+                        $newProps['object_name'] = $object_name;
                     }
                 }

@mkayontour
Copy link
Member Author

Even when I initally define the object_name as the lowercase field - the next sync will be broken.

@lazyfrosch
Copy link
Contributor

Problem is matching existing vs. imported objects, this needs to be done in a common way inside Sync.

It doesn't matter what you tune in the Import or the SyncRule

@swizzly
Copy link

swizzly commented Jun 28, 2019

Any news on this, I had a similar Problem, but luckily I had copied the icinga_hosts table Prior changing anything, then I could used it as reference to clean up the DB.
As suggested above a field for the objects would be very helpful to identifiy them from which sync/source did they come.

@carraroj
Copy link

carraroj commented Sep 5, 2019

ref/NC/632633

@dajones70
Copy link

Ran into this same problem and figured it out. I have an SQL source with a "SELECT hostname..." then an import modifer to set the hostname -> hostname_lower: Lowercase. In the Hosts area of the Director, the hosts are lowercase. If I have a single uppercase character in any hostname field of the MySQL database, the second sync will be broken with the "Trying to recreate icinga_host" error.

I know I could solve this with a "SELECT LOWER(hostname)..." but the larger issue is the Director seems to be comparing what's in the hosts table which is post modifier with the import source pre-modifier. I haven't looked at the PHP code but this is the only thing that makes sense based on how I was able to resolve it.

The Director should be comparing post-modifier to be consistent with what is being stored in the database.

@JohnBoon42
Copy link

I am currently in the process of writing a Python script which puts all Service-Templates and ServiceSets into a MySQL DB. The implementation for putting the ServiceTemplates into the DB is complete. All our ServiceTemplates are already inside the MySQL DB.

I am using Automation to import them into Icinga2 (r2.10.5-1). The automated import via Sync rule only succeeds once. When I click "Trigger this Sync" again, it will fail with the following message:

This Sync Rule failed when last checked at 2019-11-05 12:43:08: Exception while syncing Icinga\Module\Director\Objects\IcingaService app_diskfree: Trying to recreate icinga_service ("{"object_name":"app_diskfree"}")

I was told that the error I see is related to this ticket. Can someone confirm this?

@Wintermute2k6
Copy link

ref/NC/691950

@Thomas-Gelf
Copy link
Contributor

Will finally be fixed with #2598

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants