Junos OS, PyEZ User Manual

®
Published
2020-10-27
Junos
OS
Junos PyEZ Developer Guide
Juniper Networks, Inc. 1133 Innovation Way Sunnyvale, California 94089 USA 408-745-2000 www.juniper.net
Juniper Networks, the Juniper Networks logo, Juniper, and Junos are registered trademarks of Juniper Networks, Inc. in the United States and other countries. All other trademarks, service marks, registered marks, or registered service marks are the property of their respective owners.
Juniper Networks assumes no responsibility for any inaccuracies in this document. Juniper Networks reserves the right to change, modify, transfer, or otherwise revise this publication without notice.
Junos®OS Junos PyEZ Developer Guide
Copyright © 2020 Juniper Networks, Inc. All rights reserved.
The information in this document is current as of the date on the title page.
ii
YEAR 2000 NOTICE
Juniper Networks hardware and software products are Year 2000 compliant. Junos OS has no known time-related limitations through the year 2038. However, the NTP application is known to have some difficulty in the year 2036.
END USER LICENSE AGREEMENT
The Juniper Networks product that is the subject of this technical documentation consists of (or is intended for use with) Juniper Networks software. Use of such software is subject to the terms and conditions of the End User License Agreement (“EULA”) posted at https://support.juniper.net/support/eula/. By downloading, installing or using such software, you agree to the terms and conditions of that EULA.

Table of Contents

1
2
3
About the Documentation | x
Documentation and Release Notes | x
Documentation Conventions | x
Documentation Feedback | xiii
Requesting Technical Support | xiii
Self-Help Online Tools and Resources | xiv
Creating a Service Request with JTAC | xiv
Disclaimer
Junos PyEZ Disclaimer | 16
iii
Junos PyEZ Overview
Understanding Junos PyEZ | 18
Junos PyEZ Overview | 18
Benefits of Junos PyEZ | 19
Using Junos PyEZ in Automation Scripts | 19
Junos PyEZ Resources | 20
Junos PyEZ Modules Overview | 21
Installing Junos PyEZ
Installing Junos PyEZ | 25
Installing Prerequisite Software | 25
Installing Junos PyEZ on the Configuration Management Server | 27
Installing Junos PyEZ in a Python Virtual Environment | 28
Using the Junos PyEZ Docker Image | 29
Setting Up Junos PyEZ Managed Nodes | 31
Enabling NETCONF over SSH on Devices Running Junos OS | 32
Satisfying Requirements for SSHv2 Connections | 32
Configuring Telnet Service on Devices Running Junos OS | 33
Connecting to and Retrieving Facts From a Device Using Junos PyEZ
4
5
Connecting to Devices Running Junos OS Using Junos PyEZ | 36
Connection Methods Overview | 36
Understanding Junos PyEZ Connection Properties | 38
Connecting to a Device Using SSH | 39
Connecting to a Device Using Outbound SSH | 43
Connecting to a Device Using Telnet | 47
Connecting to a Device Using a Serial Console Connection | 49
Authenticating Junos PyEZ Users | 52
Junos PyEZ User Authentication Overview | 52
Authenticating Junos PyEZ Users Using a Password | 53
Authenticating Junos PyEZ Users Using SSH Keys | 55
Generating and Configuring SSH Keys | 56
iv
Referencing SSH Keys in Junos PyEZ Applications | 57
Using Junos PyEZ to Retrieve Facts from Devices Running Junos OS | 60
Understanding Junos PyEZ Device Facts | 61
Example: Retrieving Facts from Devices Running Junos OS | 63
Accessing the Shell on Devices Running Junos OS Using Junos PyEZ | 66
Using Junos PyEZ to Manage Device Operations
Using Junos PyEZ to Execute RPCs on Devices Running Junos OS | 71
Mapping Junos OS Commands to Junos PyEZ RPCs | 71
Executing RPCs as a Property of the Device Instance | 73
Specifying the Format of the RPC Output | 74
Specifying the Scope of Data to Return | 76
Specifying the RPC Timeout | 77
Normalizing the XML RPC Reply | 78
Suppressing RpcError Exceptions Raised for Warnings in Junos PyEZ Applications | 80
Using Junos PyEZ to Reboot or Shut Down Devices Running Junos OS | 81
Performing a Reboot or Shut Down | 82
Performing a Reboot or Shut Down with a Delay or at a Specified Time | 84
Specifying the Target for the Reboot or Shutdown | 85
6
Rebooting a VM Host | 86
Using Junos PyEZ to Install Software on Devices Running Junos OS | 87
Supported Deployment Scenarios | 87
Specifying the Software Image Location | 88
Installation Process Overview | 89
Specifying Installation and Checksum Timeouts | 91
Logging the Installation Process | 92
Performing a VM Host Upgrade | 93
Performing a Unified ISSU or NSSU | 94
Example: Using Junos PyEZ to Install Software on Devices Running Junos OS | 96
Transferring Files Using Junos PyEZ | 105
Specifying the XML Parser for a Junos PyEZ Session | 109
v
Using Junos PyEZ to Manage the Configuration
Using Junos PyEZ to Retrieve a Configuration | 112
Retrieving the Complete Candidate Configuration | 112
Specifying the Source Database for the Configuration Data | 113
Specifying the Scope of Configuration Data to Return | 115
Specifying the Format for Configuration Data to Return | 118
Retrieving Configuration Data for Standard or Custom YANG Data Models | 119
Specifying Additional RPC Options | 121
Handling Namespaces in Configuration Data | 121
Using Junos PyEZ to Compare the Candidate Configuration and a Previously Committed
Configuration | 123
Using Junos PyEZ to Configure Devices Running Junos OS | 126
Comparing Structured and Unstructured Configuration Changes | 126
Understanding the General Configuration Process | 128
Specifying the Configuration Mode | 130
Specifying the Load Operation | 132
Creating the Config or Table Object as a Property of the Device Instance | 133
Using the Junos PyEZ Config Utility to Configure Devices Running Junos OS | 134
Configuration Process Overview | 134
Specifying the Configuration Mode | 136
Specifying the Load Operation | 137
Specifying the Format of the Configuration Data to Load | 138
Specifying the Location of the Configuration Data | 139
Loading Configuration Data from a Local or Remote File | 140
Loading Configuration Data from a String | 142
Loading Configuration Data Formatted as an XML Object | 144
Loading Configuration Data Using Jinja2 Templates | 145
Rolling Back the Configuration | 147
Loading the Rescue Configuration | 149
vi
Committing the Configuration | 150
Using Junos PyEZ to Commit the Configuration | 151
Committing the Candidate Configuration | 151
Specifying Commit Options | 153
Example: Using Junos PyEZ to Load Configuration Data from a File | 157
Example: Using Junos PyEZ to Roll Back the Configuration | 167
Using Junos PyEZ to Manage the Rescue Configuration on Devices Running Junos
OS | 174
Managing the Rescue Configuration | 174
Saving a Rescue Configuration | 175
Retrieving the Rescue Configuration | 175
Loading and Committing the Rescue Configuration | 176
Deleting the Rescue Configuration | 176
Example: Using Junos PyEZ to Save a Rescue Configuration | 176
Creating and Using Junos PyEZ Tables and Views
7
Understanding Junos PyEZ Tables and Views | 185
Predefined Junos PyEZ Operational Tables (Structured Output) | 187
Loading Inline or External Tables and Views in Junos PyEZ Applications | 190
Importing Junos PyEZ’s Predefined Tables and Views | 191
Loading Inline Tables and Views | 191
Importing External Tables and Views | 193
Using Tables and Views | 194
Defining Junos PyEZ Operational Tables for Parsing Structured Output | 196
Table Name | 198
RPC Command (rpc) | 198
RPC Default Arguments (args) | 198
vii
RPC Optional Argument Key (args_key) | 199
Table Item (item) | 200
Table Item Key (key) | 201
Table View (view) | 204
Defining Views for Junos PyEZ Operational Tables that Parse Structured Output | 205
View Name | 207
Fields (fields) | 207
Groups (groups) and Field Groups (fields_) | 209
Using Junos PyEZ Operational Tables and Views that Parse Structured Output | 211
Retrieving Table Items | 211
Accessing Table Items | 213
Iterating Through a Table | 214
Defining Junos PyEZ Operational Tables for Parsing Unstructured Output | 215
Summary of Parameters in Op Tables for Parsing Unstructured Output | 216
Table Name | 217
Command | 218
Command Arguments (args) | 218
Target FPC (fpc) | 219
Table Item (item) | 221
Table Item Key (key) | 224
Selected Keys (key_items) | 225
Section Title (title) | 227
Field Delimiter (delimiter) | 228
Eval Expression (eval) | 229
Table View (view) | 231
Defining Views for Junos PyEZ Operational Tables that Parse Unstructured Output | 231
Summary of Parameters in Views for Parsing Unstructured Output | 232
View Name | 233
columns | 233
Eval Expression (eval) | 236
exists | 238
fields | 239
viii
filters | 244
regex | 246
Using Junos PyEZ Operational Tables and Views that Parse Unstructured Output | 252
Defining Junos PyEZ Configuration Tables | 253
Table Name | 255
Configuration Scope (get or set) | 255
Key Field (key-field) | 257
Required Keys (required_keys) | 258
Table View (view) | 259
Defining Views for Junos PyEZ Configuration Tables | 260
View Name | 262
Fields (fields) | 263
Field Options ('get' Tables) | 265
Field Options ('set' Tables) | 266
Groups (groups) and Field Groups (fields_) | 268
Using Junos PyEZ Configuration Tables to Retrieve Configuration Data | 270
Retrieving Configuration Items | 271
Specifying Inheritance and Group Options | 272
Accessing Table Items | 274
Iterating Through a Table | 275
8
Overview of Using Junos PyEZ Configuration Tables to Define and Configure Structured
Resources | 276
Creating the Structured Resource | 277
Using the Resource in a Junos PyEZ Application | 278
Using Junos PyEZ Configuration Tables to Configure Structured Resources on Devices
Running Junos OS | 280
General Configuration Process | 281
Configuring Statements Consisting of a Fixed-Form Keyword | 284
Configuring Multiple Values for the Same Statement | 286
Configuring Multiple Instances of the Same Statement | 287
Configuring Multiple Instances of the Same Resource | 289
Deleting Containers or Leaf Statements | 291
ix
Configuring Properties Corresponding to Junos XML Attributes | 293
Using append() to Generate the Junos XML Configuration Data | 296
Viewing Your Configuration Changes | 297
Controlling the RPC Timeout Interval | 298
Saving and Loading Junos PyEZ Table XML to and from Files | 299
Troubleshooting Junos PyEZ
Troubleshooting jnpr.junos Import Errors | 303
Troubleshooting Junos PyEZ Connection Errors | 304
Troubleshooting Junos PyEZ Authentication Errors When Managing Devices Running
Junos OS | 305
Troubleshooting Junos PyEZ Errors When Configuring Devices Running Junos OS | 306
Troubleshooting Timeout Errors | 306
Troubleshooting Configuration Lock Errors | 307
Troubleshooting Configuration Change Errors | 308

About the Documentation

IN THIS SECTION
Documentation and Release Notes | x
Documentation Conventions | x
Documentation Feedback | xiii
Requesting Technical Support | xiii
Use this guide to develop Python scripts that remotely automate and manage devices running Junos OS using the Juniper Networks Junos PyEZ Python library.
x

Documentation and Release Notes

To obtain the most current version of all Juniper Networks®technical documentation, see the product documentation page on the Juniper Networks website at https://www.juniper.net/documentation/.
If the information in the latest release notes differs from the information in the documentation, follow the product Release Notes.
Juniper Networks Books publishes books by Juniper Networks engineers and subject matter experts. These books go beyond the technical documentation to explore the nuances of network architecture, deployment, and administration. The current list can be viewed at https://www.juniper.net/books.

Documentation Conventions

