Update netconf plugins for junos and iosxr (#44157)

* Update netconf plugins for junos and iosxr

Fixes #39160

*  Update api signature for netcon api's
   from variable arguments to named arguments

* Udpate get default rpc supported

* Fix CI issue
This commit is contained in:
Ganesh Nalawade 2018-08-15 16:34:45 +05:30 committed by GitHub
commit d9ee693652
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 188 additions and 109 deletions

View file

@ -98,12 +98,19 @@ class NetconfBase(AnsiblePlugin):
conn.load_configuration(config=[''set system ntp server 1.1.1.1''], action='set', format='text')
"""
__rpc__ = ['get_config', 'edit_config', 'get_capabilities', 'get']
def __init__(self, connection):
self._connection = connection
self.m = self._connection._manager
@ensure_connected
def rpc(self, name):
"""
RPC to be execute on remote device
:param name: Name of rpc in string format
:return: Received rpc response from remote host
"""
"""RPC to be execute on remote device
:name: Name of rpc in string format"""
try:
@ -116,9 +123,9 @@ class NetconfBase(AnsiblePlugin):
@ensure_connected
def get_config(self, source=None, filter=None):
"""Retrieve all or part of a specified configuration
(by default entire configuration is retrieved).
"""
Retrieve all or part of a specified configuration
(by default entire configuration is retrieved).
:param source: Name of the configuration datastore being queried, defaults to running datastore
:param filter: This argument specifies the portion of the configuration data to retrieve
:return: Returns xml string containing the RPC response received from remote host
@ -132,88 +139,97 @@ class NetconfBase(AnsiblePlugin):
return resp.data_xml if hasattr(resp, 'data_xml') else resp.xml
@ensure_connected
def get(self, filter=None):
"""Retrieve device configuration and state information.
def get(self, filter=None, with_defaults=None):
"""
Retrieve device configuration and state information.
:param filter: This argument specifies the portion of the state data to retrieve
(by default entire state data is retrieved)
(by default entire state data is retrieved)
:param with_defaults: defines an explicit method of retrieving default values
from the configuration
:return: Returns xml string containing the RPC response received from remote host
"""
if isinstance(filter, list):
filter = tuple(filter)
resp = self.m.get(filter=filter)
resp = self.m.get(filter=filter, with_defaults=with_defaults)
response = resp.data_xml if hasattr(resp, 'data_xml') else resp.xml
return response
@ensure_connected
def edit_config(self, *args, **kwargs):
"""Loads all or part of the specified *config* to the *target* configuration datastore.
:target: is the name of the configuration datastore being edited
:config: is the configuration, which must be rooted in the `config` element.
It can be specified either as a string or an :class:`~xml.etree.ElementTree.Element`.
:default_operation: if specified must be one of { `"merge"`, `"replace"`, or `"none"` }
:test_option: if specified must be one of { `"test_then_set"`, `"set"` }
:error_option: if specified must be one of { `"stop-on-error"`, `"continue-on-error"`, `"rollback-on-error"` }
The `"rollback-on-error"` *error_option* depends on the `:rollback-on-error` capability.
def edit_config(self, config, format='xml', target='candidate', default_operation=None, test_option=None, error_option=None):
"""
resp = self.m.edit_config(*args, **kwargs)
return resp.data_xml if hasattr(resp, 'data_xml') else resp.xml
@ensure_connected
def validate(self, *args, **kwargs):
"""Validate the contents of the specified configuration.
:source: is the name of the configuration datastore being validated or `config`
element containing the configuration subtree to be validated
Loads all or part of the specified *config* to the *target* configuration datastore.
:param config: Is the configuration, which must be rooted in the `config` element.
It can be specified either as a string or an :class:`~xml.etree.ElementTree.Element`.
:param format: The format of configuration eg. xml, text
:param target: Is the name of the configuration datastore being edited
:param default_operation: If specified must be one of { `"merge"`, `"replace"`, or `"none"` }
:param test_option: If specified must be one of { `"test_then_set"`, `"set"` }
:param error_option: If specified must be one of { `"stop-on-error"`, `"continue-on-error"`, `"rollback-on-error"` }
The `"rollback-on-error"` *error_option* depends on the `:rollback-on-error` capability.
:return: Returns xml string containing the RPC response received from remote host
"""
resp = self.m.validate(*args, **kwargs)
resp = self.m.edit_config(config, format=format, target=target, default_operation=default_operation, test_option=test_option,
error_option=error_option)
return resp.data_xml if hasattr(resp, 'data_xml') else resp.xml
@ensure_connected
def copy_config(self, *args, **kwargs):
"""Create or replace an entire configuration datastore with the contents of another complete
configuration datastore.
:source: is the name of the configuration datastore to use as the source of the
copy operation or `config` element containing the configuration subtree to copy
:target: is the name of the configuration datastore to use as the destination of the copy operation"""
resp = self.m.copy_config(*args, **kwargs)
def validate(self, source='candidate'):
"""
Validate the contents of the specified configuration.
:param source: Is the name of the configuration datastore being validated or `config` element
containing the configuration subtree to be validated
:return: Returns xml string containing the RPC response received from remote host
"""
resp = self.m.validate(source=source)
return resp.data_xml if hasattr(resp, 'data_xml') else resp.xml
@ensure_connected
def dispatch(self, request):
def copy_config(self, source, target):
"""
Create or replace an entire configuration datastore with the contents of another complete configuration datastore.
:param source: Is the name of the configuration datastore to use as the source of the copy operation or `config`
element containing the configuration subtree to copy
:param target: Is the name of the configuration datastore to use as the destination of the copy operation
:return: Returns xml string containing the RPC response received from remote host
"""
resp = self.m.copy_config(source, target)
return resp.data_xml if hasattr(resp, 'data_xml') else resp.xml
@ensure_connected
def dispatch(self, rpc_command, source=None, filter=None):
"""
Execute rpc on the remote device eg. dispatch('clear-arp-table')
:param rpc_command: specifies rpc command to be dispatched either in plain text or in xml element format (depending on command)
:param source: name of the configuration datastore being queried
:param filter: specifies the portion of the configuration to retrieve (by default entire configuration is retrieved)
:return: Returns xml string containing the RPC response received from remote host
"""
"""Execute operation on the remote device
:request: is the rpc request including attributes as XML string
"""
req = fromstring(request)
resp = self.m.dispatch(req)
req = fromstring(rpc_command)
resp = self.m.dispatch(req, source=source, filter=filter)
return resp.data_xml if hasattr(resp, 'data_xml') else resp.xml
@ensure_connected
def lock(self, target=None):
def lock(self, target="candidate"):
"""
Allows the client to lock the configuration system of a device.
:param target: is the name of the configuration datastore to lock,
defaults to candidate datastore
:return: Returns xml string containing the RPC response received from remote host
"""
if not target:
target = 'candidate'
resp = self.m.lock(target=target)
return resp.data_xml if hasattr(resp, 'data_xml') else resp.xml
@ensure_connected
def unlock(self, target=None):
def unlock(self, target="candidate"):
"""
Release a configuration lock, previously obtained with the lock operation.
:param target: is the name of the configuration datastore to unlock,
defaults to candidate datastore
:return: Returns xml string containing the RPC response received from remote host
"""
"""Release a configuration lock, previously obtained with the lock operation.
:target: is the name of the configuration datastore to unlock
"""
if not target:
target = 'candidate'
resp = self.m.unlock(target=target)
return resp.data_xml if hasattr(resp, 'data_xml') else resp.xml
@ -228,60 +244,95 @@ class NetconfBase(AnsiblePlugin):
return resp.data_xml if hasattr(resp, 'data_xml') else resp.xml
@ensure_connected
def commit(self, *args, **kwargs):
"""Commit the candidate configuration as the device's new current configuration.
Depends on the `:candidate` capability.
A confirmed commit (i.e. if *confirmed* is `True`) is reverted if there is no
followup commit within the *timeout* interval. If no timeout is specified the
confirm timeout defaults to 600 seconds (10 minutes).
A confirming commit may have the *confirmed* parameter but this is not required.
Depends on the `:confirmed-commit` capability.
:confirmed: whether this is a confirmed commit
:timeout: specifies the confirm timeout in seconds
def commit(self, confirmed=False, timeout=None, persist=None):
"""
resp = self.m.commit(*args, **kwargs)
Commit the candidate configuration as the device's new current configuration.
Depends on the `:candidate` capability.
A confirmed commit (i.e. if *confirmed* is `True`) is reverted if there is no
followup commit within the *timeout* interval. If no timeout is specified the
confirm timeout defaults to 600 seconds (10 minutes).
A confirming commit may have the *confirmed* parameter but this is not required.
Depends on the `:confirmed-commit` capability.
:param confirmed: whether this is a confirmed commit
:param timeout: specifies the confirm timeout in seconds
:param persist: make the confirmed commit survive a session termination,
and set a token on the ongoing confirmed commit
:return: Returns xml string containing the RPC response received from remote host
"""
resp = self.m.commit(confirmed=confirmed, timeout=timeout, persist=persist)
return resp.data_xml if hasattr(resp, 'data_xml') else resp.xml
@ensure_connected
def get_schema(self, *args, **kwargs):
"""Retrieves the required schema from the device
def get_schema(self, identifier, version=None, format=None):
"""
resp = self.m.get_schema(*args, **kwargs)
Retrieve a named schema, with optional revision and type.
:param identifier: name of the schema to be retrieved
:param version: version of schema to get
:param format: format of the schema to be retrieved, yang is the default
:return: Returns xml string containing the RPC response received from remote host
"""
resp = self.m.get_schema(identifier, version=version, format=format)
return resp.data_xml if hasattr(resp, 'data_xml') else resp.xml
@ensure_connected
def locked(self, *args, **kwargs):
resp = self.m.locked(*args, **kwargs)
return resp.data_xml if hasattr(resp, 'data_xml') else resp.xml
def locked(self, target):
"""
Returns a context manager for a lock on a datastore
:param target: Name of the configuration datastore to lock
:return: Locked context object
"""
return self.m.locked(target)
@abstractmethod
def get_capabilities(self):
"""Retrieves device information and supported
"""
Retrieves device information and supported
rpc methods by device platform and return result
as a string
:return: Netconf session capability
"""
pass
@staticmethod
def guess_network_os(obj):
"""Identifies the operating system of
network device.
"""
Identifies the operating system of network device.
:param obj: ncclient manager connection instance
:return: The name of network operating system.
"""
pass
def get_base_rpc(self):
"""Returns list of base rpc method supported by remote device"""
return ['get_config', 'edit_config', 'get_capabilities', 'get']
"""
Returns list of base rpc method supported by remote device
:return: List of RPC supported
"""
return self.__rpc__
def put_file(self, source, destination):
"""Copies file over scp to remote device"""
"""
Copies file to remote host
:param source: Source location of file
:param destination: Destination file path
:return: Returns xml string containing the RPC response received from remote host
"""
pass
def fetch_file(self, source, destination):
"""Fetch file over scp from remote device"""
"""
Fetch file from remote host
:param source: Source location of file
:param destination: Source location of file
:return: Returns xml string containing the RPC response received from remote host
"""
pass
def get_device_operations(self, server_capabilities):
"""
Retrieve remote host capability from Netconf server hello message.
:param server_capabilities: Server capabilities received during Netconf session initialization
:return: Remote host capabilities in dictionary format
"""
operations = {}
capabilities = '\n'.join(server_capabilities)
operations['supports_commit'] = ':candidate' in capabilities