Skip to content

Commit 860f1ff

Browse files
committed
facts generation that supports merging existing facts modules and introduces gather_network_resources
Signed-off-by: Trishna Guha <[email protected]>
1 parent a0ac42e commit 860f1ff

File tree

6 files changed

+119
-38
lines changed

6 files changed

+119
-38
lines changed

roles/resource_module/templates/module_directory/network_os/network_os_facts.py.j2

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,30 +33,49 @@ options:
3333
gather_subset:
3434
description:
3535
- When supplied, this argument will restrict the facts collected
36-
to a given subset. Possible values for this argument include
37-
all, and net_configuration_<resource_name>. Can specify a
38-
list of values to include a larger subset. Values can also be used
36+
to a given subset. Possible values for this argument include
37+
all, min, hardware, config, legacy, and interfaces. Can specify a
38+
list of values to include a larger subset. Values can also be used
3939
with an initial C(M(!)) to specify that a specific subset should
4040
not be collected.
4141
required: false
4242
default: 'all'
4343
version_added: "2.2"
44+
gather_network_resources:
45+
description:
46+
- When supplied, this argument will restrict the facts collected
47+
to a given subset. Possible values for this argument include
48+
all and the resources like interfaces, vlans etc.
49+
Can specify a list of values to include a larger subset. Values
50+
can also be used with an initial C(M(!)) to specify that a
51+
specific subset should not be collected.
52+
required: false
53+
version_added: "2.9"
4454
"""
4555

4656
EXAMPLES = """
4757
# Gather all facts
4858
- {{ network_os }}_facts:
4959
gather_subset: all
60+
gather_network_resources: all
5061
51-
# Collect only the {{ resource }} and default facts
62+
# Collect only the {{ resource }} facts
5263
- {{ network_os }}_facts:
5364
gather_subset:
54-
- net_configuration_{{ resource }}
65+
- !all
66+
- !min
67+
gather_network_resources:
68+
- {{ resource }}
5569
5670
# Do not collect {{ resource }} facts
5771
- {{ network_os }}_facts:
58-
gather_subset:
59-
- "!net_configuration_{{ resource }}"
72+
gather_network_resources:
73+
- "!{{ resource }}"
74+
75+
# Collect {{ resource }} and minimal default facts
76+
- {{ network_os }}_facts:
77+
gather_subset: min
78+
gather_network_resources: {{ resource }}
6079
"""
6180

6281
RETURN = """
@@ -71,11 +90,19 @@ def main():
7190
"""
7291
module = AnsibleModule(argument_spec=Facts.argument_spec,
7392
supports_check_mode=True)
74-
warnings = list()
93+
warnings = ['default value for `gather_subset` will be changed to `min` from `!config` v2.11 onwards']
7594

7695
connection = Connection(module._socket_path) #pylint: disable=W0212
7796
gather_subset = module.params['gather_subset']
78-
ansible_facts = Facts().get_facts(module, connection, gather_subset)
97+
gather_network_resources = module.params['gather_network_resources']
98+
result = Facts().get_facts(module, connection, gather_subset, gather_network_resources)
99+
100+
try:
101+
ansible_facts, warning = result
102+
warnings.extend(warning)
103+
except TypeError, KeyError:
104+
ansible_facts = result
105+
79106
module.exit_json(ansible_facts=ansible_facts, warnings=warnings)
80107

81108
if __name__ == '__main__':

roles/resource_module/templates/module_utils/network_os/argspec/facts/facts.py.j2

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@ class FactsArgs(object): #pylint: disable=R0903
1515

1616
choices = [
1717
'all',
18-
'net_configuration_{{ resource }}',
18+
'{{ resource }}',
1919
]
2020

2121
argument_spec = {
22-
'gather_subset': dict(default=['all'], choices=choices, type='list')
22+
'gather_subset': dict(default=['!config'], type='list'),
23+
'gather_network_resources': dict(default=['all'], choices=choices, type='list'),
2324
}

roles/resource_module/templates/module_utils/network_os/config/resource/resource.py.j2

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,12 @@ class {{ resource|capitalize }}(ConfigBase, {{ resource|capitalize }}Args):
2626
"""
2727

2828
gather_subset = [
29-
'net_configuration_{{ resource }}',
29+
'!all',
30+
'!min',
31+
]
32+
33+
gather_network_resources = [
34+
{{ resource }},
3035
]
3136

3237
def get_{{ resource }}_facts(self):
@@ -35,8 +40,12 @@ class {{ resource|capitalize }}(ConfigBase, {{ resource|capitalize }}Args):
3540
:rtype: A dictionary
3641
:returns: The current configuration as a dictionary
3742
"""
38-
facts = Facts().get_facts(self._module, self._connection, self.gather_subset)
39-
{{ resource }}_facts = facts['net_configuration'].get('{{ resource }}')
43+
result = Facts().get_facts(self._module, self._connection, self.gather_subset, self.gather_network_resources)
44+
try:
45+
facts = result[0]
46+
except TypeError, KeyError:
47+
facts = result
48+
{{ resource }}_facts = facts['ansible_network_resources'].get('{{ resource }}')
4049
if not {{ resource }}_facts:
4150
return []
4251
return {{ resource }}_facts

roles/resource_module/templates/module_utils/network_os/facts/base.py.j2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class FactsBase(object): #pylint: disable=R0205
1717
The {{ network_os }} facts base class
1818
"""
1919
generated_spec = {}
20-
ansible_facts = {'net_configuration': {}}
20+
ansible_facts = {'ansible_network_resources': {}}
2121

2222
def __init__(self, argspec, subspec=None, options=None):
2323
spec = deepcopy(argspec)

roles/resource_module/templates/module_utils/network_os/facts/facts.py.j2

