Define Views for Junos PyEZ Operational Tables that Parse Structured Output
Junos PyEZ operational (op) Tables for structured output select specific data from the XML output
of an RPC executed on a Junos device. A Table is associated with a View, which is used to
access fields in the Table items and map them to user-defined Python variables. You associate
a Table with a particular View by including the view
property in the Table
definition, which takes the View name as its argument.
A View maps your user-defined variables to XML elements in the selected Table items. A View enables you to access specific fields in the output as variables with properties that can be manipulated in Python. Junos PyEZ handles the extraction of the data into Python as well as any type conversion or data normalization. The keys defined in the View must be valid Python variable names.
Junos PyEZ Views, like Tables, are formatted using YAML. Views that parse structured output can include a number of parameters, which are summarized in Table 1.
View Parameter Name |
View Parameter |
Description |
---|---|---|
View name |
– |
User-defined identifier for the View. |
Field items |
|
Associative array, or dictionary, of key-value pairs that map user-defined field names to XPath expressions that select elements in the Table items. The field names must be valid Python variable names. |
Field groups |
|
Associative array, or dictionary, of key-value pairs that map user-defined field names to XPath expressions that select elements in the Table items. The XPath expressions are relative to the context set by the corresponding groups parameter. The field names must be valid Python variable names. |
Groups |
|
Associative array, or dictionary, of key-value pairs that map a user-defined group name to an XPath expression (relative to the Table item context) that sets the XPath context for fields in that group. |
Consider the following Junos PyEZ op Table and View, which are included with the Junos PyEZ distribution. The Table extracts operational state information for Ethernet interfaces on the target device.
--- EthPortTable: rpc: get-interface-information args: media: True interface_name: '[afgxe][et]-*' args_key: interface_name item: physical-interface view: EthPortView EthPortView: groups: mac_stats: ethernet-mac-statistics flags: if-device-flags fields: oper: oper-status admin: admin-status description: description mtu: { mtu : int } link_mode: link-mode macaddr: current-physical-address fields_mac_stats: rx_bytes: input-bytes rx_packets: input-packets tx_bytes: output-bytes tx_packets: output-packets fields_flags: running: { ifdf-running: flag } present: { ifdf-present: flag }
The following sections discuss the different components of the View:
View Name
The View name is a user-defined identifier for the View.
You associate a Table with a particular View by including the view
property in the Table definition and providing
the View name as its argument. For example:
--- EthPortTable: # Table definition view: EthPortView EthPortView: # View definition
Fields (fields)
You customize Views so that they only reference the necessary
elements from the selected Table items. To do this you include the fields
property and an associative array containing
the mapping of user-defined field names to XPath expressions that
select the desired elements from the Table item. The field names must
be valid Python variable names. The XPath expressions are relative
to the Table item context.
Consider the following sample RPC output:
<rpc-reply> <interface-information> <physical-interface> <name>ge-0/3/0</name> <admin-status junos:format="Enabled">up</admin-status> <oper-status>down</oper-status> <local-index>135</local-index> <snmp-index>530</snmp-index> <link-level-type>Ethernet</link-level-type> <mtu>1514</mtu> ... </physical-interface> </interface-information> </rpc-reply>
If the Table item
parameter
selects <physical-interface>
elements
from the output, the XPath expression for each field in the View definition
is relative to that context. The following View definition maps each
user-defined field name to a child element of the <physical-interface>
element:
EthPortView: fields: oper: oper-status admin: admin-status mtu: { mtu : int }
In the Python script, you can then access a View item
as a variable property. By default, each View item has a name
property that references the key that uniquely
identifies that item.
from jnpr.junos import Device from jnpr.junos.op.ethport import EthPortTable with Device(host='router.example.com') as dev: eths = EthPortTable(dev) eths.get() for item in eths: print (item.name) print (item.oper) print (item.admin) print (item.mtu)
The field format determines the type for a field’s
value. By default, field values are stored as strings. You can specify
a different type for the field value in the field mapping. The following
example defines the value of the mtu
element
to be an integer:
EthPortView: fields: mtu: { mtu : int }
In the RPC output, some Junos XML elements are just empty
elements that act as flags. You can explicitly indicate that a field
is a flag in the field mapping. The field item value for a flag is
True if the element is present in the output and False if the element
is absent. The following example defines the ifdf-running
element as a flag:
EthPortView: fields: mtu: { mtu : int } running: { if-device-flags/ifdf-running : flag }
You can also set the field item value to a Boolean by using the following syntax:
fieldname: { element-name: (True | False)=regex(expression) }
The element’s value is evaluated against the regular
expression passed to regex()
. If the element’s
value matches the expression, the field item value is set to the Boolean
defined in the format. In the following example, the oper_status_down
field is set to True if the value
of the oper-status
element contains 'down':
oper_status_down: { oper-status: True=regex(down) }
You can also use more complex regular expressions and
match against multiple values. The following field item is set to
True if the address in the rt-destination
element starts with '198.51.':
dc1_route: { rt-destination: True=regex(^198\.51\.) }
The following field item is set to True if the no-refresh
element contains either value in the regular
expression.
no_refresh: { no-refresh: 'True=regex(Session ID: 0x0|no-refresh)' }
Groups (groups) and Field Groups (fields_)
Groups provide a shortcut method to select and reference elements within a specific node-set in a Table item.
In the following RPC output, the <if-device-flags>
element contains multiple child elements corresponding to values
displayed in the Device flags
field
in the CLI output:
<rpc-reply> <interface-information> <physical-interface> <name>ge-0/3/0</name> ... <if-device-flags> <ifdf-present/> <ifdf-running/> </if-device-flags> ... </physical-interface> </interface-information> </rpc-reply>
Within the View definition, you can use the fields
property to access the child elements by providing
the full XPath expression to each element relative to the selected
Table item. For example, if the EthPortTable definition selects <physical-interface>
items, the field item mapping
would use the following XPath expressions:
EthPortView: fields: present: if-device-flags/ifdf-present running: if-device-flags/ifdf-running
Alternatively, you can create a group that sets the context
to the <if-device-flags>
element and
then define field group items that just provide the XPath expression
relative to that context. You can define any number of groups within
a View definition.
To create a group, include the groups
property and map a user-defined group name to the XPath expression
that defines the new context. Then define a field group whose name
is fields_
followed by the group name.
The field group is an associative array containing the mapping of
user-defined field names to XPath expressions that now are relative
to the context set within groups
. The field
names must be valid Python variable names.
The following example defines the group flags
and the corresponding field group fields_flags
. The flags
group sets the context to
the physical-interface/if-device-flags
hierarchy
level, and the present
and running
fields access the values of the ifdf-present
and ifdf-running
elements, respectively.
EthPortView: groups: flags: if-device-flags fields_flags: present: ifdf-present running: ifdf-running
Whether you use fields or field groups, you access the value in the same manner within the Junos PyEZ script by using the user-defined field names.