From 4d8fe985e0992bc93c048507fd78075058146e07 Mon Sep 17 00:00:00 2001 From: Miguel Garcia Date: Mon, 20 Feb 2023 11:07:12 +0100 Subject: [PATCH] parse_ansible_inventory: use ansible_runner instead of importing Ansible All our interactions with Ansible are brokered by the ansible_runner module, except for this one function which imports the Ansible module proper. This leads for breakage when using the latest Ansible builds from EL9, which are on python3.11 instead of 3.9. By refactoring parse_ansible_inventory to use ansible_runner's get_inventory we avoid that breakage, but we also lose out on the pattern matching as that isn't supported. This function is called in two places: ceph_hosts_in_inventory: it didn't do any pattern matching at all, so it isn't impacted by the change. overcloud admin authorize: we can now offload the pattern matching to Ansible itself via the limit_hosts parameter we pass to the playbook run command, preserving the original functionality. Closes-Bug: #2007659 Change-Id: I08330ced3b31d0ff48a881501cae8bd726e36432 --- requirements.txt | 2 +- .../tests/v1/test_overcloud_admin.py | 1 + tripleoclient/utils.py | 22 +++++++++++-------- tripleoclient/v1/overcloud_admin.py | 11 +++++----- tripleoclient/v2/overcloud_ceph.py | 3 +-- 5 files changed, 21 insertions(+), 18 deletions(-) diff --git a/requirements.txt b/requirements.txt index c8f8d15b9..f04f3e4fc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,6 +11,6 @@ python-openstackclient>=5.2.0 # Apache-2.0 osc-lib>=2.3.0 # Apache-2.0 tripleo-common>=16.3.0 # Apache-2.0 cryptography>=2.1 # BSD/Apache-2.0 -ansible-runner>=1.4.5 # Apache 2.0 +ansible-runner>=2.0.0a2 # Apache 2.0 validations-libs>=1.5.0 # Apache-2.0 openstacksdk>=0.48.0 # Apache-2.0 diff --git a/tripleoclient/tests/v1/test_overcloud_admin.py b/tripleoclient/tests/v1/test_overcloud_admin.py index 75a399eb0..cc146a066 100644 --- a/tripleoclient/tests/v1/test_overcloud_admin.py +++ b/tripleoclient/tests/v1/test_overcloud_admin.py @@ -64,5 +64,6 @@ class TestAdminAuthorize(test_plugin.TestPluginV1): 'overcloud-dellcompute-0', 'overcloud-controller-0'] }, + limit_hosts='localhost,overcloud', ansible_timeout=parsed_args.overcloud_ssh_port_timeout ) diff --git a/tripleoclient/utils.py b/tripleoclient/utils.py index db35e414b..a8678889a 100644 --- a/tripleoclient/utils.py +++ b/tripleoclient/utils.py @@ -76,8 +76,6 @@ import warnings warnings.simplefilter("ignore", UserWarning) import ansible_runner # noqa -from ansible.parsing.dataloader import DataLoader # noqa -from ansible.inventory.manager import InventoryManager # noqa LOG = logging.getLogger(__name__ + ".utils") _local_orchestration_client = None @@ -3234,17 +3232,23 @@ def get_parameter_file(path): return file_data -def parse_ansible_inventory(inventory_file, group): +def parse_ansible_inventory(inventory_file): """ Retrieve a list of hosts from a defined ansible inventory file. - :param inventory: Ansible inventory file - :param group: The group to return hosts from, default will be 'all' - :return: list of hosts in the inventory matching the pattern + :param inventory_file: Ansible inventory file + :return: list of strings: names of hosts in the inventory """ - inventory = InventoryManager(loader=DataLoader(), - sources=[inventory_file]) + json_inv, err = ansible_runner.interface.get_inventory('list', + [inventory_file], + quiet=True) + if err: + msg = 'Error parsing inventory {}:\n{}'.format(inventory_file, err) + raise ansible_runner.exceptions.AnsibleRunnerException(msg) - return(inventory.get_hosts(pattern=group)) + inventory = json.loads(json_inv) + hosts = list(inventory['_meta']['hostvars'].keys()) + + return hosts def save_stack(stack, working_dir): diff --git a/tripleoclient/v1/overcloud_admin.py b/tripleoclient/v1/overcloud_admin.py index 5d44614bb..96bdeb2d8 100644 --- a/tripleoclient/v1/overcloud_admin.py +++ b/tripleoclient/v1/overcloud_admin.py @@ -115,13 +115,11 @@ class Authorize(command.Command): key_file = oooutils.get_key(parsed_args.stack) if not parsed_args.limit_hosts: - hosts = parsed_args.stack + limit_hosts = parsed_args.stack else: - hosts = parsed_args.limit_hosts + limit_hosts = parsed_args.limit_hosts - host_list = [str(h) for h in oooutils.parse_ansible_inventory( - inventory, hosts - )] + all_hosts = oooutils.parse_ansible_inventory(inventory) oooutils.run_ansible_playbook( playbook='cli-enable-ssh-admin.yaml', @@ -132,7 +130,8 @@ class Authorize(command.Command): ssh_user=parsed_args.overcloud_ssh_user, extra_vars={ "ANSIBLE_PRIVATE_KEY_FILE": key_file, - "ssh_servers": host_list + "ssh_servers": all_hosts }, + limit_hosts='localhost,{}'.format(limit_hosts), ansible_timeout=parsed_args.overcloud_ssh_port_timeout ) diff --git a/tripleoclient/v2/overcloud_ceph.py b/tripleoclient/v2/overcloud_ceph.py index 5749ae5c4..c6b8f6d04 100644 --- a/tripleoclient/v2/overcloud_ceph.py +++ b/tripleoclient/v2/overcloud_ceph.py @@ -60,8 +60,7 @@ def arg_parse_common(parser): def ceph_hosts_in_inventory(ceph_hosts, ceph_spec, inventory): """Raise command error if any ceph_hosts are not in the inventory """ - all_host_objs = oooutils.parse_ansible_inventory(inventory, 'all') - all_hosts = list(map(lambda x: str(x), all_host_objs)) + all_hosts = oooutils.parse_ansible_inventory(inventory) for ceph_host in ceph_hosts['_admin'] + ceph_hosts['non_admin']: if ceph_host not in all_hosts: raise oscexc.CommandError(