Lines changed: 66 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ this file validates each subset of facts and selectively
88
calls the appropriate facts gathering function
99
"""
1010

11+
from ansible.module_utils.six import string_types, iteritems
1112
from {{ import_path }}. \
1213
{{ network_os }}.argspec.facts.facts import FactsArgs
1314
from {{ import_path }}. \
@@ -17,36 +18,34 @@ from {{ import_path }}. \
1718
from {{ import_path }}. \
1819
{{ network_os }}.facts.{{ resource }}.{{ resource }} import {{ resource|capitalize }}Facts
1920

21+
22+
FACT_SUBSETS = {}
23+
2024
class Facts(FactsArgs, FactsBase): #pylint: disable=R0903
2125
""" The fact class for {{ network_os }}
2226
"""
2327

24-
def get_facts(self, module, connection, gather_subset=['all']):
25-
""" Collect the facts for {{ network_os }}
26-
27-
:param module: The module instance
28-
:param connection: The device connection
29-
:param gather_subset: The facts subset to collect
30-
:rtype: dict
31-
:returns: the facts gathered
32-
"""
33-
valid_subsets = self.argument_spec['gather_subset'].get('choices', [])
34-
if valid_subsets and 'all' in valid_subsets:
35-
valid_subsets.remove('all')
28+
VALID_GATHER_SUBSETS = frozenset(FACT_SUBSETS.keys())
3629

30+
def generate_runable_subsets(self, module, subsets, valid_subsets):
3731
runable_subsets = set()
3832
exclude_subsets = set()
39-
if not gather_subset:
40-
gather_subset = ['all']
33+
minimal_gather_subset = frozenset(['default'])
4134

42-
for subset in gather_subset:
35+
for subset in subsets:
4336
if subset == 'all':
4437
runable_subsets.update(valid_subsets)
4538
continue
39+
if subset == 'min' and minimal_gather_subset:
40+
runable_subsets.update(minimal_gather_subset)
41+
continue
4642
if subset.startswith('!'):
4743
subset = subset[1:]
44+
if subset == 'min':
45+
exclude_subsets.update(minimal_gather_subset)
46+
continue
4847
if subset == 'all':
49-
exclude_subsets.update(valid_subsets)
48+
exclude_subsets.update(valid_subsets - minimal_gather_subset)
5049
continue
5150
exclude = True
5251
else:
@@ -62,16 +61,61 @@ class Facts(FactsArgs, FactsBase): #pylint: disable=R0903
6261

6362
if not runable_subsets:
6463
runable_subsets.update(valid_subsets)
65-
6664
runable_subsets.difference_update(exclude_subsets)
67-
self.ansible_facts['gather_subset'] = list(runable_subsets)
6865

69-
for attr in runable_subsets:
70-
getattr(self, '_get_%s' % attr, {})(module, connection)
66+
return runable_subsets
67+
68+
def get_facts(self, module, connection, gather_subset=['!config'], gather_network_resources=['all']):
69+
""" Collect the facts for {{ network_os }}
70+
71+
:param module: The module instance
72+
:param connection: The device connection
73+
:param gather_subset: The facts subset to collect
74+
:param gather_network_resources: The resource subset to collect
75+
:rtype: dict
76+
:returns: the facts gathered
77+
"""
78+
self.ansible_facts['gather_network_resources'] = list()
79+
self.ansible_facts['gather_subset'] = list()
80+
81+
valid_network_resources_subsets = self.argument_spec['gather_network_resources'].get('choices', [])
82+
if valid_network_resources_subsets and 'all' in valid_network_resources_subsets:
83+
valid_network_resources_subsets.remove('all')
84+
85+
if valid_network_resources_subsets:
86+
resources_runable_subsets = self.generate_runable_subsets(module, gather_network_resources, valid_network_resources_subsets)
87+
if resources_runable_subsets:
88+
self.ansible_facts['gather_network_resources'] = list(resources_runable_subsets)
89+
for attr in resources_runable_subsets:
90+
getattr(self, '_get_%s' % attr, {})(module, connection)
91+
92+
if self.VALID_GATHER_SUBSETS:
93+
runable_subsets = self.generate_runable_subsets(module, gather_subset, self.VALID_GATHER_SUBSETS)
94+
95+
if runable_subsets:
96+
facts = dict()
97+
self.ansible_facts['gather_subset'] = list(runable_subsets)
98+
99+
instances = list()
100+
for key in runable_subsets:
101+
instances.append(FACT_SUBSETS[key](module))
102+
103+
for inst in instances:
104+
inst.populate()
105+
facts.update(inst.facts)
106+
warnings.extend(inst.warnings)
107+
108+
for key, value in iteritems(facts):
109+
key = 'ansible_net_%s' % key
110+
self.ansible_facts[key] = value
111+
112+
if warnings:
113+
return self.ansible_facts, warnings
114+
else:
115+
return self.ansible_facts
71116

72-
return self.ansible_facts
73117

74118
@staticmethod
75-
def _get_net_configuration_{{ resource }}(module, connection):
119+
def _get_{{ resource }}(module, connection):
76120
return {{ resource|capitalize }}Facts({{ resource|capitalize }}Args. \
77121
argument_spec, 'config', 'options').populate_facts(module, connection)

roles/resource_module/templates/module_utils/network_os/facts/resource/resource.py.j2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class {{ resource|capitalize }}Facts(FactsBase):
4444
facts = {}
4545
if objs:
4646
facts['{{ resource }}'] = objs
47-
self.ansible_facts['net_configuration'].update(facts)
47+
self.ansible_facts['ansible_network_resources'].update(facts)
4848
return self.ansible_facts
4949

5050
def render_config(self, spec, conf):

0 commit comments

Comments
 (0)