ansible-config: ensure we get templated default (#82974)

AKA all defaults rendered
This commit is contained in:
Brian Coca 2024-04-09 14:57:26 -04:00 committed by GitHub
parent bb138b1f6e
commit 46137127a2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 23 additions and 14 deletions

View File

@ -0,0 +1,2 @@
bugfixes:
- ansible-config will now properly template defaults before dumping them.

View File

@ -269,7 +269,7 @@ class ConfigCLI(CLI):
if not settings[setting].get('description'):
continue
default = settings[setting].get('default', '')
default = self.config.template_default(settings[setting].get('default', ''), get_constants())
if subkey == 'env':
stype = settings[setting].get('type', '')
if stype == 'boolean':
@ -351,7 +351,7 @@ class ConfigCLI(CLI):
if entry['key'] not in seen[entry['section']]:
seen[entry['section']].append(entry['key'])
default = opt.get('default', '')
default = self.config.template_default(opt.get('default', ''), get_constants())
if opt.get('type', '') == 'list' and not isinstance(default, string_types):
# python lists are not valid ini ones
default = ', '.join(default)
@ -413,14 +413,16 @@ class ConfigCLI(CLI):
if context.CLIARGS['format'] == 'display':
if isinstance(config[setting], Setting):
# proceed normally
value = config[setting].value
if config[setting].origin == 'default':
color = 'green'
value = self.config.template_default(value, get_constants())
elif config[setting].origin == 'REQUIRED':
# should include '_terms', '_input', etc
color = 'red'
else:
color = 'yellow'
msg = "%s(%s) = %s" % (setting, config[setting].origin, config[setting].value)
msg = "%s(%s) = %s" % (setting, config[setting].origin, value)
else:
color = 'green'
msg = "%s(%s) = %s" % (setting, 'default', config[setting].get('default'))

View File

@ -302,6 +302,17 @@ class ConfigManager(object):
# ensure we always have config def entry
self._base_defs['CONFIG_FILE'] = {'default': None, 'type': 'path'}
def template_default(self, value, variables):
if isinstance(value, string_types) and (value.startswith('{{') and value.endswith('}}')) and variables is not None:
# template default values if possible
# NOTE: cannot use is_template due to circular dep
try:
t = NativeEnvironment().from_string(value)
value = t.render(variables)
except Exception:
pass # not templatable
return value
def _read_config_yaml_file(self, yml_file):
# TODO: handle relative paths as relative to the directory containing the current playbook instead of CWD
# Currently this is only used with absolute paths to the `ansible/config` directory
@ -555,18 +566,9 @@ class ConfigManager(object):
to_native(_get_entry(plugin_type, plugin_name, config)))
else:
origin = 'default'
value = defs[config].get('default')
if isinstance(value, string_types) and (value.startswith('{{') and value.endswith('}}')) and variables is not None:
# template default values if possible
# NOTE: cannot use is_template due to circular dep
try:
t = NativeEnvironment().from_string(value)
value = t.render(variables)
except Exception:
pass # not templatable
# ensure correct type, can raise exceptions on mismatched types
value = self.template_default(defs[config].get('default'), variables)
try:
# ensure correct type, can raise exceptions on mismatched types
value = ensure_type(value, defs[config].get('type'), origin=origin, origin_ftype=origin_ftype)
except ValueError as e:
if origin.startswith('env:') and value == '':

View File

@ -40,3 +40,6 @@ do
ANSIBLE_LOOKUP_PLUGINS=./ ansible-config init types -t lookup -f "${format}" > "files/types.new.${format}"
diff -u "files/types.${format}" "files/types.new.${format}"
done
# ensure we don't show default templates, but templated defaults
[ "$(ansible-config init |grep '={{' -c )" -eq 0 ]