mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2026-10-12 16:32:01 -05:00
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
This commit is contained in:
1 parent
ce360f37f8
commit
7a1399bee1
3 files changed
+56
-22
No files matched your search
@@ -267,12 +267,26 @@ def del_link(realm, replica1, replica2, dirman_passwd, force=False):
|
|||||||
repl1.delete_agreement(replica2)
|
repl1.delete_agreement(replica2)
|
||||||
repl1.delete_referral(replica2)
|
repl1.delete_referral(replica2)
|
||||||
|
|
||||||
|
print "Deleted replication agreement from '%s' to '%s'" % (replica1, replica2)
|
||||||
|
|
||||||
def del_master(realm, hostname, options):
|
def del_master(realm, hostname, options):
|
||||||
|
|
||||||
force_del = False
|
force_del = False
|
||||||
|
|
||||||
delrepl = None
|
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:
|
try:
|
||||||
delrepl = CSReplicationManager(realm, hostname, options.dirman_passwd)
|
delrepl = CSReplicationManager(realm, hostname, options.dirman_passwd)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
@@ -283,21 +297,14 @@ def del_master(realm, hostname, options):
|
|||||||
print "Unable to connect to replica %s, forcing removal" % hostname
|
print "Unable to connect to replica %s, forcing removal" % hostname
|
||||||
force_del = True
|
force_del = True
|
||||||
|
|
||||||
# 2. Connect to the local dogtag DS server
|
# 4. Get list of agreements.
|
||||||
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.
|
|
||||||
if delrepl is None:
|
if delrepl is None:
|
||||||
# server not up, just remove it from this server
|
# server not up, just remove it from this server
|
||||||
replica_names = [options.host]
|
replica_names = [options.host]
|
||||||
else:
|
else:
|
||||||
replica_names = delrepl.find_ipa_replication_agreements()
|
replica_names = delrepl.find_ipa_replication_agreements()
|
||||||
|
|
||||||
# 3. Remove each agreement
|
# 5. Remove each agreement
|
||||||
for r in replica_names:
|
for r in replica_names:
|
||||||
try:
|
try:
|
||||||
del_link(realm, r, hostname, options.dirman_passwd, force=True)
|
del_link(realm, r, hostname, options.dirman_passwd, force=True)
|
||||||
|
|||||||
@@ -272,12 +272,25 @@ def del_link(realm, replica1, replica2, dirman_passwd, force=False):
|
|||||||
except Exception, e:
|
except Exception, e:
|
||||||
print "Error deleting winsync replica shared info: %s" % str(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):
|
def del_master(realm, hostname, options):
|
||||||
|
|
||||||
force_del = False
|
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:
|
try:
|
||||||
delrepl = replication.ReplicationManager(realm, hostname, options.dirman_passwd)
|
delrepl = replication.ReplicationManager(realm, hostname, options.dirman_passwd)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
@@ -288,14 +301,6 @@ def del_master(realm, hostname, options):
|
|||||||
print "Unable to connect to replica %s, forcing removal" % hostname
|
print "Unable to connect to replica %s, forcing removal" % hostname
|
||||||
force_del = True
|
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:
|
if force_del:
|
||||||
dn = 'cn=masters,cn=ipa,cn=etc,%s' % thisrepl.suffix
|
dn = 'cn=masters,cn=ipa,cn=etc,%s' % thisrepl.suffix
|
||||||
res = thisrepl.conn.search_s(dn, ldap.SCOPE_ONELEVEL)
|
res = thisrepl.conn.search_s(dn, ldap.SCOPE_ONELEVEL)
|
||||||
@@ -306,21 +311,21 @@ def del_master(realm, hostname, options):
|
|||||||
# 2. Get list of agreements.
|
# 2. Get list of agreements.
|
||||||
replica_names = delrepl.find_ipa_replication_agreements()
|
replica_names = delrepl.find_ipa_replication_agreements()
|
||||||
|
|
||||||
# 3. Remove each agreement
|
# 4. Remove each agreement
|
||||||
for r in replica_names:
|
for r in replica_names:
|
||||||
try:
|
try:
|
||||||
del_link(realm, r, hostname, options.dirman_passwd, force=True)
|
del_link(realm, r, hostname, options.dirman_passwd, force=True)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
print "There were issues removing a connection: %s" % str(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:
|
try:
|
||||||
thisrepl.replica_cleanup(hostname, realm, force=True)
|
thisrepl.replica_cleanup(hostname, realm, force=True)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
print "Failed to cleanup %s entries: %s" % (hostname, str(e))
|
print "Failed to cleanup %s entries: %s" % (hostname, str(e))
|
||||||
print "You may need to manually remove them from the tree"
|
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:
|
try:
|
||||||
if bindinstance.dns_container_exists(options.host, thisrepl.suffix,
|
if bindinstance.dns_container_exists(options.host, thisrepl.suffix,
|
||||||
dm_password=options.dirman_passwd):
|
dm_password=options.dirman_passwd):
|
||||||
|
|||||||
@@ -211,6 +211,28 @@ class ReplicationManager(object):
|
|||||||
|
|
||||||
return res
|
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):
|
def add_replication_manager(self, conn, dn, pw):
|
||||||
"""
|
"""
|
||||||
Create a pseudo user to use for replication.
|
Create a pseudo user to use for replication.
|
||||||
|
|||||||
Reference in new issue
Block a user