Sign In Start Free Trial
Account

Add to playlist

Create a Playlist

Modal Close icon
You need to login to use this feature.
  • Book Overview & Buying JUNOS Automation Cookbook
  • Table Of Contents Toc
JUNOS Automation Cookbook

JUNOS Automation Cookbook

By : Chappell
2 (1)
close
close
JUNOS Automation Cookbook

JUNOS Automation Cookbook

2 (1)
By: Chappell

Overview of this book

The JUNOS Automation Cookbook is a companion guide for the complex field of automating tasks on JUNOS devices. With a foundation in industry-standrd XML, JUNOS provides an ideal environment for programmatic interation, allowing you to build upon the capabilities provided by Juniper, with your own original code. You will begin by learning about, and setting up, the industry-standard NETCONF remote procedure call mechanisms on your device. After initial setup, you'll walk through SLAX - Juniper's foundation scripting language - for manipulating XML representations of JUNOS concepts and elements. You'll learn how to write your own SLAX scripts to customise the operating environment, and also how to write proactive event handlers that deal with situations as they happen. You'll then delve into PyEZ - Juniper's bridging framework to make automation accessible to Python code - allowing you to build automation applications in the popular scripting language. You'll witness some examples of how to write applications that can monitor configuration changes, implement BGP security policies and implement ad-hoc routing protocols, for those really tricky situations. You'll also leaarn how asynchronous I/O frameworks like Node.js can be used to implement automation applications that present an acceptable web interface. Along with way, you'll explore how to make use of the latest RESTful APIs that JUNOS provides, how to visualize aspects of your JUNOS network, and how to integrate your automation capabilities with enterprise-wide orchestration systems like Ansible. By the end of the book, you'll be able to tackle JUNOS automation challenges with confidence and understanding, and without hassle.
Table of Contents (10 chapters)
close
close

Processing NETCONF with Python

In recent years, Python has become one of the de-facto software development languages in the automation and scripting world. Its benefits include an accessible and readable syntax, a just-in-time compilation/interpretation model that allows rapid development cycles, and a batteries included standard library that immediately lends itself to many common situations.

In this recipe, we'll make use of a Python script, netconf.py, to connect to a JUNOS OS device in order to issue CLI-like RPCs, much as in the Expect/TCL example. We'll do this using just the basic standard libraries available out of the box in Python, so there is little fussing about with pip or other package management tools.

Getting ready

In order to complete this recipe, make sure you've got access to a working JUNOS OS device and have completed the JUNOS NETCONF over SSH setup recipe. Additionally, you need a suitable Python development environment. In this case, we made use of macOS X and OpenBSD with Python 2.7.13.

How to do it...

The steps for the following recipe are as follows:

  1. Import the necessary standard library modules that we're going to use. In this case, we just need access to basic system functionality, the subprocess module (for managing child processes), and the XML parsing library:
      #!/usr/bin/env python

import sys
import subprocess
import xml.etree.ElementTree as ET
  1. Create a Python object class to represent the NETCONF client, making use of the subprocess module in the Python standard library in order to call the underlying operating system's SSH client. Define an appropriate constructor and destructor function as shown:
    class NETCONFClient(object):

DELIMITER = ']]>]]>\n'

def __init__(self, hostname):
self.ssh = subprocess.Popen([
"/usr/bin/ssh",
"-q",
"-i", "JUNOS_auto_id_rsa",
"-p", "830",
"-s",
hostname,
"netconf",
],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE)

def __del__(self):
self.ssh.stdin.close()
  1. Define a method to read from the NETCONF-over-SSH stream, in a chunked, line-by-line manner, attempting to parse the XML stream.
       def read(self):
data=""
for line in iter(self.ssh.stdout.readline,
NETCONFClient.DELIMITER):
if line=='':
raise IOError("ssh session ended unexpectedly")
data += line

return ET.fromstring(data)
  1. Define a method to write to the NETCONF-over-SSH stream in order to issue RPCs:
      def cmdrpc(self, cmd):
