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._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
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ 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)
|
||||||
|
@ -55,6 +55,10 @@ class Cliconf(CliconfBase):
|
||||||
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
|
||||||
|
|
Loading…
Reference in a new issue