Skip to content

Commit 6629ecf

Browse files
Merge pull request #52 from danielmellado/add_netconf
Add netconf support Reviewed-by: Ganesh Nalawade https://github.com/ganeshrn
2 parents 3df8a34 + ce28d6d commit 6629ecf

File tree

2 files changed

+134
-3
lines changed

2 files changed

+134
-3
lines changed

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

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ created
1313
from ansible.module_utils.network.common.cfg.base import ConfigBase
1414
from ansible.module_utils.network.common.utils import to_list
1515
from {{ import_path }}.{{ network_os }}.facts.facts import Facts
16+
{% if transport.netconf %}
17+
from ansible.module_utils.network.netconf.netconf import locked_config
18+
from ansible.module_utils.network.common.netconf import (build_root_xml_node,
19+
build_child_xml_node)
20+
{% endif %}
1621

1722

1823
class {{ resource|capitalize }}(ConfigBase):
@@ -51,8 +56,29 @@ class {{ resource|capitalize }}(ConfigBase):
5156
:returns: The result from module execution
5257
"""
5358
result = {'changed': False}
54-
commands = list()
59+
{% if transport.netconf %}
60+
existing_{{ resource }}_facts = self.get_{{ resource }}_facts()
61+
config_xmls = self.set_config(existing_{{ resource }}_facts)
62+
63+
with locked_config(self._module):
64+
for config_xml in to_list(config_xmls):
65+
diff = self._module._connectionload_config(self._module, config_xml, [])
66+
67+
commit = not self._module.check_mode
68+
if diff:
69+
if commit:
70+
self._module._connection.commit_configuration(self._module)
71+
else:
72+
self._module._connection.discard_changes(self._module)
73+
result['changed'] = True
74+
75+
if self._module._diff:
76+
result['diff'] = {'prepared': diff}
77+
78+
result['xml'] = config_xmls
79+
{% else %}
5580
warnings = list()
81+
commands = list()
5682

5783
existing_{{ resource }}_facts = self.get_{{ resource }}_facts()
5884
commands.extend(self.set_config(existing_{{ resource }}_facts))
@@ -62,6 +88,7 @@ class {{ resource|capitalize }}(ConfigBase):
6288
result['changed'] = True
6389
result['commands'] = commands
6490

91+
{% endif %}
6592
changed_{{ resource }}_facts = self.get_{{ resource }}_facts()
6693

6794
result['before'] = existing_{{ resource }}_facts
@@ -93,6 +120,23 @@ class {{ resource|capitalize }}(ConfigBase):
93120
:returns: the commands necessary to migrate the current configuration
94121
to the desired configuration
95122
"""
123+
{% if transport.netconf %}
124+
root = build_root_xml_node('{{ resource }}')
125+
state = self._module.params['state']
126+
if state == 'overridden':
127+
config_xmls = self._state_overridden(want, have)
128+
elif state == 'deleted':
129+
config_xmls = self._state_deleted(want, have)
130+
elif state == 'merged':
131+
config_xmls = self._state_merged(want, have)
132+
elif state == 'replaced':
133+
config_xmls = self._state_replaced(want, have)
134+
135+
for xml in config_xmls:
136+
root.append(xml)
137+
138+
return self._module._connection.tostring(root)
139+
{% else %}
96140
state = self._module.params['state']
97141
if state == 'overridden':
98142
kwargs = {}
@@ -107,7 +151,47 @@ class {{ resource|capitalize }}(ConfigBase):
107151
kwargs = {}
108152
commands = self._state_replaced(**kwargs)
109153
return commands
154+
{% endif %}
155+
{% if transport.netconf %}
156+
def _state_replaced(self, want, have):
157+
""" The command generator when state is replaced
110158

159+
:rtype: A list
160+
:returns: the xml necessary to migrate the current configuration
161+
to the desired configuration
162+
"""
163+
intf_xml = []
164+
return intf_xml
165+
166+
def _state_overridden(self, want, have):
167+
""" The command generator when state is overridden
168+
169+
:rtype: A list
170+
:returns: the xml necessary to migrate the current configuration
171+
to the desired configuration
172+
"""
173+
intf_xml = []
174+
return intf_xml
175+
def _state_deleted(self, want, have):
176+
""" The command generator when state is deleted
177+
178+
:rtype: A list
179+
:returns: the xml necessary to migrate the current configuration
180+
to the desired configuration
181+
"""
182+
intf_xml = []
183+
return intf_xml
184+
185+
def _state_merged(self, want, have):
186+
""" The command generator when state is merged
187+
188+
:rtype: A list
189+
:returns: the xml necessary to migrate the current configuration
190+
to the desired configuration
191+
"""
192+
intf_xml = []
193+
return intf_xml
194+
{% else %}
111195
@staticmethod
112196
def _state_replaced(**kwargs):
113197
""" The command generator when state is replaced
@@ -151,3 +235,4 @@ class {{ resource|capitalize }}(ConfigBase):
151235
"""
152236
commands = []
153237
return commands
238+
{% endif %}

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

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,24 @@ It is in this file the configuration is collected from the device
99
for a given resource, parsed, and the facts tree is populated
1010
based on the configuration.
1111
"""
12+
{% if not transport.netconf %}
1213
import re
14+
{% endif %}
1315
from copy import deepcopy
1416

17+
{% if transport.netconf %}
18+
from ansible.module_utils._text import to_bytes
19+
{% endif %}
1520
from ansible.module_utils.network.common import utils
1621
from {{ import_path }}.{{ network_os }}.argspec.{{ resource }}.{{ resource }} import {{ resource|capitalize }}Args
22+
{% if transport.netconf %}
23+
from ansible.module.utils.six import string_types
24+
try:
25+
from lxml import etree
26+
HAS_LXML = True
27+
except ImportError:
28+
HAS_LXML = False
29+
{% endif %}
1730

1831

1932
class {{ resource|capitalize }}Facts(object):
@@ -42,6 +55,25 @@ class {{ resource|capitalize }}Facts(object):
4255
:rtype: dictionary
4356
:returns: facts
4457
"""
58+
{% if transport.netconf %}
59+
if not HAS_LXML:
60+
self._module.fail_json(msg='lxml is not installed.')
61+
62+
if not data:
63+
config_filter = """
64+
<configuration>
65+
<resource>
66+
</resource>
67+
</configuration>
68+
"""
69+
data = connection.get_configuration(filter=config_filter)
70+
71+
if isinstance(data, string_types):
72+
data = etree.fromstring(to_bytes(data,
73+
errors='surrogate_then_replace'))
74+
75+
resources = data.xpath('configuration/resources/resource')
76+
{% else %}
4577
if connection: # just for linting purposes, remove
4678
pass
4779

