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:
parent
40eb349ac6
commit
089226e372
5 changed files with 136 additions and 50 deletions
|
@ -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]
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in a new issue