nxos_bgp_neighbor: Add bfd support (#56932)

* nxos_bgp_neighbor: Add bfd support

- Add support for bfd state in nxos_bgp_neighbor

- Feature Pull Request

- nxos_bgp_neighbor

- Tested on platforms: `N3K,N6K,N7K,N9K`

* bfd T/F now bfd enable/disable

* pep fix ws
This commit is contained in:
Chris Van Heuveln 2019-06-19 11:53:00 -04:00 committed by Trishna Guha
parent 727a6b405a
commit 52c811c841
4 changed files with 106 additions and 34 deletions

View file

@ -53,6 +53,13 @@ options:
description: description:
description: description:
- Description of the neighbor. - Description of the neighbor.
bfd:
description:
- Enables/Disables BFD for a given neighbor.
- "Dependency: 'feature bfd'"
version_added: "2.9"
type: str
choices: ['enable', 'disable']
connected_check: connected_check:
description: description:
- Configure whether or not to check for directly connected peer. - Configure whether or not to check for directly connected peer.
@ -154,6 +161,7 @@ EXAMPLES = '''
neighbor: 192.0.2.3 neighbor: 192.0.2.3
local_as: 20 local_as: 20
remote_as: 30 remote_as: 30
bfd: enable
description: "just a description" description: "just a description"
update_source: Ethernet1/3 update_source: Ethernet1/3
state: present state: present
@ -188,6 +196,7 @@ BOOL_PARAMS = [
] ]
PARAM_TO_COMMAND_KEYMAP = { PARAM_TO_COMMAND_KEYMAP = {
'asn': 'router bgp', 'asn': 'router bgp',
'bfd': 'bfd',
'capability_negotiation': 'dont-capability-negotiate', 'capability_negotiation': 'dont-capability-negotiate',
'connected_check': 'disable-connected-check', 'connected_check': 'disable-connected-check',
'description': 'description', 'description': 'description',
@ -211,6 +220,7 @@ PARAM_TO_COMMAND_KEYMAP = {
'vrf': 'vrf' 'vrf': 'vrf'
} }
PARAM_TO_DEFAULT_KEYMAP = { PARAM_TO_DEFAULT_KEYMAP = {
'bfd': 'disable',
'shutdown': False, 'shutdown': False,
'dynamic_capability': True, 'dynamic_capability': True,
'timers_keepalive': 60, 'timers_keepalive': 60,
@ -245,6 +255,8 @@ def get_value(arg, config):
value = 'enable' value = 'enable'
elif has_command_val: elif has_command_val:
value = has_command_val.group('value') value = has_command_val.group('value')
elif arg == 'bfd':
value = 'enable' if has_command else 'disable'
else: else:
value = '' value = ''
@ -354,6 +366,9 @@ def state_present(module, existing, proposed, candidate):
proposed['timers_holdtime']) proposed['timers_holdtime'])
if command not in commands: if command not in commands:
commands.append(command) commands.append(command)
elif key == 'bfd':
no_cmd = 'no ' if value == 'disable' else ''
commands.append(no_cmd + key)
else: else:
command = '{0} {1}'.format(key, value) command = '{0} {1}'.format(key, value)
commands.append(command) commands.append(command)
@ -389,6 +404,7 @@ def main():
vrf=dict(required=False, type='str', default='default'), vrf=dict(required=False, type='str', default='default'),
neighbor=dict(required=True, type='str'), neighbor=dict(required=True, type='str'),
description=dict(required=False, type='str'), description=dict(required=False, type='str'),
bfd=dict(required=False, type='str', choices=['enable', 'disable']),
capability_negotiation=dict(required=False, type='bool'), capability_negotiation=dict(required=False, type='bool'),
connected_check=dict(required=False, type='bool'), connected_check=dict(required=False, type='bool'),
dynamic_capability=dict(required=False, type='bool'), dynamic_capability=dict(required=False, type='bool'),
@ -442,7 +458,10 @@ def main():
if key not in ['asn', 'vrf', 'neighbor', 'pwd_type']: if key not in ['asn', 'vrf', 'neighbor', 'pwd_type']:
if str(value).lower() == 'default': if str(value).lower() == 'default':
value = PARAM_TO_DEFAULT_KEYMAP.get(key, 'default') value = PARAM_TO_DEFAULT_KEYMAP.get(key, 'default')
if existing.get(key) != value: if key == 'bfd':
if existing.get('bfd', 'disable') != value:
proposed[key] = value
elif existing.get(key) != value:
proposed[key] = value proposed[key] = value
candidate = CustomNetworkConfig(indent=3) candidate = CustomNetworkConfig(indent=3)

View file

@ -15,32 +15,20 @@
- set_fact: remove_private_asr="replace-as" - set_fact: remove_private_asr="replace-as"
when: not titanium when: not titanium
- name: "Enable feature BGP" - name: "Setup: Disable features"
nxos_feature: nxos_feature:
feature: bgp feature: "{{ item }}"
provider: "{{ connection }}"
state: disabled
loop: ['bgp', 'bfd']
ignore_errors: yes
- name: "Setup: Enable features"
nxos_feature:
feature: "{{ item }}"
provider: "{{ connection }}" provider: "{{ connection }}"
state: enabled state: enabled
ignore_errors: yes loop: ['bgp', 'bfd']
- name: "Setup"
nxos_bgp_neighbor: &removenp
asn: 65535
neighbor: 192.0.2.3
vrf: "{{ item }}"
provider: "{{ connection }}"
state: absent
with_items: "{{ vrfs }}"
ignore_errors: yes
- name: "Setup"
nxos_bgp_neighbor: &remove
asn: 65535
neighbor: 192.0.2.3/32
vrf: "{{ item }}"
provider: "{{ connection }}"
state: absent
with_items: "{{ vrfs }}"
ignore_errors: yes
- block: - block:
- name: "Configure BGP neighbor1" - name: "Configure BGP neighbor1"
@ -116,7 +104,12 @@
- assert: *false - assert: *false
- name: "Remove BGP" - name: "Remove BGP"
nxos_bgp_neighbor: *remove nxos_bgp_neighbor: &remove
asn: 65535
neighbor: 192.0.2.3/32
vrf: "{{ item }}"
provider: "{{ connection }}"
state: absent
with_items: "{{ vrfs }}" with_items: "{{ vrfs }}"
register: result register: result
@ -291,7 +284,12 @@
- assert: *false - assert: *false
- name: "Remove BGP" - name: "Remove BGP"
nxos_bgp_neighbor: *removenp nxos_bgp_neighbor: &removenp
asn: 65535
neighbor: 192.0.2.3
vrf: "{{ item }}"
provider: "{{ connection }}"
state: absent
with_items: "{{ vrfs }}" with_items: "{{ vrfs }}"
register: result register: result
@ -304,17 +302,47 @@
- assert: *false - assert: *false
rescue: - name: "Configure BFD enable"
- name: "Cleanup BGP" nxos_bgp_neighbor: &bfd_enable
nxos_bgp_neighbor: *remove asn: 65535
with_items: "{{ vrfs }}" neighbor: 192.168.1.1
ignore_errors: yes bfd: enable
provider: "{{ connection }}"
state: present
register: result
- assert: *true
- name: Check BFD enable Idempotence
nxos_bgp_neighbor: *bfd_enable
register: result
- assert: *false
- name: Configure BFD disable Idempotence
nxos_bgp_neighbor: &bfd_disable
asn: 65535
neighbor: 192.168.1.1
bfd: disable
provider: "{{ connection }}"
state: present
register: result
- assert: *true
- name: Check BFD disable Idempotence
nxos_bgp_neighbor: *bfd_disable
register: result
- assert: *false
always: always:
- name: "Disable feature bgp" - name: "Teardown: Disable features"
nxos_feature: &disable_bgp nxos_feature:
feature: bgp feature: "{{ item }}"
provider: "{{ connection }}" provider: "{{ connection }}"
state: disabled state: disabled
loop: ['bgp', 'bfd']
ignore_errors: yes
- debug: msg="END connection={{ ansible_connection }} nxos_bgp_neighbor sanity test" - debug: msg="END connection={{ ansible_connection }} nxos_bgp_neighbor sanity test"

View file

@ -7,6 +7,9 @@ router bgp 65535
vrf test2 vrf test2
address-family ipv4 unicast address-family ipv4 unicast
timers bgp 1 10 timers bgp 1 10
neighbor 1.1.1.1
neighbor 1.1.1.2
bfd
neighbor 3.3.3.4 neighbor 3.3.3.4
remove-private-as all remove-private-as all
neighbor 3.3.3.5 neighbor 3.3.3.5

View file

@ -46,10 +46,32 @@ class TestNxosBgpNeighborModule(TestNxosModule):
self.get_config.return_value = load_fixture('nxos_bgp', 'config.cfg') self.get_config.return_value = load_fixture('nxos_bgp', 'config.cfg')
self.load_config.return_value = [] self.load_config.return_value = []
def test_nxos_bgp_neighbor_bfd_1(self):
# None (disable) -> enable
set_module_args(dict(asn=65535, neighbor='1.1.1.1', bfd='enable'))
self.execute_module(changed=True, commands=['router bgp 65535', 'neighbor 1.1.1.1', 'bfd'])
# enable -> enable (idempotence)
set_module_args(dict(asn=65535, neighbor='1.1.1.2', bfd='enable'))
self.execute_module(changed=False)
def test_nxos_bgp_neighbor_bfd_2(self):
# enable -> None (disable)
set_module_args(dict(asn=65535, neighbor='1.1.1.2', bfd='disable'))
self.execute_module(changed=True, commands=['router bgp 65535', 'neighbor 1.1.1.2', 'no bfd'])
# None (disable) -> disable (idempotence)
set_module_args(dict(asn=65535, neighbor='1.1.1.1', bfd='disable'))
self.execute_module(changed=False)
def test_nxos_bgp_neighbor(self): def test_nxos_bgp_neighbor(self):
set_module_args(dict(asn=65535, neighbor='192.0.2.3', description='some words')) set_module_args(dict(asn=65535, neighbor='192.0.2.3', description='some words'))
self.execute_module(changed=True, commands=['router bgp 65535', 'neighbor 192.0.2.3', 'description some words']) self.execute_module(changed=True, commands=['router bgp 65535', 'neighbor 192.0.2.3', 'description some words'])
def test_nxos_bgp_neighbor_absent(self):
set_module_args(dict(asn=65535, neighbor='1.1.1.1', state='absent'))
self.execute_module(changed=True, commands=['router bgp 65535', 'no neighbor 1.1.1.1'])
def test_nxos_bgp_neighbor_remove_private_as(self): def test_nxos_bgp_neighbor_remove_private_as(self):
set_module_args(dict(asn=65535, neighbor='3.3.3.4', remove_private_as='all')) set_module_args(dict(asn=65535, neighbor='3.3.3.4', remove_private_as='all'))
self.execute_module(changed=False, commands=[]) self.execute_module(changed=False, commands=[])