41,99 €
Administer, configure, and monitor Junos in your organization
This book targets network engineers, developers, support personals, and administrators who are working on devices running Junos OS and are looking at automating their organisation's operations. Some understanding about Junos would be necessary
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.
A guide that will cover all the automation tools along with steps on leveraging these tools
Sie lesen das E-Book in den Legimi-Apps auf:
Seitenzahl: 399
Veröffentlichungsjahr: 2017
BIRMINGHAM - MUMBAI
Copyright © 2017 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.
Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the authors, nor Packt Publishing, and its dealers and distributors will be held liable for any damages caused or alleged to be caused directly or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.
First published: September 2017
Production reference: 1220917
ISBN 978-1-78829-099-9
www.packtpub.com
Author
Adam Chappell
Copy Editor
Juliana Nair
Reviewer
Mohammad Mohsinul Malik
Project Coordinator
Judie Jose
Commissioning Editor
Vijin Boricha
Proofreader
Safis Editing
Acquisition Editor
Meeta Rajani
Indexer
Rekha Nair
ContentDevelopmentEditor
Abhishek Jadhav
Graphics
Kirk D'Penha
Technical Editor
Manish Shanbhag
Production Coordinator
Aparna Bhagat
Adam Chappell first cut his teeth in the networking world in 1995 after an opportunity in Finchley, North London, at what would become one of the pioneering dial-up Internet ISPs in the United Kingdom. His early forays into network automation generally involved cron, Perl, expect, and a healthy dose of hope and luck. As the commercial networking market matured, he joined Interoute to develop one of the first large-scale European MPLS networks, leading the market in the provision of private packet networking.
Adam was responsible for Interoute's unique network automation technology that seamlessly stitches together industry-standard MPLS VPNs and private cloud compute logical networks. Currently, he works in the thriving technology development team at Interoute, between London and Prague, focusing on network technologies, software, and security.
Mohammad Mohsinul Malik is currently working as an advanced service consultant with Juniper Networks, Malaysia.
He completed his engineering from Jamia Millia Islamia University, New Delhi, and has around 11 years of experience in the IP networking industry. He has extensive hands-on experience in large enterprise networks and tier 1 and tier 2 service providers.
His interests include SDN, NFV, network automation, IoT, network security, digital forensics, and cloud technologies.
Malik has earned the networking industry’s most sought-after certifications and is among an elite group of engineers in the world who hold such diverse certifications.
He has active triple JNCIE (SP, ENT, SEC), triple JNCSP (SP, ENT, SEC), triple JNCDS (WAN, DC, SEC), JNCIP-DC, JNCIS-QFabric, and JNCIS-SDNA from Juniper Networks. Also, he has earned other vendors certifications, such as CCIE-SP, CCNP-R&S, CISSP, PCNSE7, MCSE, BCEFP, SCP, and so on.
He also likes exploring new technologies and spends his spare time in his home lab, playing with software code.
For support files and downloads related to your book, please visit www.PacktPub.com.
Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.PacktPub.comand as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details.
At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a range of free newsletters and receive exclusive discounts and offers on Packt books and eBooks.
https://www.packtpub.com/mapt
Get the most in-demand software skills with Mapt. Mapt gives you full access to all Packt books and video courses, as well as industry-leading tools to help you plan your personal development and advance your career.
Fully searchable across every book published by Packt
Copy and paste, print, and bookmark content
On demand and accessible via a web browser
Thanks for purchasing this Packt book. At Packt, quality is at the heart of our editorial process. To help us improve, please leave us an honest review.
If you'd like to join our team of regular reviewers, you can e-mail us at [email protected]. We award our regular reviewers with free eBooks and videos in exchange for their valuable feedback. Help us be relentless in improving our products!
Preface
What this book covers?
What you need for this book
Who this book is for
Sections
Getting ready
How to do it…
How it works…
There's more…
See also
Conventions
Reader feedback
Customer support
Downloading the example code
Downloading the color images of this book
Errata
Piracy
Questions
Configuring JUNOS through NETCONF
Introduction
JUNOS NETCONF over SSH setup
Getting ready
How to do it...
How it works...
There's more...
Making NETCONF RPC requests and replies
Getting ready
How to do it...
How it works...
There's more...
Discovering NETCONF RPCs
Getting ready
How to do it...
How it works...
There's more...
See also
Using NETCONF to apply configuration changes
Getting ready
How to do it...
How it works...
Processing NETCONF using classic Expect/TCL
Getting ready
How to do it...
How it works...
Processing NETCONF with Python
Getting ready
How to do it...
How it works...
Processing NETCONF with Node.js
Getting ready
How to do it...
How it works...
Working with the Junos REST API
Introduction
Junos REST API setup
Getting ready
How to do it...
How it works...
There's more
Making REST API calls to Junos with Python
Getting ready...
How to do it...
How it works...
There's more...
Making REST API calls to Junos with Node.js
Getting ready
How to do it...
How it works...
Managing passwords safely
Getting ready
How to do it...
How it works...
Applying configuration changes through the REST API
Getting ready
How to do it...
How it works...
Using SLAX to Write Op Scripts
Introduction
Making remote procedure calls
Getting ready
How to do it...
How it works...
Using XPath predicate expressions
Getting started
How to do it...
How it works...
Working with regular expressions
Getting ready
How to do it...
How it works...
Working with IP addresses
Getting ready
How to do it...
How it works...
There's more
Debugging SLAX scripts
Getting ready
How to do it...
How it works...
There's more
Making custom show commands
Getting ready
How to do it...
How it works...
Making configuration changes
Getting ready
How to do it...
How it works...
Event Programming
Introduction
Archiving configurations after a change
Getting ready
How to do it…
How it works...
There's more
Capturing output after an event
Getting ready
How to do it…
How it works…
There's more
Custom responses to an event
Getting ready
How to do it…
How it works…
There's more
Dealing with a flapping interface
Getting ready
How to do it…
How it works…
Dealing with a flapping OSPF neighbor
Getting ready
How to do it…
How it works…
DIY routing protocol
Getting ready
How to do it…
How it works…
Debugging event scripts
Getting ready
How to do it…
How it works…
Automating JUNOS with PyEZ
Introduction
Setting up a PyEZ environment
Getting ready
How to do it…
How it works…
There’s more
Exploring the XML RPC using PyEZ
Getting ready
How to do it…
How it works…
Calling operational RPCs and setting timeouts
Getting ready
How to do it…
How it works…
Configuration analysis and reporting
Getting ready
How to do it…
How it works…
Making raw CLI commands from PyEZ
Getting ready
How to do it…
How it works…
There’s more
Using tables and views
Getting ready
How to do it…
How it works…
There's more
Using custom tables and views
Getting ready
How to do it…
How it works…
Making configuration changes with PyEZ
Getting ready
How to do it…
How it works...
There’s more
Template configurations with Jinja2
Getting ready
How to do it…
How it works...
Advanced Visualization Applications
Introduction
Visualizing graphs
Getting ready
Graph principles
Graph data
How to do it...
Instantiating the template
Drawing the graph
Running the example graph
How it works...
Instantiating the template
Drawing the graph
Extracting graphs from ISIS
Getting started
ISIS primer
How to do it...
How it works...
Extracting graphs from OSPF
Getting ready
OSPF primer
How to do it...
How it works...
Extracting graphs from MPLS VPNs
Getting ready
BGP MPLS VPN primer
How to do it...
How it works...
There's more
Monitoring and Maintaining JUNOS
Introduction
Monitoring configuration changes network-wide
Getting ready
How to do it…
SSH file transfer
JUNOS OS event policy
Web server application
Web client application
How it works...
SSH File Transfer
JUNOS OS event policy
Web server application
Web client application
There's more
Monitoring interface performance
Getting ready
Object-oriented primer for Node.js
How to do it…
Server application
Web client application
Setting up and Running
How it works...
Server application
Web client application
There's more
Monitoring system health
Getting ready
How to do it...
Server application
Web client application
How it works...
Server application
Client application
Running the application
There's more
Monitoring MPLS LDP statistics
Getting ready
How to do it...
Server application
Web client application
How it works...
Server application
Web client application
Security Applications
Introduction
Enforcing configuration standards through commit scripts
Getting ready
How to do it...
How it works...
Loopback address
IGP interface deletion
EBGP policy default
Building BGP route filters
Getting ready
How to do it...
How it works...
Applying anti-spoofing filters
Getting ready
How to do it...
How it works...
There's more
Operating a distributed ACL function
Getting ready
How to do it...
How it works...
Extending JUNOS with Ansible
Introduction
Installing Ansible
Getting ready
How to do it...
How it works...
There's more
Configuring Ansible for JUNOS
Getting ready
How to do it..
How it works...
Extracting estate-wide configurations
Getting ready
How to do it...
How it works...
There's more...
Performing platform-specific or group-specific operations
Getting ready
How to do it...
How it works...
Using variables and vaults
Getting ready
How to do it...
How it works...
In the world of networking, Juniper’s Junos operating system powers some of the largest and most demanding enterprise and service provider networks out there. Whether it’s the flagship T, MX, and PTX series routers that power ISPs, the enterprise-friendly EX series switches and SRX series firewalls or data center QFX-series, the aspect that remains in common in Junos is the operating system originally based on BSD Unix.
What Juniper has capitalized on, however, is a universal configuration management framework that powers all of the varied aspects of Junos and that is based on inter-communication using XML. The choice of XML puts Junos in a prime position for integrating its capabilities into larger systems by exposing its XML machine-to-machine interfaces—so-called RPCs or Remote Procedure Calls—to automation applications.
In this book, we take a recipe-based approach to investigating and exploring the automation technologies surrounding Junos and provide some examples of how to tackle common network requirements.
Chapter 1, Configuring JUNOS through NETCONF, explores the NETCONF standard originally defined in RFC 4741, specifically, how it’s used over SSH to communicate with Junos devices. We will work through some practical examples of communicating with Junos programmatically from several technologies.
Chapter 2,Working with the Junos REST API, explores the relatively new REST interface with Junos and how to make use of it in HTTP and HTTPS environments. We will develop two sample REST clients that interact with Junos.
Chapter 3, Using SLAX to Write Op Scripts, explores Juniper’s SLAX technology for manipulating the XML representations used by the foundations of Junos. We will look at how to use SLAX as a macro language to make use of remote procedure calls and produce customized, filtered output.
Chapter 4,Event Programming, builds upon the SLAX expertise and leverages the capability to be proactive and respond to events. We’ll develop scripts to deal with common network situations and even a make shift routing protocol.
Chapter 5, Automating Junos with PyEZ, focuses on the Juniper extension module to Python, PyEZ, and its utility in programmatically working with Junos. You'll learn about PyEZ primitives, such as facts, views, and tables, and get a taste of using YAML to write Jinja2 templates.
Chapter 6, Advanced Visualization Applications, helps us visualize some of the aspects of our Junos network. We’ll build a basic graph utility for extracting information and then we'll use a popular rendering engine to visualize elements of our network, such as routing protocols.
Chapter 7, Monitoring and Maintaining Junos, looks at ways of monitoring what happens on our Junos network. We’ll build a tool to monitor configuration changes as well as look at how we can graphically monitor interface usage and other resources.
Chapter 8, Security Applications, looks at how we can use automation technologies to maintain the security of our networks. We’ll build commit scripts to vet configuration changes and look at BGP prefix filtering and anti-spoofing protection.
Chapter 9, Extending JUNOS with Ansible, explores how we can use the popular Ansible IT automation framework in conjunction with Junos as part of a wider enterprise orchestration system.
In order to make use of the examples in this book, you’ll need a Unix-based management device, which can be your laptop or a virtual machine on your laptop, and access to a Junos platform. In some cases, it’s possible to run Junos in a virtual environment, such as with Juniper’s latest vMX developments or with vRR - virtual route reflector. Finally, if all else fails, you can also build an olive. But I'm not going to tell you how to do that!
This book is for you if you’re a network engineer or operator with enthusiasm for network technology and a persistent thirst for wanting to know how you can get Juniper routers and switches to do more with less.
In this book, you will find several headings that appear frequently (Getting ready, How to do it…, How it works…, There's more…, and See also). To give clear instructions on how to complete a recipe, we use these sections as follows:
This section tells you what to expect in the recipe, and describes how to set up any software or any preliminary settings required for the recipe.
This section contains the steps required to follow the recipe.
This section usually consists of a detailed explanation of what happened in the previous section.
This section consists of additional information about the recipe in order to make the reader more knowledgeable about the recipe.
This section provides helpful links to other useful information for the recipe.
In this book, you will find a number of text styles that distinguish between different kinds of information. Here are some examples of these styles and an explanation of their meaning.
Code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles are shown as follows: In this case, the RPC that we call isget-interface-information
A block of code is set as follows:
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:JUNOS="http://xml.juniper.net/JUNOS/15.1F6/JUNOS"> <ok/> </rpc-reply>
When we wish to draw your attention to a particular part of a code block, the relevant lines or items are set in bold:
<isis-database-entry>
<lsp-id>lon-lab-access-4.00-00</lsp-id>
<sequence-number>0x1002</sequence-number>
Any command-line input or output is written as follows:
adamc@router>
show configuration interfaces em0.0 | display xml
<rpc-reply xmlns:JUNOS="http://xml.juniper.net/JUNOS/ 15.1F6/JUNOS">
New terms and important words are shown in bold.
Feedback from our readers is always welcome. Let us know what you think about this book-what you liked or disliked. Reader feedback is important for us as it helps us develop titles that you will really get the most out of. To send us general feedback, simply e-mail [email protected], and mention the book's title in the subject of your message. If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, see our author guide at www.packtpub.com/authors.
Now that you are the proud owner of a Packt book, we have a number of things to help you to get the most from your purchase.
You can download the example code files for this book from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support, and register to have the files e-mailed directly to you. You can download the code files by following these steps:
Log in or register to our website using your e-mail address and password.
Hover the mouse pointer on the
SUPPORT
tab at the top.
Click on
Code Downloads & Errata
.
Enter the name of the book in the
Search
box.
Select the book for which you're looking to download the code files.
Choose from the drop-down menu where you purchased this book from.
Click on
Code Download
.
You can also download the code files by clicking on the Code Files button on the book's webpage at the Packt Publishing website. This page can be accessed by entering the book's name in the Search box. Please note that you need to be logged in to your Packt account. Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of:
WinRAR / 7-Zip for Windows
Zipeg / iZip / UnRarX for Mac
7-Zip / PeaZip for Linux
The code bundle for the book is also hosted on GitHub at https://github.com/PacktPublishing/JUNOS-Automation-Cookbook. We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!
We also provide you with a PDF file that has color images of the screenshots/diagrams used in this book. The color images will help you better understand the changes in the output. You can download this file from https://www.packtpub.com/sites/default/files/downloads/JUNOSAutomationCookbook_ColorImages.pdf.
Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you find a mistake in one of our books-maybe a mistake in the text or the code-we would be grateful if you could report this to us. By doing so, you can save other readers from frustration and help us improve subsequent versions of this book. If you find any errata, please report them by visiting http://www.packtpub.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details of your errata. Once your errata are verified, your submission will be accepted and the errata will be uploaded to our website or added to any list of existing errata under the Errata section of that title. To view the previously submitted errata, go to https://www.packtpub.com/books/content/support, and enter the name of the book in the search field. The required information will appear under the Errata section.
Piracy of copyrighted material on the Internet is an ongoing problem across all media. At Packt, we take the protection of our copyright and licenses very seriously. If you come across any illegal copies of our works in any form on the Internet, please provide us with the location address or website name immediately so that we can pursue a remedy. Please contact us at [email protected] with a link to the suspected pirated material. We appreciate your help in protecting our authors and our ability to bring you valuable content.
If you have a problem with any aspect of this book, you can contact us at [email protected], and we will do our best to address the problem.
In this chapter, we will cover the following recipes:
JUNOS NETCONF over SSH setup
Making NETCONF RPC requests and replies
Using NETCONF to apply configuration changes
Processing NETCONF using classic Expect/TCL
Processing NETCONF with Python
Processing NETCONF with Node.js
Discovering NETCONF RPCs
The Network Configuration Protocol (NETCONF) standard, defined most recently in RFC 6241, allows a network management application to access a JUNOS OS (or other vendor) network element through the use of a series of Remote Procedure Calls (RPCs) carried over a serialized XML transport.
For programmatic access to JUNOS OS devices, this method is preferable for the use of raw command-line processing, since the data format is structured, precise, and suitable for unambiguous machine reading.
In this chapter, we investigate how to setup NETCONF access to JUNOS OS devices and then look at how to make use of that from common programming platforms.
In this recipe, we'll prepare a JUNOS OS router for interaction using the NETCONF service. We can do this in one of two ways:
Using NETCONF-over-SSH on dedicated TCP port 830,
Using NETCONF inline with mainstream SSH communications, on TCP port 22.
We'll set up secure SSH keys and a dedicated username for an automation application. Then we'll configure the systems services hierarchy within the Junos OS for the specific method.
In order to complete this recipe, you need access to a JUNOS OS router, switch, or firewall, and a general-purpose Linux/UNIX management host from which to control it.
The steps to prepare a JUNOS OS router for interaction using NETCONF services are as follows:
Verify that SSH is configured on your router by ensuring that you have the following configuration present:
adamc@router> show configuration system services
ssh;
Generate SSH keys. Generate a public/private key pair using the SSH utility,
ssh-keygen
:
unix$ ssh-keygen -C "JUNOS Automation" -f JUNOS_auto_id_rsa
Generating public/private rsa key pair.
Enter file in which to save the key (.ssh/id_rsa):
JUNOS_auto_id_rsa
Enter passphrase (empty for no passphrase): <type nothing here>
Enter same passphrase again: <again, nothing>
Your identification has been saved in JUNOS_auto_id_rsa.
Your public key has been saved in JUNOS_auto_id_rsa.pub.
Once completed, verify that you have two new files in your working directory:
Filename
Description
JUNOS_auto_id_rsa
Private SSH key, reserved for use by your management automation application only
JUNOS_auto_id_rsa.pub
Corresponding public SSH key (think of it as a certificate) is able to authenticate the private key.
Configure a dedicated user profile to be used for NETCONF access that makes use of the previously generated key-pair. Apply the
.pub
file contents to the Junos configuration.
adamc@router> show configuration system login user auto
uid 2001;
class super-user;
authentication {
ssh-rsa "ssh-rsa [ actual key omitted] JUNOS Automation"; ##
SECRET-DATA
}
Enable a dedicated NETCONF-over-SSH transport endpoint by configuring the following service:
adamc@router> show configuration system services
ssh;
netconf {
ssh;
}
Connect to the NETCONF service to witness the protocol greeting and validate the correct operation:
unix$ ssh -p 830 -i JUNOS_auto_id_rsa [email protected] -s
netconf
<!-- No zombies were killed during the creation of this user
interface -->
<!-- user auto, class j-super-user -->
<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<capabilities>
<capability>urn:ietf:params:netconf:base:1.0</capability>
<capability>urn:ietf:params:netconf:capability:candidate:1.0
</capability>
<capability>urn:ietf:params:netconf:capability:confirmed-
commit:1.0</capability>
<capability>urn:ietf:params:netconf:capability:validate:1.0
</capability>
<capability>urn:ietf:params:netconf:capability:url:1.0?
scheme=http,ftp,file</capability>
<capability>urn:ietf:params:xml:ns:netconf:base:1.0</capability>
<capability>urn:ietf:params:xml:ns:netconf:capability:
candidate:1.0</capability>
<capability>urn:ietf:params:xml:ns:netconf:capability:confirmed-
commit:1.0</capability>
<capability>urn:ietf:params:xml:ns:netconf:capability:
validate:1.0
</capability>
<capability>urn:ietf:params:xml:ns:netconf:capability:url:1.0?
protocol=http,ftp,file</capability>
<capability>http://xml.juniper.net/netconf/JUNOS/1.0</capability>
<capability>http://xml.juniper.net/dmi/system/1.0</capability>
</capabilities>
<session-id>35980</session-id>
</hello>
]]>]]>
On the same SSH session, issue a test RPC to prove that things are working normally. Enter the highlighted first line of the following text exactly as it is and observe the response:
<rpc><get-software-information/></rpc>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:JUNOS="http://xml.juniper.net/JUNOS/15.1F6/JUNOS"> <software-information> <host-name>router</host-name> <product-model>olive</product-model> <product-name>olive</product-name> <JUNOS-version>15.1F6-S5.6</JUNOS-version> <package-information> <name>os-kernel</name> <comment>JUNOS OS Kernel 64-bit [ 20161130.340898_builder_stable_10]</comment> </package-information> <package-information> <name>os-libs</name> <comment>JUNOS OS libs [20161130.340898_builder_stable_10] </comment> </package-information> <package-information> <name>os-runtime</name> <comment>JUNOS OS runtime [20161130.340898_builder_stable_10] </comment> </package-information> […]
In step 1, we verified that the SSH protocol was configured and available in order to access the JUNOS device.
In step 2, we created an SSH public/private key-pair in order to allow any applications that we create to be able to login and authenticate with the JUNOS device in the same way that an ordinary user does. Key-based authentication is preferred over conventional password authentication for this, because it removes the authentication step from the interactive dialog under development.
In step 3, we created a dedicated user profile on the JUNOS device for automation applications and associated it with the public key that we created. Any automation application that makes use of the corresponding private key can be authenticated on the JUNOS OS platform with the public key.
With step 4, we created a NETCONF-over-SSH service endpoint. This isn't technically required, but it can be useful if you would like to treat ordinary user management traffic independently from machine-to-machine programmatic access, and want to enforce such policies via a firewall or similar.
In step 5, we connected to the NETCONF-over-SSH service on port 830 and observed its welcome greeting. We used the -i switch in order to specify the private key that we generated in step 2.
NETCONF-over-SSH runs on a separate TCP port to the conventional SSH transport. The default, Internet Assigned numbers Authority (IANA) is 830, but JUNOS OS allows you to select any arbitrary number. When NETCONF-over-SSH is used in this manner, the SSH server makes use of a protocol feature called subsystems. This allows the SSH server to directly connect to another internal component without consideration for details such as pseudo-terminal or user shell.
For this reason though, when we connect from an ordinary SSH client, we need to use the -s switch in order to specify that we want the NETCONF subsystem. Alternatively, it is possible to connect to the NETCONF service using the convention SSH management interface in the following manner:
unix$ ssh -i JUNOS_auto_id_rsa [email protected] netconfFinally, in step 6, we issued a very basic RPC request to ask the JUNOS OS device for information about its system software. We can see the regularity in the structure of communications between client and NETCONF server. The client's communications consists of a remote procedure call request, enclosed in <rpc></rpc> tags. And the server responds with a document structure enclosed within <rpc-reply></rpc-reply> tags. The actual internal structure of the response depends on the exact RPC called, but the XML format is easier to machine-read than a free-form text interface designed to please a human.
In step 5 and step6, we saw the guts of the NETCONF protocol dialog occurring. The server said hello to us, and we issued a procedure call which the server duly answered. In actual fact, we were being a little lax in our use of the NETCONF protocol standard there. If you want to speak RFC-compliant NETCONF, it is customary for both the client and the server to issue hello messages that describe their capabilities. The capabilities announced describe concepts over and above some of the base NETCONF principles that are supported by the element, and the manager. In this case, the JUNOS OS server has likely little concern for our client capabilities and takes the IETF mantra of being liberal in acceptance, conservative in communication, to heart.
The other significant point to note is the special sequence of characters used to delimit successive XML messages. We see it at the end of a hello message, and at the end of every RPC response the server answers:
]]>]]>
Technically, this framing sequence is actually deprecated within the latest specification of the NETCONF-over-SSH standard, because it was discovered that it can legitimately appear within the XML payload. The JUNOS OS implementation currently makes use of the framing sequence to flag the end of its responses, but if you write software -- as we will -- to read the NETCONF XML stream directly, then it is wise to be aware that this behavior could change in the future.
With NETCONF-over-SSH happily configured on our network of JUNOS OS devices, we can now connect over the network and make RPCs in order to inspect the operational status of the device. Lets look at a couple of examples to learn the fundamentals of how the JUNOS OS XML RPCs work.
Ensure you've completed the JUNOS NETCONF-over-SSH setup recipe previously and have a working JUNOS OS device with a NETCONF interface in place. It doesn't necessarily matter what the configuration of that device is.
The steps for making NETCONF RPC requests and replies are as follows:
Connect to the NETCONF-over-SSH server in a similar manner to the previous recipe:
unix$ ssh -i JUNOS_auto_id_rsa [email protected] netconf
Query the system ARP table by connecting to the NETCONF-over-SSH session in a similar manner to the previous recipe and issuing the appropriate RPC:
<rpc><get-arp-table-information/></rpc>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:JUNOS="http://xml.juniper.net/JUNOS/15.1F6/JUNOS"> <arp-table-information xmlns="http://xml.juniper.net/JUNOS/15.1F6/JUNOS-arp" JUNOS:style="normal"> <arp-table-entry> <mac-address> 0a:00:27:00:00:00 </mac-address> <ip-address> 10.0.201.1 </ip-address> <hostname> adamc-mac </hostname> <interface-name> em0.0 </interface-name> <arp-table-entry-flags> <none/> </arp-table-entry-flags> </arp-table-entry> </arp-table-information> </rpc-reply> ]]>]]>
Repeat the query, but use the
format
tag to modify the output to be a plain text:
<rpc><get-arp-table-information format="text"/></rpc>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:JUNOS="http://xml.juniper.net/JUNOS/15.1F6/JUNOS"> <output> MAC Address Address Name Interface Flags 0a:00:27:00:00:00 10.0.201.1 adamc-mac em0.0 none </output> </rpc-reply> ]]>]]>
Use an option to the ARP table RPC in order to disable the name resolution:
<rpc><get-arp-table-information format="text"><no-resolve/></get-
arp-table-information></rpc>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:JUNOS="http://xml.juniper.net/JUNOS/15.1F6/JUNOS"> <output> MAC Address Address Interface Flags 0a:00:27:00:00:00 10.0.201.1 em0.0 none </output> </rpc-reply> ]]>]]>
Query the system routing table and inspect the output:
<rpc><get-route-information/></rpc>
[...]
Repeat the system routing table query, but apply an argument for a particular destination:
<rpc><get-route-information>
<destination>10.0.201.201</destination></get-route-information>
</rpc>
[...]
In steps 1 and step2, we connected and issued a simple RPC to query the ARP table from the router. The rather verbose XML response encodes structure that is the machine-readable version of what we see in the CLI when we issue the show arp command. Each data atom is enclosed hierarchically within XML tags indicating its type and any associated properties. This structured output format lends itself particularly well for machine-to-machine automation applications.
In step 3, we issued the same RPC, but requested JUNOS OS to give us the plain text output so that we could compare the difference. In almost all cases, the plain text output seen when we use the format="text" modifier to the RPC is identical to what we would see in the CLI.
In step 4, we see how options to the CLI commands are encoded within the XML RPC format. In this case the show arp no-resolve option is typically used to prevent any name resolution of IP addresses. It's simply an XML subtag to the main <get-arp-table-information> tag.
Steps 5 and 6 go a step further looking at the RPC that implements the show route command. In step 5, we show how arguments are added to the RPC.
Looking at these example RPCs and the XML format within, we can see two clear styles. One pairs together the opening and closing tags in a strict manner, allowing the inclusion of options and arguments. The other allows an abbreviation of an otherwise empty pair of tags by simply using a leading slash. Compare the following two RPCs, which are identically supported by the JUNOS OS XML NETCONF interpreter:
<rpc><get-route-information/></rpc><rpc><get-route-information></get-route-information></rpc>
We've seen in the previous recipes how to use some common RPCs to query system state information on our JUNOS OS devices. But how exactly did we discover the cryptic connection between, for example, the CLI command show route and the RPC equivalent <get-route-information>? The JUNOS OS management daemon, mgd, is responsible for speaking the necessary native protocol to the type of client requesting information: either a human operator on the CLI, or a machine interface via XML. It maps the available system calls to both a CLI and an RPC. In this recipe, we'll explore this mapping.
Ensure you have access to a working JUNOS OS device. You don't necessarily need to have completed the previous recipes on setting up NETCONF remote access.
The steps for the recipe are as follows:
Log in to the JUNOS OS device using your normal user credentials and choose the operational mode CLI command that you'd like to work with:
adamc@router> show arp
MAC Address Address Name Interface Flags
0a:00:27:00:00:00 10.0.201.1 adamc-mac em0.0 none
Execute the command, but use the pipe modifier in order to query the XML that maps to the corresponding RPC call:
adamc@router> show arp | display xml rpc
<rpc-reply
xmlns:JUNOS="http://xml.juniper.net/JUNOS/15.1F6/JUNOS">
<rpc>
<get-arp-table-information>
</get-arp-table-information>
</rpc>
<cli>
<banner></banner>
</cli>
</rpc-reply>
Repeat the command, but this time use the pipe modifier in order to explore the XML which maps to the response from the RPC call:
adamc@router> show arp | display xml
<rpc-reply
xmlns:JUNOS="http://xml.juniper.net/JUNOS/15.1F6/JUNOS">
<arp-table-information
xmlns="http://xml.juniper.net/JUNOS/15.1F6/JUNOS-arp"
JUNOS:style="normal">
<arp-table-entry>
<mac-address>0a:00:27:00:00:00</mac-address>
<ip-address>10.0.201.1</ip-address>
<hostname>adamc-mac</hostname>
<interface-name>em0.0</interface-name>
<arp-table-entry-flags>
<none/>
</arp-table-entry-flags>
</arp-table-entry>
</arp-table-information>
<cli>
<banner></banner>
</cli>
</rpc-reply>
In step 1, we see the basic command that we're using as a CLI operator.
In step 2, the extra output pipe causes the JUNOS OS management daemon to not actually execute the command, but instead tell us the RPC that it would use if it were executing the command. So, in this case, we can see that it's <get-arp-table-information>, which is the focus of our attention.
In step 3, we get to learn what the likely response from this RPC will be when our automation app makes the RPC call. In this case, the normal tabular format seen by the human is presented to a machine reader, with each of the fields decorated by XML tags. This allows easy and unambiguous interpretation of the response.
Using the JUNOS OS | xml rpc modifier is also particularly useful for understanding how to present complicated arguments. In this case, for example, it's possible to see how we filter the output of the show route command (which would ordinarily be large and unwieldy) for a specific destination and table:
adamc@router> show route table inet.0 1.0.0.1/32 | display xml
rpc
<rpc-reply xmlns:JUNOS=" http://xml.juniper.net/
JUNOS/15.1F6/JUNOS">
<rpc>
<get-route-information>
<destination>1.0.0.1/32</destination>
<table>inet.0</table>
</get-route-information>
</rpc>
<cli>
<banner></banner>
</cli>
</rpc-reply>
Juniper make great efforts to document the JUNOS OS XML API. You can find the latest version of their XML API explorer at https://apps.juniper.net/xmlapi. It provides a browser-based explorer of the configuration tags available and the operational mode RPCs available as in the following screenshot:
As you might expect, NETCONF isn't limited to querying the JUNOS OS device operational status using RPCs. It can also influence the operating state of the device by applying configuration changes. In contrast to other management models like SNMP however, one doesn't manipulate individual data atoms to effect change. Instead, JUNOS OS makes use of the concept of a candidate configuration which is applied to the various software daemons when the candidate is committed. In this respect, NETCONF and the traditional user-based CLI are consistent.
In this recipe, we'll look at the NETCONF directives necessary to make configuration changes. We'll make a simple interface description change, and we'll also look at how to delete configuration stanzas.
Make sure you've got access to a JUNOS OS platform that you can make changes on. Make sure that you've got a working NETCONF-over-SSH capability with the JUNOS OS platform as per the first recipe in this chapter, JUNOS NETCONF-over-SSH setup.
The steps for the recipe are as follows:
Familiarize yourself with the XML format used within JUNOS OS to represent configuration data. Generally speaking, the XML representation follows the same hierarchy as the configuration format itself. JUNOS OS itself can help you here. Issue the
show configuration | display xml
command in order to see a portion of the configuration expressed in XML:
adamc@router>
show configuration interfaces em0.0 | display xml
<rpc-reply xmlns:JUNOS="http://xml.juniper.net/JUNOS/ 15.1F6/JUNOS">
<configuration JUNOS:commit-seconds="3780" JUNOS:commit- localtime="1970-01-01 01:03:00 UTC" JUNOS:commit-user="adamc">
<interfaces>
<interface>
<name>em0</name>
<unit>
<name>0</name>
<family>
<inet>
<address>
<name>10.0.201.201/24</name>
</address>
</inet>
</family>
</unit>
</interface>
</interfaces>
</configuration>
Connect to the NETCONF-over-SSH server in the usual manner:
unix$ ssh -i JUNOS_auto_id_rsa [email protected] netconf
Use the NETCONF-standard
edit-config
operation to submit a configuration change to the NETCONF server. In this example, we update the description on the
em0.0
interface to something trivial:
<rpc> <edit-config> <target> <candidate/> </target> <config> <configuration> <interfaces> <interface> <name>em0</name> <unit> <name>0</name> <description>Management interface</description> </unit> </interface> </interfaces> </configuration> </config> </edit-config> </rpc>
Verify that the operation was successful. The
<ok/>
RPC reply is what we want to see here.
Commit the configuration by issuing the
commit
NETCONF primitive and checking for the
<ok/>
RPC reply again:
<rpc><commit/></rpc>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:JUNOS="http://xml.juniper.net/JUNOS/15.1F6/JUNOS"> <ok/> </rpc-reply> ]]>]]>
Apply the same configuration, but delete the description attribute by including the special
operation="delete"
XML attribute decoration:
<rpc> <edit-config> <target> <candidate/> </target> <default-operation>none</default-operation> <config> <configuration> <interfaces> <interface> <name>em0</name> <unit> <name>0</name> <description operation="delete"/> </unit> </interface> </interfaces> </configuration> </config> </edit-config> </rpc>
Commit the candidate configuration again, and analyze the configuration and system commit log by hand to verify what happened:
<rpc><commit/></rpc>
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:JUNOS="http://xml.juniper.net/JUNOS/15.1F6/JUNOS"> <ok/> </rpc-reply> ]]>]]>
In step 1, we need to work out what our configuration change looks like in the XML representation that JUNOS OS requires. We can use the CLI to help us with that process.
In step 2, we connect to the NETCONF-over-SSH server in the usual manner.
In step 3, we submit the configuration change that we need, represented in XML, and then in step 4 we look for the server's response. If it isn't the standard <ok/> response, there are a couple of reasons why that might be:
The configuration submission contained an error:
<rpc-error> <error-type>protocol</error-type> <error-tag>operation-failed</error-tag> <error-severity>error</error-severity> <error-message>syntax error</error-message> <error-info> <bad-element>unti</bad-element> </error-info> </rpc-error>
The JUNOS OS configuration database is currently locked by another user:
<rpc-error> <error-type>protocol</error-type> <error-tag>lock-denied</error-tag> <error-severity>error</error-severity> <error-message> configuration database locked by: adamc terminal pts/0 (pid 19893) on since 1970-01-01 01:09:14 UTC, idle 00:03:11 exclusive [edit] </error-message> <error-info> <session-id>19893</session-id> </error-info> </rpc-error>
If all is okay, we proceed to the commit operation in step 5. This is the part of the process where the new configuration actually gets applied. JUNOS OS produces the individual instructions for each of the software processes from the configuration file, and then signals each process to re-read the configuration and implement the change to the new state.
This phase can also have errors if the new configuration causes a runtime error. It's really important to deal with this situation because the configuration change will not be removed, so it has the potential to block up future commit operations as well.
Here's the RPC response that we get, for example, if we try to commit an Ethernet sub-interface with zero-host portion:
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:JUNOS="http://xml.juniper.net/JUNOS/15.1F6/JUNOS"> <rpc-error> <error-type>protocol</error-type> <error-tag>operation-failed</error-tag> <error-severity>error</error-severity> <source-daemon> dcd </source-daemon> <error-path> [edit interfaces em0 unit 10 family inet] </error-path> <error-info> <bad-element> address 1.0.10.0/24 </bad-element> </error-info> <error-message> Cannot assign address 0 on subnet </error-message> </rpc-error>
In order to ensure that we undo the failed configuration attempt, we can use the discard-changes RPC from NETCONF standard. This will cause the JUNOS OS device to discard any changes in the global candidate configuration that we are working on.
<rpc><discard-changes/></rpc>
In steps 6 and 7, we undo the change by submitting a new configuration with a delete directive and then committing to that. Configuration deletions are quite simple, but it's important to understand them. There are two notable differences from the configuration addition:
The
default-operation
RPC property is set to
None
. This property controls how JUNOS OS applies the supplied configuration with respect to the existing candidate configuration. By default, JUNOS OS merges configuration items, which is typically what we want when we're adding or changing values. But when we're deleting configuration items, we don't want JUNOS OS to accidentally create unnecessary configuration hierarchies.
The
operation
property for the item to be deleted is set to
Delete
. This tells JUNOS OS that this particular element should be removed from the configuration.
Don Libes' Expect, extending the ever-flexible Tool Command Language (TCL), forms one of the original ways of automating I/O interaction with terminal-based UNIX processes.
It has been used for numerous applications, from managing the login process on modem dial-up systems, to automating the interaction with network elements in ISP networks in a programmatic way. While this activity of so-called screen-scraping-reading and parsing output -- meant for humans in a machine-compatible way -- can be limited and subject to future-proofing problems, it still represents a significant capability, and sometimes it can be useful to make use of Expect with NETCONF-based network elements.
In this recipe, we explore using a simplistic Expect skeleton program to make RPC calls to our JUNOS OS devices in order to execute commands and extract data.
To complete this recipe, you should have completed the previous recipe, JUNOS NETCONF- over-SSH setup for your device, particularly with respect to establishing SSH key-pairs.
You should ideally make use of Expect 5.45, or a compatible version on your management host. At the time of writing, this version was available in the built-in software package systems of OpenBSD 6.0 and Ubuntu Linux 16.04. Expect is particularly mature and stable however, so if you can't match the exact version, it's unlikely that you'll run into trouble with the example code that we have here.
Our Expect program, netconf.tcl, will be comprised of three main parts, which are as follows:
Some initialization routines to read the command-line arguments
Set up of the NETCONF-over-SSH session
Interaction with the NETCONF-over-SSH session to make an RPC call, and output the response
The steps for the recipe are as follows:
Create the interaction procedure first. To do this, create a TCL procedure that accepts a string argument that will represent the command to run:
proc cmdrpc { cmd } { send -- "<rpc><command format=\"text\">[join $cmd]</command> </rpc>\r\n" set output "" expect { -re {<error-message>([^<]+)</error-message>} { send_error "Command RPC for $cmd caused error: $expect_out(1,string)\r\n" return } -re {<(configuration-)?output[^>]*>} { expect { -re {^[^<]+} { append output $expect_out(0,string) exp_continue } -re "</(configuration-)?output>" {} } regsub -all "<" $output "<" output regsub -all ">" $output ">" output regsub -all "&" $output "&" output return $output } default { send_error "Timeout waiting for RPC [join $cmd]\r\n" send_error [ concat "\t" [ regsub -all {[\r\n]+} $expect_out(buffer) "\r\n\t" ] ] return } } }
Read the environment command-line arguments in order to determine a hostname and a command:
if { [ llength $argv ] != 2 } { send_user "Usage: netconf.tcl hostname command\r\n" exit 1 } set hostname [lrange $argv 0 0] set command [lrange $argv 1 1]
Establish a NETCONF-over-SSH session and call the previously defined interaction procedure to send the RPC and extract the results:
set DELIMITER {]]>]]>} if [ spawn -noecho ssh -p 830 -i JUNOS_auto_id_rsa auto@$hostname -s netconf ] { expect { $DELIMITER { set result [ cmdrpc $command ] if {$result ne ""} { send_user $result } } default { send_error "SSH protocol error (check authorized_keys?)\r\n" exit 1 } } } { send_error "Unable to start SSH client for connection to $hostname\r\n" exit 1 } close exit
