1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

Fixes for broken asa_config module (#27218)

* Fixes for broken asa_config module

* strip() prompt before checking
This commit is contained in:
Patrick Ogenstad 2017-08-11 17:42:42 +02:00 committed by Peter Sprygada
parent 40eb349ac6
commit 089226e372
5 changed files with 136 additions and 50 deletions

View file

@ -103,9 +103,10 @@ def to_commands(module, commands):
def run_commands(module, commands, check_rc=True):
commands = to_commands(module, to_list(commands))
connection = get_connection(module)
commands = to_commands(module, to_list(commands))
responses = list()
for cmd in commands:
@ -116,9 +117,13 @@ def run_commands(module, commands, check_rc=True):
def get_config(module, flags=[]):
cmd = 'show running-config '
cmd += ' '.join(flags)
cmd = cmd.strip()
passwords = module.params['passwords']
if passwords:
cmd = 'more system:running-config'
else:
cmd = 'show running-config '
cmd += ' '.join(flags)
cmd = cmd.strip()
try:
return _DEVICE_CONFIGS[cmd]

View file

@ -172,7 +172,6 @@ vars:
password: cisco
authorize: yes
auth_pass: cisco
transport: cli
---
- asa_config:
@ -216,30 +215,14 @@ backup_path:
returned: when backup is yes
type: string
sample: /playbooks/ansible/backup/asa_config.2016-07-16@22:28:34
responses:
description: The set of responses from issuing the commands on the device
returned: when not check_mode
type: list
sample: ['...', '...']
"""
import traceback
from ansible.module_utils.network import NetworkModule, NetworkError
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.asa import asa_argument_spec, check_args
from ansible.module_utils.asa import get_config, load_config, run_commands
from ansible.module_utils.netcfg import NetworkConfig, dumps
from ansible.module_utils._text import to_native
def get_config(module):
contents = module.params['config']
if not contents:
if module.params['defaults']:
include = 'defaults'
elif module.params['passwords']:
include = 'passwords'
else:
include = None
contents = module.config.get_config(include=include)
return NetworkConfig(indent=1, contents=contents)
def get_candidate(module):
candidate = NetworkConfig(indent=1)
@ -256,11 +239,14 @@ def run(module, result):
path = module.params['parents']
candidate = get_candidate(module)
if match != 'none':
config = get_config(module)
configobjs = candidate.difference(config, path=path, match=match,
replace=replace)
contents = module.params['config']
if not contents:
contents = get_config(module)
config = NetworkConfig(indent=1, contents=contents)
configobjs = candidate.difference(config, path=path, match=match,
replace=replace)
else:
configobjs = candidate.items
@ -279,7 +265,7 @@ def run(module, result):
# send the configuration commands to the device and merge
# them with the current running config
if not module.check_mode:
result['responses'] = module.config.load_config(commands)
load_config(module, commands)
result['changed'] = True
if module.params['save']:
@ -310,27 +296,30 @@ def main():
save=dict(type='bool', default=False),
)
argument_spec.update(asa_argument_spec)
mutually_exclusive = [('lines', 'src'), ('defaults', 'passwords')]
required_if = [('match', 'strict', ['lines']),
('match', 'exact', ['lines']),
('replace', 'block', ['lines'])]
module = NetworkModule(argument_spec=argument_spec,
connect_on_load=False,
module = AnsibleModule(argument_spec=argument_spec,
mutually_exclusive=mutually_exclusive,
required_if=required_if,
supports_check_mode=True)
result = dict(changed=False)
result = {'changed': False}
check_args(module)
config = None
if module.params['backup']:
result['__backup__'] = module.config.get_config()
result['__backup__'] = get_config(module)
try:
run(module, result)
except NetworkError as e:
module.fail_json(msg=to_native(e), exception=traceback.format_exc(), **e.kwargs)
run(module, result)
module.exit_json(**result)

View file

@ -77,11 +77,6 @@ class ActionModule(_ActionModule):
result = super(ActionModule, self).run(tmp, task_vars)
# take the shell out of enable mode
if pc.become:
req = json.dumps(request_builder('get', 'disable'))
out = connection.exec_command(req)
return result
def load_provider(self):

View file

@ -1,5 +1,5 @@
#
# Copyright 2015 Peter Sprygada <psprygada@ansible.com>
# (c) 2017, Red Hat, Inc.
#
# This file is part of Ansible
#
@ -19,9 +19,94 @@
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from ansible.plugins.action import ActionBase
from ansible.plugins.action.net_config import ActionModule as NetActionModule
import os
import re
import time
import glob
from ansible.plugins.action.asa import ActionModule as _ActionModule
from ansible.module_utils._text import to_text
from ansible.module_utils.six.moves.urllib.parse import urlsplit
from ansible.utils.vars import merge_hash
PRIVATE_KEYS_RE = re.compile('__.+__')
class ActionModule(NetActionModule, ActionBase):
pass
class ActionModule(_ActionModule):
def run(self, tmp=None, task_vars=None):
if self._task.args.get('src'):
try:
self._handle_template()
except ValueError as exc:
return dict(failed=True, msg=exc.message)
result = super(ActionModule, self).run(tmp, task_vars)
if self._task.args.get('backup') and result.get('__backup__'):
# User requested backup and no error occurred in module.
# NOTE: If there is a parameter error, _backup key may not be in results.
filepath = self._write_backup(task_vars['inventory_hostname'],
result['__backup__'])
result['backup_path'] = filepath
# strip out any keys that have two leading and two trailing
# underscore characters
for key in result.keys():
if PRIVATE_KEYS_RE.match(key):
del result[key]
return result
def _get_working_path(self):
cwd = self._loader.get_basedir()
if self._task._role is not None:
cwd = self._task._role._role_path
return cwd
def _write_backup(self, host, contents):
backup_path = self._get_working_path() + '/backup'
if not os.path.exists(backup_path):
os.mkdir(backup_path)
for fn in glob.glob('%s/%s*' % (backup_path, host)):
os.remove(fn)
tstamp = time.strftime("%Y-%m-%d@%H:%M:%S", time.localtime(time.time()))
filename = '%s/%s_config.%s' % (backup_path, host, tstamp)
open(filename, 'w').write(contents)
return filename
def _handle_template(self):
src = self._task.args.get('src')
working_path = self._get_working_path()
if os.path.isabs(src) or urlsplit('src').scheme:
source = src
else:
source = self._loader.path_dwim_relative(working_path, 'templates', src)
if not source:
source = self._loader.path_dwim_relative(working_path, src)
if not os.path.exists(source):
raise ValueError('path specified in src not found')
try:
with open(source, 'r') as f:
template_data = to_text(f.read())
except IOError:
return dict(failed=True, msg='unable to load src file')
# Create a template search path in the following order:
# [working_path, self_role_path, dependent_role_paths, dirname(source)]
searchpath = [working_path]
if self._task._role is not None:
searchpath.append(self._task._role._role_path)
if hasattr(self._task, "_block:"):
dep_chain = self._task._block.get_dep_chain()
if dep_chain is not None:
for role in dep_chain:
searchpath.append(role._role_path)
searchpath.append(os.path.dirname(source))
self._templar.environment.loader.searchpath = searchpath
self._task.args['src'] = self._templar.template(template_data)

View file

@ -36,11 +36,22 @@ class TerminalModule(TerminalBase):
terminal_stderr_re = [
re.compile(r"error:", re.I),
re.compile(r"^Removing.* not allowed")
re.compile(br"Removing.* not allowed, it is being used")
]
def on_authorize(self, passwd=None):
def on_open_shell(self):
if self._get_prompt().endswith(b'#'):
self.disable_pager()
def disable_pager(self):
cmd = {u'command': u'no terminal pager'}
try:
self._exec_cli_command(u'no terminal pager')
except AnsibleConnectionFailure:
raise AnsibleConnectionFailure('unable to disable terminal pager')
def on_authorize(self, passwd=None):
if self._get_prompt().strip().endswith(b'#'):
return
cmd = {u'command': u'enable'}
@ -52,6 +63,7 @@ class TerminalModule(TerminalBase):
try:
self._exec_cli_command(to_bytes(json.dumps(cmd), errors='surrogate_or_strict'))
self._exec_cli_command(u'no terminal pager')
except AnsibleConnectionFailure:
raise AnsibleConnectionFailure('unable to elevate privilege to enable mode')
self.disable_pager()