nxos cliconf plugin refactor (#43203)

* nxos cliconf plugin refactor

Fixes #39056

*  Refactor nxos cliconf plugin as per new api definition
*  Minor changes in ios, eos, vyos cliconf plugin
*  Change nxos httpapi plugin edit_config method to be in sync with
   nxos cliconf edit_config

* Fix CI failure

* Fix unit test failure and review comment
This commit is contained in:
Ganesh Nalawade 2018-07-27 11:05:40 +05:30 committed by GitHub
parent e215f842ba
commit af3f510316
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 426 additions and 245 deletions

View file

@ -162,9 +162,10 @@ class Cli:
return response
def get_diff(self, candidate=None, running=None, match='line', diff_ignore_lines=None, path=None, replace='line'):
def get_diff(self, candidate=None, running=None, diff_match='line', diff_ignore_lines=None, path=None, diff_replace='line'):
conn = self._get_connection()
return conn.get_diff(candidate=candidate, running=running, match=match, diff_ignore_lines=diff_ignore_lines, path=path, replace=replace)
return conn.get_diff(candidate=candidate, running=running, diff_match=diff_match, diff_ignore_lines=diff_ignore_lines, path=path,
diff_replace=diff_replace)
class Eapi:
@ -361,17 +362,17 @@ class Eapi:
return result
# get_diff added here to support connection=local and transport=eapi scenario
def get_diff(self, candidate, running=None, match='line', diff_ignore_lines=None, path=None, replace='line'):
def get_diff(self, candidate, running=None, diff_match='line', diff_ignore_lines=None, path=None, diff_replace='line'):
diff = {}
# prepare candidate configuration
candidate_obj = NetworkConfig(indent=3)
candidate_obj.load(candidate)
if running and match != 'none' and replace != 'config':
if running and diff_match != 'none' and diff_replace != 'config':
# running configuration
running_obj = NetworkConfig(indent=3, contents=running, ignore_lines=diff_ignore_lines)
configdiffobjs = candidate_obj.difference(running_obj, path=path, match=match, replace=replace)
configdiffobjs = candidate_obj.difference(running_obj, path=path, match=diff_match, replace=diff_replace)
else:
configdiffobjs = candidate_obj.items
@ -424,6 +425,6 @@ def load_config(module, config, commit=False, replace=False):
return conn.load_config(config, commit, replace)
def get_diff(self, candidate=None, running=None, match='line', diff_ignore_lines=None, path=None, replace='line'):
def get_diff(self, candidate=None, running=None, diff_match='line', diff_ignore_lines=None, path=None, diff_replace='line'):
conn = self.get_connection()
return conn.get_diff(candidate=candidate, running=running, match=match, diff_ignore_lines=diff_ignore_lines, path=path, replace=replace)
return conn.get_diff(candidate=candidate, running=running, diff_match=diff_match, diff_ignore_lines=diff_ignore_lines, path=path, diff_replace=diff_replace)

View file

@ -36,6 +36,7 @@ from ansible.module_utils._text import to_text
from ansible.module_utils.basic import env_fallback, return_values
from ansible.module_utils.network.common.utils import to_list, ComplexList
from ansible.module_utils.connection import Connection, ConnectionError
from ansible.module_utils.network.common.config import NetworkConfig, dumps
from ansible.module_utils.six import iteritems, string_types
from ansible.module_utils.urls import fetch_url
@ -138,7 +139,7 @@ class Cli:
return self._device_configs[cmd]
except KeyError:
connection = self._get_connection()
out = connection.get_config(flags=flags)
out = connection.get_config(filter=flags)
cfg = to_text(out, errors='surrogate_then_replace').strip()
self._device_configs[cmd] = cfg
return cfg
@ -153,37 +154,42 @@ class Cli:
except ConnectionError as exc:
self._module.fail_json(msg=to_text(exc))
def load_config(self, config, return_error=False, opts=None):
def load_config(self, config, return_error=False, opts=None, replace=None):
"""Sends configuration commands to the remote device
"""
if opts is None:
opts = {}
connection = self._get_connection()
msgs = []
responses = []
try:
responses = connection.edit_config(config)
msg = json.loads(responses)
resp = connection.edit_config(config, replace=replace)
if isinstance(resp, collections.Mapping):
resp = resp['response']
except ConnectionError as e:
code = getattr(e, 'code', 1)
message = getattr(e, 'err', e)
err = to_text(message, errors='surrogate_then_replace')
if opts.get('ignore_timeout') and code:
msgs.append(code)
return msgs
responses.append(code)
return responses
elif code and 'no graceful-restart' in err:
if 'ISSU/HA will be affected if Graceful Restart is disabled' in err:
msg = ['']
msgs.extend(msg)
return msgs
responses.extend(msg)
return responses
else:
self._module.fail_json(msg=err)
elif code:
self._module.fail_json(msg=err)
msgs.extend(msg)
return msgs
responses.extend(resp)
return responses
def get_diff(self, candidate=None, running=None, diff_match='line', diff_ignore_lines=None, path=None, diff_replace='line'):
conn = self._get_connection()
return conn.get_diff(candidate=candidate, running=running, diff_match=diff_match, diff_ignore_lines=diff_ignore_lines, path=path,
diff_replace=diff_replace)
def get_capabilities(self):
"""Returns platform info of the remove device
@ -371,10 +377,14 @@ class Nxapi:
return responses
def load_config(self, commands, return_error=False, opts=None):
def load_config(self, commands, return_error=False, opts=None, replace=None):
"""Sends the ordered set of commands to the device
"""
if replace:
commands = 'config replace {0}'.format(replace)
commands = to_list(commands)
msg = self.send_request(commands, output='config', check_status=True,
return_error=return_error, opts=opts)
if return_error:
@ -382,6 +392,24 @@ class Nxapi:
else:
return []
def get_diff(self, candidate=None, running=None, diff_match='line', diff_ignore_lines=None, path=None, diff_replace='line'):
diff = {}
# prepare candidate configuration
candidate_obj = NetworkConfig(indent=2)
candidate_obj.load(candidate)
if running and diff_match != 'none' and diff_replace != 'config':
# running configuration
running_obj = NetworkConfig(indent=2, contents=running, ignore_lines=diff_ignore_lines)
configdiffobjs = candidate_obj.difference(running_obj, path=path, match=diff_match, replace=diff_replace)
else:
configdiffobjs = candidate_obj.items
diff['config_diff'] = dumps(configdiffobjs, 'commands') if configdiffobjs else ''
return diff
def get_device_info(self):
device_info = {}
@ -460,9 +488,9 @@ def run_commands(module, commands, check_rc=True):
return conn.run_commands(to_command(module, commands), check_rc)
def load_config(module, config, return_error=False, opts=None):
def load_config(module, config, return_error=False, opts=None, replace=None):
conn = get_connection(module)
return conn.load_config(config, return_error, opts)
return conn.load_config(config, return_error, opts, replace=replace)
def get_capabilities(module):
@ -470,6 +498,11 @@ def get_capabilities(module):
return conn.get_capabilities()
def get_diff(self, candidate=None, running=None, diff_match='line', diff_ignore_lines=None, path=None, diff_replace='line'):
conn = self.get_connection()
return conn.get_diff(candidate=candidate, running=running, diff_match=diff_match, diff_ignore_lines=diff_ignore_lines, path=path, diff_replace=diff_replace)
def normalize_interface(name):
"""Return the normalized interface name
"""