API Reference

yang.connector module

yang.connector module defines a set of classes that connect to Data Model Interfaces (DMI)

Netconf is a wrapper around the ncclient package. Gnmi is a wrapper around the grpcio v1.12.1+ package with protobuf v3.6.0. Restconf implementation is coming next.

class yang.connector.Gnmi(*args, **kwargs)[source]

Bases: BaseConnection

Session handling for gNMI connections.

Can be used with pyATS same as yang.connector.Netconf is used or can be used as a standalone module.

Methods:

capabilities(): gNMI Capabilities.

set(dict): gNMI Set. Input is namespace, xpath/value pairs.

get(dict): gNMI Get mode=’STATE’. Input xpath/value pairs (value optional).

subscribe(dict): gNMI Subscribe. Input xpath/value pairs and format.

pyATS Examples:

>>> from pyats.topology import loader
>>> from yang.connector.gnmi import Gnmi
>>> testbed=loader.load('testbed.static.yaml')
>>> device=testbed.devices['uut']
>>> device.connect(alias='gnmi', via='yang2')
>>> #####################
>>> # Capabilities      #
>>> #####################
>>> resp=device.capabilities()
>>> resp.gNMI_version
'0.7.0'
>>> #####################
>>> # Get example       #
>>> #####################
>>> from yang.connector import proto
>>> request = proto.gnmi_pb2.GetRequest()
>>> request.type = proto.gnmi_pb2.GetRequest.DataType.Value('ALL')
>>> request.encoding = proto.gnmi_pb2.Encoding.Value('JSON_IETF')
>>> path = proto.gnmi_pb2.Path()
>>> path1, path2, path3, path4 = (
        proto.gnmi_pb2.PathElem(),
        proto.gnmi_pb2.PathElem(),
        proto.gnmi_pb2.PathElem(),
        proto.gnmi_pb2.PathElem()
    )
>>> path1.name, path2.name, path3.name, path4.name = (
        'syslog',
        'messages',
        'message',
        'node-name'
    )
>>> path.elem.extend([path1, path2, path3, path4])
>>> request.path.append(path)
>>> resp = device.gnmi.get(request)
>>> print(resp)

instantiates this pipeline instance and store arguments internally.

Parameters:
  • (obj) (device)

  • (str) (via)

  • (str)

  • (dict) (kwargs)

Note

this api only supports keyword-only arguments for clarity’s sake.

capabilities()[source]

Gnmi Capabilities method.

Returns:

gNMI Capabilities object

Return type:

proto.gnmi_pb2.CapabilityResponse

configure(cmd)[source]

Helper method for backwards compatibility.

Parameters:

cmd (proto.gnmi_pb2.SetRequest) – gNMI SetRequest object

Returns:

gNMI SetResponse object

Return type:

proto.gnmi_pb2.SetResponse

connect()[source]

Connect to device using gNMI and get capabilities.

Raises:

gNMIException – No gNMI capabilities returned by device.

property connected

Return True if session is connected.

disconnect()[source]

Disconnect from SSH device.

execute(cmd)[source]

Helper method for backwards compatibility.

Parameters:

cmd (proto.gnmi_pb2.GetRequest) – gNMI GetResponse object

Returns:

gNMI GetResponse object

Return type:

proto.gnmi_pb2.GetResponse

get(request)[source]

Gnmi GET method.

Parameters:

request (proto.gnmi_pb2.GetRequest) – gNMI GetResponse object

Returns:

gNMI GetResponse object

Return type:

proto.gnmi_pb2.GetResponse

property gnmi

Helper method to keep backwards compatibility.

Returns:

self

Return type:

Gnmi

set(request)[source]

Gnmi SET method.

Parameters:

request (proto.gnmi_pb2.SetRequest) – gNMI SetRequest object

Returns:

gNMI SetResponse object

Return type:

proto.gnmi_pb2.SetResponse

subscribe(request_iter)[source]

Gnmi Subscribe method.

Parameters:

request_iter (proto.gnmi_pb2.SubscribeRequest) – gNMI SubscribeRequest object

Returns:

gNMI SubscribeResponse object

Return type:

