Check for the existence of a replication agreement before deleting it.

When using ipa-replica-manage or ipa-csreplica-manage to delete an agreement with a host we would try to make a connection to that host prior to tryign to delete it. This meant that the trying to delete a host we don't hvae an agreement with would return a connection error instead of a "no agreement with host foo" error.

Also display a completed message when an agreement is removed.

https://fedorahosted.org/freeipa/ticket/2048
https://fedorahosted.org/freeipa/ticket/2125

rob
>From bcc804e97b83c597e6cbe71497e491020fe5f97d Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcrit...@redhat.com>
Date: Mon, 16 Jan 2012 10:24:15 -0500
Subject: [PATCH] Check for the existence of a replication agreement before
 deleting it.

When using ipa-replica-manage or ipa-csreplica-manage to delete an
agreement with a host we would try to make a connection to that host
prior to tryign to delete it. This meant that the trying to delete
a host we don't hvae an agreement with would return a connection
error instead of a "no agreement with host foo" error.

Also display a completed message when an agreement is removed.

https://fedorahosted.org/freeipa/ticket/2048
https://fedorahosted.org/freeipa/ticket/2125
---
 install/tools/ipa-csreplica-manage |   27 +++++++++++++++++----------
 install/tools/ipa-replica-manage   |   29 +++++++++++++++++------------
 ipaserver/install/replication.py   |   22 ++++++++++++++++++++++
 3 files changed, 56 insertions(+), 22 deletions(-)

diff --git a/install/tools/ipa-csreplica-manage b/install/tools/ipa-csreplica-manage
index ac39b70fa54e62ec1904784c6ceebd28c93cf804..97c504552c0763e351ef6ae7e197a0acb684a83b 100755
--- a/install/tools/ipa-csreplica-manage
+++ b/install/tools/ipa-csreplica-manage
@@ -267,12 +267,26 @@ def del_link(realm, replica1, replica2, dirman_passwd, force=False):
     repl1.delete_agreement(replica2)
     repl1.delete_referral(replica2)
 
+    print "Deleted replication agreement from '%s' to '%s'" % (replica1, replica2)
+
 def del_master(realm, hostname, options):
 
     force_del = False
 
     delrepl = None
-    # 1. Connect to the dogtag DS to be removed.
+
+    # 1. Connect to the local dogtag DS server
+    try:
+        thisrepl = CSReplicationManager(realm, options.host,
+                                        options.dirman_passwd)
+    except Exception, e:
+        sys.exit("Failed to connect to server %s: %s" % (options.host, convert_error(e)))
+
+    # 2. Ensure we have an agreement with the master
+    if thisrepl.get_replication_agreement(hostname) is None:
+        sys.exit("'%s' has no replication agreement for '%s'" % (options.host, hostname))
+
+    # 3. Connect to the dogtag DS to be removed.
     try:
         delrepl = CSReplicationManager(realm, hostname, options.dirman_passwd)
     except Exception, e:
@@ -283,21 +297,14 @@ def del_master(realm, hostname, options):
             print "Unable to connect to replica %s, forcing removal" % hostname
             force_del = True
 
-    # 2. Connect to the local dogtag DS server
-    try:
-        thisrepl = CSReplicationManager(realm, options.host,
-                                        options.dirman_passwd)
-    except Exception, e:
-        sys.exit("Failed to connect to server %s: %s" % (options.host, convert_error(e)))
-
-    # 2. Get list of agreements.
+    # 4. Get list of agreements.
     if delrepl is None:
         # server not up, just remove it from this server
         replica_names = [options.host]
     else:
         replica_names = delrepl.find_ipa_replication_agreements()
 
-    # 3. Remove each agreement
+    # 5. Remove each agreement
     for r in replica_names:
         try:
             del_link(realm, r, hostname, options.dirman_passwd, force=True)
diff --git a/install/tools/ipa-replica-manage b/install/tools/ipa-replica-manage
index 8506fcba75bc1f6c1f8877605e30be00c651e8f7..32cee6ed21eea38192fe292dc38824049c05ab3a 100755
--- a/install/tools/ipa-replica-manage
+++ b/install/tools/ipa-replica-manage
@@ -272,12 +272,25 @@ def del_link(realm, replica1, replica2, dirman_passwd, force=False):
         except Exception, e:
             print "Error deleting winsync replica shared info: %s" % str(e)
 
