summaryrefslogtreecommitdiffstats
path: root/ipaserver
diff options
context:
space:
mode:
authorMartin Babinsky <mbabinsk@redhat.com>2016-06-08 18:34:37 +0200
committerMartin Basti <mbasti@redhat.com>2016-06-17 18:55:19 +0200
commit47decc9b843b1b1d292511bcc8a24f8ac85745c0 (patch)
treef24aad61089618a1106c396ebd6c2428da2dd223 /ipaserver
parent081941a5b9c9ac8832c465b857032e474bb9b09f (diff)
downloadfreeipa-47decc9b843b1b1d292511bcc8a24f8ac85745c0.tar.gz
freeipa-47decc9b843b1b1d292511bcc8a24f8ac85745c0.tar.xz
freeipa-47decc9b843b1b1d292511bcc8a24f8ac85745c0.zip
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 <mbasti@redhat.com>
Diffstat (limited to 'ipaserver')
-rw-r--r--ipaserver/install/replication.py124
1 files changed, 14 insertions, 110 deletions
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 name>: (<original errors>,
- <errors after removing the node>)}
- """
- 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)