mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
nxos_udld_interface: improve interface detection (#28682)
* fix for nxos_udld_interface * Tested Note added back
This commit is contained in:
parent
6d196eaa98
commit
4e32c92166
2 changed files with 88 additions and 67 deletions
|
@ -157,7 +157,7 @@ class Cli:
|
||||||
responses.append(out)
|
responses.append(out)
|
||||||
return responses
|
return responses
|
||||||
|
|
||||||
def load_config(self, config):
|
def load_config(self, config, return_error=False):
|
||||||
"""Sends configuration commands to the remote device
|
"""Sends configuration commands to the remote device
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -236,7 +236,7 @@ class Nxapi:
|
||||||
|
|
||||||
return dict(ins_api=msg)
|
return dict(ins_api=msg)
|
||||||
|
|
||||||
def send_request(self, commands, output='text', check_status=True):
|
def send_request(self, commands, output='text', check_status=True, return_error=False):
|
||||||
# only 10 show commands can be encoded in each request
|
# only 10 show commands can be encoded in each request
|
||||||
# messages sent to the remote device
|
# messages sent to the remote device
|
||||||
if output != 'config':
|
if output != 'config':
|
||||||
|
@ -287,6 +287,9 @@ class Nxapi:
|
||||||
output = response['ins_api']['outputs']['output']
|
output = response['ins_api']['outputs']['output']
|
||||||
for item in to_list(output):
|
for item in to_list(output):
|
||||||
if check_status and item['code'] != '200':
|
if check_status and item['code'] != '200':
|
||||||
|
if return_error:
|
||||||
|
result.append(item)
|
||||||
|
else:
|
||||||
self._error(output=output, **item)
|
self._error(output=output, **item)
|
||||||
elif 'body' in item:
|
elif 'body' in item:
|
||||||
result.append(item['body'])
|
result.append(item['body'])
|
||||||
|
@ -341,11 +344,14 @@ class Nxapi:
|
||||||
|
|
||||||
return responses
|
return responses
|
||||||
|
|
||||||
def load_config(self, commands):
|
def load_config(self, commands, return_error=False):
|
||||||
"""Sends the ordered set of commands to the device
|
"""Sends the ordered set of commands to the device
|
||||||
"""
|
"""
|
||||||
commands = to_list(commands)
|
commands = to_list(commands)
|
||||||
self.send_request(commands, output='config')
|
msg = self.send_request(commands, output='config', check_status=True, return_error=return_error)
|
||||||
|
if return_error:
|
||||||
|
return msg
|
||||||
|
else:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
@ -397,6 +403,6 @@ def run_commands(module, commands, check_rc=True):
|
||||||
return conn.run_commands(to_command(module, commands), check_rc)
|
return conn.run_commands(to_command(module, commands), check_rc)
|
||||||
|
|
||||||
|
|
||||||
def load_config(module, config):
|
def load_config(module, config, return_error=False):
|
||||||
conn = get_connection(module)
|
conn = get_connection(module)
|
||||||
return conn.load_config(config)
|
return conn.load_config(config, return_error=return_error)
|
||||||
|
|
|
@ -115,10 +115,6 @@ from ansible.module_utils.nxos import nxos_argument_spec, check_args
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
|
||||||
|
|
||||||
import re
|
|
||||||
import re
|
|
||||||
|
|
||||||
|
|
||||||
def execute_show_command(command, module, command_type='cli_show'):
|
def execute_show_command(command, module, command_type='cli_show'):
|
||||||
if module.params['transport'] == 'cli':
|
if module.params['transport'] == 'cli':
|
||||||
if 'show run' not in command:
|
if 'show run' not in command:
|
||||||
|
@ -167,50 +163,16 @@ def get_udld_interface(module, interface):
|
||||||
return interface_udld
|
return interface_udld
|
||||||
|
|
||||||
|
|
||||||
def is_interface_copper(module, interface):
|
def get_commands_config_udld_interface1(delta, interface, module, existing):
|
||||||
command = 'show interface status'
|
|
||||||
copper = []
|
|
||||||
try:
|
|
||||||
body = execute_show_command(command, module)[0]
|
|
||||||
table = body['TABLE_interface']['ROW_interface']
|
|
||||||
for each in table:
|
|
||||||
itype = each.get('type', 'DNE')
|
|
||||||
if 'CU' in itype or '1000' in itype or '10GBaseT' in itype:
|
|
||||||
copper.append(str(each['interface'].lower()))
|
|
||||||
except (KeyError, AttributeError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
if interface in copper:
|
|
||||||
found = True
|
|
||||||
else:
|
|
||||||
found = False
|
|
||||||
|
|
||||||
return found
|
|
||||||
|
|
||||||
|
|
||||||
def get_commands_config_udld_interface(delta, interface, module, existing):
|
|
||||||
commands = []
|
commands = []
|
||||||
copper = is_interface_copper(module, interface)
|
|
||||||
if delta:
|
if delta:
|
||||||
mode = delta['mode']
|
mode = delta['mode']
|
||||||
if mode == 'aggressive':
|
if mode == 'aggressive':
|
||||||
command = 'udld aggressive'
|
command = 'udld aggressive'
|
||||||
elif copper:
|
|
||||||
if mode == 'enabled':
|
if mode == 'enabled':
|
||||||
if existing['mode'] == 'aggressive':
|
|
||||||
command = 'no udld aggressive ; udld enable'
|
command = 'no udld aggressive ; udld enable'
|
||||||
else:
|
|
||||||
command = 'udld enable'
|
|
||||||
elif mode == 'disabled':
|
elif mode == 'disabled':
|
||||||
command = 'no udld enable'
|
command = 'no udld aggressive ; no udld enable'
|
||||||
elif not copper:
|
|
||||||
if mode == 'enabled':
|
|
||||||
if existing['mode'] == 'aggressive':
|
|
||||||
command = 'no udld aggressive ; no udld disable'
|
|
||||||
else:
|
|
||||||
command = 'no udld disable'
|
|
||||||
elif mode == 'disabled':
|
|
||||||
command = 'udld disable'
|
|
||||||
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,20 +180,48 @@ def get_commands_config_udld_interface(delta, interface, module, existing):
|
||||||
return commands
|
return commands
|
||||||
|
|
||||||
|
|
||||||
def get_commands_remove_udld_interface(delta, interface, module, existing):
|
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 = []
|
commands = []
|
||||||
copper = is_interface_copper(module, interface)
|
|
||||||
|
|
||||||
if delta:
|
if delta:
|
||||||
mode = delta['mode']
|
mode = delta['mode']
|
||||||
if mode == 'aggressive':
|
if mode == 'aggressive':
|
||||||
command = 'no udld aggressive'
|
command = 'no udld aggressive'
|
||||||
elif copper:
|
|
||||||
if mode == 'enabled':
|
if mode == 'enabled':
|
||||||
command = 'no udld enable'
|
command = 'no udld enable'
|
||||||
elif mode == 'disabled':
|
elif mode == 'disabled':
|
||||||
command = 'udld enable'
|
command = 'udld enable'
|
||||||
elif not copper:
|
if command:
|
||||||
|
commands.append(command)
|
||||||
|
commands.insert(0, 'interface {0}'.format(interface))
|
||||||
|
|
||||||
|
return commands
|
||||||
|
|
||||||
|
|
||||||
|
def get_commands_remove_udld_interface2(delta, interface, module, existing):
|
||||||
|
commands = []
|
||||||
|
|
||||||
|
if delta:
|
||||||
|
mode = delta['mode']
|
||||||
|
if mode == 'aggressive':
|
||||||
|
command = 'no udld aggressive'
|
||||||
if mode == 'enabled':
|
if mode == 'enabled':
|
||||||
command = 'udld disable'
|
command = 'udld disable'
|
||||||
elif mode == 'disabled':
|
elif mode == 'disabled':
|
||||||
|
@ -259,7 +249,6 @@ def main():
|
||||||
warnings = list()
|
warnings = list()
|
||||||
check_args(module, warnings)
|
check_args(module, warnings)
|
||||||
|
|
||||||
|
|
||||||
interface = module.params['interface'].lower()
|
interface = module.params['interface'].lower()
|
||||||
mode = module.params['mode']
|
mode = module.params['mode']
|
||||||
state = module.params['state']
|
state = module.params['state']
|
||||||
|
@ -274,13 +263,13 @@ def main():
|
||||||
commands = []
|
commands = []
|
||||||
if state == 'present':
|
if state == 'present':
|
||||||
if delta:
|
if delta:
|
||||||
command = get_commands_config_udld_interface(delta, interface,
|
command = get_commands_config_udld_interface1(delta, interface,
|
||||||
module, existing)
|
module, existing)
|
||||||
commands.append(command)
|
commands.append(command)
|
||||||
elif state == 'absent':
|
elif state == 'absent':
|
||||||
common = set(proposed.items()).intersection(existing.items())
|
common = set(proposed.items()).intersection(existing.items())
|
||||||
if common:
|
if common:
|
||||||
command = get_commands_remove_udld_interface(
|
command = get_commands_remove_udld_interface1(
|
||||||
dict(common), interface, module, existing
|
dict(common), interface, module, existing
|
||||||
)
|
)
|
||||||
commands.append(command)
|
commands.append(command)
|
||||||
|
@ -291,7 +280,32 @@ def main():
|
||||||
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)
|
end_state = get_udld_interface(module, interface)
|
||||||
if 'configure' in cmds:
|
if 'configure' in cmds:
|
||||||
cmds.pop(0)
|
cmds.pop(0)
|
||||||
|
@ -306,5 +320,6 @@ def main():
|
||||||
|
|
||||||
module.exit_json(**results)
|
module.exit_json(**results)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
Loading…
Reference in a new issue