+    print "Deleted replication agreement from '%s' to '%s'" % (replica1, replica2)
 
 def del_master(realm, hostname, options):
 
     force_del = False
 
-    # 1. Connect to the master to be removed.
+    # 1. Connect to the local server
+    try:
+        thisrepl = replication.ReplicationManager(realm, options.host,
+                                                  options.dirman_passwd)
+    except Exception, e:
+        print "Failed to connect to server %s: %s" % (options.host, str(e))
+        sys.exit(1)
+
+    # 2. Ensure we have an agreement with the master
+    if thisrepl.get_replication_agreement(hostname) is None:
+        sys.exit("'%s' has no replication agreement for '%s'" % (options.host, hostname))
+
+    # 3. Connect to the master to be removed.
     try:
         delrepl = replication.ReplicationManager(realm, hostname, options.dirman_passwd)
     except Exception, e:
@@ -288,14 +301,6 @@ def del_master(realm, hostname, options):
             print "Unable to connect to replica %s, forcing removal" % hostname
             force_del = True
 
-    # 2. Connect to the local server
-    try:
-        thisrepl = replication.ReplicationManager(realm, options.host,
-                                                  options.dirman_passwd)
-    except Exception, e:
-        print "Failed to connect to server %s: %s" % (options.host, str(e))
-        sys.exit(1)
-
     if force_del:
         dn = 'cn=masters,cn=ipa,cn=etc,%s' % thisrepl.suffix
         res = thisrepl.conn.search_s(dn, ldap.SCOPE_ONELEVEL)
@@ -306,21 +311,21 @@ def del_master(realm, hostname, options):
         # 2. Get list of agreements.
         replica_names = delrepl.find_ipa_replication_agreements()
 
-    # 3. Remove each agreement
+    # 4. Remove each agreement
     for r in replica_names:
         try:
             del_link(realm, r, hostname, options.dirman_passwd, force=True)
         except Exception, e:
             print "There were issues removing a connection: %s" % str(e)
 
-    # 4. Finally clean up the removed replica common entries.
+    # 5. Finally clean up the removed replica common entries.
     try:
         thisrepl.replica_cleanup(hostname, realm, force=True)
     except Exception, e:
         print "Failed to cleanup %s entries: %s" % (hostname, str(e))
         print "You may need to manually remove them from the tree"
 
-    # 5. And clean up the removed replica DNS entries if any.
+    # 6. And clean up the removed replica DNS entries if any.
     try:
         if bindinstance.dns_container_exists(options.host, thisrepl.suffix,
                                              dm_password=options.dirman_passwd):
diff --git a/ipaserver/install/replication.py b/ipaserver/install/replication.py
index 3ac99e6bd75f2990be346c14fce424927c6550fa..3f3dfa30433f55789dd5774124d761ed12a89e5d 100644
--- a/ipaserver/install/replication.py
+++ b/ipaserver/install/replication.py
@@ -211,6 +211,28 @@ class ReplicationManager(object):
 
         return res
 
+    def get_replication_agreement(self, hostname):
+        """
+        The replication agreements are stored in
+        cn="$SUFFIX",cn=mapping tree,cn=config
+
+        Get the replication agreement for a specific host.
+
+        Returns None if not found.
+        """
+
+        filt = "(&(objectclass=nsds5ReplicationAgreement)(nsDS5ReplicaHost=%s))" % hostname
+        try:
+            entry = self.conn.search_s("cn=mapping tree,cn=config",
+                                       ldap.SCOPE_SUBTREE, filt)
+        except ldap.NO_SUCH_OBJECT:
+            return None
+
+        if len(entry) == 0:
+            return None
+        else:
+            return entry[0] # There can be only one
+
     def add_replication_manager(self, conn, dn, pw):
         """
         Create a pseudo user to use for replication.
-- 
1.7.6

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to