pysros - Model-driven SR OS interface

Library for management of Nokia SR OS nodes.

pysros.management - Connection and data handling

This module contains basic primitives for managing an SR OS node. It contains functions to obtain and manipulate configuration and state data.

pysros.management.connect(*, host, port=830, username, password=None, yang_directory=None, rebuild=False, transport='netconf', timeout=300, hostkey_verify=True)

Create a Connection object. This function is the main entry point for model-driven management of configuration and state for a specific SR OS node using the pySROS library.

Note

All parameters to connect are ignored when executed on an SR OS node.

Parameters
  • host (str) – Hostname, Fully Qualified Domain Name (FQDN) or IP address of the SR OS node.

  • port (int, optional) – TCP port on the SR OS node to connect to. Default 830.

  • username (str) – User name.

  • password (str, optional) – User password. If the password is not provided the systems SSH key is used.

  • yang_directory (str, optional) – Path (absolute or relative to the local machine) to the YANG modules for the specific node. If this argument is used, YANG modules are not downloaded from the SR OS node.

  • rebuild (bool, optional) – Trigger the rebuild of an already cached YANG schema.

  • timeout (int, optional) – Timeout of the transport protocol, in seconds. Default 300.

  • hostkey_verify (bool, optional) – Enables hostkey verification using the SSH known_hosts file. Default True.

Returns

Connection object for specific SR OS node.

Return type

Connection

Raises
  • RuntimeError – Error occurred during creation of connection

  • ModelProcessingError – Error occurred during compilation of the YANG modules

Note

When executing a Python application using the pySROS libraries on a remote workstation, the initial connection is slower to complete than subsequent connections as the schema is generated from the YANG models and cached.

Warning

hostkey_verify should be set to True in a live network environment.

Example 1 - Connection using YANG models automatically obtained from the SR OS node
from pysros.management import connect
from pysros.exceptions import ModelProcessingError
import sys

def get_connection():
    try:
        connection_object = connect(host="192.168.1.1",
                                    username="myusername",
                                    password="mypassword")
    except RuntimeError as runtime_error:
        print("Failed to connect.  Error:", runtime_error)
        sys.exit(-1)
    except ModelProcessingError as model_proc_error:
        print("Failed to create model-driven schema.  Error:", model_proc_error)
        sys.exit(-2)
    return connection_object

if __name__ == "__main__":
    connection_object = get_connection()
Example 2 - Connection using YANG models obtained from a local directory
from pysros.management import connect
from pysros.exceptions import ModelProcessingError
import sys

def get_connection():
    try:
        connection_object = connect(host="192.168.1.1",
                                    username="myusername",
                                    password="mypassword",
                                    yang_directory="./YANG")
    except RuntimeError as runtime_error:
        print("Failed to connect.  Error:", runtime_error)
        sys.exit(-1)
    except ModelProcessingError as model_proc_error:
        print("Failed to create model-driven schema.  Error:", model_proc_error)
        sys.exit(-2)
    return connection_object

if __name__ == "__main__":
    connection_object = get_connection()
pysros.management.sros()

Determine whether the execution environment is an SR OS node

Returns

True if the application is executed on an SR OS node, False otherwise.

Return type

bool

Example
from pysros.management import sros

def main():
    if sros():
        print("I'm running on a SR OS device")
    else:
        print("I'm not running on a SR OS device")

if __name__ == "__main__":
    main()
class pysros.management.Connection(*args, yang_directory, rebuild, **kwargs)

Bases: object

An object representing a connection to an SR OS device. This object is transport agnostic and manages the connection whether the application is run on the SR OS node or remotely.

Warning

You should not create this class directly. Please use connect() instead.

The underlying transport is NETCONF when executed on a machine that is not running SR OS.

Variables
  • running (.Datastore) – running datastore

  • candidate (.Datastore) – candidate datastore

disconnect()

Disconnect the current transport session. After disconnect, the model-driven interfaces for the SR OS devices are not available.

Example
from pysros.management import connect
connection_object = connect()
connection_object.disconnect()
cli(command)

Run a single MD-CLI command. A single line of input is allowed. This may include MD-CLI output redirection (such as no-more). Some restrictions apply to the commands that may be provided.

Parameters

command (str) – MD-CLI command

Returns

Output as returned from the MD-CLI. The returned data is an unstructured string. An empty string is returned if the command does not have any output (for example, a clear command).

Return type

str

Raises
Example
from pysros.management import connect
connection_object = connect(host='192.168.1.1', username='myusername', password='mypassword')
print(connection_object.cli('show version'))
action(path, value={})

Perform a YANG modeled action on SR OS by providing the json-instance-path to the action statement in the chosen operations YANG model, and the pySROS data structure to match the YANG modeled input for that action. This method provides structured data input and output for available operations.

Parameters
  • path (str) – json-instance-path to the YANG action.

  • value (pySROS data structure) – pySROS data structure providing the input data for the chosen action.

Returns

YANG modeled, structured data representing the output of the modeled action (operation)

Return type

pySROS data structure

