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
This commit is contained in:
Miguel Garcia 2023-02-20 11:07:12 +01:00
parent d027aa968a
commit 4d8fe985e0
5 changed files with 21 additions and 18 deletions

View File

@ -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

View File

@ -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
)

View File

@ -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):

View File

@ -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
)

View File

@ -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(