summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRohit Thakur <rohitthakur2590@outlook.com>2020-04-22 16:22:46 +0530
committerRohit Thakur <rohitthakur2590@outlook.com>2020-05-11 19:29:07 +0530
commit7e32c63e6d065062b4540b9bf467989ee86e1f2a (patch)
tree8dfa6115d91015c8100ed9994321e4073d17448e
parent37289b45840129f2296fbc9cff9a3eab97bdb2a5 (diff)
downloadvyos-ansible-collection-7e32c63e6d065062b4540b9bf467989ee86e1f2a.tar.gz
vyos-ansible-collection-7e32c63e6d065062b4540b9bf467989ee86e1f2a.zip
test cases added
Signed-off-by: Rohit Thakur <rohitthakur2590@outlook.com>
-rw-r--r--plugins/module_utils/network/vyos/argspec/ospfv2/ospfv2.py16
-rw-r--r--plugins/module_utils/network/vyos/config/ospfv2/ospfv2.py467
-rw-r--r--plugins/module_utils/network/vyos/facts/ospfv2/ospfv2.py309
-rw-r--r--plugins/module_utils/network/vyos/utils/utils.py1
-rw-r--r--plugins/modules/vyos_ospfv2.py2366
-rw-r--r--tests/integration/targets/vyos_ospfv2/defaults/main.yaml3
-rw-r--r--tests/integration/targets/vyos_ospfv2/meta/main.yaml3
-rw-r--r--tests/integration/targets/vyos_ospfv2/tasks/cli.yaml19
-rw-r--r--tests/integration/targets/vyos_ospfv2/tasks/main.yaml4
-rw-r--r--tests/integration/targets/vyos_ospfv2/tests/cli/_parsed_config.cfg29
-rw-r--r--tests/integration/targets/vyos_ospfv2/tests/cli/_populate.yaml35
-rw-r--r--tests/integration/targets/vyos_ospfv2/tests/cli/_remove_config.yaml6
-rw-r--r--tests/integration/targets/vyos_ospfv2/tests/cli/delete_single.yaml57
-rw-r--r--tests/integration/targets/vyos_ospfv2/tests/cli/deleted.yaml48
-rw-r--r--tests/integration/targets/vyos_ospfv2/tests/cli/empty_config.yaml49
-rw-r--r--tests/integration/targets/vyos_ospfv2/tests/cli/gathered.yaml33
-rw-r--r--tests/integration/targets/vyos_ospfv2/tests/cli/merged.yaml101
-rw-r--r--tests/integration/targets/vyos_ospfv2/tests/cli/merged_update.yaml70
-rw-r--r--tests/integration/targets/vyos_ospfv2/tests/cli/parsed.yaml41
-rw-r--r--tests/integration/targets/vyos_ospfv2/tests/cli/rendered.yaml88
-rw-r--r--tests/integration/targets/vyos_ospfv2/tests/cli/replaced.yaml100
-rw-r--r--tests/integration/targets/vyos_ospfv2/tests/cli/rtt.yaml149
-rw-r--r--tests/integration/targets/vyos_ospfv2/vars/main.yaml444
-rw-r--r--tests/unit/modules/network/vyos/fixtures/vyos_ospfv2_config.cfg9
-rw-r--r--tests/unit/modules/network/vyos/test_vyos_ospfv2.py526
-rw-r--r--tests/unit/modules/network/vyos/vyos_module.py2
26 files changed, 3817 insertions, 1158 deletions
diff --git a/plugins/module_utils/network/vyos/argspec/ospfv2/ospfv2.py b/plugins/module_utils/network/vyos/argspec/ospfv2/ospfv2.py
index 1b11d3c..a2a6e04 100644
--- a/plugins/module_utils/network/vyos/argspec/ospfv2/ospfv2.py
+++ b/plugins/module_utils/network/vyos/argspec/ospfv2/ospfv2.py
@@ -34,7 +34,6 @@ class Ospfv2Args(object): # pylint: disable=R0903
argument_spec = {
'config': {
- 'elements': 'dict',
'options': {
'auto_cost': {
'options': {
@@ -140,10 +139,10 @@ class Ospfv2Args(object): # pylint: disable=R0903
},
'type': 'list'
},
- 'ospf_area': {
+ 'areas': {
'elements': 'dict',
'options': {
- 'area': {
+ 'area_id': {
'type': 'str'
},
'area_type': {
@@ -159,6 +158,9 @@ class Ospfv2Args(object): # pylint: disable=R0903
'no_summary': {
'type': 'bool'
},
+ 'set': {
+ 'type': 'bool'
+ },
'translate': {
'choices':
['always', 'candidate', 'never'],
@@ -175,6 +177,9 @@ class Ospfv2Args(object): # pylint: disable=R0903
},
'no_summary': {
'type': 'bool'
+ },
+ 'set': {
+ 'type': 'bool'
}
},
'type': 'dict'
@@ -227,6 +232,7 @@ class Ospfv2Args(object): # pylint: disable=R0903
'authentication': {
'options': {
'md5': {
+ 'elements': 'dict',
'options': {
'key_id': {
'type': 'int'
@@ -235,7 +241,7 @@ class Ospfv2Args(object): # pylint: disable=R0903
'type': 'str'
}
},
- 'type': 'dict'
+ 'type': 'list'
},
'plaintext_password': {
'type': 'str'
@@ -343,7 +349,7 @@ class Ospfv2Args(object): # pylint: disable=R0903
'type': 'dict'
}
},
- 'type': 'list'
+ 'type': 'dict'
},
"running_config": {"type": "str"},
'state': {
diff --git a/plugins/module_utils/network/vyos/config/ospfv2/ospfv2.py b/plugins/module_utils/network/vyos/config/ospfv2/ospfv2.py
index 0109ca1..13645cd 100644
--- a/plugins/module_utils/network/vyos/config/ospfv2/ospfv2.py
+++ b/plugins/module_utils/network/vyos/config/ospfv2/ospfv2.py
@@ -29,19 +29,16 @@ from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.utils
list_diff_want_only, _in_target, _is_w_same, _bool_to_str
)
+
class Ospfv2(ConfigBase):
+
"""
The vyos_ospfv2 class
"""
- gather_subset = [
- '!all',
- '!min',
- ]
+ gather_subset = ['!all', '!min']
- gather_network_resources = [
- 'ospfv2',
- ]
+ gather_network_resources = ['ospfv2']
def __init__(self, module):
super(Ospfv2, self).__init__(module)
@@ -52,7 +49,10 @@ class Ospfv2(ConfigBase):
:rtype: A dictionary
:returns: The current configuration as a dictionary
"""
- facts, _warnings = Facts(self._module).get_facts(self.gather_subset, self.gather_network_resources, data=data)
+
+ (facts, _warnings) = \
+ Facts(self._module).get_facts(self.gather_subset,
+ self.gather_network_resources, data=data)
ospfv2_facts = facts['ansible_network_resources'].get('ospfv2')
if not ospfv2_facts:
return []
@@ -64,6 +64,7 @@ class Ospfv2(ConfigBase):
:rtype: A dictionary
:returns: The result from module execution
"""
+
result = {'changed': False}
warnings = list()
commands = list()
@@ -73,41 +74,38 @@ class Ospfv2(ConfigBase):
else:
existing_ospfv2_facts = []
- if self.state in self.ACTION_STATES or self.state == "rendered":
+ if self.state in self.ACTION_STATES or self.state == 'rendered':
commands.extend(self.set_config(existing_ospfv2_facts))
if commands and self.state in self.ACTION_STATES:
if not self._module.check_mode:
self._connection.edit_config(commands)
- result["changed"] = True
+ result['changed'] = True
if self.state in self.ACTION_STATES:
- result["commands"] = commands
+ result['commands'] = commands
- if self.state in self.ACTION_STATES or self.state == "gathered":
+ if self.state in self.ACTION_STATES or self.state == 'gathered':
changed_ospfv2_facts = self.get_ospfv2_facts()
- elif self.state == "rendered":
- result["rendered"] = commands
- elif self.state == "parsed":
- running_config = self._module.params["running_config"]
+ elif self.state == 'rendered':
+ result['rendered'] = commands
+ elif self.state == 'parsed':
+ running_config = self._module.params['running_config']
if not running_config:
- self._module.fail_json(
- msg="value of running_config parameter must not be empty for state parsed"
- )
- result["parsed"] = self.get_ospfv2_facts(
- data=running_config
- )
+ self._module.fail_json(msg='value of running_config parameter must not be empty for state parsed')
+ result['parsed'] = \
+ self.get_ospfv2_facts(data=running_config)
else:
changed_ospfv2_facts = []
if self.state in self.ACTION_STATES:
- result["before"] = existing_ospfv2_facts
- if result["changed"]:
- result["after"] = changed_ospfv2_facts
- elif self.state == "gathered":
- result["gathered"] = changed_ospfv2_facts
+ result['before'] = existing_ospfv2_facts
+ if result['changed']:
+ result['after'] = changed_ospfv2_facts
+ elif self.state == 'gathered':
+ result['gathered'] = changed_ospfv2_facts
- result["warnings"] = warnings
+ result['warnings'] = warnings
return result
def set_config(self, existing_ospfv2_facts):
@@ -118,6 +116,7 @@ class Ospfv2(ConfigBase):
:returns: the commands necessary to migrate the current configuration
to the desired configuration
"""
+
want = self._module.params['config']
have = existing_ospfv2_facts
resp = self.set_state(want, have)
@@ -132,24 +131,18 @@ class Ospfv2(ConfigBase):
:returns: the commands necessary to migrate the current configuration
to the desired configuration
"""
+
commands = []
- if self.state in ("merged", "replaced", "overridden", "rendered") and not w:
- self._module.fail_json(
- msg="value of config parameter must not be empty for state {0}".format(
- self.state
- )
- )
- if self.state == "overridden":
- commands.extend(self._state_overridden(w, h))
- elif self.state == "deleted":
+ if self.state in ('merged', 'replaced', 'overridden', 'rendered'
+ ) and not w:
+ self._module.fail_json(msg='value of config parameter must not be empty for state {0}'.format(self.state))
+
+ if self.state == 'deleted':
commands.extend(self._state_deleted(w, h))
- elif w:
- if self.state == "merged" or self.state == "rendered":
- for w_item in w:
- commands.extend(self._state_merged(w_item, h))
- elif self.state == "replaced":
- for w_item in w:
- commands.extend(self._state_replaced(w_item, h))
+ elif self.state in ('merged', 'rendered'):
+ commands.extend(self._state_merged(w, h))
+ elif self.state == 'replaced':
+ commands.extend(self._state_replaced(w, h))
return commands
def search_obj_in_have(self, have, w_name, key):
@@ -160,6 +153,7 @@ class Ospfv2(ConfigBase):
:param type: rule_sets/rule/r_list.
:return: rule-set/rule.
"""
+
if have:
for item in have:
if item[key] == w_name[key]:
@@ -173,12 +167,12 @@ class Ospfv2(ConfigBase):
:returns: the commands necessary to migrate the current configuration
to the desired configuration
"""
+
commands = []
- h_item = {}
if have:
- h_item = have[0]
- commands.extend(self._render_ospf_param(h_item, want, opr=False))
- commands.extend(self._render_ospf_param(want, h_item))
+ commands.extend(self._render_ospf_param(have, want,
+ opr=False))
+ commands.extend(self._render_ospf_param(want, have))
return commands
def _state_merged(self, want, have):
@@ -188,11 +182,9 @@ class Ospfv2(ConfigBase):
:returns: the commands necessary to merge the provided into
the current configuration
"""
+
commands = []
- h_item = {}
- if have:
- h_item = have[0]
- commands.extend(self._render_ospf_param(want, h_item))
+ commands.extend(self._render_ospf_param(want, have))
return commands
def _state_deleted(self, want, have):
@@ -202,18 +194,27 @@ class Ospfv2(ConfigBase):
:returns: the commands necessary to remove the current configuration
of the provided objects
"""
+
commands = []
- if want:
- for w in want:
- if have:
- h = have[0]
- if h:
- for key, val in iteritems(w):
- if key in h:
- if key == 'ospf_area':
- key = 'area'
- commands.append(self._compute_command(attr=key, opr=False))
- elif have and have[0]:
+ if want and have:
+ for (key, val) in iteritems(want):
+ if key in have:
+ if key == 'areas':
+ h_areas = have.get(key) or []
+ key = 'area'
+ for area in h_areas:
+ h_vlist = area.get('virtual_link') or []
+ if h_vlist:
+ for vlink in h_vlist:
+ cmd = self._compute_command(
+ key=key + ' ' + area['area_id'], attr='virtual_link',
+ val=vlink['address'], opr=False)
+ commands.append(cmd)
+ commands.append(self._compute_command(key=key,
+ attr=area['area_id'], opr=False))
+ commands.append(self._compute_command(attr=key,
+ opr=False))
+ elif have:
commands.append('delete protocols ospf')
return commands
@@ -227,16 +228,15 @@ class Ospfv2(ConfigBase):
:param opr: True/False.
:return: generated commands list.
"""
+
commands = []
w = deepcopy(remove_empties(want))
- leaf = (
- "default_metric",
- "log_adjacency_changes"
- )
+ leaf = ('default_metric', 'log_adjacency_changes')
if w:
- for key, val in iteritems(w):
+ for (key, val) in iteritems(w):
if opr and key in leaf and not _is_w_same(w, have, key):
- commands.append(self._form_attr_cmd(attr=key, val=_bool_to_str(val), opr=opr))
+ commands.append(self._form_attr_cmd(attr=key,
+ val=_bool_to_str(val), opr=opr))
elif not opr and key in leaf and not _in_target(have, key):
commands.append(self._form_attr_cmd(attr=key, val=_bool_to_str(val), opr=opr))
else:
@@ -253,21 +253,25 @@ class Ospfv2(ConfigBase):
:param opr: operation.
:return: list of commands.
"""
+
commands = []
- if key in ("neighbor", "redistribute"):
- commands.extend(self._render_list_dict_param(key, w, h, opr=opr))
- elif key in ("default_information", 'max_metric'):
- commands.extend(self._render_nested_dict_param(key, w, h, opr=opr))
- elif key in ("mpls_te", "auto_cost", "parameters", "auto_cost"):
+ if key in ('neighbor', 'redistribute'):
+ commands.extend(self._render_list_dict_param(key, w, h,
+ opr=opr))
+ elif key in ('default_information', 'max_metric'):
+ commands.extend(self._render_nested_dict_param(key, w, h,
+ opr=opr))
+ elif key in ('mpls_te', 'auto_cost', 'parameters', 'auto_cost'):
commands.extend(self._render_dict_param(key, w, h, opr=opr))
- elif key in ("route_map", "passive_interface", "passive_interface_exclude"):
+ elif key in ('route_map', 'passive_interface',
+ 'passive_interface_exclude'):
commands.extend(self._render_list_param(key, w, h, opr=opr))
- elif key == "ospf_area":
- commands.extend(self._render_ospf_area(key, w, h, opr=opr))
- elif key == "timers":
- commands.extend(self._render_timers(key, w, h, opr=opr, remove=remove))
- elif key == "distance":
- commands.extend(self._render_distance(key, w, h, opr=opr, remove=remove))
+ elif key == 'areas':
+ commands.extend(self._render_areas(key, w, h, opr=opr))
+ elif key == 'timers':
+ commands.extend(self._render_timers(key, w, h, opr=opr))
+ elif key == 'distance':
+ commands.extend(self._render_distance(key, w, h, opr=opr))
return commands
def _render_dict_param(self, attr, want, have, opr=True):
@@ -279,6 +283,7 @@ class Ospfv2(ConfigBase):
:param opr: True/False.
:return: generated list of commands.
"""
+
commands = []
h = {}
if have:
@@ -288,18 +293,19 @@ class Ospfv2(ConfigBase):
elif want[attr]:
leaf_dict = {'auto_cost': 'reference_bandwidth',
'mpls_te': ('enabled', 'router_address'),
- 'parameters': ("router_id", "abr_type", "opaque_lsa", "rfc1583_compatibility")}
+ 'parameters': ('router_id', 'abr_type',
+ 'opaque_lsa', 'rfc1583_compatibility')}
leaf = leaf_dict[attr]
- for item, value in iteritems(want[attr]):
+ for (item, value) in iteritems(want[attr]):
if opr and item in leaf and not _is_w_same(want[attr], h, item):
- if item == "enabled":
+ if item == 'enabled':
item = 'enable'
- if item in ("opaque_lsa", "enable", "rfc1583_compatibility"):
+ if item in ('opaque_lsa', 'enable', 'rfc1583_compatibility'):
commands.append(self._form_attr_cmd(key=attr, attr=item, opr=opr))
else:
commands.append(self._form_attr_cmd(key=attr, attr=item, val=value, opr=opr))
elif not opr and item in leaf and not _in_target(h, item):
- if item == "enabled":
+ if item == 'enabled':
commands.append(self._form_attr_cmd(key=attr, attr='enable', opr=opr))
else:
commands.append(self._form_attr_cmd(key=attr, attr=item, opr=opr))
@@ -315,6 +321,7 @@ class Ospfv2(ConfigBase):
:param opr: True/False.
:return: generated list of commands.
"""
+
commands = []
h = []
if want:
@@ -327,7 +334,7 @@ class Ospfv2(ConfigBase):
if opr:
members = list_diff_want_only(w, h)
for member in members:
- command = cmd + attr.replace("_","-") + " "
+ command = cmd + attr.replace('_', '-') + ' '
if attr == 'network':
command += member['address']
else:
@@ -338,11 +345,96 @@ class Ospfv2(ConfigBase):
for member in w:
if attr == 'network':
if not self.search_obj_in_have(h, member, 'address'):
- commands.append(cmd + attr.replace("_","-") + ' ' + member['address'])
+ commands.append(cmd + attr.replace('_','-') +
+ ' ' + member['address'])
elif member not in h:
- commands.append(cmd + attr.replace("_","-") + ' ' + member)
+ commands.append(cmd + attr.replace('_', '-') +
+ ' ' + member)
else:
- commands.append(cmd + " " + attr.replace("_","-"))
+ commands.append(cmd + ' ' + attr.replace('_', '-'))
+ return commands
+
+ def _render_vlink(self, attr, want, have, cmd=None, opr=True):
+ """
+ This function forms the set/delete commands based on the 'opr' type
+ for attributes with in desired list of dictionary.
+ :param attr: attribute name.
+ :param w: the desired config.
+ :param h: the target config.
+ :param cmd: commands to be prepend.
+ :param opr: True/False.
+ :return: generated commands list.
+ """
+
+ commands = []
+ h = []
+ name = {'virtual_link': 'address'}
+ leaf_dict = {'virtual_link': ('address', 'dead_interval',
+ 'transmit_delay', 'hello_interval',
+ 'retransmit_interval')}
+ leaf = leaf_dict[attr]
+ w = want.get(attr) or []
+ if have:
+ h = have.get(attr) or []
+ if not opr and not h:
+ commands.append(cmd + attr.replace('_', '-'))
+ elif w:
+ for w_item in w:
+ for (key, val) in iteritems(w_item):
+ if not cmd:
+ cmd = self._compute_command(opr=opr)
+ h_item = self.search_obj_in_have(h, w_item, name[attr])
+ if opr and key in leaf and not _is_w_same(w_item, h_item, key):
+ if key in 'address':
+ commands.append(cmd
+ + attr.replace('_', '-')
+ + ' ' + str(val))
+ else:
+ commands.append(cmd + attr.replace('_', '-')
+ + ' ' + w_item[name[attr]]
+ + ' ' + key.replace('_', '-')
+ + ' ' + str(val))
+ elif not opr and key in leaf and not _in_target(h_item, key):
+ if key in 'address':
+ commands.append(cmd + attr.replace('_', '-')
+ + ' ' + str(val))
+ else:
+ commands.append(cmd + attr.replace('_', '-')
+ + ' ' + w_item[name[attr]]
+ + ' ' + key)
+ elif key == 'authentication':
+ commands.extend(self._render_vlink_auth(
+ attr,
+ key,
+ w_item,
+ h_item,
+ w_item['address'],
+ cmd,
+ opr,
+ ))
+ return commands
+
+ def _render_vlink_auth(self, attr, key, want, have, address, cmd=None, opr=True):
+ """
+ This function forms the set/delete commands based on the 'opr' type
+ for attributes with in desired list of dictionary.
+ :param attr: attribute name.
+ :param w: the desired config.
+ :param h: the target config.
+ :param cmd: commands to be prepend.
+ :param opr: True/False.
+ :return: generated commands list.
+ """
+
+ commands = []
+ h = []
+
+ w = want.get(key) or {}
+ if have:
+ h = have.get(key) or {}
+ cmd += attr.replace('_', '-') + ' ' + address + ' ' + key + ' '
+ commands.extend(self._render_list_dict_param('md5', w, h, cmd,
+ opr))
return commands
def _render_list_dict_param(self, attr, want, have, cmd=None, opr=True):
@@ -356,17 +448,24 @@ class Ospfv2(ConfigBase):
:param opr: True/False.
:return: generated commands list.
"""
+
commands = []
h = []
- name = {'redistribute': 'route_type',
- 'neighbor': 'neighbor_id',
- 'range': 'address',
- 'vlink': 'address'}
- leaf_dict = {'redistribute': ("metric", "route_map", "route_type", "metric_type"),
- 'neighbor': ("priority", "poll_interval", "neighbor_id"),
- 'range': ("cost", "address", "substitute", "not_advertise"),
- 'vlink': ("address", "dead_interval", "transmit_delay", "hello_interval", "retransmit_interval")
- }
+ name = {
+ 'redistribute': 'route_type',
+ 'neighbor': 'neighbor_id',
+ 'range': 'address',
+ 'md5': 'key_id',
+ 'vlink': 'address',
+ }
+ leaf_dict = {
+ 'md5': 'md5_key',
+ 'redistribute': ('metric', 'route_map', 'route_type', 'metric_type'),
+ 'neighbor': ('priority', 'poll_interval', 'neighbor_id'),
+ 'range': ('cost', 'address', 'substitute', 'not_advertise'),
+ 'vlink': ('address', 'dead_interval', 'transmit_delay',
+ 'hello_interval', 'retransmit_interval'),
+ }
leaf = leaf_dict[attr]
w = want.get(attr) or []
if have:
@@ -375,26 +474,43 @@ class Ospfv2(ConfigBase):
commands.append(self._compute_command(attr=attr, opr=opr))
elif w:
for w_item in w:
- for key, val in iteritems(w_item):
+ for (key, val) in iteritems(w_item):
if not cmd:
cmd = self._compute_command(opr=opr)
h_item = self.search_obj_in_have(h, w_item, name[attr])
if opr and key in leaf and not _is_w_same(w_item, h_item, key):
- if key == 'cost':
- commands.append(cmd + attr + ' ' + w_item[name[attr]] + ' ' + key + ' ' + str(val))
- elif key == 'not_advertise':
- commands.append(cmd + attr + ' ' + w_item[name[attr]] + ' ' + key.replace("_","-"))
- elif key in ('route_type', 'neighbor_id', 'address'):
+ if key in ('route_type', 'neighbor_id',
+ 'address', 'key_id'):
commands.append(cmd + attr + ' ' + str(val))
- elif key == 'authentication':
- commands.append(self._render_vlink(key, w_item, h_item, cmd, opr))
+ elif key == 'cost':
+ commands.append(cmd + attr
+ + ' ' + w_item[name[attr]]
+ + ' ' + key
+ + ' ' + str(val))
+ elif key == 'not_advertise':
+ commands.append(cmd + attr
+ + ' ' + w_item[name[attr]]
+ + ' ' + key.replace('_', '-'))
+ elif key == 'md5_key':
+ commands.append(cmd + attr
+ + ' ' + 'key-id'
+ + ' ' + str(w_item[name[attr]])
+ + ' ' + key.replace('_', '-')
+ + ' ' + w_item[key])
else:
- commands.append(cmd + attr + ' ' + w_item[name[attr]] + ' ' + key.replace("_", "-") + ' ' + str(val))
- elif not opr and key in leaf and not _in_target(h_item, key):
- if key in ('route_type', 'neighbor_id', 'address'):
+ commands.append(cmd + attr
+ + ' ' + w_item[name[attr]]
+ + ' ' + key.replace('_', '-')
+ + ' ' + str(val))
+ elif not opr and key in leaf \
+ and not _in_target(h_item, key):
+ if key in ('route_type', 'neighbor_id',
+ 'address', 'key_id'):
commands.append(cmd + attr + ' ' + str(val))
else:
- commands.append(cmd + (attr + ' ' + w_item[name[attr]] + ' ' + key))
+ commands.append(cmd + attr
+ + ' ' + w_item[name[attr]]
+ + ' ' + key)
return commands
def _render_nested_dict_param(self, attr, want, have, opr=True):
@@ -408,13 +524,12 @@ class Ospfv2(ConfigBase):
:param opr: True/False.
:return: generated commands list.
"""
+
commands = []
attr_dict = {'default_information': 'originate',
- 'max_metric': 'router_lsa',
- }
- leaf_dict = {'default_information': ("always", "metric", "metric_type", "route_map"),
- 'max_metric': ("always", "metric", "metric_type", "route_map"),
- }
+ 'max_metric': 'router_lsa'}
+ leaf_dict = {'default_information': ('always', 'metric', 'metric_type', 'route_map'),
+ 'max_metric': ('administrative', 'on_startup', 'on_shutdown')}
h = {}
w = want.get(attr) or {}
if have:
@@ -430,18 +545,24 @@ class Ospfv2(ConfigBase):
leaf = leaf_dict[attr]
if h and key in h.keys():
h_attrib = h.get(key) or {}
- for item, val in iteritems(w[key]):
+ for (item, val) in iteritems(w[key]):
if opr and item in leaf and not _is_w_same(w[key], h_attrib, item):
- if item in ('administrative', 'always'):
- commands.append(cmd + (attr.replace("_","-") + " " + key.replace("_","-") + " " + item.replace("_","-")))
- else:
- commands.append(cmd + (attr.replace("_","-") + " " + key.replace("_","-") + " " + item.replace("_","-") + " " + str(val)))
-
- elif not opr and item in leaf and not _in_target(h_attrib, item):
- commands.append(cmd + (attr + " " + item))
+ if item in ('administrative', 'always') and val:
+ commands.append(cmd + attr.replace('_', '-')
+ + ' ' + key.replace('_', '-')
+ + ' ' + item.replace('_', '-'))
+ elif item not in ('administrative', 'always'):
+ commands.append(cmd + attr.replace('_', '-')
+ + ' ' + key.replace('_', '-')
+ + ' ' + item.replace('_', '-')
+ + ' ' + str(val))
+ elif not opr and item in leaf \
+ and not _in_target(h_attrib, item):
+
+ commands.append(cmd + attr + ' ' + item)
return commands
- def _render_ospf_area(self, attr, want, have, opr=True):
+ def _render_areas(self, attr, want, have, opr=True):
"""
This function forms the set/delete commands based on the 'opr' type
for ospf area attributes.
@@ -451,32 +572,38 @@ class Ospfv2(ConfigBase):
:param opr: True/False.
:return: generated commands list.
"""
+
commands = []
h_lst = {}
w_lst = want.get(attr) or []
- l_set = ("area", "shortcut", "authentication")
+ l_set = ('area_id', 'shortcut', 'authentication')
if have:
h_lst = have.get(attr) or []
if not opr and not h_lst:
commands.append(self._form_attr_cmd(attr='area', opr=opr))
elif w_lst:
for w_area in w_lst:
- cmd = self._compute_command(key='area', attr=_bool_to_str(w_area['area']), opr=opr) + ' '
- h_area = self.search_obj_in_have(h_lst, w_area, 'area')
+ cmd = self._compute_command(
+ key='area', attr=_bool_to_str(w_area['area_id']), opr=opr
+ ) + ' '
+ h_area = self.search_obj_in_have(h_lst, w_area, 'area_id')
if not opr and not h_area:
- commands.append(self._form_attr_cmd(key='area', attr=w_area['area'], opr=opr))
+ commands.append(self._form_attr_cmd(key='area',
+ attr=w_area['area_id'], opr=opr))
else:
- for key, val in iteritems(w_area):
+ for (key, val) in iteritems(w_area):
if opr and key in l_set and not _is_w_same(w_area, h_area, key):
- if key == 'area':
- commands.append(self._form_attr_cmd(attr=key, val=_bool_to_str(val), opr=opr))
+ if key == 'area_id':
+ commands.append(self._form_attr_cmd(attr='area',
+ val=_bool_to_str(val), opr=opr))
else:
- commands.append(cmd + key + ' ' + _bool_to_str(val).replace("_","-"))
+ commands.append(cmd + key + ' ' +
+ _bool_to_str(val).replace('_', '-'))
elif not opr and key in l_set:
- if key == 'area' and not _in_target(h_area, key):
+ if key == 'area_id' and not _in_target(h_area, key):
commands.append(cmd)
continue
- elif key != 'area' and not _in_target(h_area, key):
+ elif key != 'area_id' and not _in_target(h_area, key):
commands.append(cmd + val + ' ' + key)
elif key == 'area_type':
commands.extend(self._render_area_type(w_area, h_area, key, cmd, opr))
@@ -499,33 +626,61 @@ class Ospfv2(ConfigBase):
:param opr: True/False.
:return: generated commands list.
"""
+
commands = []
h_type = {}
w_type = want.get(attr) or []
if have:
h_type = have.get(attr) or {}
if not opr and not h_type:
- commands.append(cmd + attr.replace("_","-"))
+ commands.append(cmd + attr.replace('_', '-'))
elif w_type:
- key = "normal"
+ key = 'normal'
if opr and key in w_type.keys() and not _is_w_same(w_type, h_type, key):
- commands.append(cmd + attr.replace("_","-") + ' ' + key)
- elif not opr and key in w_type.keys() and not (h_type and key in h_type.keys()):
- commands.append(cmd + want['area'] + ' ' + attr.replace("_","-"))
-
- a_type = {'nssa': ("default_cost", "no_summary", "translate"),
- 'stub': ("default_cost", "no_summary")}
+ if not w_type[key] and h_type and h_type[key]:
+ commands.append(cmd.replace('set', 'delete')
+ + attr.replace('_', '-')
+ + ' ' + key)
+ elif w_type[key]:
+ commands.append(cmd + attr.replace('_', '-')
+ + ' ' + key)
+ elif not opr and key in w_type.keys() and not (h_type
+ and key in h_type.keys()):
+ commands.append(cmd + want['area']
+ + ' ' + attr.replace('_', '-'))
+
+ a_type = {'nssa': ('set', 'default_cost', 'no_summary', 'translate'),
+ 'stub': ('set', 'default_cost', 'no_summary')}
for key in a_type:
w_area = want[attr].get(key) or {}
h_area = {}
if w_area:
if h_type and key in h_type.keys():
h_area = h_type.get(key) or {}
- for item, val in iteritems(w_type[key]):
- if opr and item in a_type[key] and not _is_w_same(w_type[key], h_area, item):
- commands.append(cmd + (attr.replace("_","-") + " " + key + " " + item.replace("_","-") + " " + str(val)))
- elif not opr and item in a_type[key] and not (h_type and key in h_type):
- commands.append(cmd + (want['area'] + ' ' + attr.replace("_","-") + " " + key + " " + item.replace("_","-")))
+ for (item, val) in iteritems(w_type[key]):
+ if opr and item in a_type[key] \
+ and not _is_w_same(w_type[key], h_area, item):
+ if item == 'set' and val:
+ commands.append(cmd + attr.replace('_', '-')
+ + ' ' + key)
+ elif not val and h_area and h_area[item]:
+ commands.append(cmd.replace('set', 'delete')
+ + attr.replace('_', '-')
+ + ' ' + key)
+ elif item != 'set':
+ commands.append(cmd + attr.replace('_', '-')
+ + ' ' + key
+ + ' ' + item.replace('_', '-')
+ + ' ' + str(val))
+ elif not opr and item in a_type[key] \
+ and not (h_type and key in h_type):
+ if item == 'set':
+ commands.append(cmd + attr.replace('_', '-')
+ + ' ' + key)
+ else:
+ commands.append(cmd + want['area']
+ + ' ' + attr.replace('_', '-')
+ + ' ' + key + ' ' + item.replace('_', '-'))
return commands
def _form_attr_cmd(self, key=None, attr=None, val=None, opr=True):
@@ -537,6 +692,7 @@ class Ospfv2(ConfigBase):
:param opr: True/False.
:return: generated command.
"""
+
return self._compute_command(key, attr=self._map_attrib(attr), val=val, opr=opr)
def _compute_command(self, key=None, attr=None, val=None, remove=False, opr=True):
@@ -548,15 +704,16 @@ class Ospfv2(ConfigBase):
:param opr: True/False.
:return: generated command.
"""
+
if remove or not opr:
- cmd = "delete protocols ospf "
+ cmd = 'delete protocols ospf '
else:
- cmd = "set protocols ospf "
+ cmd = 'set protocols ospf '
if key:
- cmd += key.replace("_", "-") + " "
+ cmd += key.replace('_', '-') + ' '
if attr:
- cmd += attr.replace("_", "-")
- if val and opr:
+ cmd += attr.replace('_', '-')
+ if val:
cmd += " '" + str(val) + "'"
return cmd
@@ -567,4 +724,6 @@ class Ospfv2(ConfigBase):
:param attrib: attribute
:return: regex string
"""
- return 'disable' if attrib =='disabled' else attrib.replace("_","-")
+
+ return ('disable' if attrib == 'disabled'
+ else attrib.replace('_', '-'))
diff --git a/plugins/module_utils/network/vyos/facts/ospfv2/ospfv2.py b/plugins/module_utils/network/vyos/facts/ospfv2/ospfv2.py
index 3457fac..0467b72 100644
--- a/plugins/module_utils/network/vyos/facts/ospfv2/ospfv2.py
+++ b/plugins/module_utils/network/vyos/facts/ospfv2/ospfv2.py
@@ -9,19 +9,29 @@ It is in this file the configuration is collected from the device
for a given resource, parsed, and the facts tree is populated
based on the configuration.
"""
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
from re import findall, search, M
from copy import deepcopy
-from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import (
- utils,
-)
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils
+
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.ospfv2.ospfv2 import Ospfv2Args
class Ospfv2Facts(object):
+
""" The vyos ospfv2 fact class
"""
- def __init__(self, module, subspec='config', options='options'):
+ def __init__(
+ self,
+ module,
+ subspec='config',
+ options='options',
+ ):
+
self._module = module
self.argument_spec = Ospfv2Args.argument_spec
spec = deepcopy(self.argument_spec)
@@ -46,25 +56,22 @@ class Ospfv2Facts(object):
:rtype: dictionary
:returns: facts
"""
+
if not data:
data = self.get_device_data(connection)
+
# typically data is populated from the current device configuration
# data = connection.get('show running-config | section ^interface')
# using mock data instead
- objs = []
+
+ objs = {}
ospfv2 = findall(r"^set protocols ospf (.+)", data, M)
if ospfv2:
- config = self.render_config(ospfv2)
- if config:
- objs.append(config)
- ansible_facts["ansible_network_resources"].pop("ospfv2", None)
+ objs = self.render_config(ospfv2)
facts = {}
- if objs:
- facts["ospfv2"] = []
- params = utils.validate_config(self.argument_spec, {"config": objs})
- for cfg in params["config"]:
- facts["ospfv2"].append(utils.remove_empties(cfg))
- ansible_facts["ansible_network_resources"].update(facts)
+ params = utils.validate_config(self.argument_spec,{'config': objs})
+ facts['ospfv2'] = utils.remove_empties(params['config'])
+ ansible_facts['ansible_network_resources'].update(facts)
return ansible_facts
def render_config(self, conf):
@@ -74,37 +81,38 @@ class Ospfv2Facts(object):
:param conf: The configuration
:returns: The generated config
"""
- conf = "\n".join(filter(lambda x: x, conf))
- a_lst = ["default_metric", "log_adjacency_changes"]
+
+ conf = '\n'.join(filter(lambda x: x, conf))
+ a_lst = ['default_metric', 'log_adjacency_changes']
config = self.parse_attr(conf, a_lst)
if not config:
config = {}
- config["timers"] = self.parse_timers(conf)
- config["auto_cost"] = self.parse_auto_cost(conf)
- config["distance"] = self.parse_distance(conf)
- config["max_metric"] = self.parse_max_metric(conf)
- config["mpls_te"] = self.parse_attrib(conf, "mpls_te", "mpls-te")
- config["default_information"] = self.parse_def_info(conf)
- config["parameters"] = self.parse_attrib(conf, "parameters", "parameters")
- config["route_map"] = self.parse_leaf_list(conf, "route-map")
- config["ospf_area"] = self.parse_attrib_list(conf, "area", "area")
- config["neighbor"] = self.parse_attrib_list(conf, "neighbor", "neighbor_id")
- config["passive_interface"] = self.parse_leaf_list(conf, "passive-interface")
- config["redistribute"] = self.parse_attrib_list(conf, "redistribute", "route_type")
- config["passive_interface_exclude"] = self.parse_leaf_list(conf, "passive-interface-exclude")
+ config['timers'] = self.parse_timers(conf)
+ config['auto_cost'] = self.parse_auto_cost(conf)
+ config['distance'] = self.parse_distance(conf)
+ config['max_metric'] = self.parse_max_metric(conf)
+ config['default_information'] = self.parse_def_info(conf)
+ config['route_map'] = self.parse_leaf_list(conf, 'route-map')
+ config['mpls_te'] = self.parse_attrib(conf, 'mpls_te', 'mpls-te')
+ config['areas'] = self.parse_attrib_list(conf, 'area', 'area_id')
+ config['parameters'] = self.parse_attrib(conf, 'parameters', 'parameters')
+ config['neighbor'] = self.parse_attrib_list(conf, 'neighbor', 'neighbor_id')
+ config['passive_interface'] = self.parse_leaf_list(conf, 'passive-interface')
+ config['redistribute'] = self.parse_attrib_list(conf, 'redistribute', 'route_type')
+ config['passive_interface_exclude'] = self.parse_leaf_list(conf, 'passive-interface-exclude')
return config
- def parse_timers(self, conf, attrib=None):
+ def parse_timers(self, conf):
"""
This function triggers the parsing of 'timers' attributes
:param conf: configuration
- :param attrib: attribute name
:return: generated config dictionary
"""
+
cfg_dict = {}
- cfg_dict["refresh"] = self.parse_refresh(conf, "refresh")
- cfg_dict["throttle"] = self.parse_throttle(conf, "spf")
+ cfg_dict['refresh'] = self.parse_refresh(conf, 'refresh')
+ cfg_dict['throttle'] = self.parse_throttle(conf, 'spf')
return cfg_dict
def parse_throttle(self, conf, attrib=None):
@@ -114,6 +122,7 @@ class Ospfv2Facts(object):
:param attrib: 'spf'
:return: generated config dictionary
"""
+
cfg_dict = {}
cfg_dict[attrib] = self.parse_attrib(conf, attrib, match=attrib)
return cfg_dict
@@ -125,39 +134,9 @@ class Ospfv2Facts(object):
:param attrib: 'refresh'
:return: generated config dictionary
"""
- cfg_dict = self.parse_attr(conf, ["timers"], match=attrib)
- return cfg_dict
- def parse_attrib_list(self, conf, attrib, param):
- """
- This function forms the regex to fetch the listed attributes
- from config
- :param conf: configuration data
- :param attrib: attribute name
- :param param: parameter data
- :return: generated rule list configuration
- """
- r_lst = []
- if attrib == "area":
- items = findall(r"^" + attrib + " (?:\'*)(\S+)(?:\'*)", conf, M)
- else:
- items = findall(r"" + attrib + " (?:\'*)(\S+)(?:\'*)", conf, M)
- if items:
- a_lst = []
- for item in set(items):
- i_regex = r" %s .+$" % item
- cfg = "\n".join(findall(i_regex, conf, M))
- if attrib == 'area':
- obj = self.parse_area(cfg, item)
- elif attrib == 'virtual-link':
- obj = self.parse_vlink(cfg)
- else:
- obj = self.parse_attrib(cfg, attrib)
- obj[param] = item.strip("'")
- if obj:
- a_lst.append(obj)
- r_lst = sorted(a_lst, key=lambda i: i[param])
- return r_lst
+ cfg_dict = self.parse_attr(conf, ['timers'], match=attrib)
+ return cfg_dict
def parse_leaf_list(self, conf, attrib):
"""
@@ -167,8 +146,9 @@ class Ospfv2Facts(object):
:param attrib: attribute name
:return: generated rule list configuration
"""
+
lst = []
- items = findall(r"^" + attrib + " (?:\'*)(\S+)(?:\'*)", conf, M)
+ items = findall(r"^" + attrib + " (?:\'*)(\\S+)(?:\'*)", conf, M)
if items:
for i in set(items):
lst.append(i.strip("'"))
@@ -181,8 +161,9 @@ class Ospfv2Facts(object):
:param attrib: attribute name
:return: generated config dictionary
"""
- cfg_dict = self.parse_attr(conf, ["global"], match=attrib)
- cfg_dict["ospf"] = self.parse_ospf(conf, "ospf")
+
+ cfg_dict = self.parse_attr(conf, ['global'], match=attrib)
+ cfg_dict['ospf'] = self.parse_ospf(conf, 'ospf')
return cfg_dict
def parse_ospf(self, conf, attrib=None):
@@ -192,18 +173,19 @@ class Ospfv2Facts(object):
:param attrib: 'ospf'
:return: generated config dictionary
"""
+
cfg_dict = self.parse_attrib(conf, 'ospf', match=attrib)
return cfg_dict
- def parse_max_metric(self, conf, attrib=None):
+ def parse_max_metric(self, conf):
"""
This function triggers the parsing of 'max_metric' attributes
:param conf: configuration
- :param attrib: attribute name
:return: generated config dictionary
"""
+
cfg_dict = {}
- cfg_dict["router_lsa"] = self.parse_attrib(conf, "router_lsa", match="router-lsa")
+ cfg_dict['router_lsa'] = self.parse_attrib(conf, 'router_lsa', match='router-lsa')
return cfg_dict
def parse_auto_cost(self, conf, attrib=None):
@@ -213,18 +195,20 @@ class Ospfv2Facts(object):
:param attrib: attribute name
:return: generated config dictionary
"""
- cfg_dict = self.parse_attr(conf, ["reference_bandwidth"], match=attrib)
+
+ cfg_dict = self.parse_attr(conf, ['reference_bandwidth'],
+ match=attrib)
return cfg_dict
- def parse_def_info(self, conf, attrib=None):
+ def parse_def_info(self, conf):
"""
This function triggers the parsing of 'default_information' attributes
:param conf: configuration
- :param attrib: attribute name
:return: generated config dictionary
"""
+
cfg_dict = {}
- cfg_dict["originate"] = self.parse_attrib(conf, "originate", "originate")
+ cfg_dict['originate'] = self.parse_attrib(conf, 'originate', 'originate')
return cfg_dict
def parse_area(self, conf, area_id):
@@ -234,16 +218,28 @@ class Ospfv2Facts(object):
:param area_id: area identity
:return: generated rule configuration dictionary.
"""
- rule = self.parse_attrib(conf, "area", match=area_id)
+
+ rule = self.parse_attrib(conf, 'area_id', match=area_id)
r_sub = {
- "area_type": self.parse_area_type(conf, "area-type"),
- "network": self.parse_network(conf),
- "range": self.parse_attrib_list(conf, "range", "address"),
- "virtual_link": self.parse_attrib_list(conf, "virtual-link", "address")
- }
+ 'area_type': self.parse_area_type(conf, 'area-type'),
+ 'network': self.parse_network(conf),
+ 'range': self.parse_attrib_list(conf, 'range', 'address'),
+ 'virtual_link': self.parse_attrib_list(conf, 'virtual-link', 'address'),
+ }
rule.update(r_sub)
return rule
+ def parse_key(self, conf, key_id):
+ """
+ This function triggers the parsing of 'area' attributes.
+ :param conf: configuration data
+ :param area_id: area identity
+ :return: generated rule configuration dictionary.
+ """
+
+ rule = self.parse_attrib(conf, 'key_id', match=key_id)
+ return rule
+
def parse_area_type(self, conf, attrib=None):
"""
This function triggers the parsing of 'area_type' attributes
@@ -251,9 +247,10 @@ class Ospfv2Facts(object):
:param attrib: 'area-type'
:return: generated config dictionary
"""
- cfg_dict = self.parse_attr(conf, ["normal"], match=attrib)
- cfg_dict["nssa"] = self.parse_attrib(conf, "nssa")
- cfg_dict["stub"] = self.parse_attrib(conf, "stub")
+
+ cfg_dict = self.parse_attr(conf, ['normal'], match=attrib)
+ cfg_dict['nssa'] = self.parse_attrib(conf, 'nssa', match='nssa')
+ cfg_dict['stub'] = self.parse_attrib(conf, 'stub', match='stub')
return cfg_dict
def parse_network(self, conf):
@@ -262,24 +259,27 @@ class Ospfv2Facts(object):
:param conf: configuration data
:return: generated rule list configuration
"""
+
a_lst = []
applications = findall(r"network (.+)", conf, M)
if applications:
app_lst = []
for r in set(applications):
- obj = {"address": r.strip("'")}
+ obj = {'address': r.strip("'")}
app_lst.append(obj)
- a_lst = sorted(app_lst, key=lambda i: i["address"])
+ a_lst = sorted(app_lst, key=lambda i: i['address'])
return a_lst
def parse_vlink(self, conf):
"""
- This function triggers the parsing of 'vitual_link' attributes
+ This function triggers the parsing of 'virtual_link' attributes
:param conf: configuration data
:return: generated rule configuration dictionary
"""
+
rule = self.parse_attrib(conf, 'vlink')
- r_sub = {"authentication": self.parse_authentication(conf, "authentication")}
+ r_sub = {'authentication': self.parse_authentication(conf,
+ 'authentication')}
rule.update(r_sub)
return rule
@@ -290,19 +290,49 @@ class Ospfv2Facts(object):
:param attrib: 'authentication'
:return: generated config dictionary
"""
- cfg_dict = self.parse_attr(conf, ["plaintext_password"], match=attrib)
- cfg_dict["md5"] = self.parse_md5(conf, "md5")
+
+ cfg_dict = self.parse_attr(conf, ['plaintext_password'],
+ match=attrib)
+ cfg_dict['md5'] = self.parse_attrib_list(conf, 'key-id', 'key_id')
return cfg_dict
- def parse_md5(self, conf, attrib=None):
+ def parse_attrib_list(self, conf, attrib, param):
"""
- This function triggers the parsing of 'md5' attributes
- :param conf: configuration
- :param attrib: 'md5'
- :return: generated config dictionary
+ This function forms the regex to fetch the listed attributes
+ from config
+ :param conf: configuration data
+ :param attrib: attribute name
+ :param param: parameter data
+ :return: generated rule list configuration
"""
- cfg_dict = self.parse_attr(conf, ["key_id"], match=attrib)
- return cfg_dict
+
+ r_lst = []
+ if attrib == 'area':
+ items = findall(r"^" + attrib.replace('_', '-')
+ + " (?:\'*)(\\S+)(?:\'*)", conf, M)
+ elif attrib == 'key-id':
+ items = findall(r"^.*" + attrib.replace('_', '-')
+ + " (?:\'*)(\\S+)(?:\'*)", conf, M)
+ else:
+ items = findall(r"" + attrib + " (?:\'*)(\\S+)(?:\'*)", conf, M)
+ if items:
+ a_lst = []
+ for item in set(items):
+ i_regex = r" %s .+$" % item
+ cfg = '\n'.join(findall(i_regex, conf, M))
+ if attrib == 'area':
+ obj = self.parse_area(cfg, item)
+ elif attrib == 'virtual-link':
+ obj = self.parse_vlink(cfg)
+ elif attrib == 'key-id':
+ obj = self.parse_key(cfg, item)
+ else:
+ obj = self.parse_attrib(cfg, attrib)
+ obj[param] = item.strip("'")
+ if obj:
+ a_lst.append(obj)
+ r_lst = sorted(a_lst, key=lambda i: i[param])
+ return r_lst
def parse_attrib(self, conf, param, match=None):
"""
@@ -310,21 +340,28 @@ class Ospfv2Facts(object):
:param conf: configuration data
:return: generated configuration dictionary
"""
+
param_lst = {
- 'stub': ["default_cost", "no_summary"],
- 'area': ["shortcut", "authentication"],
- 'mpls_te': ["enabled", "router_address"],
- 'neighbor': ["priority", "poll_interval"],
- 'ospf': ["external", "inter_area", "intra_area"],
- 'nssa': ["translate", "default_cost", "no_summary"],
- 'redistribute': ["metric", "metric_type", "route_map"],
- 'spf': ["delay", "max_holdtime", "initial_holdtime"],
- 'range': ["cost", "substitute", "not_advertise"],
- 'originate': ["always", "metric", "metric_type", "route_map"],
- 'router_lsa': ["administrative", "on_shutdown", "on_startup"],
- 'config_routes': ["default_metric", "log_adjacency_changes"],
- 'parameters': ["abr_type", "opaque_lsa", "router_id", "rfc1583_compatibility"],
- 'vlink': ["dead_interval", "hello_interval", "transmit_delay", "retransmit_interval"]
+ 'key_id': ['md5_key'],
+ 'mpls_te': ['enabled', 'router_address'],
+ 'area_id': ['shortcut', 'authentication'],
+ 'neighbor': ['priority', 'poll_interval'],
+ 'stub': ['set', 'default_cost', 'no_summary'],
+ 'range': ['cost', 'substitute', 'not_advertise'],
+ 'ospf': ['external', 'inter_area', 'intra_area'],
+ 'spf': ['delay', 'max_holdtime', 'initial_holdtime'],
+ 'redistribute': ['metric', 'metric_type', 'route_map'],
+ 'nssa': ['set', 'translate', 'default_cost', 'no_summary'],
+ 'config_routes': ['default_metric', 'log_adjacency_changes'
+ ],
+ 'originate': ['always', 'metric', 'metric_type', 'route_map'
+ ],
+ 'router_lsa': ['administrative', 'on_shutdown', 'on_startup'
+ ],
+ 'parameters': ['abr_type', 'opaque_lsa', 'router_id',
+ 'rfc1583_compatibility'],
+ 'vlink': ['dead_interval', 'hello_interval',
+ 'transmit_delay', 'retransmit_interval'],
}
cfg_dict = self.parse_attr(conf, param_lst[param], match)
return cfg_dict
@@ -339,16 +376,21 @@ class Ospfv2Facts(object):
:param match: parent node/attribute name.
:return: generated config dictionary.
"""
+
config = {}
for attrib in attr_list:
regex = self.map_regex(attrib)
+
if match:
- regex = match.replace("_", "-") + " " + regex
+ regex = match.replace('_', '-') + ' ' + regex
if conf:
if self.is_bool(attrib):
- out = conf.find(attrib.replace("_", "-"))
- dis = conf.find(attrib.replace("_", "-") + " 'disable'")
+ out = conf.find(attrib.replace('_', '-'))
+ dis = conf.find(attrib.replace('_', '-')
+ + " 'disable'")
if match:
+ if attrib == 'set' and conf.find(match) >= 1:
+ config[attrib] = True
en = conf.find(match + " 'enable'")
if out >= 1:
if dis >= 1:
@@ -358,7 +400,7 @@ class Ospfv2Facts(object):
elif match and en >= 1:
config[attrib] = True
else:
- out = search(r"^.*" + regex + " (.+)", conf, M)
+ out = search(r"^.*" + regex + ' (.+)', conf, M)
if out:
val = out.group(1).strip("'")
if self.is_num(attrib):
@@ -373,7 +415,10 @@ class Ospfv2Facts(object):
:param attrib: attribute
:return: regex string
"""
- return 'disable' if attrib == "disabled" else 'enable' if attrib == "enabled" else attrib.replace("_","-")
+
+ return ('disable' if attrib == 'disabled' else ('enable'
+ if attrib == 'enabled' else ('area' if attrib
+ == 'area_id' else attrib.replace('_', '-'))))
def is_bool(self, attrib):
"""
@@ -381,7 +426,17 @@ class Ospfv2Facts(object):
:param attrib: attribute.
:return: True/False
"""
- bool_set = ("always", "normal", "enabled", "opaque_lsa", "not_advertise", "administrative", "rfc1583_compatibility")
+
+ bool_set = (
+ 'set',
+ 'always',
+ 'normal',
+ 'enabled',
+ 'opaque_lsa',
+ 'not_advertise',
+ 'administrative',
+ 'rfc1583_compatibility',
+ )
return True if attrib in bool_set else False
def is_num(self, attrib):
@@ -390,6 +445,20 @@ class Ospfv2Facts(object):
:param attrib: attribute.
:return: True/false.
"""
- num_set = ("ospf", "delay", "metric", "inter_area", "intra_area", "on_startup", "metric_type", "on_shutdown",
- "max_holdtime", "default_metric", "initial_holdtime")
+
+ num_set = (
+ 'ospf',
+ 'delay',
+ 'metric',
+ 'inter_area',
+ 'intra_area',
+ 'on_startup',
+ 'metric_type',
+ 'on_shutdown',
+ 'max_holdtime',
+ 'poll_interval',
+ 'default_metric',
+ 'initial_holdtime',
+ 'key_id',
+ )
return True if attrib in num_set else False
diff --git a/plugins/module_utils/network/vyos/utils/utils.py b/plugins/module_utils/network/vyos/utils/utils.py
index c7dc575..c539beb 100644
--- a/plugins/module_utils/network/vyos/utils/utils.py
+++ b/plugins/module_utils/network/vyos/utils/utils.py
@@ -7,7 +7,6 @@
from __future__ import absolute_import, division, print_function
__metaclass__ = type
-import q
from ansible.module_utils.six import iteritems
from ansible_collections.ansible.netcommon.plugins.module_utils.compat import (
ipaddress,
diff --git a/plugins/modules/vyos_ospfv2.py b/plugins/modules/vyos_ospfv2.py
index 73528eb..866ed76 100644
--- a/plugins/modules/vyos_ospfv2.py
+++ b/plugins/modules/vyos_ospfv2.py
@@ -39,21 +39,24 @@ DOCUMENTATION = """
---
module: vyos_ospfv2
version_added: 2.10
-short_description: Manages attributes of OSPF IPv4 routes on VyOS network devices.
-description: This module manages attributes of OSPF IPv4 routes on VyOS network devices.
-author: Rohit Thakur (@rohitthakur2590)
+short_description: This resource module configures and manages attributes of OSPFv2 routes on VyOS network devices.
+description: This resource module configures and manages attributes of OSPFv2 routes on VyOS network devices.
+notes:
+ - Tested against VyOS 1.1.8 (helium).
+ - This module works with connection C(network_cli). See L(the VyOS OS Platform Options,../network/user_guide/platform_vyos.html).
+author:
+ - Rohit Thakur (@rohitthakur2590)
options:
config:
- description: A provided OSPF route configuration.
- type: list
- elements: dict
+ description: A provided OSPFv2 route configuration.
+ type: dict
suboptions:
- ospf_area:
- description: OSPF area.
+ areas:
+ description: OSPFv2 area.
type: list
elements: dict
suboptions:
- area:
+ area_id:
description: Configured to discard packets.
type: str
area_type:
@@ -61,12 +64,15 @@ options:
type: dict
suboptions:
normal:
- description: Normal OSPF area.
+ description: Normal OSPFv2 area.
type: bool
nssa:
- description: Nssa OSPF area.
+ description: Nssa OSPFv2 area.
type: dict
suboptions:
+ set:
+ description: Enabling nssa.
+ type: bool
default_cost:
description: Summary-default cost of nssa area.
type: int
@@ -78,9 +84,12 @@ options:
type: str
choices: ['always', 'candidate', 'never']
stub:
- description: Stub OSPF area.
+ description: Stub OSPFv2 area.
type: dict
suboptions:
+ set:
+ description: Enabling stub.
+ type: bool
default_cost:
description: Summary-default cost of stub area.
type: int
@@ -88,17 +97,17 @@ options:
description: Do not inject inter-area routes into stub.
type: bool
authentication:
- description: OSPF area authentication type.
+ description: OSPFv2 area authentication type.
type: str
choices: ['plaintext-password', 'md5']
network:
- description: OSPF network.
+ description: OSPFv2 network.
type: list
elements: dict
suboptions:
address:
required: True
- description: OSPF IPv4 network address.
+ description: OSPFv2 IPv4 network address.
type: str
range:
description: Summarize routes matching prefix (border routers only).
@@ -130,12 +139,13 @@ options:
description: virtual link address.
type: str
authentication:
- description: OSPF area authentication type.
+ description: OSPFv2 area authentication type.
type: dict
suboptions:
md5:
description: MD5 key id based authentication.
- type: dict
+ type: list
+ elements: dict
suboptions:
key_id:
description: MD5 key id.
@@ -163,7 +173,7 @@ options:
type: str
choices: ['detail']
max_metric:
- description: OSPF maximum/infinite-distance metric.
+ description: OSPFv2 maximum/infinite-distance metric.
type: dict
suboptions:
router_lsa:
@@ -180,7 +190,7 @@ options:
description: Time to advertise self as stub-router
type: int
auto_cost:
- description: Calculate OSPF interface cost according to bandwidth.
+ description: Calculate OSPFv2 interface cost according to bandwidth.
type: dict
suboptions:
reference_bandwidth:
@@ -198,10 +208,10 @@ options:
description: Always advertise default route.
type: bool
metric:
- description: OSPF default metric.
+ description: OSPFv2 default metric.
type: int
metric_type:
- description: OSPF Metric types for default routes.
+ description: OSPFv2 Metric types for default routes.
type: int
route_map:
description: Route map references.
@@ -214,10 +224,10 @@ options:
type: dict
suboptions:
global:
- description: Global OSPF administrative distance.
+ description: Global OSPFv2 administrative distance.
type: int
ospf:
- description: OSPF administrative distance.
+ description: OSPFv2 administrative distance.
type: dict
suboptions:
external:
@@ -255,11 +265,11 @@ options:
description: Neighbor priority.
type: int
parameters:
- descriptions: OSPF specific parameters.
+ descriptions: OSPFv2 specific parameters.
type: dict
suboptions:
abr_type:
- description: OSPF ABR Type.
+ description: OSPFv2 ABR Type.
type: str
choices: ['cisco', 'ibm', 'shortcut', 'standard']
opaque_lsa:
@@ -290,7 +300,7 @@ options:
description: Metric for redistribution routes.
type: int
metric_type:
- description: OSPF Metric types.
+ description: OSPFv2 Metric types.
type: int
route_map:
description: Route map references.
@@ -315,7 +325,7 @@ options:
type: dict
suboptions:
spf:
- description: OSPF SPF timers.
+ description: OSPFv2 SPF timers.
type: dict
suboptions:
delay:
@@ -327,6 +337,16 @@ options:
max_holdtime:
description: maximum hold time (sec).
type: int
+ running_config:
+ description:
+ - The module, by default, will connect to the remote device and retrieve the current
+ running-config to use as a base for comparing against the contents of source.
+ There are times when it is not desirable to have the task get the current running-config
+ for every task in a playbook. The I(running_config) argument allows the implementer
+ to pass in the configuration to use as the base config for comparison. This
+ value of this option should be the output received from device by executing
+ command C(show configuration commands | grep 'ospf')
+ type: str
state:
description:
- The state the configuration should be left in.
@@ -346,35 +366,66 @@ EXAMPLES = """
# Before state:
# -------------
#
-# vyos@192# run show configuration commands | grep ospf
+# vyos@vyos# run show configuration commands | grep ospf
+#
#
-- name: Merge the provided configuration with the existing running configuration
- vyos_ospf_routes:
+- name: Merge the provided configuration with the exisiting running configuration
+ vyos.vyos.vyos_ospfv2:
config:
- - afi: 'ipv4'
- ospf_area:
- - area: 0
- network: 192.168.0.0/24
- default_information:
- originate:
- always: true
- metric: 2
- metric_type: 10
- log_adjacency_changes: "details"
- parameters:
- router_id: 10.1.1.1
- redistribute:
- - route_type: 'connected'
- metric_type: 2
- route_map: 'CONNECT'
- - afi: 'ipv6'
- ospf_area:
- - area: 0.0.0.0
- range: 2001:db8:1::/64
- parameters:
- router-id 192.168.1.1
- redistribute:
- - route_type: 'connected'
+ log_adjacency_changes: 'detail'
+ max_metric:
+ router_lsa:
+ administrative: true
+ on_shutdown: 10
+ on_startup: 10
+ default_information:
+ originate:
+ always: true
+ metric: 10
+ metric_type: 2
+ route_map: 'ingress'
+ mpls_te:
+ enabled: true
+ router_address: '192.0.11.11'
+ auto_cost:
+ reference_bandwidth: 2
+ neighbor:
+ - neighbor_id: '192.0.11.12'
+ poll_interval: 10
+ priority: 2
+ redistribute:
+ - route_type: 'bgp'
+ metric: 10
+ metric_type: 2
+ passive_interface:
+ - 'eth1'
+ - 'eth2'
+ parameters:
+ router_id: '192.0.1.1'
+ opaque_lsa: true
+ rfc1583_compatibility: true
+ abr_type: 'cisco'
+ areas:
+ - area_id: '2'
+ area_type:
+ normal: true
+ authentication: "plaintext-password"
+ shortcut: 'enable'
+ - area_id: '3'
+ area_type:
+ nssa:
+ set: true
+ - area_id: '4'
+ area_type:
+ stub:
+ default_cost: 20
+ network:
+ - address: '192.0.2.0/24'
+ range:
+ - address: '192.0.3.0/24'
+ cost: 10
+ - address: '192.0.4.0/24'
+ cost: 12
state: merged
#
#
@@ -385,276 +436,432 @@ EXAMPLES = """
# before": []
#
# "commands": [
-# "set interfaces ethernet eth1 firewall in name 'INBOUND'",
-# "set protocols ospf area 0 network 192.168.0.0/24",
+# "set protocols ospf mpls-te enable",
+# "set protocols ospf mpls-te router-address '192.0.11.11'",
+# "set protocols ospf redistribute bgp",
+# "set protocols ospf redistribute bgp metric-type 2",
+# "set protocols ospf redistribute bgp metric 10",
+# "set protocols ospf default-information originate metric-type 2",
# "set protocols ospf default-information originate always",
# "set protocols ospf default-information originate metric 10",
-# "set protocols ospf default-information originate metric-type 2",
-# "set protocols ospf log-adjacency-changes",
-# "set protocols ospf parameters router-id 10.1.1.1",
-# "set protocols ospf redistribute connected metric-type 2",
-# "set protocols ospf redistribute connected route-map CONNECT",
-# "set protocols ospfv3 area 0.0.0.0 range 2001:db8:1::/64,
-# "set protocols ospfv3 parameters router-id 192.168.1.1,
-# "set protocols ospfv3 redistribute connected
+# "set protocols ospf default-information originate route-map ingress",
+# "set protocols ospf auto-cost reference-bandwidth '2'",
+# "set protocols ospf parameters router-id '192.0.1.1'",
+# "set protocols ospf parameters opaque-lsa",
+# "set protocols ospf parameters abr-type 'cisco'",
+# "set protocols ospf parameters rfc1583-compatibility",
+# "set protocols ospf passive-interface eth1",
+# "set protocols ospf passive-interface eth2",
+# "set protocols ospf max-metric router-lsa on-shutdown 10",
+# "set protocols ospf max-metric router-lsa administrative",
+# "set protocols ospf max-metric router-lsa on-startup 10",
+# "set protocols ospf log-adjacency-changes 'detail'",
+# "set protocols ospf neighbor 192.0.11.12 priority 2",
+# "set protocols ospf neighbor 192.0.11.12 poll-interval 10",
+# "set protocols ospf neighbor 192.0.11.12",
+# "set protocols ospf area '2'",
+# "set protocols ospf area 2 authentication plaintext-password",
+# "set protocols ospf area 2 shortcut enable",
+# "set protocols ospf area 2 area-type normal",
+# "set protocols ospf area '3'",
+# "set protocols ospf area 3 area-type nssa",
+# "set protocols ospf area 4 range 192.0.3.0/24 cost 10",
+# "set protocols ospf area 4 range 192.0.3.0/24",
+# "set protocols ospf area 4 range 192.0.4.0/24 cost 12",
+# "set protocols ospf area 4 range 192.0.4.0/24",
+# "set protocols ospf area 4 area-type stub default-cost 20",
+# "set protocols ospf area '4'",
+# "set protocols ospf area 4 network 192.0.2.0/24"
# ]
#
-# "after": [
-# {
-# {
-# "afi": "ipv4",
-# "ospf_area":[
-# {
-# "area": "0",
-# "network": "192.168.0.0/24"
-# }
-# ],
-# "default_information":
-# {
-# "originate":
-# {
-# always: true,
-# metric: 2,
-# metric_type: 10
-# }
-# },
-# "log_adjacency_changes": "details"
-# "parameters":
-# {
-# "router_id": "10.1.1.1"
-# },
-# "redistribute":[
-# {
-# "route_type": "connetced",
-# "metric_type": 2
-# "route_map": "CONNECT"
-# }
-# ]
-# },
-# {
-# "afi": "ipv6",
-# "ospf_area":[
-# {
-# "area": "0.0.0.0",
-# }
-# ],
-# "range": "2001:db8:1::/64",
-# "parameters":
-# {
-# "router_id": "192.168.1.1"
-# },
-# "redistribute":
-# [
-# {
-# "route_type": "connetced",
-# }
-# ]
+# "after": {
+# "areas": [
+# {
+# "area_id": "2",
+# "area_type": {
+# "normal": true
+# },
+# "authentication": "plaintext-password",
+# "shortcut": "enable"
+# },
+# {
+# "area_id": "3",
+# "area_type": {
+# "nssa": {
+# "set": true
+# }
# }
-# ]
+# },
+# {
+# "area_id": "4",
+# "area_type": {
+# "stub": {
+# "default_cost": 20,
+# "set": true
+# }
+# },
+# "network": [
+# {
+# "address": "192.0.2.0/24"
+# }
+# ],
+# "range": [
+# {
+# "address": "192.0.3.0/24",
+# "cost": 10
+# },
+# {
+# "address": "192.0.4.0/24",
+# "cost": 12
+# }
+# ]
+# }
+# ],
+# "auto_cost": {
+# "reference_bandwidth": 2
+# },
+# "default_information": {
+# "originate": {
+# "always": true,
+# "metric": 10,
+# "metric_type": 2,
+# "route_map": "ingress"
+# }
+# },
+# "log_adjacency_changes": "detail",
+# "max_metric": {
+# "router_lsa": {
+# "administrative": true,
+# "on_shutdown": 10,
+# "on_startup": 10
+# }
+# },
+# "mpls_te": {
+# "enabled": true,
+# "router_address": "192.0.11.11"
+# },
+# "neighbor": [
+# {
+# "neighbor_id": "192.0.11.12",
+# "poll_interval": 10,
+# "priority": 2
+# }
+# ],
+# "parameters": {
+# "abr_type": "cisco",
+# "opaque_lsa": true,
+# "rfc1583_compatibility": true,
+# "router_id": "192.0.1.1"
+# },
+# "passive_interface": [
+# "eth2",
+# "eth1"
+# ],
+# "redistribute": [
+# {
+# "metric": 10,
+# "metric_type": 2,
+# "route_type": "bgp"
+# }
+# ]
+# }
#
# After state:
# -------------
#
-# vyos@vyos:~$ show configuration commands| grep firewall
-# set protocols ospf area 0 network 192.168.0.0/24
-# set protocols ospf default-information originate always
-# set protocols ospf default-information originate metric 10
-# set protocols ospf default-information originate metric-type 2
-# set protocols ospf log-adjacency-changes details
-# set protocols ospf parameters router-id 10.1.1.1
-# set protocols ospf redistribute connected metric-type 2
-# set protocols ospf redistribute connected route-map CONNECT
-# set protocols ospfv3 area 0.0.0.0 range 2001:db8:1::/64
-# set protocols ospfv3 parameters router-id 192.168.1.1
-# set protocols ospfv3 redistribute connected
+# vyos@192# run show configuration commands | grep ospf
+# set protocols ospf area 2 area-type 'normal'
+# set protocols ospf area 2 authentication 'plaintext-password'
+# set protocols ospf area 2 shortcut 'enable'
+# set protocols ospf area 3 area-type 'nssa'
+# set protocols ospf area 4 area-type stub default-cost '20'
+# set protocols ospf area 4 network '192.0.2.0/24'
+# set protocols ospf area 4 range 192.0.3.0/24 cost '10'
+# set protocols ospf area 4 range 192.0.4.0/24 cost '12'
+# set protocols ospf auto-cost reference-bandwidth '2'
+# set protocols ospf default-information originate 'always'
+# set protocols ospf default-information originate metric '10'
+# set protocols ospf default-information originate metric-type '2'
+# set protocols ospf default-information originate route-map 'ingress'
+# set protocols ospf log-adjacency-changes 'detail'
+# set protocols ospf max-metric router-lsa 'administrative'
+# set protocols ospf max-metric router-lsa on-shutdown '10'
+# set protocols ospf max-metric router-lsa on-startup '10'
+# set protocols ospf mpls-te 'enable'
+# set protocols ospf mpls-te router-address '192.0.11.11'
+# set protocols ospf neighbor 192.0.11.12 poll-interval '10'
+# set protocols ospf neighbor 192.0.11.12 priority '2'
+# set protocols ospf parameters abr-type 'cisco'
+# set protocols ospf parameters 'opaque-lsa'
+# set protocols ospf parameters 'rfc1583-compatibility'
+# set protocols ospf parameters router-id '192.0.1.1'
+# set protocols ospf passive-interface 'eth1'
+# set protocols ospf passive-interface 'eth2'
+# set protocols ospf redistribute bgp metric '10'
+# set protocols ospf redistribute bgp metric-type '2'
-# Using replaced
+# Using merged
#
# Before state:
# -------------
#
-# vyos@192# run show configuration commands | grep ospf
-# set protocols ospf area 0 network 192.168.0.0/24
-# set protocols ospf default-information originate always
-# set protocols ospf default-information originate metric 10
-# set protocols ospf default-information originate metric-type 2
-# set protocols ospf log-adjacency-changes details
-# set protocols ospf parameters router-id 10.1.1.1
-# set protocols ospf redistribute connected metric-type 2
-# set protocols ospf redistribute connected route-map CONNECT
-# set protocols ospfv3 area 0.0.0.0 range 2001:db8:1::/64
-# set protocols ospfv3 parameters router-id 192.168.1.1
-# set protocols ospfv3 redistribute connected
-#
-- name: Replace the provided configuration with the existing running configuration
- vyos_ospf_routes:
+# vyos@vyos# run show configuration commands | grep ospf
+#
+#
+- name: Merge the provided configuration to update exisiting running configuration
+ vyos.vyos.vyos_ospfv2:
config:
- - afi: 'ipv4'
- ospf_area:
- - area: 0
- network: 192.168.0.0/24
- area_type:
- normal: True
- default_information:
- originate:
- always: true
- metric: 2
- metric_type: 10
- log_adjacency_changes: "details"
- parameters:
- router_id: 10.1.1.1
- redistribute:
- - route_type: 'static'
- metric_type: 2
- route_map: 'STATIC'
- - afi: 'ipv6'
- ospf_area:
- - area: 0.0.0.0
- range: 2001:db8:1::/64
- parameters:
- router-id 192.168.1.1
- redistribute:
- - route_type: 'connected'
- state: replaced
+ areas:
+ - area_id: '2'
+ area_type:
+ normal: true
+ authentication: "plaintext-password"
+ shortcut: 'enable'
+ - area_id: '3'
+ area_type:
+ nssa:
+ set: false
+ - area_id: '4'
+ area_type:
+ stub:
+ default_cost: 20
+ network:
+ - address: '192.0.2.0/24'
+ - address: '192.0.22.0/24'
+ - address: '192.0.32.0/24'
+ state: merged
#
#
# -------------------------
# Module Execution Result
# -------------------------
#
-# before": [
-# {
-# {
-# "afi": "ipv4",
-# "ospf_area":[
-# {
-# "area": "0",
-# "network": "192.168.0.0/24"
-# }
-# ],
-# "default_information":
-# {
-# "originate":
-# {
-# always: true,
-# metric: 2,
-# metric_type: 10
-# }
-# },
-# "log_adjacency_changes": "details"
-# "parameters":
-# {
-# "router_id": "10.1.1.1"
-# },
-# "redistribute":[
-# {
-# "route_type": "connetced",
-# "metric_type": 2
-# "route_map": "CONNECT"
-# }
-# ]
-# },
-# {
-# "afi": "ipv6",
-# "ospf_area":[
-# {
-# "area": "0.0.0.0",
-# }
-# ],
-# "range": "2001:db8:1::/64",
-# "parameters":
-# {
-# "router_id": "192.168.1.1"
-# },
-# "redistribute":
-# [
-# {
-# "route_type": "connetced",
-# }
-# ]
+# "before": {
+# "areas": [
+# {
+# "area_id": "2",
+# "area_type": {
+# "normal": true
+# },
+# "authentication": "plaintext-password",
+# "shortcut": "enable"
+# },
+# {
+# "area_id": "3",
+# "area_type": {
+# "nssa": {
+# "set": true
+# }
# }
-# ]
+# },
+# {
+# "area_id": "4",
+# "area_type": {
+# "stub": {
+# "default_cost": 20,
+# "set": true
+# }
+# },
+# "network": [
+# {
+# "address": "192.0.2.0/24"
+# }
+# ],
+# "range": [
+# {
+# "address": "192.0.3.0/24",
+# "cost": 10
+# },
+# {
+# "address": "192.0.4.0/24",
+# "cost": 12
+# }
+# ]
+# }
+# ],
+# "auto_cost": {
+# "reference_bandwidth": 2
+# },
+# "default_information": {
+# "originate": {
+# "always": true,
+# "metric": 10,
+# "metric_type": 2,
+# "route_map": "ingress"
+# }
+# },
+# "log_adjacency_changes": "detail",
+# "max_metric": {
+# "router_lsa": {
+# "administrative": true,
+# "on_shutdown": 10,
+# "on_startup": 10
+# }
+# },
+# "mpls_te": {
+# "enabled": true,
+# "router_address": "192.0.11.11"
+# },
+# "neighbor": [
+# {
+# "neighbor_id": "192.0.11.12",
+# "poll_interval": 10,
+# "priority": 2
+# }
+# ],
+# "parameters": {
+# "abr_type": "cisco",
+# "opaque_lsa": true,
+# "rfc1583_compatibility": true,
+# "router_id": "192.0.1.1"
+# },
+# "passive_interface": [
+# "eth2",
+# "eth1"
+# ],
+# "redistribute": [
+# {
+# "metric": 10,
+# "metric_type": 2,
+# "route_type": "bgp"
+# }
+# ]
+# }
#
# "commands": [
-# "delete protocols ospf redistribute connected",
-# "set protocols ospf area 0 area_type normal",
-# "set protocols ospf redistribute static metric-type 2",
-# "set protocols ospf redistribute static route-map CONNECT"
+# "delete protocols ospf area 4 area-type stub",
+# "set protocols ospf area 4 network 192.0.22.0/24"
+# "set protocols ospf area 4 network 192.0.32.0/24"
# ]
#
-# "after": [
-# {
-# {
-# "afi": "ipv4",
-# "ospf_area":[
-# {
-# "area": "0",
-# "area_type":
-# {
-# normal: true
-# }
-# "network": "192.168.0.0/24"
-# }
-# ],
-# "default_information":
-# {
-# "originate":
-# {
-# always: true,
-# metric: 2,
-# metric_type: 10
-# }
-# },
-# "log_adjacency_changes": "details"
-# "parameters":
-# {
-# "router_id": "10.1.1.1"
-# },
-# "redistribute":[
-# {
-# "route_type": "static",
-# "metric_type": 2
-# "route_map": "STATIC"
-# }
-# ]
-# },
-# {
-# "afi": "ipv6",
-# "ospf_area":[
-# {
-# "area": "0.0.0.0",
-# }
-# ],
-# "range": "2001:db8:1::/64",
-# "parameters":
-# {
-# "router_id": "192.168.1.1"
-# },
-# "redistribute":
-# [
-# {
-# "route_type": "connected",
-# }
-# ]
+# "after": {
+# "areas": [
+# {
+# "area_id": "2",
+# "area_type": {
+# "normal": true
+# },
+# "authentication": "plaintext-password",
+# "shortcut": "enable"
+# },
+# {
+# "area_id": "3",
+# "area_type": {
+# "nssa": {
+# "set": true
+# }
# }
-# ]
+# },
+# {
+# "area_id": "4",
+# },
+# "network": [
+# {
+# "address": "192.0.2.0/24"
+# },
+# {
+# "address": "192.0.22.0/24"
+# },
+# {
+# "address": "192.0.32.0/24"
+# }
+# ],
+# "range": [
+# {
+# "address": "192.0.3.0/24",
+# "cost": 10
+# },
+# {
+# "address": "192.0.4.0/24",
+# "cost": 12
+# }
+# ]
+# }
+# ],
+# "auto_cost": {
+# "reference_bandwidth": 2
+# },
+# "default_information": {
+# "originate": {
+# "always": true,
+# "metric": 10,
+# "metric_type": 2,
+# "route_map": "ingress"
+# }
+# },
+# "log_adjacency_changes": "detail",
+# "max_metric": {
+# "router_lsa": {
+# "administrative": true,
+# "on_shutdown": 10,
+# "on_startup": 10
+# }
+# },
+# "mpls_te": {
+# "enabled": true,
+# "router_address": "192.0.11.11"
+# },
+# "neighbor": [
+# {
+# "neighbor_id": "192.0.11.12",
+# "poll_interval": 10,
+# "priority": 2
+# }
+# ],
+# "parameters": {
+# "abr_type": "cisco",
+# "opaque_lsa": true,
+# "rfc1583_compatibility": true,
+# "router_id": "192.0.1.1"
+# },
+# "passive_interface": [
+# "eth2",
+# "eth1"
+# ],
+# "redistribute": [
+# {
+# "metric": 10,
+# "metric_type": 2,
+# "route_type": "bgp"
+# }
+# ]
+# }
#
# After state:
# -------------
#
-# vyos@vyos:~$ show configuration commands| grep firewall
-# set protocols ospf area 0 network 192.168.0.0/24
-# set protocols ospf default-information originate always
-# set protocols ospf default-information originate metric 10
-# set protocols ospf default-information originate metric-type 2
-# set protocols ospf log-adjacency-changes details
-# set protocols ospf parameters router-id 10.1.1.1
-# set protocols ospf redistribute static metric-type 2
-# set protocols ospf redistribute static route-map CONNECT
-# set protocols ospfv3 area 0.0.0.0 range 2001:db8:2::/64
-# set protocols ospfv3 parameters router-id 192.168.2.1
-# set protocols ospfv3 redistribute connected
+# vyos@192# run show configuration commands | grep ospf
+# set protocols ospf area 2 area-type 'normal'
+# set protocols ospf area 2 authentication 'plaintext-password'
+# set protocols ospf area 2 shortcut 'enable'
+# set protocols ospf area 3 area-type 'nssa'
+# set protocols ospf area 4 network '192.0.2.0/24'
+# set protocols ospf area 4 network '192.0.22.0/24'
+# set protocols ospf area 4 network '192.0.32.0/24'
+# set protocols ospf area 4 range 192.0.3.0/24 cost '10'
+# set protocols ospf area 4 range 192.0.4.0/24 cost '12'
+# set protocols ospf auto-cost reference-bandwidth '2'
+# set protocols ospf default-information originate 'always'
+# set protocols ospf default-information originate metric '10'
+# set protocols ospf default-information originate metric-type '2'
+# set protocols ospf default-information originate route-map 'ingress'
+# set protocols ospf log-adjacency-changes 'detail'
+# set protocols ospf max-metric router-lsa 'administrative'
+# set protocols ospf max-metric router-lsa on-shutdown '10'
+# set protocols ospf max-metric router-lsa on-startup '10'
+# set protocols ospf mpls-te 'enable'
+# set protocols ospf mpls-te router-address '192.0.11.11'
+# set protocols ospf neighbor 192.0.11.12 poll-interval '10'
+# set protocols ospf neighbor 192.0.11.12 priority '2'
+# set protocols ospf parameters abr-type 'cisco'
+# set protocols ospf parameters 'opaque-lsa'
+# set protocols ospf parameters 'rfc1583-compatibility'
+# set protocols ospf parameters router-id '192.0.1.1'
+# set protocols ospf passive-interface 'eth1'
+# set protocols ospf passive-interface 'eth2'
+# set protocols ospf redistribute bgp metric '10'
+# set protocols ospf redistribute bgp metric-type '2'
# Using replaced
@@ -663,47 +870,89 @@ EXAMPLES = """
# -------------
#
# vyos@192# run show configuration commands | grep ospf
-# set protocols ospf area 0 network 192.168.0.0/24
-# set protocols ospf default-information originate always
-# set protocols ospf default-information originate metric 10
-# set protocols ospf default-information originate metric-type 2
-# set protocols ospf log-adjacency-changes details
-# set protocols ospf parameters router-id 10.1.1.1
-# set protocols ospf redistribute connected metric-type 2
-# set protocols ospf redistribute connected route-map CONNECT
-# set protocols ospfv3 area 0.0.0.0 range 2001:db8:1::/64
-# set protocols ospfv3 parameters router-id 192.168.1.1
-# set protocols ospfv3 redistribute connected
-#
-- name: Replace the provided configuration with the existing running configuration
- vyos_ospf_routes:
+# set protocols ospf area 2 area-type 'normal'
+# set protocols ospf area 2 authentication 'plaintext-password'
+# set protocols ospf area 2 shortcut 'enable'
+# set protocols ospf area 3 area-type 'nssa'
+# set protocols ospf area 4 area-type stub default-cost '20'
+# set protocols ospf area 4 network '192.0.2.0/24'
+# set protocols ospf area 4 range 192.0.3.0/24 cost '10'
+# set protocols ospf area 4 range 192.0.4.0/24 cost '12'
+# set protocols ospf auto-cost reference-bandwidth '2'
+# set protocols ospf default-information originate 'always'
+# set protocols ospf default-information originate metric '10'
+# set protocols ospf default-information originate metric-type '2'
+# set protocols ospf default-information originate route-map 'ingress'
+# set protocols ospf log-adjacency-changes 'detail'
+# set protocols ospf max-metric router-lsa 'administrative'
+# set protocols ospf max-metric router-lsa on-shutdown '10'
+# set protocols ospf max-metric router-lsa on-startup '10'
+# set protocols ospf mpls-te 'enable'
+# set protocols ospf mpls-te router-address '192.0.11.11'
+# set protocols ospf neighbor 192.0.11.12 poll-interval '10'
+# set protocols ospf neighbor 192.0.11.12 priority '2'
+# set protocols ospf parameters abr-type 'cisco'
+# set protocols ospf parameters 'opaque-lsa'
+# set protocols ospf parameters 'rfc1583-compatibility'
+# set protocols ospf parameters router-id '192.0.1.1'
+# set protocols ospf passive-interface 'eth1'
+# set protocols ospf passive-interface 'eth2'
+# set protocols ospf redistribute bgp metric '10'
+# set protocols ospf redistribute bgp metric-type '2'
+#
+- name: Replace ospfv2 routes attributes configuration.
+ vyos.vyos.vyos_ospfv2:
config:
- - afi: 'ipv4'
- ospf_area:
- - area: 0
- network: 192.168.0.0/24
- area_type:
- normal: True
- default_information:
- originate:
- always: true
- metric: 2
- metric_type: 10
- log_adjacency_changes: "details"
- parameters:
- router_id: 10.1.1.1
- redistribute:
- - route_type: 'static'
- metric_type: 2
- route_map: 'STATIC'
- - afi: 'ipv6'
- ospf_area:
- - area: 0.0.0.0
- range: 2001:db8:1::/64
- parameters:
- router-id 192.168.1.1
- redistribute:
- - route_type: 'connected'
+ log_adjacency_changes: 'detail'
+ max_metric:
+ router_lsa:
+ administrative: true
+ on_shutdown: 10
+ on_startup: 10
+ default_information:
+ originate:
+ always: true
+ metric: 10
+ metric_type: 2
+ route_map: 'ingress'
+ mpls_te:
+ enabled: true
+ router_address: '192.0.22.22'
+ auto_cost:
+ reference_bandwidth: 2
+ neighbor:
+ - neighbor_id: '192.0.11.12'
+ poll_interval: 10
+ priority: 2
+ redistribute:
+ - route_type: 'bgp'
+ metric: 10
+ metric_type: 2
+ passive_interface:
+ - 'eth1'
+ parameters:
+ router_id: '192.0.1.1'
+ opaque_lsa: true
+ rfc1583_compatibility: true
+ abr_type: 'cisco'
+ areas:
+ - area_id: '2'
+ area_type:
+ normal: true
+ authentication: "plaintext-password"
+ shortcut: 'enable'
+ - area_id: '4'
+ area_type:
+ stub:
+ default_cost: 20
+ network:
+ - address: '192.0.2.0/24'
+ - address: '192.0.12.0/24'
+ - address: '192.0.22.0/24'
+ - address: '192.0.32.0/24'
+ range:
+ - address: '192.0.42.0/24'
+ cost: 10
state: replaced
#
#
@@ -711,608 +960,968 @@ EXAMPLES = """
# Module Execution Result
# -------------------------
#
-# before": [
-# {
-# {
-# "afi": "ipv4",
-# "ospf_area":[
-# {
-# "area": "0",
-# "network": "192.168.0.0/24"
-# }
-# ],
-# "default_information":
-# {
-# "originate":
-# {
-# always: true,
-# metric: 2,
-# metric_type: 10
-# }
-# },
-# "log_adjacency_changes": "details"
-# "parameters":
-# {
-# "router_id": "10.1.1.1"
-# },
-# "redistribute":[
-# {
-# "route_type": "connetced",
-# "metric_type": 2
-# "route_map": "CONNECT"
-# }
-# ]
-# },
-# {
-# "afi": "ipv6",
-# "ospf_area":[
-# {
-# "area": "0.0.0.0",
-# }
-# ],
-# "range": "2001:db8:1::/64",
-# "parameters":
-# {
-# "router_id": "192.168.1.1"
-# },
-# "redistribute":
-# [
-# {
-# "route_type": "connetced",
-# }
-# ]
-# }
-# ]
-#
-# "commands": [
-# "delete protocols ospf redistribute connected",
-# "set protocols ospf area 0 area_type normal",
-# "set protocols ospf redistribute static metric-type 2",
-# "set protocols ospf redistribute static route-map CONNECT"
-# ]
-#
-# "after": [
-# {
-# {
-# "afi": "ipv4",
-# "ospf_area":[
-# {
-# "area": "0",
-# "area_type":
-# {
-# normal: true
-# }
-# "network": "192.168.0.0/24"
-# }
-# ],
-# "default_information":
-# {
-# "originate":
-# {
-# always: true,
-# metric: 2,
-# metric_type: 10
-# }
-# },
-# "log_adjacency_changes": "details"
-# "parameters":
-# {
-# "router_id": "10.1.1.1"
-# },
-# "redistribute":[
-# {
-# "route_type": "static",
-# "metric_type": 2
-# "route_map": "STATIC"
-# }
-# ]
-# },
-# {
-# "afi": "ipv6",
-# "ospf_area":[
-# {
-# "area": "0.0.0.0",
-# }
-# ],
-# "range": "2001:db8:1::/64",
-# "parameters":
-# {
-# "router_id": "192.168.1.1"
-# },
-# "redistribute":
-# [
-# {
-# "route_type": "connected",
-# }
-# ]
+# "before": {
+# "areas": [
+# {
+# "area_id": "2",
+# "area_type": {
+# "normal": true
+# },
+# "authentication": "plaintext-password",
+# "shortcut": "enable"
+# },
+# {
+# "area_id": "3",
+# "area_type": {
+# "nssa": {
+# "set": true
+# }
# }
+# },
+# {
+# "area_id": "4",
+# "area_type": {
+# "stub": {
+# "default_cost": 20,
+# "set": true
+# }
+# },
+# "network": [
+# {
+# "address": "192.0.2.0/24"
+# }
+# ],
+# "range": [
+# {
+# "address": "192.0.3.0/24",
+# "cost": 10
+# },
+# {
+# "address": "192.0.4.0/24",
+# "cost": 12
+# }
+# ]
+# }
+# ],
+# "auto_cost": {
+# "reference_bandwidth": 2
+# },
+# "default_information": {
+# "originate": {
+# "always": true,
+# "metric": 10,
+# "metric_type": 2,
+# "route_map": "ingress"
+# }
+# },
+# "log_adjacency_changes": "detail",
+# "max_metric": {
+# "router_lsa": {
+# "administrative": true,
+# "on_shutdown": 10,
+# "on_startup": 10
+# }
+# },
+# "mpls_te": {
+# "enabled": true,
+# "router_address": "192.0.11.11"
+# },
+# "neighbor": [
+# {
+# "neighbor_id": "192.0.11.12",
+# "poll_interval": 10,
+# "priority": 2
+# }
+# ],
+# "parameters": {
+# "abr_type": "cisco",
+# "opaque_lsa": true,
+# "rfc1583_compatibility": true,
+# "router_id": "192.0.1.1"
+# },
+# "passive_interface": [
+# "eth2",
+# "eth1"
+# ],
+# "redistribute": [
+# {
+# "metric": 10,
+# "metric_type": 2,
+# "route_type": "bgp"
+# }
+# ]
+# }
+#
+# "commands": [
+# "delete protocols ospf passive-interface eth2",
+# "delete protocols ospf area 3",
+# "delete protocols ospf area 4 range 192.0.3.0/24 cost",
+# "delete protocols ospf area 4 range 192.0.3.0/24",
+# "delete protocols ospf area 4 range 192.0.4.0/24 cost",
+# "delete protocols ospf area 4 range 192.0.4.0/24",
+# "set protocols ospf mpls-te router-address '192.0.22.22'",
+# "set protocols ospf area 4 range 192.0.42.0/24 cost 10",
+# "set protocols ospf area 4 range 192.0.42.0/24",
+# "set protocols ospf area 4 network 192.0.12.0/24",
+# "set protocols ospf area 4 network 192.0.22.0/24",
+# "set protocols ospf area 4 network 192.0.32.0/24"
# ]
#
+# "after": {
+# "areas": [
+# {
+# "area_id": "2",
+# "area_type": {
+# "normal": true
+# },
+# "authentication": "plaintext-password",
+# "shortcut": "enable"
+# },
+# {
+# "area_id": "4",
+# "area_type": {
+# "stub": {
+# "default_cost": 20,
+# "set": true
+# }
+# },
+# "network": [
+# {
+# "address": "192.0.12.0/24"
+# },
+# {
+# "address": "192.0.2.0/24"
+# },
+# {
+# "address": "192.0.22.0/24"
+# },
+# {
+# "address": "192.0.32.0/24"
+# }
+# ],
+# "range": [
+# {
+# "address": "192.0.42.0/24",
+# "cost": 10
+# }
+# ]
+# }
+# ],
+# "auto_cost": {
+# "reference_bandwidth": 2
+# },
+# "default_information": {
+# "originate": {
+# "always": true,
+# "metric": 10,
+# "metric_type": 2,
+# "route_map": "ingress"
+# }
+# },
+# "log_adjacency_changes": "detail",
+# "max_metric": {
+# "router_lsa": {
+# "administrative": true,
+# "on_shutdown": 10,
+# "on_startup": 10
+# }
+# },
+# "mpls_te": {
+# "enabled": true,
+# "router_address": "192.0.22.22"
+# },
+# "neighbor": [
+# {
+# "neighbor_id": "192.0.11.12",
+# "poll_interval": 10,
+# "priority": 2
+# }
+# ],
+# "parameters": {
+# "abr_type": "cisco",
+# "opaque_lsa": true,
+# "rfc1583_compatibility": true,
+# "router_id": "192.0.1.1"
+# },
+# "passive_interface": [
+# "eth1"
+# ],
+# "redistribute": [
+# {
+# "metric": 10,
+# "metric_type": 2,
+# "route_type": "bgp"
+# }
+# ]
+# }
+#
# After state:
# -------------
#
-# vyos@vyos:~$ show configuration commands| grep firewall
-# set protocols ospf area 0 network 192.168.0.0/24
-# set protocols ospf default-information originate always
-# set protocols ospf default-information originate metric 10
-# set protocols ospf default-information originate metric-type 2
-# set protocols ospf log-adjacency-changes details
-# set protocols ospf parameters router-id 10.1.1.1
-# set protocols ospf redistribute static metric-type 2
-# set protocols ospf redistribute static route-map CONNECT
-# set protocols ospfv3 area 0.0.0.0 range 2001:db8:2::/64
-# set protocols ospfv3 parameters router-id 192.168.2.1
-# set protocols ospfv3 redistribute connected
+# vyos@192# run show configuration commands | grep ospf
+# set protocols ospf area 2 area-type 'normal'
+# set protocols ospf area 2 authentication 'plaintext-password'
+# set protocols ospf area 2 shortcut 'enable'
+# set protocols ospf area 4 area-type stub default-cost '20'
+# set protocols ospf area 4 network '192.0.2.0/24'
+# set protocols ospf area 4 network '192.0.12.0/24'
+# set protocols ospf area 4 network '192.0.22.0/24'
+# set protocols ospf area 4 network '192.0.32.0/24'
+# set protocols ospf area 4 range 192.0.42.0/24 cost '10'
+# set protocols ospf auto-cost reference-bandwidth '2'
+# set protocols ospf default-information originate 'always'
+# set protocols ospf default-information originate metric '10'
+# set protocols ospf default-information originate metric-type '2'
+# set protocols ospf default-information originate route-map 'ingress'
+# set protocols ospf log-adjacency-changes 'detail'
+# set protocols ospf max-metric router-lsa 'administrative'
+# set protocols ospf max-metric router-lsa on-shutdown '10'
+# set protocols ospf max-metric router-lsa on-startup '10'
+# set protocols ospf mpls-te 'enable'
+# set protocols ospf mpls-te router-address '192.0.22.22'
+# set protocols ospf neighbor 192.0.11.12 poll-interval '10'
+# set protocols ospf neighbor 192.0.11.12 priority '2'
+# set protocols ospf parameters abr-type 'cisco'
+# set protocols ospf parameters 'opaque-lsa'
+# set protocols ospf parameters 'rfc1583-compatibility'
+# set protocols ospf parameters router-id '192.0.1.1'
+# set protocols ospf passive-interface 'eth1'
+# set protocols ospf redistribute bgp metric '10'
+# set protocols ospf redistribute bgp metric-type '2'
-# Using replaced
+# Using rendered
#
-# Before state:
-# -------------
#
-# vyos@192# run show configuration commands | grep ospf
-# set protocols ospf area 0 network 192.168.0.0/24
-# set protocols ospf default-information originate always
-# set protocols ospf default-information originate metric 10
-# set protocols ospf default-information originate metric-type 2
-# set protocols ospf log-adjacency-changes details
-# set protocols ospf parameters router-id 10.1.1.1
-# set protocols ospf redistribute connected metric-type 2
-# set protocols ospf redistribute connected route-map CONNECT
-# set protocols ospfv3 area 0.0.0.0 range 2001:db8:1::/64
-# set protocols ospfv3 parameters router-id 192.168.1.1
-# set protocols ospfv3 redistribute connected
-#
-- name: Replace the provided configuration with the existing running configuration
- vyos_ospf_routes:
+- name: Render the commands for provided configuration
+ vyos.vyos.vyos_ospfv2:
config:
- - afi: 'ipv4'
- ospf_area:
- - area: 0
- network: 192.168.0.0/24
- area_type:
- normal: True
- default_information:
- originate:
- always: true
- metric: 2
- metric_type: 10
- log_adjacency_changes: "details"
- parameters:
- router_id: 10.1.1.1
- redistribute:
- - route_type: 'static'
- metric_type: 2
- route_map: 'STATIC'
- - afi: 'ipv6'
- ospf_area:
- - area: 0.0.0.0
- range: 2001:db8:1::/64
- parameters:
- router-id 192.168.1.1
- redistribute:
- - route_type: 'connected'
- state: replaced
+ log_adjacency_changes: 'detail'
+ max_metric:
+ router_lsa:
+ administrative: true
+ on_shutdown: 10
+ on_startup: 10
+ default_information:
+ originate:
+ always: true
+ metric: 10
+ metric_type: 2
+ route_map: 'ingress'
+ mpls_te:
+ enabled: true
+ router_address: '192.0.11.11'
+ auto_cost:
+ reference_bandwidth: 2
+ neighbor:
+ - neighbor_id: '192.0.11.12'
+ poll_interval: 10
+ priority: 2
+ redistribute:
+ - route_type: 'bgp'
+ metric: 10
+ metric_type: 2
+ passive_interface:
+ - 'eth1'
+ - 'eth2'
+ parameters:
+ router_id: '192.0.1.1'
+ opaque_lsa: true
+ rfc1583_compatibility: true
+ abr_type: 'cisco'
+ areas:
+ - area_id: '2'
+ area_type:
+ normal: true
+ authentication: "plaintext-password"
+ shortcut: 'enable'
+ - area_id: '3'
+ area_type:
+ nssa:
+ set: true
+ - area_id: '4'
+ area_type:
+ stub:
+ default_cost: 20
+ network:
+ - address: '192.0.2.0/24'
+ range:
+ - address: '192.0.3.0/24'
+ cost: 10
+ - address: '192.0.4.0/24'
+ cost: 12
+ state: rendered
#
#
# -------------------------
# Module Execution Result
# -------------------------
#
-# before": [
-# {
-# {
-# "afi": "ipv4",
-# "ospf_area":[
-# {
-# "area": "0",
-# "network": "192.168.0.0/24"
-# }
-# ],
-# "default_information":
-# {
-# "originate":
-# {
-# always: true,
-# metric: 2,
-# metric_type: 10
-# }
-# },
-# "log_adjacency_changes": "details"
-# "parameters":
-# {
-# "router_id": "10.1.1.1"
-# },
-# "redistribute":[
-# {
-# "route_type": "connetced",
-# "metric_type": 2
-# "route_map": "CONNECT"
-# }
-# ]
-# },
-# {
-# "afi": "ipv6",
-# "ospf_area":[
-# {
-# "area": "0.0.0.0",
-# }
-# ],
-# "range": "2001:db8:1::/64",
-# "parameters":
-# {
-# "router_id": "192.168.1.1"
-# },
-# "redistribute":
-# [
-# {
-# "route_type": "connetced",
-# }
-# ]
-# }
-# ]
#
-# "commands": [
-# "delete protocols ospf redistribute connected",
-# "set protocols ospf area 0 area_type normal",
-# "set protocols ospf redistribute static metric-type 2",
-# "set protocols ospf redistribute static route-map CONNECT"
+# "rendered": [
+# [
+# "set protocols ospf mpls-te enable",
+# "set protocols ospf mpls-te router-address '192.0.11.11'",
+# "set protocols ospf redistribute bgp",
+# "set protocols ospf redistribute bgp metric-type 2",
+# "set protocols ospf redistribute bgp metric 10",
+# "set protocols ospf default-information originate metric-type 2",
+# "set protocols ospf default-information originate always",
+# "set protocols ospf default-information originate metric 10",
+# "set protocols ospf default-information originate route-map ingress",
+# "set protocols ospf auto-cost reference-bandwidth '2'",
+# "set protocols ospf parameters router-id '192.0.1.1'",
+# "set protocols ospf parameters opaque-lsa",
+# "set protocols ospf parameters abr-type 'cisco'",
+# "set protocols ospf parameters rfc1583-compatibility",
+# "set protocols ospf passive-interface eth1",
+# "set protocols ospf passive-interface eth2",
+# "set protocols ospf max-metric router-lsa on-shutdown 10",
+# "set protocols ospf max-metric router-lsa administrative",
+# "set protocols ospf max-metric router-lsa on-startup 10",
+# "set protocols ospf log-adjacency-changes 'detail'",
+# "set protocols ospf neighbor 192.0.11.12 priority 2",
+# "set protocols ospf neighbor 192.0.11.12 poll-interval 10",
+# "set protocols ospf neighbor 192.0.11.12",
+# "set protocols ospf area '2'",
+# "set protocols ospf area 2 authentication plaintext-password",
+# "set protocols ospf area 2 shortcut enable",
+# "set protocols ospf area 2 area-type normal",
+# "set protocols ospf area '3'",
+# "set protocols ospf area 3 area-type nssa",
+# "set protocols ospf area 4 range 192.0.3.0/24 cost 10",
+# "set protocols ospf area 4 range 192.0.3.0/24",
+# "set protocols ospf area 4 range 192.0.4.0/24 cost 12",
+# "set protocols ospf area 4 range 192.0.4.0/24",
+# "set protocols ospf area 4 area-type stub default-cost 20",
+# "set protocols ospf area '4'",
+# "set protocols ospf area 4 network 192.0.2.0/24"
# ]
+
+
+# Using parsed
+#
+#
+- name: Render the commands for provided configuration
+ vyos.vyos.vyos_ospfv2:
+ running_config:
+ "set protocols ospf area 2 area-type 'normal'
+ set protocols ospf area 2 authentication 'plaintext-password'
+ set protocols ospf area 2 shortcut 'enable'
+ set protocols ospf area 3 area-type 'nssa'
+ set protocols ospf area 4 area-type stub default-cost '20'
+ set protocols ospf area 4 network '192.0.2.0/24'
+ set protocols ospf area 4 range 192.0.3.0/24 cost '10'
+ set protocols ospf area 4 range 192.0.4.0/24 cost '12'
+ set protocols ospf auto-cost reference-bandwidth '2'
+ set protocols ospf default-information originate 'always'
+ set protocols ospf default-information originate metric '10'
+ set protocols ospf default-information originate metric-type '2'
+ set protocols ospf default-information originate route-map 'ingress'
+ set protocols ospf log-adjacency-changes 'detail'
+ set protocols ospf max-metric router-lsa 'administrative'
+ set protocols ospf max-metric router-lsa on-shutdown '10'
+ set protocols ospf max-metric router-lsa on-startup '10'
+ set protocols ospf mpls-te 'enable'
+ set protocols ospf mpls-te router-address '192.0.11.11'
+ set protocols ospf neighbor 192.0.11.12 poll-interval '10'
+ set protocols ospf neighbor 192.0.11.12 priority '2'
+ set protocols ospf parameters abr-type 'cisco'
+ set protocols ospf parameters 'opaque-lsa'
+ set protocols ospf parameters 'rfc1583-compatibility'
+ set protocols ospf parameters router-id '192.0.1.1'
+ set protocols ospf passive-interface 'eth1'
+ set protocols ospf passive-interface 'eth2'
+ set protocols ospf redistribute bgp metric '10'
+ set protocols ospf redistribute bgp metric-type '2'"
+ state: parsed
#
-# "after": [
-# {
-# {
-# "afi": "ipv4",
-# "ospf_area":[
-# {
-# "area": "0",
-# "area_type":
-# {
-# normal: true
-# }
-# "network": "192.168.0.0/24"
-# }
-# ],
-# "default_information":
-# {
-# "originate":
-# {
-# always: true,
-# metric: 2,
-# metric_type: 10
-# }
-# },
-# "log_adjacency_changes": "details"
-# "parameters":
-# {
-# "router_id": "10.1.1.1"
-# },
-# "redistribute":[
-# {
-# "route_type": "static",
-# "metric_type": 2
-# "route_map": "STATIC"
-# }
-# ]
-# },
-# {
-# "afi": "ipv6",
-# "ospf_area":[
-# {
-# "area": "0.0.0.0",
-# }
-# ],
-# "range": "2001:db8:1::/64",
-# "parameters":
-# {
-# "router_id": "192.168.1.1"
-# },
-# "redistribute":
-# [
-# {
-# "route_type": "connected",
-# }
-# ]
-# }
-# ]
#
-# After state:
-# -------------
+# -------------------------
+# Module Execution Result
+# -------------------------
+#
#
-# vyos@vyos:~$ show configuration commands| grep firewall
-# set protocols ospf area 0 network 192.168.0.0/24
-# set protocols ospf default-information originate always
-# set protocols ospf default-information originate metric 10
-# set protocols ospf default-information originate metric-type 2
-# set protocols ospf log-adjacency-changes details
-# set protocols ospf parameters router-id 10.1.1.1
-# set protocols ospf redistribute static metric-type 2
-# set protocols ospf redistribute static route-map CONNECT
-# set protocols ospfv3 area 0.0.0.0 range 2001:db8:2::/64
-# set protocols ospfv3 parameters router-id 192.168.2.1
-# set protocols ospfv3 redistribute connected
+# "parsed": {
+# "areas": [
+# {
+# "area_id": "2",
+# "area_type": {
+# "normal": true
+# },
+# "authentication": "plaintext-password",
+# "shortcut": "enable"
+# },
+# {
+# "area_id": "3",
+# "area_type": {
+# "nssa": {
+# "set": true
+# }
+# }
+# },
+# {
+# "area_id": "4",
+# "area_type": {
+# "stub": {
+# "default_cost": 20,
+# "set": true
+# }
+# },
+# "network": [
+# {
+# "address": "192.0.2.0/24"
+# }
+# ],
+# "range": [
+# {
+# "address": "192.0.3.0/24",
+# "cost": 10
+# },
+# {
+# "address": "192.0.4.0/24",
+# "cost": 12
+# }
+# ]
+# }
+# ],
+# "auto_cost": {
+# "reference_bandwidth": 2
+# },
+# "default_information": {
+# "originate": {
+# "always": true,
+# "metric": 10,
+# "metric_type": 2,
+# "route_map": "ingress"
+# }
+# },
+# "log_adjacency_changes": "detail",
+# "max_metric": {
+# "router_lsa": {
+# "administrative": true,
+# "on_shutdown": 10,
+# "on_startup": 10
+# }
+# },
+# "mpls_te": {
+# "enabled": true,
+# "router_address": "192.0.11.11"
+# },
+# "neighbor": [
+# {
+# "neighbor_id": "192.0.11.12",
+# "poll_interval": 10,
+# "priority": 2
+# }
+# ],
+# "parameters": {
+# "abr_type": "cisco",
+# "opaque_lsa": true,
+# "rfc1583_compatibility": true,
+# "router_id": "192.0.1.1"
+# },
+# "passive_interface": [
+# "eth2",
+# "eth1"
+# ],
+# "redistribute": [
+# {
+# "metric": 10,
+# "metric_type": 2,
+# "route_type": "bgp"
+# }
+# ]
+# }
+# }
-# Using replaced
+# Using gathered
#
# Before state:
# -------------
#
# vyos@192# run show configuration commands | grep ospf
-# set protocols ospf area 0 network 192.168.0.0/24
-# set protocols ospf default-information originate always
-# set protocols ospf default-information originate metric 10
-# set protocols ospf default-information originate metric-type 2
-# set protocols ospf log-adjacency-changes details
-# set protocols ospf parameters router-id 10.1.1.1
-# set protocols ospf redistribute connected metric-type 2
-# set protocols ospf redistribute connected route-map CONNECT
-# set protocols ospfv3 area 0.0.0.0 range 2001:db8:1::/64
-# set protocols ospfv3 parameters router-id 192.168.1.1
-# set protocols ospfv3 redistribute connected
-#
-- name: Replace the provided configuration with the existing running configuration
- vyos_ospf_routes:
- config:
- - afi: 'ipv4'
- ospf_area:
- - area: 0
- network: 192.168.0.0/24
- area_type:
- normal: True
- default_information:
- originate:
- always: true
- metric: 2
- metric_type: 10
- log_adjacency_changes: "details"
- parameters:
- router_id: 10.1.1.1
- redistribute:
- - route_type: 'static'
- metric_type: 2
- route_map: 'STATIC'
- - afi: 'ipv6'
- ospf_area:
- - area: 0.0.0.0
- range: 2001:db8:1::/64
- parameters:
- router-id 192.168.1.1
- redistribute:
- - route_type: 'connected'
- state: replaced
+# set protocols ospf area 2 area-type 'normal'
+# set protocols ospf area 2 authentication 'plaintext-password'
+# set protocols ospf area 2 shortcut 'enable'
+# set protocols ospf area 3 area-type 'nssa'
+# set protocols ospf area 4 area-type stub default-cost '20'
+# set protocols ospf area 4 network '192.0.2.0/24'
+# set protocols ospf area 4 range 192.0.3.0/24 cost '10'
+# set protocols ospf area 4 range 192.0.4.0/24 cost '12'
+# set protocols ospf auto-cost reference-bandwidth '2'
+# set protocols ospf default-information originate 'always'
+# set protocols ospf default-information originate metric '10'
+# set protocols ospf default-information originate metric-type '2'
+# set protocols ospf default-information originate route-map 'ingress'
+# set protocols ospf log-adjacency-changes 'detail'
+# set protocols ospf max-metric router-lsa 'administrative'
+# set protocols ospf max-metric router-lsa on-shutdown '10'
+# set protocols ospf max-metric router-lsa on-startup '10'
+# set protocols ospf mpls-te 'enable'
+# set protocols ospf mpls-te router-address '192.0.11.11'
+# set protocols ospf neighbor 192.0.11.12 poll-interval '10'
+# set protocols ospf neighbor 192.0.11.12 priority '2'
+# set protocols ospf parameters abr-type 'cisco'
+# set protocols ospf parameters 'opaque-lsa'
+# set protocols ospf parameters 'rfc1583-compatibility'
+# set protocols ospf parameters router-id '192.0.1.1'
+# set protocols ospf passive-interface 'eth1'
+# set protocols ospf passive-interface 'eth2'
+# set protocols ospf redistribute bgp metric '10'
+# set protocols ospf redistribute bgp metric-type '2'
+#
+- name: Gather ospfv2 routes config with provided configurations
+ vyos.vyos.vyos_ospfv2:
+ config:
+ state: gathered
#
#
# -------------------------
# Module Execution Result
# -------------------------
#
-# before": [
-# {
-# {
-# "afi": "ipv4",
-# "ospf_area":[
-# {
-# "area": "0",
-# "network": "192.168.0.0/24"
-# }
-# ],
-# "default_information":
-# {
-# "originate":
-# {
-# always: true,
-# metric: 2,
-# metric_type: 10
-# }
-# },
-# "log_adjacency_changes": "details"
-# "parameters":
-# {
-# "router_id": "10.1.1.1"
-# },
-# "redistribute":[
-# {
-# "route_type": "connetced",
-# "metric_type": 2
-# "route_map": "CONNECT"
-# }
-# ]
-# },
-# {
-# "afi": "ipv6",
-# "ospf_area":[
-# {
-# "area": "0.0.0.0",
-# }
-# ],
-# "range": "2001:db8:1::/64",
-# "parameters":
-# {
-# "router_id": "192.168.1.1"
-# },
-# "redistribute":
-# [
-# {
-# "route_type": "connetced",
-# }
-# ]
-# }
-# ]
-#
-# "commands": [
-# "delete protocols ospf redistribute connected",
-# "set protocols ospf area 0 area_type normal",
-# "set protocols ospf redistribute static metric-type 2",
-# "set protocols ospf redistribute static route-map CONNECT"
-# ]
-#
-# "after": [
-# {
-# {
-# "afi": "ipv4",
-# "ospf_area":[
-# {
-# "area": "0",
-# "area_type":
-# {
-# normal: true
-# }
-# "network": "192.168.0.0/24"
-# }
-# ],
-# "default_information":
-# {
-# "originate":
-# {
-# always: true,
-# metric: 2,
-# metric_type: 10
-# }
-# },
-# "log_adjacency_changes": "details"
-# "parameters":
-# {
-# "router_id": "10.1.1.1"
-# },
-# "redistribute":[
-# {
-# "route_type": "static",
-# "metric_type": 2
-# "route_map": "STATIC"
-# }
-# ]
-# },
-# {
-# "afi": "ipv6",
-# "ospf_area":[
-# {
-# "area": "0.0.0.0",
-# }
-# ],
-# "range": "2001:db8:1::/64",
-# "parameters":
-# {
-# "router_id": "192.168.1.1"
-# },
-# "redistribute":
-# [
-# {
-# "route_type": "connected",
-# }
-# ]
+# "gathered": {
+# "areas": [
+# {
+# "area_id": "2",
+# "area_type": {
+# "normal": true
+# },
+# "authentication": "plaintext-password",
+# "shortcut": "enable"
+# },
+# {
+# "area_id": "3",
+# "area_type": {
+# "nssa": {
+# "set": true
+# }
# }
-# ]
+# },
+# {
+# "area_id": "4",
+# "area_type": {
+# "stub": {
+# "default_cost": 20,
+# "set": true
+# }
+# },
+# "network": [
+# {
+# "address": "192.0.2.0/24"
+# }
+# ],
+# "range": [
+# {
+# "address": "192.0.3.0/24",
+# "cost": 10
+# },
+# {
+# "address": "192.0.4.0/24",
+# "cost": 12
+# }
+# ]
+# }
+# ],
+# "auto_cost": {
+# "reference_bandwidth": 2
+# },
+# "default_information": {
+# "originate": {
+# "always": true,
+# "metric": 10,
+# "metric_type": 2,
+# "route_map": "ingress"
+# }
+# },
+# "log_adjacency_changes": "detail",
+# "max_metric": {
+# "router_lsa": {
+# "administrative": true,
+# "on_shutdown": 10,
+# "on_startup": 10
+# }
+# },
+# "mpls_te": {
+# "enabled": true,
+# "router_address": "192.0.11.11"
+# },
+# "neighbor": [
+# {
+# "neighbor_id": "192.0.11.12",
+# "poll_interval": 10,
+# "priority": 2
+# }
+# ],
+# "parameters": {
+# "abr_type": "cisco",
+# "opaque_lsa": true,
+# "rfc1583_compatibility": true,
+# "router_id": "192.0.1.1"
+# },
+# "passive_interface": [
+# "eth2",
+# "eth1"
+# ],
+# "redistribute": [
+# {
+# "metric": 10,
+# "metric_type": 2,
+# "route_type": "bgp"
+# }
+# ]
+# }
#
# After state:
# -------------
#
-# vyos@vyos:~$ show configuration commands| grep firewall
-# set protocols ospf area 0 network 192.168.0.0/24
-# set protocols ospf default-information originate always
-# set protocols ospf default-information originate metric 10
-# set protocols ospf default-information originate metric-type 2
-# set protocols ospf log-adjacency-changes details
-# set protocols ospf parameters router-id 10.1.1.1
-# set protocols ospf redistribute static metric-type 2
-# set protocols ospf redistribute static route-map CONNECT
-# set protocols ospfv3 area 0.0.0.0 range 2001:db8:2::/64
-# set protocols ospfv3 parameters router-id 192.168.2.1
-# set protocols ospfv3 redistribute connected
+# vyos@192# run show configuration commands | grep ospf
+# set protocols ospf area 2 area-type 'normal'
+# set protocols ospf area 2 authentication 'plaintext-password'
+# set protocols ospf area 2 shortcut 'enable'
+# set protocols ospf area 3 area-type 'nssa'
+# set protocols ospf area 4 area-type stub default-cost '20'
+# set protocols ospf area 4 network '192.0.2.0/24'
+# set protocols ospf area 4 range 192.0.3.0/24 cost '10'
+# set protocols ospf area 4 range 192.0.4.0/24 cost '12'
+# set protocols ospf auto-cost reference-bandwidth '2'
+# set protocols ospf default-information originate 'always'
+# set protocols ospf default-information originate metric '10'
+# set protocols ospf default-information originate metric-type '2'
+# set protocols ospf default-information originate route-map 'ingress'
+# set protocols ospf log-adjacency-changes 'detail'
+# set protocols ospf max-metric router-lsa 'administrative'
+# set protocols ospf max-metric router-lsa on-shutdown '10'
+# set protocols ospf max-metric router-lsa on-startup '10'
+# set protocols ospf mpls-te 'enable'
+# set protocols ospf mpls-te router-address '192.0.11.11'
+# set protocols ospf neighbor 192.0.11.12 poll-interval '10'
+# set protocols ospf neighbor 192.0.11.12 priority '2'
+# set protocols ospf parameters abr-type 'cisco'
+# set protocols ospf parameters 'opaque-lsa'
+# set protocols ospf parameters 'rfc1583-compatibility'
+# set protocols ospf parameters router-id '192.0.1.1'
+# set protocols ospf passive-interface 'eth1'
+# set protocols ospf passive-interface 'eth2'
+# set protocols ospf redistribute bgp metric '10'
+# set protocols ospf redistribute bgp metric-type '2'
# Using deleted
#
-# Before state:
+# Before state
# -------------
#
# vyos@192# run show configuration commands | grep ospf
-# set protocols ospf area 0 network 192.168.0.0/24
-# set protocols ospf default-information originate always
-# set protocols ospf default-information originate metric 10
-# set protocols ospf default-information originate metric-type 2
-# set protocols ospf log-adjacency-changes details
-# set protocols ospf parameters router-id 10.1.1.1
-# set protocols ospf redistribute connected metric-type 2
-# set protocols ospf redistribute connected route-map CONNECT
-# set protocols ospfv3 area 0.0.0.0 range 2001:db8:1::/64
-# set protocols ospfv3 parameters router-id 192.168.1.1
-# set protocols ospfv3 redistribute connected
-#
-- name: Delete all the configuration
- vyos_ospf_routes:
+# set protocols ospf area 2 area-type 'normal'
+# set protocols ospf area 2 authentication 'plaintext-password'
+# set protocols ospf area 2 shortcut 'enable'
+# set protocols ospf area 3 area-type 'nssa'
+# set protocols ospf area 4 area-type stub default-cost '20'
+# set protocols ospf area 4 network '192.0.2.0/24'
+# set protocols ospf area 4 range 192.0.3.0/24 cost '10'
+# set protocols ospf area 4 range 192.0.4.0/24 cost '12'
+# set protocols ospf auto-cost reference-bandwidth '2'
+# set protocols ospf default-information originate 'always'
+# set protocols ospf default-information originate metric '10'
+# set protocols ospf default-information originate metric-type '2'
+# set protocols ospf default-information originate route-map 'ingress'
+# set protocols ospf log-adjacency-changes 'detail'
+# set protocols ospf max-metric router-lsa 'administrative'
+# set protocols ospf max-metric router-lsa on-shutdown '10'
+# set protocols ospf max-metric router-lsa on-startup '10'
+# set protocols ospf mpls-te 'enable'
+# set protocols ospf mpls-te router-address '192.0.11.11'
+# set protocols ospf neighbor 192.0.11.12 poll-interval '10'
+# set protocols ospf neighbor 192.0.11.12 priority '2'
+# set protocols ospf parameters abr-type 'cisco'
+# set protocols ospf parameters 'opaque-lsa'
+# set protocols ospf parameters 'rfc1583-compatibility'
+# set protocols ospf parameters router-id '192.0.1.1'
+# set protocols ospf passive-interface 'eth1'
+# set protocols ospf passive-interface 'eth2'
+# set protocols ospf redistribute bgp metric '10'
+# set protocols ospf redistribute bgp metric-type '2'
+#
+- name: Delete single attributes of ospfv2 routes.
+ vyos.vyos.vyos_ospfv2:
config:
+ log_adjacency_changes: 'detail'
+ max_metric:
+ default_information:
+ mpls_te:
+ neighbor:
+ redistribute:
+ parameters:
+ passive_interface:
+ areas:
state: deleted
#
#
-# -------------------------
-# Module Execution Result
-# -------------------------
-#
-# before": [
-# {
-# {
-# "afi": "ipv4",
-# "ospf_area":[
-# {
-# "area": "0",
-# "network": "192.168.0.0/24"
-# }
-# ],
-# "default_information":
-# {
-# "originate":
-# {
-# always: true,
-# metric: 2,
-# metric_type: 10
-# }
-# },
-# "log_adjacency_changes": "details"
-# "parameters":
-# {
-# "router_id": "10.1.1.1"
-# },
-# "redistribute":[
-# {
-# "route_type": "connetced",
-# "metric_type": 2
-# "route_map": "CONNECT"
-# }
-# ]
-# },
-# {
-# "afi": "ipv6",
-# "ospf_area":[
-# {
-# "area": "0.0.0.0",
-# }
-# ],
-# "range": "2001:db8:1::/64",
-# "parameters":
-# {
-# "router_id": "192.168.1.1"
-# },
-# "redistribute":
-# [
-# {
-# "route_type": "connetced",
-# }
-# ]
+# ------------------------
+# Module Execution Results
+# ------------------------
+#
+# "before": {
+# "areas": [
+# {
+# "area_id": "2",
+# "area_type": {
+# "normal": true
+# },
+# "authentication": "plaintext-password",
+# "shortcut": "enable"
+# },
+# {
+# "area_id": "3",
+# "area_type": {
+# "nssa": {
+# "set": true
+# }
# }
-# ]
-#
-# "commands": [
-# "delete protocols ospf",
-# "delete protocols ospfv3",
+# },
+# {
+# "area_id": "4",
+# "area_type": {
+# "stub": {
+# "default_cost": 20,
+# "set": true
+# }
+# },
+# "network": [
+# {
+# "address": "192.0.2.0/24"
+# }
+# ],
+# "range": [
+# {
+# "address": "192.0.3.0/24",
+# "cost": 10
+# },
+# {
+# "address": "192.0.4.0/24",
+# "cost": 12
+# }
+# ]
+# }
+# ],
+# "auto_cost": {
+# "reference_bandwidth": 2
+# },
+# "default_information": {
+# "originate": {
+# "always": true,
+# "metric": 10,
+# "metric_type": 2,
+# "route_map": "ingress"
+# }
+# },
+# "log_adjacency_changes": "detail",
+# "max_metric": {
+# "router_lsa": {
+# "administrative": true,
+# "on_shutdown": 10,
+# "on_startup": 10
+# }
+# },
+# "mpls_te": {
+# "enabled": true,
+# "router_address": "192.0.11.11"
+# },
+# "neighbor": [
+# {
+# "neighbor_id": "192.0.11.12",
+# "poll_interval": 10,
+# "priority": 2
+# }
+# ],
+# "parameters": {
+# "abr_type": "cisco",
+# "opaque_lsa": true,
+# "rfc1583_compatibility": true,
+# "router_id": "192.0.1.1"
+# },
+# "passive_interface": [
+# "eth2",
+# "eth1"
+# ],
+# "redistribute": [
+# {
+# "metric": 10,
+# "metric_type": 2,
+# "route_type": "bgp"
+# }
+# ]
+# }
+# "commands": [
+# "delete protocols ospf mpls-te",
+# "delete protocols ospf redistribute",
+# "delete protocols ospf auto-cost",
+# "delete protocols ospf passive-interface",
+# "delete protocols ospf parameters",
+# "delete protocols ospf default-information",
+# "delete protocols ospf max-metric",
+# "delete protocols ospf log-adjacency-changes",
+# "delete protocols ospf neighbor",
+# "delete protocols ospf area 2",
+# "delete protocols ospf area 3",
+# "delete protocols ospf area 4",
+# "delete protocols ospf area"
# ]
#
# "after": []
+# After state
+# ------------
+# vyos@192# run show configuration commands | grep ospf
+
+
+# Using deleted
#
-# After state:
+# Before state
# -------------
#
-# vyos@vyos:~$ show configuration commands| grep firewall
+# vyos@192# run show configuration commands | grep ospf
+# set protocols ospf area 2 area-type 'normal'
+# set protocols ospf area 2 authentication 'plaintext-password'
+# set protocols ospf area 2 shortcut 'enable'
+# set protocols ospf area 3 area-type 'nssa'
+# set protocols ospf area 4 area-type stub default-cost '20'
+# set protocols ospf area 4 network '192.0.2.0/24'
+# set protocols ospf area 4 range 192.0.3.0/24 cost '10'
+# set protocols ospf area 4 range 192.0.4.0/24 cost '12'
+# set protocols ospf auto-cost reference-bandwidth '2'
+# set protocols ospf default-information originate 'always'
+# set protocols ospf default-information originate metric '10'
+# set protocols ospf default-information originate metric-type '2'
+# set protocols ospf default-information originate route-map 'ingress'
+# set protocols ospf log-adjacency-changes 'detail'
+# set protocols ospf max-metric router-lsa 'administrative'
+# set protocols ospf max-metric router-lsa on-shutdown '10'
+# set protocols ospf max-metric router-lsa on-startup '10'
+# set protocols ospf mpls-te 'enable'
+# set protocols ospf mpls-te router-address '192.0.11.11'
+# set protocols ospf neighbor 192.0.11.12 poll-interval '10'
+# set protocols ospf neighbor 192.0.11.12 priority '2'
+# set protocols ospf parameters abr-type 'cisco'
+# set protocols ospf parameters 'opaque-lsa'
+# set protocols ospf parameters 'rfc1583-compatibility'
+# set protocols ospf parameters router-id '192.0.1.1'
+# set protocols ospf passive-interface 'eth1'
+# set protocols ospf passive-interface 'eth2'
+# set protocols ospf redistribute bgp metric '10'
+# set protocols ospf redistribute bgp metric-type '2'
+#
+- name: Delete attributes of ospfv2 routes.
+ vyos.vyos.vyos_ospfv2:
+ config:
+ state: deleted
+#
+#
+# ------------------------
+# Module Execution Results
+# ------------------------
+#
+# "before": {
+# "areas": [
+# {
+# "area_id": "2",
+# "area_type": {
+# "normal": true
+# },
+# "authentication": "plaintext-password",
+# "shortcut": "enable"
+# },
+# {
+# "area_id": "3",
+# "area_type": {
+# "nssa": {
+# "set": true
+# }
+# }
+# },
+# {
+# "area_id": "4",
+# "area_type": {
+# "stub": {
+# "default_cost": 20,
+# "set": true
+# }
+# },
+# "network": [
+# {
+# "address": "192.0.2.0/24"
+# }
+# ],
+# "range": [
+# {
+# "address": "192.0.3.0/24",
+# "cost": 10
+# },
+# {
+# "address": "192.0.4.0/24",
+# "cost": 12
+# }
+# ]
+# }
+# ],
+# "auto_cost": {
+# "reference_bandwidth": 2
+# },
+# "default_information": {
+# "originate": {
+# "always": true,
+# "metric": 10,
+# "metric_type": 2,
+# "route_map": "ingress"
+# }
+# },
+# "log_adjacency_changes": "detail",
+# "max_metric": {
+# "router_lsa": {
+# "administrative": true,
+# "on_shutdown": 10,
+# "on_startup": 10
+# }
+# },
+# "mpls_te": {
+# "enabled": true,
+# "router_address": "192.0.11.11"
+# },
+# "neighbor": [
+# {
+# "neighbor_id": "192.0.11.12",
+# "poll_interval": 10,
+# "priority": 2
+# }
+# ],
+# "parameters": {
+# "abr_type": "cisco",
+# "opaque_lsa": true,
+# "rfc1583_compatibility": true,
+# "router_id": "192.0.1.1"
+# },
+# "passive_interface": [
+# "eth2",
+# "eth1"
+# ],
+# "redistribute": [
+# {
+# "metric": 10,
+# "metric_type": 2,
+# "route_type": "bgp"
+# }
+# ]
+# }
+# "commands": [
+# "delete protocols ospf"
+# ]
+#
+# "after": []
+# After state
+# ------------
+# vyos@192# run show configuration commands | grep ospf
"""
@@ -1320,12 +1929,14 @@ RETURN = """
before:
description: The configuration prior to the model invocation.
returned: always
+ type: dict
sample: >
The configuration returned will always be in the same format
of the parameters above.
after:
description: The resulting configuration model invocation.
returned: when changed
+ type: dict
sample: >
The configuration returned will always be in the same format
of the parameters above.
@@ -1333,7 +1944,8 @@ commands:
description: The set of commands pushed to the remote device.
returned: always
type: list
- sample: ['command 1', 'command 2', 'command 3']
+ sample: ['set protocols ospf parameters router-id 192.0.1.1',
+ 'set protocols ospf passive-interface 'eth1']
"""
diff --git a/tests/integration/targets/vyos_ospfv2/defaults/main.yaml b/tests/integration/targets/vyos_ospfv2/defaults/main.yaml
new file mode 100644
index 0000000..852a6be
--- /dev/null
+++ b/tests/integration/targets/vyos_ospfv2/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+testcase: '[^_].*'
+test_items: []
diff --git a/tests/integration/targets/vyos_ospfv2/meta/main.yaml b/tests/integration/targets/vyos_ospfv2/meta/main.yaml
new file mode 100644
index 0000000..7413320
--- /dev/null
+++ b/tests/integration/targets/vyos_ospfv2/meta/main.yaml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - prepare_vyos_tests
diff --git a/tests/integration/targets/vyos_ospfv2/tasks/cli.yaml b/tests/integration/targets/vyos_ospfv2/tasks/cli.yaml
new file mode 100644
index 0000000..93eb2fe
--- /dev/null
+++ b/tests/integration/targets/vyos_ospfv2/tasks/cli.yaml
@@ -0,0 +1,19 @@
+---
+- name: Collect all cli test cases
+ find:
+ paths: '{{ role_path }}/tests/cli'
+ patterns: '{{ testcase }}.yaml'
+ use_regex: true
+ register: test_cases
+ delegate_to: localhost
+
+- name: Set test_items
+ set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
+
+- name: Run test case (connection=ansible.netcommon.network_cli)
+ include: '{{ test_case_to_run }}'
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
+ with_items: '{{ test_items }}'
+ loop_control:
+ loop_var: test_case_to_run
diff --git a/tests/integration/targets/vyos_ospfv2/tasks/main.yaml b/tests/integration/targets/vyos_ospfv2/tasks/main.yaml
new file mode 100644
index 0000000..a3db933
--- /dev/null
+++ b/tests/integration/targets/vyos_ospfv2/tasks/main.yaml
@@ -0,0 +1,4 @@
+---
+- include: cli.yaml
+ tags:
+ - cli
diff --git a/tests/integration/targets/vyos_ospfv2/tests/cli/_parsed_config.cfg b/tests/integration/targets/vyos_ospfv2/tests/cli/_parsed_config.cfg
new file mode 100644
index 0000000..9cc720b
--- /dev/null
+++ b/tests/integration/targets/vyos_ospfv2/tests/cli/_parsed_config.cfg
@@ -0,0 +1,29 @@
+set protocols ospf area 2 area-type 'normal'
+set protocols ospf area 2 authentication 'plaintext-password'
+set protocols ospf area 2 shortcut 'enable'
+set protocols ospf area 3 area-type 'nssa'
+set protocols ospf area 4 area-type stub default-cost '20'
+set protocols ospf area 4 network '192.0.2.0/24'
+set protocols ospf area 4 range 192.0.3.0/24 cost '10'
+set protocols ospf area 4 range 192.0.4.0/24 cost '12'
+set protocols ospf auto-cost reference-bandwidth '2'
+set protocols ospf default-information originate 'always'
+set protocols ospf default-information originate metric '10'
+set protocols ospf default-information originate metric-type '2'
+set protocols ospf default-information originate route-map 'ingress'
+set protocols ospf log-adjacency-changes 'detail'
+set protocols ospf max-metric router-lsa 'administrative'
+set protocols ospf max-metric router-lsa on-shutdown '10'
+set protocols ospf max-metric router-lsa on-startup '10'
+set protocols ospf mpls-te 'enable'
+set protocols ospf mpls-te router-address '192.0.11.11'
+set protocols ospf neighbor 192.0.11.12 poll-interval '10'
+set protocols ospf neighbor 192.0.11.12 priority '2'
+set protocols ospf parameters abr-type 'cisco'
+set protocols ospf parameters 'opaque-lsa'
+set protocols ospf parameters 'rfc1583-compatibility'
+set protocols ospf parameters router-id '192.0.1.1'
+set protocols ospf passive-interface 'eth1'
+set protocols ospf passive-interface 'eth2'
+set protocols ospf redistribute bgp metric '10'
+set protocols ospf redistribute bgp metric-type '2'
diff --git a/tests/integration/targets/vyos_ospfv2/tests/cli/_populate.yaml b/tests/integration/targets/vyos_ospfv2/tests/cli/_populate.yaml
new file mode 100644
index 0000000..9f358d5
--- /dev/null
+++ b/tests/integration/targets/vyos_ospfv2/tests/cli/_populate.yaml
@@ -0,0 +1,35 @@
+---
+- name: Setup
+ vars:
+ lines: "set protocols ospf mpls-te 'enable' \n
+ set protocols ospf mpls-te router-address '192.0.11.11' \n
+ set protocols ospf redistribute bgp metric-type '2' \n
+ set protocols ospf redistribute bgp metric '10'\n
+ set protocols ospf default-information originate metric-type '2' \n
+ set protocols ospf default-information originate 'always' \n
+ set protocols ospf default-information originate metric '10' \n
+ set protocols ospf default-information originate route-map 'ingress' \n
+ set protocols ospf auto-cost reference-bandwidth '2' \n
+ set protocols ospf parameters router-id '192.0.1.1' \n
+ set protocols ospf parameters 'opaque-lsa' \n
+ set protocols ospf parameters abr-type 'cisco' \n
+ set protocols ospf parameters 'rfc1583-compatibility' \n
+ set protocols ospf passive-interface 'eth1' \n
+ set protocols ospf passive-interface 'eth2' \n
+ set protocols ospf max-metric router-lsa on-shutdown '10' \n
+ set protocols ospf max-metric router-lsa 'administrative' \n
+ set protocols ospf max-metric router-lsa on-startup '10' \n
+ set protocols ospf log-adjacency-changes 'detail' \n
+ set protocols ospf neighbor 192.0.11.12 priority '2' \n
+ set protocols ospf neighbor 192.0.11.12 poll-interval '10' \n
+ set protocols ospf area 2 authentication 'plaintext-password' \n
+ set protocols ospf area 2 shortcut 'enable' \n
+ set protocols ospf area 2 area-type 'normal' \n
+ set protocols ospf area 3 area-type 'nssa' \n
+ set protocols ospf area 4 range 192.0.3.0/24 cost '10' \n
+ set protocols ospf area 4 range 192.0.4.0/24 cost '12' \n
+ set protocols ospf area 4 area-type stub default-cost '20' \n
+ set protocols ospf area 4 network '192.0.2.0/24'"
+
+ ansible.netcommon.cli_config:
+ config: '{{ lines }}'
diff --git a/tests/integration/targets/vyos_ospfv2/tests/cli/_remove_config.yaml b/tests/integration/targets/vyos_ospfv2/tests/cli/_remove_config.yaml
new file mode 100644
index 0000000..7360870
--- /dev/null
+++ b/tests/integration/targets/vyos_ospfv2/tests/cli/_remove_config.yaml
@@ -0,0 +1,6 @@
+---
+- name: Remove Config
+ vars:
+ lines: "delete protocols ospf\n"
+ ansible.netcommon.cli_config:
+ config: '{{ lines }}'
diff --git a/tests/integration/targets/vyos_ospfv2/tests/cli/delete_single.yaml b/tests/integration/targets/vyos_ospfv2/tests/cli/delete_single.yaml
new file mode 100644
index 0000000..150242a
--- /dev/null
+++ b/tests/integration/targets/vyos_ospfv2/tests/cli/delete_single.yaml
@@ -0,0 +1,57 @@
+---
+- debug:
+ msg: Start vyos_ospfv2 deleted integration tests ansible_connection={{
+ ansible_connection }}
+
+- include_tasks: _populate.yaml
+
+- block:
+
+ - name: Delete attributes of ospfv2.
+ register: result
+ vyos.vyos.vyos_ospfv2: &id001
+ config:
+ log_adjacency_changes: 'detail'
+ max_metric:
+ default_information:
+ mpls_te:
+ neighbor:
+ redistribute:
+ parameters:
+ passive_interface:
+ areas:
+ state: deleted
+
+ - name: Assert that the before dicts were correctly generated
+ assert:
+ that:
+ - "{{ populate == result['before'] }}"
+
+ - name: Assert that the correct set of commands were generated
+ assert:
+ that:
+ - "{{ deleted_single['commands'] | symmetric_difference(result['commands']) |length\
+ \ == 0 }}"
+
+ - name: Assert that the after dicts were correctly generated
+ assert:
+ that:
+ - "{{ deleted_single['after'] == result['after'] }}"
+
+ - name: Delete attributes of given interfaces (IDEMPOTENT)
+ register: result
+ vyos.vyos.vyos_ospfv2: *id001
+
+ - name: Assert that the previous task was idempotent
+ assert:
+ that:
+ - result.changed == false
+ - result.commands|length == 0
+
+ - name: Assert that the before dicts were correctly generated
+ assert:
+ that:
+ - "{{ deleted_single['after'] == result['before'] }}"
+ always:
+
+ - include_tasks: _remove_config.yaml
diff --git a/tests/integration/targets/vyos_ospfv2/tests/cli/deleted.yaml b/tests/integration/targets/vyos_ospfv2/tests/cli/deleted.yaml
new file mode 100644
index 0000000..a61f5a7
--- /dev/null
+++ b/tests/integration/targets/vyos_ospfv2/tests/cli/deleted.yaml
@@ -0,0 +1,48 @@
+---
+- debug:
+ msg: Start vyos_ospfv2 deleted integration tests ansible_connection={{
+ ansible_connection }}
+
+- include_tasks: _populate.yaml
+
+- block:
+
+ - name: Delete attributes of ospfv2.
+ register: result
+ vyos.vyos.vyos_ospfv2: &id001
+ config:
+ state: deleted
+
+ - name: Assert that the before dicts were correctly generated
+ assert:
+ that:
+ - "{{ populate == result['before'] }}"
+
+ - name: Assert that the correct set of commands were generated
+ assert:
+ that:
+ - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length\
+ \ == 0 }}"
+
+ - name: Assert that the after dicts were correctly generated
+ assert:
+ that:
+ - "{{ deleted['after'] == result['after'] }}"
+
+ - name: Delete attributes of given interfaces (IDEMPOTENT)
+ register: result
+ vyos.vyos.vyos_ospfv2: *id001
+
+ - name: Assert that the previous task was idempotent
+ assert:
+ that:
+ - result.changed == false
+ - result.commands|length == 0
+
+ - name: Assert that the before dicts were correctly generated
+ assert:
+ that:
+ - "{{ deleted['after'] == result['before'] }}"
+ always:
+
+ - include_tasks: _remove_config.yaml
diff --git a/tests/integration/targets/vyos_ospfv2/tests/cli/empty_config.yaml b/tests/integration/targets/vyos_ospfv2/tests/cli/empty_config.yaml
new file mode 100644
index 0000000..4566bf4
--- /dev/null
+++ b/tests/integration/targets/vyos_ospfv2/tests/cli/empty_config.yaml
@@ -0,0 +1,49 @@
+---
+- debug:
+ msg: START vyos_ospfv2 empty_config integration tests on connection={{
+ ansible_connection }}
+
+- name: Merged with empty config should give appropriate error message
+ register: result
+ ignore_errors: true
+ vyos.vyos.vyos_ospfv2:
+ config:
+ state: merged
+
+- assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state merged'
+
+- name: Replaced with empty config should give appropriate error message
+ register: result
+ ignore_errors: true
+ vyos.vyos.vyos_ospfv2:
+ config:
+ state: replaced
+
+- assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state replaced'
+
+- name: Parsed with empty running_config should give appropriate error message
+ register: result
+ ignore_errors: true
+ vyos.vyos.vyos_ospfv2:
+ running_config:
+ state: parsed
+
+- assert:
+ that:
+ - result.msg == 'value of running_config parameter must not be empty for state
+ parsed'
+
+- name: Rendered with empty config should give appropriate error message
+ register: result
+ ignore_errors: true
+ vyos.vyos.vyos_ospfv2:
+ config:
+ state: rendered
+
+- assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state rendered'
diff --git a/tests/integration/targets/vyos_ospfv2/tests/cli/gathered.yaml b/tests/integration/targets/vyos_ospfv2/tests/cli/gathered.yaml
new file mode 100644
index 0000000..22c378b
--- /dev/null
+++ b/tests/integration/targets/vyos_ospfv2/tests/cli/gathered.yaml
@@ -0,0 +1,33 @@
+---
+- debug:
+ msg: START vyos_ospfv2 gathered integration tests on connection={{
+ ansible_connection }}
+
+- include_tasks: _remove_config.yaml
+
+- include_tasks: _populate.yaml
+
+- block:
+
+ - name: Merge the provided configuration with the exisiting running configuration
+ register: result
+ vyos.vyos.vyos_ospfv2: &id001
+ config:
+ state: gathered
+
+ - name: Assert that gathered dicts was correctly generated
+ assert:
+ that:
+ - "{{ populate == result['gathered'] }}"
+
+ - name: Gather the existing running configuration (IDEMPOTENT)
+ register: result
+ vyos.vyos.vyos_ospfv2: *id001
+
+ - name: Assert that the previous task was idempotent
+ assert:
+ that:
+ - result['changed'] == false
+ always:
+
+ - include_tasks: _remove_config.yaml
diff --git a/tests/integration/targets/vyos_ospfv2/tests/cli/merged.yaml b/tests/integration/targets/vyos_ospfv2/tests/cli/merged.yaml
new file mode 100644
index 0000000..6a58bb5
--- /dev/null
+++ b/tests/integration/targets/vyos_ospfv2/tests/cli/merged.yaml
@@ -0,0 +1,101 @@
+---
+- debug:
+ msg: START vyos_ospfv2 merged integration tests on connection={{ ansible_connection
+ }}
+
+- include_tasks: _remove_config.yaml
+
+- block:
+
+ - name: Merge the provided configuration with the exisiting running configuration
+ register: result
+ vyos.vyos.vyos_ospfv2: &id001
+ config:
+ log_adjacency_changes: 'detail'
+ max_metric:
+ router_lsa:
+ administrative: true
+ on_shutdown: 10
+ on_startup: 10
+ default_information:
+ originate:
+ always: true
+ metric: 10
+ metric_type: 2
+ route_map: 'ingress'
+ mpls_te:
+ enabled: true
+ router_address: '192.0.11.11'
+ auto_cost:
+ reference_bandwidth: 2
+ neighbor:
+ - neighbor_id: '192.0.11.12'
+ poll_interval: 10
+ priority: 2
+ redistribute:
+ - route_type: 'bgp'
+ metric: 10
+ metric_type: 2
+ passive_interface:
+ - 'eth1'
+ - 'eth2'
+ parameters:
+ router_id: '192.0.1.1'
+ opaque_lsa: true
+ rfc1583_compatibility: true
+ abr_type: 'cisco'
+ areas:
+ - area_id: '2'
+ area_type:
+ normal: true
+ authentication: "plaintext-password"
+ shortcut: 'enable'
+ - area_id: '3'
+ area_type:
+ nssa:
+ set: true
+ - area_id: '4'
+ area_type:
+ stub:
+ default_cost: 20
+ network:
+ - address: '192.0.2.0/24'
+ range:
+ - address: '192.0.3.0/24'
+ cost: 10
+ - address: '192.0.4.0/24'
+ cost: 12
+ state: merged
+
+ - name: Assert that before dicts were correctly generated
+ assert:
+ that: "{{ merged['before'] == result['before'] }}"
+
+ - name: Assert that correct set of commands were generated
+ assert:
+ that:
+ - "{{ merged['commands'] | symmetric_difference(result['commands']) |length\
+ \ == 0 }}"
+
+ - name: Assert that after dicts was correctly generated
+ assert:
+ that:
+ - "{{ merged['after'] == result['after'] }}"
+
+ - name: Merge the provided configuration with the existing running configuration
+ (IDEMPOTENT)
+ register: result
+ vyos.vyos.vyos_ospfv2: *id001
+
+ - name: Assert that the previous task was idempotent
+ assert:
+ that:
+ - result['changed'] == false
+
+ - name: Assert that before dicts were correctly generated
+ assert:
+ that:
+ - "{{ merged['after'] == result['before'] }}"
+ always:
+
+ - include_tasks: _remove_config.yaml
diff --git a/tests/integration/targets/vyos_ospfv2/tests/cli/merged_update.yaml b/tests/integration/targets/vyos_ospfv2/tests/cli/merged_update.yaml
new file mode 100644
index 0000000..453dbb0
--- /dev/null
+++ b/tests/integration/targets/vyos_ospfv2/tests/cli/merged_update.yaml
@@ -0,0 +1,70 @@
+---
+- debug:
+ msg: START vyos_ospfv2 merged integration tests on connection={{ ansible_connection
+ }}
+
+- include_tasks: _remove_config.yaml
+
+- include_tasks: _populate.yaml
+
+- block:
+
+ - name: Merge the provided configuration with the exisiting running configuration
+ register: result
+ vyos.vyos.vyos_ospfv2: &id001
+ config:
+ log_adjacency_changes: 'detail'
+ max_metric:
+ router_lsa:
+ administrative: true
+ on_shutdown: 10
+ on_startup: 10
+ passive_interface:
+ - 'eth1'
+ areas:
+ - area_id: '3'
+ area_type:
+ nssa:
+ set: true
+ - area_id: '4'
+ area_type:
+ stub:
+ set: false
+ network:
+ - address: '192.0.2.0/24'
+ - address: '192.0.22.0/24'
+ - address: '192.0.32.0/24'
+ state: merged
+
+ - name: Assert that before dicts were correctly generated
+ assert:
+ that: "{{ merged_update['before'] == result['before'] }}"
+
+ - name: Assert that correct set of commands were generated
+ assert:
+ that:
+ - "{{ merged_update['commands'] | symmetric_difference(result['commands']) |length\
+ \ == 0 }}"
+
+ - name: Assert that after dicts was correctly generated
+ assert:
+ that:
+ - "{{ merged_update['after'] == result['after'] }}"
+
+ - name: Merge the provided configuration with the existing running configuration
+ (IDEMPOTENT)
+ register: result
+ vyos.vyos.vyos_ospfv2: *id001
+
+ - name: Assert that the previous task was idempotent
+ assert:
+ that:
+ - result['changed'] == false
+
+ - name: Assert that before dicts were correctly generated
+ assert:
+ that:
+ - "{{ merged_update['after'] == result['before'] }}"
+ always:
+
+ - include_tasks: _remove_config.yaml \ No newline at end of file
diff --git a/tests/integration/targets/vyos_ospfv2/tests/cli/parsed.yaml b/tests/integration/targets/vyos_ospfv2/tests/cli/parsed.yaml
new file mode 100644
index 0000000..6fbe2f9
--- /dev/null
+++ b/tests/integration/targets/vyos_ospfv2/tests/cli/parsed.yaml
@@ -0,0 +1,41 @@
+---
+- debug:
+ msg: START vyos_ospfv2 parsed integration tests on connection={{ ansible_connection
+ }}
+
+- include_tasks: _remove_config.yaml
+
+- include_tasks: _populate.yaml
+
+- block:
+
+ - name: Gather ospfv2 facts
+ register: ospfv2_facts
+ vyos.vyos.vyos_facts:
+ gather_subset:
+ - default
+ gather_network_resources:
+ - ospfv2
+
+ - name: Provide the running configuration for parsing (config to be parsed)
+ register: result
+ vyos.vyos.vyos_ospfv2: &id001
+ running_config: "{{ lookup('file', '_parsed_config.cfg') }}"
+ state: parsed
+
+ - name: Assert that correct parsing done
+ assert:
+ that: "{{ ansible_facts['network_resources']['ospfv2'] == result['parsed']\
+ \ }}"
+
+ - name: Gather the existing running configuration (IDEMPOTENT)
+ register: result
+ vyos.vyos.vyos_ospfv2: *id001
+
+ - name: Assert that the previous task was idempotent
+ assert:
+ that:
+ - result['changed'] == false
+ always:
+
+ - include_tasks: _remove_config.yaml
diff --git a/tests/integration/targets/vyos_ospfv2/tests/cli/rendered.yaml b/tests/integration/targets/vyos_ospfv2/tests/cli/rendered.yaml
new file mode 100644
index 0000000..86c07cf
--- /dev/null
+++ b/tests/integration/targets/vyos_ospfv2/tests/cli/rendered.yaml
@@ -0,0 +1,88 @@
+---
+- debug:
+ msg: START vyos_ospfv2 rendered integration tests on connection={{
+ ansible_connection }}
+
+- include_tasks: _remove_config.yaml
+
+- include_tasks: _populate.yaml
+
+- block:
+
+ - name: Structure provided configuration into device specific commands
+ register: result
+ vyos.vyos.vyos_ospfv2: &id001
+ config:
+ log_adjacency_changes: 'detail'
+ max_metric:
+ router_lsa:
+ administrative: true
+ on_shutdown: 10
+ on_startup: 10
+ default_information:
+ originate:
+ always: true
+ metric: 10
+ metric_type: 2
+ route_map: 'ingress'
+ mpls_te:
+ enabled: true
+ router_address: '192.0.11.11'
+ auto_cost:
+ reference_bandwidth: 2
+ neighbor:
+ - neighbor_id: '192.0.11.12'
+ poll_interval: 10
+ priority: 2
+ redistribute:
+ - route_type: 'bgp'
+ metric: 10
+ metric_type: 2
+ passive_interface:
+ - 'eth1'
+ - 'eth2'
+ parameters:
+ router_id: '192.0.1.1'
+ opaque_lsa: true
+ rfc1583_compatibility: true
+ abr_type: 'cisco'
+ areas:
+ - area_id: '2'
+ area_type:
+ normal: true
+ authentication: "plaintext-password"
+ shortcut: 'enable'
+ - area_id: '3'
+ area_type:
+ nssa:
+ set: true
+ - area_id: '4'
+ area_type:
+ stub:
+ default_cost: 20
+ network:
+ - address: '192.0.2.0/24'
+ range:
+ - address: '192.0.3.0/24'
+ cost: 10
+ - address: '192.0.4.0/24'
+ cost: 12
+ state: rendered
+
+ - name: Assert that correct set of commands were generated
+ assert:
+ that:
+ - "{{ rendered['commands'] | symmetric_difference(result['rendered'])\
+ \ |length == 0 }}"
+
+ - name: Structure provided configuration into device specific commands (IDEMPOTENT)
+ register: result
+ vyos.vyos.vyos_ospfv2: *id001
+
+ - name: Assert that the previous task was idempotent
+ assert:
+ that:
+ - result['changed'] == false
+ always:
+
+ - include_tasks: _remove_config.yaml
diff --git a/tests/integration/targets/vyos_ospfv2/tests/cli/replaced.yaml b/tests/integration/targets/vyos_ospfv2/tests/cli/replaced.yaml
new file mode 100644
index 0000000..07606f9
--- /dev/null
+++ b/tests/integration/targets/vyos_ospfv2/tests/cli/replaced.yaml
@@ -0,0 +1,100 @@
+---
+- debug:
+ msg: START vyos_ospfv2 replaced integration tests on connection={{
+ ansible_connection }}
+
+- include_tasks: _remove_config.yaml
+
+- include_tasks: _populate.yaml
+
+- block:
+
+ - name: Replace device configurations of listed ospfv2 routes with provided configurations
+ register: result
+ vyos.vyos.vyos_ospfv2: &id001
+ config:
+ log_adjacency_changes: 'detail'
+ max_metric:
+ router_lsa:
+ administrative: true
+ on_shutdown: 10
+ on_startup: 10
+ default_information:
+ originate:
+ always: true
+ metric: 10
+ metric_type: 2
+ route_map: 'ingress'
+ mpls_te:
+ enabled: true
+ router_address: '192.0.22.22'
+ auto_cost:
+ reference_bandwidth: 2
+ neighbor:
+ - neighbor_id: '192.0.11.12'
+ poll_interval: 10
+ priority: 2
+ redistribute:
+ - route_type: 'bgp'
+ metric: 10
+ metric_type: 2
+ passive_interface:
+ - 'eth1'
+ parameters:
+ router_id: '192.0.1.1'
+ opaque_lsa: true
+ rfc1583_compatibility: true
+ abr_type: 'cisco'
+ areas:
+ - area_id: '2'
+ area_type:
+ normal: true
+ authentication: "plaintext-password"
+ shortcut: 'enable'
+ - area_id: '4'
+ area_type:
+ stub:
+ default_cost: 20
+ network:
+ - address: '192.0.2.0/24'
+ - address: '192.0.12.0/24'
+ - address: '192.0.22.0/24'
+ - address: '192.0.32.0/24'
+ range:
+ - address: '1.1.2.0/24'
+ cost: 10
+ state: replaced
+
+ - name: Assert that correct set of commands were generated
+ assert:
+ that:
+ - "{{ replaced['commands'] | symmetric_difference(result['commands'])\
+ \ |length == 0 }}"
+
+ - name: Assert that before dicts are correctly generated
+ assert:
+ that:
+ - "{{ populate == result['before'] }}"
+
+ - name: Assert that after dict is correctly generated
+ assert:
+ that:
+ - "{{ replaced['after'] == result['after'] }}"
+
+ - name: Replace device configurations of listed ospfv2 routes with provided configurarions
+ (IDEMPOTENT)
+ register: result
+ vyos.vyos.vyos_ospfv2: *id001
+
+ - name: Assert that task was idempotent
+ assert:
+ that:
+ - result['changed'] == false
+
+ - name: Assert that before dict is correctly generated
+ assert:
+ that:
+ - "{{ replaced['after'] == result['before'] }}"
+ always:
+
+ - include_tasks: _remove_config.yaml
diff --git a/tests/integration/targets/vyos_ospfv2/tests/cli/rtt.yaml b/tests/integration/targets/vyos_ospfv2/tests/cli/rtt.yaml
new file mode 100644
index 0000000..7efc2a7
--- /dev/null
+++ b/tests/integration/targets/vyos_ospfv2/tests/cli/rtt.yaml
@@ -0,0 +1,149 @@
+---
+- debug:
+ msg: START vyos_ospfv2 round trip integration tests on connection={{
+ ansible_connection }}
+
+- include_tasks: _remove_config.yaml
+
+- block:
+
+ - name: Apply the provided configuration (base config)
+ register: base_config
+ vyos.vyos.vyos_ospfv2:
+ config:
+ log_adjacency_changes: 'detail'
+ max_metric:
+ router_lsa:
+ administrative: true
+ on_shutdown: 10
+ on_startup: 10
+ default_information:
+ originate:
+ always: true
+ metric: 10
+ metric_type: 2
+ route_map: 'ingress'
+ mpls_te:
+ enabled: true
+ router_address: '192.0.11.11'
+ auto_cost:
+ reference_bandwidth: 2
+ neighbor:
+ - neighbor_id: '192.0.11.12'
+ poll_interval: 10
+ priority: 2
+ redistribute:
+ - route_type: 'bgp'
+ metric: 10
+ metric_type: 2
+ passive_interface:
+ - 'eth1'
+ - 'eth2'
+ parameters:
+ router_id: '192.0.1.1'
+ opaque_lsa: true
+ rfc1583_compatibility: true
+ abr_type: 'cisco'
+ areas:
+ - area_id: '2'
+ area_type:
+ normal: true
+ authentication: "plaintext-password"
+ shortcut: 'enable'
+ - area_id: '3'
+ area_type:
+ nssa:
+ set: true
+ - area_id: '4'
+ area_type:
+ stub:
+ default_cost: 20
+ network:
+ - address: '192.0.2.0/24'
+ range:
+ - address: '192.0.3.0/24'
+ cost: 10
+ - address: '192.0.4.0/24'
+ cost: 12
+ state: merged
+
+ - name: Gather ospfv2 facts
+ vyos.vyos.vyos_facts:
+ gather_subset:
+ - default
+ gather_network_resources:
+ - ospfv2
+
+ - name: Apply the provided configuration (config to be reverted)
+ register: result
+ vyos.vyos.vyos_ospfv2:
+ config:
+ areas:
+ - area_id: '2'
+ area_type:
+ normal: true
+ authentication: "plaintext-password"
+ shortcut: 'enable'
+ - area_id: '4'
+ area_type:
+ stub:
+ default_cost: 20
+ set: true
+ network:
+ - address: '192.0.12.0/24'
+ - address: '192.0.2.0/24'
+ - address: '192.0.22.0/24'
+ - address: '192.0.32.0/24'
+ range:
+ - address: '1.1.2.0/24'
+ cost: 10
+ auto_cost:
+ reference_bandwidth: 2
+ default_information:
+ originate:
+ always: true
+ metric: 10
+ metric_type: 2
+ route_map: 'ingress'
+ log_adjacency_changes: 'detail'
+ max_metric:
+ router_lsa:
+ administrative: true
+ on_shutdown: 10
+ on_startup: 10
+ mpls_te:
+ enabled: true
+ router_address: '192.0.22.22'
+ neighbor:
+ - neighbor_id: '192.0.11.12'
+ poll_interval: 10
+ priority: 2
+ parameters:
+ abr_type: 'cisco'
+ opaque_lsa: true
+ rfc1583_compatibility: true
+ router_id: '192.0.1.1'
+ passive_interface:
+ - 'eth1'
+ redistribute:
+ - metric: 10
+ metric_type: 2
+ route_type: 'bgp'
+ state: replaced
+
+ - name: Assert that changes were applied
+ assert:
+ that: "{{ round_trip['after'] == result['after'] }}"
+
+ - name: Revert back to base config using facts round trip
+ register: revert
+ vyos.vyos.vyos_ospfv2:
+ config: "{{ ansible_facts['network_resources']['ospfv2'] }}"
+ state: replaced
+
+ - name: Assert that config was reverted
+ assert:
+ that: "{{ base_config['after'] == revert['after']}}"
+ always:
+
+ - include_tasks: _remove_config.yaml
diff --git a/tests/integration/targets/vyos_ospfv2/vars/main.yaml b/tests/integration/targets/vyos_ospfv2/vars/main.yaml
new file mode 100644
index 0000000..76a54e3
--- /dev/null
+++ b/tests/integration/targets/vyos_ospfv2/vars/main.yaml
@@ -0,0 +1,444 @@
+---
+merged:
+ before: []
+ commands:
+ - set protocols ospf mpls-te enable
+ - set protocols ospf mpls-te router-address '192.0.11.11'
+ - set protocols ospf redistribute bgp
+ - set protocols ospf redistribute bgp metric-type 2
+ - set protocols ospf redistribute bgp metric 10
+ - set protocols ospf default-information originate metric-type 2
+ - set protocols ospf default-information originate always
+ - set protocols ospf default-information originate metric 10
+ - set protocols ospf default-information originate route-map ingress
+ - set protocols ospf auto-cost reference-bandwidth '2'
+ - set protocols ospf parameters router-id '192.0.1.1'
+ - set protocols ospf parameters opaque-lsa
+ - set protocols ospf parameters abr-type 'cisco'
+ - set protocols ospf parameters rfc1583-compatibility
+ - set protocols ospf passive-interface eth1
+ - set protocols ospf passive-interface eth2
+ - set protocols ospf max-metric router-lsa on-shutdown 10
+ - set protocols ospf max-metric router-lsa administrative
+ - set protocols ospf max-metric router-lsa on-startup 10
+ - set protocols ospf log-adjacency-changes 'detail'
+ - set protocols ospf neighbor 192.0.11.12 priority 2
+ - set protocols ospf neighbor 192.0.11.12 poll-interval 10
+ - set protocols ospf neighbor 192.0.11.12
+ - set protocols ospf area '2'
+ - set protocols ospf area 2 authentication plaintext-password
+ - set protocols ospf area 2 shortcut enable
+ - set protocols ospf area 2 area-type normal
+ - set protocols ospf area '3'
+ - set protocols ospf area 3 area-type nssa
+ - set protocols ospf area 4 range 192.0.3.0/24 cost 10
+ - set protocols ospf area 4 range 192.0.3.0/24
+ - set protocols ospf area 4 range 192.0.4.0/24 cost 12
+ - set protocols ospf area 4 range 192.0.4.0/24
+ - set protocols ospf area 4 area-type stub default-cost 20
+ - set protocols ospf area '4'
+ - set protocols ospf area 4 network 192.0.2.0/24
+ after:
+ areas:
+ - area_id: '2'
+ area_type:
+ normal: true
+ authentication: "plaintext-password"
+ shortcut: 'enable'
+ - area_id: '3'
+ area_type:
+ nssa:
+ set: true
+ - area_id: '4'
+ area_type:
+ stub:
+ default_cost: 20
+ set: true
+ network:
+ - address: '192.0.2.0/24'
+ range:
+ - address: '192.0.3.0/24'
+ cost: 10
+ - address: '192.0.4.0/24'
+ cost: 12
+ auto_cost:
+ reference_bandwidth: 2
+ default_information:
+ originate:
+ always: true
+ metric: 10
+ metric_type: 2
+ route_map: 'ingress'
+ log_adjacency_changes: 'detail'
+ max_metric:
+ router_lsa:
+ administrative: true
+ on_shutdown: 10
+ on_startup: 10
+ mpls_te:
+ enabled: true
+ router_address: '192.0.11.11'
+ neighbor:
+ - neighbor_id: '192.0.11.12'
+ poll_interval: 10
+ priority: 2
+ parameters:
+ abr_type: 'cisco'
+ opaque_lsa: true
+ rfc1583_compatibility: true
+ router_id: '192.0.1.1'
+ passive_interface:
+ - 'eth2'
+ - 'eth1'
+ redistribute:
+ - metric: 10
+ metric_type: 2
+ route_type: 'bgp'
+merged_update:
+ before:
+ areas:
+ - area_id: '2'
+ area_type:
+ normal: true
+ authentication: "plaintext-password"
+ shortcut: 'enable'
+ - area_id: '3'
+ area_type:
+ nssa:
+ set: true
+ - area_id: '4'
+ area_type:
+ stub:
+ default_cost: 20
+ set: true
+ network:
+ - address: '192.0.2.0/24'
+ range:
+ - address: '192.0.3.0/24'
+ cost: 10
+ - address: '192.0.4.0/24'
+ cost: 12
+ auto_cost:
+ reference_bandwidth: 2
+ default_information:
+ originate:
+ always: true
+ metric: 10
+ metric_type: 2
+ route_map: 'ingress'
+ log_adjacency_changes: 'detail'
+ max_metric:
+ router_lsa:
+ administrative: true
+ on_shutdown: 10
+ on_startup: 10
+ mpls_te:
+ enabled: true
+ router_address: '192.0.11.11'
+ neighbor:
+ - neighbor_id: '192.0.11.12'
+ poll_interval: 10
+ priority: 2
+ parameters:
+ abr_type: 'cisco'
+ opaque_lsa: true
+ rfc1583_compatibility: true
+ router_id: '192.0.1.1'
+ passive_interface:
+ - 'eth2'
+ - 'eth1'
+ redistribute:
+ - metric: 10
+ metric_type: 2
+ route_type: 'bgp'
+ after:
+ areas:
+ - area_id: '2'
+ area_type:
+ normal: true
+ authentication: "plaintext-password"
+ shortcut: 'enable'
+ - area_id: '3'
+ area_type:
+ nssa:
+ set: true
+ - area_id: '4'
+ network:
+ - address: '192.0.2.0/24'
+ - address: '192.0.22.0/24'
+ - address: '192.0.32.0/24'
+ range:
+ - address: '192.0.3.0/24'
+ cost: 10
+ - address: '192.0.4.0/24'
+ cost: 12
+ auto_cost:
+ reference_bandwidth: 2
+ default_information:
+ originate:
+ always: true
+ metric: 10
+ metric_type: 2
+ route_map: 'ingress'
+ log_adjacency_changes: 'detail'
+ max_metric:
+ router_lsa:
+ administrative: true
+ on_shutdown: 10
+ on_startup: 10
+ mpls_te:
+ enabled: true
+ router_address: '192.0.11.11'
+ neighbor:
+ - neighbor_id: '192.0.11.12'
+ poll_interval: 10
+ priority: 2
+ parameters:
+ abr_type: 'cisco'
+ opaque_lsa: true
+ rfc1583_compatibility: true
+ router_id: '192.0.1.1'
+ passive_interface:
+ - 'eth2'
+ - 'eth1'
+ redistribute:
+ - metric: 10
+ metric_type: 2
+ route_type: 'bgp'
+ commands:
+ - delete protocols ospf area 4 area-type stub
+ - set protocols ospf area 4 network 192.0.22.0/24
+ - set protocols ospf area 4 network 192.0.32.0/24
+populate:
+ areas:
+ - area_id: '2'
+ area_type:
+ normal: true
+ authentication: "plaintext-password"
+ shortcut: 'enable'
+ - area_id: '3'
+ area_type:
+ nssa:
+ set: true
+ - area_id: '4'
+ area_type:
+ stub:
+ default_cost: 20
+ set: true
+ network:
+ - address: '192.0.2.0/24'
+ range:
+ - address: '192.0.3.0/24'
+ cost: 10
+ - address: '192.0.4.0/24'
+ cost: 12
+ auto_cost:
+ reference_bandwidth: 2
+ default_information:
+ originate:
+ always: true
+ metric: 10
+ metric_type: 2
+ route_map: 'ingress'
+ log_adjacency_changes: 'detail'
+ max_metric:
+ router_lsa:
+ administrative: true
+ on_shutdown: 10
+ on_startup: 10
+ mpls_te:
+ enabled: true
+ router_address: '192.0.11.11'
+ neighbor:
+ - neighbor_id: '192.0.11.12'
+ poll_interval: 10
+ priority: 2
+ parameters:
+ abr_type: 'cisco'
+ opaque_lsa: true
+ rfc1583_compatibility: true
+ router_id: '192.0.1.1'
+ passive_interface:
+ - 'eth2'
+ - 'eth1'
+ redistribute:
+ - metric: 10
+ metric_type: 2
+ route_type: 'bgp'
+replaced:
+ commands:
+ - delete protocols ospf passive-interface eth2
+ - delete protocols ospf area 3
+ - delete protocols ospf area 4 range 192.0.3.0/24 cost
+ - delete protocols ospf area 4 range 192.0.3.0/24
+ - delete protocols ospf area 4 range 192.0.4.0/24 cost
+ - delete protocols ospf area 4 range 192.0.4.0/24
+ - set protocols ospf mpls-te router-address '192.0.22.22'
+ - set protocols ospf area 4 range 1.1.2.0/24 cost 10
+ - set protocols ospf area 4 range 1.1.2.0/24
+ - set protocols ospf area 4 network 192.0.12.0/24
+ - set protocols ospf area 4 network 192.0.22.0/24
+ - set protocols ospf area 4 network 192.0.32.0/24
+ after:
+ areas:
+ - area_id: '2'
+ area_type:
+ normal: true
+ authentication: "plaintext-password"
+ shortcut: 'enable'
+ - area_id: '4'
+ area_type:
+ stub:
+ default_cost: 20
+ set: true
+ network:
+ - address: '192.0.12.0/24'
+ - address: '192.0.2.0/24'
+ - address: '192.0.22.0/24'
+ - address: '192.0.32.0/24'
+ range:
+ - address: '1.1.2.0/24'
+ cost: 10
+ auto_cost:
+ reference_bandwidth: 2
+ default_information:
+ originate:
+ always: true
+ metric: 10
+ metric_type: 2
+ route_map: 'ingress'
+ log_adjacency_changes: 'detail'
+ max_metric:
+ router_lsa:
+ administrative: true
+ on_shutdown: 10
+ on_startup: 10
+ mpls_te:
+ enabled: true
+ router_address: '192.0.22.22'
+ neighbor:
+ - neighbor_id: '192.0.11.12'
+ poll_interval: 10
+ priority: 2
+ parameters:
+ abr_type: 'cisco'
+ opaque_lsa: true
+ rfc1583_compatibility: true
+ router_id: '192.0.1.1'
+ passive_interface:
+ - 'eth1'
+ redistribute:
+ - metric: 10
+ metric_type: 2
+ route_type: 'bgp'
+rendered:
+ commands:
+ - set protocols ospf mpls-te enable
+ - set protocols ospf mpls-te router-address '192.0.11.11'
+ - set protocols ospf redistribute bgp
+ - set protocols ospf redistribute bgp metric-type 2
+ - set protocols ospf redistribute bgp metric 10
+ - set protocols ospf default-information originate metric-type 2
+ - set protocols ospf default-information originate always
+ - set protocols ospf default-information originate metric 10
+ - set protocols ospf default-information originate route-map ingress
+ - set protocols ospf auto-cost reference-bandwidth '2'
+ - set protocols ospf parameters router-id '192.0.1.1'
+ - set protocols ospf parameters opaque-lsa
+ - set protocols ospf parameters abr-type 'cisco'
+ - set protocols ospf parameters rfc1583-compatibility
+ - set protocols ospf passive-interface eth1
+ - set protocols ospf passive-interface eth2
+ - set protocols ospf max-metric router-lsa on-shutdown 10
+ - set protocols ospf max-metric router-lsa administrative
+ - set protocols ospf max-metric router-lsa on-startup 10
+ - set protocols ospf log-adjacency-changes 'detail'
+ - set protocols ospf neighbor 192.0.11.12 priority 2
+ - set protocols ospf neighbor 192.0.11.12 poll-interval 10
+ - set protocols ospf neighbor 192.0.11.12
+ - set protocols ospf area '2'
+ - set protocols ospf area 2 authentication plaintext-password
+ - set protocols ospf area 2 shortcut enable
+ - set protocols ospf area 2 area-type normal
+ - set protocols ospf area '3'
+ - set protocols ospf area 3 area-type nssa
+ - set protocols ospf area 4 range 192.0.3.0/24 cost 10
+ - set protocols ospf area 4 range 192.0.3.0/24
+ - set protocols ospf area 4 range 192.0.4.0/24 cost 12
+ - set protocols ospf area 4 range 192.0.4.0/24
+ - set protocols ospf area 4 area-type stub default-cost 20
+ - set protocols ospf area '4'
+ - set protocols ospf area 4 network 192.0.2.0/24
+deleted_single:
+ commands:
+ - delete protocols ospf mpls-te
+ - delete protocols ospf redistribute
+ - delete protocols ospf auto-cost
+ - delete protocols ospf passive-interface
+ - delete protocols ospf parameters
+ - delete protocols ospf default-information
+ - delete protocols ospf max-metric
+ - delete protocols ospf log-adjacency-changes
+ - delete protocols ospf neighbor
+ - delete protocols ospf area 2
+ - delete protocols ospf area 3
+ - delete protocols ospf area 4
+ - delete protocols ospf area
+ after: []
+deleted:
+ commands:
+ - 'delete protocols ospf'
+ after: []
+round_trip:
+ after:
+ areas:
+ - area_id: '2'
+ area_type:
+ normal: true
+ authentication: "plaintext-password"
+ shortcut: 'enable'
+ - area_id: '4'
+ area_type:
+ stub:
+ default_cost: 20
+ set: true
+ network:
+ - address: '192.0.12.0/24'
+ - address: '192.0.2.0/24'
+ - address: '192.0.22.0/24'
+ - address: '192.0.32.0/24'
+ range:
+ - address: '1.1.2.0/24'
+ cost: 10
+ auto_cost:
+ reference_bandwidth: 2
+ default_information:
+ originate:
+ always: true
+ metric: 10
+ metric_type: 2
+ route_map: 'ingress'
+ log_adjacency_changes: 'detail'
+ max_metric:
+ router_lsa:
+ administrative: true
+ on_shutdown: 10
+ on_startup: 10
+ mpls_te:
+ enabled: true
+ router_address: '192.0.22.22'
+ neighbor:
+ - neighbor_id: '192.0.11.12'
+ poll_interval: 10
+ priority: 2
+ parameters:
+ abr_type: 'cisco'
+ opaque_lsa: true
+ rfc1583_compatibility: true
+ router_id: '192.0.1.1'
+ passive_interface:
+ - 'eth1'
+ redistribute:
+ - metric: 10
+ metric_type: 2
+ route_type: 'bgp'
diff --git a/tests/unit/modules/network/vyos/fixtures/vyos_ospfv2_config.cfg b/tests/unit/modules/network/vyos/fixtures/vyos_ospfv2_config.cfg
new file mode 100644
index 0000000..297671b
--- /dev/null
+++ b/tests/unit/modules/network/vyos/fixtures/vyos_ospfv2_config.cfg
@@ -0,0 +1,9 @@
+set protocols ospf area 12 area-type normal
+set protocols ospf area 12 authentication plaintext-password
+set protocols ospf area 12 shortcut enable
+set protocols ospf area 14 range 192.0.13.0/24 cost 10
+set protocols ospf area 14 range 192.0.13.0/24
+set protocols ospf area 14 range 192.0.14.0/24 cost 12
+set protocols ospf area 14 range 192.0.14.0/24
+set protocols ospf area 14 area-type stub default-cost 20
+set protocols ospf area 14 network 192.0.12.0/24
diff --git a/tests/unit/modules/network/vyos/test_vyos_ospfv2.py b/tests/unit/modules/network/vyos/test_vyos_ospfv2.py
new file mode 100644
index 0000000..8e6b095
--- /dev/null
+++ b/tests/unit/modules/network/vyos/test_vyos_ospfv2.py
@@ -0,0 +1,526 @@
+# (c) 2016 Red Hat Inc.
+#
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+
+# Make coding more python3-ish
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+from ansible_collections.vyos.vyos.tests.unit.compat.mock import patch
+from ansible_collections.vyos.vyos.plugins.modules import vyos_ospfv2
+from ansible_collections.vyos.vyos.tests.unit.modules.utils import (
+ set_module_args,
+)
+from .vyos_module import TestVyosModule, load_fixture
+
+
+class TestVyosFirewallRulesModule(TestVyosModule):
+
+ module = vyos_ospfv2
+
+ def setUp(self):
+ super(TestVyosFirewallRulesModule, self).setUp()
+ self.mock_get_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.get_config"
+ )
+ self.get_config = self.mock_get_config.start()
+
+ self.mock_load_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.load_config"
+ )
+ self.load_config = self.mock_load_config.start()
+
+ self.mock_get_resource_connection_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base.get_resource_connection"
+ )
+ self.get_resource_connection_config = (
+ self.mock_get_resource_connection_config.start()
+ )
+
+ self.mock_get_resource_connection_facts = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection"
+ )
+ self.get_resource_connection_facts = (
+ self.mock_get_resource_connection_facts.start()
+ )
+
+ self.mock_execute_show_command = patch(
+ "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.ospfv2.ospfv2.Ospfv2Facts.get_device_data"
+ )
+
+ self.execute_show_command = self.mock_execute_show_command.start()
+
+ def tearDown(self):
+ super(TestVyosFirewallRulesModule, self).tearDown()
+ self.mock_get_resource_connection_config.stop()
+ self.mock_get_resource_connection_facts.stop()
+ self.mock_get_config.stop()
+ self.mock_load_config.stop()
+ self.mock_execute_show_command.stop()
+
+ def load_fixtures(self, commands=None, transport="cli", filename=None):
+ if filename is None:
+ filename = "vyos_ospfv2_config.cfg"
+
+ def load_from_file(*args, **kwargs):
+ output = load_fixture(filename)
+ return output
+
+ self.execute_show_command.side_effect = load_from_file
+
+ def test_vyos_ospfv2_merged_new_config(self):
+ set_module_args(
+ dict(
+ config=dict(
+ log_adjacency_changes="detail",
+ mpls_te=dict(enabled=True, router_address='192.0.11.11'),
+ auto_cost=dict(reference_bandwidth=2),
+ areas=[
+ dict(
+ area_id="2",
+ area_type=dict(normal=True),
+ authentication="plaintext-password",
+ shortcut='enable',
+ ),
+ dict(
+ area_id="4",
+ area_type=dict(
+ stub=dict(default_cost=10)
+ ),
+ network=[
+ dict(address="192.0.2.0/24"),
+ ],
+ range=[
+ dict(address="192.0.3.0/24", cost=10),
+ dict(address="192.0.4.0/24", cost=12)
+ ]
+ ),
+ ],
+ ),
+ state="merged",
+ )
+ )
+ commands = [
+ "set protocols ospf mpls-te enable",
+ "set protocols ospf mpls-te router-address '192.0.11.11'",
+ "set protocols ospf auto-cost reference-bandwidth '2'",
+ "set protocols ospf log-adjacency-changes 'detail'",
+ "set protocols ospf area '2'",
+ "set protocols ospf area 2 authentication plaintext-password",
+ "set protocols ospf area 2 shortcut enable",
+ "set protocols ospf area 2 area-type normal",
+ "set protocols ospf area 4 range 192.0.3.0/24 cost 10",
+ "set protocols ospf area 4 range 192.0.3.0/24",
+ "set protocols ospf area 4 range 192.0.4.0/24 cost 12",
+ "set protocols ospf area 4 range 192.0.4.0/24",
+ "set protocols ospf area 4 area-type stub default-cost 10",
+ "set protocols ospf area '4'",
+ "set protocols ospf area 4 network 192.0.2.0/24"
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_vyos_ospfv2_merged_idem(self):
+ set_module_args(
+ dict(
+ config=dict(
+ areas=[
+ dict(
+ area_id="12",
+ area_type=dict(normal=True),
+ authentication="plaintext-password",
+ shortcut='enable',
+ ),
+ dict(
+ area_id="14",
+ area_type=dict(
+ stub=dict(default_cost=20)
+ ),
+ network=[
+ dict(address="192.0.12.0/24"),
+ ],
+ range=[
+ dict(address="192.0.13.0/24", cost=10),
+ dict(address="192.0.14.0/24", cost=12)
+ ]
+ ),
+ ],
+ ),
+ state="merged",
+ )
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_vyos_ospfv2_merged_update_existing(self):
+ set_module_args(
+ dict(
+ config=dict(
+ areas=[
+ dict(
+ area_id="12",
+ area_type=dict(normal=True),
+ authentication="plaintext-password",
+ shortcut='enable',
+ ),
+ dict(
+ area_id="14",
+ area_type=dict(
+ stub=dict(set=False)
+ ),
+ network=[
+ dict(address="192.0.12.0/24"),
+ dict(address="192.0.22.0/24"),
+ ],
+ range=[
+ dict(address="192.0.13.0/24", cost=10),
+ dict(address="192.0.14.0/24", cost=12)
+ ]
+ ),
+ ],
+ ),
+ state="merged",
+ )
+ )
+ commands = [
+ "delete protocols ospf area 14 area-type stub",
+ "set protocols ospf area 14 network 192.0.22.0/24"
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_vyos_ospfv2_replaced(self):
+ set_module_args(
+ dict(
+ config=dict(
+ log_adjacency_changes="detail",
+ mpls_te=dict(enabled=True, router_address='192.0.11.11'),
+ auto_cost=dict(reference_bandwidth=2),
+ areas=[
+ dict(
+ area_id="12",
+ area_type=dict(normal=True),
+ authentication="plaintext-password",
+ shortcut='enable',
+ ),
+ dict(
+ area_id="15",
+ area_type=dict(
+ stub=dict(default_cost=10)
+ ),
+ network=[
+ dict(address="192.0.12.0/24"),
+ ],
+ range=[
+ dict(address="192.0.13.0/24", cost=10),
+ dict(address="192.0.14.0/24", cost=12),
+ dict(address="192.0.15.0/24", cost=14)
+ ]
+ ),
+ ],
+ ),
+ state="replaced",
+ )
+ )
+ commands = [
+ "set protocols ospf mpls-te enable",
+ "set protocols ospf mpls-te router-address '192.0.11.11'",
+ "set protocols ospf auto-cost reference-bandwidth '2'",
+ "set protocols ospf log-adjacency-changes 'detail'",
+ "delete protocols ospf area 14",
+ "set protocols ospf area 15 range 192.0.13.0/24 cost 10",
+ "set protocols ospf area 15 range 192.0.13.0/24",
+ "set protocols ospf area 15 range 192.0.14.0/24 cost 12",
+ "set protocols ospf area 15 range 192.0.14.0/24",
+ "set protocols ospf area 15 range 192.0.15.0/24 cost 14",
+ "set protocols ospf area 15 range 192.0.15.0/24",
+ "set protocols ospf area 15 area-type stub default-cost 10",
+ "set protocols ospf area '15'",
+ "set protocols ospf area 15 network 192.0.12.0/24"
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_vyos_ospfv2_replaced_idem(self):
+ set_module_args(
+ dict(
+ config=dict(
+ areas=[
+ dict(
+ area_id="12",
+ area_type=dict(normal=True),
+ authentication="plaintext-password",
+ shortcut='enable',
+ ),
+ dict(
+ area_id="14",
+ area_type=dict(
+ stub=dict(default_cost=20)
+ ),
+ network=[
+ dict(address="192.0.12.0/24"),
+ ],
+ range=[
+ dict(address="192.0.13.0/24", cost=10),
+ dict(address="192.0.14.0/24", cost=12)
+ ]
+ ),
+ ],
+ ),
+ state="replaced",
+ )
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_vyos_ospfv2_deleted_no_config(self):
+ set_module_args(dict(config=None, state="deleted"))
+ commands = ["delete protocols ospf"]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_vyos_ospfv2_set_01_deleted_single_attributes(self):
+ set_module_args(
+ dict(
+ config=dict(
+ mpls_te=dict(),
+ auto_cost=dict(),
+ areas=[]
+ ),
+ state="deleted",
+ )
+ )
+ commands = ["delete protocols ospf area 12",
+ "delete protocols ospf area 14",
+ "delete protocols ospf area"]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_vyos_ospfv2_gathered(self):
+ set_module_args(dict(state="gathered"))
+ result = self.execute_module(
+ changed=False, filename="vyos_ospfv2_config.cfg"
+ )
+ gather_dict = {
+ "areas": [
+ {
+ "area_id": "2",
+ "area_type": {
+ "normal": True
+ },
+ "authentication": "plaintext-password",
+ "shortcut": "enable"
+ },
+ {
+ "area_id": "14",
+ "area_type": {
+ "stub": {
+ "default_cost": 20,
+ "set": True
+ }
+ },
+ "network": [
+ {
+ "address": "192.0.12.0/24"
+ }
+ ],
+ "range": [
+ {
+ "address": "192.0.13.0/24",
+ "cost": 10
+ },
+ {
+ "address": "192.0.14.0/24",
+ "cost": 12
+ }
+ ]
+ }
+ ],
+ }
+ self.assertEqual(sorted(gather_dict), sorted(result["gathered"]))
+
+ def test_vyos_ospfv2_parsed(self):
+ parsed_str = """set protocols ospf area 2 area-type 'normal'
+ set protocols ospf area 2 authentication 'plaintext-password'
+ set protocols ospf area 2 shortcut 'enable'
+ set protocols ospf area 3 area-type 'nssa'
+ set protocols ospf area 4 area-type stub default-cost '20'
+ set protocols ospf area 4 network '192.0.2.0/24'
+ set protocols ospf area 4 range 192.0.3.0/24 cost '10'
+ set protocols ospf area 4 range 192.0.4.0/24 cost '12'
+ set protocols ospf default-information originate 'always'
+ set protocols ospf default-information originate metric '10'
+ set protocols ospf default-information originate metric-type '2'
+set protocols ospf auto-cost reference-bandwidth '2'
+set protocols ospf default-information originate route-map 'ingress'
+set protocols ospf log-adjacency-changes 'detail'
+set protocols ospf max-metric router-lsa 'administrative'
+set protocols ospf max-metric router-lsa on-shutdown '10'
+set protocols ospf max-metric router-lsa on-startup '10'
+set protocols ospf mpls-te 'enable'
+set protocols ospf mpls-te router-address '192.0.11.11'
+set protocols ospf neighbor 192.0.11.12 poll-interval '10'
+set protocols ospf neighbor 192.0.11.12 priority '2'
+set protocols ospf parameters abr-type 'cisco'
+set protocols ospf parameters 'opaque-lsa'
+set protocols ospf parameters 'rfc1583-compatibility'
+set protocols ospf parameters router-id '192.0.1.1'
+set protocols ospf passive-interface 'eth1'
+set protocols ospf passive-interface 'eth2'
+set protocols ospf redistribute bgp metric '10'
+set protocols ospf redistribute bgp metric-type '2'"""
+ set_module_args(dict(running_config=parsed_str, state="parsed"))
+ result = self.execute_module(changed=False)
+ parsed_list = {
+ "areas": [
+ {
+ "area_id": "2",
+ "area_type": {
+ "normal": True
+ },
+ "authentication": "plaintext-password",
+ "shortcut": "enable"
+ },
+ {
+ "area_id": "3",
+ "area_type": {
+ "nssa": {
+ "set": True
+ }
+ }
+ },
+ {
+ "area_id": "4",
+ "area_type": {
+ "stub": {
+ "default_cost": 20,
+ "set": True
+ }
+ },
+ "network": [
+ {
+ "address": "192.0.2.0/24"
+ }
+ ],
+ "range": [
+ {
+ "address": "192.0.3.0/24",
+ "cost": 10
+ },
+ {
+ "address": "192.0.4.0/24",
+ "cost": 12
+ }
+ ]
+ }
+ ],
+ "auto_cost": {
+ "reference_bandwidth": 2
+ },
+ "default_information": {
+ "originate": {
+ "always": True,
+ "metric": 10,
+ "metric_type": 2,
+ "route_map": "ingress"
+ }
+ },
+ "log_adjacency_changes": "detail",
+ "max_metric": {
+ "router_lsa": {
+ "administrative": True,
+ "on_shutdown": 10,
+ "on_startup": 10
+ }
+ },
+ "mpls_te": {
+ "enabled": True,
+ "router_address": "192.0.11.11"
+ },
+ "neighbor": [
+ {
+ "neighbor_id": "192.0.11.12",
+ "poll_interval": 10,
+ "priority": 2
+ }
+ ],
+ "parameters": {
+ "abr_type": "cisco",
+ "opaque_lsa": True,
+ "rfc1583_compatibility": True,
+ "router_id": "192.0.1.1"
+ },
+ "passive_interface": [
+ "eth2",
+ "eth1"
+ ],
+ "redistribute": [
+ {
+ "metric": 10,
+ "metric_type": 2,
+ "route_type": "bgp"
+ }
+ ]
+ }
+ self.assertEqual(sorted(parsed_list), sorted(result["parsed"]))
+
+ def test_vyos_ospfv2_rendered(self):
+ set_module_args(
+ dict(
+ config=dict(
+ log_adjacency_changes="detail",
+ mpls_te=dict(enabled=True, router_address='192.0.11.11'),
+ auto_cost=dict(reference_bandwidth=2),
+ areas=[
+ dict(
+ area_id="2",
+ area_type=dict(normal=True),
+ authentication="plaintext-password",
+ shortcut='enable',
+ ),
+ dict(
+ area_id="4",
+ area_type=dict(
+ stub=dict(default_cost=10)
+ ),
+ network=[
+ dict(address="192.0.2.0/24"),
+ ],
+ range=[
+ dict(address="192.0.3.0/24", cost=10),
+ dict(address="192.0.4.0/24", cost=12)
+ ]
+ ),
+ ],
+ ),
+ state="rendered",
+ )
+ )
+ commands = [
+ "set protocols ospf mpls-te enable",
+ "set protocols ospf mpls-te router-address '192.0.11.11'",
+ "set protocols ospf auto-cost reference-bandwidth '2'",
+ "set protocols ospf log-adjacency-changes 'detail'",
+ "set protocols ospf area '2'",
+ "set protocols ospf area 2 authentication plaintext-password",
+ "set protocols ospf area 2 shortcut enable",
+ "set protocols ospf area 2 area-type normal",
+ "set protocols ospf area 4 range 192.0.3.0/24 cost 10",
+ "set protocols ospf area 4 range 192.0.3.0/24",
+ "set protocols ospf area 4 range 192.0.4.0/24 cost 12",
+ "set protocols ospf area 4 range 192.0.4.0/24",
+ "set protocols ospf area 4 area-type stub default-cost 10",
+ "set protocols ospf area '4'",
+ "set protocols ospf area 4 network 192.0.2.0/24"
+ ]
+ result = self.execute_module(changed=False)
+ self.assertEqual(
+ sorted(result["rendered"]), sorted(commands), result["rendered"]
+ )
diff --git a/tests/unit/modules/network/vyos/vyos_module.py b/tests/unit/modules/network/vyos/vyos_module.py
index 49d4652..e0ab699 100644
--- a/tests/unit/modules/network/vyos/vyos_module.py
+++ b/tests/unit/modules/network/vyos/vyos_module.py
@@ -60,7 +60,7 @@ class TestVyosModule(ModuleTestCase):
commands=None,
sort=True,
defaults=False,
- filename=None,
+ filename=None
):
self.load_fixtures(commands)