summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Crittenden <rcritten@redhat.com>2012-01-16 10:24:15 -0500
committerMartin Kosek <mkosek@redhat.com>2012-01-30 17:28:18 +0100
commitbf29b44942160b30eb9ed347bf5b6c8f30418d6e (patch)
tree4f7809b7a9ea2e22cef486152fa1a548839d80b5
parent46a472ef20ae3b25a2e4c4f92b26127e73f8f7a4 (diff)
downloadfreeipa-bf29b44942160b30eb9ed347bf5b6c8f30418d6e.tar.gz
freeipa-bf29b44942160b30eb9ed347bf5b6c8f30418d6e.tar.xz
freeipa-bf29b44942160b30eb9ed347bf5b6c8f30418d6e.zip
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 have 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
-rwxr-xr-xinstall/tools/ipa-csreplica-manage27
-rwxr-xr-xinstall/tools/ipa-replica-manage29
-rw-r--r--ipaserver/install/replication.py22
3 files changed, 56 insertions, 22 deletions
diff --git a/install/tools/ipa-csreplica-manage b/install/tools/ipa-csreplica-manage
index ac39b70fa..97c504552 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 8506fcba7..32cee6ed2 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 052f18346..6f6372514 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.