Allow list of filters for the setup module (#68551)

The setup module can now filter out multiple pattern by providing a list
to the filter parameter instead of just a string. Single string sill
works. Previous behaviour remains.

(cherry picked from commit b5c36dac483fdd74d6c570d77cc8f3e396720366)
This commit is contained in:
Jérôme Loyet 2020-09-09 20:40:48 +02:00 committed by GitHub
parent b430f9b9aa
commit daca3ade99
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 45 additions and 7 deletions

View file

@ -0,0 +1,2 @@
minor_changes:
- setup - allow list of filters (https://github.com/ansible/ansible/pull/68551).

View file

@ -61,6 +61,7 @@ Noteworthy module changes
* facts - On NetBSD, ``ansible_virtualization_type`` now tries to report a more accurate result than ``xen`` when virtualized and not running on Xen.
* facts - Virtualization facts now include ``virtualization_tech_guest`` and ``virtualization_tech_host`` keys. These are lists of virtualization technologies that a guest is a part of, or that a host provides, respectively. As an example, a host may be set up to provide both KVM and VirtualBox, and these will be included in ``virtualization_tech_host``, and a podman container running on a VM powered by KVM will have a ``virtualization_tech_guest`` of ``["kvm", "podman", "container"]``.
* The parameter ``filter`` type is changed from ``string`` to ``list`` in the :ref:`setup <setup_module>` module in order to use more than one filter. Previous behaviour (using a ``string``) still remains and works as a single filter.
Plugins

View file

@ -34,6 +34,7 @@ import sys
from ansible.module_utils.facts import timeout
from ansible.module_utils.facts import collector
from ansible.module_utils.common.collections import is_string
class AnsibleFactCollector(collector.BaseFactCollector):
@ -53,11 +54,14 @@ class AnsibleFactCollector(collector.BaseFactCollector):
self.filter_spec = filter_spec
def _filter(self, facts_dict, filter_spec):
# assume a filter_spec='' is equilv to filter_spec='*'
# assume filter_spec='' or filter_spec=[] is equivalent to filter_spec='*'
if not filter_spec or filter_spec == '*':
return facts_dict
return [(x, y) for x, y in facts_dict.items() if fnmatch.fnmatch(x, filter_spec)]
if is_string(filter_spec):
filter_spec = [filter_spec]
return [(x, y) for x, y in facts_dict.items() for f in filter_spec if not f or fnmatch.fnmatch(x, f)]
def collect(self, module=None, collected_facts=None):
collected_facts = collected_facts or {}
@ -111,7 +115,7 @@ def get_ansible_collector(all_collector_classes,
gather_timeout=None,
minimal_gather_subset=None):
filter_spec = filter_spec or '*'
filter_spec = filter_spec or []
gather_subset = gather_subset or ['all']
gather_timeout = gather_timeout or timeout.DEFAULT_GATHER_TIMEOUT
minimal_gather_subset = minimal_gather_subset or frozenset()

View file

@ -39,9 +39,16 @@ options:
filter:
version_added: "1.1"
description:
- If supplied, only return facts that match this shell-style (fnmatch) wildcard.
- If supplied, only return facts that match one of the shell-style
(fnmatch) pattern. An empty list basically means 'no filter'.
As of Ansible 2.11, the type has changed from string to list
and the default has became an empty list. A simple string is
still accepted and works as a single pattern. The behaviour
prior to Ansible 2.11 remains.
required: false
default: "*"
type: list
elements: str
default: []
fact_path:
version_added: "1.3"
description:
@ -105,6 +112,13 @@ EXAMPLES = """
- '!any'
- facter
- name: Collect only selected facts
setup:
filter:
- 'ansible_distribution'
- 'ansible_machine_id'
- 'ansible_*_mb'
# Display only facts about certain interfaces.
# ansible all -m setup -a 'filter=ansible_eth[0-2]'
@ -141,7 +155,7 @@ def main():
argument_spec=dict(
gather_subset=dict(default=["all"], required=False, type='list'),
gather_timeout=dict(default=10, required=False, type='int'),
filter=dict(default="*", required=False),
filter=dict(default=[], required=False, type='list', elements='str'),
fact_path=dict(default='/etc/ansible/facts.d', required=False, type='path'),
),
supports_check_mode=True,

View file

@ -122,6 +122,24 @@
- 'ansible_virtualization_role|default("UNDEF_VIRT") == "UNDEF_VIRT"'
- 'ansible_env|default("UNDEF_ENV") != "UNDEF_ENV"'
- hosts: facthost24
tags: [ 'fact_min' ]
connection: local
gather_facts: no
tasks:
- setup:
filter:
- "*env*"
- "*virt*"
- name: Test that retrieving all facts filtered to env and virt works
assert:
that:
- 'ansible_interfaces|default("UNDEF_NET") == "UNDEF_NET"'
- 'ansible_mounts|default("UNDEF_MOUNT") == "UNDEF_MOUNT"'
- 'ansible_virtualization_role|default("UNDEF_VIRT") != "UNDEF_VIRT"'
- 'ansible_env|default("UNDEF_ENV") != "UNDEF_ENV"'
- hosts: facthost13
tags: [ 'fact_min' ]
connection: local

View file

@ -147,7 +147,6 @@ lib/ansible/modules/iptables.py pylint:blacklisted-name
lib/ansible/modules/iptables.py validate-modules:parameter-list-no-elements
lib/ansible/modules/service.py validate-modules:nonexistent-parameter-documented
lib/ansible/modules/service.py validate-modules:use-run-command-not-popen
lib/ansible/modules/setup.py validate-modules:doc-missing-type
lib/ansible/modules/setup.py validate-modules:parameter-list-no-elements
lib/ansible/modules/setup.py validate-modules:parameter-type-not-in-doc
lib/ansible/modules/systemd.py validate-modules:parameter-invalid