Example calling the ping YANG modeled action (operation)
>>> from pysros.management import connect
>>> from pysros.pprint import printTree
>>> connection_object = connect(host='192.168.1.1',
... username='myusername', password='mypassword')
>>> path = '/nokia-oper-global:global-operations/ping'
>>> input_data = {'destination': '172.16.100.101'}
>>> output = connection_object.action(path, input_data)
>>> output
Container({'operation-id': Leaf(12), 'start-time': Leaf('2022-09-08T22:21:32.6Z'), 'results': Container({'test-parameters': Container({'destination': Leaf('172.16.100.101'), 'count': Leaf(5), 'output-format': Leaf('detail'), 'do-not-fragment': Leaf(False), 'fc': Leaf('nc'), 'interval': Leaf('1'), 'pattern': Leaf('sequential'), 'router-instance': Leaf('Base'), 'size': Leaf(56), 'timeout': Leaf(5), 'tos': Leaf(0), 'ttl': Leaf(64)}), 'probe': {1: Container({'probe-index': Leaf(1), 'status': Leaf('response-received'), 'round-trip-time': Leaf(2152), 'response-packet': Container({'size': Leaf(64), 'source-address': Leaf('172.16.100.101'), 'icmp-sequence-number': Leaf(1), 'ttl': Leaf(64)})}), 2: Container({'probe-index': Leaf(2), 'status': Leaf('response-received'), 'round-trip-time': Leaf(2097), 'response-packet': Container({'size': Leaf(64), 'source-address': Leaf('172.16.100.101'), 'icmp-sequence-number': Leaf(2), 'ttl': Leaf(64)})}), 3: Container({'probe-index': Leaf(3), 'status': Leaf('response-received'), 'round-trip-time': Leaf(2223), 'response-packet': Container({'size': Leaf(64), 'source-address': Leaf('172.16.100.101'), 'icmp-sequence-number': Leaf(3), 'ttl': Leaf(64)})}), 4: Container({'probe-index': Leaf(4), 'status': Leaf('response-received'), 'round-trip-time': Leaf(2164), 'response-packet': Container({'size': Leaf(64), 'source-address': Leaf('172.16.100.101'), 'icmp-sequence-number': Leaf(4), 'ttl': Leaf(64)})}), 5: Container({'probe-index': Leaf(5), 'status': Leaf('response-received'), 'round-trip-time': Leaf(1690), 'response-packet': Container({'size': Leaf(64), 'source-address': Leaf('172.16.100.101'), 'icmp-sequence-number': Leaf(5), 'ttl': Leaf(64)})})}, 'summary': Container({'statistics': Container({'packets': Container({'sent': Leaf(5), 'received': Leaf(5), 'loss': Leaf('0.0')}), 'round-trip-time': Container({'minimum': Leaf(1690), 'average': Leaf(2065), 'maximum': Leaf(2223), 'standard-deviation': Leaf(191)})})})}), 'status': Leaf('completed'), 'end-time': Leaf('2022-09-08T22:21:36.9Z')})
>>> printTree(output)
+-- operation-id: 13
+-- start-time: 2022-09-08T22:23:21.2Z
+-- results:
|   +-- test-parameters:
|   |   +-- destination: 172.16.100.101
|   |   +-- count: 5
|   |   +-- output-format: detail
|   |   +-- do-not-fragment: False
|   |   +-- fc: nc
|   |   +-- interval: 1
|   |   +-- pattern: sequential
|   |   +-- router-instance: Base
|   |   +-- size: 56
|   |   +-- timeout: 5
|   |   +-- tos: 0
|   |   `-- ttl: 64
|   +-- probe:
|   |   +-- 1:
|   |   |   +-- probe-index: 1
|   |   |   +-- status: response-received
|   |   |   +-- round-trip-time: 2159
|   |   |   `-- response-packet:
|   |   |       +-- size: 64
|   |   |       +-- source-address: 172.16.100.101
|   |   |       +-- icmp-sequence-number: 1
|   |   |       `-- ttl: 64
|   |   +-- 2:
|   |   |   +-- probe-index: 2
|   |   |   +-- status: response-received
|   |   |   +-- round-trip-time: 2118
|   |   |   `-- response-packet:
|   |   |       +-- size: 64
|   |   |       +-- source-address: 172.16.100.101
|   |   |       +-- icmp-sequence-number: 2
|   |   |       `-- ttl: 64
|   |   +-- 3:
|   |   |   +-- probe-index: 3
|   |   |   +-- status: response-received
|   |   |   +-- round-trip-time: 2098
|   |   |   `-- response-packet:
|   |   |       +-- size: 64
|   |   |       +-- source-address: 172.16.100.101
|   |   |       +-- icmp-sequence-number: 3
|   |   |       `-- ttl: 64
|   |   +-- 4:
|   |   |   +-- probe-index: 4
|   |   |   +-- status: response-received
|   |   |   +-- round-trip-time: 2084
|   |   |   `-- response-packet:
|   |   |       +-- size: 64
|   |   |       +-- source-address: 172.16.100.101
|   |   |       +-- icmp-sequence-number: 4
|   |   |       `-- ttl: 64
|   |   `-- 5:
|   |       +-- probe-index: 5
|   |       +-- status: response-received
|   |       +-- round-trip-time: 1735
|   |       `-- response-packet:
|   |           +-- size: 64
|   |           +-- source-address: 172.16.100.101
|   |           +-- icmp-sequence-number: 5
|   |           `-- ttl: 64
|   `-- summary:
|       `-- statistics:
|           +-- packets:
|           |   +-- sent: 5
|           |   +-- received: 5
|           |   `-- loss: 0.0
|           `-- round-trip-time:
|               +-- minimum: 1735
|               +-- average: 2038
|               +-- maximum: 2159
|               `-- standard-deviation: 153
+-- status: completed
`-- end-time: 2022-09-08T22:23:25.4Z
convert(path, payload, *, source_format, destination_format, pretty_print=False, action_io='output')

Returns converted version of the input data (payload) in the destination format.

The input data must be valid according to the YANG schema for the Connection object that convert() is being called against.

Parameters
  • path (str) – json-instance-path to the location in the YANG schema that the payload uses as its YANG modeled root.

  • payload (pySROS data structure, str) – Input data for conversion. The payload must be valid data according to the YANG schema associated with the Connection object and should be in the format as defined in the source_format argument. For pySROS, the payload must be a pySROS data structure. For xml or json, the payload must be a string containing valid XML or JSON IETF data.

  • source_format (str) – Format of the input data. Valid options are xml, json, or pysros.

  • destination_format (str) – Format of the output data. Valid options are xml, json, or pysros.

  • pretty_print (bool, optional) – Format the output for human consumption.

  • action_io (str, optional) – When converting the input/output of a YANG modeled operation (action), it is possible for there to be conflicting fields in the input and output sections of the YANG. This parameter selects whether to consider the payload against the input or output section of the YANG. Default: output.

Returns

Data structure of the same format as destination_format.

Return type

pySROS data structure, str

An example of the convert() function can be found in the Converting data formats section.

Note

Any metadata associated with a YANG node is currently not converted. Metadata includes SR OS configuration comments as well as more general metadata such as insert or delete operations defined in XML attributes. If metadata is provided in the payload in XML or JSON format, it is stripped from the resulting output. Attention should be given to converting the output of the compare summary netconf-rpc MD-CLI command.

class pysros.management.Datastore(connection, target)

Bases: object

Datastore object that can be used to perform multiple operations on a specified datastore.

get(path, *, defaults=False, config_only=False, filter=None)

Obtain a pySROS data structure containing the contents of the supplied path. See the The pySROS data model section for more information about the pySROS data structure.

Parameters
  • path (str) – Path to the requested node in the datastore. The path is an instance-identifier based on RFC 6020 and RFC 7951. The path can be obtained from an SR OS device using the pwc json-instance-path MD-CLI command. The path may point to a YANG Container, List, Leaf, Leaf-List or a specific List entry.

  • defaults (bool) – Obtain default values in addition to specifically set values.

  • config_only (bool) – Obtain configuration data only. Items marked as config false in YANG are not returned.

  • filter (dict) – A filter defining one or more of the following: Content node matches that select items whose values are equal to the provided filter or Selection node matches that define which fields to return. See Example using content node matching filters, Example using selection node filters and Example using content node match filters and selection node filters together for examples.

Returns

A pySROS data structure. This may be a simple value or a more complicated structure depending on the path requested.

Return type

pysros.wrappers.Leaf, pysros.wrappers.LeafList, pysros.wrappers.Container

Raises
  • RuntimeError – Error if the connection was lost.

  • InvalidPathError – Error if the path is malformed.

  • SrosMgmtError – Error for broader SR OS issues including (non-exhaustive list): passing invalid objects, and setting to an unsupported branch.

  • TypeError – Error if fields or keys are incorrect.

  • InternalError – Error if the schema is corrupted.

Note

Any whitespace at the beginning or end of a content match filter is stripped.

Example
 from pysros.management import connect
 import sys

 connection_object = connect()
 try:
     oper_name = connection_object.running.get("/nokia-state:state/system/oper-name")
 except RuntimeError as runtime_error:
     print("Runtime Error:", runtime_error)
     sys.exit(100)
 except InvalidPathError as invalid_path_error:
     print("Invalid Path Error:", invalid_path_error)
     sys.exit(101)
 except SrosMgmtError as sros_mgmt_error:
     print("SR OS Management Error:", sros_mgmt_error)
     sys.exit(102)
 except TypeError as type_error:
     print("Type Error:", type_error)
     sys.exit(103)
 except InternalError as internal_error:
     print("Internal Error:", internal_error)
     sys.exit(104)
