From 7da0d18f31eac854c9a5eed52e250171d0449542 Mon Sep 17 00:00:00 2001 From: mciecier Date: Wed, 1 Mar 2023 13:20:41 +0100 Subject: [PATCH] Fix update run to not run update on excluded nodes Change[1] modified how --limit option, used together with skiplist, works in ussuri and onwards. For overcloud update run the change poses some problems, because when update run is triggered --limit option is used to run control sequence of nodes being updated. As a result skiplisted nodes can be added to update run unintentionally. With this fix `excluded_overcloud` group is added to --limit flag to exclude all nodes in skiplist when update run is triggered. `excluded_overcloud` group is added only when skiplist contains any host Resolves: rhbz#2166224 [1]https: //review.opendev.org/c/openstack/python-tripleoclient/+/741406 Change-Id: Icd782739003f4ee77895b0c028500cc6de808ead --- tripleoclient/utils.py | 39 ++++++++++++++++++++++++++++ tripleoclient/v1/overcloud_update.py | 26 ++++++++++++++++--- 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/tripleoclient/utils.py b/tripleoclient/utils.py index 14ef59429..0dcdd74b8 100644 --- a/tripleoclient/utils.py +++ b/tripleoclient/utils.py @@ -210,6 +210,40 @@ def makedirs(dir_path): return True +def compare_limit_nodes_with_excluded_hosts(limit_nodes, excluded_hosts): + """Compare limit nodes list with excluded hosts list. + + This will compare the limit nodes list with the excluded hosts list + and raise an Exception if there is a match to inform user that the + host is in both lists. If user marks a host in limit option as + excluded with exclamatory mark (!) then it will be ignored during + the comparison. + + :param limit_hosts: list of hosts to limit the playbook to. + :type limit_hosts: `list` + :param excluded_hosts: list of hosts to exclude from the playbook. + :type excluded_hosts: `list` + + :raises: + RuntimeError if there is a match between the limit nodes and the + excluded hosts. + + """ + if limit_nodes and excluded_hosts: + matching_hosts_found = [] + for limit_node in re.split(':', limit_nodes): + if not limit_node.startswith('!') and limit_node in \ + excluded_hosts: + matching_hosts_found.append(limit_node) + + if matching_hosts_found: + raise RuntimeError( + 'Hosts {} are in both the limit nodes and the ' + 'excluded hosts list. Please remove it from one of ' + 'the lists.'.format(','.join(matching_hosts_found)) + ) + + def playbook_limit_parse(limit_nodes): """Return a parsed string for limits. @@ -1012,6 +1046,11 @@ def get_excluded_ip_addresses(working_dir): 'BlacklistedIpAddresses', working_dir) +def get_excluded_hostnames(working_dir): + return get_stack_saved_output_item( + 'BlacklistedHostnames', working_dir) + + def get_role_net_ip_map(working_dir): return get_stack_saved_output_item( 'RoleNetIpMap', working_dir) diff --git a/tripleoclient/v1/overcloud_update.py b/tripleoclient/v1/overcloud_update.py index 12745c53b..c93cf0d34 100644 --- a/tripleoclient/v1/overcloud_update.py +++ b/tripleoclient/v1/overcloud_update.py @@ -95,9 +95,12 @@ class UpdateRun(command.Command): action='store', required=True, help=_("A string that identifies a single node or comma-separated" - "list of nodes the config-download Ansible playbook " - "execution will be limited to. For example: --limit" - " \"compute-0,compute-1,compute-5\".") + " list of nodes the config-download Ansible playbook" + " execution will be limited to. For example: --limit" + " \"compute-0,compute-1,compute-5\". When" + " DeploymentServerBlacklist is defined, excluded_overcloud" + " group is added at the end of the string and nodes from" + " the group will be skipped during the execution.") ) parser.add_argument('--playbook', nargs="*", @@ -190,6 +193,19 @@ class UpdateRun(command.Command): ansible_cfg = os.path.join(ansible_dir, 'ansible.cfg') key_file = oooutils.get_key(parsed_args.stack) + limit_hosts = oooutils.playbook_limit_parse(parsed_args.limit) + excluded_hostnames = oooutils.get_excluded_hostnames( + oooutils.get_default_working_dir( + parsed_args.stack)) + + if any(excluded_hostname.strip() for excluded_hostname in + excluded_hostnames): + oooutils.compare_limit_nodes_with_excluded_hosts( + limit_nodes=limit_hosts, excluded_hosts=excluded_hostnames) + self.log.info("Excluded hostnames detected. Added" + " excluded_overcloud host group to --limit flag.") + limit_hosts += ':!excluded_overcloud' + oooutils.run_ansible_playbook( playbook=playbook, inventory=inventory, @@ -199,7 +215,9 @@ class UpdateRun(command.Command): tags=parsed_args.tags, ansible_cfg=ansible_cfg, ssh_user='tripleo-admin', - limit_hosts=parsed_args.limit, + limit_hosts=oooutils.playbook_limit_parse( + limit_nodes=limit_hosts + ), reproduce_command=True, forks=parsed_args.ansible_forks, extra_env_variables={