nxos_ospf_vrf: Add 'bfd' support (#57425)

* nxos_ospf_vrf: Add 'bfd' support

* Add default to bfd doc hdr

* bfd T/F now bfd enable/disable
pull/57713/head
Chris Van Heuveln 6 years ago committed by Trishna Guha
parent 30830a4482
commit 727a6b405a

@ -90,6 +90,13 @@ options:
description: description:
- Specifies the reference bandwidth used to assign OSPF cost. - Specifies the reference bandwidth used to assign OSPF cost.
Valid values are an integer, in Mbps, or the keyword 'default'. Valid values are an integer, in Mbps, or the keyword 'default'.
bfd:
description:
- Enables BFD on all OSPF interfaces.
- "Dependency: 'feature bfd'"
version_added: "2.9"
type: str
choices: ['enable', 'disable']
passive_interface: passive_interface:
description: description:
- Setting to C(yes) will suppress routing update on interface. - Setting to C(yes) will suppress routing update on interface.
@ -112,6 +119,7 @@ EXAMPLES = '''
timer_throttle_lsa_hold: 1100 timer_throttle_lsa_hold: 1100
timer_throttle_lsa_max: 3000 timer_throttle_lsa_max: 3000
vrf: test vrf: test
bfd: enable
state: present state: present
''' '''
@ -120,8 +128,11 @@ commands:
description: commands sent to the device description: commands sent to the device
returned: always returned: always
type: list type: list
sample: ["router ospf 1", "vrf test", "timers throttle lsa 60 1100 3000", sample:
"ospf 1", "timers throttle spf 50 1000 2000", "vrf test"] - router ospf 1
- vrf test
- bfd
- timers throttle lsa 60 1100 3000
''' '''
import re import re
@ -146,6 +157,7 @@ PARAM_TO_COMMAND_KEYMAP = {
'timer_throttle_spf_start': 'timers throttle spf', 'timer_throttle_spf_start': 'timers throttle spf',
'timer_throttle_spf_hold': 'timers throttle spf', 'timer_throttle_spf_hold': 'timers throttle spf',
'auto_cost': 'auto-cost reference-bandwidth', 'auto_cost': 'auto-cost reference-bandwidth',
'bfd': 'bfd',
'passive_interface': 'passive-interface default' 'passive_interface': 'passive-interface default'
} }
PARAM_TO_DEFAULT_KEYMAP = { PARAM_TO_DEFAULT_KEYMAP = {
@ -156,6 +168,7 @@ PARAM_TO_DEFAULT_KEYMAP = {
'timer_throttle_spf_max': '5000', 'timer_throttle_spf_max': '5000',
'timer_throttle_spf_hold': '1000', 'timer_throttle_spf_hold': '1000',
'auto_cost': '40000', 'auto_cost': '40000',
'bfd': 'disable',
'default_metric': '', 'default_metric': '',
'passive_interface': False, 'passive_interface': False,
'router_id': '', 'router_id': '',
@ -206,6 +219,8 @@ def get_existing(module, args):
if 'Gbps' in line: if 'Gbps' in line:
cost = int(cost) * 1000 cost = int(cost) * 1000
existing['auto_cost'] = str(cost) existing['auto_cost'] = str(cost)
elif 'bfd' in line:
existing['bfd'] = 'enable'
elif 'timers throttle lsa' in line: elif 'timers throttle lsa' in line:
tmp = re.search(r'timers throttle lsa (\S+) (\S+) (\S+)', line) tmp = re.search(r'timers throttle lsa (\S+) (\S+) (\S+)', line)
existing['timer_throttle_lsa_start'] = tmp.group(1) existing['timer_throttle_lsa_start'] = tmp.group(1)
@ -244,6 +259,8 @@ def state_present(module, existing, proposed, candidate):
existing_commands = apply_key_map(PARAM_TO_COMMAND_KEYMAP, existing) existing_commands = apply_key_map(PARAM_TO_COMMAND_KEYMAP, existing)
for key, value in proposed_commands.items(): for key, value in proposed_commands.items():
if key == 'vrf':
continue
if value is True: if value is True:
commands.append(key) commands.append(key)
@ -284,6 +301,8 @@ def state_present(module, existing, proposed, candidate):
else: else:
value = str(int(value) / 1000) value = str(int(value) / 1000)
command = '{0} {1} Gbps'.format(key, value) command = '{0} {1} Gbps'.format(key, value)
elif key == 'bfd':
command = 'no bfd' if value == 'disable' else 'bfd'
else: else:
command = '{0} {1}'.format(key, value.lower()) command = '{0} {1}'.format(key, value.lower())
@ -304,6 +323,7 @@ def state_absent(module, existing, proposed, candidate):
existing_commands = apply_key_map(PARAM_TO_COMMAND_KEYMAP, existing) existing_commands = apply_key_map(PARAM_TO_COMMAND_KEYMAP, existing)
for key, value in existing_commands.items(): for key, value in existing_commands.items():
if value and key != 'vrf': if value and key != 'vrf':
command = None
if key == 'passive-interface default': if key == 'passive-interface default':
command = 'no {0}'.format(key) command = 'no {0}'.format(key)
elif key == 'timers throttle lsa': elif key == 'timers throttle lsa':
@ -337,6 +357,9 @@ def state_absent(module, existing, proposed, candidate):
command = 'no {0}'.format(key) command = 'no {0}'.format(key)
else: else:
command = None command = None
elif key == 'bfd':
if value == 'enable':
command = 'no bfd'
else: else:
existing_value = existing_commands.get(key) existing_value = existing_commands.get(key)
command = 'no {0} {1}'.format(key, existing_value) command = 'no {0} {1}'.format(key, existing_value)
@ -367,6 +390,7 @@ def main():
timer_throttle_spf_hold=dict(required=False, type='str'), timer_throttle_spf_hold=dict(required=False, type='str'),
timer_throttle_spf_max=dict(required=False, type='str'), timer_throttle_spf_max=dict(required=False, type='str'),
auto_cost=dict(required=False, type='str'), auto_cost=dict(required=False, type='str'),
bfd=dict(required=False, type='str', choices=['enable', 'disable']),
passive_interface=dict(required=False, type='bool'), passive_interface=dict(required=False, type='bool'),
state=dict(choices=['present', 'absent'], default='present', required=False) state=dict(choices=['present', 'absent'], default='present', required=False)
) )

@ -7,19 +7,20 @@
# CSCvi74876 Cannot remove default-metric # CSCvi74876 Cannot remove default-metric
when: imagetag is not search("I7") when: imagetag is not search("I7")
- name: "Setup: disable feature OSPF for initial cleanup" - name: "Setup: disable features for initial cleanup"
nxos_feature: nxos_feature:
feature: ospf feature: "{{ item }}"
provider: "{{ connection }}" provider: "{{ connection }}"
state: disabled state: disabled
loop: ['ospf', 'bfd']
ignore_errors: yes ignore_errors: yes
- name: "Enable feature OSPF" - name: "Enable features"
nxos_feature: nxos_feature:
feature: ospf feature: "{{ item }}"
provider: "{{ connection }}" provider: "{{ connection }}"
state: enabled state: enabled
ignore_errors: yes loop: ['ospf', 'bfd']
- block: - block:
- name: Configure ospf vrf - name: Configure ospf vrf
@ -33,6 +34,7 @@
timer_throttle_lsa_hold: 1100 timer_throttle_lsa_hold: 1100
timer_throttle_lsa_max: 3000 timer_throttle_lsa_max: 3000
vrf: test vrf: test
bfd: enable
passive_interface: true passive_interface: true
provider: "{{ connection }}" provider: "{{ connection }}"
state: present state: present
@ -60,6 +62,7 @@
default_metric: 1000 default_metric: 1000
log_adjacency: log log_adjacency: log
vrf: default vrf: default
bfd: disable
passive_interface: true passive_interface: true
provider: "{{ connection }}" provider: "{{ connection }}"
state: present state: present
@ -129,11 +132,12 @@
when: def_met_default is defined when: def_met_default is defined
always: always:
- name: "Disable feature OSPF" - name: "Disable features"
nxos_feature: nxos_feature:
feature: ospf feature: "{{ item }}"
provider: "{{ connection }}" provider: "{{ connection }}"
state: disabled state: disabled
loop: ['ospf', 'bfd']
ignore_errors: yes ignore_errors: yes
- debug: msg="END connection={{ ansible_connection }} nxos_ospf_vrf sanity test" - debug: msg="END connection={{ ansible_connection }} nxos_ospf_vrf sanity test"

@ -54,6 +54,7 @@ class TestNxosOspfVrfModule(TestNxosModule):
timer_throttle_lsa_start=60, timer_throttle_lsa_start=60,
timer_throttle_lsa_hold=1100, timer_throttle_lsa_hold=1100,
timer_throttle_lsa_max=3000, timer_throttle_lsa_max=3000,
bfd='enable',
state='present')) state='present'))
result = self.execute_module(changed=True) result = self.execute_module(changed=True)
self.assertEqual(sorted(result['commands']), self.assertEqual(sorted(result['commands']),
@ -61,9 +62,67 @@ class TestNxosOspfVrfModule(TestNxosModule):
'vrf test', 'vrf test',
'timers throttle lsa 60 1100 3000', 'timers throttle lsa 60 1100 3000',
'timers throttle spf 50 1000 2000', 'timers throttle spf 50 1000 2000',
'vrf test'])) 'bfd',
]))
def test_nxos_ospf_vrf_absent(self): def test_nxos_ospf_vrf_absent(self):
set_module_args(dict(ospf=1, vrf='test', state='absent')) set_module_args(dict(ospf=1, vrf='test', state='absent'))
result = self.execute_module(changed=False) result = self.execute_module(changed=False)
self.assertEqual(result['commands'], []) self.assertEqual(result['commands'], [])
def test_bfd_1(self):
self.get_config.return_value = 'router ospf 1\n bfd\nrouter ospf 2'
# enable -> disable
set_module_args(dict(
ospf=1,
bfd='disable',
))
self.execute_module(changed=True, commands=[
'router ospf 1',
'no bfd',
])
# disable -> enable
set_module_args(dict(
ospf=2,
bfd='enable',
))
self.execute_module(changed=True, commands=[
'router ospf 2',
'bfd',
])
def test_bfd_2(self):
# enable idempotence
self.get_config.return_value = 'router ospf 1\n bfd\nrouter ospf 2'
set_module_args(dict(
ospf=1,
bfd='enable',
))
self.execute_module(changed=False)
# disable idempotence
set_module_args(dict(
ospf=2,
bfd='disable',
))
self.execute_module(changed=False)
def test_bfd_3(self):
# absent tests
self.get_config.return_value = 'router ospf 1\n bfd\nrouter ospf 2'
set_module_args(dict(
ospf=1,
state='absent'
))
self.execute_module(changed=True, commands=[
'router ospf 1',
'no bfd',
])
# absent w/bfd disable
set_module_args(dict(
ospf=2,
state='absent'
))
self.execute_module(changed=False)

Loading…
Cancel
Save