mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-07-22 12:50:22 -07:00
Refactor ios cliconf plugin and ios_config module (#39695)
* Refactor ios cliconf plugin and ios_config module * Refactor ios cliconf plugin to support generic network_config module * Refactor ios_config module to work with cliconf api's * Enable command and response logging in cliconf pulgin * cliconf api documentation * Fix unit test and other minor changes * Doc update * Fix CI failure * Add default flag related changes * Minor changes * redact input command logging by default
This commit is contained in:
parent
9abc3dbec4
commit
ba4b12358c
8 changed files with 473 additions and 182 deletions
|
@ -291,17 +291,14 @@ backup_path:
|
|||
type: string
|
||||
sample: /playbooks/ansible/backup/ios_config.2016-07-16@22:28:34
|
||||
"""
|
||||
import re
|
||||
import time
|
||||
import json
|
||||
|
||||
from ansible.module_utils.network.ios.ios import run_commands, get_config, load_config
|
||||
from ansible.module_utils.network.ios.ios import get_defaults_flag
|
||||
from ansible.module_utils.network.ios.ios import run_commands, get_config
|
||||
from ansible.module_utils.network.ios.ios import get_defaults_flag, get_connection
|
||||
from ansible.module_utils.network.ios.ios import ios_argument_spec
|
||||
from ansible.module_utils.network.ios.ios import check_args as ios_check_args
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.network.common.parsing import Conditional
|
||||
from ansible.module_utils.network.common.config import NetworkConfig, dumps
|
||||
from ansible.module_utils.six import iteritems
|
||||
|
||||
|
||||
def check_args(module, warnings):
|
||||
|
@ -312,70 +309,29 @@ def check_args(module, warnings):
|
|||
'single character')
|
||||
|
||||
|
||||
def extract_banners(config):
|
||||
banners = {}
|
||||
banner_cmds = re.findall(r'^banner (\w+)', config, re.M)
|
||||
for cmd in banner_cmds:
|
||||
regex = r'banner %s \^C(.+?)(?=\^C)' % cmd
|
||||
match = re.search(regex, config, re.S)
|
||||
if match:
|
||||
key = 'banner %s' % cmd
|
||||
banners[key] = match.group(1).strip()
|
||||
def get_candidate_config(module):
|
||||
candidate = ''
|
||||
if module.params['src']:
|
||||
candidate = module.params['src']
|
||||
|
||||
for cmd in banner_cmds:
|
||||
regex = r'banner %s \^C(.+?)(?=\^C)' % cmd
|
||||
match = re.search(regex, config, re.S)
|
||||
if match:
|
||||
config = config.replace(str(match.group(1)), '')
|
||||
elif module.params['lines']:
|
||||
candidate_obj = NetworkConfig(indent=1)
|
||||
parents = module.params['parents'] or list()
|
||||
candidate_obj.add(module.params['lines'], parents=parents)
|
||||
candidate = dumps(candidate_obj, 'raw')
|
||||
|
||||
config = re.sub(r'banner \w+ \^C\^C', '!! banner removed', config)
|
||||
return (config, banners)
|
||||
|
||||
|
||||
def diff_banners(want, have):
|
||||
candidate = {}
|
||||
for key, value in iteritems(want):
|
||||
if value != have.get(key):
|
||||
candidate[key] = value
|
||||
return candidate
|
||||
|
||||
|
||||
def load_banners(module, banners):
|
||||
delimiter = module.params['multiline_delimiter']
|
||||
for key, value in iteritems(banners):
|
||||
key += ' %s' % delimiter
|
||||
for cmd in ['config terminal', key, value, delimiter, 'end']:
|
||||
obj = {'command': cmd, 'sendonly': True}
|
||||
run_commands(module, [cmd])
|
||||
time.sleep(0.1)
|
||||
run_commands(module, ['\n'])
|
||||
|
||||
|
||||
def get_running_config(module, current_config=None, flags=None):
|
||||
contents = module.params['running_config']
|
||||
|
||||
if not contents:
|
||||
running = module.params['running_config']
|
||||
if not running:
|
||||
if not module.params['defaults'] and current_config:
|
||||
contents, banners = extract_banners(current_config.config_text)
|
||||
running = current_config
|
||||
else:
|
||||
contents = get_config(module, flags=flags)
|
||||
contents, banners = extract_banners(contents)
|
||||
return NetworkConfig(indent=1, contents=contents), banners
|
||||
running = get_config(module, flags=flags)
|
||||
|
||||
|
||||
def get_candidate(module):
|
||||
candidate = NetworkConfig(indent=1)
|
||||
banners = {}
|
||||
|
||||
if module.params['src']:
|
||||
src, banners = extract_banners(module.params['src'])
|
||||
candidate.load(src)
|
||||
|
||||
elif module.params['lines']:
|
||||
parents = module.params['parents'] or list()
|
||||
candidate.add(module.params['lines'], parents=parents)
|
||||
|
||||
return candidate, banners
|
||||
return running
|
||||
|
||||
|
||||
def save_config(module, result):
|
||||
|
@ -445,7 +401,9 @@ def main():
|
|||
result['warnings'] = warnings
|
||||
|
||||
config = None
|
||||
contents = None
|
||||
flags = get_defaults_flag(module) if module.params['defaults'] else []
|
||||
connection = get_connection(module)
|
||||
|
||||
if module.params['backup'] or (module._diff and module.params['diff_against'] == 'running'):
|
||||
contents = get_config(module, flags=flags)
|
||||
|
@ -458,20 +416,16 @@ def main():
|
|||
replace = module.params['replace']
|
||||
path = module.params['parents']
|
||||
|
||||
candidate, want_banners = get_candidate(module)
|
||||
candidate = get_candidate_config(module)
|
||||
running = get_running_config(module, contents, flags=flags)
|
||||
|
||||
if match != 'none':
|
||||
config, have_banners = get_running_config(module, config, flags=flags)
|
||||
path = module.params['parents']
|
||||
configobjs = candidate.difference(config, path=path, match=match, replace=replace)
|
||||
else:
|
||||
configobjs = candidate.items
|
||||
have_banners = {}
|
||||
response = connection.get_diff(candidate=candidate, running=running, match=match, diff_ignore_lines=None, path=path, replace=replace)
|
||||
diff = json.loads(response)
|
||||
config_diff = diff['config_diff']
|
||||
banner_diff = diff['banner_diff']
|
||||
|
||||
banners = diff_banners(want_banners, have_banners)
|
||||
|
||||
if configobjs or banners:
|
||||
commands = dumps(configobjs, 'commands').split('\n')
|
||||
if config_diff or banner_diff:
|
||||
commands = config_diff.split('\n')
|
||||
|
||||
if module.params['before']:
|
||||
commands[:0] = module.params['before']
|
||||
|
@ -481,15 +435,15 @@ def main():
|
|||
|
||||
result['commands'] = commands
|
||||
result['updates'] = commands
|
||||
result['banners'] = banners
|
||||
result['banners'] = banner_diff
|
||||
|
||||
# send the configuration commands to the device and merge
|
||||
# them with the current running config
|
||||
if not module.check_mode:
|
||||
if commands:
|
||||
load_config(module, commands)
|
||||
if banners:
|
||||
load_banners(module, banners)
|
||||
connection.edit_config(commands)
|
||||
if banner_diff:
|
||||
connection.edit_banner(json.dumps(banner_diff), multiline_delimiter=module.params['multiline_delimiter'])
|
||||
|
||||
result['changed'] = True
|
||||
|
||||
|
@ -556,6 +510,5 @@ def main():
|
|||
|
||||
module.exit_json(**result)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue