From 75d7c70e703670296411e0b57c8f26f2ae60d2f0 Mon Sep 17 00:00:00 2001 From: Dhivyap Date: Wed, 22 Feb 2017 20:28:21 +0530 Subject: [PATCH] Fixes#5534-Handled Command Prompt in exec mode (#21651) * Fixes#5534-Handled Command Prompt in exec mode * Pep8 Cleanup --- .../network/dellos10/dellos10_command.py | 24 +++++++++++--- .../network/dellos6/dellos6_command.py | 31 ++++++++++++++----- .../network/dellos9/dellos9_command.py | 22 ++++++++++--- 3 files changed, 60 insertions(+), 17 deletions(-) diff --git a/lib/ansible/modules/network/dellos10/dellos10_command.py b/lib/ansible/modules/network/dellos10/dellos10_command.py index 64bfbe50b3..07bcbc3566 100644 --- a/lib/ansible/modules/network/dellos10/dellos10_command.py +++ b/lib/ansible/modules/network/dellos10/dellos10_command.py @@ -143,16 +143,30 @@ warnings: from ansible.module_utils.basic import get_exception from ansible.module_utils.netcli import CommandRunner, FailedConditionsError from ansible.module_utils.network import NetworkModule, NetworkError +from ansible.module_utils.six import string_types import ansible.module_utils.dellos10 +VALID_KEYS = ['command', 'prompt', 'response'] + def to_lines(stdout): for item in stdout: if isinstance(item, basestring): item = str(item).split('\n') yield item +def parse_commands(module): + for cmd in module.params['commands']: + if isinstance(cmd, string_types): + cmd = dict(command=cmd, output=None) + elif 'command' not in cmd: + module.fail_json(msg='command keyword argument is required') + elif not set(cmd.keys()).issubset(VALID_KEYS): + module.fail_json(msg='unknown keyword specified') + yield cmd + def main(): spec = dict( + # { command: , prompt: , response: } commands=dict(type='list', required=True), wait_for=dict(type='list'), retries=dict(default=10, type='int'), @@ -163,7 +177,7 @@ def main(): connect_on_load=False, supports_check_mode=True) - commands = module.params['commands'] + commands = list(parse_commands(module)) conditionals = module.params['wait_for'] or list() warnings = list() @@ -171,15 +185,15 @@ def main(): runner = CommandRunner(module) for cmd in commands: - if module.check_mode and not cmd.startswith('show'): + if module.check_mode and not cmd['command'].startswith('show'): warnings.append('only show commands are supported when using ' 'check mode, not executing `%s`' % cmd) else: - if cmd.startswith('conf'): + if cmd['command'].startswith('conf'): module.fail_json(msg='dellos10_command does not support running ' 'config mode commands. Please use ' 'dellos10_config instead') - runner.add_command(cmd) + runner.add_command(**cmd) for item in conditionals: runner.add_conditional(item) @@ -201,7 +215,7 @@ def main(): result['stdout'] = list() for cmd in commands: try: - output = runner.get_command(cmd) + output = runner.get_command(cmd['command']) except ValueError: output = 'command not executed due to check_mode, see warnings' result['stdout'].append(output) diff --git a/lib/ansible/modules/network/dellos6/dellos6_command.py b/lib/ansible/modules/network/dellos6/dellos6_command.py index 6aa601af49..814e660e31 100644 --- a/lib/ansible/modules/network/dellos6/dellos6_command.py +++ b/lib/ansible/modules/network/dellos6/dellos6_command.py @@ -28,10 +28,11 @@ DOCUMENTATION = """ --- module: dellos6_command version_added: "2.2" +author: "Abirami N (@abirami-n)" short_description: Run commands on remote devices running Dell OS6 description: - Sends arbitrary commands to a Dell OS6 node and returns the results - read from the device. The C(dellos6_command) module includes an + read from the device. This module includes an argument that will cause the module to wait for a specific condition before returning or timing out if the condition is not met. - This module does not support running commands in configuration mode. @@ -143,6 +144,10 @@ from ansible.module_utils.basic import get_exception from ansible.module_utils.netcli import CommandRunner, FailedConditionsError from ansible.module_utils.network import NetworkModule, NetworkError import ansible.module_utils.dellos6 +from ansible.module_utils.six import string_types + +VALID_KEYS = ['command', 'prompt', 'response'] + def to_lines(stdout): for item in stdout: @@ -150,6 +155,15 @@ def to_lines(stdout): item = str(item).split('\n') yield item +def parse_commands(module): + for cmd in module.params['commands']: + if isinstance(cmd, string_types): + cmd = dict(command=cmd, output=None) + elif 'command' not in cmd: + module.fail_json(msg='command keyword argument is required') + elif not set(cmd.keys()).issubset(VALID_KEYS): + module.fail_json(msg='unknown keyword specified') + yield cmd def main(): spec = dict( @@ -162,8 +176,7 @@ def main(): module = NetworkModule(argument_spec=spec, connect_on_load=False, supports_check_mode=True) - - commands = module.params['commands'] + commands = list(parse_commands(module)) conditionals = module.params['wait_for'] or list() warnings = list() @@ -171,15 +184,19 @@ def main(): runner = CommandRunner(module) for cmd in commands: - if module.check_mode and not cmd.startswith('show'): + if module.check_mode and not cmd['command'].startswith('show'): warnings.append('only show commands are supported when using ' 'check mode, not executing `%s`' % cmd) else: - if cmd.startswith('conf'): + if cmd['command'].startswith('conf'): module.fail_json(msg='dellos6_command does not support running ' 'config mode commands. Please use ' 'dellos6_config instead') - runner.add_command(cmd) + try: + runner.add_command(**cmd) + except AddCommandError: + exc = get_exception() + warnings.append('duplicate command detected: %s' % cmd) for item in conditionals: runner.add_conditional(item) @@ -201,7 +218,7 @@ def main(): result['stdout'] = list() for cmd in commands: try: - output = runner.get_command(cmd) + output = runner.get_command(cmd['command']) except ValueError: output = 'command not executed due to check_mode, see warnings' result['stdout'].append(output) diff --git a/lib/ansible/modules/network/dellos9/dellos9_command.py b/lib/ansible/modules/network/dellos9/dellos9_command.py index 110bc1de9c..c3c4eedbcd 100755 --- a/lib/ansible/modules/network/dellos9/dellos9_command.py +++ b/lib/ansible/modules/network/dellos9/dellos9_command.py @@ -152,8 +152,10 @@ warnings: from ansible.module_utils.basic import get_exception from ansible.module_utils.netcli import CommandRunner, FailedConditionsError from ansible.module_utils.network import NetworkModule, NetworkError +from ansible.module_utils.six import string_types import ansible.module_utils.dellos9 +VALID_KEYS = ['command', 'prompt', 'response'] def to_lines(stdout): for item in stdout: @@ -161,9 +163,19 @@ def to_lines(stdout): item = str(item).split('\n') yield item +def parse_commands(module): + for cmd in module.params['commands']: + if isinstance(cmd, string_types): + cmd = dict(command=cmd, output=None) + elif 'command' not in cmd: + module.fail_json(msg='command keyword argument is required') + elif not set(cmd.keys()).issubset(VALID_KEYS): + module.fail_json(msg='unknown keyword specified') + yield cmd def main(): spec = dict( + # { command: , prompt: , response: } commands=dict(type='list', required=True), wait_for=dict(type='list'), retries=dict(default=10, type='int'), @@ -174,7 +186,7 @@ def main(): connect_on_load=False, supports_check_mode=True) - commands = module.params['commands'] + commands = list(parse_commands(module)) conditionals = module.params['wait_for'] or list() warnings = list() @@ -182,15 +194,15 @@ def main(): runner = CommandRunner(module) for cmd in commands: - if module.check_mode and not cmd.startswith('show'): + if module.check_mode and not cmd['command'].startswith('show'): warnings.append('only show commands are supported when using ' 'check mode, not executing `%s`' % cmd) else: - if cmd.startswith('conf'): + if cmd['command'].startswith('conf'): module.fail_json(msg='dellos9_command does not support running ' 'config mode commands. Please use ' 'dellos9_config instead') - runner.add_command(cmd) + runner.add_command(**cmd) for item in conditionals: runner.add_conditional(item) @@ -212,7 +224,7 @@ def main(): result['stdout'] = list() for cmd in commands: try: - output = runner.get_command(cmd) + output = runner.get_command(cmd['command']) except ValueError: output = 'command not executed due to check_mode, see warnings' result['stdout'].append(output)