abort-clean/list/clean-ruv now work for both suffixes

The rid passed to abort-clean-ruv and clean-ruv is now searched
for in both ipaca and domain trees as well as list-ruv now
displays both RUVs and CS-RUVs

https://fedorahosted.org/freeipa/ticket/4987

Reviewed-By: Martin Basti <mbasti@redhat.com>
This commit is contained in:
Stanislav Laznicka
2016-03-11 10:15:02 +01:00
committed by Martin Basti
parent d2bb8b7bb1
commit ee05442e5d
2 changed files with 100 additions and 29 deletions

View File

@@ -68,7 +68,7 @@ commands = {
"dnanextrange-set":(2, 2, "<master fqdn> <range>", "must provide a master and ID range"),
}
# tuple of commands that need proper Directory Manager password
# tuple of commands that work with ca tree and need Directory Manager password
dirman_passwd_req_commands = ("list-ruv", "clean-ruv", "abort-clean-ruv")
@@ -396,18 +396,67 @@ def get_ruv(realm, host, dirman_passwd, nolookup=False, ca=False):
return servers
def get_ruv_both_suffixes(realm, host, dirman_passwd, verbose, nolookup=False):
"""
Get RUVs for both domain and ipaca suffixes
"""
ruvs = {}
fail_gracefully = True
try:
ruvs['ca'] = get_ruv(realm, host, dirman_passwd, nolookup, True)
except (NoRUVsFound, RuntimeError) as e:
err = "Failed to get CS-RUVs from {host}: {err}".format(host=host,
err=e)
if isinstance(e, RuntimeError):
fail_gracefully = False
if verbose:
print(err)
root_logger.debug(err)
try:
ruvs['domain'] = get_ruv(realm, host, dirman_passwd, nolookup)
except (NoRUVsFound, RuntimeError) as e:
err = "Failed to get RUVs from {host}: {err}".format(host=host, err=e)
if isinstance(e, RuntimeError):
if not fail_gracefully:
raise
if verbose:
print(err)
root_logger.debug(err)
if not ruvs.keys():
raise NoRUVsFound("No RUV records found.")
return ruvs
def list_ruv(realm, host, dirman_passwd, verbose, nolookup=False):
"""
List the Replica Update Vectors on this host to get the available
replica IDs.
"""
try:
servers = get_ruv(realm, host, dirman_passwd, nolookup)
servers = get_ruv_both_suffixes(realm, host, dirman_passwd,
verbose, nolookup)
except (NoRUVsFound, RuntimeError) as e:
print(e)
sys.exit(0 if isinstance(e, NoRUVsFound) else 1)
for (netloc, rid) in servers:
print("%s: %s" % (netloc, rid))
print('Replica Update Vectors:')
if servers.get('domain'):
for netloc, rid in servers['domain']:
print("\t{name}: {id}".format(name=netloc, id=rid))
else:
print('\tNo RUVs found.')
print('Certificate Server Replica Update Vectors:')
if servers.get('ca'):
for netloc, rid in servers['ca']:
print("\t{name}: {id}".format(name=netloc, id=rid))
else:
print('\tNo CS-RUVs found.')
def get_rid_by_host(realm, sourcehost, host, dirman_passwd, nolookup=False):
"""
@@ -422,7 +471,8 @@ def get_rid_by_host(realm, sourcehost, host, dirman_passwd, nolookup=False):
if '%s:389' % host == netloc:
return int(rid)
def clean_ruv(realm, ruv, options, ca=False):
def clean_ruv(realm, ruv, options):
"""
Given an RID create a CLEANALLRUV task to clean it up.
"""
@@ -432,23 +482,28 @@ def clean_ruv(realm, ruv, options, ca=False):
sys.exit("Replica ID must be an integer: %s" % ruv)
try:
servers = get_ruv(realm, options.host, options.dirman_passwd,
options.nolookup, ca=ca)
servers = get_ruv_both_suffixes(realm, options.host,
options.dirman_passwd,
options.verbose,
options.nolookup)
except (NoRUVsFound, RuntimeError) as e:
print(e)
sys.exit(0 if isinstance(e, NoRUVsFound) else 1)
found = False
for (netloc, rid) in servers:
if ruv == int(rid):
found = True
hostname = netloc
tree_found = None
for tree, ruvs in servers.items():
for netloc, rid in ruvs:
if ruv == int(rid):
tree_found = tree
hostname = netloc
break
if tree_found:
break
if not found:
if not tree_found:
sys.exit("Replica ID %s not found" % ruv)
if ca:
if tree_found == 'ca':
print("Clean the Certificate Server Replication Update Vector for %s"
% hostname)
else:
@@ -463,7 +518,7 @@ def clean_ruv(realm, ruv, options, ca=False):
if not ipautil.user_input("Continue to clean?", False):
sys.exit("Aborted")
if ca:
if tree_found == 'ca':
thisrepl = replication.get_cs_replication_manager(realm, options.host,
options.dirman_passwd)
else:
@@ -472,6 +527,7 @@ def clean_ruv(realm, ruv, options, ca=False):
thisrepl.cleanallruv(ruv)
print("Cleanup task created")
def abort_clean_ruv(realm, ruv, options):
"""
Given an RID abort a CLEANALLRUV task.
@@ -482,30 +538,40 @@ def abort_clean_ruv(realm, ruv, options):
sys.exit("Replica ID must be an integer: %s" % ruv)
try:
servers = get_ruv(realm, options.host, options.dirman_passwd,
options.nolookup)
servers = get_ruv_both_suffixes(realm, options.host,
options.dirman_passwd,
options.verbose,
options.nolookup)
except (NoRUVsFound, RuntimeError) as e:
print(e)
sys.exit(0 if isinstance(e, NoRUVsFound) else 1)
found = False
for (netloc, rid) in servers:
if ruv == int(rid):
found = True
hostname = netloc
tree_found = None
for tree, ruvs in servers.items():
for netloc, rid in ruvs:
if ruv == int(rid):
tree_found = tree
hostname = netloc
break
if tree_found:
break
if not found:
if not tree_found:
sys.exit("Replica ID %s not found" % ruv)
print("Aborting the clean Replication Update Vector task for %s" % hostname)
print()
thisrepl = replication.ReplicationManager(realm, options.host,
options.dirman_passwd)
if tree_found == 'ca':
thisrepl = replication.get_cs_replication_manager(realm, options.host,
options.dirman_passwd)
else:
thisrepl = replication.ReplicationManager(realm, options.host,
options.dirman_passwd)
thisrepl.abortcleanallruv(ruv, options.force)
print("Cleanup task stopped")
def list_clean_ruv(realm, host, dirman_passwd, verbose, nolookup=False):
"""
List all clean RUV tasks.
@@ -701,7 +767,7 @@ def clean_dangling_ruvs(realm, host, options):
for csruv in master_info['clean_csruv']:
if csruv[1] not in cleaned:
cleaned.add(csruv[1])
clean_ruv(realm, csruv[1], options, ca=True)
clean_ruv(realm, csruv[1], options)
def check_last_link(delrepl, realm, dirman_passwd, force):
@@ -1574,7 +1640,8 @@ def main(options, args):
if options.dirman_passwd:
dirman_passwd = options.dirman_passwd
else:
if not test_connection(realm, host, options.nolookup):
if (not test_connection(realm, host, options.nolookup) or
args[0] in dirman_passwd_req_commands):
dirman_passwd = installutils.read_password("Directory Manager",
confirm=False, validate=False, retry=False)
if dirman_passwd is None or (

View File

@@ -135,6 +135,7 @@ Password for the IPA system user used by the Windows PassSync plugin to synchron
.TP
\fB\-\-from\fR=\fISERVER\fR
The server to pull the data from, used by the re\-initialize and force\-sync commands.
.TP
.SH "RANGES"
IPA uses the 389\-ds Distributed Numeric Assignment (DNA) Plugin to allocate POSIX ids for users and groups. A range is created when IPA is installed and half the range is assigned to the first IPA master for the purposes of allocation.
.TP
@@ -190,8 +191,11 @@ Using connect/disconnect you can manage the replication topology.
.TP
List the replication IDs in use:
# ipa\-replica\-manage list\-ruv
srv1.example.com:389: 7
srv2.example.com:389: 4
Replica Update Vectors:
srv1.example.com:389: 7
srv2.example.com:389: 4
Certificate Server Replica Update Vectors:
srv1.example.com:389: 9
.TP
Remove references to an orphaned and deleted master:
# ipa\-replica\-manage del \-\-force \-\-cleanup master.example.com