Example using content node matching filters
from pysros.management import connect

connection_object = connect()

connection_object.running.get(
    "/nokia-conf:configure/service/vprn", filter={"service-name": "VPRN_42"}
)
Example using selection node filters
from pysros.management import connect

connection_object = connect()

connection_object.running.get(
    "/nokia-conf:configure/service/vprn",
    filter={"admin-state": {}, "interface": {"interface-name": {}}},
)
Example using content node match filters and selection node filters together
from pysros.management import connect

connection_object = connect()

connection_object.running.get(
    "/nokia-conf:configure/service/vprn",
    filter={'service-name': 'VPRN_42', 'admin-state': {}, 'interface': {'interface-name': {}}},
)
set(path, value, commit=True, method='default')

Set a pySROS data structure to the supplied path. See the The pySROS data model section for more information about the pySROS data structure.

Parameters
  • path (str) – Path to the target node in the datastore. See the path parameter definition in pysros.management.Datastore.get() for details.

  • value – Value to set the node to. When path points to a Leaf, the value should be a str (optionally wrapped in a pysros.wrappers.Leaf). When path points to a Leaf-List, the value should be a list of str (optionally wrapped in a pysros.wrappers.LeafList). When path points to a Container or list item, the value should be a dict (optionally wrapped in a pysros.wrappers.Container). Valid nested data structures are supported.

  • commit (bool) – Specify whether update and commit should be executed after set. Default True.

  • method (str) – Specify whether set operation should be default or merge or replace. Default default.

Raises
  • RuntimeError – Error if the connection is lost.

  • InvalidPathError – Error if the path is malformed.

  • SrosMgmtError – Error for broader SR OS issues, including (non-exhaustive list): passing invalid objects, and setting to an unsupported branch.

  • TypeError – Error if fields or keys are incorrect.

  • InternalError – Error if the schema is corrupted.

  • SrosConfigConflictError – Error if configuration commit failed due to conflicts.

Example 1 - Configuring a leaf
from pysros.management import connect

connection_object = connect()
payload = "my-router-name"
connection_object.candidate.set("/nokia-conf:configure/system/name", payload)
Example 2 - Configuring a more complex structure
from pysros.management import connect
from pysros.wrappers import *

connection_object = connect()
path = '/nokia-conf:configure/router[router-name="Base"]/interface[interface-name="demo1"]'
data = Container({'interface-name': Leaf('demo1'), 'port': Leaf('1/1/c1/1:0'),
       'ipv4': Container({'primary': Container({'prefix-length': Leaf(24),
       'address': Leaf('192.168.100.1')})}), 'admin-state': Leaf('enable')})
connection_object.candidate.set(path, data)
delete(path, commit=True, *, annotations_only=False)

Delete a specific path from an SR OS node.

Parameters
  • path (str) – Path to the node in the datastore. See the path parameter definition in pysros.management.Datastore.get() for details.

  • commit (bool) – Specify whether commit should be executed after delete. Default True.

  • annotations_only (bool) – If specified, object where path is pointing is not deleted but only the annotation attached to the object.

Raises
  • RuntimeError – Error if the connection is lost.

  • InvalidPathError – Error if the path is malformed.

  • LookupError – Error if path does not exist.

  • SrosMgmtError – Error for broader SR OS issues, including (non-exhaustive list): passing invalid objects, and setting to an unsupported branch.

  • TypeError – Error if fields or keys are incorrect.

  • InternalError – Error if the schema is corrupted.

  • SrosConfigConflictError – Error if configuration commit failed due to conflicts.

Example
from pysros.management import connect
connection_object = connect()
connection_object.candidate.delete('/nokia-conf:configure/log/log-id[name="33"]')
exists(path)

Check if a specific node exists.

Parameters

path (str) – Path to the node in the datastore. See the path parameter definition in pysros.management.Datastore.get() for details.

Return type

bool

Raises
  • RuntimeError – Error if the connection is lost.

  • InvalidPathError – Error if the path is malformed.

  • SrosMgmtError – Error for broader SR OS issues, including (non-exhaustive list): passing invalid objects, and setting to an unsupported branch.

  • TypeError – Error if fields or keys are incorrect.

  • InternalError – Error if the schema is corrupted.

Example
from pysros.management import connect
connection_object = connect()
if connection_object.running.exists('/nokia-conf:configure/log/log-id[name="33"]') == True:
    print("The log with the ID of 33 is present on the SR OS router")
else:
    print("This log ID is not present on the SR OS router")
get_list_keys(path, defaults=False)

Returns list of key values.

Parameters
  • path (str) – Path to the node in the datastore. See the path parameter definition in pysros.management.Datastore.get() for details.

  • defaults (bool) – Obtain default values in addition to specifically set values.

Return type

list

Raises
  • RuntimeError – Error if the connection was lost.

  • InvalidPathError – Error if the path is malformed.

  • SrosMgmtError – Error for broader SR OS issues, including (non-exhaustive list): passing invalid objects, and setting to an unsupported branch.

  • TypeError – Error if fields or keys are incorrect.

  • InternalError – Error if the schema is corrupted.

  • LookupError – Error if path does not exist.

lock()

Lock the configuration datastore. Transitions a candidate configuration into an exclusive candidate configuration.

Raises

SrosMgmtError – Error if a lock cannot be obtained.

Note

The lock() method may only be called against the candidate configuration datastore.

Note

Only one lock may be obtained per SR OS system. Attempting to obtain another lock raises an exception.

unlock()

Unlock the configuration datastore. Transitions an exclusive candidate configuration to a candidate configuration. Any changes present in the candidate configuration are retained.

Raises

SrosMgmtError – Error if no lock is held.

Note

The unlock() method may only be called against the candidate configuration datastore.

commit()

Commit the candidate configuration.

Raises

SrosMgmtError – Error if committing the configuration is not possible.

Note

The commit() method may only be called against the candidate configuration datastore.

discard()

Discard the current candidate configuration.

Raises

SrosMgmtError – Error if discarding the candidate configuration is not possible.

Note

The discard() method may only be called against the candidate configuration datastore.

compare(path='', *, output_format)

Perform a comparison of the uncommitted candidate configuration with the baseline configuration. The output can be provided in XML or in MD-CLI format and provided in a format where, if applied to the node, the resulting configuration would be the same as if the candidate configuration is committed.

Parameters
  • output_format (str) – Specify output format of compare command. Supported formats are xml and md-cli. The md-cli output format displays similar output to that of the compare summary command on the MD-CLI. The xml output format displays similar output to that of the compare summary netconf-rpc MD-CLI command.

  • path (str) – Specify json-instance-path to the location in the schema that the compare runs from. This is the root of the comparison.

Returns

The formatted differences between the configurations.

Return type

str

Note

The compare() method may only be called against the candidate configuration datastore.

Example - Compare in XML format
from pysros.management import connect

connection_object = connect()
path = '/nokia-conf:configure/policy-options/policy-statement[name="DEMO"]'
output_format = 'xml'

