summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xinstall/tools/ipa-csreplica-manage58
-rw-r--r--ipaserver/install/replication.py22
2 files changed, 57 insertions, 23 deletions
diff --git a/install/tools/ipa-csreplica-manage b/install/tools/ipa-csreplica-manage
index 39cfa5851..5fce48a37 100755
--- a/install/tools/ipa-csreplica-manage
+++ b/install/tools/ipa-csreplica-manage
@@ -176,7 +176,7 @@ def list_replicas(realm, host, replica, dirman_passwd, verbose):
peers[ent.getValue('cn')] = ['CA not configured', '']
except Exception, e:
- sys.exit("Failed to get data from '%s': %s" % (host, convert_error(e)))
+ sys.exit("Failed to get data from '%s' while trying to list replicas: %s" % (host, convert_error(e)))
finally:
conn.unbind_s()
@@ -205,18 +205,21 @@ def del_link(realm, replica1, replica2, dirman_passwd, force=False):
repl1 = CSReplicationManager(realm, replica1, dirman_passwd, PORT, True)
repl1.hostnames = [replica1, replica2]
- type1 = repl1.get_agreement_type(replica2)
- repl_list = repl1.find_ipa_replication_agreements()
- if not force and len(repl_list) <= 1:
- print "Cannot remove the last replication link of '%s'" % replica1
- print "Please use the 'del' command to remove it from the domain"
- sys.exit(1)
+ repl_list1 = repl1.find_replication_agreements()
+
+ # Find the DN of the replication agreement to remove
+ replica1_dn = None
+ for e in repl_list1:
+ if e.getValue('nsDS5ReplicaHost') == replica2:
+ replica1_dn = e.dn
+ break
+
+ if replica1_dn is None:
+ sys.exit("'%s' has no replication agreement for '%s'" % (replica1, replica2))
+
+ repl1.hostnames = [replica1, replica2]
- except ldap.NO_SUCH_OBJECT:
- sys.exit("'%s' has no replication agreement for '%s'" % (replica1, replica2))
- except errors.NotFound:
- sys.exit("'%s' has no replication agreement for '%s'" % (replica1, replica2))
except ldap.SERVER_DOWN, e:
sys.exit("Unable to connect to %s: %s" % (ipautil.format_netloc(replica1, PORT), convert_error(e)))
except Exception, e:
@@ -226,12 +229,31 @@ def del_link(realm, replica1, replica2, dirman_passwd, force=False):
repl2 = CSReplicationManager(realm, replica2, dirman_passwd, PORT, True)
repl2.hostnames = [replica1, replica2]
- repl_list = repl1.find_ipa_replication_agreements()
+ repl_list = repl2.find_replication_agreements()
+
+ # Now that we've confirmed that both hostnames are vaild, make sure
+ # that we aren't removing the last link from either side.
if not force and len(repl_list) <= 1:
print "Cannot remove the last replication link of '%s'" % replica2
print "Please use the 'del' command to remove it from the domain"
sys.exit(1)
+ if not force and len(repl_list1) <= 1:
+ print "Cannot remove the last replication link of '%s'" % replica1
+ print "Please use the 'del' command to remove it from the domain"
+ sys.exit(1)
+
+ # Find the DN of the replication agreement to remove
+ replica2_dn = None
+ for e in repl_list:
+ if e.getValue('nsDS5ReplicaHost') == replica1:
+ replica2_dn = e.dn
+ break
+
+ # This should never happen
+ if replica2_dn is None:
+ sys.exit("'%s' has no replication agreement for '%s'" % (replica1, replica2))
+
except ldap.NO_SUCH_OBJECT:
print "'%s' has no replication agreement for '%s'" % (replica2, replica1)
if not force:
@@ -248,7 +270,7 @@ def del_link(realm, replica1, replica2, dirman_passwd, force=False):
if repl2:
failed = False
try:
- repl2.delete_agreement(replica1)
+ repl2.delete_agreement(replica1, replica2_dn)
repl2.delete_referral(replica1)
except Exception, e:
print "Unable to remove agreement on %s: %s" % (replica2, convert_error(e))
@@ -263,7 +285,7 @@ def del_link(realm, replica1, replica2, dirman_passwd, force=False):
if not repl2 and force:
print "Forcing removal on '%s'" % replica1
- repl1.delete_agreement(replica2)
+ repl1.delete_agreement(replica2, replica1_dn)
repl1.delete_referral(replica2)
print "Deleted replication agreement from '%s' to '%s'" % (replica1, replica2)
@@ -324,13 +346,13 @@ def add_link(realm, replica1, replica2, dirman_passwd, options):
except ldap.SERVER_DOWN, e:
sys.exit("Unable to connect to %s: %s" % (ipautil.format_netloc(replica2, 636), convert_error(e)))
except Exception, e:
- sys.exit("Failed to get data from '%s': %s" % (replica1, convert_error(e)))
+ sys.exit("Failed to get data while trying to bind to '%s': %s" % (replica1, convert_error(e)))
try:
repl1 = CSReplicationManager(realm, replica1, dirman_passwd, PORT, True)
entries = repl1.find_replication_agreements()
for e in entries:
- if replica1 in e.dn or replica2 in e.dn:
+ if e.getValue('nsDS5ReplicaHost') == replica2:
sys.exit('This replication agreement already exists.')
repl1.hostnames = [replica1, replica2]
@@ -339,7 +361,7 @@ def add_link(realm, replica1, replica2, dirman_passwd, options):
except ldap.SERVER_DOWN, e:
sys.exit("Unable to connect to %s %s" % (ipautil.format_netloc(replica1, PORT), convert_error(e)))
except Exception, e:
- sys.exit("Failed to get data from '%s': %s" % (replica1, convert_error(e)))
+ sys.exit("Failed to get data from '%s' while trying to get current agreements: %s" % (replica1, convert_error(e)))
repl1.setup_replication(replica2, PORT, 0, DN(('cn', 'Directory Manager')), dirman_passwd, True, True)
print "Connected '%s' to '%s'" % (replica1, replica2)
@@ -436,7 +458,7 @@ def main():
elif len(args) == 2:
replica1 = host
replica2 = args[1]
- del_link(realm, replica1, replica2, dirman_passwd)
+ del_link(realm, replica1, replica2, dirman_passwd, options.force)
try:
main()
diff --git a/ipaserver/install/replication.py b/ipaserver/install/replication.py
index 564097e76..260e7bba1 100644
--- a/ipaserver/install/replication.py
+++ b/ipaserver/install/replication.py
@@ -648,8 +648,20 @@ class ReplicationManager(object):
except ldap.NO_SUCH_OBJECT:
pass
- def delete_agreement(self, hostname):
- cn, dn = self.agreement_dn(hostname)
+ def delete_agreement(self, hostname, dn=None):
+ """
+ Delete a replication agreement.
+
+ @hostname: the hostname of the agreement to remove
+ @dn: optional dn of the agreement to remove
+
+ For IPA agreements we can easily calculate the DN of the agreement
+ to remove. Dogtag agreements are another matter, its agreement
+ names depend entirely on where it is created. In this case it is
+ better to pass the DN in directly.
+ """
+ if dn is None:
+ cn, dn = self.agreement_dn(hostname)
return self.conn.deleteEntry(dn)
def delete_referral(self, hostname):
@@ -808,11 +820,11 @@ class ReplicationManager(object):
self.setup_agreement(r_conn, self.conn.host, port=r_port,
repl_man_dn=self.repl_man_dn,
repl_man_passwd=self.repl_man_passwd,
- master=True)
+ master=False)
self.setup_agreement(self.conn, r_hostname, port=r_port,
repl_man_dn=self.repl_man_dn,
repl_man_passwd=self.repl_man_passwd,
- master=False)
+ master=True)
else:
self.setup_agreement(r_conn, self.conn.host, port=r_port,
repl_man_dn=self.repl_man_dn,
@@ -822,7 +834,7 @@ class ReplicationManager(object):
repl_man_passwd=self.repl_man_passwd)
#Finally start replication
- ret = self.start_replication(r_conn, master=True)
+ ret = self.start_replication(r_conn, master=False)
if ret != 0:
raise RuntimeError("Failed to start replication")