fix up ios_command to use NetworkModule

* using check mode will now block all commands except show commands
* module will no longer allow config mode commands
* check args for unused values and issue warning
This commit is contained in:
Peter Sprygada 2016-07-09 15:17:59 -04:00 committed by Matt Clay
parent b86a229b61
commit 66268dd3ec

View file

@ -20,13 +20,15 @@ DOCUMENTATION = """
--- ---
module: ios_command module: ios_command
version_added: "2.1" version_added: "2.1"
author: "Peter sprygada (@privateip)" author: "Peter Sprygada (@privateip)"
short_description: Run arbitrary commands on ios devices. short_description: Run commands on remote devices running Cisco IOS
description: description:
- Sends arbitrary commands to an ios node and returns the results - Sends arbitrary commands to an ios node and returns the results
read from the device. The M(ios_command) module includes an read from the device. The M(ios_command) module includes an
argument that will cause the module to wait for a specific condition argument that will cause the module to wait for a specific condition
before returning or timing out if the condition is not met. before returning or timing out if the condition is not met.
- This module does not support running commands in configuration mode.
Please use M(ios_config) to configure IOS devices.
extends_documentation_fragment: ios extends_documentation_fragment: ios
options: options:
commands: commands:
@ -64,32 +66,50 @@ options:
trying the command again. trying the command again.
required: false required: false
default: 1 default: 1
""" """
EXAMPLES = """ EXAMPLES = """
# Note: examples below use the following provider dict to handle
# transport and authentication to the node.
vars:
cli:
host: "{{ inventory_hostname }}"
username: cisco
password: cisco
transport: cli
- ios_command: - name: run show verion on remote devices
commands: ios_command:
- show version commands: show version
register: output provider "{{ cli }}"
- ios_command: - name: run show version and check to see if output contains IOS
commands: ios_command:
- show version commands: show version
waitfor: wait_for: result[0] contains IOS
- "result[0] contains IOS" provider "{{ cli }}"
- ios_command: - name: run multiple commands on remote nodes
ios_command:
commands: commands:
- show version - show version
- show interfaces - show interfaces
provider "{{ cli }}"
- name: run multiple commands and evalute the output
ios_command:
commands:
- show version
- show interfaces
wait_for:
- result[0] contains IOS
- result[1] contains Loopback0
provider "{{ cli }}"
""" """
RETURN = """ RETURN = """
stdout: stdout:
description: the set of responses from the commands description: The set of responses from the commands
returned: always returned: always
type: list type: list
sample: ['...', '...'] sample: ['...', '...']
@ -101,14 +121,23 @@ stdout_lines:
sample: [['...', '...'], ['...'], ['...']] sample: [['...', '...'], ['...'], ['...']]
failed_conditions: failed_conditions:
description: the conditionals that failed description: The list of conditionals that have failed
retured: failed retured: failed
type: list type: list
sample: ['...', '...'] sample: ['...', '...']
warnings:
description: The list of warnings (if any) generated by module based on arguments
returned: always
type: list
sample: ['...', '...']
""" """
from ansible.module_utils.netcmd import CommandRunner, FailedConditionsError from ansible.module_utils.netcmd import CommandRunner, FailedConditionsError
from ansible.module_utils.network import NetworkError from ansible.module_utils.ios import NetworkModule, NetworkError
from ansible.module_utils.ios import get_module
def check_args(module, warnings):
if module.params['save_config'] is True:
warnings.append('save_config argument will be ignored')
def to_lines(stdout): def to_lines(stdout):
for item in stdout: for item in stdout:
@ -118,20 +147,21 @@ def to_lines(stdout):
def main(): def main():
spec = dict( spec = dict(
commands=dict(type='list'), commands=dict(type='list', required=True),
wait_for=dict(type='list'), wait_for=dict(type='list'),
retries=dict(default=10, type='int'), retries=dict(default=10, type='int'),
interval=dict(default=1, type='int') interval=dict(default=1, type='int')
) )
module = get_module(argument_spec=spec, module = NetworkModule(argument_spec=spec,
connect_on_load=False, connect_on_load=False,
supports_check_mode=True) supports_check_mode=True)
commands = module.params['commands'] commands = module.params['commands']
conditionals = module.params['wait_for'] or list() conditionals = module.params['wait_for'] or list()
warnings = list() warnings = list()
check_args(module, warnings)
runner = CommandRunner(module) runner = CommandRunner(module)
@ -140,6 +170,10 @@ def main():
warnings.append('only show commands are supported when using ' warnings.append('only show commands are supported when using '
'check mode, not executing `%s`' % cmd) 'check mode, not executing `%s`' % cmd)
else: else:
if cmd.startswith('conf'):
module.fail_json(msg='ios_command does not support running '
'config mode commands. Please use '
'ios_config instead')
runner.add_command(cmd) runner.add_command(cmd)
for item in conditionals: for item in conditionals:
@ -169,7 +203,6 @@ def main():
result['warnings'] = warnings result['warnings'] = warnings
result['connected'] = module.connected
result['stdout_lines'] = list(to_lines(result['stdout'])) result['stdout_lines'] = list(to_lines(result['stdout']))
module.exit_json(**result) module.exit_json(**result)