diff --git a/changelogs/fragments/59728-ce_config-to-fix-bugs.yml b/changelogs/fragments/59728-ce_config-to-fix-bugs.yml new file mode 100644 index 00000000000..acdc74b914f --- /dev/null +++ b/changelogs/fragments/59728-ce_config-to-fix-bugs.yml @@ -0,0 +1,2 @@ +bugfixes: +- ce_config - Optimize multi-level views & fix a bug. (https://github.com/ansible/ansible/pull/59523) diff --git a/lib/ansible/modules/network/cloudengine/ce_config.py b/lib/ansible/modules/network/cloudengine/ce_config.py index a18e5363534..011dba46b13 100644 --- a/lib/ansible/modules/network/cloudengine/ce_config.py +++ b/lib/ansible/modules/network/cloudengine/ce_config.py @@ -220,9 +220,10 @@ backup_path: sample: /playbooks/ansible/backup/ce_config.2016-07-16@22:28:34 """ from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.common.config import NetworkConfig, dumps -from ansible.module_utils.network.cloudengine.ce import get_config, load_config, run_commands -from ansible.module_utils.network.cloudengine.ce import ce_argument_spec +from ansible.module_utils.network.common.config import NetworkConfig as _NetworkConfig +from ansible.module_utils.network.common.config import dumps, ConfigLine, ignore_line +from ansible.module_utils.network.cloudengine.ce import get_config, run_commands, exec_command, cli_err_msg +from ansible.module_utils.network.cloudengine.ce import ce_argument_spec, load_config from ansible.module_utils.network.cloudengine.ce import check_args as ce_check_args import re @@ -231,48 +232,60 @@ def check_args(module, warnings): ce_check_args(module, warnings) -def get_running_config(module): - contents = module.params['config'] - if not contents: - flags = [] - if module.params['defaults']: - flags.append('include-default') - contents = get_config(module, flags=flags) - return NetworkConfig(indent=1, contents=contents) +def _load_config(module, config): + """Sends configuration commands to the remote device + """ + rc, out, err = exec_command(module, 'mmi-mode enable') + if rc != 0: + module.fail_json(msg='unable to set mmi-mode enable', output=err) + rc, out, err = exec_command(module, 'system-view immediately') + if rc != 0: + module.fail_json(msg='unable to enter system-view', output=err) + + for index, cmd in enumerate(config): + rc, out, err = exec_command(module, cmd) + if rc != 0: + print_msg = cli_err_msg(cmd.strip(), err) + exec_command(module, "quit") + rc, out, err = exec_command(module, cmd) + if rc != 0: + print_msg1 = cli_err_msg(cmd.strip(), err) + if not re.findall(r"unrecognized command found", print_msg1): + print_msg = print_msg1 + exec_command(module, "return") + exec_command(module, "system-view immediately") + rc, out, err = exec_command(module, cmd) + if rc != 0: + print_msg2 = cli_err_msg(cmd.strip(), err) + if not re.findall(r"unrecognized command found", print_msg2): + print_msg = print_msg2 + module.fail_json(msg=print_msg) + + exec_command(module, 'return') def conversion_src(module): src_list = module.params['src'].split('\n') src_list_organize = [] - exit_list = [' return', ' system-view'] if src_list[0].strip() == '#': src_list.pop(0) for per_config in src_list: if per_config.strip() == '#': - if per_config.rstrip() == '#': - src_list_organize.extend(exit_list) - else: - src_list_organize.append('quit') + src_list_organize.append('quit') else: src_list_organize.append(per_config) src_str = '\n'.join(src_list_organize) return src_str -def conversion_lines(commands): - all_config = [] - exit_list = [' return', ' system-view'] - for per_command in commands: - if re.search(r',', per_command): - all_config.extend(exit_list) - per_config = per_command.split(',') - for config in per_config: - if config: - all_config.append(config) - all_config.extend(exit_list) - else: - all_config.append(per_command) - return all_config +def get_running_config(module): + contents = module.params['config'] + if not contents: + flags = [] + if module.params['defaults']: + flags.append('include-default') + contents = get_config(module, flags=flags) + return NetworkConfig(indent=1, contents=contents) def get_candidate(module): @@ -289,6 +302,7 @@ def get_candidate(module): def run(module, result): match = module.params['match'] replace = module.params['replace'] + candidate = get_candidate(module) if match != 'none': @@ -300,10 +314,8 @@ def run(module, result): if configobjs: commands = dumps(configobjs, 'commands').split('\n') - if module.params['lines']: - - commands = conversion_lines(commands) + if module.params['lines']: if module.params['before']: commands[:0] = module.params['before'] @@ -317,10 +329,69 @@ def run(module, result): result['commands'] = command_display result['updates'] = command_display + if not module.check_mode: - load_config(module, commands) - if result['commands']: - result['changed'] = True + if module.params['parents'] is not None: + load_config(module, commands) + else: + _load_config(module, commands) + + result['changed'] = True + + +class NetworkConfig(_NetworkConfig): + + def add(self, lines, parents=None): + ancestors = list() + offset = 0 + obj = None + + # global config command + if not parents: + for line in lines: + # handle ignore lines + if ignore_line(line): + continue + + item = ConfigLine(line) + item.raw = line + self.items.append(item) + + else: + for index, p in enumerate(parents): + try: + i = index + 1 + obj = self.get_block(parents[:i])[0] + ancestors.append(obj) + + except ValueError: + # add parent to config + offset = index * self._indent + obj = ConfigLine(p) + obj.raw = p.rjust(len(p) + offset) + if ancestors: + obj._parents = list(ancestors) + ancestors[-1]._children.append(obj) + self.items.append(obj) + ancestors.append(obj) + + # add child objects + for line in lines: + # handle ignore lines + if ignore_line(line): + continue + + # check if child already exists + for child in ancestors[-1]._children: + if child.text == line: + break + else: + offset = len(parents) * self._indent + item = ConfigLine(line) + item.raw = line.rjust(len(line) + offset) + item._parents = ancestors + ancestors[-1]._children.append(item) + self.items.append(item) def main():