mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Refactor EOS code to use cliconf (#34426)
* WIP Refactor EOS code to use cliconf * Fix connection.get where sendonly is True * Fix pylint issue * Remove return from send_config and various exec_commands Also, removed a few try/except, which are anyways handled in Connection.
This commit is contained in:
parent
477cd3f775
commit
32e7c9bc9c
2 changed files with 59 additions and 47 deletions
|
@ -32,7 +32,7 @@ import time
|
|||
|
||||
from ansible.module_utils._text import to_text, to_native
|
||||
from ansible.module_utils.basic import env_fallback, return_values
|
||||
from ansible.module_utils.connection import exec_command
|
||||
from ansible.module_utils.connection import Connection
|
||||
from ansible.module_utils.network.common.utils import to_list, ComplexList
|
||||
from ansible.module_utils.six import iteritems
|
||||
from ansible.module_utils.urls import fetch_url
|
||||
|
@ -112,19 +112,28 @@ class Cli:
|
|||
self._module = module
|
||||
self._device_configs = {}
|
||||
self._session_support = None
|
||||
self._connection = None
|
||||
|
||||
def _get_connection(self):
|
||||
if self._connection:
|
||||
return self._connection
|
||||
self._connection = Connection(self._module._socket_path)
|
||||
|
||||
return self._connection
|
||||
|
||||
@property
|
||||
def supports_sessions(self):
|
||||
if self._session_support is not None:
|
||||
return self._session_support
|
||||
rc, out, err = self.exec_command('show configuration sessions')
|
||||
self._session_support = rc == 0
|
||||
return self._session_support
|
||||
conn = self._get_connection()
|
||||
|
||||
def exec_command(self, command):
|
||||
if isinstance(command, dict):
|
||||
command = self._module.jsonify(command)
|
||||
return exec_command(self._module, command)
|
||||
self._session_support = True
|
||||
try:
|
||||
out = conn.get('show configuration sessions')
|
||||
except:
|
||||
self._session_support = False
|
||||
|
||||
return self._session_support
|
||||
|
||||
def get_config(self, flags=None):
|
||||
"""Retrieves the current config from the device or cache
|
||||
|
@ -138,12 +147,9 @@ class Cli:
|
|||
try:
|
||||
return self._device_configs[cmd]
|
||||
except KeyError:
|
||||
conn = get_connection(self)
|
||||
rc, out, err = self.exec_command(cmd)
|
||||
out = to_text(out, errors='surrogate_then_replace')
|
||||
if rc != 0:
|
||||
self._module.fail_json(msg=to_text(err, errors='surrogate_then_replace'))
|
||||
cfg = str(out).strip()
|
||||
conn = self._get_connection()
|
||||
out = conn.get_config(flags=flags)
|
||||
cfg = to_text(out, errors='surrogate_then_replace').strip()
|
||||
self._device_configs[cmd] = cfg
|
||||
return cfg
|
||||
|
||||
|
@ -151,12 +157,20 @@ class Cli:
|
|||
"""Run list of commands on remote device and return results
|
||||
"""
|
||||
responses = list()
|
||||
connection = self._get_connection()
|
||||
|
||||
for cmd in to_list(commands):
|
||||
rc, out, err = self.exec_command(cmd)
|
||||
out = to_text(out, errors='surrogate_then_replace')
|
||||
if check_rc and rc != 0:
|
||||
self._module.fail_json(msg=to_text(err, errors='surrogate_then_replace'))
|
||||
if isinstance(cmd, dict):
|
||||
command = cmd['command']
|
||||
prompt = cmd['prompt']
|
||||
answer = cmd['answer']
|
||||
else:
|
||||
command = cmd
|
||||
prompt = None
|
||||
answer = None
|
||||
|
||||
out = connection.get(command, prompt, answer)
|
||||
out = to_text(out, errors='surrogate_or_strict')
|
||||
|
||||
try:
|
||||
out = self._module.from_json(out)
|
||||
|
@ -164,9 +178,12 @@ class Cli:
|
|||
out = str(out).strip()
|
||||
|
||||
responses.append(out)
|
||||
|
||||
return responses
|
||||
|
||||
def send_config(self, commands):
|
||||
conn = self._get_connection()
|
||||
|
||||
multiline = False
|
||||
rc = 0
|
||||
for command in to_list(commands):
|
||||
|
@ -175,31 +192,24 @@ class Cli:
|
|||
|
||||
if command.startswith('banner') or multiline:
|
||||
multiline = True
|
||||
command = self._module.jsonify({'command': command, 'sendonly': True})
|
||||
elif command == 'EOF' and multiline:
|
||||
multiline = False
|
||||
|
||||
rc, out, err = self.exec_command(command)
|
||||
if rc != 0:
|
||||
return (rc, out, to_text(err, errors='surrogate_then_replace'))
|
||||
|
||||
return (rc, 'ok', '')
|
||||
conn.get(command, None, None, multiline)
|
||||
|
||||
def configure(self, commands):
|
||||
"""Sends configuration commands to the remote device
|
||||
"""
|
||||
conn = get_connection(self)
|
||||
|
||||
rc, out, err = self.exec_command('configure')
|
||||
if rc != 0:
|
||||
self._module.fail_json(msg='unable to enter configuration mode', output=to_text(err, errors='surrogate_then_replace'))
|
||||
out = conn.get('configure')
|
||||
|
||||
rc, out, err = self.send_config(commands)
|
||||
if rc != 0:
|
||||
self.exec_command('abort')
|
||||
self._module.fail_json(msg=to_text(err, errors='surrogate_then_replace'))
|
||||
try:
|
||||
self.send_config(commands)
|
||||
except:
|
||||
conn.get('abort')
|
||||
|
||||
self.exec_command('end')
|
||||
conn.get('end')
|
||||
return {}
|
||||
|
||||
def load_config(self, commands, commit=False, replace=False):
|
||||
|
@ -214,30 +224,28 @@ class Cli:
|
|||
if not all((bool(use_session), self.supports_sessions)):
|
||||
return self.configure(self, commands)
|
||||
|
||||
conn = get_connection(self)
|
||||
conn = self._get_connection()
|
||||
session = 'ansible_%s' % int(time.time())
|
||||
result = {'session': session}
|
||||
|
||||
rc, out, err = self.exec_command('configure session %s' % session)
|
||||
if rc != 0:
|
||||
self._module.fail_json(msg='unable to enter configuration mode', output=to_text(err, errors='surrogate_then_replace'))
|
||||
out = conn.get('configure session %s' % session)
|
||||
|
||||
if replace:
|
||||
self.exec_command('rollback clean-config')
|
||||
out = conn.get('rollback clean-config')
|
||||
|
||||
rc, out, err = self.send_config(commands)
|
||||
if rc != 0:
|
||||
self.exec_command('abort')
|
||||
self._module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), commands=commands)
|
||||
try:
|
||||
self.send_config(commands)
|
||||
except:
|
||||
conn.get('abort')
|
||||
|
||||
rc, out, err = self.exec_command('show session-config diffs')
|
||||
if rc == 0 and out:
|
||||
out = conn.get('show session-config diffs')
|
||||
if out:
|
||||
result['diff'] = to_text(out, errors='surrogate_then_replace').strip()
|
||||
|
||||
if commit:
|
||||
self.exec_command('commit')
|
||||
conn.get('commit')
|
||||
else:
|
||||
self.exec_command('abort')
|
||||
conn.get('abort')
|
||||
|
||||
return result
|
||||
|
||||
|
|
|
@ -47,14 +47,18 @@ class Cliconf(CliconfBase):
|
|||
return device_info
|
||||
|
||||
@enable_mode
|
||||
def get_config(self, source='running', format='text'):
|
||||
def get_config(self, source='running', format='text', flags=None):
|
||||
lookup = {'running': 'running-config', 'startup': 'startup-config'}
|
||||
if source not in lookup:
|
||||
return self.invalid_params("fetching configuration from %s is not supported" % source)
|
||||
if format == 'text':
|
||||
cmd = b'show %s' % lookup[source]
|
||||
cmd = b'show %s ' % lookup[source]
|
||||
else:
|
||||
cmd = b'show %s | %s' % (lookup[source], format)
|
||||
|
||||
flags = [] if flags is None else flags
|
||||
cmd += ' '.join(flags)
|
||||
cmd = cmd.strip()
|
||||
return self.send_command(cmd)
|
||||
|
||||
@enable_mode
|
||||
|
|
Loading…
Reference in a new issue