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)
|
||||
return responses
|
||||
|
||||
def load_config(self, config):
|
||||
def load_config(self, config, return_error=False):
|
||||
"""Sends configuration commands to the remote device
|
||||
"""
|
||||
|
||||
|
@ -236,7 +236,7 @@ class Nxapi:
|
|||
|
||||
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
|
||||
# messages sent to the remote device
|
||||
if output != 'config':
|
||||
|
@ -287,6 +287,9 @@ class Nxapi:
|
|||
output = response['ins_api']['outputs']['output']
|
||||
for item in to_list(output):
|
||||
if check_status and item['code'] != '200':
|
||||
if return_error:
|
||||
result.append(item)
|
||||
else:
|
||||
self._error(output=output, **item)
|
||||
elif 'body' in item:
|
||||
result.append(item['body'])
|
||||
|
@ -341,11 +344,14 @@ class Nxapi:
|
|||
|
||||
return responses
|
||||
|
||||
def load_config(self, commands):
|
||||
def load_config(self, commands, return_error=False):
|
||||
"""Sends the ordered set of commands to the device
|
||||
"""
|
||||
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 []
|
||||
|
||||
|
||||
|
@ -397,6 +403,6 @@ def run_commands(module, commands, check_rc=True):
|
|||
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)
|
||||
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
|
||||
|
||||
|
||||
import re
|
||||
import re
|
||||
|
||||
|
||||
def execute_show_command(command, module, command_type='cli_show'):
|
||||
if module.params['transport'] == 'cli':
|
||||
if 'show run' not in command:
|
||||
|
@ -167,50 +163,16 @@ def get_udld_interface(module, interface):
|
|||
return interface_udld
|
||||
|
||||
|
||||
def is_interface_copper(module, interface):
|
||||
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):
|
||||
def get_commands_config_udld_interface1(delta, interface, module, existing):
|
||||
commands = []
|
||||
copper = is_interface_copper(module, interface)
|
||||
if delta:
|
||||
mode = delta['mode']
|
||||
if mode == 'aggressive':
|
||||
command = 'udld aggressive'
|
||||
elif copper:
|
||||
if mode == 'enabled':
|
||||
if existing['mode'] == 'aggressive':
|
||||
command = 'no udld aggressive ; udld enable'
|
||||
else:
|
||||
command = 'udld enable'
|
||||
elif mode == 'disabled':
|
||||
command = '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'
|
||||
command = 'no udld aggressive ; no udld enable'
|
||||
if command:
|
||||
commands.append(command)
|
||||
commands.insert(0, 'interface {0}'.format(interface))
|
||||
|
@ -218,20 +180,48 @@ def get_commands_config_udld_interface(delta, interface, module, existing):
|
|||
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 = []
|
||||
copper = is_interface_copper(module, interface)
|
||||
|
||||
if delta:
|
||||
mode = delta['mode']
|
||||
if mode == 'aggressive':
|
||||
command = 'no udld aggressive'
|
||||
elif copper:
|
||||
if mode == 'enabled':
|
||||
command = 'no udld enable'
|
||||
elif mode == 'disabled':
|
||||
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':
|
||||
command = 'udld disable'
|
||||
elif mode == 'disabled':
|
||||
|
@ -259,7 +249,6 @@ def main():
|
|||
warnings = list()
|
||||
check_args(module, warnings)
|
||||
|
||||
|
||||
interface = module.params['interface'].lower()
|
||||
mode = module.params['mode']
|
||||
state = module.params['state']
|
||||
|
@ -274,13 +263,13 @@ def main():
|
|||
commands = []
|
||||
if state == 'present':
|
||||
if delta:
|
||||
command = get_commands_config_udld_interface(delta, interface,
|
||||
command = get_commands_config_udld_interface1(delta, interface,
|
||||
module, existing)
|
||||
commands.append(command)
|
||||
elif state == 'absent':
|
||||
common = set(proposed.items()).intersection(existing.items())
|
||||
if common:
|
||||
command = get_commands_remove_udld_interface(
|
||||
command = get_commands_remove_udld_interface1(
|
||||
dict(common), interface, module, existing
|
||||
)
|
||||
commands.append(command)
|
||||
|
@ -291,7 +280,32 @@ def main():
|
|||
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)
|
||||
|
@ -306,5 +320,6 @@ def main():
|
|||
|
||||
module.exit_json(**results)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
Loading…
Reference in a new issue