print("Current config in", path)
print(connection_object.candidate.get(path))

print("Deleting config in", path)
connection_object.candidate.delete(path, commit=False)

print("Comparing the candidate configuration to the baseline configuration in {} format".format(output_format))
print(connection_object.candidate.compare(output_format=output_format))
exception pysros.management.SrosMgmtError

Bases: Exception

Exception raised by the pysros.management objects when:

exception pysros.management.InvalidPathError

Bases: Exception

Exception raised when a path provided by the user:

  • is empty

  • fails to parse

  • does not point to an existing object

  • is missing list keys that must be provided

exception pysros.management.ModelProcessingError

Bases: Exception

Exception raised when an error occurs during processing of the YANG model (schema) when:

  • a YANG file cannot be found

  • a YANG file is malformed

exception pysros.management.InternalError

Bases: Exception

Exception raised for broader issues when:

  • schema creation fails and this unfinished schema is utilized

exception pysros.management.SrosConfigConflictError

Bases: Exception

Exception raised when a configuration commit failed due to conflicts between the candidate datastore and the baseline datastore. Retrying the configuration operation usually resolves the situation. If retrying does not resolve the issue, the connection should be closed using pysros.management.Connection.disconnect() and the operation restarted to make a new connection.

exception pysros.management.ActionTerminatedIncompleteError

Bases: Exception

Exception raised when an operation (also known as an action) completes with a terminated-incomplete status.

exception pysros.management.JsonDecodeError

Bases: Exception

Exception raised when parsing json input fail.

exception pysros.management.XmlDecodeError

Bases: Exception

Exception raised when parsing xml input fail.

pysros.management.Empty

Define the YANG empty type.

The YANG empty type is not the same as an empty string "" or as the None type in Python. It requires specific translation depending on whether it is being used in XML or in JSON IETF encodings.

The Empty class is used to represent the value of a node that is of the YANG type empty.

Example - Obtaining YANG empty type values
>>> connection_object.running.get('/nokia-conf:configure/system/grpc/allow-unsecure-connection')
Leaf(Empty)
Example - Configuring a YANG empty type
>>> from pysros.management import Empty
>>> connection_object.candidate.set('/nokia-conf:configure/system/grpc/allow-unsecure-connection', Empty)

pysros.pprint - Specialized output formatting

This module contains functions to assist with stylized formatting of data.

class pysros.pprint.TreePrinter(*, align=False, depth=None)

Bases: object

Object used to print the result of a call to pysros.management.Datastore.get() as an ASCII tree.

Parameters
  • align (bool) – Whether to align values of a container in the same column.

  • depth (None, int) – Maximum tree depth to print.

Raises

ValueError – Error if the depth is not positive.

Note

The pysros.pprint.printTree() function provides a simple way to use this object.

print(obj)

Print the specified object.

Parameters

obj – Object to print.

pysros.pprint.printTree(obj, **kwargs)

Print the result of a call to pysros.management.Datastore.get() as an ASCII tree.

See arguments of TreePrinter

Example
from pysros.pprint import printTree
from pysros.wrappers import Leaf, Container

def main():
    data = Container({'auto-config-save': Leaf(True),
                      'capabilities': Container({'candidate': Leaf(True),
                      'writable-running': Leaf(False)}), 'admin-state': Leaf('enable')})
    printTree(data)

if __name__ == "__main__":
    main()
class pysros.pprint.Column(width, name=None, align='<', padding=0)

Bases: object

Column descriptor to be used in pysros.pprint.Table and pysros.pprint.KeyValueTable.

Parameters
  • width (int) – Width of the column (number of characters).

  • name (None, str) – Name of the column. This may be None when column headers are not to be printed. Default None.

  • align (str) – Alignment of the column: ‘<’ for left, ‘>’ for right and ‘^’ for centered. Defaults to ‘<’.

  • padding (int) – Number of padding characters, already accounted for in width. Default 0.

Raises

ValueError – Error if align is not valid.

format(value)

Format a value according to the parameters of this column, considering width, alignment, and padding.

Parameters

value – Value to format.

Returns

Formatted value.

Return type

str

static create(arg)

Static method to create a Column object.

Parameters

arg (pysros.pprint.Column, tuple) – This can either be a pysros.pprint.Column object or the parameters to pass to the constructor thereof.

Raises

TypeError – Error if Column is not valid.

class pysros.pprint.Padding(width)

Bases: Column

Special type of column which takes no data. It is only used to add empty space into a table.

Parameters

width (int) – Width of the (empty) column.

class pysros.pprint.Table(title, columns, width=79, showCount=None, summary=None)

Bases: ATable

Class that provides the functionality to display tabulated data in the standard SR OS style.

Parameters
  • title (str) – Title of the table.

  • columns – List of column descriptions. Elements of the list can be a pysros.pprint.Column or a tuple with parameters to be passed to pysros.pprint.Column.create().

  • width (int) – Width of the table in characters.

  • showCount – Indicate if a count of rows should be shown in the footer. In case no count is required, pass in None. In case a count is required, pass in the name of the object represented in a row.

  • summary (str) – Optional block of text to be displayed in the footer.

Example creation of a Table object
from pysros.pprint import Table, Padding

def simple_table_builder_example():
    summary = \
    """
This is the text that we would like in our summary sections
at the end of the output"""
    rows = [["row0col0", "row0col1"], ["row1col0", "row1col1"]]
    cols = [(30, "Column0"), (30, "Column1")]
    width = sum([col[0] for col in cols])
    table = Table("This is my tables title", columns=cols,
                  showCount="CounterName", summary=summary, width=width)
    return table, rows

if __name__ == "__main__":
    table, rows = simple_table_builder_example()
print(rows)

Display a complete table when passed in the rows of data. Separate components are displayed as configured during initialization.

Parameters

rows – List of tuples containing the data to be displayed. Each tuple in the list is a row and each item in the tuple is the value for a specific column. Padding columns do not need corresponding values in the tuple.

Example Table.print() using the Table defined in this Example creation of a Table object
>>> def table_print_example(table, rows):
...     table.print(rows)
...
>>> table_print_example(table, rows)
============================================================
This is my tables title
============================================================
Column0                        Column1
------------------------------------------------------------
row0col0                       row0col1
row1col0                       row1col1
------------------------------------------------------------
No. of CounterName: 2

This is the text that we would like in our summary sections
at the end of the output
============================================================
printRows(rows)

Print rows of data.

Parameters

rows – List of tuples containing the data to be displayed. Each tuple in the list is a row and each item in the tuple is the value for a specific column. Padding columns do not need corresponding values in the tuple.

Example Table.printRows() using the Table defined in this Example creation of a Table object
>>> def table_printRows_example(table, rows):
...     table.printRows(rows)
...
>>> table_printRows_example(table, rows)
row0col0                       row0col1
row1col0                       row1col1
printRow(row)

Print a specific row of data.

Parameters

row – Tuple where each item in the tuple is the value for a specific column. Padding columns do not need corresponding values in the tuple.

Example Table.printRow() using the Table defined in this Example creation of a Table object
>>> def table_printRow_example(table, row):
...     table.printRow(row)
...
>>> table_printRow_example(table, rows[0])
row0col0                       row0col1
printColumnHeaders()

