mirror of
https://github.com/ansible/ansible.git
synced 2026-08-02 00:22:14 +02: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:
co-authored by
Matt Clay
parent
3c5bb535a9
commit
829373bfb9
@@ -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 = dict(
|
||||||
ANSIBLE_PYTHON_MODULE_RLIMIT_NOFILE=str(SOFT_RLIMIT_NOFILE),
|
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_COLOR='%s' % 'true' if args.color and color else 'false',
|
||||||
ANSIBLE_FORCE_HANDLERS='true', # allow cleanup handlers to run when tests fail
|
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
|
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:
|
def write(self, args: CommonConfig, path: str) -> None:
|
||||||
"""Write the given inventory to the specified path on disk."""
|
"""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.
|
inventory_data: dict[str, dict[str, dict[str, dict[str, object]]]] = dict()
|
||||||
# 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 = ''
|
|
||||||
|
|
||||||
for group, hosts in self.host_groups.items():
|
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():
|
for host, variables in hosts.items():
|
||||||
kvp = ' '.join(f"{key}={value!r}" for key, value in variables.items())
|
host_entry = hosts_data.setdefault(host, dict())
|
||||||
inventory_text += f'{host} {kvp}\n'
|
host_entry.update(variables)
|
||||||
|
|
||||||
inventory_text += '\n'
|
|
||||||
|
|
||||||
for group, children in (self.extra_groups or {}).items():
|
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:
|
for child in children:
|
||||||
inventory_text += f'{child}\n'
|
group_children[child] = dict()
|
||||||
|
|
||||||
inventory_text += '\n'
|
inventory_text = json.dumps(inventory_data, indent=4)
|
||||||
|
|
||||||
inventory_text = inventory_text.strip()
|
|
||||||
|
|
||||||
if not args.explain:
|
if not args.explain:
|
||||||
write_text_file(path, inventory_text + '\n')
|
write_text_file(path, inventory_text + '\n')
|
||||||
@@ -1380,7 +1373,7 @@ class NetworkRemoteProfile(RemoteProfile[NetworkRemoteConfig]):
|
|||||||
env = ansible_environment(self.args)
|
env = ansible_environment(self.args)
|
||||||
module_name = f'{self.config.collection + "." if self.config.collection else ""}{self.config.platform}_command'
|
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)
|
inventory.write(self.args, inventory_file.name)
|
||||||
|
|
||||||
cmd = ['ansible', '-m', module_name, '-a', 'commands=?', '-i', inventory_file.name, 'all']
|
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)
|
env = ansible_environment(self.args)
|
||||||
module_name = 'ansible.windows.win_ping'
|
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)
|
inventory.write(self.args, inventory_file.name)
|
||||||
|
|
||||||
cmd = ['ansible', '-m', module_name, '-i', inventory_file.name, 'all']
|
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 `testhost` group is needed to support the `binary_modules_winrm` integration test.
|
||||||
# The test should be updated to remove the need for this.
|
# The test should be updated to remove the need for this.
|
||||||
extra_groups={
|
extra_groups={
|
||||||
'testhost:children': [
|
'testhost': ['windows'],
|
||||||
'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/34661
|
||||||
# see: https://github.com/ansible/ansible/pull/34707
|
# see: https://github.com/ansible/ansible/pull/34707
|
||||||
extra_groups={
|
extra_groups={
|
||||||
'net:children': sorted(host_groups),
|
'net': list(sorted(host_groups)),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user