nxos_udld_interface: improve interface detection (#28682)

* fix for nxos_udld_interface

* Tested Note added back
This commit is contained in:
saichint 2017-09-13 11:06:56 -07:00 committed by Nathaniel Case
parent 6d196eaa98
commit 4e32c92166
2 changed files with 88 additions and 67 deletions

View file

@ -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,7 +287,10 @@ class Nxapi:
output = response['ins_api']['outputs']['output']
for item in to_list(output):
if check_status and item['code'] != '200':
self._error(output=output, **item)
if return_error:
result.append(item)
else:
self._error(output=output, **item)
elif 'body' in item:
result.append(item['body'])
# else:
@ -341,12 +344,15 @@ 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')
return []
msg = self.send_request(commands, output='config', check_status=True, return_error=return_error)
if return_error:
return msg
else:
return []
def is_json(cmd):
@ -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)

View file

@ -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'
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))
@ -218,24 +180,52 @@ 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 mode == 'enabled':
command = 'udld disable'
elif mode == 'disabled':
command = 'no udld disable'
if mode == 'enabled':
command = 'no udld enable'
elif mode == 'disabled':
command = 'udld enable'
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':
command = 'no udld disable'
if command:
commands.append(command)
commands.insert(0, 'interface {0}'.format(interface))
@ -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
load_config(module, cmds)
# 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()