proto.gnmi_pb2.SubscribeResponse

class yang.connector.GnmiNotification(device, response, **request)[source]

Bases: Thread

Thread listening for event notifications from the device.

This constructor should always be called with keyword arguments. Arguments are:

group should be None; reserved for future extension when a ThreadGroup class is implemented.

target is the callable object to be invoked by the run() method. Defaults to None, meaning nothing is called.

name is the thread name. By default, a unique name is constructed of the form “Thread-N” where N is a small decimal number.

args is the argument tuple for the target invocation. Defaults to ().

kwargs is a dictionary of keyword arguments for the target invocation. Defaults to {}.

If a subclass overrides the constructor, it must make sure to invoke the base class constructor (Thread.__init__()) before doing anything else to the thread.

process_opfields(response)[source]

Decode response and verify result.

Decoder callback returns desired format of response. Verify callback returns verification of expected results.

Parameters:

response (proto.gnmi_pb2.Notification) – Contains updates that have changes since last timestamp.

property request
run()[source]

Check for inbound notifications.

stop()[source]
stopped()[source]
class yang.connector.Grpc(*args, **kwargs)[source]

Bases: BaseConnection

Session handling for Grpc outbound connections.

Can be used with pyATS same as yang.connector

EXAMPLE TESTBED

devices:
router-1:
connections:
a:

ip: 10.10.0.1 port: 23 protocol: telnet

grpc:

protocol: grpc class: yang.connector.Grpc overwrite_config_file: True (Optional, default: False) config_file: /Users/user/telemetry/router_1/config.conf (Optional, default: ./transporter.conf) output_file: /Users/user/telemetry/router_1/output.txt (Optional, default: ./mdt.json) telemetry_subscription_id: 501 (Optional, default: 11172017) transporter: telegraf (Optional, default: telegraf) transporter_ip: 192.168.0.253 (Optional, default will fetch local IP) transporter_port: 56789 (Optional, default is a dynamic port) autoconfigure: True (Optional, default: True)

credentials:
default:

username: user password: cisco123

os: iosxe

EXAMPLE USAGE

Welcome to pyATS Interactive Shell

Python 3.11.5 (main, Sep 25 2023, 16:57:00) [Clang 14.0.0 (clang-1400.0.29.202)]

>>> from pyats.topology.loader import load
>>> testbed = load('/Users/user/testbed.yaml')
-------------------------------------------------------------------------------
>>> dev = testbed.devices['router-1.yaml']
>>> dev.connect(via='grpc', alias='grpc')

instantiates this pipeline instance and store arguments internally.

param device (obj):

type device (obj):

topology device object

param alias (str):

type alias (str):

string alias for this pipeline

param via (str):

type via (str):

path to take for this pipeline

param kwargs (dict):

type kwargs (dict):

all other key/values to be stored for this pipeline

Note

this api only supports keyword-only arguments for clarity’s sake.

class yang.connector.Netconf(*args, **kwargs)[source]

Bases: Manager, BaseConnection

Implementation of NetConf connection to devices (NX-OS, IOS-XR or IOS-XE), based on pyATS BaseConnection and ncclient.

YAML Example:

devices:
    asr22:
        type: 'ASR'
        tacacs:
            login_prompt: "login:"
            password_prompt: "Password:"
            username: "admin"
        passwords:
            tacacs: admin
            enable: admin
            line: admin
        connections:
            a:
                protocol: telnet
                ip: "1.2.3.4"
                port: 2004
            vty:
                protocol : telnet
                ip : "2.3.4.5"
            netconf:
                class: yang.connector.Netconf
                ip : "2.3.4.5"
                port: 830
                username: admin
                password: admin

Code Example:

>>> from pyats.topology import loader
>>> testbed = loader.load('/users/xxx/xxx/asr22.yaml')
>>> device = testbed.devices['asr22']
>>> device.connect(alias='nc', via='netconf')
>>> device.nc.connected
True
>>> netconf_request = """
...     <rpc message-id="101"
...      xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
...     <get>
...     <filter>
...     <native xmlns="http://cisco.com/ns/yang/ned/ios">
...     <version>
...     </version>
...     </native>
...     </filter>
...     </get>
...     </rpc>
...     """
>>> reply = device.nc.request(netconf_request)
>>> print(reply)
<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
message-id="101"><data>
<native xmlns="http://cisco.com/ns/yang/ned/ios">
<version>16.3</version></native></data></rpc-reply>
>>> device.nc.disconnect()
>>> device.nc.connected
False
>>>
timeout