e = ET.Element("rpc")
e.append(ET.Element("command", {'format': "text"}))
e.find("command").text = cmd;
self.ssh.stdin.write(ET.tostring(e))
self.ssh.stdin.write(NETCONFClient.DELIMITER)
  1. Write the main code to read the command-line arguments and instantiate the NETCONFClient object:
      if len(sys.argv) < 3:
print "Usage: netconf.py hostname command"
sys.exit(1)

netconf = NETCONFClient("auto@"+str(sys.argv[1]))
response = netconf.read()
netconf.cmdrpc(" ".join(sys.argv[2:]))
response = netconf.read()

output=response.find(".//{urn:ietf:params:xml:ns:
netconf:base:1.0}output")
config = response.find(".//{urn:ietf:params:xml:ns:
netconf:base:1.0}configuration-output")
error = response.find(".//{urn:ietf:params:xml:ns:
netconf:base:1.0}error-message")
  1. Output the response:
      if output != None:
print output.text
elif config != None:
print config.text
elif error != None:
print error.text
else:
print "NETCONF server provided no usable response"

How it works...

Step 1 sets up the dependent standard library modules. In this case, we use only the well-trodden modules included with the standard Python distribution. The sys module provides access to the command-line environment. The subprocess module provides a flexible way of managing child processes. ElementTree is the Python built-in XML parsing environment.

In step 2, we create a Python new-style class with a constructor and a destructor. The constructor invokes the subprocess module in order to manage a child process consisting of an SSH client. We use the typical options of SSH to influence its behavior:

Option

Description
-q

Quiet mode. Typically omits message-of-the-day banners, which are not helpful for machine reading.

-i JUNOS_auto_id_rsa

Specify the private SSH key file.

-p 830

Establish TCP port 830 as the transport endpoint.

-s

Invoke the SSH subsytem specified (netconf).

The destructor attempts to clean up by closing the standard input stream to the SSH client, which will usually result in the SSH client disconnecting from the remote endpoint.

In step 3, we define a method to read data from the SSH client. The data is read line-by-line until we see the special NETCONF delimiter token. When we see that, we know a message has been completed and it is passed to the ElementTree routines for XML decomposition as a Python object.

In step 4, we define the complimenting output method — a function to write a command RPC. The method simply wraps the input parameter — which is the command line to be executed — in the necessary XML decoration in order to invoke the command RPC.

Step 5 is about putting it all together. We read the command-line arguments to determine the hostname and the command to use. Since most commands consist of multiple words, the user is expected to quote the command. For example:

   unix$ ./netconf.py 10.0.201.201 "show route summary"

We call the method to read data from the SSH stream in order to eat the hello message - we've no real need to understand its contents. Then we output a command RPC for the desired command, and call the read method once more in order to receive the response.

As we handle the response from the command RPC, we anticipate receiving one of three types of tag, as shown in the following table:

Tag

Description

<output>

Normal output from a show command or otherwise

<configuration-output>

Output from the show configuration command

<error-message>

An error message when something goes wrong

Note that the response.find() calls in step 5 make use of the so-called fully qualified XML tag name. The braces denote an XML namespace identifier. Namespaces allow the construction of XML documents comprising of multiple tag dictionaries from multiple sources without collision. They are a flexible tool, but they can make for wordy and verbose text.

Finally, in step 6, we print what we've discovered for the user's attention.

CONTINUE READING
83
Tech Concepts
36
Programming languages
73
Tech Tools
Icon Unlimited access to the largest independent learning library in tech of over 8,000 expert-authored tech books and videos.
Icon Innovative learning tools, including AI book assistants, code context explainers, and text-to-speech.
Icon 50+ new titles added per month and exclusive early access to books as they are being written.
JUNOS Automation Cookbook
notes
bookmark Notes and Bookmarks search Search in title playlist Add to playlist download Download options font-size Font size

Change the font size

margin-width Margin width

Change margin width

day-mode Day/Sepia/Night Modes

Change background colour

Close icon Search
Country selected

Close icon Your notes and bookmarks

Confirmation

Modal Close icon
claim successful

Buy this book with your credits?

Modal Close icon
Are you sure you want to buy this book with one of your credits?
Close
YES, BUY

Submit Your Feedback

Modal Close icon
Modal Close icon
Modal Close icon