1
0
Fork 0
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:
Ricardo Carrillo Cruz 2018-01-11 13:33:33 +01:00 committed by GitHub
parent 477cd3f775
commit 32e7c9bc9c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 47 deletions

View file

@ -32,7 +32,7 @@ import time
from ansible.module_utils._text import to_text, to_native from ansible.module_utils._text import to_text, to_native
from ansible.module_utils.basic import env_fallback, return_values 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.network.common.utils import to_list, ComplexList
from ansible.module_utils.six import iteritems from ansible.module_utils.six import iteritems
from ansible.module_utils.urls import fetch_url from ansible.module_utils.urls import fetch_url
@ -112,19 +112,28 @@ class Cli:
self._module = module self._module = module
self._device_configs = {} self._device_configs = {}
self._session_support = None 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 @property
def supports_sessions(self): def supports_sessions(self):
if self._session_support is not None: if self._session_support is not None:
return self._session_support return self._session_support
rc, out, err = self.exec_command('show configuration sessions') conn = self._get_connection()
self._session_support = rc == 0
return self._session_support
def exec_command(self, command): self._session_support = True
if isinstance(command, dict): try:
command = self._module.jsonify(command) out = conn.get('show configuration sessions')
return exec_command(self._module, command) except:
self._session_support = False
return self._session_support
def get_config(self, flags=None): def get_config(self, flags=None):
"""Retrieves the current config from the device or cache """Retrieves the current config from the device or cache
@ -138,12 +147,9 @@ class Cli:
try: try:
return self._device_configs[cmd] return self._device_configs[cmd]
except KeyError: except KeyError:
conn = get_connection(self) conn = self._get_connection()
rc, out, err = self.exec_command(cmd) out = conn.get_config(flags=flags)
out = to_text(out, errors='surrogate_then_replace') cfg = to_text(out, errors='surrogate_then_replace').strip()
if rc != 0:
self._module.fail_json(msg=to_text(err, errors='surrogate_then_replace'))
cfg = str(out).strip()
self._device_configs[cmd] = cfg self._device_configs[cmd] = cfg
return cfg return cfg
@ -151,12 +157,20 @@ class Cli:
"""Run list of commands on remote device and return results """Run list of commands on remote device and return results
""" """
responses = list() responses = list()
connection = self._get_connection()
for cmd in to_list(commands): for cmd in to_list(commands):
rc, out, err = self.exec_command(cmd) if isinstance(cmd, dict):
out = to_text(out, errors='surrogate_then_replace') command = cmd['command']
if check_rc and rc != 0: prompt = cmd['prompt']
self._module.fail_json(msg=to_text(err, errors='surrogate_then_replace')) 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: try:
out = self._module.from_json(out) out = self._module.from_json(out)
@ -164,9 +178,12 @@ class Cli:
out = str(out).strip() out = str(out).strip()
responses.append(out) responses.append(out)
return responses return responses
def send_config(self, commands): def send_config(self, commands):
conn = self._get_connection()
multiline = False multiline = False
rc = 0 rc = 0
for command in to_list(commands): for command in to_list(commands):
@ -175,31 +192,24 @@ class Cli:
if command.startswith('banner') or multiline: if command.startswith('banner') or multiline:
multiline = True multiline = True
command = self._module.jsonify({'command': command, 'sendonly': True})
elif command == 'EOF' and multiline: elif command == 'EOF' and multiline:
multiline = False multiline = False
rc, out, err = self.exec_command(command) conn.get(command, None, None, multiline)
if rc != 0:
return (rc, out, to_text(err, errors='surrogate_then_replace'))
return (rc, 'ok', '')
def configure(self, commands): def configure(self, commands):
"""Sends configuration commands to the remote device """Sends configuration commands to the remote device
""" """
conn = get_connection(self) conn = get_connection(self)
rc, out, err = self.exec_command('configure') out = conn.get('configure')
if rc != 0:
self._module.fail_json(msg='unable to enter configuration mode', output=to_text(err, errors='surrogate_then_replace'))
rc, out, err = self.send_config(commands) try:
if rc != 0: self.send_config(commands)
self.exec_command('abort') except:
self._module.fail_json(msg=to_text(err, errors='surrogate_then_replace')) conn.get('abort')
self.exec_command('end') conn.get('end')
return {} return {}
def load_config(self, commands, commit=False, replace=False): def load_config(self, commands, commit=False, replace=False):
@ -214,30 +224,28 @@ class Cli:
if not all((bool(use_session), self.supports_sessions)): if not all((bool(use_session), self.supports_sessions)):
return self.configure(self, commands) return self.configure(self, commands)
conn = get_connection(self) conn = self._get_connection()
session = 'ansible_%s' % int(time.time()) session = 'ansible_%s' % int(time.time())
result = {'session': session} result = {'session': session}
rc, out, err = self.exec_command('configure session %s' % session) out = conn.get('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'))
if replace: if replace:
self.exec_command('rollback clean-config') out = conn.get('rollback clean-config')
rc, out, err = self.send_config(commands) try:
if rc != 0: self.send_config(commands)
self.exec_command('abort') except:
self._module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), commands=commands) conn.get('abort')
rc, out, err = self.exec_command('show session-config diffs') out = conn.get('show session-config diffs')
if rc == 0 and out: if out:
result['diff'] = to_text(out, errors='surrogate_then_replace').strip() result['diff'] = to_text(out, errors='surrogate_then_replace').strip()
if commit: if commit:
self.exec_command('commit') conn.get('commit')
else: else:
self.exec_command('abort') conn.get('abort')
return result return result

View file

@ -47,14 +47,18 @@ class Cliconf(CliconfBase):
return device_info return device_info
@enable_mode @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'} lookup = {'running': 'running-config', 'startup': 'startup-config'}
if source not in lookup: if source not in lookup:
return self.invalid_params("fetching configuration from %s is not supported" % source) return self.invalid_params("fetching configuration from %s is not supported" % source)
if format == 'text': if format == 'text':
cmd = b'show %s' % lookup[source] cmd = b'show %s ' % lookup[source]
else: else:
cmd = b'show %s | %s' % (lookup[source], format) 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) return self.send_command(cmd)
@enable_mode @enable_mode