Blob Blame History Raw
From cb2347ad79fe30076fad1579d1f5ee27a1835963 Mon Sep 17 00:00:00 2001
From: Tomas Jelinek <tojeline@redhat.com>
Date: Fri, 22 Jul 2016 16:29:04 +0200
Subject: [PATCH] fix check if id exists in cib

---
 pcs/lib/cib/tools.py           | 11 ++++++++++-
 pcs/test/test_lib_cib_tools.py | 24 ++++++++++++++++++++++++
 pcs/utils.py                   | 30 +++++++++++++++++++++++++-----
 3 files changed, 59 insertions(+), 6 deletions(-)

diff --git a/pcs/lib/cib/tools.py b/pcs/lib/cib/tools.py
index b59d50d..f86b63b 100644
--- a/pcs/lib/cib/tools.py
+++ b/pcs/lib/cib/tools.py
@@ -21,7 +21,16 @@ def does_id_exist(tree, check_id):
     tree cib etree node
     check_id id to check
     """
-    return tree.find('.//*[@id="{0}"]'.format(check_id)) is not None
+    # ElementTree has getroot, Elemet has getroottree
+    root = tree.getroot() if hasattr(tree, "getroot") else tree.getroottree()
+    # do not search in /cib/status, it may contain references to previously
+    # existing and deleted resources and thus preventing creating them again
+    existing = root.xpath(
+        '(/cib/*[name()!="status"]|/*[name()!="cib"])//*[@id="{0}"]'.format(
+            check_id
+        )
+    )
+    return len(existing) > 0
 
 def validate_id_does_not_exist(tree, id):
     """
diff --git a/pcs/test/test_lib_cib_tools.py b/pcs/test/test_lib_cib_tools.py
index 1149a3f..e1f2313 100644
--- a/pcs/test/test_lib_cib_tools.py
+++ b/pcs/test/test_lib_cib_tools.py
@@ -48,6 +48,30 @@ class DoesIdExistTest(CibToolsTest):
         self.assertFalse(lib.does_id_exist(self.cib.tree, "myId "))
         self.assertFalse(lib.does_id_exist(self.cib.tree, "my Id"))
 
+    def test_ignore_status_section(self):
+        self.cib.append_to_first_tag_name(
+            "status",
+            """\
+<elem1 id="status-1">
+    <elem1a id="status-1a">
+        <elem1aa id="status-1aa"/>
+        <elem1ab id="status-1ab"/>
+    </elem1a>
+    <elem1b id="status-1b">
+        <elem1ba id="status-1ba"/>
+        <elem1bb id="status-1bb"/>
+    </elem1b>
+</elem1>
+"""
+        )
+        self.assertFalse(lib.does_id_exist(self.cib.tree, "status-1"))
+        self.assertFalse(lib.does_id_exist(self.cib.tree, "status-1a"))
+        self.assertFalse(lib.does_id_exist(self.cib.tree, "status-1aa"))
+        self.assertFalse(lib.does_id_exist(self.cib.tree, "status-1ab"))
+        self.assertFalse(lib.does_id_exist(self.cib.tree, "status-1b"))
+        self.assertFalse(lib.does_id_exist(self.cib.tree, "status-1ba"))
+        self.assertFalse(lib.does_id_exist(self.cib.tree, "status-1bb"))
+
 class FindUniqueIdTest(CibToolsTest):
     def test_already_unique(self):
         self.fixture_add_primitive_with_id("myId")
diff --git a/pcs/utils.py b/pcs/utils.py
index 079d916..a7ed975 100644
--- a/pcs/utils.py
+++ b/pcs/utils.py
@@ -1589,15 +1589,35 @@ def is_valid_cib_scope(scope):
 # Checks to see if id exists in the xml dom passed
 # DEPRECATED use lxml version available in pcs.lib.cib.tools
 def does_id_exist(dom, check_id):
+    # do not search in /cib/status, it may contain references to previously
+    # existing and deleted resources and thus preventing creating them again
     if is_etree(dom):
-        for elem in dom.findall(str(".//*")):
+        for elem in dom.findall(str(
+            '(/cib/*[name()!="status"]|/*[name()!="cib"])/*'
+        )):
             if elem.get("id") == check_id:
                 return True
     else:
-        all_elem = dom.getElementsByTagName("*")
-        for elem in all_elem:
-            if elem.getAttribute("id") == check_id:
-                return True
+        document = (
+            dom
+            if isinstance(dom, xml.dom.minidom.Document)
+            else dom.ownerDocument
+        )
+        cib_found = False
+        for cib in dom_get_children_by_tag_name(document, "cib"):
+            cib_found = True
+            for section in cib.childNodes:
+                if section.nodeType != xml.dom.minidom.Node.ELEMENT_NODE:
+                    continue
+                if section.tagName == "status":
+                    continue
+                for elem in section.getElementsByTagName("*"):
+                    if elem.getAttribute("id") == check_id:
+                        return True
+        if not cib_found:
+            for elem in document.getElementsByTagName("*"):
+                if elem.getAttribute("id") == check_id:
+                    return True
     return False
 
 # Returns check_id if it doesn't exist in the dom, otherwise it adds an integer
-- 
1.8.3.1