Table 1 on page xi defines notice icons used in this guide.
Table 1: Notice Icons
xi
DescriptionMeaningIcon
Indicates important features or instructions.Informational note
Caution
Indicates a situation that might result in loss of data or hardware damage.
Alerts you to the risk of personal injury or death.Warning
Alerts you to the risk of personal injury from a laser.Laser warning
Indicates helpful information.Tip
Alerts you to a recommended use or implementation.Best practice
Table 2 on page xi defines the text and syntax conventions used in this guide.
Table 2: Text and Syntax Conventions
ExamplesDescriptionConvention
Fixed-width text like this
Italic text like this
Represents text that you type.Bold text like this
Represents output that appears on the terminal screen.
Introduces or emphasizes important
new terms.
Identifies guide names.
Identifies RFC and Internet draft
titles.
To enter configuration mode, type the configure command:
user@host> configure
user@host> show chassis alarms
No alarms currently active
A policy term is a named structure
that defines match conditions and actions.
Junos OS CLI User Guide
RFC 1997, BGP Communities
Attribute
Table 2: Text and Syntax Conventions (continued)
xii
ExamplesDescriptionConvention
Italic text like this
Text like this
< > (angle brackets)
| (pipe symbol)
Represents variables (options for which you substitute a value) in commands or configuration statements.
Represents names of configuration statements, commands, files, and directories; configuration hierarchy levels; or labels on routing platform components.
variables.
Indicates a choice between the mutually exclusive keywords or variables on either side of the symbol. The set of choices is often enclosed in parentheses for clarity.
Configure the machine’s domain name:
[edit] root@# set system domain-name
domain-name
To configure a stub area, include
the stub statement at the [edit protocols ospf area area-id]
hierarchy level.
The console port is labeled
CONSOLE.
stub <default-metric metric>;Encloses optional keywords or
broadcast | multicast
(string1 | string2 | string3)
# (pound sign)
[ ] (square brackets)
Indention and braces ( { } )
; (semicolon)
GUI Conventions
Indicates a comment specified on the same line as the configuration statement to which it applies.
Encloses a variable for which you can substitute one or more values.
Identifies a level in the configuration hierarchy.
Identifies a leaf statement at a configuration hierarchy level.
rsvp { # Required for dynamic MPLS only
community name members [ community-ids ]
[edit] routing-options {
static {
route default {
nexthop address; retain;
}
}
}
Table 2: Text and Syntax Conventions (continued)
xiii
ExamplesDescriptionConvention
Bold text like this
> (bold right angle bracket)
Represents graphical user interface (GUI) items you click or select.
Separates levels in a hierarchy of menu selections.
In the Logical Interfaces box, select
All Interfaces.
To cancel the configuration, click
Cancel.
In the configuration editor hierarchy, select Protocols>Ospf.

Documentation Feedback

We encourage you to provide feedback so that we can improve our documentation. You can use either of the following methods:
Online feedback system—Click TechLibrary Feedback, on the lower right of any page on the Juniper
Networks TechLibrary site, and do one of the following:
Click the thumbs-up icon if the information on the page was helpful to you.
Click the thumbs-down icon if the information on the page was not helpful to you or if you have
suggestions for improvement, and use the pop-up form to provide feedback.
E-mail—Send your comments to techpubs-comments@juniper.net. Include the document or topic name,
URL or page number, and software version (if applicable).

Requesting Technical Support

Technical product support is available through the Juniper Networks Technical Assistance Center (JTAC). If you are a customer with an active Juniper Care or Partner Support Services support contract, or are
covered under warranty, and need post-sales technical support, you can access our tools and resources online or open a case with JTAC.
JTAC policies—For a complete understanding of our JTAC procedures and policies, review the JTAC User
Guide located at https://www.juniper.net/us/en/local/pdf/resource-guides/7100059-en.pdf.
Product warranties—For product warranty information, visit https://www.juniper.net/support/warranty/.
JTAC hours of operation—The JTAC centers have resources available 24 hours a day, 7 days a week,
365 days a year.

Self-Help Online Tools and Resources

For quick and easy problem resolution, Juniper Networks has designed an online self-service portal called the Customer Support Center (CSC) that provides you with the following features:
Find CSC offerings: https://www.juniper.net/customers/support/
Search for known bugs: https://prsearch.juniper.net/
xiv
Find product documentation: https://www.juniper.net/documentation/
Find solutions and answer questions using our Knowledge Base: https://kb.juniper.net/
Download the latest versions of software and review release notes:
https://www.juniper.net/customers/csc/software/
Search technical bulletins for relevant hardware and software notifications:
https://kb.juniper.net/InfoCenter/
Join and participate in the Juniper Networks Community Forum:
https://www.juniper.net/company/communities/
Create a service request online: https://myjuniper.juniper.net
To verify service entitlement by product serial number, use our Serial Number Entitlement (SNE) Tool:
https://entitlementsearch.juniper.net/entitlementsearch/

Creating a Service Request with JTAC

You can create a service request with JTAC on the Web or by telephone.
Visit https://myjuniper.juniper.net.
Call 1-888-314-JTAC (1-888-314-5822 toll-free in the USA, Canada, and Mexico).
For international or direct-dial options in countries without toll-free numbers, see
https://support.juniper.net/support/requesting-support/.
1
CHAPTER

Disclaimer

Junos PyEZ Disclaimer | 16

Junos PyEZ Disclaimer

Use of the Junos PyEZ software implies acceptance of the terms of this disclaimer, in addition to any other licenses and terms required by Juniper Networks.
Juniper Networks is willing to make the Junos PyEZ software available to you only on the condition that you accept all of the terms contained in this disclaimer. Please read the terms and conditions of this disclaimer carefully.
The Junos PyEZ software is provided as is. Juniper Networks makes no warranties of any kind whatsoever with respect to this software. All express or implied conditions, representations and warranties, including any warranty of non-infringement or warranty of merchantability or fitness for a particular purpose, are hereby disclaimed and excluded to the extent allowed by applicable law.
In no event will Juniper Networks be liable for any direct or indirect damages, including but not limited to lost revenue, profit or data, or for direct, special, indirect, consequential, incidental or punitive damages however caused and regardless of the theory of liability arising out of the use of or inability to use the software, even if Juniper Networks has been advised of the possibility of such damages.
16
2
CHAPTER

Junos PyEZ Overview

Understanding Junos PyEZ | 18
Junos PyEZ Modules Overview | 21

Understanding Junos PyEZ

IN THIS SECTION
Junos PyEZ Overview | 18
Benefits of Junos PyEZ | 19
Using Junos PyEZ in Automation Scripts | 19
Junos PyEZ Resources | 20

Junos PyEZ Overview

18
Junos PyEZ is a microframework for Python that enables you to manage and automate devices running the Junos operating system (Junos OS). Junos PyEZ is designed to provide the capabilities that a user would have on the Junos OS command-line interface (CLI) in an environment built for automation tasks. Junos PyEZ does not require extensive knowledge of Junos OS or the Junos XML APIs.
Junos PyEZ enables you to manage devices running Junos OS using the familiarity of Python. However, you do not have to be an experienced programmer to use Junos PyEZ. Non-programmers can quickly execute simple commands in Python interactive mode, and more experienced programmers can opt to create more complex, robust, and reusable programs to perform tasks.
Junos PyEZ enables you to directly connect to a device using a serial console connection, telnet, or a NETCONF session over SSH. In addition, Junos PyEZ also supports connecting to the device through a telnet or SSH connection to a console server that is connected to the device’s CONSOLE port. You can use Junos PyEZ to initially configure a new or zeroized device that is not yet configured for remote access by using either a serial console connection when you are directly connected to the device or by using telnet or SSH through a console server that is directly connected to the device.
Junos PyEZ provides device, software, and file system utilities that enable you to perform common operational tasks on devices running Junos OS. You can use Junos PyEZ to:
Retrieve facts or operational information from a device
Execute remote procedure calls (RPC) available through the Junos XML API
Install or upgrade the Junos OS software
Reboot or shut down the device
Perform common administrative tasks such as copying files and calculating checksums
Junos PyEZ also enables you to manage the configurations of devices running Junos OS. Junos PyEZ configuration management utilities enable you to:
retrieve configuration data
compare configurations
upload and commit configuration changes
roll back the configuration
manage the rescue configuration
Junos PyEZ supports standard formats for configuration data including ASCII text, Junos XML elements, Junos OS set commands, and JavaScript Object Notation (JSON), and also supports using Jinja2 templates and template files for added flexibility and customization. In addition, you can use Tables and Views to define structured resources that you can use to programmatically configure a device.
Junos PyEZ Tables and Views enable you to both configure devices running Junos OS and extract specific operational information or configuration data from the devices. You define Tables and Views using simple YAML files that contain key:value pair mappings, so no complex coding is required to use them. You can use Tables and Views to retrieve the device configuration or the output for any Junos OS command or RPC and then extract a customized subset of information. This is useful when you need to retrieve information from a few specific fields that are embedded in extensive command output such as for the show route or show interfaces command. In addition, starting in Junos PyEZ Release 2.0, you can use Tables and Views to define structured configuration resources. Junos PyEZ dynamically creates a configuration class for the resource, which enables you to programmatically configure the resource on a device.
19

Benefits of Junos PyEZ

Provides an abstraction layer that enables Python programmers as well as non-programmers to easily
manage and automate devices running Junos OS
Increases operational efficiency by enabling operators to automate common tasks thereby reducing the
manual configuration and management of devices
Minimizes errors and risks by enabling structured configuration changes of targeted resources

Using Junos PyEZ in Automation Scripts

Junos OS includes the Python extensions package and the Junos PyEZ library in the software image for certain supported devices. These extensions enable you to create on-box Python scripts that use Junos
PyEZ to execute RPCs and perform operational and configuration tasks on devices running Junos OS. Junos PyEZ is supported in commit, event, op, and SNMP scripts; Juniper Extension Toolkit (JET) scripts; and YANG action and translation scripts.
Table 3 on page 20 summarizes the Junos PyEZ version that is available on supported devices running the
given Junos OS release. For example, starting in Junos OS Release 17.4R1, an on-box Python script can leverage features in Junos PyEZ Release 2.1.4 and earlier releases.
Table 3: Junos PyEZ Version on Supported Devices Running Junos OS
Junos PyEZ VersionJunos OS Release
1.3.116.1R3 through 17.3
2.1.417.4R1 through 19.3
2.2.019.4R1 and later
For more information about creating onbox Python automation scripts, see Understanding Python
Automation Scripts for Devices Running Junos OS in the Junos OS Automation Scripting User Guide.
20

Junos PyEZ Resources

Juniper Networks provides a number of Junos PyEZ resources, which are described in Table 4 on page 20.
Table 4: Junos PyEZ Resources
URLDescriptionResource
API Reference
Day One: Junos PyEZ Cookbook and script repository
Documentation
modules.
Junos PyEZ network automation cookbook with a setup guide, a start-up sandbox, and a complete showcase of automation scripts that are available on GitHub.
Junos PyEZ documentation containing detailed information about installing Junos PyEZ and using Junos PyEZ to perform operational and configuration tasks on devices running Junos OS.
http://junos-pyez.readthedocs.org/Detailed documentation for the Junos PyEZ
https://www.juniper.net/ documentation/en_US/day-one-books/ DO_PyEZ_Cookbook.pdf
https://github.com/Juniper/ junosautomation/tree/master/pyez/ PyEZ_Cookbook_2017
https://www.juniper.net/ documentation/product/en_US/ junos-pyez
Table 4: Junos PyEZ Resources (continued)
21
URLDescriptionResource
GitHub repository
Google Groups forum
Stack Overflow forum
Techwiki page
Public repository for the Junos PyEZ project. This repository includes the most current source code, installation instructions, and release note summaries for all releases.
Forum that addresses questions and provides general support for Junos PyEZ.
Junos PyEZ sample scripts to get you started.Sample scripts
Forum that addresses questions and provides general support for Junos PyEZ.
Juniper Networks J-Net community forum containing additional how-to articles and usage examples.
RELATED DOCUMENTATION
https://github.com/Juniper/ py-junos-eznc/
http://groups.google.com/group/ junos-python-ez
https://github.com/Juniper/ junosautomation/tree/master/pyez
https://stackoverflow.com/questions/ tagged/pyez
https://forums.juniper.net/t5/ Automation-Scripting/Junos-PyEZ/ta-p/ 280496
Junos PyEZ Modules Overview | 21
Installing Junos PyEZ | 25
Connecting to Devices Running Junos OS Using Junos PyEZ | 36
Using Junos PyEZ to Configure Devices Running Junos OS | 126

Junos PyEZ Modules Overview

Junos PyEZ is a microframework for Python that enables you to manage and automate devices running Junos OS. Junos PyEZ consists of the jnpr.junos package, which contains modules that handle device connectivity and provide operational and configuration utilities.
Table 5 on page 22 outlines the primary Junos PyEZ modules that are used to manage devices running
Junos OS. For detailed information about each module, see the Junos PyEZ API Reference at
http://junos-pyez.readthedocs.org/.
Table 5: Junos PyEZ Modules
Descriptionjnpr.junos Modules
22
device
command
exception
factory
facts
op
resources
Defines the Device class, which represents the device running Junos OS and enables you to connect to and retrieve facts from the device.
Includes predefined operational Tables and Views that can be used to filter unstructured output returned from CLI and vty commands and convert it to JSON.
Defines exceptions encountered when accessing, configuring, and managing devices running Junos OS.
Contains code pertaining to Tables and Views, including the loadyaml() function, which is used to load custom Tables and Views.
A dictionary-like object of read-only facts about the device. These facts are accessed using the facts attribute of a Device object instance.
Includes predefined operational Tables and Views that can be used to filter structured output returned from RPCs.
Includes predefined configuration Tables and Views representing specific configuration resources, which can be used to programmatically configure devices running Junos OS.
Contains code used by the Device class to support the different connection types.transport
utils
Includes configuration utilities, file system utilities, shell utilities, software installation utilities, and secure copy utilities.
In Junos PyEZ, each device is modeled as an instance of the jnpr.junos.device.Device class. The device module provides access to devices running Junos OS through a serial console connection, telnet, or SSH and also supports connecting to the device through a telnet or SSH connection to a console server that is connected to the device’s CONSOLE port. All connection methods support retrieving device facts, performing operations, and executing RPCs on demand. Support for serial console connections and for telnet and SSH connections through a console server enables you to connect to and initially configure new or zeroized devices that are not yet configured for remote access. Facts about the device are accessed using the facts attribute of the Device object instance.
The utils module defines submodules and classes that handle software installation, file system and copy operations, and configuration management. The exception module defines exceptions encountered when managing devices running Junos OS.
The command, op, resources, and factory modules pertain to Tables and Views. The command and op modules contain predefined operational Tables and Views that can be used to extract specific information
from the output of common operational commands and RPCs on devices running Junos OS. The resources module contains predefined configuration Tables and Views that can be used to configure specific resources on devices running Junos OS. The factory module contains methods that enable you to load your own custom Tables and Views in Junos PyEZ applications.
RELATED DOCUMENTATION
Understanding Junos PyEZ | 18
Understanding Junos PyEZ Tables and Views | 185
Using Junos PyEZ to Retrieve Facts from Devices Running Junos OS | 60
23
3
CHAPTER

Installing Junos PyEZ

Installing Junos PyEZ | 25
Setting Up Junos PyEZ Managed Nodes | 31

Installing Junos PyEZ

Junos PyEZ is a Python library that enables you to manage and automate devices running Junos OS. You can install Junos PyEZ on a UNIX-like operating system or on Windows. You have the option to install and run Junos PyEZ directly on the configuration management server, within a Python virtual environment, or as a Docker container.
As an alternative to installing Junos PyEZ directly on the server, you can install it in a virtual environment. A Python virtual environment isolates a project’s Python installation and packages from those installed on the system or in other virtual environments, which prevents breaking the dependencies of other projects. You can create virtual environments when you have projects that require different versions of Python or Python packages or as an alternative to installing packages globally on the system.
Juniper Networks also provides a Junos PyEZ Docker image that enables you to run Junos PyEZ as a Docker container. The Docker container is a lightweight, self-contained system that bundles Junos PyEZ, its dependencies, and Python into a single portable container. The Docker image enables you to quickly run Junos PyEZ in interactive mode, as an executable package, or as a terminal on any platform that supports Docker.
25
To install Junos PyEZ on the configuration management server, see the following sections:
Installing Prerequisite Software on page 25
Installing Junos PyEZ on the Configuration Management Server on page 27
To install Junos PyEZ in a Python virtual environment, see the following sections:
Installing Prerequisite Software on page 25
Installing Junos PyEZ in a Python Virtual Environment on page 28
To use the Junos PyEZ Docker image, see the following section:
Using the Junos PyEZ Docker Image on page 29

Installing Prerequisite Software

Before you install the Junos PyEZ library on the configuration management server or in a virtual environment, ensure that the configuration management server has the following software installed:
Python 2.7, or Python 3.5 or later
All prerequisite software for the given operating system, which is outlined in Table 6 on page 26
NOTE: Python 3.x is only supported in Junos PyEZ Release 2.0 and later releases.
Table 6: Junos PyEZ Prerequisite Software
Package or LibraryOperating System
26
CentOS
Debian
Fedora
gcc
libffi-devel
libxml2-devel
libxslt-devel
openssl-devel
pip
python-devel
redhat-rpm-config
libxml2-dev
libxslt1-dev
libssl-dev
pip
python-devel (required for Python 2)
python3-devel (required for Python 3)
gcc
libffi-devel
libxml2-devel
libxslt-devel
openssl-devel
pip
python-devel (required for Python 2)
python3-devel (required for Python 3)
redhat-rpm-config
FreeBSD
libxml2
libxslt
py27-pip
Table 6: Junos PyEZ Prerequisite Software (continued)
Package or LibraryOperating System
27
OSX
NOTE: If Junos PyEZ does not
successfully install using pip, try using easy_install to install the lxml library and
then Junos PyEZ.
Ubuntu
Windows
pip
xcode
libffi-dev
libssl-dev
libxml2-dev
libxslt1-dev
python-dev (required for Python 2)
python3-dev (required for Python 3)
pip
ecdsa
pip
pycrypto

Installing Junos PyEZ on the Configuration Management Server

After you install the prerequisite software on the configuration management server, you can install the
latest release of Junos PyEZ from the Python Package Index (PyPI). You can also download the latest
version of the code from the Junos PyEZ GitHub repository. To install Junos PyEZ from GitHub, you must have Git installed on the configuration management server.
To install the current release of Junos PyEZ from PyPI, execute the following command (use sudo pip
where appropriate):
user@server:~$ sudo pip install junos-eznc
NOTE: To upgrade an existing version of Junos PyEZ, include the -U or --upgrade option when
executing the pip install command.
To install Junos PyEZ from the GitHub project master branch, execute the following command (use sudo
pip where appropriate):
user@server:~$ sudo pip install git+https://github.com/Juniper/py-junos-eznc.git
NOTE: The latest code in the GitHub source repository is under active development and might
not be stable.
NOTE: The pip command name might vary depending on your operating system and version of
Python. Before installing Junos PyEZ using pip, use the pip -V command to display the version, and verify that the pip command corresponds to the version of Python that you are using for Junos PyEZ on your system. If the version is not the same as the Python version used for Junos PyEZ, then try using the pip2 or pip3 commands instead of pip.
For additional information about installing Junos PyEZ, including additional installation options, see the INSTALL file for your specific operating system in the Junos PyEZ GitHub repository at
https://github.com/Juniper/py-junos-eznc.
28

Installing Junos PyEZ in a Python Virtual Environment

As an alternative to installing Python packages globally on a system, you can install the required packages and dependencies for a specific project in an isolated Python virtual environment. After you install the prerequisite software on the configuration management server, you can create a Python virtual environment for your Junos PyEZ project.
For example, to create a virtual Python 3 installation with Junos PyEZ on a Linux or macOS server:
1. Move into your existing project directory or create a new one, if none exists.
user@host:~$ mkdir junos-pyez user@host:~$ cd junos-pyez
2. Create a virtual Python installation and specify its name, which in this case is venv.
user@host:~/junos-pyez$ python3 -m venv venv
NOTE: Ubuntu and Debian systems might require you to install the python3-venv package
before you can create the virtual environment.
3. Activate the virtual environment by executing the script in the virtual environment’s bin directory that
is appropriate for your platform and shell.
user@host:~/junos-pyez$ source venv/bin/activate
(venv) user@host:~/junos-pyez$
4. Install Junos PyEZ.
To install the current release of Junos PyEZ from PyPI, execute the following command:
(venv) user@host:~/junos-pyez$ pip install junos-eznc
To install Junos PyEZ from the GitHub project master branch, execute the following command, which
requires that Git is installed:
(venv) user@host:~/junos-pyez$ pip install git+https://github.com/Juniper/py-junos-eznc.git
29
NOTE: The latest code in the GitHub source repository is under active development and
might not be stable.
5. Execute your Junos PyEZ commands or scripts within the virtual environment.
6. When you are finished working in the virtual environment, deactivate it to return to the main shell prompt.
(venv) user@host:~/junos-pyez$ deactivate user@host:~/junos-pyez$
NOTE: For Python 2 virtual environments, use the virtualenv tool.

Using the Junos PyEZ Docker Image

Docker is a software container platform that is used to package and run an application and its dependencies in an isolated container. Juniper Networks provides a Junos PyEZ Dockerfile as well as Junos PyEZ Docker
images, which are automatically built for every Junos PyEZ release. Starting in Junos PyEZ Release 2.1.8,
the Docker images include Python 3.6. In earlier release, the images include Python 2.7.x.
You can customize and use the Dockerfile to build your own Junos PyEZ Docker image, or you can use one of the prebuilt Docker images, which are stored on Docker Hub, to run Junos PyEZ as a Docker container. You can run the container in interactive mode, as an executable package, or as a terminal.
To use a prebuilt Junos PyEZ Docker image on your configuration management server:
1. Install Docker.
See the Docker website at https://www.docker.com for instructions on installing and configuring Docker on your specific operating system.
2. Download the juniper/pyez Docker image from Docker Hub.
To download the latest image, issue the following command:
user@server:~$ docker pull juniper/pyez
NOTE: The latest Junos PyEZ Docker image is built using the most recently committed
code in the Junos PyEZ source repository, which is under active development and might not be stable.
30
To download a specific image, append the appropriate release tag to the image name, for example,
2.1.2.
user@server:~$ docker pull juniper/pyez:tag
3. Move to the local directory that contains your scripts.
When you run the Docker container, the local scripts are mounted to /scripts in the container.
4. Run the container.
For instructions on running the container, see the official usage examples at DOCKER-EXAMPLES.md.
RELATED DOCUMENTATION
Setting Up Junos PyEZ Managed Nodes | 31
Understanding Junos PyEZ | 18
Junos PyEZ Modules Overview | 21
Authenticating Junos PyEZ Users | 52
Using Junos PyEZ to Retrieve Facts from Devices Running Junos OS | 60

Setting Up Junos PyEZ Managed Nodes

IN THIS SECTION
Enabling NETCONF over SSH on Devices Running Junos OS | 32
Satisfying Requirements for SSHv2 Connections | 32
Configuring Telnet Service on Devices Running Junos OS | 33
31
Junos PyEZ is a Python library that enables you to manage and automate devices running Junos OS. You do not need to install any client software on the nodes in order to use Junos PyEZ to manage the devices. Also, Python is not required on the managed devices, because Junos PyEZ utilizes NETCONF and the Junos XML APIs.
You can use Junos PyEZ to manage devices running Junos OS using any user account that has access to the device. You can explicitly define the user when creating a new instance of the jnpr.junos.device.Device class, or if you do not specify a user in the parameter list, the user defaults to $USER. When you use Junos PyEZ to access and manage devices running Junos OS, Junos OS user account access privileges are enforced. The class configured for the Junos OS user account determines the permissions. Thus, if you use Junos PyEZ to load configuration changes onto a device, the user must have permissions to change the relevant portions of the configuration.
Junos PyEZ enables you to connect directly to a device running Junos OS using a serial console connection, telnet, or a NETCONF session over SSH. To telnet directly to a device, you must first configure the Telnet service on the managed device. To manage devices through a NETCONF session over SSH, you must enable the SSH or NETCONF-over-SSH service on the managed device and ensure that the device meets requirements for SSHv2 connections. You do not need to configure these services if the client application connects to the device through a separate console server.
This topic outlines the requirements and required configuration on devices running Junos OS when using Junos PyEZ to access the device using the different connection protocols.

Enabling NETCONF over SSH on Devices Running Junos OS

To enable the NETCONF-over-SSH service on the default port (830) on a device running Junos OS:
1. Configure the NETCONF-over-SSH service.
[edit system services] user@host# set netconf ssh
NOTE: It is also possible to reach the NETCONF-over-SSH service on TCP port 22 by
configuring the ssh statement at the [edit system services] hierarchy level, which enables SSH access to the device for all users and applications. However, we recommend configuring the netconf ssh statement to more easily identify and filter NETCONF traffic.
32
2. Commit the configuration.
[edit] user@host# commit

Satisfying Requirements for SSHv2 Connections

The NETCONF server communicates with client applications within the context of a NETCONF session. The server and client explicitly establish a connection and session before exchanging data, and close the session and connection when they are finished. Junos PyEZ accesses the NETCONF server using the SSH protocol and standard SSH authentication mechanisms. When you use Junos PyEZ to manage devices running Junos OS, the most convenient way to access the devices is to configure SSH keys.
To establish an SSHv2 connection with a device running Junos OS, you must ensure that the following requirements are met:
The NETCONF service over SSH is enabled on each device where a NETCONF session will be established.
The client application has a user account and can log in to each device where a NETCONF session will
be established.
The login account used by the client application has an SSH public/private key pair or a text-based
password configured.
The client application can access the public/private keys or text-based password.
For additional information about enabling NETCONF on a device running Junos OS and satisfying the requirements for establishing an SSH session, see the NETCONF XML Management Protocol Developer
Guide.

Configuring Telnet Service on Devices Running Junos OS

Starting in Junos PyEZ Release 2.0, Junos PyEZ applications can telnet to a device running Junos OS, provided that the Telnet service is configured on the device. Configuring Telnet service for a device enables unencrypted, remote access to the device.
NOTE: Because telnet uses clear-text passwords (therefore creating a potential security
vulnerability), we recommend that you use SSH.
33
To enable Telnet service:
1. Configure the service.
[edit system services] user@host# set telnet
2. (Optional) Configure the connection limit, rate limit, and order of authentication, as necessary.
[edit system services] user@host# set telnet connection-limit connection-limit user@host# set telnet rate-limit rate-limit user@host# set telnet authentication-order [radius tacplus password]
3. Commit the configuration.
[edit] user@host# commit
RELATED DOCUMENTATION
Installing Junos PyEZ | 25
Understanding Junos PyEZ | 18
Junos PyEZ Modules Overview | 21
Authenticating Junos PyEZ Users | 52
Using Junos PyEZ to Retrieve Facts from Devices Running Junos OS | 60
34
4
CHAPTER
Connecting to and Retrieving Facts
From a Device Using Junos PyEZ
Connecting to Devices Running Junos OS Using Junos PyEZ | 36
Authenticating Junos PyEZ Users | 52
Using Junos PyEZ to Retrieve Facts from Devices Running Junos OS | 60
Accessing the Shell on Devices Running Junos OS Using Junos PyEZ | 66

Connecting to Devices Running Junos OS Using Junos PyEZ

IN THIS SECTION
Connection Methods Overview | 36
Understanding Junos PyEZ Connection Properties | 38
Connecting to a Device Using SSH | 39
Connecting to a Device Using Outbound SSH | 43
Connecting to a Device Using Telnet | 47
Connecting to a Device Using a Serial Console Connection | 49
36
Junos PyEZ is a microframework for Python that enables you to manage devices running Junos OS. Junos PyEZ models each device as an instance of the jnpr.junos.device.Device class. The Device class enables you to connect to a device running Junos OS using a serial console connection, telnet, or by establishing a NETCONF session over SSH. In addition, Junos PyEZ also supports connecting to the device through a telnet or SSH connection to a console server. A console server, also known as a terminal server, is a specialized device that provides a network connection to a device’s out-of-band management console port.
This topic provides an overview of the connection methods supported by Junos PyEZ and explains how to use the different methods to connect to a device running Junos OS. The Junos PyEZ examples use various authentication methods, but for detailed information about authenticating a user, see “Authenticating
Junos PyEZ Users” on page 52.

Connection Methods Overview

Junos PyEZ enables you to connect to devices running Junos OS using a serial console connection, telnet, or a NETCONF session over SSH. You must use a serial console connection when you are physically connected to the CONSOLE port on a device. You can use telnet or SSH to connect to the device’s management interface or to a console server that is connected to the device’s CONSOLE port. In addition, Junos PyEZ supports outbound SSH connections, in which the device running Junos OS initiates the connection with the client management application.
New or zeroized devices that have factory default configurations require access through a console connection. Thus, you can use Junos PyEZ to initially configure a device that is not yet configured for remote access by using either a serial console connection when you are directly connected to the device or by using telnet or SSH through a console server that is connected to the device.
By default, Junos PyEZ uses SSH to connect to a device . To specify a different connection type, you must include the mode parameter in the Device argument list. To telnet to a device, include the mode='telnet' argument. To connect to a device using a serial console connection, include the mode='serial' argument.
Table 7 on page 37 summarizes the Junos PyEZ connection methods, their default values for certain
parameters, any required Junos OS configuration, and the Junos PyEZ release in which support for that connection method was first introduced.
Table 7: Junos PyEZ Connection Modes
37
OS
Value of
mode
ArgumentConnection Mode
First Supported Required Junos OS ConfigurationDefault Port
830NETCONF over SSH (default)
netconf {
ssh;
}
23telnetTelnet to device running Junos
telnet;
Outbound SSH
outbound-ssh {
...
}
Junos PyEZ
Release
1.0.0[edit system services]
2.0.0/dev/ttyUSB0serialSerial console connection
2.0.0[edit system services]
2.0.023telnetTelnet through a console server
2.2.022SSH through a console server
2.2.0[edit system services]
NOTE: Before you can access a device’s management interface using telnet or NETCONF over
SSH, you must first enable the appropriate service at the [edit system services] hierarchy. For more information, see “Setting Up Junos PyEZ Managed Nodes” on page 31. Because telnet uses clear-text passwords (therefore creating a potential security vulnerability), we recommend that you use SSH.
NOTE: It is the user's responsibility to obtain the username and password authentication
credentials in a secure manner appropriate for their environment. It is best practice to prompt for these authentication credentials during each invocation of the script, rather than storing the credentials in an unencrypted format.
Junos PyEZ supports using context managers (with ... as syntax) for all connection methods. When you use a context manager, Junos PyEZ automatically calls the open() and close() methods to connect to and disconnect from the device. If you do not use a context manager, you must explicitly call the open() and close() methods in your application. We recommend that you use a context manager for console connections, because the context manager automatically handles closing the connection, and failure to close the connection can lead to unpredictable results.

Understanding Junos PyEZ Connection Properties

38
When you connect to a device running Junos OS, Junos PyEZ stores information about the current connection as properties of the Device instance. Table 8 on page 38 outlines the available connection properties.
Table 8: Device Properties
DescriptionProperty
Boolean specifying the current state of the connection. Returns True when connected.connected
String specifying the hostname of the device to which the application is connected.hostname
master
Boolean returning True if the Routing Engine to which the application is connected is the primary Routing Engine.
Integer or string specifying the port used for the connection.port
String specifying the Routing Engine name to which the application is connected.re_name
Integer specifying the RPC timeout value in seconds.timeout
uptime
Integer representing the number of seconds since the current Routing Engine was booted. This property is available starting in Junos PyEZ Release 2.1.5.
String specifying the user accessing the device running Junos OS.user
For example, after connecting to a device, you can query the connected property to return the current state of the connection. A SessionListener monitors the session and responds to transport errors by raising a TransportError exception and setting the Device.connected property to False.
The following sample code prints the value of the connected property after connecting to a device running Junos OS and again after closing the session.
from jnpr.junos import Device
dev = Device(host='router.example.net')
dev.open()
print (dev.connected)
dev.close()
print (dev.connected)
39
When you execute the program, the connected property returns True while the application is connected to the device and returns False after the connection is closed.
user@host:~$ python connect.py
True False

Connecting to a Device Using SSH

The Junos PyEZ Device class supports using SSH to connect to a device running Junos OS. You can establish a NETCONF session over SSH with the device’s management interface or you can establish an SSH connection with a console server that is directly connected to the device’s CONSOLE port. The SSH server must be able to authenticate the user using standard SSH authentication mechanisms, as described in
“Authenticating Junos PyEZ Users” on page 52. To establish a NETCONF session over SSH, you must also
satisfy the requirements outlined in “Setting Up Junos PyEZ Managed Nodes” on page 31.
Junos PyEZ automatically queries the default SSH configuration file at ~/.ssh/config, if one exists. When using SSH to connect to a device running Junos OS or to a console server connected to the device, Junos PyEZ first attempts SSH public key-based authentication and then tries password-based authentication. When SSH keys are in use, the supplied password is used as the passphrase for unlocking the private key. When password-based authentication is used, the supplied password is used as the device password. If
SSH public key-based authentication is being used and the SSH private key has an empty passphrase, then a password is not required. However, SSH private keys with empty passphrases are not recommended.
To establish a NETCONF session over SSH with a device running Junos OS and print the device facts in a Junos PyEZ application using Python 3:
1. Import the Device class and any other modules or objects required for your tasks.
import sys from getpass import getpass from jnpr.junos import Device from jnpr.junos.exception import ConnectError
2. Create the device instance, and provide the hostname, any parameters required for authentication, and any optional parameters.
hostname = input("Device hostname: ") junos_username = input("Junos OS username: ") junos_password = getpass("Junos OS or SSH key password: ")
40
dev = Device(host=hostname, user=junos_username, passwd=junos_password)
3. Connect to the device by calling the open() method, for example:
try:
dev.open()
except ConnectError as err:
print ("Cannot connect to device: {0}".format(err))
sys.exit(1)
except Exception as err:
print (err)
sys.exit(1)
4. Print the device facts.
print (dev.facts)
5. After performing any necessary tasks, close the connection to the device.
dev.close()
The sample program in its entirety is presented here:
import sys from getpass import getpass from jnpr.junos import Device from jnpr.junos.exception import ConnectError
hostname = input("Device hostname: ") junos_username = input("Junos OS username: ") junos_password = getpass("Junos OS or SSH key password: ")
dev = Device(host=hostname, user=junos_username, passwd=junos_password)
try:
dev.open()
except ConnectError as err:
print ("Cannot connect to device: {0}".format(err))
sys.exit(1)
except Exception as err:
print (err)
sys.exit(1)
41
print (dev.facts)
dev.close()
Alternatively, you can use a context manager when connecting to the device, which automatically calls the open() and close() methods. For example:
import sys from getpass import getpass from jnpr.junos import Device from jnpr.junos.exception import ConnectError
hostname = input("Device hostname: ") junos_username = input("Junos OS username: ") junos_password = getpass("Junos OS or SSH key password: ")
try:
with Device(host=hostname, user=junos_username, passwd=junos_password) as dev:
print (dev.facts)
except ConnectError as err:
print ("Cannot connect to device: {0}".format(err))
sys.exit(1)
except Exception as err:
print (err)
sys.exit(1)
Junos PyEZ also enables a client to connect to a device running Junos OS through an SSH connection to a console server. In this case, you must specify the login credentials for the console server by including the cs_user and cs_passwd arguments in the Device argument list. When SSH keys are in use, set the cs_passwd argument to the variable containing the passphrase for the private key.
The console server connects to the device running Junos OS through a serial connection, which can be slow. Junos PyEZ connections through a console server have a default connection timeout value of 0.5 seconds. As a result, you might need to increase the connection timeout interval by including the Device timeout=seconds argument to allow sufficient time for the client application to establish the connection.
The following Python 3 example authenticates with the console server and then the device running Junos OS. The connection timeout is set to six seconds so that the client has sufficient time to establish the connection.
42
import sys from getpass import getpass from jnpr.junos import Device from jnpr.junos.exception import ConnectError
hostname = input("Console server hostname: ") cs_username = input("Console server username: ") cs_password = getpass("Console server or SSH key password: ") junos_username = input("Junos OS username: ") junos_password = getpass("Junos OS password: ")
try:
with Device(host=hostname, user=junos_username, passwd=junos_password,
cs_user=cs_username, cs_passwd=cs_password, timeout=6) as dev:
print (dev.facts)
except ConnectError as err:
print ("Cannot connect to device: {0}".format(err))
sys.exit(1)
except Exception as err:
print (err)
sys.exit(1)
Junos PyEZ automatically queries the default SSH configuration file at ~/.ssh/config, if one exists. However, starting with Junos PyEZ Release 1.2, you can specify a different SSH configuration file when you create the device instance by including the ssh_config parameter in the Device argument list. For example:
ssh_config_file = "~/.ssh/config_dc" dev = Device(host='198.51.100.1', ssh_config=ssh_config_file)
Also, starting in Junos PyEZ Release 1.2, Junos PyEZ provides support for ProxyCommand, which enables you to access a target device through an intermediary host that supports netcat. This is useful when you can only log in to the target device through the intermediate host.
To configure ProxyCommand, add the appropriate information to the SSH configuration file. For example:
[user1@server ~]$ cat ~/.ssh/config Host 198.51.100.1 User user1 ProxyCommand ssh -l user1 198.51.100.2 nc %h 22 2>/dev/null
43

Connecting to a Device Using Outbound SSH

You can configure a device running Junos OS to initiate a TCP/IP connection with a client management application that would be blocked if the client attempted to initiate the connection (for example, if the device is behind a firewall). The outbound-ssh configuration instructs the device to create a TCP/IP connection with the client management application and to forward the identity of the device. Once the connection is established, the management application acts as the client and initiates the SSH sequence, and the device acts as the server and authenticates the client.
NOTE: There is no initiation command with outbound SSH. Once outbound SSH is configured
and committed, the device begins to initiate an outbound SSH connection based on the committed configuration. The device repeatedly attempts to create this connection until successful. If the connection between the device and the client management application is dropped, the device again attempts to create a new outbound SSH connection until successful. This connection is maintained until the outbound SSH stanza is removed from the configuration.
To configure the device running Junos OS for outbound SSH connections, include the outbound-ssh statement at the [edit system services] hierarchy level. In the following example, the device running Junos OS attempts to initiate a connection with the host at 198.51.100.101 on port 2200:
user@router1> show configuration system services outbound-ssh
client outbound-ssh { device-id router1; secret "$9$h1/ceWbs4UDkGD/Cpu1I-Vb"; ## SECRET-DATA services netconf;
198.51.100.101 port 2200; }
To establish a connection with the device running Junos OS using outbound SSH, the Junos PyEZ application sets the sock_fd argument in the Device constructor equal to the file descriptor of an existing socket and either omits the host argument or sets it to None.
44
The following Junos PyEZ example listens on the configured TCP port for incoming SSH sessions from devices running Junos OS. The application accepts an incoming connection and retrieves the socket’s file descriptor for that connection, which is used for the value of the sock_fd argument. The client application establishes the SSH connection with the device, collects and prints the device facts, disconnects from the device, and waits for more connections.
import socket from jnpr.junos import Device from jnpr.junos.exception import ConnectError from getpass import getpass from pprint import pprint
"""
Listen on TCP port 2200 for incoming SSH session with a device running Junos OS.
Upon connecting, collect and print the devices facts, then disconnect from that device and wait for more connections.
"""
def launch_junos_proxy(client, addr):
val = {
'MSG-ID': None, 'MSG-VER': None, 'DEVICE-ID': None
}
msg = ''
count = 3
while len(msg) < 100 and count > 0:
c = client.recv(1)
if c == '\r':
continue
if c == '\n':
count -= 1
if msg.find(':'):
(key, value) = msg.split(': ') val[key] = value msg = ''
else:
msg += str(c)
print('MSG %s %s %s' %
(val['MSG-ID'], val['MSG-VER'], val['DEVICE-ID']))
45
return client.fileno()
def main():
PORT = 2200
junos_username = input('Junos OS username: ') junos_password = getpass('Junos OS password: ')
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', PORT)) s.listen(5)
print('\nListening on port %d for incoming sessions ...' % (PORT))
sock_fd = 0
while True:
client, addr = s.accept()
print('\nGot a connection from %s:%d' % (addr[0], addr[1]))
sock_fd = launch_junos_proxy(client, addr)
print('Logging in ...') try:
with Device(host=None, sock_fd=sock_fd, user=junos_username,
passwd=junos_password) as dev:
pprint(dev.facts)
except ConnectError as err:
print ("Cannot connect to device: {0}".format(err))
if __name__ == "__main__":
main()
user@server:~$ python3 junos-pyez-outbound-ssh.py
Junos OS username: user Junos OS password:
Listening on port 2200 for incoming sessions ...
Got a connection from 10.10.0.5:57881 MSG DEVICE-CONN-INFO V1 router1 Logging in ... {'2RE': True, 'HOME': '/var/home/user', 'RE0': {'last_reboot_reason': 'Router rebooted after a normal shutdown.', 'mastership_state': 'master', 'model': 'RE-MX-104', 'status': 'OK', 'up_time': '2 days, 6 hours, 22 minutes, 22 seconds'}, 'RE1': {'last_reboot_reason': 'Router rebooted after a normal shutdown.', 'mastership_state': 'backup', 'model': 'RE-MX-104', 'status': 'OK', 'up_time': '2 days, 6 hours, 22 minutes, 12 seconds'}, 'RE_hw_mi': False, 'current_re': ['re0', 'master', 'node', 'fwdd', 'member', 'pfem'], 'domain': 'example.com', 'fqdn': 'router1.example.com', 'hostname': 'router1', ...
46
For detailed information about configuring outbound SSH on devices running Junos OS, see Configuring
Outbound SSH Service.

Connecting to a Device Using Telnet

The Junos PyEZ Device class supports connecting to a device running Junos OS using telnet, which provides unencrypted access to the network device. You can telnet to the device’s management interface or to a console server that is directly connected to the device’s CONSOLE port. You must configure the Telnet service at the [edit system services] hierarchy level on all devices that require access to the management interface. Accessing the device through a console server enables you to initially configure a new or zeroized device that is not yet configured for remote access.
To use Junos PyEZ to telnet to a device running Junos OS, you must include mode='telnet' in the Device argument list, and optionally include the port parameter to specify a port. When you include the mode='telnet' argument but omit the port parameter, the value for port defaults to 23. When the application connects through a console server, specify the port through which the console server connects to the device running Junos OS.
To use Junos PyEZ to telnet to a device running Junos OS and print the device facts in a Junos PyEZ application using Python 3:
47
1. Import the Device class and any other modules or objects required for your tasks.
import sys from getpass import getpass from jnpr.junos import Device
2. Create the device instance with the mode='telnet' argument, specify the connection port if different from the default, and provide the hostname, any parameters required for authentication, and any optional parameters.
hostname = input("Device hostname: ") junos_username = input("Junos OS username: ") junos_password = getpass("Junos OS password: ")
dev = Device(host=hostname, user=junos_username, passwd=junos_password, mode='telnet', port='23')
3. Connect to the device by calling the open() method.
try:
dev.open()
except Exception as err:
print (err)
sys.exit(1)
4. Print the device facts.
print (dev.facts)
5. After performing any necessary tasks, close the connection to the device.
dev.close()
The sample program in its entirety is presented here:
import sys from getpass import getpass from jnpr.junos import Device
hostname = input("Device hostname: ") junos_username = input("Junos OS username: ") junos_password = getpass("Junos OS password: ")
48
dev = Device(host=hostname, user=junos_username, passwd=junos_password, mode='telnet',
port='23')
try:
dev.open()
except Exception as err:
print (err)
sys.exit(1)
print (dev.facts)
dev.close()
Alternatively, you can use a context manager when connecting to the device, which handles opening and closing the connection. For example:
import sys from getpass import getpass from jnpr.junos import Device
hostname = input("Device hostname: ") junos_username = input("Junos OS username: ") junos_password = getpass("Junos OS password: ")
try:
with Device(host=hostname, user=junos_username, passwd=junos_password,
mode='telnet', port='23') as dev:
print (dev.facts)
except Exception as err:
print (err)
sys.exit(1)
In some cases, when you connect to a console server that emits a banner message, you might be required to press Enter after the message to reach the login prompt. If a Junos PyEZ application opens a Telnet session with a console server that requires the user to press Enter after a banner message, the application might fail to receive the login prompt, which can cause the connection to hang.
Starting in Junos PyEZ Release 2.1.0, a Junos PyEZ application can include the console_has_banner=True argument in the Device argument list to telnet to a console server that emits a banner message.
dev = Device(host=hostname, user=username, passwd=password, mode='telnet', console_has_banner=True)
49
When you include the console_has_banner=True argument and the application does not receive a login prompt upon initial connection, the application waits for 5 seconds and then emits a newline (\n) character so that the console server issues the login prompt. If you omit the argument and the connection hangs, the application instead emits the <close-session/> RPC to terminate the connection.

Connecting to a Device Using a Serial Console Connection

The Junos PyEZ Device class enables you to connect to a device running Junos OS using a serial console connection, which is useful when you must initially configure a new or zeroized device that is not yet configured for remote access. To use this connection method, you must be physically connected to the device through the CONSOLE port. For detailed instructions about connecting to the CONSOLE port on your device, see the hardware documentation for your specific device.
NOTE: Junos PyEZ supports using context managers for serial console connections. We
recommend that you use a context manager for console connections, because the context manager automatically handles opening and closing the connection. Failure to close the connection can lead to unpredictable results.
To use Junos PyEZ to connect to a device running Junos OS through a serial console connection, you must include mode='serial' in the Device argument list, and optionally include the port parameter to specify a
port. When you include the mode='serial' argument but omit the port parameter, the value for port defaults to /dev/ttyUSB0.
To connect to a device running Junos OS using a serial console connection and also load and commit a configuration on the device in a Junos PyEZ application using Python 3:
1. Import the Device class and any other modules or objects required for your tasks.
import sys from getpass import getpass from jnpr.junos import Device from jnpr.junos.utils.config import Config
2. Create the device instance with the mode='serial' argument, specify the connection port if different from the default, and provide any parameters required for authentication and any optional parameters.
junos_username = input("Junos OS username: ") junos_password = getpass("Junos OS password: ")
50
try:
with Device(mode='serial', port='port' user=junos_username,
passwd=junos_password) as dev:
print (dev.facts)
NOTE: All platforms running Junos OS have only the root user configured by default, without
any password. For new or zeroized devices, use user='root' and omit the passwd parameter.
3. Load and commit the configuration on the device.
cu = Config(dev) cu.lock() cu.load(path='/tmp/config_mx.conf') cu.commit() cu.unlock()
4. Include any necessary error handing.
except Exception as err:
print (err)
sys.exit(1)
The sample program in its entirety is presented here:
import sys from getpass import getpass from jnpr.junos import Device from jnpr.junos.utils.config import Config
junos_username = input("Junos OS username: ") junos_password = getpass("Junos OS password: ")
try:
with Device(mode='serial', port='port', user=junos_username,
passwd=junos_password) as dev:
print (dev.facts)
cu = Config(dev) cu.lock() cu.load(path='/tmp/config_mx.conf') cu.commit() cu.unlock()
51
except Exception as err:
print (err)
sys.exit(1)
RELATED DOCUMENTATION
Setting Up Junos PyEZ Managed Nodes | 31
Authenticating Junos PyEZ Users | 52
Using Junos PyEZ to Retrieve Facts from Devices Running Junos OS | 60
Troubleshooting Junos PyEZ Connection Errors | 304

Authenticating Junos PyEZ Users

IN THIS SECTION
Junos PyEZ User Authentication Overview | 52
Authenticating Junos PyEZ Users Using a Password | 53
Authenticating Junos PyEZ Users Using SSH Keys | 55

Junos PyEZ User Authentication Overview

Junos PyEZ enables you to directly connect to and manage devices running Junos OS using a serial console connection, telnet, or a NETCONF session over SSH. In addition, Junos PyEZ also supports connecting to the device through a telnet or SSH connection to a console server that is connected to the device’s CONSOLE port. The device must be able to authenticate the user using either a password or other standard SSH authentication mechanisms, depending on the connection method. When you manage devices running Junos OS through an SSH connection, the most convenient and secure way to access a device is to configure SSH keys. SSH keys enable the remote device to identify trusted users.
52
You can perform device operations using any user account that has access to the managed device running Junos OS. You can explicitly define the user when creating a new instance of the jnpr.junos.device.Device class, or if you do not specify a user in the parameter list, the user defaults to $USER.
For SSH connections, Junos PyEZ automatically queries the default SSH configuration file at ~/.ssh/config, if one exists, unless the Device argument list includes the ssh_config argument to specify a different configuration file. Junos PyEZ uses any relevant settings in the SSH configuration file for the given connection that are not overridden by the arguments in the Device argument list, such as the user or the identity file.
When the Junos PyEZ client uses SSH to connect to either the device running Junos OS or to a console server connected to the device, Junos PyEZ first attempts SSH public key-based authentication and then tries password-based authentication. When SSH keys are in use, the supplied password is used as the passphrase for unlocking the private key. When password-based authentication is used, the supplied password is used as the device password. If SSH public key-based authentication is being used and the SSH private key has an empty passphrase, then a password is not required. However, SSH private keys with empty passphrases are not recommended.
It is the user's responsibility to obtain the username and password authentication credentials in a secure manner appropriate for their environment. It is best practice to prompt for these authentication credentials during each invocation of the script rather than storing the credentials in an unencrypted format.

Authenticating Junos PyEZ Users Using a Password

To authenticate a Junos PyEZ user using a password:
1. In your favorite editor, create a new file that uses the .py file extension.
This example uses the filename junos-pyez-pw.py.
2. Include code that prompts for the hostname to which to connect and the username and password for the device running Junos OS and stores each value in a variable.
# Python 3
from jnpr.junos import Device from getpass import getpass
import sys
53
hostname = input("Hostname: ") junos_username = input("Junos OS username: ") junos_password = getpass("Junos OS password: ")
NOTE: For Python 2.7, you can use the raw_input() function instead of input(), or you can
install the future module and include the "from builtins import input" line in your application to make the code compatible with both Python 2 and 3.
3. If the Junos PyEZ client connects to the device through an SSH connection to a console server, include code that prompts for the console server username and password and stores each value in a variable.
# login credentials required for SSH connection to console server
cs_username = input("Console server username: ") cs_password = getpass("Console server password: ")
4. In the Device constructor argument list:
Set the host argument to the variable containing the hostname
Set the user and passwd arguments to the variables containing the Junos OS login credentials
If the Junos PyEZ client connects through a console server using SSH, set the cs_user and cs_passwd
arguments to the variables containing the console server login credentials.
Include any additional arguments required for the connection method
The following example provides sample code for each of the different connection methods:
# Python 3
from jnpr.junos import Device from getpass import getpass
import sys
hostname = input("Device hostname: ") junos_username = input("Junos OS username: ") junos_password = getpass("Junos OS password: ")
# login credentials required for SSH connection to console server
cs_username = input("Console server username: ") cs_password = getpass("Console server password: ")
54
try:
# NETCONF session over SSH
with Device(host=hostname, user=junos_username, passwd=junos_password) as
dev:
# Telnet connection to device or console server connected to device #with Device(host=hostname, user=junos_username, passwd=junos_password,
mode='telnet', port='23') as dev:
# Serial console connection to device #with Device(host=hostname, user=junos_username, passwd=junos_password,
mode='serial', port='/dev/ttyUSB0') as dev:
# SSH connection to console server connected to device #with Device(host=hostname, user=junos_username, passwd=junos_password,
cs_user=cs_username, cs_passwd=cs_password, timeout=5) as dev:
print (dev.facts)
except Exception as err:
print (err)
sys.exit(1)
NOTE: All platforms running Junos OS have only the root user configured by default, without
any password. When using Junos PyEZ to initially configure a new or zeroized device through a console connection, use user='root', and omit the passwd parameter.
5. Execute the Junos PyEZ code, which prompts for the hostname, the Junos OS username and password, and the console server username and password (when requested) and does not echo the password on the command line.
bsmith@server:~$ python3 junos-pyez-pw.py
Device hostname: dc1a.example.com Junos OS username: bsmith Junos OS password: Console server username: bsmith Console server password: {'domain': 'example.com', 'serialnumber': 'JNXXXXXXXXXX', 'ifd_style': 'CLASSIC', 'version_info': junos.version_info(major=(13, 3), type=R, minor=1, build=8), '2RE': True, 'hostname': 'dc1a', 'fqdn': 'dc1a.example.com', 'switch_style': 'NONE', 'version': '13.3R1.8', 'HOME': '/var/home/bsmith', 'model': 'MX240', 'RE0': {'status': 'OK', 'last_reboot_reason': 'Router rebooted after a normal shutdown.', 'model': 'RE-S-1300', 'up_time': '14 days, 17 hours, 45 minutes, 8 seconds'}, 'personality': 'MX'}
55

