Explains using tables for automation tasks.
Table widgets can be either loaded from a Python module or using the loadyaml() function provided by the jnpr.junos.factory module. For the purpose of this discussion to illustrate the use of tables, we will use the former. The use of loadyaml() is explained here.
Tables are associated to Device variables using one of two methods:
As a standalone variable:
As a bound attribute of the Device:
In either case, using the table once it is bound to the Device is the same.
Table widgets are presented to have a "look and feel" similar to Python dictionary types (dict). This enables you to access information bykeys(), values(), and items() and select a specific item by key name or index location.
The underlying Junos OS XML command and response data extraction is handled by Junos PyEZ so the user does not need to know these details. The Table or View widgets are abstractions defined using YAML files, so that the widgets creator does not need to code these in Python. The topic of creating these YAML files is discussed on other topic pages (see sidebar links).
Retrieving table items is done using the get() method. If you do not pass any arguments to get(), then all of the table items will be extracted from the Junos OS device.
From the Python shell we can see that there are three Ethernet ports in this table. Programmatically, we could also use the len() function to obtain this information:
You can use get() to be more specific about the items to retrieve. You can do this by knowing the available Junos OS command options and passing them directly to get(). Let's take a look at an example using the equivalent of the Junos OS CLI show route command. This Table widget is provided by Junos PyEZ. We can use it to retrieve all the routes:
But what if we want only a specific destination, for example, the same as doing show route 192.168.56.0/24? You would pass the specific destination to the get() method like so:
show route 192.168.56.0/24
You can be even more specific if you know the Junos OS CLI command parameter. For example, let's say that you only wanted to retrieve "local" routes for a given destination, the same as show route 192.168.56.0/24 protocol local.
show route 192.168.56.0/24 protocol local
Ok, so how did I know what to do? This is where actually knowing the Junos OS CLI (as a network engineer) comes into play.
If you were to go to the Junos OS CLI and enter the command, you can display the Junos OS XML API using the "pipe display" filter like so:
jeremy@junos> show route 192.168.56.0/24 protocol local | display xml rpc
Here you can see that the command is taking two arguments: destination and protocol. So to use any Junos OS CLI parameter, you simply provide the key=value pair when you make a call with get(). You can pass multiple key value pairs. For example, let's say you wanted to do the above, but for just a specific routing table. I'll use "inet.0" just for an example. From the Junos OS CLI, it would look like this:
jeremy@junos> show route 192.168.56.0/24 protocol local table inet.0 | display xml rpc
And the corresponding use of get() would look like this:
But hold on, why didn't we explicitly use destination in the call to get()? This is because when we defined the YAML widget for the table, we identified that the "default argument key" was the field called "destination". Here is the corresponding YAML file for theRouteTable:
args_key: destination item: route-table/rt
The choice to define the YAML in this way was to mimic the behavior of the Junos OS CLI; you can simply provide the destination value as the first parameter to the show command. On the Junos OS CLI you can see this identified:
jeremy@junos> show route ?
<[Enter]> Execute this
<destination> IP address and optional prefix length of destination
active-path Show active paths
It should be noted that you can explicitly use the destination key=value in the call to get() should you choose to do so. Also, if the YAML forRouteTable did not have the args_key property defined, you would be required to do so.
Once you've retrieved table items, you can treat the table like a Python dictionary:
>>> pp( routes.values() )
>>> pp( routes.items() )
You can select a specific table item either by key (name) or by index. When you select a table item, you get a View. The View lets you then access the specific fields in a native Pythonic way (i.e., you don't need to know the Junos OS or XML).
By specific key or name:
By index, get the first entry in the table:
Once you have a View to the table item, you can access the properties, like so:
You can apply a different View to a table item, which gives you the effective capability similar to "brief, extensive, detailed", except in the case of Junos PyEZ, you get to decide what is in the view, rather than Junos OS. Details on this process are described in the View topic pages.
Tables support iteration, so you can loop through each item in the same way you would loop through a list or dictionary. Each iteration item is the table-item view. So you can do things like:
You can take "slices" of a table the same way you would with a list. For example, if you wanted to look at the first ten items in a table, you could do this:
You can also us the "in" operator to determine if a table contains a key entry. For example:
You can save the XML data to your local file system (not the Junos OS device) using the savexml() method. You can optionally include the Device hostname and timestamp as part of the created filename:
Looking at the local file system:
[jeremy@centos /var/tmp]$ ls -al *.xml
-rw-rw-r--. 1 jeremy jeremy 7930 Dec 23 15:27 eths_jnpr-dc-fw_20131223152707.xml
You can load the locally stored XML data directly into a Table widget using the path parameter to the table creation, as illustrated:
The Junos PyEZ library will contain a growing number of table definitions. The Junos PyEZ library was designed so that you can quickly define you own tables; it is assumed that what you want will not be in the library, and you do not need to wait. Generally speaking, it should take you less than 10 minutes to define a new table and associated view, once you get the hang of it. Take a look at the existing tables in the source directory: jnpr/junos/op for examples. See the sidebar links to jump to topic pages discussions for the specific process.
Excellent post! Quite helpful.