Print the column headers and a separator line.

>>> def table_printColumnHeaders_example(table):
...     table.printColumnHeaders()
...
>>> table_printColumnHeaders_example(table)
Column0                        Column1
------------------------------------------------------------
printSummary(showLine=True, customSummary=None)

Print a summary. This section contains the count of rows and any optional summary text.

Parameters
  • showLine (bool) – Display a line above the summary section.

  • customSummary (str) – Custom text to be displayed.

Example Table.printSummary() using the Table defined in this Example creation of a Table object
>>> def table_printSummary_example(table):
...     table.printSummary(customSummary='This is an optional customized summary')
...
>>> table_printSummary_example(table)
------------------------------------------------------------
No. of CounterName: 0
This is an optional customized summary
class pysros.pprint.KeyValueTable(title, columns, width=79)

Bases: ATable

Display a list of key and value data in an SR OS table format.

Parameters
  • title (str) – Title of the table.

  • columns – List of column descriptions. Elements of the list can be pysros.pprint.Column or a tuple with parameters to be passed to pysros.pprint.Column.create(). When displaying the data, key and value columns are interleaved. Multiple key-value pairs are allowed on a single row, and the number of columns is even, that is, key and value data always appear on the same row next to each other.

  • width – Width of the table in characters.

Raises

ValueError – Error if the number of columns is not valid.

Example table creation using KeyValueTable
>>> from pysros.pprint import KeyValueTable
>>> table = KeyValueTable('Key Value Table Title', [(20, None), (20, None)])

Note

This class defines the KeyValueTable object. The KeyValueTable.print(), KeyValueTable.printKV() or KeyValueTable.printKVs() methods should be used to output KeyValueTables.

printKV(*kvs)

Print a table of key-value pairs that are passed into this method. This method does not require the data to be structured as a list of 2-tuples. The key-value pairs are displayed in the available columns if the pairs are available in the KeyValueTable definition.

Parameters

args – Interleaved key and value objects.

Example table output using KeyValueTable and KeyValueTable.printKV().
>>> from pysros.pprint import KeyValueTable
>>> table = KeyValueTable(None, [(20, None), (20, None)])
>>> table.printKV("k0", "v0", "k1", "v1", "k2", "v2")
k0                  : v0
>>> table = KeyValueTable(None, [(12,), (12,), (12,), (12,), (12,), (12,)])
>>> table.printKV("k0", "v0", "k1", "v1", "k2", "v2")
k0          : v0           k1          : v1           k2          : v2
printKVs(items)

Print a table of key-value pairs that are passed into this method as a list of 2-tuples.

Parameters

data – List of tuples containing the data to be displayed. Each tuple in the list must contain two fields: (key, value). Data is spread over the available columns first, starting a new row when required.

Example table output using KeyValueTable and KeyValueTable.printKVs().
>>> from pysros.pprint import KeyValueTable
>>> table = KeyValueTable(None, [(20, None), (20, None)])
>>> table.printKVs([("k0", "v0"), ("k1", "v1"), ("k2", "v2")])
k0                  : v0
k1                  : v1
k2                  : v2
>>> table = KeyValueTable(None, [(12,), (12,), (12,), (12,), (12,), (12,)])
>>> table.printKVs([("k0", "v0"), ("k1", "v1"), ("k2", "v2")])
k0          : v0           k1          : v1           k2          : v2
print(data)

Display a complete table when passed in the list of key-value pairs. Separate components are displayed as configured during initialization.

Parameters

data – List of tuples containing the data to be displayed. Each tuple in the list must contain two fields: (key, value). Data is spread over the available columns first, starting a new row when required.

Example table output using KeyValueTable and KeyValueTable.print().
>>> from pysros.pprint import KeyValueTable
>>> data = [('k0','v0'), ('k1','v1'),('k2','v2')]
>>> table = KeyValueTable('Two column Key Value Table Title', [(20, None), (20, None)])
>>> table.print(data)
===============================================================================
Two column Key Value Table Title
===============================================================================
k0                  : v0
k1                  : v1
k2                  : v2
===============================================================================
>>> table = KeyValueTable('Six column Key Value Table Title',
...                       [(12,), (12,), (12,), (12,), (12,), (12,)])
>>> table.print(data)
===============================================================================
Six column Key Value Table Title
===============================================================================
k0          : v0           k1          : v1           k2          : v2
===============================================================================
printColumnHeaders()

Print the column headers and a separator line.

>>> def table_printColumnHeaders_example(table):
...     table.printColumnHeaders()
...
>>> table_printColumnHeaders_example(table)
Column0                        Column1

pysros.wrappers - Model-driven class wrappers

This module contains wrappers describing the YANG structure and metadata obtained from SR OS.

class pysros.wrappers.Action(value=None, *, annotations=None)

Bases: Container

YANG Action data structure node wrapper.

Action in the pySROS data structure behaves as Container, but it it returned by convert action.

Variables

data – dictionary containing the fields data

class pysros.wrappers.Container(value=None, *, annotations=None)

Bases: Wrapper

YANG container data structure node wrapper.

A YANG container in the pySROS data structure behaves in the same way as a Python dict, where the value of a field can be obtained using the field name.

Variables

data – dictionary containing the fields data

class pysros.wrappers.Leaf(value, annotations=None)

Bases: Wrapper

YANG leaf data structure node wrapper.

Depending on the base (root) YANG type of the node, this object wraps a str, int, or bool.

Variables

data – python object corresponding to the value

class pysros.wrappers.LeafList(value=None, *, annotations=None)

Bases: Wrapper

YANG leaf-list data structure node wrapper.

A YANG leaf-list in the pySROS data structure behaves in the same way as a Python list, where the separate values can be obtained using an index.

Variables

data – list containing the values

property annotations

List of YANG annotations (metadata) applied to the LeafList.

Applying YANG annotations to a LeafList uses the same constructs detailed in the Annotations section. When applied to LeafLists the annotations property is a Python list. Each entry in the LeafList has an entry in the annotations list.

Each entry in the LeafList may have zero or more annotations. This list of annotations per entry is represented as an instance of the Annotations class. Each instance of Annotations has zero or more instances of the Annotation.

This concept is better illustrated through examples.

Note

The example below will not validate against the Nokia YANG models but is provided to detail the implementation and usage of YANG annotations attached to LeafList classes.

Consider the following LeafList:

>>> my_leaflist
LeafList(['one', 'two', 'three'])

The list of annotations attached to this LeafList is stored in the annotations attribute:

>>> my_leaflist.annotations
[]

This is an empty list as there are no annotations defined against any entry in the LeafList. Annotations will now be added to the first entry and the last entry of the list. The first entry will have two annotations and the last one:

Example showing annotations in LeafList objects
>>> my_leaflist.annotations = [
...     Annotations([
...         Annotation(key='key1', data='value1'),
...         Annotation(key='key2', data='value2')
...     ]),
...     Annotations([]),
...     Annotations([
...         Annotation(key='key3', data='value3')
...     ])
... ]
>>> my_leaflist.annotations
[
    Annotations([
        Annotation(key='key1', data='value1'),
        Annotation(key='key2', data='value2')]),
    Annotations([]),
    Annotations([
        Annotation(key='key3', data='value3')
    ])
]
class pysros.wrappers.Annotation(key, data=None, *, module=None, namespace=None)

