A sort of auxilliary patch which makes topology checks more resistant to https://fedorahosted.org/freeipa/ticket/5526

If required I will open a separate ticket for it though.

--
Martin^3 Babinsky
From 6b722203ba9442559b1311be63b8b05b862af084 Mon Sep 17 00:00:00 2001
From: Martin Babinsky <mbabi...@redhat.com>
Date: Tue, 8 Dec 2015 17:24:36 +0100
Subject: [PATCH] harden domain level 1 topology connectivity checks

this patch makes the check_last_link_managed() function more resistant to both
orphaned topology suffixes and also to cases when there are IPA masters do not
seem to manage any suffix. The function will now only complain loudly about
these cases and not cause crashes.

https://fedorahosted.org/freeipa/ticket/5526
---
 install/tools/ipa-replica-manage |  6 ++----
 ipaserver/install/replication.py | 41 ++++++++++++++++++++++++++++++++--------
 2 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/install/tools/ipa-replica-manage b/install/tools/ipa-replica-manage
index 5124731255807287a7857b1a4cdc2e6799cd7278..81a133192b17bd2de45aabccec279c9b0c8b2fb8 100755
--- a/install/tools/ipa-replica-manage
+++ b/install/tools/ipa-replica-manage
@@ -785,11 +785,9 @@ def check_deleted_segments(hostname, masters, topo_errors, starting_host):
             hostname))
         return
 
-    suffixes = api.Command.topologysuffix_find('', sizelimit=0)['result']
-    suffix_to_masters = replication.map_masters_to_suffixes(masters, suffixes)
+    suffix_to_masters = replication.map_masters_to_suffixes(masters)
 
-    for suffix in suffixes:
-        suffix_name = suffix['cn'][0]
+    for suffix_name in suffix_to_masters:
         suffix_member_cns = [
             m['cn'][0] for m in suffix_to_masters[suffix_name]
         ]
diff --git a/ipaserver/install/replication.py b/ipaserver/install/replication.py
index aaa841ca6ac415f90d71a3126f18a787500d7e6a..522e93fa2c751c18064004d30059e67fba0e9294 100644
--- a/ipaserver/install/replication.py
+++ b/ipaserver/install/replication.py
@@ -1740,11 +1740,16 @@ class CAReplicationManager(ReplicationManager):
             raise RuntimeError("Failed to start replication")
 
 
-def map_masters_to_suffixes(masters, suffixes):
+def map_masters_to_suffixes(masters):
     masters_to_suffix = {}
 
     for master in masters:
-        managed_suffixes = master['iparepltopomanagedsuffix_topologysuffix']
+        try:
+            managed_suffixes = master['iparepltopomanagedsuffix_topologysuffix']
+        except KeyError:
+            print("IPA master {0} does not manage any suffix")
+            continue
+
         for suffix_name in managed_suffixes:
             try:
                 masters_to_suffix[suffix_name].append(master)
@@ -1759,6 +1764,19 @@ def check_hostname_in_masters(hostname, masters):
     return hostname in master_cns
 
 
+def get_orphaned_suffixes(masters):
+    """
+    :param masters: result of server_find command
+    :return a set consisting of suffix names which are not managed by any
+    master
+    """
+    all_suffixes = api.Command.topologysuffix_find(sizelimit=0)['result']
+    all_suffix_names = set(s['cn'][0] for s in all_suffixes)
+    managed_suffixes = set(map_masters_to_suffixes(masters))
+
+    return all_suffix_names ^ managed_suffixes
+
+
 def check_last_link_managed(api, hostname, masters):
     """
     Check if 'hostname' is safe to delete.
@@ -1767,16 +1785,23 @@ def check_last_link_managed(api, hostname, masters):
               {<suffix name>: (<original errors>,
               <errors after removing the node>)}
     """
-    suffixes = api.Command.topologysuffix_find(sizelimit=0)['result']
-    suffix_to_masters = map_masters_to_suffixes(masters, suffixes)
+    suffix_to_masters = map_masters_to_suffixes(masters)
     topo_errors_by_suffix = {}
 
-    for suffix in suffixes:
-        suffix_name = suffix['cn'][0]
-        suffix_members = suffix_to_masters[suffix_name]
+    # sanity check for orphaned suffixes
+    orphaned_suffixes = get_orphaned_suffixes(masters)
+    if orphaned_suffixes:
+        print("The following suffixes are not managed by any IPA master:")
+        print("  {0}".format(
+                ', '.join(sorted(orphaned_suffixes))
+            )
+        )
+
+    for suffix_name in suffix_to_masters:
         print("Checking connectivity in topology suffix '{0}'".format(
             suffix_name))
-        if not check_hostname_in_masters(hostname, suffix_members):
+        if not check_hostname_in_masters(hostname,
+                                         suffix_to_masters[suffix_name]):
             print(
                 "'{0}' is not a part of topology suffix '{1}'".format(
                     hostname, suffix_name
-- 
2.5.0

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to