add a 'min' type for gather_subset to collect nothing (#27085)
previously gather_subset=['!all'] would still gather the min set of facts, and there was no way to collect no facts. The 'min' specifier in gather_subset is equilivent to exclude the minimal_gather_subset facts as well. gather_subset=['!all', '!min'] will collect no facts This also lets explicitly added gather_subsets override excludes. gather_subset=['pkg_mgr', '!all', '!min'] will collect only the pkg_mgr fact.
This commit is contained in:
parent
c85b36d220
commit
27a015f0ad
4 changed files with 172 additions and 36 deletions
|
@ -111,16 +111,31 @@ def get_collector_names(valid_subsets=None,
|
|||
additional_subsets = set()
|
||||
exclude_subsets = set()
|
||||
|
||||
for subset in gather_subset:
|
||||
subset_id = subset
|
||||
# total always starts with the min set, then
|
||||
# adds of the additions in gather_subset, then
|
||||
# excludes all of the excludes, then add any explicitly
|
||||
# requested subsets.
|
||||
gather_subset_with_min = ['min']
|
||||
gather_subset_with_min.extend(gather_subset)
|
||||
|
||||
# subsets we mention in gather_subset explicitly, except for 'all'/'min'
|
||||
explicitly_added = set()
|
||||
|
||||
for subset in gather_subset_with_min:
|
||||
subset_id = subset
|
||||
if subset_id == 'min':
|
||||
additional_subsets.update(minimal_gather_subset)
|
||||
continue
|
||||
if subset_id == 'all':
|
||||
additional_subsets.update(valid_subsets)
|
||||
continue
|
||||
if subset_id.startswith('!'):
|
||||
subset = subset[1:]
|
||||
if subset == 'min':
|
||||
exclude_subsets.update(minimal_gather_subset)
|
||||
continue
|
||||
if subset == 'all':
|
||||
exclude_subsets.update(valid_subsets)
|
||||
exclude_subsets.update(valid_subsets - minimal_gather_subset)
|
||||
continue
|
||||
exclude = True
|
||||
else:
|
||||
|
@ -137,14 +152,13 @@ def get_collector_names(valid_subsets=None,
|
|||
raise TypeError("Bad subset '%s' given to Ansible. gather_subset options allowed: all, %s" %
|
||||
(subset, ", ".join(sorted(valid_subsets))))
|
||||
|
||||
explicitly_added.add(subset)
|
||||
additional_subsets.add(subset)
|
||||
|
||||
if not additional_subsets:
|
||||
additional_subsets.update(valid_subsets)
|
||||
|
||||
additional_subsets.difference_update(exclude_subsets)
|
||||
|
||||
additional_subsets.update(minimal_gather_subset)
|
||||
additional_subsets.difference_update(exclude_subsets - explicitly_added)
|
||||
|
||||
return additional_subsets
|
||||
|
||||
|
|
|
@ -23,13 +23,16 @@ options:
|
|||
version_added: "2.1"
|
||||
description:
|
||||
- "if supplied, restrict the additional facts collected to the given subset.
|
||||
Possible values: all, hardware, network, virtual, ohai, and
|
||||
Possible values: all, min, hardware, network, virtual, ohai, and
|
||||
facter Can specify a list of values to specify a larger subset.
|
||||
Values can also be used with an initial C(!) to specify that
|
||||
that specific subset should not be collected. For instance:
|
||||
!hardware, !network, !virtual, !ohai, !facter. Note that a few
|
||||
facts are always collected. Use the filter parameter if you do
|
||||
not want to display those."
|
||||
!hardware, !network, !virtual, !ohai, !facter. If !all is specified
|
||||
then only the min subset is collected. To avoid collecting even the
|
||||
min subset, specify !all and !min subsets. To collect only specific facts,
|
||||
use !all, !min, and specify the particular fact subsets.
|
||||
Use the filter parameter if you do not want to display some collected
|
||||
facts."
|
||||
required: false
|
||||
default: 'all'
|
||||
gather_timeout:
|
||||
|
@ -93,18 +96,27 @@ EXAMPLES = """
|
|||
# Display only facts returned by facter.
|
||||
# ansible all -m setup -a 'filter=facter_*'
|
||||
|
||||
# Collect only facts returned by facter.
|
||||
# ansible all -m setup -a 'gather_subset=!all,!any,facter'
|
||||
|
||||
# Display only facts about certain interfaces.
|
||||
# ansible all -m setup -a 'filter=ansible_eth[0-2]'
|
||||
|
||||
# Restrict additional gathered facts to network and virtual.
|
||||
# Restrict additional gathered facts to network and virtual (includes default minimum facts)
|
||||
# ansible all -m setup -a 'gather_subset=network,virtual'
|
||||
|
||||
# Collect only network and virtual (excludes default minimum facts)
|
||||
# ansible all -m setup -a 'gather_subset=!all,!any,network,virtual'
|
||||
|
||||
# Do not call puppet facter or ohai even if present.
|
||||
# ansible all -m setup -a 'gather_subset=!facter,!ohai'
|
||||
|
||||
# Only collect the minimum amount of facts:
|
||||
# Only collect the default minimum amount of facts:
|
||||
# ansible all -m setup -a 'gather_subset=!all'
|
||||
|
||||
# Collect no facts, even the default minimum subset of facts:
|
||||
# ansible all -m setup -a 'gather_subset=!all,!min'
|
||||
|
||||
# Display facts from Windows hosts with custom facts stored in C(C:\\custom_facts).
|
||||
# ansible windows -m setup -a "fact_path='c:\\custom_facts'"
|
||||
"""
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
---
|
||||
|
||||
- hosts: facthost7
|
||||
tags: [ 'fact_negation' ]
|
||||
connection: local
|
||||
|
@ -12,9 +11,6 @@
|
|||
- "!hardware"
|
||||
register: not_hardware_facts
|
||||
|
||||
- name: debug setup with not hardware
|
||||
debug:
|
||||
var: not_hardware_facts
|
||||
|
||||
- hosts: facthost0
|
||||
tags: [ 'fact_min' ]
|
||||
|
@ -67,6 +63,7 @@
|
|||
- 'ansible_mounts|default("UNDEF_MOUNT") == "UNDEF_MOUNT"'
|
||||
- 'ansible_virtualization_role|default("UNDEF_VIRT") == "UNDEF_VIRT"'
|
||||
- 'ansible_env|default("UNDEF_ENV") == "UNDEF_ENV"'
|
||||
- 'ansible_pkg_mgr|default("UNDEF_PKG_MGR") == "UNDEF_PKG_MGR"'
|
||||
|
||||
- hosts: facthost11
|
||||
tags: [ 'fact_min' ]
|
||||
|
@ -111,7 +108,10 @@
|
|||
- name: Test that only retrieving minimal facts work
|
||||
assert:
|
||||
that:
|
||||
# from the min set, which should still collect
|
||||
- 'ansible_user_id|default("UNDEF_MIN") != "UNDEF_MIN"'
|
||||
- 'ansible_env|default("UNDEF_ENV") != "UNDEF_ENV"'
|
||||
# non min facts that are not collected
|
||||
- 'ansible_interfaces|default("UNDEF_NET") == "UNDEF_NET"'
|
||||
- 'ansible_mounts|default("UNDEF_HW") == "UNDEF_HW"'
|
||||
- 'ansible_virtualization_role|default("UNDEF_VIRT") == "UNDEF_VIRT"'
|
||||
|
@ -198,10 +198,16 @@
|
|||
- name: Test that negation of fact subsets work
|
||||
assert:
|
||||
that:
|
||||
# network, not collected since it is not in min
|
||||
- 'ansible_interfaces|default("UNDEF_NET") == "UNDEF_NET"'
|
||||
# not collecting virt, should be undef
|
||||
- 'ansible_virtualization_role|default("UNDEF_VIRT") == "UNDEF_VIRT"'
|
||||
# mounts/devices are collected by hardware, so should be not collected and undef
|
||||
- 'ansible_mounts|default("UNDEF_MOUNTS") == "UNDEF_MOUNTS"'
|
||||
- 'ansible_devices|default("UNDEF_DEVICES") == "UNDEF_DEVICES"'
|
||||
# from the min set, which should still collect
|
||||
- 'ansible_user_id|default("UNDEF_MIN") != "UNDEF_MIN"'
|
||||
- 'ansible_interfaces|default("UNDEF_NET") != "UNDEF_NET"'
|
||||
- 'ansible_mounts|default("UNDEF_HW") == "UNDEF_HW"'
|
||||
- 'ansible_virtualization_role|default("UNDEF_VIRT") != "UNDEF_VIRT"'
|
||||
- 'ansible_env|default("UNDEF_ENV") != "UNDEF_ENV"'
|
||||
|
||||
- hosts: facthost8
|
||||
tags: [ 'fact_mixed_negation_addition' ]
|
||||
|
@ -217,6 +223,46 @@
|
|||
- 'ansible_mounts|default("UNDEF_HW") == "UNDEF_HW"'
|
||||
- 'ansible_virtualization_role|default("UNDEF_VIRT") == "UNDEF_VIRT"'
|
||||
|
||||
- hosts: facthost14
|
||||
tags: [ 'fact_mixed_negation_addition_min' ]
|
||||
connection: local
|
||||
gather_subset: "!all,!min,network"
|
||||
gather_facts: yes
|
||||
tasks:
|
||||
- name: Test that negation and additional subsets work together for min subset
|
||||
assert:
|
||||
that:
|
||||
- 'ansible_user_id|default("UNDEF_MIN") == "UNDEF_MIN"'
|
||||
- 'ansible_interfaces|default("UNDEF_NET") != "UNDEF_NET"'
|
||||
- 'ansible_default_ipv4|default("UNDEF_DEFAULT_IPV4") != "UNDEF_DEFAULT_IPV4"'
|
||||
- 'ansible_all_ipv4_addresses|default("UNDEF_ALL_IPV4") != "UNDEF_ALL_IPV4"'
|
||||
- 'ansible_mounts|default("UNDEF_HW") == "UNDEF_HW"'
|
||||
- 'ansible_virtualization_role|default("UNDEF_VIRT") == "UNDEF_VIRT"'
|
||||
- 'ansible_env|default("UNDEF_ENV") == "UNDEF_ENV"'
|
||||
|
||||
- hosts: facthost15
|
||||
tags: [ 'fact_negate_all_min_add_pkg_mgr' ]
|
||||
connection: local
|
||||
gather_subset: "!all,!min,pkg_mgr"
|
||||
gather_facts: yes
|
||||
tasks:
|
||||
- name: Test that negation and additional subsets work together for min subset
|
||||
assert:
|
||||
that:
|
||||
# network, not collected since it is not in min
|
||||
- 'ansible_interfaces|default("UNDEF_NET") == "UNDEF_NET"'
|
||||
# not collecting virt, should be undef
|
||||
- 'ansible_virtualization_role|default("UNDEF_VIRT") == "UNDEF_VIRT"'
|
||||
# mounts/devices are collected by hardware, so should be not collected and undef
|
||||
- 'ansible_mounts|default("UNDEF_MOUNTS") == "UNDEF_MOUNTS"'
|
||||
- 'ansible_devices|default("UNDEF_DEVICES") == "UNDEF_DEVICES"'
|
||||
# from the min set, which should not collect
|
||||
- 'ansible_user_id|default("UNDEF_MIN") == "UNDEF_MIN"'
|
||||
- 'ansible_env|default("UNDEF_ENV") == "UNDEF_ENV"'
|
||||
# the pkg_mgr fact we requested explicitly
|
||||
- 'ansible_pkg_mgr|default("UNDEF_PKG_MGR") != "UNDEF_PKGMGR"'
|
||||
|
||||
|
||||
- hosts: facthost9
|
||||
tags: [ 'fact_local']
|
||||
connection: local
|
||||
|
|
|
@ -37,14 +37,14 @@ class TestGetCollectorNames(unittest.TestCase):
|
|||
def test_empty_sets(self):
|
||||
res = collector.get_collector_names(valid_subsets=frozenset([]),
|
||||
minimal_gather_subset=frozenset([]),
|
||||
gather_subset=set([]))
|
||||
gather_subset=[])
|
||||
self.assertIsInstance(res, set)
|
||||
self.assertEqual(res, set([]))
|
||||
|
||||
def test_empty_valid_and_min_with_all_gather_subset(self):
|
||||
res = collector.get_collector_names(valid_subsets=frozenset([]),
|
||||
minimal_gather_subset=frozenset([]),
|
||||
gather_subset=set(['all']))
|
||||
gather_subset=['all'])
|
||||
self.assertIsInstance(res, set)
|
||||
self.assertEqual(res, set([]))
|
||||
|
||||
|
@ -52,10 +52,48 @@ class TestGetCollectorNames(unittest.TestCase):
|
|||
valid_subsets = frozenset(['my_fact'])
|
||||
res = collector.get_collector_names(valid_subsets=valid_subsets,
|
||||
minimal_gather_subset=frozenset([]),
|
||||
gather_subset=set(['all']))
|
||||
gather_subset=['all'])
|
||||
self.assertIsInstance(res, set)
|
||||
self.assertEqual(res, set(['my_fact']))
|
||||
|
||||
def _compare_res(self, gather_subset1, gather_subset2,
|
||||
valid_subsets=None, min_subset=None):
|
||||
|
||||
valid_subsets = valid_subsets or frozenset()
|
||||
minimal_gather_subset = min_subset or frozenset()
|
||||
|
||||
res1 = collector.get_collector_names(valid_subsets=valid_subsets,
|
||||
minimal_gather_subset=minimal_gather_subset,
|
||||
gather_subset=gather_subset1)
|
||||
|
||||
res2 = collector.get_collector_names(valid_subsets=valid_subsets,
|
||||
minimal_gather_subset=minimal_gather_subset,
|
||||
gather_subset=gather_subset2)
|
||||
|
||||
return res1, res2
|
||||
|
||||
def test_not_all_other_order(self):
|
||||
valid_subsets = frozenset(['min_fact', 'something_else', 'whatever'])
|
||||
minimal_gather_subset = frozenset(['min_fact'])
|
||||
|
||||
res1, res2 = self._compare_res(['!all', 'whatever'],
|
||||
['whatever', '!all'],
|
||||
valid_subsets=valid_subsets,
|
||||
min_subset=minimal_gather_subset)
|
||||
self.assertEqual(res1, res2)
|
||||
self.assertEqual(res1, set(['min_fact', 'whatever']))
|
||||
|
||||
def test_not_all_other_order_min(self):
|
||||
valid_subsets = frozenset(['min_fact', 'something_else', 'whatever'])
|
||||
minimal_gather_subset = frozenset(['min_fact'])
|
||||
|
||||
res1, res2 = self._compare_res(['!min_fact', 'whatever'],
|
||||
['whatever', '!min_fact'],
|
||||
valid_subsets=valid_subsets,
|
||||
min_subset=minimal_gather_subset)
|
||||
self.assertEqual(res1, res2)
|
||||
self.assertEqual(res1, set(['whatever']))
|
||||
|
||||
def test_one_minimal_with_all_gather_subset(self):
|
||||
my_fact = 'my_fact'
|
||||
valid_subsets = frozenset([my_fact])
|
||||
|
@ -63,7 +101,7 @@ class TestGetCollectorNames(unittest.TestCase):
|
|||
|
||||
res = collector.get_collector_names(valid_subsets=valid_subsets,
|
||||
minimal_gather_subset=minimal_gather_subset,
|
||||
gather_subset=set(['all']))
|
||||
gather_subset=['all'])
|
||||
self.assertIsInstance(res, set)
|
||||
self.assertEqual(res, set(['my_fact']))
|
||||
|
||||
|
@ -74,7 +112,7 @@ class TestGetCollectorNames(unittest.TestCase):
|
|||
# even with '!all', the minimal_gather_subset should be returned
|
||||
res = collector.get_collector_names(valid_subsets=valid_subsets,
|
||||
minimal_gather_subset=minimal_gather_subset,
|
||||
gather_subset=set(['all']))
|
||||
gather_subset=['all'])
|
||||
self.assertIsInstance(res, set)
|
||||
self.assertEqual(res, set(['my_fact', 'something_else', 'whatever']))
|
||||
|
||||
|
@ -85,21 +123,23 @@ class TestGetCollectorNames(unittest.TestCase):
|
|||
# even with '!all', the minimal_gather_subset should be returned
|
||||
res = collector.get_collector_names(valid_subsets=valid_subsets,
|
||||
minimal_gather_subset=minimal_gather_subset,
|
||||
gather_subset=set(['!all']))
|
||||
gather_subset=['!all'])
|
||||
self.assertIsInstance(res, set)
|
||||
self.assertEqual(res, set(['my_fact']))
|
||||
|
||||
def test_gather_subset_excludes(self):
|
||||
valid_subsets = frozenset(['my_fact', 'something_else', 'whatever'])
|
||||
minimal_gather_subset = frozenset(['my_fact'])
|
||||
minimal_gather_subset = frozenset(['min_fact', 'min_another'])
|
||||
|
||||
# even with '!all', the minimal_gather_subset should be returned
|
||||
res = collector.get_collector_names(valid_subsets=valid_subsets,
|
||||
minimal_gather_subset=minimal_gather_subset,
|
||||
gather_subset=set(['all', '!my_fact', '!whatever']))
|
||||
# gather_subset=set(['all', '!my_fact', '!whatever']))
|
||||
# gather_subset=['all', '!my_fact', '!whatever'])
|
||||
gather_subset=['!min_fact', '!whatever'])
|
||||
self.assertIsInstance(res, set)
|
||||
# my_facts is in minimal_gather_subset, so always returned
|
||||
self.assertEqual(res, set(['my_fact', 'something_else']))
|
||||
# min_another is in minimal_gather_subset, so always returned
|
||||
self.assertEqual(res, set(['min_another']))
|
||||
|
||||
def test_gather_subset_excludes_ordering(self):
|
||||
valid_subsets = frozenset(['my_fact', 'something_else', 'whatever'])
|
||||
|
@ -107,11 +147,35 @@ class TestGetCollectorNames(unittest.TestCase):
|
|||
|
||||
res = collector.get_collector_names(valid_subsets=valid_subsets,
|
||||
minimal_gather_subset=minimal_gather_subset,
|
||||
gather_subset=set(['!all', 'whatever']))
|
||||
gather_subset=['!all', 'whatever'])
|
||||
self.assertIsInstance(res, set)
|
||||
# excludes are higher precedence than includes, so !all excludes everything
|
||||
# and then minimal_gather_subset is added. so '!all', 'other' == '!all'
|
||||
self.assertEqual(res, set(['my_fact']))
|
||||
self.assertEqual(res, set(['my_fact', 'whatever']))
|
||||
|
||||
def test_gather_subset_excludes_min(self):
|
||||
valid_subsets = frozenset(['min_fact', 'something_else', 'whatever'])
|
||||
minimal_gather_subset = frozenset(['min_fact'])
|
||||
|
||||
res = collector.get_collector_names(valid_subsets=valid_subsets,
|
||||
minimal_gather_subset=minimal_gather_subset,
|
||||
gather_subset=['whatever', '!min'])
|
||||
self.assertIsInstance(res, set)
|
||||
# excludes are higher precedence than includes, so !all excludes everything
|
||||
# and then minimal_gather_subset is added. so '!all', 'other' == '!all'
|
||||
self.assertEqual(res, set(['whatever']))
|
||||
|
||||
def test_gather_subset_excludes_min_and_all(self):
|
||||
valid_subsets = frozenset(['min_fact', 'something_else', 'whatever'])
|
||||
minimal_gather_subset = frozenset(['min_fact'])
|
||||
|
||||
res = collector.get_collector_names(valid_subsets=valid_subsets,
|
||||
minimal_gather_subset=minimal_gather_subset,
|
||||
gather_subset=['whatever', '!all', '!min'])
|
||||
self.assertIsInstance(res, set)
|
||||
# excludes are higher precedence than includes, so !all excludes everything
|
||||
# and then minimal_gather_subset is added. so '!all', 'other' == '!all'
|
||||
self.assertEqual(res, set(['whatever']))
|
||||
|
||||
def test_invaid_gather_subset(self):
|
||||
valid_subsets = frozenset(['my_fact', 'something_else'])
|
||||
|
@ -122,7 +186,7 @@ class TestGetCollectorNames(unittest.TestCase):
|
|||
collector.get_collector_names,
|
||||
valid_subsets=valid_subsets,
|
||||
minimal_gather_subset=minimal_gather_subset,
|
||||
gather_subset=set(['my_fact', 'not_a_valid_gather_subset']))
|
||||
gather_subset=['my_fact', 'not_a_valid_gather_subset'])
|
||||
|
||||
|
||||
class TestCollectorClassesFromGatherSubset(unittest.TestCase):
|
||||
|
@ -145,13 +209,13 @@ class TestCollectorClassesFromGatherSubset(unittest.TestCase):
|
|||
|
||||
def test(self):
|
||||
res = self._classes(all_collector_classes=default_collectors.collectors,
|
||||
gather_subset=set(['!all']))
|
||||
gather_subset=['!all'])
|
||||
self.assertIsInstance(res, list)
|
||||
self.assertEqual(res, [])
|
||||
|
||||
def test_env(self):
|
||||
res = self._classes(all_collector_classes=default_collectors.collectors,
|
||||
gather_subset=set(['env']))
|
||||
gather_subset=['env'])
|
||||
self.assertIsInstance(res, list)
|
||||
self.assertEqual(res, [default_collectors.EnvFactCollector])
|
||||
|
||||
|
@ -181,7 +245,7 @@ class TestCollectorClassesFromGatherSubset(unittest.TestCase):
|
|||
|
||||
def test_collector_specified_multiple_times(self):
|
||||
res = self._classes(all_collector_classes=default_collectors.collectors,
|
||||
gather_subset=set(['platform', 'all', 'machine']))
|
||||
gather_subset=['platform', 'all', 'machine'])
|
||||
self.assertIsInstance(res, list)
|
||||
self.assertIn(default_collectors.PlatformFactCollector,
|
||||
res)
|
||||
|
@ -193,4 +257,4 @@ class TestCollectorClassesFromGatherSubset(unittest.TestCase):
|
|||
'Bad subset.*unknown_collector.*given to Ansible.*allowed\:.*all,.*env.*',
|
||||
self._classes,
|
||||
all_collector_classes=default_collectors.collectors,
|
||||
gather_subset=set(['env', 'unknown_collector']))
|
||||
gather_subset=['env', 'unknown_collector'])
|
||||
|
|
Loading…
Reference in a new issue