Timeout value in seconds which is used by paramiko channel. By default this value is 30 seconds.

Type:

int

client_capabilities

Object ncclient.capabilities.Capabilities representing the client’s capabilities.

Type:

object

server_capabilities

Object ncclient.capabilities.Capabilities representing the server’s capabilities, and it has a list of data models the server supports.

Type:

object

async_mode

Specify whether operations are executed asynchronously (True) or synchronously (False). The default value is False.

Type:

boolean

__init__ instantiates a single connection instance.

configure(msg)[source]

High-level api: configure is a common method of console, vty and ssh sessions, however it is not supported by this Netconf class. This is just a placeholder in case someone mistakenly calls config method in a netconf session. An Exception is thrown out with explanation.

Parameters:

msg (str) – Any config CLI need to be sent out.

Raises:

Exception – configure is not a supported method of this Netconf class.

configure_logging()[source]
connect()[source]

High-level api: opens the NetConf connection and exchanges capabilities. Since topology YAML file is parsed by BaseConnection, the following parameters can be specified in your YAML file.

Parameters:
  • host (string) – Hostname or IP address to connect to.

  • port (int, optional) – By default port is 830, but some devices use the default SSH port of 22 so this may need to be specified.

  • timeout (int, optional) – An optional keyed argument to set timeout value in seconds. By default this value is 30 seconds.

  • username (string) – The username to use for SSH authentication.

  • password (string) – The password used if using password authentication, or the passphrase to use for unlocking keys that require it.

  • key_filename (string) – a filename where a the private key to be used can be found.

  • allow_agent (boolean) – Enables querying SSH agent (if found) for keys. The default value is True.

  • hostkey_verify (boolean) – Enables hostkey verification from ~/.ssh/known_hosts. The default value is False.

  • look_for_keys (boolean) – Enables looking in the usual locations for ssh keys (e.g. ~/.ssh/id_*). The default value is True.

  • ssh_config (string) – Enables parsing of an OpenSSH configuration file, if set to its path, e.g. ~/.ssh/config or to True. If the value is True, ncclient uses ~/.ssh/config. The default value is None.

Raises:

Exception – If the YAML file does not have correct connections section, or establishing transport to ip:port is failed, ssh authentication is failed, or other transport failures.

Note

There is no return from this method. If something goes wrong, an exception will be raised.

YAML Example:

devices:
    asr22:
        type: 'ASR'
        tacacs:
            login_prompt: "login:"
            password_prompt: "Password:"
            username: "admin"
        passwords:
            tacacs: admin
            enable: admin
            line: admin
        connections:
            a:
                protocol: telnet
                ip: "1.2.3.4"
                port: 2004
            vty:
                protocol : telnet
                ip : "2.3.4.5"
            netconf:
                class: yang.connector.Netconf
                ip : "2.3.4.5"
                port: 830
                username: admin
                password: admin

Code Example:

>>> from pyats.topology import loader
>>> testbed = loader.load('/users/xxx/xxx/asr22.yaml')
>>> device = testbed.devices['asr22']
>>> device.connect(alias='nc', via='netconf')
>>>

Expected Results:

>>> device.nc.connected
True
>>> for iter in device.nc.server_capabilities:
...     print(iter)
...
urn:ietf:params:xml:ns:yang:smiv2:RFC-1215?module=RFC-1215
urn:ietf:params:xml:ns:yang:smiv2:SNMPv2-TC?module=SNMPv2-TC
...
>>>
disconnect()[source]

High-level api: closes the NetConf connection.

execute(operation, *args, **kwargs)[source]

High-level api: The fact that most connection classes implement execute method lead us to add this method here as well. Supported operations are get, get_config, get_schema, dispatch, edit_config, copy_config, validate, commit, discard_changes, delete_config, lock, unlock, close_session, kill_session, poweroff_machine and reboot_machine. Refer to ncclient document for more details.

