diff --git a/lib/ansible/module_utils/nxos.py b/lib/ansible/module_utils/nxos.py index 502c118386f..aecd9811523 100644 --- a/lib/ansible/module_utils/nxos.py +++ b/lib/ansible/module_utils/nxos.py @@ -159,7 +159,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 """ @@ -238,7 +238,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': @@ -289,7 +289,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): @@ -395,6 +401,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) diff --git a/lib/ansible/modules/network/nxos/nxos_udld_interface.py b/lib/ansible/modules/network/nxos/nxos_udld_interface.py index 2c9d154b81a..c1146f2b532 100644 --- a/lib/ansible/modules/network/nxos/nxos_udld_interface.py +++ b/lib/ansible/modules/network/nxos/nxos_udld_interface.py @@ -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,33 @@ 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 +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)) - return found + return commands -def get_commands_config_udld_interface(delta, interface, module, existing): +def get_commands_config_udld_interface2(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 ; no udld disable' + elif mode == 'disabled': + command = 'no udld aggressive ; udld disable' if command: commands.append(command) commands.insert(0, 'interface {0}'.format(interface)) @@ -218,24 +197,35 @@ 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_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,6 +320,7 @@ def main(): module.exit_json(**results) + if __name__ == '__main__': main()