mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
fix nxos_udld_interface issue (#37527)
This commit is contained in:
parent
023f130a46
commit
135d343254
2 changed files with 131 additions and 126 deletions
|
@ -110,27 +110,11 @@ changed:
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
from ansible.module_utils.network.nxos.nxos import get_config, load_config, run_commands
|
from ansible.module_utils.network.nxos.nxos import load_config, run_commands
|
||||||
from ansible.module_utils.network.nxos.nxos import get_capabilities, nxos_argument_spec
|
from ansible.module_utils.network.nxos.nxos import nxos_argument_spec
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
|
||||||
|
|
||||||
def execute_show_command(command, module, command_type='cli_show'):
|
|
||||||
device_info = get_capabilities(module)
|
|
||||||
network_api = device_info.get('network_api', 'nxapi')
|
|
||||||
|
|
||||||
if network_api == 'cliconf':
|
|
||||||
if 'show run' not in command:
|
|
||||||
command += ' | json'
|
|
||||||
cmds = [command]
|
|
||||||
body = run_commands(module, cmds)
|
|
||||||
elif network_api == 'nxapi':
|
|
||||||
cmds = [command]
|
|
||||||
body = run_commands(module, cmds)
|
|
||||||
|
|
||||||
return body
|
|
||||||
|
|
||||||
|
|
||||||
def flatten_list(command_lists):
|
def flatten_list(command_lists):
|
||||||
flat_command_list = []
|
flat_command_list = []
|
||||||
for command in command_lists:
|
for command in command_lists:
|
||||||
|
@ -142,42 +126,42 @@ def flatten_list(command_lists):
|
||||||
|
|
||||||
|
|
||||||
def get_udld_interface(module, interface):
|
def get_udld_interface(module, interface):
|
||||||
command = 'show udld {0}'.format(interface)
|
command = 'show run udld all | section ' + interface.title() + '$'
|
||||||
interface_udld = {}
|
interface_udld = {}
|
||||||
mode = None
|
mode = None
|
||||||
|
mode_str = None
|
||||||
try:
|
try:
|
||||||
body = execute_show_command(command, module)[0]
|
body = run_commands(module, [{'command': command, 'output': 'text'}])[0]
|
||||||
table = body['TABLE_interface']['ROW_interface']
|
if 'aggressive' in body:
|
||||||
|
|
||||||
status = str(table.get('mib-port-status', None))
|
|
||||||
# Note: 'mib-aggresive-mode' is NOT a typo
|
|
||||||
agg = str(table.get('mib-aggresive-mode', 'disabled'))
|
|
||||||
|
|
||||||
if agg == 'enabled':
|
|
||||||
mode = 'aggressive'
|
mode = 'aggressive'
|
||||||
else:
|
mode_str = 'aggressive'
|
||||||
mode = status
|
elif 'no udld enable' in body:
|
||||||
|
mode = 'disabled'
|
||||||
|
mode_str = 'no udld enable'
|
||||||
|
elif 'no udld disable' in body:
|
||||||
|
mode = 'enabled'
|
||||||
|
mode_str = 'no udld disable'
|
||||||
|
elif 'udld disable' in body:
|
||||||
|
mode = 'disabled'
|
||||||
|
mode_str = 'udld disable'
|
||||||
|
elif 'udld enable' in body:
|
||||||
|
mode = 'enabled'
|
||||||
|
mode_str = 'udld enable'
|
||||||
interface_udld['mode'] = mode
|
interface_udld['mode'] = mode
|
||||||
|
|
||||||
except (KeyError, AttributeError, IndexError):
|
except (KeyError, AttributeError, IndexError):
|
||||||
interface_udld = {}
|
interface_udld = {}
|
||||||
|
|
||||||
return interface_udld
|
return interface_udld, mode_str
|
||||||
|
|
||||||
|
|
||||||
def get_commands_config_udld_interface1(delta, interface, module, existing):
|
def get_commands_config_udld_interface1(delta, interface, module, existing):
|
||||||
commands = []
|
commands = []
|
||||||
if delta:
|
|
||||||
mode = delta['mode']
|
mode = delta['mode']
|
||||||
if mode == 'aggressive':
|
if mode == 'aggressive':
|
||||||
command = 'udld aggressive'
|
commands.append('udld aggressive')
|
||||||
if mode == 'enabled':
|
else:
|
||||||
command = 'no udld aggressive ; udld enable'
|
commands.append('no udld aggressive')
|
||||||
elif mode == 'disabled':
|
|
||||||
command = 'no udld aggressive ; no udld enable'
|
|
||||||
if command:
|
|
||||||
commands.append(command)
|
|
||||||
commands.insert(0, 'interface {0}'.format(interface))
|
commands.insert(0, 'interface {0}'.format(interface))
|
||||||
|
|
||||||
return commands
|
return commands
|
||||||
|
@ -185,32 +169,18 @@ def get_commands_config_udld_interface1(delta, interface, module, existing):
|
||||||
|
|
||||||
def get_commands_config_udld_interface2(delta, interface, module, existing):
|
def get_commands_config_udld_interface2(delta, interface, module, existing):
|
||||||
commands = []
|
commands = []
|
||||||
if delta:
|
existing, mode_str = get_udld_interface(module, interface)
|
||||||
mode = delta['mode']
|
mode = delta['mode']
|
||||||
if mode == 'aggressive':
|
|
||||||
command = 'udld aggressive'
|
|
||||||
if mode == 'enabled':
|
if mode == 'enabled':
|
||||||
command = 'no udld aggressive ; no udld disable'
|
if mode_str == 'no udld enable':
|
||||||
elif mode == 'disabled':
|
|
||||||
command = 'no udld aggressive ; udld disable'
|
|
||||||
if command:
|
|
||||||
commands.append(command)
|
|
||||||
commands.insert(0, 'interface {0}'.format(interface))
|
|
||||||
|
|
||||||
return commands
|
|
||||||
|
|
||||||
|
|
||||||
def get_commands_remove_udld_interface1(delta, interface, module, existing):
|
|
||||||
commands = []
|
|
||||||
|
|
||||||
if delta:
|
|
||||||
mode = delta['mode']
|
|
||||||
if mode == 'aggressive':
|
|
||||||
command = 'no udld aggressive'
|
|
||||||
if mode == 'enabled':
|
|
||||||
command = 'no udld enable'
|
|
||||||
elif mode == 'disabled':
|
|
||||||
command = 'udld enable'
|
command = 'udld enable'
|
||||||
|
else:
|
||||||
|
command = 'no udld disable'
|
||||||
|
else:
|
||||||
|
if mode_str == 'no udld disable':
|
||||||
|
command = 'udld disable'
|
||||||
|
else:
|
||||||
|
command = 'no udld enable'
|
||||||
if command:
|
if command:
|
||||||
commands.append(command)
|
commands.append(command)
|
||||||
commands.insert(0, 'interface {0}'.format(interface))
|
commands.insert(0, 'interface {0}'.format(interface))
|
||||||
|
@ -218,17 +188,24 @@ def get_commands_remove_udld_interface1(delta, interface, module, existing):
|
||||||
return commands
|
return commands
|
||||||
|
|
||||||
|
|
||||||
def get_commands_remove_udld_interface2(delta, interface, module, existing):
|
def get_commands_remove_udld_interface(delta, interface, module, existing):
|
||||||
commands = []
|
commands = []
|
||||||
|
existing, mode_str = get_udld_interface(module, interface)
|
||||||
|
|
||||||
if delta:
|
|
||||||
mode = delta['mode']
|
mode = delta['mode']
|
||||||
if mode == 'aggressive':
|
if mode == 'aggressive':
|
||||||
command = 'no udld aggressive'
|
command = 'no udld aggressive'
|
||||||
|
else:
|
||||||
if mode == 'enabled':
|
if mode == 'enabled':
|
||||||
|
if mode_str == 'udld enable':
|
||||||
|
command = 'no udld enable'
|
||||||
|
else:
|
||||||
command = 'udld disable'
|
command = 'udld disable'
|
||||||
elif mode == 'disabled':
|
elif mode == 'disabled':
|
||||||
command = 'no udld disable'
|
if mode_str == 'no udld disable':
|
||||||
|
command = 'udld disable'
|
||||||
|
else:
|
||||||
|
command = 'no udld enable'
|
||||||
if command:
|
if command:
|
||||||
commands.append(command)
|
commands.append(command)
|
||||||
commands.insert(0, 'interface {0}'.format(interface))
|
commands.insert(0, 'interface {0}'.format(interface))
|
||||||
|
@ -256,59 +233,52 @@ def main():
|
||||||
state = module.params['state']
|
state = module.params['state']
|
||||||
|
|
||||||
proposed = dict(mode=mode)
|
proposed = dict(mode=mode)
|
||||||
existing = get_udld_interface(module, interface)
|
existing, mode_str = get_udld_interface(module, interface)
|
||||||
end_state = existing
|
end_state = existing
|
||||||
|
|
||||||
delta = dict(set(proposed.items()).difference(existing.items()))
|
delta = dict(set(proposed.items()).difference(existing.items()))
|
||||||
|
|
||||||
changed = False
|
changed = False
|
||||||
commands = []
|
commands = []
|
||||||
|
cmds = []
|
||||||
if state == 'present':
|
if state == 'present':
|
||||||
if delta:
|
if delta:
|
||||||
command = get_commands_config_udld_interface1(delta, interface,
|
command = get_commands_config_udld_interface1(delta, interface,
|
||||||
module, existing)
|
module, existing)
|
||||||
commands.append(command)
|
commands.append(command)
|
||||||
elif state == 'absent':
|
|
||||||
common = set(proposed.items()).intersection(existing.items())
|
|
||||||
if common:
|
|
||||||
command = get_commands_remove_udld_interface1(
|
|
||||||
dict(common), interface, module, existing
|
|
||||||
)
|
|
||||||
commands.append(command)
|
|
||||||
|
|
||||||
cmds = flatten_list(commands)
|
cmds = flatten_list(commands)
|
||||||
if cmds:
|
|
||||||
if module.check_mode:
|
if module.check_mode:
|
||||||
module.exit_json(changed=True, commands=cmds)
|
module.exit_json(changed=True, commands=cmds)
|
||||||
else:
|
else:
|
||||||
changed = True
|
changed = True
|
||||||
# set the return_error to True for load_config
|
|
||||||
msgs = load_config(module, cmds, True)
|
|
||||||
# since there are multiple commands sent simultaneously
|
|
||||||
# the output will have one error code for each command.
|
|
||||||
# For commands which are successful, it is empty
|
|
||||||
for item in msgs:
|
|
||||||
if item:
|
|
||||||
err_str = ''
|
|
||||||
if isinstance(item, list) and item['msg']:
|
|
||||||
err_str = item['msg']
|
|
||||||
elif isinstance(item, str):
|
|
||||||
err_str = item
|
|
||||||
if 'rejecting a config that is valid only for' in err_str:
|
|
||||||
commands = []
|
|
||||||
if state == 'present':
|
|
||||||
command = get_commands_config_udld_interface2(delta, interface,
|
|
||||||
module, existing)
|
|
||||||
elif state == 'absent':
|
|
||||||
command = get_commands_remove_udld_interface2(
|
|
||||||
dict(common), interface, module, existing
|
|
||||||
)
|
|
||||||
commands.append(command)
|
|
||||||
|
|
||||||
cmds = flatten_list(commands)
|
|
||||||
load_config(module, cmds)
|
load_config(module, cmds)
|
||||||
|
|
||||||
end_state = get_udld_interface(module, interface)
|
if delta['mode'] == 'enabled' or delta['mode'] == 'disabled':
|
||||||
|
commands = []
|
||||||
|
command = get_commands_config_udld_interface2(delta, interface,
|
||||||
|
module, existing)
|
||||||
|
commands.append(command)
|
||||||
|
cmds = flatten_list(commands)
|
||||||
|
if module.check_mode:
|
||||||
|
module.exit_json(changed=True, commands=cmds)
|
||||||
|
else:
|
||||||
|
load_config(module, cmds)
|
||||||
|
|
||||||
|
else:
|
||||||
|
common = set(proposed.items()).intersection(existing.items())
|
||||||
|
if common:
|
||||||
|
command = get_commands_remove_udld_interface(
|
||||||
|
dict(common), interface, module, existing
|
||||||
|
)
|
||||||
|
cmds = flatten_list(commands)
|
||||||
|
if module.check_mode:
|
||||||
|
module.exit_json(changed=True, commands=cmds)
|
||||||
|
else:
|
||||||
|
changed = True
|
||||||
|
load_config(module, cmds)
|
||||||
|
|
||||||
|
if not module.check_mode:
|
||||||
|
end_state, mode_str = get_udld_interface(module, interface)
|
||||||
if 'configure' in cmds:
|
if 'configure' in cmds:
|
||||||
cmds.pop(0)
|
cmds.pop(0)
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,13 @@
|
||||||
when: ansible_connection == "local"
|
when: ansible_connection == "local"
|
||||||
|
|
||||||
- set_fact: udld_run="true"
|
- set_fact: udld_run="true"
|
||||||
|
- set_fact: udld_enable="true"
|
||||||
- set_fact: udld_run="false"
|
- set_fact: udld_run="false"
|
||||||
when: ((platform is search('N9K-F')) and (imagetag and (imagetag is version('F3', 'lt'))))
|
when: ((platform is search('N9K-F')) and (imagetag and (imagetag is version_compare('F3', 'lt'))))
|
||||||
- set_fact: udld_run="false"
|
- set_fact: udld_run="false"
|
||||||
when: titanium
|
when: titanium
|
||||||
|
- set_fact: udld_enable="false"
|
||||||
|
when: imagetag and (imagetag is version_compare('N1', 'eq'))
|
||||||
|
|
||||||
# Select interface for test
|
# Select interface for test
|
||||||
- set_fact: intname="{{ nxos_int1 }}"
|
- set_fact: intname="{{ nxos_int1 }}"
|
||||||
|
@ -46,6 +49,8 @@
|
||||||
that:
|
that:
|
||||||
- "result.changed == false"
|
- "result.changed == false"
|
||||||
|
|
||||||
|
- block:
|
||||||
|
|
||||||
- name: ensure interface has mode enabled
|
- name: ensure interface has mode enabled
|
||||||
nxos_udld_interface: &conf2
|
nxos_udld_interface: &conf2
|
||||||
interface: "{{ intname }}"
|
interface: "{{ intname }}"
|
||||||
|
@ -62,6 +67,36 @@
|
||||||
|
|
||||||
- assert: *false
|
- assert: *false
|
||||||
|
|
||||||
|
- name: ensure interface has mode aggressive
|
||||||
|
nxos_udld_interface: *conf1
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- assert: *true
|
||||||
|
|
||||||
|
- name: "Conf1 Idempotence"
|
||||||
|
nxos_udld_interface: *conf1
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- assert: *false
|
||||||
|
|
||||||
|
- name: ensure interface has mode disabled
|
||||||
|
nxos_udld_interface: &conf3
|
||||||
|
interface: "{{ intname }}"
|
||||||
|
mode: disabled
|
||||||
|
state: present
|
||||||
|
provider: "{{ connection }}"
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- assert: *true
|
||||||
|
|
||||||
|
- name: "Conf3 Idempotence"
|
||||||
|
nxos_udld_interface: *conf3
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- assert: *false
|
||||||
|
|
||||||
|
when: udld_enable
|
||||||
|
|
||||||
- name: Remove the config
|
- name: Remove the config
|
||||||
nxos_udld_interface: &remove
|
nxos_udld_interface: &remove
|
||||||
interface: "{{ intname }}"
|
interface: "{{ intname }}"
|
||||||
|
|
Loading…
Reference in a new issue