ansible-config: default to checking all plugin configs (#87212)

* ansible-config: default validate to checking all plugin configs

ansible-config validate defaulted to -t base, so any configuration file
using a section owned by a plugin (e.g. [ssh_connection]) was reported
as an unknown section, and keys inside such sections were never
validated at all - a stock, perfectly valid ansible.cfg failed
validation out of the box.

Default the validate action to -t all so installed plugin configuration
is taken into account. An explicit -t still narrows validation, and the
other ansible-config actions keep their base default (the -t default is
now resolved per action in post_process_args, since the shared parent
parser action object cannot carry per-subcommand defaults).

Fixes #86398

Signed-off-by: Apoorv Darshan <ad13dtu@gmail.com>

* Move -t to per-default shared parsers built by a factory

Per review: instead of a None sentinel resolved in post_process_args,
provide two small shared parent parsers for -t (one with default
'base', one with default 'all', built by a factory) so each
subcommand's --help states its actual default.

Signed-off-by: Apoorv Darshan <ad13dtu@gmail.com>

* Address review: parametrize ansible-config type tests

Deduplicate the three near-identical tests into a single
@pytest.mark.parametrize with descriptive IDs, return the resolved type
directly from the helper, add return-type annotations, and turn the
helper's leading comment into a docstring.

* Default ansible-config type to all for every action

Broaden the new default as requested in review, while keeping -t base as the compatibility override for users who need the previous behavior. Cover every action and both explicit override paths in the parser tests.

Assisted-by: OpenAI Codex
Signed-off-by: Apoorv Darshan <ad13dtu@gmail.com>

* Move ansible-config default coverage to integration tests

Exercise the public CLI across every action and run existing init, validate, and dump scenarios without an explicit type. Remove the parser-only unit test and use translation-friendly changelog wording.

Assisted-by: OpenAI Codex
Signed-off-by: Apoorv Darshan <ad13dtu@gmail.com>

* Document ansible-config default as breaking

Move the entry into the generated porting-guide section and document the -t base compatibility override.

Assisted-by: OpenAI Codex
Signed-off-by: Apoorv Darshan <ad13dtu@gmail.com>

---------

Signed-off-by: Apoorv Darshan <ad13dtu@gmail.com>
This commit is contained in:
Apoorv Darshan
2026-07-17 14:34:17 -04:00
committed by GitHub
parent b31b74b87f
commit 5149f7c640
3 changed files with 34 additions and 10 deletions
@@ -0,0 +1,6 @@
breaking_changes:
- >-
ansible-config - all actions now default to ``-t all``, so configuration files using sections
owned by plugins (for example, ``[ssh_connection]``) are no longer reported as unknown sections,
and keys within those sections are actually validated. Use ``-t base`` to retain the previous
behavior (https://github.com/ansible/ansible/issues/86398).
+4 -3
View File
@@ -103,8 +103,9 @@ class ConfigCLI(CLI):
opt_help.add_verbosity_options(common)
common.add_argument('-c', '--config', dest='config_file',
help="path to configuration file, defaults to first file found in precedence.")
common.add_argument("-t", "--type", action="store", default='base', dest='type', choices=['all', 'base'] + list(C.CONFIGURABLE_PLUGINS),
help="Filter down to a specific plugin type.")
common.add_argument("-t", "--type", action="store", default='all', dest='type',
choices=['all', 'base'] + list(C.CONFIGURABLE_PLUGINS),
help="Filter down to a specific plugin type. Defaults to 'all'; use 'base' for the previous behavior.")
common.add_argument('args', help='Specific plugin to target, requires type of plugin to be set', nargs='*')
subparsers = self.parser.add_subparsers(dest='action')
@@ -134,7 +135,7 @@ class ConfigCLI(CLI):
validate_parser = subparsers.add_parser('validate',
help='Validate the configuration file and environment variables. '
'By default it only checks the base settings without accounting for plugins (see -t).',
'By default it checks the base settings and all installed plugins (use -t to narrow down).',
parents=[common])
validate_parser.set_defaults(func=self.execute_validate)
validate_parser.add_argument('--format', '-f', dest='format', action='store', choices=['ini', 'env'] , default='ini',
@@ -1,3 +1,21 @@
- name: check the default type in help for every action
ansible.builtin.command: ansible-config {{ item }} --help
loop:
- list
- dump
- view
- init
- validate
register: config_help
changed_when: false
- name: ensure every action documents all as the default type
ansible.builtin.assert:
that:
- >-
item.stdout is regex("Defaults to\\s*'all'")
loop: '{{ config_help.results }}'
- name: test ansible-config init for valid output and no dupes
block:
- name: Create temporary file
@@ -7,17 +25,16 @@
suffix: temp.ini
register: ini_tempfile
- name: run config full dump
shell: ansible-config init -t all > {{ini_tempfile.path}}
- name: run config full dump using the default type
shell: ansible-config init > {{ini_tempfile.path}}
- name: run ini tester, for correctness and dupes
shell: "{{ansible_playbook_python}} '{{role_path}}/files/ini_dupes.py' '{{ini_tempfile.path}}'"
- name: test ansible-config validate
block:
# not testing w/o -t all as ansible-test uses it's own plugins and would give false positives
- name: validate config files
shell: ansible-config validate -t all -v
- name: validate config files using the default type
shell: ansible-config validate -v
register: valid_cfg
loop:
- empty.cfg
@@ -142,8 +159,8 @@
vars:
config_keys: "{{ config_dump['stdout'] | from_json | selectattr('name', 'defined') }}"
block:
- name: run config full dump
shell: ansible-config dump -t all -f json
- name: run config full dump using the default type
shell: ansible-config dump -f json
register: config_dump
- name: validate we get 'internal' but not hidden (_Z_)