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 get_capabilities, nxos_argument_spec
|
||||
from ansible.module_utils.network.nxos.nxos import load_config, run_commands
|
||||
from ansible.module_utils.network.nxos.nxos import nxos_argument_spec
|
||||
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):
|
||||
flat_command_list = []
|
||||
for command in command_lists:
|
||||
|
@ -142,75 +126,61 @@ def flatten_list(command_lists):
|
|||
|
||||
|
||||
def get_udld_interface(module, interface):
|
||||
command = 'show udld {0}'.format(interface)
|
||||
command = 'show run udld all | section ' + interface.title() + '$'
|
||||
interface_udld = {}
|
||||
mode = None
|
||||
mode_str = None
|
||||
try:
|
||||
body = execute_show_command(command, module)[0]
|
||||
table = body['TABLE_interface']['ROW_interface']
|
||||
|
||||
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':
|
||||
body = run_commands(module, [{'command': command, 'output': 'text'}])[0]
|
||||
if 'aggressive' in body:
|
||||
mode = 'aggressive'
|
||||
else:
|
||||
mode = status
|
||||
|
||||
mode_str = 'aggressive'
|
||||
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
|
||||
|
||||
except (KeyError, AttributeError, IndexError):
|
||||
interface_udld = {}
|
||||
|
||||
return interface_udld
|
||||
return interface_udld, mode_str
|
||||
|
||||
|
||||
def get_commands_config_udld_interface1(delta, interface, module, existing):
|
||||
commands = []
|
||||
if delta:
|
||||
mode = delta['mode']
|
||||
if mode == 'aggressive':
|
||||
command = 'udld aggressive'
|
||||
if mode == 'enabled':
|
||||
command = 'no udld aggressive ; udld enable'
|
||||
elif mode == 'disabled':
|
||||
command = 'no udld aggressive ; no udld enable'
|
||||
if command:
|
||||
commands.append(command)
|
||||
commands.insert(0, 'interface {0}'.format(interface))
|
||||
mode = delta['mode']
|
||||
if mode == 'aggressive':
|
||||
commands.append('udld aggressive')
|
||||
else:
|
||||
commands.append('no udld aggressive')
|
||||
commands.insert(0, 'interface {0}'.format(interface))
|
||||
|
||||
return commands
|
||||
|
||||
|
||||
def get_commands_config_udld_interface2(delta, interface, module, existing):
|
||||
commands = []
|
||||
if delta:
|
||||
mode = delta['mode']
|
||||
if mode == 'aggressive':
|
||||
command = 'udld aggressive'
|
||||
if mode == 'enabled':
|
||||
command = 'no udld aggressive ; no udld disable'
|
||||
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':
|
||||
existing, mode_str = get_udld_interface(module, interface)
|
||||
mode = delta['mode']
|
||||
if mode == 'enabled':
|
||||
if mode_str == 'no 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:
|
||||
commands.append(command)
|
||||
commands.insert(0, 'interface {0}'.format(interface))
|
||||
|
@ -218,17 +188,24 @@ def get_commands_remove_udld_interface1(delta, interface, module, existing):
|
|||
return commands
|
||||
|
||||
|
||||
def get_commands_remove_udld_interface2(delta, interface, module, existing):
|
||||
def get_commands_remove_udld_interface(delta, interface, module, existing):
|
||||
commands = []
|
||||
existing, mode_str = get_udld_interface(module, interface)
|
||||
|
||||
if delta:
|
||||
mode = delta['mode']
|
||||
if mode == 'aggressive':
|
||||
command = 'no udld aggressive'
|
||||
mode = delta['mode']
|
||||
if mode == 'aggressive':
|
||||
command = 'no udld aggressive'
|
||||
else:
|
||||
if mode == 'enabled':
|
||||
command = 'udld disable'
|
||||
if mode_str == 'udld enable':
|
||||
command = 'no udld enable'
|
||||
else:
|
||||
command = 'udld disable'
|
||||
elif mode == 'disabled':
|
||||
command = 'no udld disable'
|
||||
if mode_str == 'no udld disable':
|
||||
command = 'udld disable'
|
||||
else:
|
||||
command = 'no udld enable'
|
||||
if command:
|
||||
commands.append(command)
|
||||
commands.insert(0, 'interface {0}'.format(interface))
|
||||
|
@ -256,61 +233,54 @@ def main():
|
|||
state = module.params['state']
|
||||
|
||||
proposed = dict(mode=mode)
|
||||
existing = get_udld_interface(module, interface)
|
||||
existing, mode_str = get_udld_interface(module, interface)
|
||||
end_state = existing
|
||||
|
||||
delta = dict(set(proposed.items()).difference(existing.items()))
|
||||
|
||||
changed = False
|
||||
commands = []
|
||||
cmds = []
|
||||
if state == 'present':
|
||||
if delta:
|
||||
command = get_commands_config_udld_interface1(delta, interface,
|
||||
module, existing)
|
||||
commands.append(command)
|
||||
elif state == 'absent':
|
||||
cmds = flatten_list(commands)
|
||||
if module.check_mode:
|
||||
module.exit_json(changed=True, commands=cmds)
|
||||
else:
|
||||
changed = True
|
||||
load_config(module, cmds)
|
||||
|
||||
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_interface1(
|
||||
command = get_commands_remove_udld_interface(
|
||||
dict(common), interface, module, existing
|
||||
)
|
||||
commands.append(command)
|
||||
cmds = flatten_list(commands)
|
||||
if module.check_mode:
|
||||
module.exit_json(changed=True, commands=cmds)
|
||||
else:
|
||||
changed = True
|
||||
load_config(module, cmds)
|
||||
|
||||
cmds = flatten_list(commands)
|
||||
if cmds:
|
||||
if module.check_mode:
|
||||
module.exit_json(changed=True, commands=cmds)
|
||||
else:
|
||||
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)
|
||||
|
||||
end_state = get_udld_interface(module, interface)
|
||||
if 'configure' in cmds:
|
||||
cmds.pop(0)
|
||||
if not module.check_mode:
|
||||
end_state, mode_str = get_udld_interface(module, interface)
|
||||
if 'configure' in cmds:
|
||||
cmds.pop(0)
|
||||
|
||||
results = {}
|
||||
results['proposed'] = proposed
|
||||
|
|
|
@ -4,10 +4,13 @@
|
|||
when: ansible_connection == "local"
|
||||
|
||||
- set_fact: udld_run="true"
|
||||
- set_fact: udld_enable="true"
|
||||
- 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"
|
||||
when: titanium
|
||||
- set_fact: udld_enable="false"
|
||||
when: imagetag and (imagetag is version_compare('N1', 'eq'))
|
||||
|
||||
# Select interface for test
|
||||
- set_fact: intname="{{ nxos_int1 }}"
|
||||
|
@ -46,21 +49,53 @@
|
|||
that:
|
||||
- "result.changed == false"
|
||||
|
||||
- name: ensure interface has mode enabled
|
||||
nxos_udld_interface: &conf2
|
||||
interface: "{{ intname }}"
|
||||
mode: enabled
|
||||
state: present
|
||||
provider: "{{ connection }}"
|
||||
register: result
|
||||
- block:
|
||||
|
||||
- assert: *true
|
||||
- name: ensure interface has mode enabled
|
||||
nxos_udld_interface: &conf2
|
||||
interface: "{{ intname }}"
|
||||
mode: enabled
|
||||
state: present
|
||||
provider: "{{ connection }}"
|
||||
register: result
|
||||
|
||||
- name: "Conf2 Idempotence"
|
||||
nxos_udld_interface: *conf2
|
||||
register: result
|
||||
- assert: *true
|
||||
|
||||
- assert: *false
|
||||
- name: "Conf2 Idempotence"
|
||||
nxos_udld_interface: *conf2
|
||||
register: result
|
||||
|
||||
- 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
|
||||
nxos_udld_interface: &remove
|
||||
|
|
Loading…
Reference in a new issue