Blog Viewer

Scripting How-To: Define a table view to access table item fields

By Erdem posted 08-06-2015 05:19


Define a Table View to Access Table Item Fields


You generally define a Table View when you define the Table in operational or configuration mode. The purpose of a View is to map the Junos XML fields into native Python so the caller doesn't need to know XML (or Junos OS).
For example, the same Ethernet Port Table used is as presented in the Define Operational Table page. The View is associated to the table on line 9:


1 ---
2 EthPortTable:
3   rpc: get-interface-information
4   args:
5     media: True
6     interface_name: '[afgx]e*'
7   args_key: interface_name
8   item: physical-interface
9   view: EthPortView



The following illustrates the EthPortView YAML definition which is used for the example. This definition is actually stored in the same file as the EthPortTable, and you can find the ethport.yml file in the Junos PyEZ distribution, located in the op directory.


01 EthPortView:
02   groups:
03     mac_stats: ethernet-mac-statistics
04     flags: if-device-flags
05   fields:
06     oper: oper-status
07     admin: admin-status
08     mtu: { mtu : int }
09     link_mode: link-mode
10     macaddr: current-physical-address
11   fields_mac_stats:
12     rx_bytes: input-bytes
13     rx_packets: input-packets
14     tx_bytes: output-bytes
15     tx_packets: output-packets
16   fields_flags:
17     running: { ifdf-running: flag }
18     present: { ifdf-present: flag }



You create a View using fields, groups, and field_group definitions. The purpose of a View is to map what you want to call the table item (left-hand side) to the Junos XML XPath expression (right-hand side). To understand where the XPath values come from, you need to examine the Junos XML output. Review the sample output:



01 jeremy@junos> show interfaces media ge-0/0/0 | display xml
02 <rpc-reply xmlns:junos="">
03     <interface-information xmlns=""junos:style="normal">
04         <physical-interface>
05             <name>ge-0/0/0</name>
06             <admin-status junos:format="Enabled">up</admin-status>
07             <oper-status>up</oper-status>
08             <local-index>134</local-index>
09             <snmp-index>508</snmp-index>
10             <link-level-type>Ethernet</link-level-type>
11             <mtu>1514</mtu>
12             <source-filtering>disabled</source-filtering>
13             <link-mode>Full-duplex</link-mode>
14             <speed>1000mbps</speed>
15             <bpdu-error>none</bpdu-error>
16             <l2pt-error>none</l2pt-error>
17             <loopback>disabled</loopback>
18             <if-flow-control>enabled</if-flow-control>
19             <if-auto-negotiation>enabled</if-auto-negotiation>
20             <if-remote-fault>online</if-remote-fault>
21             <if-device-flags>
22                 <ifdf-present/>
23                 <ifdf-running/>
24             </if-device-flags>
25 ### SNIP ###



Table Item Reference


When you define a Table, you define the XPath expression for each item. From the table definition, line 8, you can see that each item is<physical-interface>. Therefore every other field XPath expression is "relative" to the <physical-interface>. While you do not need to be an expert with XPath expression syntax, you do need a basic understanding. If XPath is new to you, please review the W3Schools link on the sidebar.


Field Item Reference


Now that you have your table item point of reference, you can define your fields accordingly. For example, the "operational status" value,oper-status, is directly "under" the physical-interface. So the XPath expression is very simple, it's just oper-status. That field is defined in the view on line 6. The left-hand side of the colon (:) is what you will use in Python, in this case oper. If you were using this table in the Python shell, you could do something like the following, assuming dev is a connected Device instance:


1 >>> dev
2 Device(srx210)
3 >>>
4 >>> from jnpr.junos.op.ethport import *
5 >>> eths = EthPortTable(dev)
6 >>> eths.get()
7 EthPortTable:srx210: 8 items
8 >>> eths['ge-0/0/0'].oper
9 'up'


At a minimum, you must define fields within your view, as illustrated in lines 5 through 10. Any field definition you include here is relative to the Table item. 


You can additionally define field groups. The idea behind field groups is that you want to reference Junos XML items that are contained by other XML elements. For example, looking at the RPC output, you can see that there is a group of fields enclosed by <if-device-flags>. If you want to use values in that group ("node-set" in XPath parlance), you have the following two choices:


You could reference the XPath explicitly like this:


1 EthPortView:
2   fields:
3     present: if-device-flags/present
4     running: if-device-flags/running


Or, you could define a group and then set up a field group definition:


1 EthPortView:
2   groups:
3     flags: if-device-flags
4   fields_flags:
5     running: ifdf-running
6     present: ifdf-present


To create a group, declare a group name under the groups keyword. In this example, the group name is flags. You then define the XPath expression relative from the table item to the XPath node-set. Since if-device-flags is a direct child of physical-interface, this is a simple expression, just if-device-flags. You can declare multiple groups. If you don't use groups, then you don't include it in the View definition.


As you can see, the field group name is "fields_" followed by the name of the group, so in this case fields_flags. The choice to use groups or not is entirely up to you; it's really meant as a "shortcut" so you don't have to keep re-keying repetitive XPath expressions. From a Python coding perspective, there is no difference; you access the running value in the same way.


Field Item Values


By default, field items are stored as strings. When you want something different, such as a number, you need to define the field slightly differently. For example, review the mtu definition on line 8. You can see how the field is defined to make it an integer (int). Another case is when the Junos XML field does not have a value, rather it is a "flag". You can define a field as flag so that you get True or False if the flag is present or missing. For example, review line 17, and then this Python shell output:


1 >>> eths['ge-0/0/0'].present
2 True