mirror of
https://github.com/ansible/ansible.git
synced 2025-11-30 23:16:08 +07:00
Use json for test inventory - ci_complete (#86118)
* Use json for test inventory - ci_complete Uses the JSON/YAML format for the inventory files generated by `ansible-test`. This solves minor issues with using complex values when building the test inventory files like backslashes or more complex data structures. * Apply suggestions from code review Co-authored-by: Matt Clay <matt@mystile.com> * Add changelog and use more limited ext config var - ci_complete --------- Co-authored-by: Matt Clay <matt@mystile.com>
This commit is contained in:
4
changelogs/fragments/ansible-test-inventory-json.yml
Normal file
4
changelogs/fragments/ansible-test-inventory-json.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
minor_changes:
|
||||
- >-
|
||||
ansible-test - add ``.winrm`` and ``.networking`` as valid JSON/YAML inventory file extensions. This should not
|
||||
affect any public facing code as it is used internally for inventories generated by ``ansible-test``.
|
||||
@@ -93,6 +93,7 @@ def ansible_environment(args: CommonConfig, color: bool = True, ansible_config:
|
||||
|
||||
ansible = dict(
|
||||
ANSIBLE_PYTHON_MODULE_RLIMIT_NOFILE=str(SOFT_RLIMIT_NOFILE),
|
||||
ANSIBLE_INVENTORY_PLUGIN_EXTS='.yaml, .yml, .json, .winrm, .networking', # allows the yaml/json inventory format for windows and networking
|
||||
ANSIBLE_FORCE_COLOR='%s' % 'true' if args.color and color else 'false',
|
||||
ANSIBLE_FORCE_HANDLERS='true', # allow cleanup handlers to run when tests fail
|
||||
ANSIBLE_HOST_PATTERN_MISMATCH='error', # prevent tests from unintentionally passing when hosts are not found
|
||||
|
||||
@@ -202,31 +202,24 @@ class Inventory:
|
||||
def write(self, args: CommonConfig, path: str) -> None:
|
||||
"""Write the given inventory to the specified path on disk."""
|
||||
|
||||
# NOTE: Switching the inventory generation to write JSON would be nice, but is currently not possible due to the use of hard-coded inventory filenames.
|
||||
# The name `inventory` works for the POSIX integration tests, but `inventory.winrm` and `inventory.networking` will only parse in INI format.
|
||||
# If tests are updated to use the `INVENTORY_PATH` environment variable, then this could be changed.
|
||||
# Also, some tests detect the test type by inspecting the suffix on the inventory filename, which would break if it were changed.
|
||||
|
||||
inventory_text = ''
|
||||
inventory_data: dict[str, dict[str, dict[str, dict[str, object]]]] = dict()
|
||||
|
||||
for group, hosts in self.host_groups.items():
|
||||
inventory_text += f'[{group}]\n'
|
||||
group_data = inventory_data.setdefault(group, dict())
|
||||
hosts_data = group_data.setdefault('hosts', dict())
|
||||
|
||||
for host, variables in hosts.items():
|
||||
kvp = ' '.join(f"{key}={value!r}" for key, value in variables.items())
|
||||
inventory_text += f'{host} {kvp}\n'
|
||||
|
||||
inventory_text += '\n'
|
||||
host_entry = hosts_data.setdefault(host, dict())
|
||||
host_entry.update(variables)
|
||||
|
||||
for group, children in (self.extra_groups or {}).items():
|
||||
inventory_text += f'[{group}]\n'
|
||||
group_data = inventory_data.setdefault(group, dict())
|
||||
group_children = group_data.setdefault('children', dict())
|
||||
|
||||
for child in children:
|
||||
inventory_text += f'{child}\n'
|
||||
group_children[child] = dict()
|
||||
|
||||
inventory_text += '\n'
|
||||
|
||||
inventory_text = inventory_text.strip()
|
||||
inventory_text = json.dumps(inventory_data, indent=4)
|
||||
|
||||
if not args.explain:
|
||||
write_text_file(path, inventory_text + '\n')
|
||||
@@ -1380,7 +1373,7 @@ class NetworkRemoteProfile(RemoteProfile[NetworkRemoteConfig]):
|
||||
env = ansible_environment(self.args)
|
||||
module_name = f'{self.config.collection + "." if self.config.collection else ""}{self.config.platform}_command'
|
||||
|
||||
with tempfile.NamedTemporaryFile() as inventory_file:
|
||||
with tempfile.NamedTemporaryFile(suffix='.json') as inventory_file:
|
||||
inventory.write(self.args, inventory_file.name)
|
||||
|
||||
cmd = ['ansible', '-m', module_name, '-a', 'commands=?', '-i', inventory_file.name, 'all']
|
||||
@@ -1636,7 +1629,7 @@ class WindowsRemoteProfile(RemoteProfile[WindowsRemoteConfig]):
|
||||
env = ansible_environment(self.args)
|
||||
module_name = 'ansible.windows.win_ping'
|
||||
|
||||
with tempfile.NamedTemporaryFile() as inventory_file:
|
||||
with tempfile.NamedTemporaryFile(suffix='.json') as inventory_file:
|
||||
inventory.write(self.args, inventory_file.name)
|
||||
|
||||
cmd = ['ansible', '-m', module_name, '-i', inventory_file.name, 'all']
|
||||
|
||||
@@ -109,9 +109,7 @@ def create_windows_inventory(args: EnvironmentConfig, path: str, target_hosts: l
|
||||
# The `testhost` group is needed to support the `binary_modules_winrm` integration test.
|
||||
# The test should be updated to remove the need for this.
|
||||
extra_groups={
|
||||
'testhost:children': [
|
||||
'windows',
|
||||
],
|
||||
'testhost': ['windows'],
|
||||
},
|
||||
)
|
||||
|
||||
@@ -145,7 +143,7 @@ def create_network_inventory(args: EnvironmentConfig, path: str, target_hosts: l
|
||||
# see: https://github.com/ansible/ansible/pull/34661
|
||||
# see: https://github.com/ansible/ansible/pull/34707
|
||||
extra_groups={
|
||||
'net:children': sorted(host_groups),
|
||||
'net': list(sorted(host_groups)),
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user