Authenticating Junos PyEZ Users Using SSH Keys

To use SSH keys in a Junos PyEZ application, you must first generate the keys on the configuration management server and configure the public key on each device to which the Junos PyEZ client will connect. To directly connect to the device running Junos OS, configure the key on that device. To connect to a device running Junos OS through a console server, configure the key on the console server. To use the keys, you must include the appropriate arguments in the Device argument list.
Junos PyEZ can utilize SSH keys that are actively loaded into an SSH key agent, keys that are generated in either the default location or a user-defined location, and keys that either use or forgo password protection. When connecting directly to a device running Junos OS, if the Device arguments do not specify a password or SSH key file, Junos PyEZ first checks the SSH keys that are actively loaded in the SSH key agent and then checks for SSH keys in the default location. When connecting to a console server, only password-protected keys are supported.
The following sections outline the steps for generating the SSH keys, configuring the keys on devices running Junos OS, and using the keys to connect to the managed device:
1.
Generating and Configuring SSH Keys | 56
2.
Referencing SSH Keys in Junos PyEZ Applications | 57
Generating and Configuring SSH Keys
To generate SSH keys on the configuration management server and configure the public key on devices running Junos OS:
1. On the server, generate the public and private SSH key pair for the desired user, and provide any required or desired options, for example:
user@server:~$ cd ~/.ssh user@server:~/.ssh$ ssh-keygen -t rsa -b 2048 Generating public/private rsa key pair. Enter file in which to save the key (/home/user/.ssh/id_rsa): id_rsa_dc Enter passphrase (empty for no passphrase): ***** Enter same passphrase again: *****
56
2. (Optional) Load the key into the native SSH key agent.
3. Configure the public key on each device to which the Junos PyEZ application will connect, which could include devices running Junos OS or a console server connected to the device running Junos OS.
The easiest method to configure the public key on a device running Junos OS is to load a file that contains the public key under the appropriate user account.
[edit] user@router# set system login user username authentication load-key-file URL user@router# commit
4. Verify that the key works by logging in to the device using the key.
user@server:~$ ssh -i ~/.ssh/id_rsa_dc router.example.com Enter passphrase for key '/home/user/.ssh/id_rsa_dc': user@router>
Referencing SSH Keys in Junos PyEZ Applications
IN THIS SECTION
Authenticating the User Using an SSH Key Agent with Actively Loaded Keys | 57
Authenticating the User Using SSH Keys Without Password Protection | 57
Authenticating the User Using Password-Protected SSH Key Files | 58
After generating the SSH key pair and configuring the public key on the remote device, you can use the key to connect to the device by including the appropriate arguments in the Device constructor code. The Device arguments are determined by the location of the key, whether the key is password-protected, whether the key is actively loaded into an SSH key agent, such as ssh-agent, and whether the user’s SSH configuration file already defines settings for that host. The following sections outline the various scenarios:
57
Authenticating the User Using an SSH Key Agent with Actively Loaded Keys
You can use an SSH key agent to securely store private keys and avoid repeatedly retyping the passphrase for password-protected keys. Junos PyEZ enables a client to connect directly to a device running Junos OS using SSH keys that are actively loaded into an SSH key agent. When connecting to a device running Junos OS, if the Device arguments do not specify a password or SSH key file, Junos PyEZ first checks the SSH keys that are actively loaded in the SSH key agent and then checks for SSH keys in the default location.
To use SSH keys that are actively loaded into the native SSH key agent to connect directly to a device running Junos OS:
In the Device argument list, you need only supply the required hostname and any desired variables.
dev = Device(host='router.example.com')
Authenticating the User Using SSH Keys Without Password Protection
Junos PyEZ enables a client to connect directly to a device running Junos OS using SSH private keys that do not have password protection, although we do not recommend using SSH private keys with an empty passphrase. Junos PyEZ does not support connecting to a console server using SSH private keys with an empty passphrase.
To connect to a device running Junos OS using SSH keys that are in the default location and do not have password protection:
In the Device argument list, you need only supply the required hostname and any desired variables.
dev = Device(host='router.example.com')
Junos PyEZ first checks the SSH keys that are loaded in any active SSH key agent and then checks the SSH keys in the default location.
To connect to a device running Junos OS using SSH keys that are not in the default location and do not have password protection:
In the Device argument list, set the ssh_private_key_file argument to the path of the SSH private key.
dev = Device(host='router.example.com', ssh_private_key_file='/home/user/.ssh/id_rsa_dc')
58
NOTE: If the user’s SSH configuration file already specifies the local SSH private key file path
for a given host, you can omit the ssh_private_key_file argument in the Device argument list. Including the ssh_private_key_file argument overrides any existing IdentityFile value defined for a host in the user’s SSH configuration file.
Authenticating the User Using Password-Protected SSH Key Files
Junos PyEZ clients can use password-protected SSH key files to connect directly to a device running Junos OS or to connect to a console server connected to the device.
To connect directly to a device running Junos OS using a password-protected SSH key file:
1. Include code that prompts for the SSH private key password and stores the value in a variable.
from jnpr.junos import Device from getpass import getpass
key_password = getpass('Password for SSH private key file: ')
2. In the Device argument list, set the passwd argument to reference the variable containing the SSH key file password.
If the key is not in the default location and the file path is not already defined in the user’s SSH configuration file, set the ssh_private_key_file argument to the path of the private key.
from jnpr.junos import Device from getpass import getpass
key_password = getpass('Password for SSH private key file: ')
dev = Device(host='router.example.com', passwd=key_password, ssh_private_key_file='/home/user/.ssh/id_rsa_dc') dev.open()
# ...
dev.close()
To connect to a device running Junos OS through a console server using a password-protected SSH key file:
1. Include code that prompts for the login credentials for the device running Junos OS and stores each value in a variable.
59
from jnpr.junos import Device from getpass import getpass
junos_username = input('Junos OS username: ') junos_password = getpass('Junos OS password: ')
2. Include code that prompts for the console server username and the SSH private key password and stores each value in a variable.
from jnpr.junos import Device from getpass import getpass
junos_username = input('Junos OS username: ') junos_password = getpass('Junos OS password: ')
cs_username = input("Console server username: ") key_password = getpass('Password for SSH private key file: ')
3. In the Device constructor argument list:
Set the host argument to the console server hostname or IP address
Set the user and passwd arguments to the variables containing the Junos OS login credentials
Set the cs_user argument to the variable containing the console server username
Set the cs_passwd argument to the variable containing the SSH key file password
Set the ssh_private_key_file argument to the path of the private key, if the key is not in the default
location and the file path is not already defined in the user’s SSH configuration file
from jnpr.junos import Device from getpass import getpass
junos_username = input('Junos OS username: ') junos_password = getpass('Junos OS password: ')
cs_username = input("Console server username: ") key_password = getpass('Password for SSH private key file: ')
with Device(host='router.example.com', user=junos_username, passwd=junos_password,
cs_user=cs_username, cs_passwd=key_password,
ssh_private_key_file='/home/user/.ssh/id_rsa_dc') as dev:
print (dev.facts)
# ...
60
RELATED DOCUMENTATION
Connecting to Devices Running Junos OS Using Junos PyEZ | 36
Troubleshooting Junos PyEZ Authentication Errors When Managing Devices Running Junos OS | 305
Using Junos PyEZ to Retrieve Facts from Devices Running Junos OS | 60

