From 7c6916f8d1af7fa6252aee7f7af73a5250c754a8 Mon Sep 17 00:00:00 2001 From: Peter Sprygada Date: Wed, 11 Jan 2017 09:46:38 -0500 Subject: [PATCH] refactors iosxr shared module to use network_cli (#20132) This refactors the iosxr shared module to make use of the network_cli connection plugin and removes the dependency on the shared shell module. This change will break current modules until the modules are updated. --- lib/ansible/module_utils/iosxr.py | 141 ++++++++++++------------------ 1 file changed, 57 insertions(+), 84 deletions(-) diff --git a/lib/ansible/module_utils/iosxr.py b/lib/ansible/module_utils/iosxr.py index bd9866c22bb..e1f3a59f96f 100644 --- a/lib/ansible/module_utils/iosxr.py +++ b/lib/ansible/module_utils/iosxr.py @@ -26,87 +26,60 @@ # USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -import re - -from ansible.module_utils.netcli import Command -from ansible.module_utils.network import NetworkError, NetworkModule -from ansible.module_utils.network import register_transport, to_list -from ansible.module_utils.shell import CliBase - - -class Cli(CliBase): - - CLI_PROMPTS_RE = [ - re.compile(r"[\r\n]?[\w+\-\.:\/\[\]]+(?:\([^\)]+\)){,3}(?:>|#) ?$"), - re.compile(r"\[\w+\@[\w\-\.]+(?: [^\]])\] ?[>#\$] ?$") - ] - - CLI_ERRORS_RE = [ - re.compile(r"% ?Error"), - re.compile(r"% ?Bad secret"), - re.compile(r"invalid input", re.I), - re.compile(r"(?:incomplete|ambiguous) command", re.I), - re.compile(r"connection timed out", re.I), - re.compile(r"[^\r\n]+ not found", re.I), - re.compile(r"'[^']' +returned error code: ?\d+"), - ] - - NET_PASSWD_RE = re.compile(r"[\r\n]?password: $", re.I) - - def connect(self, params, **kwargs): - super(Cli, self).connect(params, kickstart=False, **kwargs) - self.shell.send(['terminal length 0', 'terminal exec prompt no-timestamp']) - - ### Config methods ### - - def configure(self, commands): - cmds = ['configure terminal'] - if commands[-1] == 'end': - commands.pop() - cmds.extend(to_list(commands)) - cmds.extend(['commit', 'end']) - responses = self.execute(cmds) - return responses[1:] - - def get_config(self, flags=None): - cmd = 'show running-config' - if flags: - if isinstance(flags, list): - cmd += ' %s' % ' '.join(flags) - else: - cmd += ' %s' % flags - return self.execute([cmd])[0] - - def load_config(self, config, commit=False, replace=False, comment=None): - commands = ['configure terminal'] - commands.extend(config) - - if commands[-1] == 'end': - commands.pop() - - try: - self.execute(commands) - diff = self.execute(['show commit changes diff']) - if commit: - if replace: - prompt = re.compile(r'\[no\]:\s$') - commit = 'commit replace' - if comment: - commit += ' comment %s' % comment - cmd = Command(commit, prompt=prompt, response='yes') - self.execute([cmd, 'end']) - else: - commit = 'commit' - if comment: - commit += ' comment %s' % comment - self.execute([commit, 'end']) - else: - self.execute(['abort']) - except NetworkError: - self.execute(['abort']) - diff = None - raise - - return diff[0] - -Cli = register_transport('cli', default=True)(Cli) +_DEVICE_CONFIGS = {} + +def get_config(module, flags=[]): + cmd = 'show running-config ' + cmd += ' '.join(flags) + cmd = cmd.strip() + + try: + return _DEVICE_CONFIGS[cmd] + except KeyError: + rc, out, err = module.exec_command(cmd) + if rc != 0: + module.fail_json(msg='unable to retrieve current config', stderr=err) + cfg = str(out).strip() + _DEVICE_CONFIGS[cmd] = cfg + return cfg + +def run_commands(module, commands, check_rc=True): + assert isinstance(commands, list), 'commands must be a list' + responses = list() + + for cmd in commands: + rc, out, err = module.exec_command(cmd) + if check_rc and rc != 0: + module.fail_json(msg=err, rc=rc) + responses.append(out) + return responses + +def load_config(module, commands, commit=False, replace=False): + assert isinstance(commands, list), 'commands must be a list' + + rc, out, err = module.exec_command('configure terminal') + if rc != 0: + module.fail_json(msg='unable to enter configuration mode', err=err) + + failed = False + for command in commands: + if command == 'end': + pass + + rc, out, err = module.exec_command(command) + if rc != 0: + failed = True + break + + if failed: + module.exec_command('abort') + module.fail_json(msg=err, commands=commands, rc=rc) + + rc, diff, err = module.exec_command('show commit changes diff') + if commit: + cmd = 'commit' + else: + cmd = 'abort' + module.exec_command(cmd) + + return {'diff': diff}