Juniper Network Automation using Python–Part 2

In This multi-posts series, We will deep dive into Juniper network automation and how to automate both configuration and operation for Juniper Nodes.

if you miss the first part, Building Basic Configuration using Jinja2 Template, Please Read it first to understand the network topology that we will work on it and generate the initial configuration.

In this part we will cover and excellent and powerful python library from juniper called PyEZ (some folks in Juniper say it’s abbreviation for Python Easy!).  Anyways the PyEZ provides an abstraction layer built on top of the NETCONF protocol  (so you need to enable netconf over ssh first on juniper device before getting the information)

So Why it’s Easy?

Assume you need to get a “show version” from specific juniper device. if you used a Raw Python (i.e paramiko for ssh then open a socket for receiving data then parse the returned data..etc) you will need 48 lines to get only the device version. but using the PyEZ will minimize the code to only 7 lines and will gather more data !


Actually in the backend, PyEZ use the raw python and some additional libraries like lxml for sending and receiving messages to Juniper Device. Again, Over NETCONF Transport protocol




You just need to open the command line (windows cmd or linux shell) and write

pip install junos-eznc


in the background, the pip will install additional packages required by original Juniper PyEZ

Operation using PyEZ

The Below sample script is used to iterate over all devices and gather a specific information from them


First , we import the installed python library

Second, we define all management IP Address for juniper devices in our network and provide the credentials

Third, we iterate over devices and get facts  for this devic. By default, the PyEZ library gathers basic information about the device and stores this information in a Python dictionary. This dictionary can be easily accessed with the facts attribute

The result of executing the above script will be as following


What’s the facts available to be collected?

All the below data could be retrieved from the device. For example the Hostname,Model,Version,Current Routing Engine, Virtual or Physical and so on

{'2RE': None,
  'HOME': '/root',
  'RE0': None,
  'RE1': None,
  'RE_hw_mi': None,
  'current_re': ['re0'],
  'domain': None,
  'fqdn': 'PE1-Region1',
  'hostname': 'PE1-Region1',
  'hostname_info': {'re0': 'PE1-Region1'},
  'ifd_style': 'CLASSIC',
  'junos_info': {'re0': {'object': junos.version_info(major=(14, 1), type=R, minor=1, build=10),
                         'text': '14.1R1.10'}},
  'master': None,
  'model': 'VMX',
  'model_info': {'re0': 'VMX'},
  'personality': 'MX',
  're_info': None,
  're_master': None,
  'serialnumber': None,
  'srx_cluster': None,
  'srx_cluster_id': None,
  'srx_cluster_redundancy_group': None,
  'switch_style': 'BRIDGE_DOMAIN',
  'vc_capable': False,
  'vc_fabric': None,
  'vc_master': None,
  'vc_mode': None,
  'version': '14.1R1.10',
  'version_RE0': '14.1R1.10',
  'version_RE1': None,
  'version_info': junos.version_info(major=(14, 1), type=R, minor=1, build=10),
  'virtual': True}

in the background, PyEZ send a lot of RPC (Remote Procedure Calls) to the device and requesting specific information then store it to the above table, then another RPC requesting another info and so on. Finally it will collect all of these information into the nice dictionary above. So COOL.

if you need to see the exact RPC call send on the wire to juniper device. You can get it from JunOS CLI directly by writing the command and displaying the xml rpc request


You can instruct the PyEZ to send the XML request and return the reply also in XML (but in this case you will need to parse the returned data yourself). This is useful if you’re designing some sort of management system and you need to monitor output from specific command. The RPC provide structured data that could be easily parsed by any XML parser available in python

For Example I need to  get the route_summary from devices and I know the exact RPC call, so I wrote the below script to get the data and convert it to string for prettyprint. but again you write any parser to get just specific information





PyEZ use concept of python metaprogramming to generate any kind of RPC (because it’s really hard to hard-code each RPC. it will only be generated only when requested). Additionally you can use xpath expressions to match specific data from returned response

Configuration using PyEZ

PyEZ provides a “Config” class which simplifies the process of loading and committing configuration to the device and it integrates with the Jinja2 templating engine that we used before to generate configuration from Template

Also PyEZ offers utilities for comparing configurations, rolling back configuration changes, and locking or unlocking the configuration database

The load() method can be used to load a configuration snippet, or full configuration, into the device’s candidate configuration

The configuration can be specified in text (aka “curly brace”), set, or XML syntax. Alternatively, the configuration may be specified as an lxml.etree.Element object

I will define a simple configuration file with “set” style to change hostname for specific host and use the “Config” class to push configuration


Please note this only change the candidate config and will not commit change unless you request that.


Also there’re commit parameters available on PyEZ excatly like CLI. For Example you can comment, commit_check, rollback. commit_sync.etc

Other Utilities inside PyEZ

There’re a lot of classes to be covered inside the PyEZ. I’ll mention some of them briefly  in case you need to deep dive into them

The FS class
of the jnpr.junos.utils.fs module provide common commands that access the filesystem on the Junos device

The jnpr.junos.utils.start_shell module provides a StartShell class that allows an SSH connection to be initiated to a Junos device

The SW class in the jnpr.junos.utils.sw module provides a set of methods for upgrading the Junos software on a device as well as rebooting or powering off the device.

You can check and visualize the full architecture of PyEZ in this post where I generate a full visualization for every package and utility inside the PyEZ

Wrapping Up

in this post we walk-through an excellent python library used to communicate with Juniper Devices. The real power of PyEZ (beside the  usability) is it’s provided from the Vendor itself so you’re 100% sure the source code is compatible with device and won’t break anything in the device.

In next post of this series, we will walk through another python library called “NAPALM”

I hope this been informative for you and I’d like to thank you for reading

Share you opinion to benefit others :)

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s