From 47decc9b843b1b1d292511bcc8a24f8ac85745c0 Mon Sep 17 00:00:00 2001 From: Martin Babinsky Date: Wed, 8 Jun 2016 18:34:37 +0200 Subject: ipa-replica-manage: use `server_del` when removing domain level 1 replica `ipa-replica-manage del` will now call `server_del` behind the scenes when a removal of replica from managed topology is requested. The existing removal options were mapped on the server_del options to maintain backwards compatibility with earlier versions. https://fedorahosted.org/freeipa/ticket/5588 Reviewed-By: Martin Basti --- ipaserver/install/replication.py | 124 +++++---------------------------------- 1 file changed, 14 insertions(+), 110 deletions(-) (limited to 'ipaserver') diff --git a/ipaserver/install/replication.py b/ipaserver/install/replication.py index cbef796ac..b8b665267 100644 --- a/ipaserver/install/replication.py +++ b/ipaserver/install/replication.py @@ -29,9 +29,8 @@ from random import randint import ldap from ipalib import api, errors +from ipalib.cli import textui from ipalib.constants import CACERT -from ipaserver.topology import ( - create_topology_graph, get_topology_connection_errors) from ipapython.ipa_log_manager import root_logger from ipapython import ipautil, ipaldap from ipapython.dn import DN @@ -1768,116 +1767,21 @@ class CAReplicationManager(ReplicationManager): raise RuntimeError("Failed to start replication") -def map_masters_to_suffixes(masters): - masters_to_suffix = {} - - for master in masters: - try: - managed_suffixes = master['iparepltopomanagedsuffix_topologysuffix'] - except KeyError: - print("IPA master {0} does not manage any suffix") - continue - - for suffix_name in managed_suffixes: - try: - masters_to_suffix[suffix_name].append(master) - except KeyError: - masters_to_suffix[suffix_name] = [master] - - return masters_to_suffix - - -def check_hostname_in_masters(hostname, masters): - master_cns = {m['cn'][0] for m in masters} - return hostname in master_cns - - -def get_orphaned_suffixes(masters): - """ - :param masters: result of server_find command - :return a set consisting of suffix names which are not managed by any - master +def run_server_del_as_cli(api_instance, hostname, **options): """ - all_suffixes = api.Command.topologysuffix_find( - sizelimit=0)['result'] - all_suffix_names = set(s['cn'][0] for s in all_suffixes) - managed_suffixes = set(map_masters_to_suffixes(masters)) + run server_del API command and print the result to stdout/stderr using + textui backend. - return all_suffix_names ^ managed_suffixes - - -def check_last_link_managed(api, hostname, masters): + :params api_instance: API instance + :params hostname: server FQDN + :params options: options for server_del command """ - Check if 'hostname' is safe to delete. + server_del_cmd = api_instance.Command.server_del - :returns: a dictionary of topology errors across all suffixes in the form - {: (, - )} - """ - suffix_to_masters = map_masters_to_suffixes(masters) - topo_errors_by_suffix = {} - - # sanity check for orphaned suffixes - orphaned_suffixes = get_orphaned_suffixes(masters) - if orphaned_suffixes: - print("The following suffixes are not managed by any IPA master:") - print(" {0}".format( - ', '.join(sorted(orphaned_suffixes)) - ) - ) + if 'version' not in options: + options['version'] = api_instance.env.api_version - for suffix_name in suffix_to_masters: - print("Checking connectivity in topology suffix '{0}'".format( - suffix_name)) - if not check_hostname_in_masters(hostname, - suffix_to_masters[suffix_name]): - print( - "'{0}' is not a part of topology suffix '{1}'".format( - hostname, suffix_name - ) - ) - print("Not checking connectivity") - continue - - segments = api.Command.topologysegment_find( - suffix_name, sizelimit=0).get('result') - graph = create_topology_graph(suffix_to_masters[suffix_name], segments) - - # check topology before removal - orig_errors = get_topology_connection_errors(graph) - if orig_errors: - print("Current topology in suffix '{0}' is disconnected:".format( - suffix_name)) - print("Changes are not replicated to all servers and data are " - "probably inconsistent.") - print("You need to add segments to reconnect the topology.") - print_connect_errors(orig_errors) - - # after removal - try: - graph.remove_vertex(hostname) - except ValueError: - pass # ignore already deleted master, continue to clean - - new_errors = get_topology_connection_errors(graph) - if new_errors: - print("WARNING: Removal of '{0}' will lead to disconnected " - "topology in suffix '{1}'".format(hostname, suffix_name)) - print("Changes will not be replicated to all servers and data will" - " become inconsistent.") - print("You need to add segments to prevent disconnection of the " - "topology.") - print("Errors in topology after removal:") - print_connect_errors(new_errors) - - topo_errors_by_suffix[suffix_name] = (orig_errors, new_errors) - - return topo_errors_by_suffix - - -def print_connect_errors(errors): - for error in errors: - print("Topology does not allow server %s to replicate with servers:" - % error[0]) - for srv in error[2]: - print(" %s" % srv) + result = server_del_cmd(hostname, **options) + + textui_backend = textui(api_instance) + server_del_cmd.output_for_cli(textui_backend, result, hostname, **options) -- cgit