Using Junos PyEZ to Retrieve Facts from Devices Running Junos OS

IN THIS SECTION
Understanding Junos PyEZ Device Facts | 61
Example: Retrieving Facts from Devices Running Junos OS | 63

Understanding Junos PyEZ Device Facts

Junos PyEZ is a microframework for Python that enables you to manage and automate devices running Junos OS. Junos PyEZ models each device as an instance of the jnpr.junos.device.Device class. After connecting to a device running Junos OS, Junos PyEZ applications can retrieve facts about the device. The device facts are accessed as the facts attribute of the Device object. For detailed information about the keys that are included in the returned device facts, see jnpr.junos.facts.
The following example establishes a NETCONF session over SSH with the device and prints the device facts. The device uses SSH keys to authenticate the user.
from jnpr.junos import Device from pprint import pprint
with Device(host='router1.example.net') as dev:
pprint (dev.facts['hostname']) pprint (dev.facts)
61
user1@server:~$ python get-facts.py
'router1' {'2RE': True, 'HOME': '/var/home/user1', 'RE0': {'last_reboot_reason': '0x200:normal shutdown', 'mastership_state': 'master', 'model': 'RE-MX-104', 'status': 'OK', 'up_time': '25 days, 8 hours, 22 minutes, 40 seconds'}, 'RE1': {'last_reboot_reason': '0x200:normal shutdown', 'mastership_state': 'backup', 'model': 'RE-MX-104', 'status': 'OK', 'up_time': '25 days, 8 hours, 23 minutes, 55 seconds'}, ...
In Junos PyEZ Release 2.0.0 and earlier releases, when the application calls the Device open() method to connect to a device, Junos PyEZ automatically gathers the device facts for NETCONF-over-SSH connections and gathers the device facts for Telnet and serial console connections when you explicitly include gather_facts=True in the Device argument list.
Starting in Junos PyEZ Release 2.1.0, device facts are gathered on demand for all connection types. Each fact is gathered and cached the first time the application accesses its value or the value of a dependent
fact. When you print or use device facts, previously accessed facts are served from the cache, and facts that have not yet been accessed are retrieved from the device. If a fact is not supported on a given platform, or if the application encounters an issue gathering the value of a specific fact, then the fact will have the value None.
Junos PyEZ caches a device fact when it first accesses the fact or a dependent fact, but it does not update the cached value upon subsequent access. To refresh the device facts, call the facts_refresh() method. The facts_refresh() method empties the cache of all facts, such that when the application next accesses a fact, it retrieves it from the device and stores the current value in the cache.
from jnpr.junos import Device from pprint import pprint
with Device(host='router1.example.net') as dev:
pprint (dev.facts) dev.facts_refresh() pprint (dev.facts)
62
To refresh only a single fact or a set of facts, include the keys argument in the facts_refresh() method, and specify the keys to clear from the cache. For example:
dev.facts_refresh(keys='hostname') dev.facts_refresh(keys=('hostname','domain','master'))
NOTE: Starting in Junos PyEZ Release 2.0.0, exceptions that occur when gathering facts raise
a warning instead of an error, which enables the script to continue running.
By default, Junos PyEZ returns the device facts as a dictionary-like object. Starting in Junos PyEZ Release
2.2.1, you can view the device facts in JavaScript Object Notation (JSON). To view a JSON representation
of the facts, import the json module, and call the json.dumps() function.
from jnpr.junos import Device
import json
with Device(host='router1.example.net') as dev:
print (json.dumps(dev.facts))

Example: Retrieving Facts from Devices Running Junos OS

With Junos PyEZ, you can quickly execute commands in Python interactive mode, or you can create programs to perform tasks. The following example establishes a NETCONF session over SSH with a device running Junos OS and retrieves and prints facts for the device using both a simple Python program and Python interactive mode. The examples use existing SSH keys for authentication.
To create a Junos PyEZ application that establishes a NETCONF session over SSH with a device running Junos OS and prints the device facts:
1. In your favorite editor, create a new file with a descriptive name that uses the .py file extension.
2. Import the Device class and any other modules or objects required for your tasks.
import sys from jnpr.junos import Device from jnpr.junos.exception import ConnectError from pprint import pprint
63
3. Create the device instance and provide the hostname, any parameters required for authentication, and any optional parameters.
dev = Device(host='router1.example.net')
4. Connect to the device by calling the open() method.
try:
dev.open()
except ConnectError as err:
print ("Cannot connect to device: {0}".format(err))
sys.exit(1)
5. Print the device facts.
pprint (dev.facts['hostname']) pprint (dev.facts)
TIP: To refresh the facts for a device, call the facts_refresh() method, for example,
dev.facts_refresh().
6. Close the connection to the device.
dev.close()
7. Save and execute the program.
user1@server:~$ python junos-pyez-device-facts.py
'router1' {'2RE': True, 'HOME': '/var/home/user1', 'RE0': {'last_reboot_reason': '0x200:normal shutdown', 'mastership_state': 'master', 'model': 'RE-MX-104', 'status': 'OK', 'up_time': '25 days, 8 hours, 22 minutes, 40 seconds'}, 'RE1': {'last_reboot_reason': '0x200:normal shutdown', 'mastership_state': 'backup', 'model': 'RE-MX-104', 'status': 'OK', 'up_time': '25 days, 8 hours, 23 minutes, 55 seconds'}, ...
64
The entire program is presented here:
import sys from jnpr.junos import Device from jnpr.junos.exception import ConnectError from pprint import pprint
dev = Device(host='router1.example.net')
try:
dev.open()
except ConnectError as err:
print ("Cannot connect to device: {0}".format(err))
sys.exit(1)
pprint (dev.facts['hostname']) pprint (dev.facts)
dev.close()
You can also quickly perform the same operations in Python interactive mode.
user1@server:~$ python Python 2.7.12 (default, Nov 12 2018, 14:36:49) [GCC 5.4.0 20160609] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>>
>>> from jnpr.junos import Device >>> from pprint import pprint
>>> >>> dev = Device('router1.example.net') >>> dev.open()
Device(router1.example.net) >>>
>>> pprint (dev.facts) {'2RE': True, 'HOME': '/var/home/user1', 'RE0': {'last_reboot_reason': '0x200:normal shutdown', 'mastership_state': 'master', 'model': 'RE-MX-104', 'status': 'OK', 'up_time': '25 days, 8 hours, 22 minutes, 40 seconds'}, 'RE1': {'last_reboot_reason': '0x200:normal shutdown', 'mastership_state': 'backup', 'model': 'RE-MX-104', 'status': 'OK', 'up_time': '25 days, 8 hours, 23 minutes, 55 seconds'}, ... >>>
>>> dev.close() >>> quit()
65
The following video presents a short Python session that demonstrates how to use Junos PyEZ to connect to and retrieve facts from a device running Junos OS.
Video: Junos PyEZ - Hello, World
Release History Table
66
DescriptionRelease
2.1.0
2.0.0
RELATED DOCUMENTATION
Connecting to Devices Running Junos OS Using Junos PyEZ | 36
Authenticating Junos PyEZ Users | 52
Troubleshooting Junos PyEZ Connection Errors | 304
Starting in Junos PyEZ Release 2.1.0, device facts are gathered on demand for all connection types.
Starting in Junos PyEZ Release 2.0.0, exceptions that occur when gathering facts raise a warning instead of an error, which enables the script to continue running.

Accessing the Shell on Devices Running Junos OS Using Junos PyEZ

The Junos OS command-line interface (CLI) has many operational mode commands that return information that is similar to the information returned by many shell commands. Thus, access to the UNIX-level shell on devices running Junos OS is usually not required. However in some cases, a user or application might need to access the shell and execute shell commands or CLI commands from the shell.
The Junos PyEZ jnpr.junos.utils.start_shell module defines the StartShell class, which enables Junos PyEZ applications to initiate an SSH connection to a device running Junos OS and access the shell. The StartShell methods enable the application to then execute commands over the connection and retrieve the response. The StartShell open() and close() methods establish and terminate an SSH connection with the device. As a result, if the client application only requires access to the shell, it can omit the calls to the Device open() and close() methods.
The StartShell run() method executes a shell command and waits for the response. By default, the method waits for one of the default shell prompts (%, #, >, or \$) before returning the command output. If you set the this="string" argument to a specific string, the method waits for the expected string or pattern before
returning the command output. The return value is a tuple, where the first item is True if the exit code is 0, and False otherwise, and the second item is the output of the command.
The following example connects to a host and executes two operational mode commands from the shell. The script first executes the request support information command and saves the output to a file. The script then executes the show version command, stores the output in the version variable, and then prints the contents of the variable.
from jnpr.junos import Device from jnpr.junos.utils.start_shell import StartShell
dev = Device(host='router1.example.net')
ss = StartShell(dev) ss.open() ss.run('cli -c "request support information | save /var/tmp/information.txt"') version = ss.run('cli -c "show version"')
print (version)
ss.close()
67
In this example, the returned tuple includes the Boolean corresponding to the exit code for the command and the command output for the show version command. The output in this example is truncated for brevity.
(False, '\r \rHostname: router1\r\nModel: mx104\r\nJunos:
17.1R8\r\nJUNOS Base OS boot [17.1R1.8]\r\n ...)
Instances of the StartShell class can also be used as context managers. In this case, you do not need to explicitly call the StartShell open() and close() methods. For example:
from jnpr.junos import Device from jnpr.junos.utils.start_shell import StartShell
dev = Device(host='router1.example.net')
with StartShell(dev) as ss:
ss.run('cli -c "request support information | save /var/tmp/information.txt"') version = ss.run('cli -c "show version"')
print (version)
Starting in Junos PyEZ Release 2.0.1, you can include the StartShell timeout argument to specify the duration of time in seconds that the utility must wait for the expected string or pattern in the Junos OS shell before timing out. If you do not specify a timeout, the default is 30 seconds.
from jnpr.junos import Device from jnpr.junos.utils.start_shell import StartShell
dev = Device(host='router1.example.net')
with StartShell(dev, timeout=60) as ss:
ss.run('cli -c "request support information | save /var/tmp/information.txt"') version = ss.run('cli -c "show version"')
print (version)
In certain cases, you might need to execute nonreturning shell commands, such as the monitor traffic command, which displays traffic that originates or terminates on the local Routing Engine. In the Junos OS CLI, the monitor traffic command displays the information in real time until the user sends a Ctrl+c keyboard sequence to stop the packet capture.
68
Starting in Junos PyEZ Release 2.1.0, you can execute nonreturning shell commands using the StartShell run() method by setting the this parameter equal to None. When you include the this=None argument,
the method waits until the specified timeout value to retrieve and return all command output from the shell. In this case, the first item of the returned tuple is True when the result of the executed shell command returns content, and the second item is the command output. If you omit the this argument or set it equal to a specific string or pattern, the method might return partial output for a nonreturning command if it encounters a default prompt or the specified string pattern within the command output.
The following sample code executes the monitor traffic interface fxp0 command, waits for 15 seconds, and then retrieves and returns the command output.
from jnpr.junos import Device from jnpr.junos.utils.start_shell import StartShell
dev = Device(host='router1.example.net')
with StartShell(dev) as ss:
ss.run('cli -c "monitor traffic interface fxp0"', this=None, timeout=15)
For more information about the StartShell class and its methods, see
http://junos-pyez.readthedocs.io/en/latest/jnpr.junos.utils.html#module-jnpr.junos.utils.start_shell.
RELATED DOCUMENTATION
Using Junos PyEZ to Execute RPCs on Devices Running Junos OS | 71
Connecting to Devices Running Junos OS Using Junos PyEZ | 36
69
5
CHAPTER
Using Junos PyEZ to Manage Device
Operations
Using Junos PyEZ to Execute RPCs on Devices Running Junos OS | 71
Suppressing RpcError Exceptions Raised for Warnings in Junos PyEZ Applications | 80
Using Junos PyEZ to Reboot or Shut Down Devices Running Junos OS | 81
Using Junos PyEZ to Install Software on Devices Running Junos OS | 87
Transferring Files Using Junos PyEZ | 105
Specifying the XML Parser for a Junos PyEZ Session | 109

Using Junos PyEZ to Execute RPCs on Devices Running Junos OS

IN THIS SECTION
Mapping Junos OS Commands to Junos PyEZ RPCs | 71
Executing RPCs as a Property of the Device Instance | 73
Specifying the Format of the RPC Output | 74
Specifying the Scope of Data to Return | 76
Specifying the RPC Timeout | 77
Normalizing the XML RPC Reply | 78
71
You can use Junos PyEZ to execute remote procedure calls (RPCs) on demand on devices running Junos OS. After creating an instance of the Device class, you can execute RPCs as a property of the Device instance. You can perform most of the same operational commands using Junos PyEZ that you can execute in the CLI.
The Junos XML API is an XML representation of Junos OS configuration statements and operational mode commands. It defines an XML equivalent for all statements in the Junos OS configuration hierarchy and many of the commands that you issue in CLI operational mode. Each operational mode command with a Junos XML counterpart maps to a request tag element and, if necessary, a response tag element. Request tags are used in RPCs within NETCONF or Junos XML protocol sessions to request information from a device running Junos OS. The server returns the response using Junos XML elements enclosed within the response tag element.
When you use Junos PyEZ to execute RPCs, you map the request tag name to a method name. This topic outlines how to map CLI commands to Junos PyEZ RPCs, how to execute RPCs using Junos PyEZ, and how to customize the data returned in the RPC reply.

Mapping Junos OS Commands to Junos PyEZ RPCs

All operational commands that have Junos XML counterparts are listed in the Junos XML API Explorer. You can also display the Junos XML request tag element for any operational mode command that has a
Junos XML counterpart either on the CLI or using Junos PyEZ. Once you obtain the request tag, you can map it to the Junos PyEZ RPC method name.
To display the Junos XML request tag for a command in the CLI, include the | display xml rpc option after the command. The following example displays the request tag for the show route command:
user@router> show route | display xml rpc
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/15.1R1/junos"> <rpc> <get-route-information> </get-route-information> </rpc> </rpc-reply>
You can also display the Junos XML request tag for a command using Junos PyEZ. To display the request tag, call the Device instance display_xml_rpc() method, and include the command string and format='text' as arguments. For example:
72
from jnpr.junos import Device
with Device(host='router.example.com') as dev:
print (dev.display_xml_rpc('show route', format='text'))
Executing the program returns the request tag for the show route command.
<get-route-information> </get-route-information>
You can map the request tags for an operational command to a Junos PyEZ RPC method name. To derive the RPC method name, replace any hyphens in the request tag with underscores (_) and remove the enclosing angle brackets. For example, the <get-route-information> request tag maps to the
get_route_information() method name.

Executing RPCs as a Property of the Device Instance

Each instance of Device has an rpc property that enables you to execute any RPC available through the Junos XML API. In a Junos PyEZ application, after establishing a connection with the device, you can execute the RPC by appending the rpc property and RPC method name to the device instance as shown in the following example:
from jnpr.junos import Device from lxml import etree
with Device(host='dc1a.example.com') as dev:
#invoke the RPC equivalent to "show version"
sw = dev.rpc.get_software_information()
print(etree.tostring(sw, encoding='unicode'))
The return value is an XML object starting at the first element under the <rpc-reply> tag. In this case, the get_software_information() RPC returns the <software-information> element.
73
<software-information> <host-name>dc1a</host-name> ... </software-information>
Junos OS commands can have fixed-form options that do not have a value. For example, the Junos XML equivalent for the show interfaces terse command indicates that terse is an empty element.
user@router> show interfaces terse | display xml rpc <rpc-reply xmlns:junos="http://xml.juniper.net/junos/14.1R1/junos"> <rpc> <get-interface-information> <terse/> </get-interface-information> </rpc> </rpc-reply>
To execute an RPC and include a command option that does not take a value, add the option to the RPC method’s argument list, change any dashes in the option name to underscores, and set it equal to True. The following code executes the Junos PyEZ RPC equivalent of the show interfaces terse command:
rsp = dev.rpc.get_interface_information(terse=True)
Junos OS commands can also have options that require a value. For example, in the following output, the interface-name element requires a value, which is the name of the interface for which you want to return information:
user@router> show interfaces ge-0/0/0 | display xml rpc <rpc-reply xmlns:junos="http://xml.juniper.net/junos/14.1R1/junos"> <rpc> <get-interface-information> <interface-name>ge-0/0/0</interface-name> </get-interface-information> </rpc> </rpc-reply>
74
To execute an RPC and include a command option that requires a value, add the option to the RPC method’s argument list, change any dashes in the option name to underscores, and then set it equal to the appropriate value. The following example executes the Junos PyEZ RPC equivalent of the show interfaces ge-0/0/0 command:
rsp = dev.rpc.get_interface_information(interface_name='ge-0/0/0')

Specifying the Format of the RPC Output

By default, the RPC return value is an XML object starting at the first element under the <rpc-reply> tag. Starting in Junos PyEZ Release 1.2.3, you can also return the RPC output in text or JavaScript Object Notation (JSON) format by including either the {'format':'text'} or {'format':'json'} dictionary as the RPC method’s first argument.
NOTE: RPC output in JSON format is only supported on devices running Junos OS Release 14.2
and later releases.
The following example returns the output of the get_software_information() RPC in text format, which is identical to the output emitted for the show version command in the CLI, except that the RPC output is enclosed within an <output> element.
from jnpr.junos import Device from lxml import etree
with Device(host='router1.example.com') as dev:
sw_info_text = dev.rpc.get_software_information({'format':'text'})
print(etree.tostring(sw_info_text))
user@server:~$ python junos-pyez-rpc-text-format.py
<output> Hostname: router1 Model: mx104 Junos: 18.3R1.9 JUNOS Base OS boot [18.3R1.9] JUNOS Base OS Software Suite [18.3R1.9] JUNOS Crypto Software Suite [18.3R1.9] JUNOS Packet Forwarding Engine Support (TRIO) [18.3R1.9] JUNOS Web Management [18.3R1.9] JUNOS Online Documentation [18.3R1.9] JUNOS SDN Software Suite [18.3R1.9] JUNOS Services Application Level Gateways [18.3R1.9] JUNOS Services COS [18.3R1.9] JUNOS Services Jflow Container package [18.3R1.9] JUNOS Services Stateful Firewall [18.3R1.9] JUNOS Services NAT [18.3R1.9] JUNOS Services RPM [18.3R1.9] JUNOS Services Captive Portal and Content Delivery Container package [18.3R1.9] JUNOS Macsec Software Suite [18.3R1.9] JUNOS Services Crypto [18.3R1.9] JUNOS Services IPSec [18.3R1.9] JUNOS DP Crypto Software Software Suite [18.3R1.9] JUNOS py-base-powerpc [18.3R1.9] JUNOS py-extensions-powerpc [18.3R1.9] JUNOS jsd [powerpc-18.3R1.9-jet-1] JUNOS Kernel Software Suite [18.3R1.9] JUNOS Routing Software Suite [18.3R1.9] <output>
75
The following example returns the output of the get_software_information() RPC in JSON format.
from jnpr.junos import Device from pprint import pprint
with Device(host='router1.example.com') as dev:
sw_info_json = dev.rpc.get_software_information({'format':'json'}) pprint(sw_info_json)
user@server:~$ python junos-pyez-rpc-json-format.py
{u'software-information': [{u'host-name': [{u'data': u'router1'}], u'junos-version': [{u'data': u'18.3R1.9'}], u'package-information': [{u'comment': [{u'data': u'JUNOS Base OS boot [18.3R1.9]'}], u'name': [{u'data': u'junos'}]}, {u'comment': [{u'data': u'JUNOS Base OS Software Suite [18.3R1.9]'}], u'name': [{u'data': u'jbase'}]}, ...
76

Specifying the Scope of Data to Return

You can use Junos PyEZ to execute an RPC to retrieve operational information from devices running Junos OS. Starting in Junos PyEZ Release 2.3.0, when you request XML output, you can filter the reply to return only specific elements. Filtering the output is beneficial when you have extensive operational output, but you only need to work with a subset of the data.
To filter the RPC reply to return only specific tags, include the RPC method’s filter_xml argument. The filter_xml parameter takes a string containing the subtree filter that selects the elements to return. The subtree filter returns the data that matches the selection criteria.
The following Junos PyEZ example executes the <get-interface-information> RPC and filters the output to retrieve just the <name> element for each <physical-interface> element in the reply:
from jnpr.junos import Device from lxml import etree
with Device(host='router.example.com', use_filter=True) as dev:
filter =
'<interface-information><physical-interface><name/></physical-interface></interface-information>'
result = dev.rpc.get_interface_information(filter_xml=filter)
print (etree.tostring(reply, encoding='unicode'))
When you execute the script, it displays each physical interface’s name element.
user@server:~$ python junos-pyez-get-interface-names.py
<interface-information style="normal"><physical-interface><name> lc-0/0/0 </name></physical-interface><physical-interface><name> pfe-0/0/0 </name></physical-interface><physical-interface><name> pfh-0/0/0 </name></physical-interface><physical-interface><name> xe-0/0/0 </name></physical-interface><physical-interface><name> xe-0/1/0 </name></physical-interface><physical-interface><name> ge-1/0/0 </name></physical-interface> ... </interface-information>
77

Specifying the RPC Timeout

RPC execution time can vary considerably depending on the RPC and the device. By default, NETCONF RPCs time out after 30 seconds. Starting in Junos PyEZ Release 1.2, you can extend the timeout value by including the dev_timeout=seconds argument when you execute the RPC to ensure that the RPC does not time out during execution. dev_timeout adjusts the device timeout only for that single RPC operation.
dev.rpc.get_route_information(table='inet.0', dev_timeout=55)

Normalizing the XML RPC Reply

When you execute an RPC, the RPC reply can include data that is wrapped in newlines or contains other superfluous whitespace. Unnecessary whitespace can make it difficult to parse the XML and find information using text-based searches. Starting in Junos PyEZ Release 1.2, you can normalize an RPC reply, which strips out all leading and trailing whitespace and replaces sequences of internal whitespace characters with a single space.
Table 9 on page 78 compares a default RPC reply to the normalized version. The default RPC reply includes
many newlines that are not present in the normalized reply.
Table 9: Comparison of a Default and Normalized RPC Reply
Normalized RPC ReplyDefault RPC Reply
78
<interface-information style="terse"> <logical-interface> <name>\nge-0/0/0.0\n</name> <admin-status>\nup\n</admin-status> <oper-status>\nup\n</oper-status> <filter-information>\n</filter-information> <address-family> <address-family-name>\ninet\n</address-family-name> <interface-address> <ifa-local emit="emit">\n198.51.100.1/24\n</ifa-local> </interface-address> </address-family> </logical-interface> </interface-information>
<interface-information style="terse"> <logical-interface> <name>ge-0/0/0.0</name> <admin-status>up</admin-status> <oper-status>up</oper-status> <filter-information/> <address-family>
<address-family-name>inet</address-family-name>
<interface-address> <ifa-local emit="emit">198.51.100.1/24</ifa-local> </interface-address> </address-family> </logical-interface> </interface-information>
You can enable normalization for the duration of a session with a device, or you can normalize an individual RPC reply when you execute the RPC. To enable normalization for the entire device session, include normalize=True in the argument list either when you create the device instance or when you connect to the device using the open() method.
dev = Device(host='router1.example.com', user='root', normalize=True)
# or
dev.open(normalize=True)
To normalize an individual RPC reply, include normalize=True in the argument list for that RPC method.
dev.rpc.rpc_method(normalize=True)
For example:
rsp = dev.rpc.get_interface_information(interface_name='ge-0/0/0.0', terse=True, normalize=True)
If you do not normalize the RPC reply, you must account for any whitespace when using XPath expressions that reference a specific node or value. The following example selects the IPv4 address for a logical interface. In the XPath expression, the predicate specifying the inet family must account for the additional whitespace in order for the search to succeed. The resulting value includes leading and trailing newlines.
rsp = dev.rpc.get_interface_information(interface_name='ge-0/0/0.0', terse=True)
print (rsp.xpath(".// \
address-family[normalize-space(address-family-name)='inet']/ \ interface-address/ifa-local")[0].text)
'\n198.51.100.1/24\n'
79
When you normalize the RPC reply, any leading and trailing whitespace is removed, which makes text-based searches much more straightforward.
rsp = dev.rpc.get_interface_information(interface_name='ge-0/0/0.0', terse=True, normalize=True)
print (rsp.xpath(".//address-family[address-family-name='inet']/ \
interface-address/ifa-local")[0].text)
'198.51.100.1/24'
RELATED DOCUMENTATION
Suppressing RpcError Exceptions Raised for Warnings in Junos PyEZ Applications | 80
Accessing the Shell on Devices Running Junos OS Using Junos PyEZ | 66
Using Junos PyEZ to Retrieve Facts from Devices Running Junos OS | 60

Suppressing RpcError Exceptions Raised for Warnings in Junos PyEZ Applications

Junos PyEZ enables you to perform operational and configuration tasks on devices running Junos OS. In a Junos PyEZ application, when you call specific methods or execute on-demand RPCs, Junos PyEZ sends the appropriate RPCs to the device to perform the operation or retrieve the requested information. If the RPC reply contains <rpc-error> elements with a severity of warning or higher, the Junos PyEZ application raises an RpcError exception.
In certain cases, it might be necessary or desirable to suppress the RpcError exceptions that are raised in response to warnings. You can instruct a Junos PyEZ application to suppress RpcError exceptions that are raised for warnings by including the ignore_warning argument in the method call or RPC invocation. The ignore_warning argument takes a Boolean, a string, or a list of strings.
To instruct the application to ignore all warnings for an operation or RPC, include the ignore_warning=True argument in the method call or RPC invocation. The following example ignores all warnings for the load() method and the get_configuration() RPC:
80
from jnpr.junos import Device from jnpr.junos.utils.config import Config
dev = Device(host='router1.example.com') dev.open()
with Config(dev, mode='exclusive') as cu:
cu.load(path="mx-config.conf", ignore_warning=True) cu.commit()
data = dev.rpc.get_configuration(ignore_warning=True)
print(etree.tostring(data, encoding='unicode'))
dev.close()
If you include ignore_warning=True and all of the <rpc-error> elements have a severity of warning, the application ignores all warnings and does not raise an RpcError exception. However, any <rpc-error> elements with higher severity levels will still raise exceptions.
To instruct the application to ignore specific warnings, set the ignore_warning argument to a string or a list of strings containing the warnings to ignore. For example, the following Junos PyEZ application ignores two specific warnings during the commit operation:
from jnpr.junos import Device from jnpr.junos.utils.config import Config
commit_warnings = ['Advertisement-interval is less than four times',
'Chassis configuration for network services has been changed.']
dev = Device(host='router1.example.com') dev.open()
with Config(dev, mode='exclusive') as cu:
cu.load(path="mx-config.conf") cu.commit(ignore_warning=commit_warnings)
dev.close()
81
The Junos PyEZ application suppresses RpcError exceptions if all of the <rpc-error> elements have a severity of warning and each warning in the response matches one or more of the specified strings. When ignore_warning is set to a string or list of strings, the string is used as a case-insensitive regular expression. If a string contains only alphanumeric characters, it results in a case-insensitive substring match. However, you can include any regular expression pattern supported by the re library to match warnings.
RELATED DOCUMENTATION
Using Junos PyEZ to Execute RPCs on Devices Running Junos OS | 71
Troubleshooting Junos PyEZ Errors When Configuring Devices Running Junos OS | 306

Using Junos PyEZ to Reboot or Shut Down Devices Running Junos OS

IN THIS SECTION
Performing a Reboot or Shut Down | 82
Performing a Reboot or Shut Down with a Delay or at a Specified Time | 84
Specifying the Target for the Reboot or Shutdown | 85
Rebooting a VM Host | 86

Performing a Reboot or Shut Down

The Junos PyEZ jnpr.junos.utils.sw.SW utility enables you to reboot or shut down a device running Junos OS by executing the reboot() or poweroff() method, respectively. You can perform an immediate system reboot or shutdown operation, request the operation with an optional delay, or you can schedule the operation at a specified date and time. By default, the reboot() and poweroff() methods execute the operation immediately on all Routing Engines, if in a dual Routing Engine or Virtual Chassis setup.
NOTE: Starting in Junos PyEZ Release 2.1.0, the reboot() and poweroff() methods perform the
requested operation on all Routing Engines in a dual Routing Engine or Virtual Chassis setup. In earlier releases, the methods only perform the operation on the Routing Engine to which the application is connected.
82
NOTE: If a Junos PyEZ application reboots a device from a NETCONF-over-SSH session or from
a Telnet session through the management interface, the application loses connectivity to the device when it reboots. If the application requires access to the device after the reboot, it must issue the Junos PyEZ open() method to restore connectivity.
The following Junos PyEZ example, which uses Python 3, establishes a NETCONF session over SSH with a device running Junos OS and reboots all Routing Engines, effective immediately.
#Python 3
from jnpr.junos import Device from jnpr.junos.utils.sw import SW from jnpr.junos.exception import ConnectError from getpass import getpass
hostname = input("Device hostname: ") username = input("Device username: ") password = getpass("Device password: ")
try:
with Device(host=hostname, user=username, passwd=password) as dev:
sw = SW(dev)
print(sw.reboot())
except ConnectError as err:
print (err)
The application prompts for the device hostname and user credentials. After requesting the system reboot, the application displays the reboot message and the process ID for the process on the connected Routing Engine.
user1@server:~$ python3 junos-pyez-reboot.py
Device hostname: dc1a.example.com Device username: user1 Device password: Shutdown NOW! [pid 2358]
83
The following Junos PyEZ example shuts down all Routing Engines on the device, effective immediately.
#Python 3
from jnpr.junos import Device from jnpr.junos.utils.sw import SW from jnpr.junos.exception import ConnectError from getpass import getpass
hostname = input("Device hostname: ") username = input("Device username: ") password = getpass("Device password: ")
try:
with Device(host=hostname, user=username, passwd=password) as dev:
sw = SW(dev)
print(sw.poweroff())
except ConnectError as err:
print (err)

Performing a Reboot or Shut Down with a Delay or at a Specified Time

The default behavior of the reboot() and poweroff() methods is to immediately execute the operation. You can also request a delay before executing the operation, or you can schedule the operation at a particular date and time.
To delay the reboot or shutdown operation by a specified number of minutes, set the optional in_min parameter to the amount of time in minutes that the system should wait before rebooting or powering off. The following example requests a reboot of all Routing Engines in 2 minutes:
from jnpr.junos import Device from jnpr.junos.utils.sw import SW
with Device(host='dc1a.example.com') as dev:
sw = SW(dev) sw.reboot(in_min=2)
84
The target device issues messages about the impending reboot to any users logged into the system. After the specified amount of time has passed, the system reboots.
*** System shutdown message from user1@dc1a ***
System going down in 2 minutes
To schedule the reboot or shutdown operation at a specific time, include the at parameter, which takes a string that can be specified in one of the following ways:
now—Stop or reboot the software immediately.
+minutes—Number of minutes from now to perform the operation.
yymmddhhmm—Absolute time at which to perform the operation, specified as year, month, day, hour,
and minute.
hh:mm—Absolute time on the current day at which to perform the operation, specified in 24-hour time.
NOTE: The poweroff() method supports the at parameter starting in Junos PyEZ Release 2.3.0.
The following example schedules a system reboot of all Routing Engines at 22:30 on the current day:
from jnpr.junos import Device from jnpr.junos.utils.sw import SW
with Device(host='dc1a.example.com') as dev:
sw = SW(dev) sw.reboot(at='22:30')
Similarly, the following example schedules all Routing Engines to power off at 22:30 on the current day:
from jnpr.junos import Device from jnpr.junos.utils.sw import SW
with Device(host='dc1a.example.com') as dev:
sw = SW(dev) sw.poweroff(at='22:30')
85

Specifying the Target for the Reboot or Shutdown

Starting in Junos PyEZ Release 2.1.0, the reboot() and poweroff() methods reboot or shut down all Routing Engines in a dual Routing Engine or Virtual Chassis setup. You can also instruct the device to only reboot the Routing Engine to which the application is connected or to reboot or shutdown a certain node of a device running Junos OS Evolved.
To reboot only the Routing Engine to which the application is connected, include the all_re=False argument in the reboot() method.
from jnpr.junos import Device from jnpr.junos.utils.sw import SW
with Device(host='dc1a.example.com') as dev:
sw = SW(dev) sw.reboot(all_re=False)
To reboot or shut down a specific node of a device running Junos OS Evolved, include the on_node argument, and specify the node. For example:
from jnpr.junos import Device from jnpr.junos.utils.sw import SW
with Device(host='router1.example.com') as dev:
sw = SW(dev) sw.reboot(on_node='re0')

Rebooting a VM Host

On devices that have Routing Engines with VM host support, Junos OS runs as a virtual machine (VM) over a Linux-based host (VM host). Starting in Junos PyEZ Release 2.3.0, the reboot() method supports the vmhost argument, which enables you to reboot a VM Host. When you include the vmhost=True argument, the system reboots the host OS and compatible Junos OS on all Routing Engines by executing the <request-vmhost-reboot> RPC, which corresponds to the request vmhost reboot operational mode command.
86
The following example reboots the Routing Engines on the VM Host, which reboots both the guest Junos OS and the host OS.
from jnpr.junos import Device from jnpr.junos.utils.sw import SW
with Device(host='switch1.example.net') as dev:
sw = SW(dev) sw.reboot(vmhost=True)
Release History Table
DescriptionRelease
2.1.0
Starting in Junos PyEZ Release 2.1.0, the reboot() and poweroff() methods perform the requested operation on all Routing Engines in a dual Routing Engine or Virtual Chassis setup.
RELATED DOCUMENTATION
Using Junos PyEZ to Install Software on Devices Running Junos OS | 87

Using Junos PyEZ to Install Software on Devices Running Junos OS

IN THIS SECTION
Supported Deployment Scenarios | 87
Specifying the Software Image Location | 88
Installation Process Overview | 89
Specifying Installation and Checksum Timeouts | 91
Logging the Installation Process | 92
Performing a VM Host Upgrade | 93
Performing a Unified ISSU or NSSU | 94
Example: Using Junos PyEZ to Install Software on Devices Running Junos OS | 96
87
The Junos PyEZ jnpr.junos.utils.sw.SW utility enables you to install or upgrade the software image on devices running Junos OS. The install() method installs the specified software package.
This topic discusses the supported deployment scenarios, how to specify the software image location, and the general installation process and options when using Junos PyEZ to upgrade a device. It also discusses how to use Junos PyEZ to perform more specialized upgrade scenarios such as a VM host upgrade, a unified in-service software upgrade (unified ISSU), or a nonstop software upgrade (NSSU) on devices that support these features.

Supported Deployment Scenarios

The Junos PyEZ jnpr.junos.utils.sw.SW utility enables you to install or upgrade the software image on an individual device running Junos OS or on the members in a mixed or non-mixed Virtual Chassis. The following scenarios are supported:
Standalone devices with a single Routing Engine
Standalone devices equipped with dual Routing Engines
EX Series Virtual Chassis in mixed and non-mixed-mode configurations
QFX Series Virtual Chassis in mixed and non-mixed-mode configurations
Mixed EX Series and QFX Series Virtual Chassis
VM host upgrades on Routing Engines with VM Host Support
Deployment configurations that have some form of in-service features enabled, such as unified ISSU or
NSSU
NOTE: The jnpr.junos.utils.sw.SW utility does not support upgrading devices in an MX Series
Virtual Chassis, an SRX Series chassis cluster, or a Virtual Chassis Fabric (VCF).

Specifying the Software Image Location

When you use Junos PyEZ to install software on devices running Junos OS, you can download the software image to the configuration management server, and the install() method, by default, copies it to the target device before performing the installation. You can also instruct the install() method to install an image that already resides on the target device or resides at a URL that is reachable from the target device.
88
Table 10 on page 88 outlines the install() method parameters that you must set depending on the software
package location. You must always include either the package or pkg_set parameter in the install() method invocation.
Table 10: install() Method Parameter Settings for Software Package Location
Software Package Location
Configuration management server
no_copy
Parameter
Omitted or set to False
Set to TrueTarget device
URL
File path including the filename of the software package or packages on the local server running Junos PyEZ.
Filename of the software package or packages.
target device running Junos OS from which the software package is installed.
remote_path Parameterpackage or pkg_set Parameter
(Optional) Path to the directory on the target device to which the package or packages will be copied. Default is /var/tmp.
(Optional) Path to the directory on the target device where the package or packages must already reside. Default is /var/tmp.
URL from the perspective of the
The package argument is used to install software on a single device running Junos OS or on members in a non-mixed Virtual Chassis. The package argument is a string that specifies a single software image. For example:
package = 'jinstall-13.3R1.8-domestic-signed.tgz'
The pkg_set argument is used to install software on the members in a mixed Virtual Chassis. It contains a list or tuple of strings that specify the necessary software images, in no particular order, for the various Virtual Chassis members. For example:
pkg_set=['jinstall-qfx-5-13.2X51-D35.3-domestic-signed.tgz',
'jinstall-ex-4300-13.2X51-D35.3-domestic-signed.tgz']
For packages residing on the local server running Junos PyEZ, when you omit the no_copy argument or set it to False, the server copies the specified software package to the device. Including the package argument causes the server to copy the package to the target device (individual device or primary router or switch in a non-mixed Virtual Chassis), and including the pkg_set argument causes the server to copy all packages in the list to the primary router or switch in a mixed Virtual Chassis. By default, software images are placed in the /var/tmp directory unless the remote_path argument specifies a different directory.
89
If you set the no_copy argument to True, the necessary software packages must already exist on the target device or Virtual Chassis primary device before the installation begins. The packages must reside either in the directory specified by the remote_path argument, or if remote_path is omitted, in the default /var/tmp directory.
Starting in Release 2.1.5, Junos PyEZ supports installing software images from a URL. In this case, the package or pkg_set value must be a URL from the perspective of the target device running Junos OS. The package is copied over and installed from the specified URL, and the no-copy and remote_path arguments are ignored. For information about specifying the format of the URL, see Format for Specifying Filenames
and URLs in Junos OS CLI Commands.

Installation Process Overview

To install a software image on a device running Junos OS, a Junos PyEZ application connects to the individual device or to the primary device in a Virtual Chassis, creates an instance of the SW utility, and calls the install() method with any required or optional arguments. For example:
from jnpr.junos import Device from jnpr.junos.utils.sw import SW
pkg = 'junos-install-mx-x86-64-17.2R1.13.tgz'
with Device(host='router1.example.net') as dev:
sw = SW(dev)
# In Junos PyEZ Release 2.4.1 and earlier, install() returns a Boolean # ok = sw.install(package=pkg, validate=True, checksum_algorithm='sha256')
# In Junos PyEZ Release 2.5.0 and later, install() returns a tuple
ok, msg = sw.install(package=pkg, validate=True, checksum_algorithm='sha256')
print("Status: " + str(ok) + ", Message: " + msg) if ok:
sw.reboot()
For the current list of install() method parameters, see
http://junos-pyez.readthedocs.io/en/latest/jnpr.junos.utils.html#jnpr.junos.utils.sw.SW.install.
If the software package is located on the configuration management server, and the no_copy parameter is omitted or set to False, the install() method performs the following operations before installing the software:
90
Computes the checksum of the local software package or packages using the algorithm specified in the
checksum_algorithm argument, if the checksum is not already provided through the checksum argument. Acceptable checksum_algorithm values are "md5", "sha1", and "sha256". The default is "md5".
Performs a storage cleanup on the target device to create space for the software package, unless cleanfs
is set to False.
SCP or FTP copies the package to the remote_path directory, or if remote_path is not specified, to the
/var/tmp directory, if a file with the same name and checksum does not already reside in the target location on the device.
Computes the checksum of the remote file and compares it to the value of the local file.
After the software package is on the target device, whether downloaded there initially, copied over from the configuration management server by the install() method, or copied from a URL by the target device, the install() method performs the following operations:
Validates the configuration against the new package if the validate parameter is set to True
Installs the package on all Routing Engines unless all_re is set to False
NOTE: Starting in Release 2.1.5, Junos PyEZ, by default, upgrades all Routing Engines on individual
devices and members in a Virtual Chassis. In earlier releases, or if all_re=False, Junos PyEZ only upgrades the Routing Engine to which it is connected.
Starting in Junos PyEZ Release 2.5.0, the install() method returns a tuple that contains the status of the installation and a message string. In earlier releases, the method returns only the status of the installation. The status is True if the installation is successful and False otherwise. The message string provides additional information about the success or failure of the installation and can include informational messages or error messages that are generated by Junos PyEZ or the device. For example:
Package junos-install-mx-x86-64-17.2R1.13.tgz couldn't be copied
The install() method does not automatically reboot the device. To reboot or shut down the device after the installation is complete, call the reboot() or shutdown() method, respectively.
The following video presents a short Python session that demonstrates how to use Junos PyEZ to install Junos OS.
Video: Junos PyEZ - Software Upgrading Device
91

Specifying Installation and Checksum Timeouts

Junos PyEZ performs operations over a NETCONF session. The default time for a NETCONF RPC to time out is 30 seconds. During the installation process, Junos PyEZ increases the RPC timeout interval to 1800 seconds (30 minutes) when copying and installing the package on the device and to 300 seconds (5 minutes) when computing the checksum. In some cases, the installation process or checksum calculation might exceed these time intervals.
To increase the timeout value for the installation process and the checksum calculation, include the timeout and checksum_timeout parameters, respectively, in the call to the install() method, and set them to appropriate values. For example:
from jnpr.junos import Device from jnpr.junos.utils.sw import SW
pkg = 'junos-install-mx-x86-64-17.2R1.13.tgz'
with Device(host='router1.example.net') as dev:
sw = SW(dev)
# Starting in Release 2.5.0, install() returns a tuple instead of a Boolean
ok, msg = sw.install(package=pkg, validate=True, timeout=2400,
checksum_timeout=400)
if ok:
sw.reboot()
NOTE: The checksum_timeout parameter is available starting in Junos PyEZ Release 2.1.4.

Logging the Installation Process

The Junos PyEZ install process enables you to display or log the progress of the installation by including the progress argument in the install() method call. The argument is set to a callback function, which must have a function prototype defined that includes the Device instance and report string arguments. Starting in Junos PyEZ Release 1.2.3, you can also set progress=True to use sw.progress() for basic reporting.
92
The following example prints the installation progress using the myprogress function.
from jnpr.junos import Device from jnpr.junos.utils.sw import SW
def myprogress(dev, report):
print "host: %s, report: %s" % (dev.hostname, report)
pkg = 'junos-install-mx-x86-64-17.2R1.13.tgz'
with Device(host='router1.example.net') as dev:
sw = SW(dev)
# Starting in Release 2.5.0, install() returns a tuple instead of a Boolean
ok, msg = sw.install(package=pkg, validate=True, progress=myprogress)
if ok:
sw.reboot()
The progress output is in the user-defined format.
user@server:~$ python junos-pyez-install.py
Found package. Installing: junos-install-mx-x86-64-17.2R1.13.tgz
host: router1.example.net, report: computing checksum on local package:
junos-install-mx-x86-64-17.2R1.13.tgz host: router1.example.net, report: cleaning filesystem ... host: router1.example.net, report: before copy, computing checksum on remote package: /var/tmp/junos-install-mx-x86-64-17.2R1.13.tgz host: router1.example.net, report: junos-install-mx-x86-64-17.2R1.13.tgz: 38682624 / 386795750 (10%) host: router1.example.net, report: junos-install-mx-x86-64-17.2R1.13.tgz: 77365248 / 386795750 (20%) host: router1.example.net, report: junos-install-mx-x86-64-17.2R1.13.tgz: 116047872 / 386795750 (30%) host: router1.example.net, report: junos-install-mx-x86-64-17.2R1.13.tgz: 154730496 / 386795750 (40%) host: router1.example.net, report: junos-install-mx-x86-64-17.2R1.13.tgz: 193413120 / 386795750 (50%) host: router1.example.net, report: junos-install-mx-x86-64-17.2R1.13.tgz: 232079360 / 386795750 (60%) host: router1.example.net, report: junos-install-mx-x86-64-17.2R1.13.tgz: 270761984 / 386795750 (70%) host: router1.example.net, report: junos-install-mx-x86-64-17.2R1.13.tgz: 309444608 / 386795750 (80%) host: router1.example.net, report: junos-install-mx-x86-64-17.2R1.13.tgz: 348127232 / 386795750 (90%) host: router1.example.net, report: junos-install-mx-x86-64-17.2R1.13.tgz: 386795750 / 386795750 (100%) host: router1.example.net, report: after copy, computing checksum on remote package: /var/tmp/junos-install-mx-x86-64-17.2R1.13.tgz host: router1.example.net, report: checksum check passed. host: router1.example.net, report: installing software ... please be patient ... host: router1.example.net, report: software pkgadd package-result: 0 Output: Installing package '/var/tmp/junos-install-mx-x86-64-17.2R1.13.tgz' ... ...
93

Performing a VM Host Upgrade

On devices that have Routing Engines with VM host support, Junos OS runs as a virtual machine (VM) over a Linux-based host (VM host). A VM host upgrade, which upgrades the host OS and compatible Junos OS, requires a VM Host Installation Package (junos-vmhost-install-x.tgz) and is performed using the request
vmhost software add operational mode command, which corresponds to the <request-vmhost-package-add> RPC.
Starting in Junos PyEZ Release 2.1.6, the sw.install() method supports the vmhost=True argument for performing a VM host upgrade. When the vmhost=True argument is present, the sw.install() method performs the installation using the <request-vmhost-package-add> RPC instead of the <request-package-add> RPC.
The following example upgrades and reboots both the Junos OS and host OS on a single Routing Engine device:
from jnpr.junos import Device from jnpr.junos.utils.sw import SW
with Device(host='switch1.example.net') as dev:
sw = SW(dev)
# Starting in Release 2.5.0, install() returns a tuple instead of a Boolean
ok, msg = sw.install(package='junos-vmhost-install-qfx-x86-64-18.1R1.9.tgz',
vmhost=True, no_copy=True)
if ok:
sw.reboot(vmhost=True)
94
To reboot just the Junos OS software, call the sw.reboot() method instead.

Performing a Unified ISSU or NSSU

Junos PyEZ provides support for performing a unified in-service software upgrade (unified ISSU) or a nonstop software upgrade (NSSU) on devices that support the feature and meet the necessary requirements.
Table 11 on page 94 outlines the Junos PyEZ release in which the unified ISSU and NSSU features are
first supported. For more information about unified ISSU and NSSU, see the software documentation for your product.
Table 11: Junos PyEZ Unified ISSU and NSSU Support
Feature SupportJunos PyEZ Release
Support for unified ISSU and NSSU on dual-Routing Engine devices running Junos OS.2.1.0
2.1.6
Support for unified ISSU during a VM host upgrade for those devices with VM host support that use the request vmhost software in-service-upgrade command to perform a unified in-service software upgrade of the host OS and Junos OS.
The unified ISSU feature enables you to upgrade between two different Junos OS releases with no disruption on the control plane and with minimal disruption of traffic. To perform a unified in-service software upgrade on devices that support this feature, include the issu=True argument in the install() method.
In the the following example, the install() method upgrades Junos OS on both Routing Engines and reboots the new primary Routing Engine (previously the old backup Routing Engine) as part of the installation process. If the installation is successful, the reboot() method then reboots the connected Routing Engine, which is the new backup Routing Engine (previously the old primary Routing Engine).
from jnpr.junos import Device from jnpr.junos.utils.sw import SW
pkg = 'junos-install-mx-x86-64-17.2R1.13.tgz'
with Device(host='router1.example.net') as dev:
sw = SW(dev)
# Starting in Release 2.5.0, install() returns a tuple instead of a Boolean
ok, msg = sw.install(package=pkg, issu=True, progress=True)
if ok:
sw.reboot(all_re=False)
To perform a unified in-service software upgrade on a Routing Engine with VM host support that meets the necessary requirements and supports unified ISSU, include the vmhost=True and issu=True arguments in the install() method. The device upgrades from one host OS and Junos OS release to the requested release using the <request-vmhost-package-in-service-upgrade> RPC.
95
sw.install(package='junos-vmhost-install-qfx-x86-64-18.1R1.9.tgz', vmhost=True, issu=True, progress=True)
The NSSU feature enables you to upgrade the Junos OS software running on a switch or Virtual Chassis with redundant Routing Engines with minimal disruption to network traffic. To perform a nonstop software upgrade on devices that support this feature, include the nssu=True argument in the install() method. For example:
from jnpr.junos import Device from jnpr.junos.utils.sw import SW
pkg = 'jinstall-ex-4300–14.1X53-D44.3-domestic-signed.tgz'
with Device(host='switch1.example.net') as dev:
sw = SW(dev)
# Starting in Release 2.5.0, install() returns a tuple instead of a Boolean
ok, msg = sw.install(package=pkg, nssu=True, progress=True)
if ok:
sw.reboot(all_re=False)

Example: Using Junos PyEZ to Install Software on Devices Running Junos OS

IN THIS SECTION
Requirements | 96
Overview | 96
Configuration | 97
Executing the Junos PyEZ Application | 102
Verification | 102
Troubleshooting | 104
96
Juniper Networks provides support for using Python to manage devices running Junos OS. The Junos PyEZ package provides simple yet powerful methods to perform certain operational and configuration tasks on devices running Junos OS. This example outlines how to use the Junos PyEZ jnpr.junos.utils.sw.SW utility to install or upgrade the software image on a device running Junos OS.
Requirements
This example uses the following hardware and software components:
Configuration management server running Python 2.7 or Python 3.4 or later and Junos PyEZ Release
2.0 or later
Device running Junos OS with NETCONF enabled and a user account configured with appropriate
permissions
SSH public/private key pair configured for the appropriate user on the Junos PyEZ server and device
running Junos OS
Overview
This example presents a Python program that uses the Junos PyEZ SW utility to upgrade Junos OS on the specified device. This example assumes that the image has been downloaded to the local server.
The program imports the Junos PyEZ Device class, which handles the connection with the device running Junos OS; the SW class, which is used to perform the software installation operations on the target device; and required exceptions from the jnpr.junos.exception module, which contains exceptions encountered
when managing devices running Junos OS. The program also imports the os, sys, and logging Python modules for verifying the existence of the software package and performing basic logging functions.
The program defines the update_progress() method, which is used by the install() method to report on the progress of the installation. By logging the installation process, you can more readily identify the point where any failures occur. In this example, progress messages are sent to standard output and also logged in a separate file.
Before connecting to the device and proceeding with the installation, the program first verifies that the software package exists. If the file cannot be found, the program exits with an error message. If the file exists, the program creates the Device instance for the target device and calls the open() method to establish a connection and NETCONF session with the device.
The program creates an instance of the SW utility and uses the install() method to install the Junos OS software image on the target device. The package variable defines the path on the local server to the new Junos OS image. Because the no_copy parameter defaults to False, the installation process copies the software image from the local server to the target device. The remote_path variable defines the path on the target device to which the software package is copied. The default is /var/tmp. Although not required, this example explicitly configures the parameter for clarity.
97
When the install() method is called, the program calculates the local MD5 checksum, performs a storage cleanup and copies the software image to the target device, computes the remote MD5 checksum and compares it to the local value, validates the configuration against the new image, and then installs the package. If the installation is successful, the program then calls the reboot() method to reboot the device.
After performing the installation, the NETCONF session and connection are terminated using the close() method. The program includes code for handling any exceptions that might occur when connecting to the device or performing the installation.
Configuration
Creating the Junos PyEZ Program
Step-by-Step Procedure
To create a Python program that uses Junos PyEZ to install a software image on a device running Junos OS:
1. Import any required modules, classes, and objects.
import os, sys, logging from jnpr.junos import Device from jnpr.junos.utils.sw import SW from jnpr.junos.exception import ConnectError
2. Include any required variables, which for this example includes the hostname of the managed device, the software package path, and the log file.
host = 'dc1a.example.com' package = '/var/tmp/junos-install/jinstall-13.3R1.8-domestic-signed.tgz' remote_path = '/var/tmp' validate = True logfile = '/var/log/junos-pyez/install.log'
3. Define the logging method used within the program and by the install() method.
def update_progress(dev, report):
# log the progress of the installing process
logging.info(report)
NOTE: Starting in Junos PyEZ 1.2.3, you can set progress=True to use sw.progress() for basic
reporting.
98
4. Create a main() function definition and function call, and place the remaining statements within the definition.
def main():
if __name__ == "__main__":
main()
5. Initialize the logger instance.
# initialize logging
logging.basicConfig(filename=logfile, level=logging.INFO,
format='%(asctime)s:%(name)s: %(message)s') logging.getLogger().name = host logging.getLogger().addHandler(logging.StreamHandler()) logging.info('Information logged in {0}'.format(logfile))
6. (Optional) Add code that verifies the existence of the software package.
# verify package exists
if not (os.path.isfile(package)):
msg = 'Software package does not exist: {0}. '.format(package) logging.error(msg) sys.exit()
7. Create an instance of the Device class, and supply the hostname and any parameters required for that
specific connection.
Then open a connection and establish a NETCONF session with the device.
# open a connection with the device and start a NETCONF session
dev = Device(host=host)
try:
dev.open()
except ConnectError as err:
logging.error('Cannot connect to device: {0}\n'.format(err))
return
99
8. Create an instance of the SW utility.
# Create an instance of SW
sw = SW(dev)
9. Include code to install the software package and to reboot the device if the installation succeeds.
try:
logging.info('Starting the software upgrade process: {0}' \
.format(package))
# Starting in Release 2.5.0, install() returns a tuple instead of a Boolean
ok, msg = sw.install(package=package, remote_path=remote_path,
progress=update_progress, validate=validate)
except Exception as err:
msg = 'Unable to install software, {0}'.format(err) logging.error(msg) ok = False
if ok is True:
logging.info('Software installation complete. Rebooting')
rsp = sw.reboot() logging.info('Upgrade pending reboot cycle, please be patient.') logging.info(rsp)
else:
msg = 'Unable to install software, {0}'.format(ok) logging.error(msg)
10. End the NETCONF session and close the connection with the device.
# End the NETCONF session and close the connection
dev.close()
Results
On the configuration management server, review the completed program. If the program does not display the intended code, repeat the instructions in this example to correct the program.
100
import os, sys, logging from jnpr.junos import Device from jnpr.junos.utils.sw import SW from jnpr.junos.exception import ConnectError
host = 'dc1a.example.com' package = '/var/tmp/junos-install/jinstall-13.3R1.8-domestic-signed.tgz' remote_path = '/var/tmp' validate = True logfile = '/var/log/junos-pyez/install.log'
def update_progress(dev, report):
# log the progress of the installing process
logging.info(report)
def main():
# initialize logging
logging.basicConfig(filename=logfile, level=logging.INFO,
format='%(asctime)s:%(name)s: %(message)s') logging.getLogger().name = host logging.getLogger().addHandler(logging.StreamHandler()) logging.info('Information logged in {0}'.format(logfile))
Loading...