mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-01-27 16:46:42 -06:00
Fix CS replication management.
The master side should be on the local side, replica1, not the remote. This required reversing a few master variables. This impacts the naming of the replication agreements. When deleting an agreement pass in the DN of that agreement rather than trying to calculate what it is on-the-fly. We cannot be sure which side is the master/clone and since we search for it anyway to determine if the agreement exists it is more correct to use what we find. The force flag wasn't being passed into del_link so there was no way to force a deletion. https://fedorahosted.org/freeipa/ticket/2858
This commit is contained in:
parent
b3606e3d92
commit
2ca7bb3134
@ -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()
|
||||
|
@ -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")
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user