From 2a4b1c8248d7bf4cc81ecb2659282544841626b1 Mon Sep 17 00:00:00 2001 From: Abhijeet Kasurde Date: Tue, 1 Apr 2025 08:36:15 -0700 Subject: [PATCH] ansible-config: Dump galaxy server config in proper JSON format (#84912) Fixes: #84840 Signed-off-by: Abhijeet Kasurde --- changelogs/fragments/config_dump.yml | 3 ++ lib/ansible/cli/config.py | 41 +++++++++++++------ lib/ansible/config/manager.py | 3 -- .../targets/ansible-config/tasks/main.yml | 7 +--- 4 files changed, 33 insertions(+), 21 deletions(-) create mode 100644 changelogs/fragments/config_dump.yml diff --git a/changelogs/fragments/config_dump.yml b/changelogs/fragments/config_dump.yml new file mode 100644 index 00000000000..bcd5e7e7ad6 --- /dev/null +++ b/changelogs/fragments/config_dump.yml @@ -0,0 +1,3 @@ +--- +bugfixes: + - ansible-config - format galaxy server configs while dumping in JSON format (https://github.com/ansible/ansible/issues/84840). diff --git a/lib/ansible/cli/config.py b/lib/ansible/cli/config.py index cd801212fca..a88beb7b1ea 100755 --- a/lib/ansible/cli/config.py +++ b/lib/ansible/cli/config.py @@ -21,7 +21,7 @@ import ansible.plugins.loader as plugin_loader from ansible import constants as C from ansible.cli.arguments import option_helpers as opt_help -from ansible.config.manager import ConfigManager, Setting +from ansible.config.manager import ConfigManager from ansible.errors import AnsibleError, AnsibleOptionsError, AnsibleRequiredOptionError from ansible.module_utils.common.text.converters import to_native, to_text, to_bytes from ansible.module_utils.common.json import json_dump @@ -458,21 +458,21 @@ class ConfigCLI(CLI): entries = [] for setting in sorted(config): - changed = (config[setting].origin not in ('default', 'REQUIRED') and setting not in _IGNORE_CHANGED) + changed = (config[setting]['origin'] not in ('default', 'REQUIRED') and setting not in _IGNORE_CHANGED) if context.CLIARGS['format'] == 'display': - if isinstance(config[setting], Setting): + if isinstance(config[setting], dict): # proceed normally - value = config[setting].value - if config[setting].origin == 'default' or setting in _IGNORE_CHANGED: + value = config[setting]['value'] + if config[setting]['origin'] == 'default' or setting in _IGNORE_CHANGED: color = 'green' value = self.config.template_default(value, get_constants()) - elif config[setting].origin == 'REQUIRED': + elif config[setting]['origin'] == 'REQUIRED': # should include '_terms', '_input', etc color = 'red' else: color = 'yellow' - msg = "%s(%s) = %s" % (setting, config[setting].origin, value) + msg = "%s(%s) = %s" % (setting, config[setting]['origin'], value) else: color = 'green' msg = "%s(%s) = %s" % (setting, 'default', config[setting].get('default')) @@ -480,10 +480,10 @@ class ConfigCLI(CLI): entry = stringc(msg, color) else: entry = {} - for key in config[setting]._fields: + for key in config[setting].keys(): if key == 'type': continue - entry[key] = getattr(config[setting], key) + entry[key] = config[setting][key] if not context.CLIARGS['only_changed'] or changed: entries.append(entry) @@ -497,7 +497,12 @@ class ConfigCLI(CLI): # convert to settings for setting in config.keys(): v, o = C.config.get_config_value_and_origin(setting, cfile=self.config_file, variables=get_constants()) - config[setting] = Setting(setting, v, o, None) + config[setting] = { + 'name': setting, + 'value': v, + 'origin': o, + 'type': None + } return self._render_settings(config) @@ -554,7 +559,12 @@ class ConfigCLI(CLI): # not all cases will be error o = 'REQUIRED' - config_entries[finalname][setting] = Setting(setting, v, o, None) + config_entries[finalname][setting] = { + 'name': setting, + 'value': v, + 'origin': o, + 'type': None + } # pretty please! results = self._render_settings(config_entries[finalname]) @@ -587,7 +597,12 @@ class ConfigCLI(CLI): if v is None and o is None: # not all cases will be error o = 'REQUIRED' - server_config[setting] = Setting(setting, v, o, None) + server_config[setting] = { + 'name': setting, + 'value': v, + 'origin': o, + 'type': None + } if context.CLIARGS['format'] == 'display': if not context.CLIARGS['only_changed'] or server_config: equals = '=' * len(server) @@ -617,7 +632,7 @@ class ConfigCLI(CLI): for server_config in server_config_list: server = list(server_config.keys())[0] server_reduced_config = server_config.pop(server) - configs[server] = server_reduced_config + configs[server] = list(server_reduced_config.values()) output.append({'GALAXY_SERVERS': configs}) if context.CLIARGS['type'] == 'all': diff --git a/lib/ansible/config/manager.py b/lib/ansible/config/manager.py index 4838ed59441..52bd6547b33 100644 --- a/lib/ansible/config/manager.py +++ b/lib/ansible/config/manager.py @@ -12,7 +12,6 @@ import sys import stat import tempfile -from collections import namedtuple from collections.abc import Mapping, Sequence from jinja2.nativetypes import NativeEnvironment @@ -27,8 +26,6 @@ from ansible.parsing.yaml.objects import AnsibleVaultEncryptedUnicode from ansible.utils.path import cleanup_tmp_file, makedirs_safe, unfrackpath -Setting = namedtuple('Setting', 'name value origin type') - INTERNAL_DEFS = {'lookup': ('_terms',)} GALAXY_SERVER_DEF = [ diff --git a/test/integration/targets/ansible-config/tasks/main.yml b/test/integration/targets/ansible-config/tasks/main.yml index f9f50412ed1..88f29818590 100644 --- a/test/integration/targets/ansible-config/tasks/main.yml +++ b/test/integration/targets/ansible-config/tasks/main.yml @@ -86,9 +86,6 @@ - all register: galaxy_server_dump - #- debug: msg='{{ (galaxy_server_dump.results[0].stdout | from_json) }}' - #- debug: msg='{{ (galaxy_server_dump.results[1].stdout | from_json) }}' - - name: extract galaxy servers from config dump set_fact: galaxy_server_dump_base: '{{ (galaxy_server_dump.results[0].stdout | from_json | select("contains", "GALAXY_SERVERS"))[0].get("GALAXY_SERVERS") }}' @@ -139,8 +136,8 @@ - name: Check individual settings assert: that: - - gs[item[0]][item[1]] == galaxy_server_dump_base[item[0]][item[1]][1] - - gs[item[0]][item[1]] == galaxy_server_dump_all[item[0]][item[1]][1] + - gs[item[0]][item[1]] == (galaxy_server_dump_base[item[0]] | selectattr('name', '==', item[1]))[0]['value'] + - gs[item[0]][item[1]] == (galaxy_server_dump_all[item[0]] | selectattr('name', '==', item[1]))[0]['value'] when: - item[1] in gs[item[0]] loop: '{{gs_keys | product(gs_all) }}'