Bases: object

Wrapper for an individual annotation (YANG metadata) associated with an elements in the data structure. An element in the data structure may have more than one Annotation. The Annotations class is used to define this.

Allows operator to provide an arbitrary key/value pair to any element in the pySROS data structure. The data in the Annotation must exist in the nodes YANG schema for the pysros.management.Datastore.set() and pysros.management.Connection.convert() methods to function.

Variables
  • key – The name of the YANG annotation statement. This may be in simple form or in namespace qualified form, for example: comment or nokia-attr:comment.

  • data – The value of the annotation.

  • module – The YANG module name in which the YANG annotation exists.

  • namespace – The YANG module namespace in which the YANG annotation exists.

key

The name of the YANG annotation statement. This may be in simple form or in namespace qualified form, for example: comment or nokia-attr:comment.

data

The value of the annotation.

module

The YANG module name in which the YANG annotation exists.

namespace

The YANG module namespace in which the YANG annotation exists.

property schema

YANG schema supporting information associated with elements in the data structure (Read only).

class pysros.wrappers.Annotations(initlist=None)

Bases: UserList

Annotations class provides wrapper for instances of the Annotation class that must be supplied in the same way as Python list.

The annotations (there may be more than one) on a particular YANG node are defined in the annotations parameter attached to a Leaf, Container or LeafList. The annotations parameter is a class of type Annotations (with an ‘s’). This is a list of Annotation (without an ‘s’) class instances.

An Annotation in pySROS is treated in a similar way as any other YANG structure such as a Leaf. A Annotation class wrapper encodes the structures required to define and use a YANG modeled annotation. Unlike other wrappers, because a YANG modeled annotation can be in a different YANG namespace from the node it is attached to, additional information is needed.

The pysros.management.Connection.convert() method and the pysros.management.Datastore.set() method support the Annotation class. This means that, as with other data in pySROS, annotations can be entered without providing the details of the YANG module and these methods derive the correct YANG model information using the YANG schema learned from the specific router.

Note

Applying annotations to LeafList objects requires special consideration. Please refer to the LeafList.annotations section for more information.

The following example obtains a Leaf from the device, in this instance the system name, and adds a configuration comment to it which it then sets back to the router using the pysros.management.Datastore.set() method. The example assumes that a pysros.management.Connection object called connection_object has already been created:

Set a configuration comment on the system name obtained from the device
>>> from pysros.wrappers import Annotations, Annotation
>>> path = '/nokia-conf:configure/system/name'
>>> system_name = connection_object.running.get(path)
>>> system_name
Leaf('sros')
>>> system_name.annotations = [Annotation('comment', 'This is my comment')]
>>> connection_object.candidate.set(path, system_name)

The following example obtains a Leaf from the device and adds a configuration comment to it in the native Python data structure. It then uses the pysros.management.Connection.convert() method to query the known YANG schema for the given router and add the YANG model information to the Annotation. The example assumes that a pysros.management.Connection object called connection_object has already been created:

Use convert to identify and complete YANG specific attributes in the object
>>> from pysros.wrappers import Annotations, Annotation
>>> path = '/nokia-conf:configure/system/name'
>>> system_name = connection_object.running.get(path)
>>> system_name
Leaf('sros')
>>> system_name.annotations
Annotations([])
>>> system_name.annotations.append(Annotation('comment', 'This is my configuration comment'))
>>> system_name.annotations
Annotations([Annotation(key='comment', data='This is my configuration comment')])
>>> connection_object.convert(path,
...                           system_name,
...                           source_format='pysros',
...                           destination_format='xml')
'<nokia-conf:name xmlns:nokia-conf="urn:nokia.com:sros:ns:yang:sr:conf" xmlns:nokia-attr="urn:nokia.com:sros:ns:yang:sr:attributes" nokia-attr:comment="This is my configuration comment">sros</nokia-conf:name>'
>>> connection_object.convert(path,
...                           system_name,
...                           source_format='pysros',
...                           destination_format='json')
'{"@nokia-conf:name": {"nokia-attributes:comment": "This is my configuration comment"}, "nokia-conf:name": "sros"}'
>>> augmented_system_name = connection_object.convert(path,
...                                                   system_name,
...                                                   source_format='pysros',
...                                                   destination_format='pysros')
>>> augmented_system_name.annotations
Annotations([Annotation(key='comment', data='This is my configuration comment', module='nokia-attributes', namespace='urn:nokia.com:sros:ns:yang:sr:attributes')])

This next example takes a valid NETCONF RPC encoded in XML that inserts a new item into a user-ordered YANG list. The well-known operation annotation. Using the Annotations and Annotation classes, this RPC can be converted into native the native Python (pySROS) data structure, manipulated if required, and sent to the router. The example assumes that a pysros.management.Connection object called connection_object has already been created.

The initial configuration of the user-ordered list is as follows:

Initial state of the user-ordered list
(gl)[/configure policy-options policy-statement "example"]
A:admin@sros# info
    entry-type named
    named-entry "one" {
        action {
            action-type accept
        }
    }
    named-entry "three" {
        action {
            action-type accept
        }
    }
    default-action {
        action-type reject
    }
Convert NETCONF operations using system defined annotations
 >>> from pysros.wrappers import Annotation, Annotations
 >>> from pysros.management import connect
 >>> my_xml = """
 ... <configure xmlns="urn:nokia.com:sros:ns:yang:sr:conf" xmlns:yang="urn:ietf:params:xml:ns:yang:1" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
 ...     <policy-options>
 ...         <policy-statement>
 ...             <name>example</name>
 ...             <named-entry nc:operation="merge" yang:insert="after" yang:key="[entry-name='one']">
 ...                 <entry-name>two</entry-name>
 ...                 <action>
 ...                     <action-type>accept</action-type>
 ...                 </action>
 ...             </named-entry>
 ...         </policy-statement>
 ...     </policy-options>
 ... </configure>
 ... """
 >>> my_rpc = connection_object.convert('/', my_xml, source_format='xml', destination_format='pysros')
 {'configure': Container({'policy-options': Container({'policy-statement': {'example': Container({'name': Leaf('example'), 'named-entry': OrderedDict([('two', Container({'entry-name': Leaf('two'), 'action': Container({'action-type': Leaf('accept')})}, annotations = Annotations([Annotation(key='operation', data='merge', module='ietf-netconf', namespace='urn:ietf:params:xml:ns:netconf:base:1.0'), Annotation(key='insert', data='after', module='yang', namespace='urn:ietf:params:xml:ns:yang:1'), Annotation(key='key', data="[entry-name='one']", module='yang', namespace='urn:ietf:params:xml:ns:yang:1')])))])})}})})}
 >>> connection_object.candidate.set('/nokia-conf:configure', my_rpc['configure'])
Resulting state of the user-ordered list
(gl)[/configure policy-options policy-statement "example"]
A:admin@sros# info
    entry-type named
    named-entry "one" {
        action {
            action-type accept
        }
    }
    named-entry "two" {
        action {
            action-type accept
        }
    }
    named-entry "three" {
        action {
            action-type accept
        }
    }
    default-action {
        action-type reject
    }