notify_wait(steps)[source]

Activate notification listener and check results

request(msg, timeout=30, return_obj=False)[source]

High-level api: sends message through NetConf session and returns with a reply. Exception is thrown out either the reply is in wrong format or timout. Users can modify timeout value (in seconds) by passing parameter timeout. Users may want to set a larger timeout when making a large query.

Parameters:
  • msg (str) – Any message need to be sent out in XML format. The message can be in wrong format if it is a negative test case. Because ncclient tracks same message-id in both rpc and rpc-reply, missing message-id in your rpc may cause exception when receiving rpc-reply. Most other wrong format rpc’s can be sent without exception.

  • timeout (int, optional) – An optional keyed argument to set timeout value in seconds. Its default value is 30 seconds. If timeout is less than 30, timeout will use the default of 30 seconds.

  • return_obj (boolean, optional) – Normally a string is returned as a reply. In other cases, we may want to return a RPCReply object, so we can access some attributes, e.g., reply.ok or reply.elapsed.

Returns:

The reply from the device in string. If something goes wrong, an exception will be raised. If return_obj=True, the reply is a RPCReply object.

Return type:

str or RPCReply

Raises:

Exception – If NetConf is not connected, or there is a timeout when receiving reply.

Code Example:

>>> from pyats.topology import loader
>>> testbed = loader.load('/users/xxx/xxx/asr_20_22.yaml')
>>> device = testbed.devices['asr22']
>>> device.connect(alias='nc', via='netconf')
>>> netconf_request = """
...     <rpc message-id="101"
...      xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
...     <get>
...     <filter>
...     <native xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-native">
...     <version>
...     </version>
...     </native>
...     </filter>
...     </get>
...     </rpc>
...     """
>>> reply = device.nc.request(netconf_request)
>>>

Expected Results:

>>> print(reply)
<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
message-id="101"><data>
<native xmlns="http://cisco.com/ns/yang/ned/ios">
<version>16.3</version></native></data></rpc-reply>
>>>
property session

return the SSH session object.

Returns:

The SSH session that was created by ncclient.transport.SSHSession.

Return type:

object

Type:

High-level api

subscribe(request)[source]

Creates a notification listener and mark it as active

class yang.connector.NetconfEnxr(*args, **kwargs)[source]

Bases: object

Subclass using POSIX pipes to Communicate NETCONF messaging.

class LockContext(target, cls)[source]

Bases: object

chunk = re.compile('(\n#+\\d+\n)')
commit(**kwargs)[source]
configure(msg)[source]

High-level api: configure is a common method of console, vty and ssh sessions, however it is not supported by this NetconfEnxr class. This is just a placeholder in case someone mistakenly calls config method in a netconf session. An Exception is thrown out with explanation.

Parameters:

msg (str) – Any config CLI need to be sent out.

Raises:

Exception – configure is not a supported method of this Netconf class.

connect(timeout=None)[source]

Connect to ENXR pipe.

property connected

Check for active connection.

discard_changes(**kwargs)[source]
disconnect()[source]

Disconnect from ENXR pipe.

dispatch(rpc_command=None, **kwargs)[source]
edit_config(target=None, config=None, **kwargs)[source]

Send edit-config.

get(filter=None, **kwargs)[source]
get_config(source=None, filter=None, **kwargs)[source]

Send get-config.

get_rpc(elements)[source]

Return string representation of lxml element with rpc.

lock(target=None, **kwargs)[source]
locked(target)[source]

Return a lock context manager for EnXR

recv_data()[source]

Retrieve data from process pipe.

request(rpc)[source]
rpc_pipe_err = '\n        <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">\n        <rpc-error>\n            <error-type>transport</error-type>\n            <error-tag>resource-denied</error-tag>\n            <error-severity>error</error-severity>\n            <error-message>No pipe data returned</error-message>\n        </rpc-error>\n        </rpc-reply>'
send_cmd(rpc)[source]

Send a message to process pipe.

unlock(target=None, **kwargs)[source]