ce_config/bug/jingdong: a bug from jingdong. (#62872)

* update to fix "`quit` may make seesion closed."

* update to fix "`quit` may make seesion closed."

* 274:49: E272: multiple spaces before keyword

* add a changelog fragment.

* Update ce_config.py

using run_command for prompts.

* Update ce_config.py

* Update ce_config.py

typo error

* update to use get_prompt

* Update ce_config.py

* Update ce_config.py

* Update ce_config.py

* Update ce_config.py

* Update ce_config.py

* Update ce_config.py

* Update ce_config.py
This commit is contained in:
Xu Yuandong 2019-10-22 19:38:10 +08:00 committed by ansibot
parent c317c3cadf
commit e4b6dd1862
2 changed files with 77 additions and 45 deletions

View file

@ -0,0 +1,2 @@
bugfixes:
- ce_config - fixed issue - Re-building commands(config src) by replacing '#' with 'quit','quit' commands may close connection (https://github.com/ansible/ansible/issues/62872)

View file

@ -220,6 +220,7 @@ 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.connection import ConnectionError, Connection
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
@ -232,71 +233,70 @@ def check_args(module, warnings):
ce_check_args(module, warnings)
def not_user_view(prompt):
return prompt is not None and prompt.strip().startswith("[")
def command_level(command):
regex_level = re.search(r"^(\s*)\S+", command)
if regex_level is not None:
level = str(regex_level.group(1))
return len(level)
return 0
def _load_config(module, config):
"""Sends configuration commands to the remote device
"""
connection = Connection(module._socket_path)
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)
current_view_prompt = system_view_prompt = connection.get_prompt()
for index, cmd in enumerate(config):
level = command_level(cmd)
current_view_prompt = connection.get_prompt()
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")
# re-try command max 3 times
for i in (1, 2, 3):
current_view_prompt = connection.get_prompt()
if current_view_prompt != system_view_prompt and not_user_view(current_view_prompt):
exec_command(module, "quit")
current_view_prompt = connection.get_prompt()
# if current view is system-view, break.
if current_view_prompt == system_view_prompt and level > 0:
break
elif current_view_prompt == system_view_prompt or not not_user_view(current_view_prompt):
break
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)
rc, out, err = exec_command(module, 'return')
if rc != 0:
module.fail_json(msg='unable to return', output=err)
rc, out, err = exec_command(module, 'undo mmi-mode enable')
if rc != 0:
module.fail_json(msg='unable to undo mmi-mode enable', output=err)
def conversion_src(module):
src_list = module.params['src'].split('\n')
src_list_organize = []
if src_list[0].strip() == '#':
src_list.pop(0)
for per_config in src_list:
if per_config.strip() == '#':
src_list_organize.append('quit')
else:
src_list_organize.append(per_config)
src_str = '\n'.join(src_list_organize)
return src_str
if rc == 0:
print_msg = None
break
if print_msg is not None:
module.fail_json(msg=print_msg)
def get_running_config(module):
contents = module.params['config']
if not contents:
flags = []
command = "display current-configuration "
if module.params['defaults']:
flags.append('include-default')
contents = get_config(module, flags=flags)
command += 'include-default'
resp = run_commands(module, command)
contents = resp[0]
return NetworkConfig(indent=1, contents=contents)
def get_candidate(module):
candidate = NetworkConfig(indent=1)
if module.params['src']:
config = conversion_src(module)
config = module.params['src']
candidate.load(config)
elif module.params['lines']:
parents = module.params['parents'] or list()
@ -311,14 +311,17 @@ def run(module, result):
candidate = get_candidate(module)
if match != 'none':
config = get_running_config(module)
before = get_running_config(module)
path = module.params['parents']
configobjs = candidate.difference(config, match=match, replace=replace, path=path)
configobjs = candidate.difference(before, match=match, replace=replace, path=path)
else:
configobjs = candidate.items
if configobjs:
commands = dumps(configobjs, 'commands').split('\n')
out_type = "commands"
if module.params["src"] is not None:
out_type = "raw"
commands = dumps(configobjs, out_type).split('\n')
if module.params['lines']:
if module.params['before']:
@ -340,8 +343,34 @@ def run(module, result):
load_config(module, commands)
else:
_load_config(module, commands)
result['changed'] = True
if match != "none":
after = get_running_config(module)
path = module.params["parents"]
if path is not None and match != 'line':
before_objs = before.get_block(path)
after_objs = after.get_block(path)
update = []
if len(before_objs) == len(after_objs):
for b_item, a_item in zip(before_objs, after_objs):
if b_item != a_item:
update.append(a_item.text)
else:
update = [item.text for item in after_objs]
if len(update) == 0:
result["changed"] = False
result['updates'] = []
else:
result["changed"] = True
result['updates'] = update
else:
configobjs = after.difference(before, match=match, replace=replace, path=path)
if len(configobjs) > 0:
result["changed"] = True
else:
result["changed"] = False
result['updates'] = []
else:
result['changed'] = True
class NetworkConfig(_NetworkConfig):
@ -452,8 +481,9 @@ def main():
if module.params['save']:
if not module.check_mode:
run_commands(module, ['save'])
result['changed'] = True
run_commands(module, ['return', 'mmi-mode enable', 'save'])
result["changed"] = True
run_commands(module, ['return', 'undo mmi-mode enable'])
module.exit_json(**result)