The Annotations class behaves in a similar way to a native Python list and many of the functions that operate on a Python list will also function on the Annotations class. Examples include index() (which returns the numerical location in the list of the requested item), remove() (which deletes a specific item from a list) and append() (which adds an item to the end of a list).

Note

When using index() and remove() the exact matching Annotation must be provided including all associated parameters.

A number of additional helper methods are provided for searching through Annotations and selecting specific Annotation entries. These are described below:

index_annotation(key, data=None, *, module=None, namespace=None)

Return the index to searched Annotation.key. An exception is raised if the Annotation is not found.

Parameters
Raises

ValueError – A matching Annotation is not found.

Note

The example below will not validate against the Nokia YANG models but is provided to detail the implementation and usage of the Annotations class.

>>> myleaf.annotations
Annotations([Annotation(key='key1', data='data1'), Annotation(key='key2', data='data2'), Annotation(key='key3', data='data3')])
>>> myleaf.annotations.index_annotation('key2')
1
Annotations.index_annotation() example handling a failed match
>>> myleaf.annotations
Annotations([Annotation(key='key1', data='data1'), Annotation(key='key2', data='data2'), Annotation(key='key3', data='data3')])
>>> try:
...   myleaf.annotations.index_annotation('foo')
... except ValueError as error:
...   print("Failed to find Annotation:", error)
...
Failed to find Annotation: Annotation not found
get(annotation)

Return the Annotation (without an ‘s’) from the Annotations (with an ‘s’) class (list) that matches the provided Annotation.

The match must be identical, that is, all parameters inside the Annotation class must match exactly.

Parameters

annotation (Annotation) – Annotation object to match in the Annotations list.

Raises

ValueError – Error if the requested Annotation is not found.

Note

The example below does not validate against the Nokia YANG models but is provided to detail the implementation and usage of the Annotations class.

>>> myleaf.annotations
Annotations([Annotation(key='key1', data='data1'), Annotation(key='key2', data='data2'), Annotation(key='key3', data='data3')])
>>> myleaf.annotations.get(Annotation(key='key3', data='data3'))
Annotation(key='key3', data='data3')
Annotations.get() example handling a failed match
>>> myleaf.annotations
Annotations([Annotation(key='key1', data='data1'), Annotation(key='key2', data='data2'), Annotation(key='key3', data='data3')])
>>> try:
...   myleaf.annotations.get('key1')
... except ValueError as error:
...   print("Failed to find Annotation:", error)
...
Failed to find Annotation: 'key1' is not in list
get_annotation(key, data=None, *, module=None, namespace=None)

Return the Annotation (without an ‘s’) from the Annotations (with an ‘s’) class (list) that matches the provided Annotation.key. An exception is raised if the Annotation is not found.

Parameters
Raises

ValueError – A matching Annotation is not found.

Note

The example below does not validate against the Nokia YANG models but is provided to detail the implementation and usage of the Annotations class.

>>> myleaf.annotations
Annotations([Annotation(key='key1', data='data1'), Annotation(key='key2', data='data2'), Annotation(key='key3', data='data3')])
>>> myleaf.annotations.get_annotation('key2')
Annotation(key='key2', data='data2')
remove_annotation(key, data=None, *, module=None, namespace=None)

Remove the Annotation object for the searched Annotation.key from the Annotations class (list). An exception is raised if the Annotation is not found.

Parameters
Raises

ValueError – A matching Annotation is not found.

Note

The example below does not validate against the Nokia YANG models but is provided to detail the implementation and usage of the Annotations class.

>>> myleaf.annotations
Annotations([Annotation(key='key1', data='data1'), Annotation(key='key2', data='data2'), Annotation(key='key3', data='data3')])
>>> myleaf.annotations.remove_annotation('key2')
>>> myleaf.annotations
Annotations([Annotation(key='key1', data='data1'), Annotation(key='key3', data='data3')])
class pysros.wrappers.Schema(model)

Bases: object

YANG schema supporting information associated with elements in the data structure.

Note

pysros.wrappers.Schema metadata is read-only.

property module

YANG module name from which this node originates.

Return type

str

property namespace

YANG module namespace from which this node originates. This is in URN or URL format.

Return type

str

property yang_type

YANG data type. This type is the derived base YANG type, for example, if a YANG node uses a typedef, and that typedef is a uint8, yang_type returns uint8.

Return type

str, SchemaType

property units

The units defined in the YANG module.

Return type

str

property default

The default value as defined in the YANG module.

Return type

str, int

property mandatory

Identifies whether the item is required (mandatory) in the YANG module.

Return type

bool

class pysros.wrappers.SchemaType(yt)

Bases: object

Type information for YANG node. Resolves to a YANG base type.

property range

The range defined in YANG.

Return type

str

property union_members

Base YANG types that form part of the YANG union.

Return type

tuple

pysros.exceptions - pySROS specific exceptions

This module contains exceptions for error handling within pySROS.

exception pysros.exceptions.SrosMgmtError

Bases: Exception

Exception raised by the pysros.management objects when:

exception pysros.exceptions.InvalidPathError

Bases: Exception

Exception raised when a path provided by the user:

  • is empty

  • fails to parse

  • does not point to an existing object

  • is missing list keys that must be provided

exception pysros.exceptions.ModelProcessingError

Bases: Exception

Exception raised when an error occurs during processing of the YANG model (schema) when:

  • a YANG file cannot be found

  • a YANG file is malformed

exception pysros.exceptions.InternalError

Bases: Exception

Exception raised for broader issues when:

  • schema creation fails and this unfinished schema is utilized

exception pysros.exceptions.SrosConfigConflictError

Bases: Exception

Exception raised when a configuration commit failed due to conflicts between the candidate datastore and the baseline datastore. Retrying the configuration operation usually resolves the situation. If retrying does not resolve the issue, the connection should be closed using pysros.management.Connection.disconnect() and the operation restarted to make a new connection.

exception pysros.exceptions.ActionTerminatedIncompleteError

Bases: Exception

Exception raised when an operation (also known as an action) completes with a terminated-incomplete status.

exception pysros.exceptions.JsonDecodeError

Bases: Exception

Exception raised when parsing json input fail.

exception pysros.exceptions.XmlDecodeError

Bases: Exception

Exception raised when parsing xml input fail.

pysros.ehs - Functions for the event handling system (EHS)

The pysros.ehs module provides functionality obtain data from the specific event that triggered the execution of a Python application from the event handling system (EHS).

Note

This module is available when executing on SR OS only. On a remote machine, the event handling system (EHS) and its functionality are not supported.

pysros.ehs.get_event()

The EHS event that triggered the execution of the Python application.

Returns

The Event object or None.

Return type

pysros.ehs.Event or None

class pysros.ehs.Event

The EHS pysros.ehs.Event Class for the event that triggered the execution of the Python application.

name

The name of the event.

Type

str

appid

The name of the application that generated the event.

Type

str

eventid

The event ID number of the application.

Type

int

severity

The severity level of the event.

Type

str

sequence

The sequence number of the event in the syslog collector.

Type

int

Raises

ValueError – for negative values.

subject

The subject or affected object of the event.

Type

str

router_name

