From 2be917851d5c8ce1b5d7b9ae3da6db5693504022 Mon Sep 17 00:00:00 2001 From: Peter Sprygada Date: Fri, 10 Jun 2016 15:37:45 -0400 Subject: [PATCH] refactor ios_command to use CommandRunner class * fixes running commands in check mode. now only show commands are allowd * renamed waitfor to wait_for with alias to waitfor for consistency --- network/ios/ios_command.py | 77 +++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 34 deletions(-) diff --git a/network/ios/ios_command.py b/network/ios/ios_command.py index 68afb04566c..d81ee862db2 100644 --- a/network/ios/ios_command.py +++ b/network/ios/ios_command.py @@ -37,7 +37,7 @@ options: module is not returned until the condition is satisfied or the number of retires as expired. required: true - waitfor: + wait_for: description: - List of conditions to evaluate against the output of the command. The task will wait for a each condition to be true @@ -46,6 +46,8 @@ options: See examples. required: false default: null + aliases: ['waitfor'] + version_added: "2.2" retries: description: - Specifies the number of retries a command should by tried @@ -104,10 +106,9 @@ failed_conditions: type: list sample: ['...', '...'] """ - -import time -import shlex -import re +from ansible.module_utils.netcmd import CommandRunner, FailedConditionsError +from ansible.module_utils.network import NetworkError +from ansible.module_utils.ios import get_module def to_lines(stdout): for item in stdout: @@ -118,54 +119,62 @@ def to_lines(stdout): def main(): spec = dict( commands=dict(type='list'), - waitfor=dict(type='list'), + wait_for=dict(type='list'), retries=dict(default=10, type='int'), interval=dict(default=1, type='int') ) module = get_module(argument_spec=spec, + connect_on_load=False, supports_check_mode=True) commands = module.params['commands'] + conditionals = module.params['wait_for'] or list() + + warnings = list() + + runner = CommandRunner(module) + + for cmd in commands: + if module.check_mode and not cmd.startswith('show'): + warnings.append('only show commands are supported when using ' + 'check mode, not executing `%s`' % cmd) + else: + runner.add_command(cmd) - retries = module.params['retries'] - interval = module.params['interval'] + for item in conditionals: + runner.add_conditional(item) + + runner.retries = module.params['retries'] + runner.interval = module.params['interval'] try: - queue = set() - for entry in (module.params['waitfor'] or list()): - queue.add(Conditional(entry)) - except AttributeError: + runner.run() + except FailedConditionsError: + exc = get_exception() + module.fail_json(msg=str(exc), failed_conditions=exc.failed_conditions) + except NetworkError: exc = get_exception() - module.fail_json(msg=exc.message) + module.fail_json(msg=str(exc)) result = dict(changed=False) - while retries > 0: - response = module.execute(commands) - result['stdout'] = response + result['stdout'] = list() + for cmd in commands: + try: + output = runner.get_command(cmd) + except ValueError: + output = 'command not executed due to check_mode, see warnings' + result['stdout'].append(output) - for item in list(queue): - if item(response): - queue.remove(item) - if not queue: - break + result['warnings'] = warnings + result['connected'] = module.connected + result['stdout_lines'] = list(to_lines(result['stdout'])) - time.sleep(interval) - retries -= 1 - else: - failed_conditions = [item.raw for item in queue] - module.fail_json(msg='timeout waiting for value', failed_conditions=failed_conditions) + module.exit_json(**result) - result['stdout_lines'] = list(to_lines(result['stdout'])) - return module.exit_json(**result) -from ansible.module_utils.basic import * -from ansible.module_utils.urls import * -from ansible.module_utils.shell import * -from ansible.module_utils.netcfg import * -from ansible.module_utils.ios import * if __name__ == '__main__': - main() + main()