@@ -64,6 +96,7 @@ class {{ resource|capitalize }}Facts(object):
6496
resources = [p.strip() for p in re.findall(find_pattern,
6597
data,
6698
re.DOTALL)]
99+
{% endif %}
67100

68101
objs = []
69102
for resource in resources:
@@ -72,11 +105,21 @@ class {{ resource|capitalize }}Facts(object):
72105
if obj:
73106
objs.append(obj)
74107

108+
{% if transport.netconf %}
109+
facts = {}
110+
if objs:
111+
facts['resource'] = []
112+
params = utils.validate_config(self.argument_spec,
113+
{'config': objs})
114+
for cfg in params['config']:
115+
facts['resource'].append(utils.remove_empties(cfg))
116+
{% else %}
75117
ansible_facts['ansible_network_resources'].pop('{{ resource }}', None)
76118
facts = {}
77119
if objs:
78120
params = utils.validate_config(self.argument_spec, {'config': objs})
79121
facts['{{ resource }}'] = params['config']
122+
{% endif %}
80123

81124
ansible_facts['ansible_network_resources'].update(facts)
82125
return ansible_facts
@@ -92,7 +135,10 @@ class {{ resource|capitalize }}Facts(object):
92135
:returns: The generated config
93136
"""
94137
config = deepcopy(spec)
95-
138+
{% if transport.netconf %}
139+
config['name'] = utils.get_xml_conf_arg(conf, 'name')
140+
config['some_value'] = utils.get_xml_conf_arg(conf, 'some_value')
141+
{% else %}
96142
config['name'] = utils.parse_conf_arg(conf, 'resource')
97143
config['some_string'] = utils.parse_conf_arg(conf, 'a_string')
98144

@@ -113,5 +159,5 @@ class {{ resource|capitalize }}Facts(object):
113159
config['some_int'] = int(utils.parse_conf_arg(conf, 'an_int'))
114160
except TypeError:
115161
config['some_int'] = None
116-
162+
{% endif %}
117163
return utils.remove_empties(config)

0 commit comments

Comments
 (0)