The name of the SR OS router-instance (For example, Base) in which this event was triggered.

Type

str

gentime

The time, in ISO 8601 format, that the event was generated.

type

str

timestamp

The timestamp, in seconds, that the event was generated.

Type

float

text

The event specific body, formatted as a string. By default, this is generated from the eventparameters.

Type

str

eventparameters

The additional parameters specific to the event that caused the Python application to execute.

Type

pysros.ehs.EventParams

format_msg()

Return a string representation of the SR OS formatted log message.

Returns

SR OS formatted log message.

Return type

str

class pysros.ehs.EventParams

The additional parameters of the specific pysros.ehs.Event. This class is read-only. Specific additional parameters may be accessed using standard Python subscript syntax.

keys()

Obtain the additional parameters names.

Returns

Additional parameters names for the Event.

Return type

tuple(str)

params[key]

Return the value of the parameter key. If the parameter does not exist, a KeyError is raised.

pysros.syslog - Functions for syslog event handling

The pysros.syslog module provides functionality for obtaining and manipulating a syslog event.

Note

This module is available when executing on SR OS only. On a remote machine, the syslog function is not supported.

Important

The pysros.syslog module is designed to be used with the SR OS syslog functionality at high processing rates. It cannot be used with the pysros.management module, SR OS filesystem access, or the EHS, CRON, or pyexec execution pathways.

Two methods are available to modify the syslog message being sent:

  • The pysros.syslog.get_event() function retrieves the syslog event that is in the queue to be sent out and allows for its attributes to be modified. When the Python application terminates successfully, the newly modified attributes are reformatted using the default syslog format.

  • The pysros.syslog.Event.override_payload() method allows for an entirely new payload to be crafted based on the data from the original event but choosing a customer format and which data to include.

Note

The maximum length of a syslog message on SR OS is 1023 bytes. When modifying the payload to become larger than this maximum value, one of the following occurs:

pysros.syslog.get_event()

Obtain the syslog event queued to be sent out.

Returns

The event object or None.

Return type

pysros.syslog.Event or None

pysros.syslog.generate_pri(facility, severity)

Converts the event severity into a syslog severity and combines it with the facility to generate the syslog PRI value (See RFC 5424 for details) that can be used when formatting a new syslog payload.

Parameters
  • facility (int) – Syslog facility value.

  • severity (str) – Event severity name.

Returns

Syslog PRI value.

Return type

str

Raises
pysros.syslog.severity_to_name(severity)

Converts an event severity name into a syslog severity name.

Parameters

severity (str) – Event severity name.

Returns

Syslog severity name.

Return type

str

Raises

ValueError – for invalid severities, see pysros.syslog.Event.severity

pysros.syslog.get_system_name()

Retrieves the system name. This function is provided directly as part of the pysros.syslog module to provide enhanced performance for the syslog execution pathway.

Returns

SR OS system name.

Return type

str

class pysros.syslog.Event

The syslog Event class provides access to the header-fields of the messages, the individual fields of the event and the syslog-specific attributes.

Note

The header-fields can be modified unless stated otherwise.

Any changes are reflected in the actual syslog-packet being sent out.

If a change of message format is required, for example, the ordering or the value of the field needs to change, override_payload() should be used to override the complete message. In this case, the actual message first needs to be formatted using the format_msg() function before it is passed to the override_payload() function.

name

The name of the event.

Type

str

appid

The name of the application that generated the event.

Type

str

eventid

The event ID number of the application.

Type

int

Raises

ValueError – for negative values.

severity

The severity level of the event. Valid values are:

  • none

  • cleared

  • indeterminate

  • critical

  • major

  • minor

  • warning

Type

str

sequence

The sequence number of the event in the syslog collector.

Type

int

Raises

ValueError – for negative values.

subject

The subject or affected object of the event.

Type

str

router_name

The name of the SR OS router-instance (For example, Base) in which this event was triggered.

Type

str

gentime

The time, in ISO 8601 format, that the event was generated.

Note

Changes to timestamp are reflected in this attribute.

Type

str, read-only

timestamp

The time, in seconds, that the event was generated.

Type

float

hostname

The hostname field of the syslog message. This can be an IP address, fully-qualified domain name (FQDN), or hostname.

Type

str

log_prefix

The log-prefix inserted into the event message.

Type

str

facility

The syslog facility code. A list of named values is provided in pysros.syslog.Facility.

Type

int

Raises

ValueError – for values outside of the valid range [0..31]

text

The event specific body formatted as a string. By default, this is generated from the eventparameters.

This attribute can be modified to provide new event text.

This message may include values from the eventparameters function.

Type

str

eventparameters

The additional parameters specific to the event that caused the Python application to execute.

Note

The parameters returned cannot be modified to alter the generated event text. Instead, a new event text should be generated from the values and assigned to the text attribute.

Returns

Event specific parameters. The parameters in this class are read-only.

Return type

pysros.syslog.EventParams

format_msg()

Return a string representation of the SR OS formatted log message.

Returns

SR OS formatted log message.

Return type

str

format_syslog_msg()

Return a string representation of the SR OS formatted log message as it appears in the syslog packet. When any of the writable attributes on this event have been modified, the output of this function contains these changes.

Returns

SR OS formatted syslog message.

Return type

str

override_payload(payload)

Provide a custom syslog message as it appears in the packet. This includes header information (facility, timestamp, etc.) and body data (the actual message).

Attributes from this event can be used to construct a completely new message format. Any prior changes to the values of these attributes are used.

Parameters

payload (str) – New syslog payload.

Raises

ValueError – when payload is larger than the maximum of 1023 bytes.

drop()

Drop the syslog message from the send queue.

class pysros.syslog.EventParams

The additional parameters of the specific pysros.syslog.Event. This class is read-only. Specific additional parameters may be accessed using standard Python subscript syntax.

keys()

Obtain the additional parameter names.

Returns

Additional parameter names for the event.

Return type

tuple(str)

params[key]

Return the value of the parameter key. If the parameter does not exist, a KeyError is raised. key is of type str.

iter(params)

Return an iterator for the key value pairs of parameters.

Where an iterator is expected, this object can be passed and the iterator is used implicitly. This can be used to collect all pysros.syslog.Event.eventparameters into a standard Python dict.

Example use of the iterator for type conversion
>>> list(event.eventparameters)
[('key1', 'value1'), ('key2', 'value2'), ('key3', 'value3')]
>>> params = dict(event.eventparameters)
>>> type(params)
<class 'dict'>
>>> params
{'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
class pysros.syslog.Facility

Class similar to an Enum that defines constants that can be used as values for the pysros.syslog.Event.facility attribute.

Note

No instances of this class can be instantiated.

KERNEL = 0
USER = 1
MAIL = 2
SYSTEMD = 3
AUTH = 4
SYSLOGD = 5
PRINTER = 6
NETNEWS = 7
UUCP = 8
CRON = 9
AUTHPRIV = 10
FTP = 11
NTP = 12
LOGAUDIT = 13
LOGALERT = 14
CRON2 = 15
LOCAL0 = 16
LOCAL1 = 17
LOCAL2 = 18
LOCAL3 = 19
LOCAL4 = 20
LOCAL5 = 21
LOCAL6 = 22
LOCAL7 = 23