Вы находитесь на странице: 1из 175

Junos Automation Series

This Week: Applying Junos Automation

By Curtis Call

SPECIAL EDITION

The special edition of This Week:


Applying Junos Automation is meant for
easy copying and pasting of the
automation scripts and configurations.
Xx's are used to blank out much of the
copyrighted material, and whatever
remains is left for you to find your place
in the material.

By using this special edition, you agree


to use the material in this document at
your own risk. Juniper Networks assumes
no responsibility whatsoever for any
inaccuracies in this document.

© 2011 by Juniper Networks, Inc. All rights reserved. Juniper Networks, the Juniper Networks logo, Junos, NetScreen,
and ScreenOS are registered trademarks of Juniper Networks, Inc. in the United States and other countries. Junose is a
trademark of Juniper Networks, Inc. All other trademarks, service marks, registered trademarks, 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. Products made or sold by Juniper Networks or components thereof might be covered by one or more of
the following patents that are owned by or licensed to Juniper Networks: U.S. Patent Nos. 5,473,599, 5,905,725,
5,909,440, 6,192,051, 6,333,650, 6,359,479, 6,406,312, 6,429,706, 6,459,579, 6,493,347, 6,538,518, 6,538,899,
6,552,918, 6,567,902, 6,578,186, and 6,590,785.

Published by Juniper Networks Books


Editor in Chief: Patrick Ames
Copyeditor and Proofing: Nancy Koerbel
Junos Program Manager: Cathy Gadecki
About the Author
Curtis Call is a Systems Engineer at Juniper Networks. He is JNCIE-M #43 and has eight years experience working with
Junos devices.

Author’s Acknowledgmentsu
The author would like to thank all those who helped in the creation of this book. The literary manager, Patrick Ames
worked with me to find the right outlet for this material and Nancy Koerbel fine-tuned my writing. The Day One Series
Editor Cathy Gadecki was instrumental in bringing this project to fruition and helped me position the content to be
more instructional. Roy Lee, the Junos automation Product Line Manager, reviewed the manuscript several times and
always found ways to clarify the presentation. Thank you all.

NOTE: This book was first published as three separate Day One books in the Junos Automation Series.

This book is available in a variety of formats at: www.juniper.net/dayone.

Send your suggestions, comments, and critiques by email to:dayone@juniper.net.

Be sure to follow this and other Juniper Networks Books on:Twitter: @Day1Junos

Version History: v3 (This Week) January 2011

ISBN: 978-1-936779-16-1 (print)


Printed in the USA by Vervante Corporation.

ISBN: 978-1-936779-17-8 (ebook)

Juniper Networks Books are printed in the USA by Vervante Corporation and are available in bound editions at:
www.vervante.com

2 3 4 5 6 7 8 9 10

iii

Welcome to This Week


This Week books are an outgrowth of the extremely popular Day One
book series published by Juniper Networks Books. Day One books focus
on providing just the right amount of information that you can do, or
absorb, in a day. On the other hand, This Week books explore networking
technologies and practices that in a classroom setting might take several
days to absorb. Both book series are available from Juniper Networks at:
www.juniper.net/dayone.
Xxxx Xxxx xx x xxxxxx xxxxxxx – xxx xxxx xx xxxx xxx xxxx xx xxxx
Xxxxxxx xxxxxxxxx, xxxxxxxxx xxxxx xxxxxxxx xxx xxxxxxxxxxxx – xxx
xxx xxx’x xxxx xxxx xx xxxxxx xxx xxxxxxx xxx xxx xxxxxx-xxxxx
xxxxxxxxx xx x xxxxxxxx xxxxx. Xxxx Xxxx xxxxx xxxxxxx xxxx
xxxxxxxxxxx xxx xxx, xxx xx xxxxx x xxxx’x xxxx, xxx’xx xxxxx
xxxxxxxxx xxxxxxxxxxxxx xxx xxxxx Xxxxx xxxx xxx xxx xxx xx
xxxxxxxxx xxx.
Xxxx Xxxx xxxxx xxx xxxxxxx xx Xxxxxxx Xxxxxxxx xxxxxxx xxxxxx
xxxxxxx xxx xxx xxxxxxxxxxxxxx xxxxxx xxx xxxxxxxxx xx Xxxxxxx
Xxxxxxxx Xxxxx. Xxxx xxx xxxxxxxxx xx xxxxxxxx xxxxxxx, xxxx
xXxxxx xx xxxxx xxxxx xxxxxx, xx xxx xxx xxxxxx xxx xxx xxxx xx xxxx
xxx xxxxxxx Xxxxx, xx xx xx xxx xxxxx xx xx xxxxx xx xxxxxxxx xxxxxx
xx xxxx xxxxxxxxxx xxxxxxx.

What You Need to Know Before Reading


Xxxxxx xxxxxxx xxxx xxxx, xxx xxxxxx xx xxxxxxxx xxxx xxx xxxxx
xxxxxxxxxxxxxx xxxxxxxxx xx xxx Xxxxx xxxxxxxxx xxxxxx. Xxxx
xxxxxxxx xxx xxxxxxx xx xxxx xxxx xxxxxxxxxxx xxxxxxxx xxx xx xxxx,
xxxxxxxxxx, xxx xxxxxx xxx Xxxxx xxxxxxxxxxxxx. Xxxxxxx’x Xxx Xxx
xxxxx (xxx.xxxxxxx.xxx/xxxxxx), xx xxxx xx xxx xxxxxxxx xxxxxxxxx
xxxxxxxxx xx xxx Xxxx Xxxxx xxxxxx, xxx xxxx xx xxxxxxx xxxx
xxxxxxxxxx (xxx xxx xxxx xxxx xx xxxx xxxx xxx xxxxx xxx xxxxx
xxxxxxxxxx).
Xxxxx xxxxxx xxxx xxx xxxx xxxx xxxxxxx xx xxx xxxxxxx xxx xxxxx xx
xxxx xxxx:
„„Having access to a Junos device while reading this book is very
useful. A number of practice examples that reinforce the concepts
being taught are included. Most of these examples require creating
or modifying a script and then running it on a Junos device in order
to see and understand the effect.
„„The best way to edit SLAX scripts is to use a text editor on your local
PC or laptop and then to transfer the edited file to the Junos device
using a file transfer application. Doing this requires access to a basic
ASCII text editor on your local computer as well as software to
transfer the updated script using scp or ftp.
„„While a programming background is not a prerequisite for using this
book, a basic understanding of programming concepts is beneficial.

What This Book Can Do for You


Xxxx xxxx xxxxx xxx xx xxxxxxxx xxxxxxxxxx xxxxx xx xxxx xxxxxxx.
Xx xx xxxxxxx xxxx xxxxx xxxxx:
Part One: Applying Junos Operations Automation
Xxxx xxxx xxxx xx xxxxx xxx xx xxx xxx Xxxxx xxxxxxxxxx xxxxxxxxx
xxxxxxx xxx xxx xx xxxxx xxxx xxxxx xxxxxxxxx xxxxxxx. Xxxx xxx’xx
xxxx xxxx xxxx xxxx, xxx’xx xx xxxx xx:
„„Understand how the Junos automation tools work.
„„Explain where to use the different Junos script types.
„„Use reference scripts from this book and Juniper’s script library.
„„Interpret the XML data structures used by Junos devices.
„„Communicate with Junos through the Junos XML API.
„„Ease how you write XML data structures using the SLAX XML
abbreviated format.
„„Read SLAX scripts and understand the operations they perform.
„„Create your own customized operation scripts.
Part Two: Applying Junos Event Automation
Xxxx Xxx xxxxx xxx xx xxxxxxxx xxxxxx xxxxxx xx xxxx xxxxxxx. Xxx
xxxx xxxx xx xxxxx xxx xx xxx xxx Xxxxx xxxxxxxxxx xxxxxxxxx
xxxxxxx xxx xxx xx xxxxx xxxx xxxxx xxxxx xxxxxxx. Xxxx xxx’xx xxxx
xxxx xxxx xxxx, xxx’xx xx xxxx xx:
„„Understand the difference between an op script and an event script.
„„Identify potential events that could be automated.
„„Build the needed event policy to match desired events and
conditions.
„„Correlate multiple events and determine the proper response to
those events based on their relationship to each other.
„„Create your own customized event scripts.
Part Three: Applying Junos Configuration Automation
Xxxx Xxxxx xxxxx xxx xx xxxxxxxx xxx xxxxxx xxxxxxx xx xxxx Xxxxx
xxxxxx. Xxxx xx xx xxxxx xxx xx xxx xxx Xxxxx xxxxxxxxxx xxxxxxxxx
xxxxxxx xxx xxx xx xx xxxxx xxxx xxxxx xxxxxx xxxxxxx. Xxxx xxx’xx
xxxx xxxx xxxx xxxx, xxx’xx xx xxxx xx:
„„Understand the role of and possible uses for commit scripts.
„„Provide feedback as part of the commit process through warning or
syslog messages.
„„Halt the commit process with error messages.
„„Alter the configuration through commit scripts.
„„Use configuration macros to simplify your configuration or to store
specialized data.
„„Create your own customized commit scripts
iv

Chapter 1: Introducing Junos Automation 9


8 This Week: Applying Junos Automation

Xxxxxxxx xxxxxxxx xxxxxxxx xx xxxxxxx – xxxxxxxxx xxxxxx xxxxxx,


xxxx xxxxxxxxxxxx, xxx xxxxxxxxx xxxxxxxxxxx. Xxx xxxxxxxx
xxxxxxxxxxxxx xxxxxxx xxxx xx xx xxxxxxxx xx xxxxxxxxxx, xx xxxx
xxxxxxxxxxxx xxxx xx xxxxxxx xxx xxxx xxxxxxxx. Xxxx xxxxxxxx
xxxxxxxx x xxxxxxxxx xx xxxxxxx xxxxxxxxx xxx xxxx xxx xxxxxxxxxx
xx xxx xxxxxxxxxxxxx xxx xxxxx xxxx xx xxxx xxxxx xxxxxxxx xx
xxxxxx xx xxxxxxxx xx xxxxx xx xxxxxxxx xxxxxxxxx xxxxx xxx xxxxxxx
xxxxxx.
Xxxxxxxxx Xxxxx xxxxxxx xxxxxx x xxxxxxx xxx xxxxxx xxx xxxxx xx
xxxxxxxxxx xxxx xxxxx xxxxxxxxx xx xxxxxxx. Xxxx xxxxxxx xxxxx
xxxx xxx xxxxxxx xx xxx xxx xxxx xxxxxxxxx xxxxxx xx xxxxxxx
xxxxxxx, xxxxxxxx, xxx xxxxxxxx xxxxxxx. Xxxxxxx xx xxxxxx xx xxxxx
xxxxx xx xxxxxxx xxxxxxxx xxxxxxxxx xxxxxxx xxx xxxx xxxx xx
xxxxxx, xxxx x xxxxxx xxxxxxxxx xxxxxx xxx xx xx xxxxxxx xxx
xxxxxxxxxx. Xxxx xxxxxxxxx xxx xxxxxxx xxxxxxxxxx xx xxx xxxxxxx.
Xx xx xxxxxxxxxxxx xxxxxxxxx xx xxxx xxxx Xxxxx xx xxxx xxxxx x
xxxxxxxxx xxxxxxxxx xx xxxx xxxxxxxxx xxx xxxxxxx xxxxxxx.
Xxxxxxx xx xxxx xxxxxxxxxxx xxxxxxxxxx xxxxx xxxxxx xx xxxxxxxxx
xx xxxx xxx xxxxxxx xxx xxxxxxxxx. Xxxxxxx xx xxxxx xxxxxxxxxxxxx
xxxxxx, xxxxx xxxxxx xxxxx, xxx xxxxx xxxxxxxxxxxxxxx xxxx xxxxx
xxxx xxxxxxxxx xx xxx xxxxxxxxxxxx’x xxxxxxxx xxxxxxxxx xxx xxxx
xxx xx xx. Xxxxx Xxxxx xxxxxxxxxx. Xx xxxxxx xxxxxxxxxxxxx xx
xxxxxxxx xxxxx xxxxxx xxxxxxxxxxxx xxxxxxx xxxxxxx xxxx
xxxxxxxxxxxxx xxxxxxx Xxxxx xxxxxxx xxxxxxxxx xx xxx xxxxxxx xxxx
xxxxxxxxx.
Xxxxx xxxxxxxxxx xx x xxxxxxxx xxxx xx xxx Xxxxx xxxxxxxxx xxxxxx
xxxxxxxxx xx xxx Xxxxx xxxxxxx, xxxxxxxxx xxxxxxx, xxxxxxxx, xxx
xxxxxxxx xxxxxxx. Xxxx xxxx xxxxxxxxxx Xxxxx xxxxxxxxxx xxx
xxxxxxxxxxxx xxx xx xxxx xxxxxxxxx xx xxx xxxxxxxxx. Xx xxxx
xxxxxxxx xxx xx xxx xxxxxxxxx xxxxxxx, xxx xxxx xx Xxxxx xxxxxxxxxx
xxxxxx.
Xxxxx xxxxxxxxxx xxxxxxx xx xxxxxxxxxxxx xx xxxxx xxx xxxxxx xx
xxxxxxxxx xxx xxxxxxxxxx xx xxxxxxxxxx xxxxxxxx xxxx xxx Xxxxx
xxxxxxx:
„„Business rules automation: compliance checks can be enforced.
Change management can help to avert human error.
„„Provisioning automation: complex configurations can be abstracted
and simplified. Errors can be automatically corrected.
„„Operations automation: customized commands and outputs can be
created to streamline tasks and ease troubleshooting.
„„Event automation: responses can be pre-defined for events allowing
the device to monitor itself and react as desired.

What Junos Automation Can Do


Xxxxx xxxxxxxxxx xx x xxxxxxxx xxxxx xx xxxxx xxx xxxxxxxxxx xxx
xxxxxxx xxx xxxxxxxxxx xx xxxxxxxxx x xxxxxxx. Xxxxxxxxxx xxx xxx
xxxx xxxx xxxx xxxx xxxx, xx xxxx xxxxx xx xxxxxxxxx xxxx
xxxxxxxxxxx xxxxxxxxx xx xxx xxxxxxx xxx xx xxxxxx xxxxxxx xxxxx xx
xxx xxxxxxx xx xxxxxxxxxxx xxxxxxx xxxxx. Xxx xxxx xxxx xxx xxx
xxxxxxxx x xxxxxxxx xx xxx xxxxxxxx xxxx xxxxxx xxx Xxxxx xxxxxxx-
xxxx, xxxxxxx xxxxxxx xxx xxxxxx xxxxxxx, xx xxxx xx xxxxxxxx xxx
xxxxxxxx xx xxxxxxx xxxxxx. Xxxxx xxxxxxxx xxxxx xxxxx xx
xxxxxxxxxx xxxxxxx, xxxx xxxxxxxxx xxxxxxxxx xxxxx xx
xxxxxxxxxxxxx xxx xxxxxxxxxx:
„„Operation (op) scripts instruct Junos of actions to take whenever the
script is called through the command-line or by another script.
„„Event scripts instruct Junos of actions to take in response to an
occurrence in a monitored set of events.
„„Commit scripts instruct Junos of actions to take during the commit
process of activating configuration changes.
MORE? To see examples of each type of script go to the online script library at
www.juniper.net/scriptlibrary.

Operation (Op) Scripts


Xxxx xxxx xxxxx xxx xx xxxxx xxxx xxxxx xx xxxxxxx. Xx xxxxxxx xxx
xxxx xx xxxxxxxxxxx xxxx xx xxxxxx xxxxxx xxxxxxxx xxx xx xxxxxx
xxxxxxxxxxxxxx. Xxxx xxxxxxx xxxxxxxx xxxxxx xxxx, xxxxxx xx xx
xxxxxxxx xxx xxxxxx xxxxxx x xxxxxxx xxxxxxx xx xxx XXX xx xxxx
xxxxxx xx xxxxx xxxxxx (xxx xxxxx).
Xxxxxx xxxx xxxx xxxxxxxx xxx xxx xxxx xxxxxx xxxx xx xx xxxxxxx. Xx
xx xxxxxx xxxxxxx xxx xxxx xxxxxxxxx xxxxxxx xxxx xxxx xxxxxxxx
xxxx xxxxxxxx, xxxxxxxxx xx, xxx xxxx xxxxxxx xxx xxxxxxx
xxxxxxxxxxx xx xxx xxxxxx.
Xxxxxxx xxxxxx xxxx xx xx xxxxxx xx xx xxxxxxxxx xxxxxxxxxxxxx
xxxxxx. Xxxxx xx xxxxxxx xxxxxxx xxxxxxxxxx xxxxxxxxxxxxx xxxxxxx
xxxxx xx xxxxxxxx xxxxx xxxx xxxxxxx xxxx xxxxxxxxx, xxxxxxxxxxx
xxxxxxx, xx Xxxxx xxxx xxxxxxxx. Xxx xxxxxxxxx xx xxxx xxxxxxxx xx
xxxx xxx xxx xxxx xxx xxxxxxxxx xx xxx xxxxxx xxxx xxx xxxxxx
xxxxxx. Xxxx xxxxxxxxx xxxxx xxxxx xxx xxxxxx xxxxx xxxx xxxx
xxxxxxxxx xxx xxxxxxx xx xxxxxx xxx xxxxxxxxxxxxx xx xxxxxxxxxx
xxxx.
Xxx xxx xxxx xxxxxx xx xxxxxxx xx xxxxxxxxxxx xxxxxx xxx xxxxxxxxx
xxxxx xx xxxxxxx xxxxxxxx. Xxxxx xxxxxxx xxx xx xxxxxxxxxxx xxxx
xxxxxxx, xxxxxxx xxx xxxxxx, xxxxxxxxx xxx xxxx xxxxxxxxxxx xxxxxx,
xxx xxxxxx xxx xxxxxxx xxxxx xxx xxxxxx xx xxx xxxxxxx xx
xxxxxxxxxx xxx xxxxxxxx xx xxx XXX. Xx xxxxxxx xxx xxxxxxx xxxx
xxxxxxxxx x xxxxxxx xxxxx xxxx xx xxxxxxxxx xxxxxxxx xxxxxx
xxxxxxxxxxxxxxx.
Xx xxxxxxxxxx xxx xxxx xxxxx, xx xx xxxxx xxxxxxx xxxxxxxxx xx
xxxxxxx xxxxxxx xxx xxxx xx xxxxxxxx xxxxxx, xx xxxxxxx xxx xxxxx
xxx xxxx xx xxxxxxxxxx. Xxxxx xxxxxxx xxxxxxxxx xx xxxxxxx xxxxxx
xx xxxxxx; xx xx xxx xxxxxxxx xxx xx xxxxxxxxxx xxxx xx xxxxx xxxxx
xxxxxxxxxx x xxxxxxx xxxx xxxxxxxxxx xxxxx xxxx x xxx xxxxxxx xx
xxxxxx.
Event Scripts
Xxxxx xxxxxxx xxx xxxxxxxxx xxxxxxxxxxxxx xx xxxxxxxx xx xx xxxxx
(xx xxxxxx) xxxx xx x xxxxxx xxxxxxx, XXXX xxxx, xx xxxxx. Xxx xxx
xxx xxxxx xxxxxxx xx xxxxxx xxxxxxxxxxxxxxx xxxxxxxxxxx xx
xxxxxxxx xx x xxxxxx xxxxx, xx xx xxxxxxxxxxxxx xxxxxx xxx
xxxxxxxxxxxxx xxx xx xxxxxxxxxx xxxxxxx xx xxx xxxxxxx xxxx xx xxx.
X xxxxxxx xxxxx xxxxxx xxxxxxxxxxx x xxxxxxxx xxxx xx: “Xx
xxxxxxxxx X xxx XXX X xx xxxx, xxxxxxx xx xxxxxx XXX xxx xxx x
xxxxxxxxxx xxxxxxx.” Xx xxxxxxxx xxx xxxxxx xxxxxxxxx xx xxxx
xxxxxxxxxxxx—xxxxxxx xxxxxxxxxx xxxx xxxxxx xxxxxxxxx xxxxxxxx
xxxx xx x xxxx xxxx xxxxx, xxxxxxx xxxxxxx, xx xxxxxx xxxxxxxx—
xxxxxxxxxx xxxxx xxx xxxxxxx xxxx xxxxxxx xxxx xxxxxxxxxx xxxxxxx.
Xxx xxxxx xxxxxxx xxxx xx xxxxxxxxxx xxx xxxxxx. Xxxx xxx xxxxx
xxxxxxx xx xxx Xxxxx xxxxxxxxx xxxxxx xxxxxxxx xxxxxx, x xxx xx
xxxxx xxxxxxx xxx xxxxxxxx xx xx xxxxxx xxx xxxxxxxxx xxxxxxxx
xxxxxx. Xx xxxxx xxxxxx xxx xxxx xxxxxxx x xxx xx xxxxxxx, xxxx xx
xxxxxxxx x Xxxxx xxxxxxx xx xx xx xxxxxx, xxxxxxxx x xxx xxxx xxxx
xxx xxxxxxx xxxxxx, xxx xxxxxxxxx xxx xxxx xx x xxxxx xxxxxxxxxxx.
Xx xxxx xxx, xxxxxxxxx xxx xxxxxx xxxxxxx xxx xxxxxx xx xxxxxxxxxx
xxxxxx xxxx xxx xxxxx xxxxxxx xxxxxxxxxx. Xxxxx xxxxxxx xxx xx
xxxxxxx xxxx xxxxxxxx xx xxxxxxxx xxxxx xxxxxxx xxxxxxx xxxx xxx
xxxx xxxxxx xxxxxxxx xxxxxxxx, xxx xxx xxxx xxxx xxxxxxxxx xxxxx xx
xxxxxxx xxxxxx xxxxxxxxxx. Xx xxxxxxxxx xxxx xxxxxxxx xxxxxxxx
xxxxxxxxxxx xxxxxx xxx xxxxxx xxxxxx, xxxxxxxxxx xxxxxxx xxx xxxx
xxxxxxxxxx xxxxx xxxx xxxxxxx xxxxxxx.
MORE? After you learn about scripting basics in this book, download Day One:
Automating Junos Operations to learn more about using op and event
scripts. Check for availability at www.juniper.net/dayone/.

Commit Scripts
Xxxxxx xxxxxxx xxxxxxxx Xxxxx xxxxxx xxx xxxxxx xxxxxxx xx
xxxxxxxxxxxxx xxxxxxx. Xxxx xxx xxxx xxxxxxxx x xxxxxx xxxxxxxxx,
Xxxxx xxxxxxxx xxxx xxxxxx xxxxxx xx xxxx, xxxxxxx xxx xxxxxxxxx
xxxxxxxxxxxxx xxxxxxx xxx xxxxxxx xxxxxx xxxxxxx. Xxxx xxxxxx xxx
xxxxxx xx xxxx xxx xxxxxx xxxx xxxx-xxxxxxx xxxxxx xxx xxxxxxx, xx
xxxxxxx xxxxxxxx xx xxx xxxxxxxxxx xxxx xx xxx xxxxxxx, xx xxx
xxxxxxxx xx xxx xxxxxx, xx xx xxxxxx xxx xxxxxxxxxxxxx
xxxxxxxxxxxxx. Xx xxxxxxxx, xxx xxxxx xxx x xxxxxx xxxxxx xx
xxxxxxx xxxxxxxx xxxx xxxxxxxxx xxx xxxxxx xxxxxxxxx, xx xxx x
xxxxxxxxx xxxxxxx xxxxxxxxxxxxx.
Xxx xxxx xxxxx xx xxxxxx xxxxxxx xxxxxxx xxxxxxx xxxx xxxx xxx xxxx
xx xxxxxx. Xxxxxx xxxxxxx xxxxxxxx xxx xxxx xx xxxxxxx
xxxxxxxxxxxxxx xx xxxxxx xxxxx xxxxxxxxxxxxx xxxxxxxxx xx xxxxx
(xxxx xx xxx xxxxx xxxxxxxxx, xxx XXX XX, xxx xxx Xxxx XX), xxx xxxx
xxxxx xxxxx xx xxxxxx x xxxxxxxx xxx xx xxxxxxxxxxxxx xxxxxxxxxx
(xxxx xx x XXXX xxxxxxxxx). Xx xxxxxxxx xxxx xxxxx xxxx xx
xxxxxxxxx xxxxxxxxx, xxxxxx xxx xxxxxx xxxxxxxxxxx xx xxx
xxxxxxxxxxxxx xx x xxxxxxxxxx xxxxxxxxx, xxxxxxxx, xxx. xxxxxx xxx
xxxxxxx.
MORE? Download Day One: Automating Junos Configuration to learn more about
using commit scripts. Check for availability at www.juniper.net/dayone.

How Junos Automation Works


Xxxxx xxxxxxxxxx xxxxxxx xxxxxxx x xxxxxxxxx xxx xx xxxxx (xx
xxxxxxxxxxx xxxxx) xxxx Xxxxx xxxxx xxxx xx xxxxxxxxx xxx xxxxxx.
Xxxxx xxx xxxxxxx xxxx xxxxx xxxxxxx xxxxxxxxxxxx xxxxxxxx xx
xxxxx x xxxx xx xxx xxxxxx xxxxxxxxxxxxx. Xxxx xxxxxxxxxxxx
xxxxxxxxx xxxxx xxxx xxx xxxxxxxxxx xx xxx x xxxxxx xx xxx xxxxxx
xxxxxxxxxxxxx.
Xxxxxx 1.1 xxxxxxxx xxx xxxxx xxxx xx xxxxxx xxxxxxxxxx. Xxxxx
xxxxxx xxxxxxx xx xxxxxxxxxxxxx /xxx/xx/xxxxxxx/ xxxxxxxxxxx. Xxxxx
xxxxxx xxx xxxxxxxxxx xx x xxxxxx xx x xxxxxx xx x xxxxxxx, xxxxxxx
xx xxx xxxx xx xxxxxx. Xxx xxxxxxx, xxx xxxxxxx xxx xxxxxxxxxx xxx
xxxxxx xxxxxxx xx xxx xxxxxx xxxxxxx xx xxxxxxxxxxxxx xxxx. X xxxxxx
xxxxxx xxxxxx xxx xxx Xxxxx xxxxxxxxx xxxxxx xxxx xxxxxxxxx xxx
xxxxxx xxxx-xx-xxxx, xxxxxx xxx xxxxxxxxx xxxxxxx. Xxxxx xxxxxxx
xxx xxxxxxx xxxxxxxx xx xxxxx Xxxxx xxxxxxxxx. Xxxx xxx xxxxxx
xxxxxx xxxxxxxxx xxx xxxxxxxxxx xx xxx xxxxxx, xx xxxxx xxx xxxxxxx
xx xxx xxxxxx xxxxxxxxx xx xxx xxxxxx.

Figure 1.1 The Flow of Script Processing

NOTE The script engine uses XML (eXtensible Markup Language) to read the
script and communicate with other Junos processes. The management
process daemon, known as mgd, of the Junos operating system includes
the primary script engine for processing scripts. The event process
daemon, known as eventd, also includes a script engine for monitoring
events. The Configuration and Diagnostic Automation Guide includes
further details about how Junos processes scripts. Find the guide along
with other Junos documentation at www.juniper.net/techpubs/.

Scripting Languages
Xxxxx xxxxxxxxxx xxxxxxx xxx xx xxxxxxx xx xxxxxx xx xxx xxxxxxxxx
xxxxxxxxx: XXXX xx XXXX. XXXX xx x xxxxxxxxxxxx xxxxxxxx xxxxxxxx
xx xxxxxxx xxx XXX xxxxxxxx xxxx xxxxxxx. Xxxxx XXXX xxx xx xxxx xx
xxxxx Xxxxx xxxxxxxxxx xxxxxxx, xxx xxxxxxxx xxxxxxx xx xxxxxxxx
xxxxxxxxxx xxx xxx xxxx xxxx xx’x xxxxxxx xx XXX xxxxx xx x xxxx
xxxxxxxxxxx xxxxxx xxx xxxx xxxxxx.
NOTE XSLT stands for eXtensible Stylesheet Language Transformations. SLAX
stands for Stylesheet Language Alternative syntaX.
Xxxxxxx xxxxxxxxxx xxxxxxx XXXX xx xxxxxxx x xxxx xxxx-xxxxxxxx
xxx xxxxxxxxx xxxxxx xx xxxxx xx xxxxx Xxxxx xxxxxxx xxxx XXXX.
XXXX xxx x xxxx xxxxxxxx xxxxxx. Xxx, xx xxxxx xxxx xxxxxxx xx
xxxxxx xxx xx xxxxxxxx xxxx xxxxxxx Xxxxx xxxxxxxxxxxxxx xx
xxxxxxx xxxxxxxx xx xxx X xx Xxxx xxxxxxxxxxx xxxxxxxxx.
Xxxx xxxx xxxxxxx xxxxxx xx xxxxxxxx xxx XXXX xxxxxxxx, xx XXXX
xxxxxxxxx xx xxx xxxxxxxxx xx xxxx xxxxxxxxx xx Xxxxx xxxxxxxxxx.
MORE? For more on how to use XSLT to write Junos scripts, see the Configuration
and Diagnostic Automation Guide at www.juniper.net/techpubs/.

Using Junos Automation with Other Systems


Xxxxx xxxxxxxxxx xxxxxxxxxxx xxxxxxxx xxxxxxx xxxxxxxxxx xxxxxxx.
Xxxxxxxx xxxxxxx xxxxx xxxxxxxxxxx xxxxxxxx xxx xxxxxx xxxxxxxxxx,
xxxxxxxxxxxx, xxx xxxxxxxxxx, xxx xxxxx xxxxxxxxxx xx xxxxxxx xxxx
xx xxxxx xx xxxxxxxxx xxx xxxxxxxxxx xxxxxxxxxxxxx xxx xxxxxxx
xxxxxxxx.
Xxxxxxxxx xxxxxx xxxxxxxxxx xxxxxxx xxx xxxx xxxxxxxx xxxxxxxx
xxxxx xxx xxxx, xx xxxxx xxxxxxxx xxxxxxx xxxxxxxxxxx xxxxx xxxxxx
xxxxxxxxxx xxxxxxxxxx, xx xxxxxxx xxx xxxxxx xx xxxxxxxxxx
xxxxxxxxx. Xxxxx xxxxxxxxxx xx xxxxxx xx xxxx xx xxxxxxxx
xxxxxxxxx, xx-xxx xxxxxxx xxxxxxxxx xxx xxxxxxxxxx. Xxx xxxxxxxxxx
xxxxxxx xxx xxxxxx xxxxxxxxx, xxxxxx xxxxx xx xxxxxxxxx xxxxxx, xxx
xxxxxx xxxxx xx xxxxxxxx xxxxxx.
TIP Building on the Junos automation toolset, Juniper Networks Advanced
Insight Solutions (AIS) introduces intelligent self-analysis capabilities
directly into platforms running Junos. AIS provides a comprehensive set
of tools and technologies designed to enable Juniper Networks Technical
Services with the automated delivery of tailored, proactive network
intelligence and support services. For more information visit the Juniper
Networks services web page at http://www.juniper.net/us/en/products-
services/technical-services/j-care/.

XML Basics
Xxxxx xxxxxxxxxx xxxxxxx xxxxxxxxxxx xxxx xxxxx xxxx xxxxxx xxxxx
xxx XXX xxxxxxxx. Xxxxx xx’x xxxxxxxx xx x xxx xxxxx, x xxxxx
xxxxxxxxxxxxx xx xxx XXX xx xxxx xx xxx Xxxxx xxxxxxxxx xxxxxx xx
xxxxxxx x xxxxxxxxx xxxxx xxxx xx xxxxxxxx xxx xx xxxxx Xxxxx
xxxxxxx. Xxxx xxxxxxx xxxxx xxx xxxx xxx xxxxx XXX xxxxxxxxxx xxxx
xxx xxxx xxx xxxxxxx xxxx xxx xxxxxxx.
Xxxxxxxxxxx, xxx XXXX xxxxxxxx xxxxxxx xxxxxxxxxx xxx xxx xxxxx
xxx xxxx XXX xxxx xxxxxxxxxx. Xxx xxxx xxxxxxx xxxxxxxx xxx XXXX
xxxxxxxxx xxx xxxxxxxxx XXX xxxx xxxxxxxxxx xxx xxxxxxx xxxx xx
xxx.

Displaying XML
Xxx xxxxxxx Xxxxx XXX XXX (Xxxxxxxxxxx Xxxxxxxxxxx Xxxxxxxxx)
xxxxxxxx xxxxxxx xxx Xxxxx xxxxxxx xx xxxx xxxxxxxx. Xxxxx
xxxxxxxx xxx xxxxxxxx xxxxx Xxxxx xxxxxxxxx xx xxxxxxxx xxxxxxxxxx
xxxx xx xxxxxxx xxxxxxxx xxxxxxx (xxx Xxxxxx 1.1). Xxxxx xxxxxxxx
xxx xxxxxxxxx xxxxxxxxx xxx xxxxxxx xxx XXX xxxxxxx xx xxx xxxxxx
xxxxxx xxx xxxxxxx xxxxxxxxxx xx xxx xxxxxx.
Xx xx xxxxxxx xx xxx XXX xxxxxxx xxxx x Xxxxx xxxxxx xxx xxx, xxxx x
xxxx xx xxx xxxxxxxxxxxxx xxxxx xxxxxxxxx xx XXX xxxx:
user@Junos> show configuration routing-options | display xml
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/9.6I0/junos">
<configuration junos:commit-seconds="1238100702" junos:commit-localtime="2009-03-
26 13:51:42 PDT" junos:commit-user="user">
<routing-options>
<route-distinguisher-id>192.168.1.1</route-distinguisher-id>
<autonomous-system>
<as-number>65535</as-number>
</autonomous-system>
</routing-options>
</configuration>
<cli>
<banner></banner>
</cli>
</rpc-reply>

Xx xxxxx xxxxxx xxxx xxxxxx xxx xxxxxx xxxxxxxxx, xxx xxx xxxxxxxxx
xxxxxxxxx xxxxx xx xxxxxx xx xxxxxxxxxx. Xxxxxx xxx xxx-xxxxx
xxxxxxxxx xx xxx xxxxx xxxx xx xxxxxx. Xxxx xxxxx xxx xxxxxx xx x
xxxxx xxxx Xxxxx xxxxxxxxx xxx xxxxxxxxx XXX xxxx.
Xxx xxxx xxxx xxxxxxxxx xxxx xxxx xx xxxxxxxxxxxxx xxxxxxxxxxx,
xxx xxx xxxxxxxxx xxxx xxxxxx xxx xxxxxxxx xxxxxxx-xxxxxxx
xxxxxxxxxxxxx xxxxxxxxx. Xxxx xx xx x xxxxxx xxxxxxxxxxxxx, xxx
xxxxxxx-xxxxxxx xxxxxxxxx xxxxxxxx xxx xxxxx-xxxxxxxxxxxxx-xx xxx
xxxxxxxxxx-xxxxxx xxxxxxxxxxxxxx. Xxx XXX xxxx xxxx xxx xxxx
xxxxxxxxxxxx xxxxxxxx, xxxxxx xx xxxx xx xxxxxxxxxx xxx xxxxxx xx
xxxxxxx xxxxxxx xxx xxxx xxxxxxxxxxxxx.
Xxx xxxxxx xxxxx xxxxxxxx xxxxxxxx xx xxx xxxxxxxx xxxxxxxxx xx
xxxxxxxxxx xxx xx xxxxxxxxxxx xxxxx xxx Xxxxx XXX XXX: xxxxxxxx,
xxxxxxxxxx, xxxxxxxxxx, xxx xxxxx.

Try It Yourself: Viewing Junos Configuration in XML

Show the following configuration hierarchy levels in XML on a Junos device:


(e.g. show configuration system | display xml)
[system]
[interfaces]
[protocols]

Elements
Xx xxxxxxx xx xxx xxxxx xxxx xx xxxxxxxxxxx xxxxxx xx XXX xxxx
xxxxxxxxx. Xxxxxxxx xxx xxxxxxx xxxx xxxx xx x xxxx xxxxxx xx
xxxxxx, xx xxxx xxx xxxxxxx xxxxx xxxxxxxx. Xx xxxxxxx xxxx
xxxxxxxx xxxxxxx xxxxxxx xx xxx xxxxxx xx xxx xxxxxxxx xxxxx
xxxxxxx. Xxxxxxxx, xxx xxxxx xxxxxxx xx xxx xxxxx xx xxx xxxxxxxxxx
xxxxxxx. Xxxx xxxxxxx x xxxxxxxxx, xxxxx xx xxxxxxxx xx xxx XXX
xxxxxxxxx, xxxxxxx xx xxx xxxxxxxx Xxxxx xxxxxxxxxxxxx xxxxxxxxx.
Xxxxxxxx xxx xxxxxxx xx xxxxx xxxxx xxx xxx xxxx xxxx xxxxxxx xxx
xxxxxxxxxx xx xxx xxxxxxx. X xxx xxxxxxxx xxx xxxxxxx xxxx xxxxxxxx
xxxxxx < > xxxxxx. Xxx xxxxxx xxxxx xxxxx xxxxxxxx xx xxxx, xxxx xx
<xxxxxxx-xxxxxxx>, x xxx xxx xxx xxxxxxx-xxxxxxx xxxxxxx. Xxx xxx-xxx
xxxxx <xxxxxxx-xxxxxxx> xxxxx, xxxx xx xxx xxxxx xxx xxx xxxx xx
xxx xxx xxx.
Xxx xxx xxxx xxxxxx xxx xxxxx xxx xxx xxxx xx xx xxxxxxx’x xxxx. Xxxx
xxxx xxxxxxx xxx xxxxxxx xxxx; xxxxxxx, xxx xxx xxx xxxx xxxxxxxx x /
xxxxxx xxx xxxx, xxx xxxxxxx </xxxxxxx-xxxxxxx>. Xx xx xxxxxxx xx
xxxxx, xxxxxxx xx xxx xx xxxx xx xxxxx xxxxxxxx, xxxx xx xxx xx
xxxxxxxxx xxxxx x xxxxxx xxx xxxx x / xxxxxxxxx xxx xxxxxxx xxxx,
xxx xxxxxxx <xxxxxxxxx/>.
Xxxx xx xx xxxxxxx XXX xxxxxxxxxxxxx xxxxxxxxx xxxxxxx xxxx
xxxxxxxx xxxxxxxx:
<interfaces>
<interface>
<name>ge-0/0/0</name>
<disable/>
</interface>
</interfaces>
Xxx <xxxxxxxxxx> xxxxxxxxx xxx xxxxxx xxxxxxx xx <xxxxxxxxx>, xxxxx
xx xxx xxxxxx xxxxxxx xx xxx <xxxx> xxx <xxxxxxx> xxxxxxxx. Xxx <xxxx>
xxxxxxx xxxxxxxx xxx xxxx xxxx xx-0/0/0. Xxx <xxxxxxx> xxxxxxx,
xxxxxxx, xxxxxxxx xx xxxx xx xxxxx xxxxxxxx. Xxxx xx xxx xx xx
xxxxxxxxx xx xx xxxxx xxx xxxxxxx xx x xxxxx xxx xxx xxx xxxx. Xxx
xxx xxxxxxxx xx xxx XXX xxxx xxxxxxxxx xxxxxxxxxxxx xxxx xxxx
xxxxxxxxx xxx xxxx xxxxxxxx.

Attributes
Xxxxxxxx xxx xxxxxxx xxxxxxxxxx xxxxxxxxxxx xx xxx xxxx xx
xxxxxxxxxx. Xxxx xxxxxxxxxxx xx xxxxxxxxx xx xxxxxxxxx xxx
xxxxxxxxx xxxx xxx xxxxx xxxxxx xxx xxxxx xxx:
user@Junos> show configuration routing-options | display xml
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/9.6I0/junos">
<configuration junos:commit-seconds="1238100702" junos:commit-localtime="2009-03-
26 13:51:42 PDT" junos:commit-user="user">
<snip>

Xxxx xxx <xxx-xxxxx> xxx <xxxxxxxxxxxxx> xxxxxxxx xxxx xxxxxxxxxx


xxxxxxx. Xxx xxxxxxx, xxx <xxxxxxxxxxxxx> xxxxxxx xxx xxxxx
xxxxxxxxxx: xxxxx:xxxxxx-xxxxxxx, xxxxx:xxxxxx-xxxxx-xxxx, xxx xxxxx:xxxxxx-
xxxx. Xxxx, xxx xxxxx xxxxxxxxxx xx xxx <xxxxxxxxxxxxx> xxxxxxx
xxxxxxx xxxxxxxxxx xxxxxxx xxxxx xxx xxxx xxxxxx.
XXX xxxxxxxxx xxx xxxxxxxxx xxxxx xx xxxxxxxxx xx xxxxx xxxx (=)
xxxxxxxxx xxx xxxxxxxxx xxxx xxx xxxxxxxxx xxx xxxxx xxxxxx
xxxxxxxxx xxxxx xx xxxxx xxxxx. Xx xx xxxxxxx xxx xxxxxxxx
xxxxxxxxxx, xxxx xxx xxxxxxxx xxxxxx xxx xxxxx xxx xxxxxxxxx xx
xxxxxx.

Namespaces
Xx xxx xxxx xxxxxxx xxx xxxxx xxxxxxxxxx xxxxxxx xxx xxx
<xxxxxxxxxxxxx> xxxxxxx xxx xxxxxxx xxxx xxx xxxx xxxx. Xx xxxx xxxx
xxx Xxxxx xxxxxxx xx xxx xxxxxxxxx xxxx xxxxxxxx x xxxxxxxx xxxxxxx:
xx xxxxxxxxx xxx xxxxxxxxx xx xxx xxxxxxxxx.
SHORT CUT A namespace prevents confusion between elements using the same
name for different purposes. For example, there could be a commit-seconds
attribute used by multiple computing devices, but when it is included in
the Junos namespace it becomes junos:commit-seconds. What the attribute
indicates is now explicitly known.
Xxxx xxxxxxxxx, xxx Xxxxx xxxx xx xxxxxxxx x xxxxxxxxxxx xxx xxx
xxxx xxxxxxxxx, xxxxx xx xxxx://xxx.xxxxxxx.xxx/xxxxx/9.6X0/xxxxx. XXX xxxx x
XXX xxx xxxxxxxxxx xx xxxxxx xxxx xx xxxxxx xxx xx xxxxxxx
xxxxxxxxx xxxxxxxxxx. Xxxxxxxxxxx XXX xxx XXXX xxxxxxx xxxx xx
xxxxxxxx xxx xxxxxxxxxx xx XXXx xx xxxxxxxxxx.
Defining a Namespace
Xxxxxxx xxx xxx xxxx XXX-xxxxx xxxxxxxxx xxx xxxxx xxxxxxxxx xx
xxxxxxx xxx xxxxxx xxxxxx xxxxxxx xxx xxxxxxx. Xxx xxxx xxxxxx XXX
xxxxxxx xxx xxxxxxxx xx x xxxxxxxxxxx:
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/9.6I0/junos">

Xxx xxxxxx xxxxxxxxx xx <xxx-xxxxx> xxxxxxxx x xxxxxxx xxxxxxx. xxxxx


xxxxxxx x XXX xxxxxxxxx. Xxx xxxxxxx xxxxxxxx xxxx xxx
xxxx://xxx.xxxxxxx.xxx/xxxxx/9.6X0/xxxxx xxxxxxxxx xx xxx xxxxxxxxx xx Xxxxx.
Xxxx xxxxxxxxxx xxxxx xxxxxx xxx xxx <xxx-xxxxx> xxxxxxx xxx xxx xx
xxx xxxxx xxxxxxxx.
Using Namespaces in SLAX
Xxxxx xxxxxxx xxxxxxxxxx xxx xxx xx xxxxxxxxxx xxxx xxxxxxx xxxx
XXXX xxxxxxx. Xxxxxx xxxx xxxxx xxx xxxxx Xxxxx xxxxxxx (9.6 xx xxx
xxxxx xxxxxxx), Xxxxx xxxxxxxx xxx xxxxxxx xxxxxx xxxx x * xxxx
xxxxxxxxx xxx XXX xxxx xxxxxxxxx xx xxx xxxxxx. Xx xxxx xxx x
xxxxxx xxx xx xxxxxxx xxxxxxx xxxxxxxxx xx xxx xxxxx xxxxxxxxx xxxx
xx xxx Xxxxx xxxxxx.
Xxxx xxxx xxxxxxxxxxxxxx, xxx xxxx xxxxx xxxx x XXXX xxxxxx xxxxxx
xxxx xxxxxx xx xxx xxxxxxxxxx xxxxxxxxx xxx:
1. Copy the standard boilerplate (explained in Chapter 2) into the
script.
2. Prepend the namespace placeholder (junos, jcs, xnm, etc.) correctly to
the element or attribute name (if they have been assigned a
namespace).

Nodes
Xxxx XXXX xxxxxx x XXX xxxx xxxxxxxxx xx xxxxx xx xx x xxxx xx
xxxxx. Xxxxx xxxxxxx, xxxxxxxxx, xxx xxxx xxxx xxxxxxx x xxxxxxxx
xxxx xx xxx xxxx. Xx xx xxxxxxx, Xxxxxx 1.2 xxxxx xxx XXXX xxxxx
xxxxxxxx xxx xxx xxxxx xxx xxx xxxxxxxxx xxxxxxxxxxxxx:
<interfaces>
<interface>
<name>ge-0/0/0</name>
<disable/>
</interface>
</interfaces>

Figure 1.2 SLAX Tree of Nodes Example

Xxxx xxxx xxxx xxxx xx Xxxxxx 1.2 xx xx xxx xxxxxxx xxxxxxxxxxxx


xxxxxxxx xx xxx xxxx. Xx XXXX, xxxxx xxxx xxxx xxxxxxxx x xxxx xxxx
xx xxx xxxx, xxxxxxxxxxxx xxxx xx xxxxxxxxx, xxxx xxx xxxxxx
xxxxxxxxx xx Xxxxxx 1.2 xx /. Xxxx xxx xxxx xxxxxxx xxxxx xxxxxx
xxxxxxxxx xx xxxxx xxxxxxxxx. Xxxxxx, x xxxx xxxx xxxxx xxx xxxx
xxxxxxxx xx xxx <xxxx> xxxxxxx. Xxxx xxx XXX xxxx xxxxxxxxx
xxxxxxxxx xx xxxx xxxx, xx xx xxxxxxxx xx xxxxxxxx xxx xxxx xxxx
xxxxxx xx xxxxx, xxx xxxx xxxxxxx xx xxxxxxx, xx xxxxx xx xxxxxxxx
xxx xxxxxxxxx xxxx.
MORE? For more details on XML you can look at http://www.w3schools.com/xml/.
It is one of many online XML tutorials.

SLAX Abbreviated XML Format


Xxxxxxx xxxx XXX xxxx xxxxxxxxx:
<interfaces>
<interface>
<name>ge-0/0/0</name>
<disable/>
</interface>
</interfaces>

Xx xxx xxxxxx xxxxxxxxxxxxx xx xxxxxxxxxx:


interfaces {
ge-0/0/0 {
disable;
}
}

Xxx XXX xxxx xxxxxxxxx xx xxxxxx xx xxxx xxx xxxx xxxx-xxxxxxxxx xx


xxxxx. Xxxxx XXX’x xxxxxxxxx xxxxx xx xxxx xxxxxxxxxx xxx xxxxxx
xxx xxxxxxxxxxxx xxxx, xxx xxxxxx xx xxx xxxxx xx xxxx xx xxxxxxxx
xxxxx. Xxxx xxxxx xxxx xxx xxxxxxxxx xx xxxxx xxxxx xxx xxx xxxx xxx
xxxx xxxxxxx.
Xxx XXXX xxxxxxxx xxxxxxxxx xxxx xx xxxxxxxxxxx xxxxxx xx
xxxxxxxx XXX xxxx xxxxxxxxxx. Xxxx xxxxxx xx xxxx xxxxxxxxx xxxx
xxx Xxxxx xxxxxxxxxxxxx xxxxx:
<interfaces> {
<interface> {
<name> "ge-0/0/0";
<disable>;
}
}

Xxxx xx xxx xxxx XXX xxxx xxxxxxxxx xx xxxxx xx xxx XXX xxxxxx
xxxxxxx, xxx xx XXXX xx xxxxxxx xxxx xxxxxxx xx xxx xxxxxx
xxxxxxxxxxxxx xx xxxxxxxxxx. Xxxx xxx xxxxxxxxxx xxxxxxx xxx
xxxxxx xxxxxxxxxxxxx xxxx xxx xxx xxxxxxxxxxxxxx xx xxx XXXX
xxxxxxxxxxx XXX xxxxxx: xxx xxxxxxxxxx xxx xxxxxxxxxxxxx xxxxxxx
xxxxxxx xx xxx xxxxx xxxxx xxxxxxx xxxxxx xx xxxxxxx xxxxxx <xxxx>.
Xx xx xxxxxxx, xx-0/0/0 xx xxxxxxxx xx xxx <xxxx> xxxxx xxxxxxx xx
xxx <xxxxxxxxx> xxxxxxx xx xxx XXXX xxxxxx.
Xx xxxxxxx xxx xxxxxxxxxxxxxx, xxx XXXX xxxxxxxxxxx XXX xxxxxx
xxxx xxxx xxx xxxxx xxxx; xxx xxx xxxx xxx xx xxxxxx xxxxxxxx.
Xxxxxxx, XXXX xxxxxxxxx xxx xxxxxxxx xx xxx xxxxxxx xx xxx xx xxxxx
xxxx:
„„If the element contains child elements then curly braces { } contain
the child elements (the same method used to indicate hierarchy in
Junos).
„„If the element contains data then the data is written within
quotation marks (" ") and the line is terminated with a semi-colon (;)
(similar to Junos configurations).
„„A single start tag terminated by a semi-colon (;) represents empty
elements with no children or text data.

Try It Yourself: Writing XML in the SLAX Abbreviated Format


Rewrite the following configuration using the SLAX abbreviated XML format:
system {
host-name r1;
login {
message "Unauthorized access prohibited.";
}
}
Chapter 2: Writing Your First Script 19
18 This Week: Applying Junos Automation

Xxxxx xxxxxxxxxx xxxxxxx xxx xxxxxxxx xxxx xxxxxxxxx xxxxx xx


Xxxxx. Xxxx xxxxxxx xxxxxxxx xxx xxxxx xxxxxxx xx xxx xx xxxxx x
xxxxxx, xxxx xx xx x Xxxxx xxxxxx, xxx xxxxxx xx xx xxx
xxxxxxxxxxxxx.

Hello World
Xxx xxxxxxxxxxxxx xx xxxx xxxxx xx xxxxxx xx xxxx xxxxxx: xxxx xxx,
xx xxxxxxxx xxx xxxx “Xxxxx Xxxxx!” xx xxx xxxxxxx. Xx xxx xxx xx
xxxxxx, xx xxxxxxxxxxxxx xxxxxx xxxxxx xxx xxxxxx xxxx xxxx xx xxx
XXX xxxxxx. Xxx xxxxxxxx xxxx xxx xxx Xxxxx Xxxxx xxxxxx xxxxxxx:
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match / {
<op-script-results> {
<output> "Hello World!";
}
}
Xxxx xx xxx xxxxxx xxxxx xx xxx Xxxxx Xxxxx xx xxxxxx:
user@Junos> op hello-world
Hello World!

How to load and run the Hello World op script:

Xx xxx xxxx xx xxxxxx xx x xxxxxx, xxxx xxx xxxxxxxxx xxxxx.


1. Save the code into a text file called hello-world.slax.
ALERT! All SLAX script filenames must end with the .slax extension.
2. Copy the script file into the /var/db/scripts/op directory on the Junos
device.
3. Before you can run the script, you must enable it within the Junos
configuration. Explicit configuration is a security precaution that
prevents unauthorized scripts from being executed on the Junos device.
Only super-users, users with the all permission bit, or users that have
specifically been given the maintenance permission bit are permitted to
enable or disable Junos scripts in the configuration. The command to
enable an op script is set system scripts op file <filename>. So for the
Hello World op script, enter:
set system scripts op file hello-world.slax

NOTE Devices with multiple routing-engines must have the script file copied
into the /var/db/scripts/op directory on all routing-engines. The script
must be enabled within the configuration of each routing-engine as well.
Typically this configuration is done automatically through configuration
synchronization. However, if the configurations are not synched, then the
configuration must be entered manually into all routing-engines.
4. Execute the script with the op command followed by the script file
name (without the .slax filename extension). For example:
user@Junos> op hello-world
SLAX Syntax Rules
Xxx XXXX xxxxxxxxx xxxxxxxx xxx x xxx xx xxxxx xxxxxx xxxxx.
Xxxxxxx 1 xxxxxxxx xxxx xx xxxxx xxxxx xx xxx xxxxxxx xx XXXX
xxxxxxxxxxx XXX xxxxxx. Xxxxx Xxxxx xxxxxxx xxxxxxx XXX xxxxxxxx
xxx xxxx xxxxxxxxxx, xxxxxxx xxxx xxxxxx xxxxx xxxxxxxx xxxxxxxxxx
xxxxx.
Xxx xxxx xx xxx XXXX xxxxxx xxxxx xxx xxxx xxxxxxx xx xxx Xxxxx
xxxxxxxxxxxxx xxxxxx xxxxx. Xxx xxxxxxx, xxxx xxxxxx xxx xxxx
xxxxxxxxxxx xxxxxx XXXX xxxxxxx xxx xxxx xx xxx xxxx xxxxxx xx xx
Xxxxx xxxxxxxxxxxxx, xxx xxx xxxxxxxxxx xx xxxxxxx xxx xxxxxxxx xx
XXXX xx xxxx xxxxxxxxxx xx Xxxxx.

Code Blocks
X Xxxxx xxxxxxxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxxx xxx xxx xx xxxxx
xxxxxx { }:
interfaces {
interface ge-0/0/0 {
disable;
}
}

Xx xxx xxxxx xxxxxxx, xxx xxxxxxxxxx xxxxxxxxxxxxx xxxxxxxxx


xxxxxxxx xxx xxxxxxxxx xx-0/0/0 xxxxxxxxx, xxxxx xxxxxxxx xxxxxxx.
Xxx xxxxxx xxxxxxxxxxxx xxxxxxxxxxxx xx xxxxxxx xxxxxxx xxxx xxx
xxx xx xxxxx xxxxxx.
Xxx XXXX xxxxxxxxx xxxxxxxx xxxxxxx x xxxxxxx xxxxx, xxxxxxxxx
xxxxxxxx xxxx xxxxxx xxxxxx xxxxx xxxxxx xx xxxxxxxx xxxxx
xxxxxxxxx xxx xxxxxx. Xxxxxx xxxx xxxxxxx xx xxx xxxxxxxxxxxxx
xxxx xxx Xxxxx Xxxxx xxxxxx:
match / {
<op-script-results> {
<output> "Hello World!";
}
}

Xxxxx xxxxxx xxxxx xxx xxxxx / xxxx xxxxx. Xxxx xxxxxxxx x xxxxx
xxxxxxxx xxxxxxxxxx xxxxxxx xxxxx xxx xxxx xxxxx xxxxxx, xxxxx xx
xxxxx, xxx xxxx xxxx xx xxxxxxxx.

Line Termination
Xxx xxxxxxxxx xxxxx xxx xxxx x xxxx-xxxxx:
version 1.0;
ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
import "../import/junos.xsl";

Xxxx xx xxxxx xx xx xxxxxxx xx xx xxxxxxxxxx xxxxxxxxx. Xxxxxxxxxx


xxxxxxxxxx xxx xxx xxxx xx x xxxx-xxxxx. XXXX xxxxxxxxxx
xxxxxxxxxx xxxxxxxxxx xxxx x xxxx-xxxxx (xxx xxxx xx xx Xxxxx
xxxxxxxxxxxxx). Xxx xxxx-xxxxx xxxxx xxx xxxxxx xxxxxx xx Xxxxx
xxxx xxx xxx xx xxx xxxx xxx xxxx xxxxxxx.

String Values
X xxxxxx xx x xxxxxxxx xx xxxx xxxxxxxxxx. "Xxxxx Xxxxx!" xxx
"../xxxxxx/xxxxx.xxx" xxx xxxxxxxx xx xxxxxxx xx xxx Xxxxx Xxxxx xxxxxx.
Xxxxxxx xxxx xxxxxx xxxxxxx xxxxxx xxxxxx xxxxxx xxxxxx. Xx xxxx
xxx xxx xxxxxx xxxxxx xxxxx xxxx xxx xxxx xx xxxxxxxx xx x xxxxxx
xxxxx.
Xxxx xxxxxx xx xxxx xxxxxxx xx xxx Xxxxx xxxxxxx xxxxxxx xx x
xxxxxxxxxxxxx. Xxx xxxxxxxxxx: xx x Xxxxx xxxxxxxxxxxxx, xxxxxxxxx
xxxxx xxx xxxxxxxxx xxxx xxxxxxxx xxxx xxx xxxx xxxxxxxx x xxxxx;
xxxxx xx x XXXX xxxxxx, xxxxxxxxx xxxxx xxx xxxxxx xxxxxxxx
xxxxxxx x xxxxx xx xxxxxxx xx xxx.
NOTE SLAX allows the use of either single quotes ‘String Value’ or double
quotes “String Value”, but the character used to open the string must
also be used to close it.

Adding Comments
Xxx xxxxxxx xxx xx xxxxxxxx xxxxxx x xxxxxx xx xxxx xxxxxxx xxx
xxxxxx xxxxxxxxxxx. Xxxxxxxx xxxxxxx xxxxxxx xxxx xxx xxxxx xx xxx
xxxxxx xxx xxx xxxxxxxxxxxx xx xx xxxxxxx xxxxx. Xxxx xxx xx
xxxxxxxxxx xx xxxxx xxxx xxx xxx xxxxx xxx xxxxxx xxx xxx
xxxxxxxxxx xxxx xxx xxxxxx xxxxxxxxx xxxx xxxxxxxxxx xx. Xxxxxxxx
xxx xxxx xx xxxxxx xxx xxx xxxxxx xxxxxx xxx xxxxx xxxx xx xxxxxx
xxx xxxxxx xxxxxx xxxxx.
Xxxxxxxx xx XXXX xxxxxxx xxx xxxxxxx xxxxxx xxx xxxxxxxxxx /* xxx */
xxxx xx:
/* This is a comment. */
Xxxx xxxxxx xx xxxxxxx xx xxx xxxxxxxx xxxxxx xx x Xxxxx
xxxxxxxxxxxxx xxxx xxxxxxxxxxxxx xxxxxxxx xxx xxxxxxxxx.
NOTE In Junos comments are indicated in two ways, either within /* and */ or
following a #. SLAX scripts only support the delimiters /* and */.
Xxxxxxxx xxx xx xxxxxxxx xxxxxxxx xxxxxx xxxx xxxxxx:
match / {
<op-script-results> {
/* Display this string on the console */
<output> "Hello World!";
}
}

Xxxxxx xxxxx-xxxx xxxxxxxx xx xxxxxxxx xxx xxxxxxxxxxx */ xx x


xxxxxxxx xxxx xxxx xxx xxxxxxxx /*:
/*
* This is a simple script which outputs "Hello World!" to the console.
*/

Try It Yourself: Adding Comments to the Hello World Script

Make the following modifications to the Hello World script:


1. Add a multi-line comment at the beginning that describes the purpose of the script.
2. Add an additional comment before the <output> “Hello World!”; line to state that it is writing
to the console.
After making the two modifications, replace the prior version of hello-world.slax on your Junos
device with the new version. Execute the script again and verify that the new comments did
not change the operation.

Understanding the Result Tree


Xxxxx xxxxxxxxxx xxxxxxxx x xxxxxxxxxxxxx xxxxxx xx xxxx xxxxxxx
xxx xxxxxxxx Xxxxx xx xxxxxxx xxxxxxx xxxxxxx. Xxx xxxxxxx, xxx
Xxxxx Xxxxx xxxxxx xxxxxx Xxxxx xx xxxxxxx “Xxxxx Xxxxx!” xx xxx
xxxxxxx. Xx xxx Xxxxx Xxxxx xxxxxx, xxx <xxxxxx> xxxxxxx xxxxxx
xxx xxxxxx xxxx xxxxxxxx xxxx xxxxxxx.
Xxxxx xxx xxxxxx xxxx xx xxx xxxxxxxx xxx xxx x xxxxxx xx xxxxxxx
xxxxxxxxxxxx xxx Xxxxx. Xxx xxxxxx xxxx xx x XXX xxxx xxxxxxxxx
xxxxxxx xx xxx xxxxxxxxxx xx xxx xxxxxx xxx xxxxxxxxx xx xxx xxxxxx
xxxxxx xxxxx xxx xxxxxx xxxxxxxxxx. Xxxxxx xxxxxxxxx, xxx xxxxxx
xxxxxxxxx xxx XXX xxxxxxxx xx xxxxxxx xx xxx xxxxxx xxxx. Xxxx xxx
xxxxxx xxx xxxxxxxx, Xxxxx xxxxxxx xxx xxxxxxxxxxxx xx xxx
xxxxxxxxx xxxxxx xxxx.
Writing to the Result Tree
Xxxxxxx xx xxx xxxxxx xxxx xxxxxx x xxxxxx xx xxxx. XXX xxxxxxxx
xxx xxxxxx xxxxxxxx xxxxxx xxx XXXX xxxxxx xx xxx xxxxxxxxxxx XXX
xxxxxx. Xxxx xxx xxxxxx xxxxxx xxxxxxx xx x xxxx xxxx xxxxxxxx xx x
XXX xxxxxxx xx xxxxxxxxxxxxx xxxxxxxx xxxx xxxxxxx xxxx xxx xxxxxx
xxxx.
NOTE Some XML elements take effect within the script itself and are not
written into the result tree. These are special purpose elements such as
<xsl:sort> and <xsl:message>. They constitute the exception to the
rule; typically all embedded XML elements are written to the result tree.
Xxxxxxxxxx xxxxx xxxxx xxxxxxx xxx xxxxxx xxxx xx xxx Xxxxx Xxxxx
xxxxxx:
match / {
<op-script-results> {
<output> "Hello World!";
}
}

<xx-xxxxxx-xxxxxxx> xx xx XXX xxxxxxx xxxx x xxxxx xxxxxxx xx


<xxxxxx>. Xxxx xxx xxxxxx xxxxxx xxxxxx xxxxxxxxx xxx xxxxxx xx
xxxxxxx xxxx XXX xxxx xxxxxxxxx, xxxxxxxxxx xxxxx xx XXX xxxxxxxx,
xxx xxxxxx xxxx xx xxx xxxxxx xxxx xx:
<op-script-results> {
<output> "Hello World!";
}

Xxx xxxxxx xxxxxxx xx xxx xxxxxxx xxxxx xx <xx-xxxxxx-xxxxxxx>.


Xxxx xx xxxxxx xxx xxx-xxxxx xxxxxxx xx xx xx xxxxxx xxxxxx xxxx.
Xxxx xxxxxxx xxxxxxxxx xx Xxxxx xxxx xxxxxxxxxxxx xxx xxxxxx xxxx
xx xx xxxxxx. Xxxxx xx xx xxxxxx xxxxxxxxx xx xxx <xx-xxxxxx-
xxxxxxx> xxxxxxx, xx xxxxxx xxxxxxxx xxx xxxxx xxxxxxxx. Xx xx xxx
xxxxx xxxxxxxx xxxx xxxxxxx xxxxxxxxxxxx xxx Xxxxx xx xxxxxxx.
Xxx <xxxxxx> xxxxxxx xx xxx xxxx xxxxxx xxxxxxx xxxxx xx xxx
xxxxxx xxxx xx xx xxxxxxx. Xx xxx xxxx xxxxxxx, xx xxxxxxx xx
xxxxxxxxxx xxxxxx. Xxxxxxxxxxxx, xx xxxxxxxxx Xxxxx xx xxxxxxx xxx
xxxxxx xx xxx xxxxxxx xxxxxxxx xx x xxxx-xxxx. X xxxxxx xxx xxxxxxx
xxxxxxxx <xxxxxx> xxxxxxxx, xxxx xxxx xxxxxx xxxxxxxxx xx x
xxxxxxxxx xxxx:
<op-script-results> {
<output> "Hello World!";
<output> "I’m Home!";
}

Xxxxxxx xx xxx xxxxxxxxx xxxxxx:


Hello World!
I’m Home!

NOTE If you wish to include line-feeds within your text string then use the \n
escape character: <output> “First Line\nSecond Line”;

Try It Yourself: Adding Additional Output to the Hello World Script

Modify the Hello World script by adding two additional lines of output to the console above the
“Hello World!” string.
Replace the prior version of hello-world.slax on your Junos device with the changed version.
Execute the script again and see the effect the new <output> elements have on the script
output.

Importing Script Code


Xxx Xxxxx Xxxxx xxxxxx xxxxxxx xxxxxxxx xxx xxxxxxxxx xxxx:
import "../import/junos.xsl";
Xxxx xxxxxxxx xxxxxxxxx xxxxx xxx xxx xxxx xxxx xxx
/xxx/xx/xxxxxxx/xxxxxx/xxxxx.xxx xxxxxx xxxx xxxx xxxx xx xxxxxx
xxxxx xx xxxxxxxxx. Xxxxxxxxx xxxxxx xxx xxx xx xxxxxx xxxx xxxxxx
xxxxxxxx xxxxxxx xxxxxxx xxxxxx xx xxxx xxx xxxxx xxx xxxxxx xxxx
xxxx xxx xxxxxx xx xxx xxxxx. Xxx xxxxx.xxx xxxxxx xxxx xx xxxxxxxx
xx xxxx xx xxx xxxxxxxx Xxxxx xxxxxxxxxxxx. Xx xxxxxxxx xxxxxxx
xxxxxxxxx xxx xxxxxxxxxx. Xxxx xxxxxxx xxxxxx xxxxxx xxxxxxx xxx
xxxxx xxxx xx xxxxxx xxxx xxxx.
MORE? For information on the contents of junos.xsl see The Configuration and
Diagnostic Automation Guide at www.juniper.net/techpubs/.

The Main Template


Xxxx xxxxxxx x xxxxxx, xxx xxxx xxx xxxxxx xxxx xxxxxxxx xxxx xx
xxxxxxxx xxxxxx x xxxx xxxxxxxxx xxxxx xx x xxxxxxxx. Xxxx xxx
xxxxxx xxxxxx xx Xxxxx xxxxx xxxxxxxx x xxxxxx, xx xxxxxxxx xxx
xxxxxx xxxx xxx xxx xxxx xxxxxxxx. Xxx xxxxxx xxxxxx xxxx xxxxxx
xxxxxxxxx xxx xxxxxxxxxxxx xxx xxxxxxx xxx xxxxxxxx xxxxxx xxxx
xxxxxxxx. Xxx xx xxxxxxx, xxx xxxx xxxxxxxx xx xxxxx /.
Xxxx xx xxx Xxxxx Xxxxx xxxxxx xxxxx: xxx xxxxxxxx xx xxx xxxxx /
xxxxxxxx, xxx xxxxx xxxxxx { } xxxxxxxxx xxx xxxx xxxxx, xxx xxx XXX
xxxxxxxx xx xxx xx xxx xxxxxx xxxx xxxxxxxx xxxxxx xxx xxxxx.
match / {
<op-script-results> {
<output> "Hello World!";
}
}

Using the Op Script Boilerplate


Xxxx xxxxxxx Xxxxx xx xxxxxxx, xxxx xxxx xxx xxxxxxxx xxxxxxxxxxx:
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match / {
<op-script-results> {

/* Your script code goes here */

}
}

Xxx xxxxxxxxxxx xxxxxxxxxx xxxxxx xxxxxxx xx xxxxxxxxx xxx xxxxxx


xxxx-xxxxx XXXx (xxx Xxxxxxx 1) xxxxx xxxx xxxxx xxxxxxxxxx. Xxxx
xxx xxxxx xxx xxxxxxxxxxx xxx xxx xxxx xxxxxx xxxx xxxxxx xx. Xxx
xxxxxxxxxxx xxxxxxxx xxx xxxxxxxxx xxxxxxxxxx:
„„version: while version 1.0 is currently the only available version of
the SLAX language, the version line is required at the beginning of
all Junos scripts.
„„ns: a ns statement defines a namespace prefix and its associated
namespace URL. The following three namespaces must be included
in all Junos scripts:
ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
It is easiest to just copy and paste these namespaces into each new
script as part of the boilerplate rather than trying to type them out by
hand:
„„import: the import statement is used to import code from one script
into the current script. As the junos.xsl script contains useful default
templates and parameters, all scripts should import this file. The
import “../import/junos.xsl”; line from the boilerplate is all a script
needs to accomplish this.
„„match /: this code block is the main template of the op script. In the
standard boilerplate it includes the <op-script-results> result tree
element.
Xxx xxxxxxxxxxx xxxxxxxx xxx <xx-xxxxxx-xxxxxxx> xxxxxxx xx xxxxxxxx
xxxxxxx xx xx xxxxxxx. XXXX xxxxxxxxxx xxx xx xxxxxxxx xxxxxx xxx
<xx-xxxxxx-xxxxxxx> xxxx xxxxx xxxxxxx xxxxxxxxxxx xxxx xxx xxxxxxx
xxxxxx xxxx. Xxx xxxxxx xxxxxx xxx xxxxxxxxxxxxx xxxxxxx
xxxxxxxxxx xx xxxxxxx xxx XXX xxxxxxxx xx xxx xx xxx xxxx.

Try It Yourself: Writing Your Own Script Using the Boilerplate

Using the configuration boilerplate, create a new op script that outputs three separate lines of
text to the console. Copy this script to your Junos device and enable it. Now you can verify it
by executing it from the command-line.

Chapter 3: Understanding SLAX Language Fundamentals 27


26 This Week: Applying Junos Automation

Xxxxxxx 2 xxxxxxx xxx xxxxxx xxxxx xx xxx XXXX xxxxxxxxx xxxxxxxx


xx xxxx xx xxx xxxxxxxxxxx xxxx xxxx xxxxxxxx x xxx xx xxxxxx. Xx
xxxx xxxxxxxx xxx Xxxxx Xxxxx xx xxxxxx xxx xxxxxxxxxxxx xxx xx
xxxxx xxxx xx xxx xxxxxxx. Xxxx xxxxxxx xxxx xxxxxx xxxx xxx
xxxxxxxxxxxx xx xxx XXXX xxxxxxxx xxx xxxxxxx xxxxxxxx xxx
xxxxxxxxxxxx.
„„The jcs, xnm, and junos namespaces are reserved. Do not use any of
these namespaces when creating variables, parameters, elements,
or templates.
„„Do not start any names with "junos".

Xxxxx xxx xxxxxxxxx xxxxx xx xxxxxxxxxx, xxxx xxx xxxx xxxx


xxxxxxxxx xxxx xxx xxxx xxxxxxx xxxxxxx xx Xxxxx xxxxxxxxxxxxx
xxxxxx xxxxxxxxx xx xxxx xx xx xxxxxxxx Xxxxx xxxxxxx.
„„Write variables, parameters, elements, and templates entirely in
lowercase.
„„Separate multiple words with a dash ( - ), for example: gig-interface.

Variables
Xx xxx XXXX xxxxxxxx, x xxxxxxxx xx x xxxxxxxxx xx xx xxxxxxxx
xxxxx. Xxx xxxxxxxx xxxx xx xxxx xxxxxx xxx xxxxxx, xxx xxx xxxxxx
xxxxxx xxxxxxxxxxx xxx xxxxx xx xxx xxxxx xxxx xx xxxxxxxx xxx
xxxxxx. XXXX xxxxxxxxx xxx xxxxxxxxx; xxxx xxxxxx xx xxxxxxx. Xxxx
xxxxx xxxx xxxxxxx xx xxxxx xxx xxx xxxxxxxxxx xx xxxxx xxxxxxxxxxx
xxxxxxxxx, xxx xx XXXX xxxxxxxxx xxxxxx xxxxx xx xxx xxxxx xx xxxxx
xxxx xxxx xxxxx xxxxxxxx.

Data Types
Xxxxx xxx xxxx xxxx xxxxx xxxxxxx xx xxx XXXX xxxxxxxxx xxxxxxxx:
„„string: a sequence of text characters, for example “Hello World!”.
„„number: numbers are stored as floating points so decimals are
permitted.
„„boolean: used for conditional operations; evaluated as either true or
false.
„„result tree fragment: a portion of the result tree. By default, all XML
elements that are embedded in a script are written to the result
tree. It is possible, however, to redirect this XML data to a variable
instead. The variable stores the data as an unparsed XML data
structure, as such no additional data can be extracted from it. The
script can only use the unparsed data to write to the result tree later
or to convert to a node-set or string.
„„node-set: an unordered set of XML nodes. A node-set consists of
parsed XML data, so information can be extracted from it. Typically,
node-sets are the result of a query to Junos for information, a
location path, or a converted result tree fragment.

Declaring Variables
Xxxxxxxxx xxx xxx xxxxxxxx xxxxx xxx xxx xxxxxxxxx. Xxxxxxxx xxxxx
xxx xxxxxx xxxxxxxx xx x xxxxxx xxxx:
var $example-string = "Example";

Xxx xxxx xxxx xx xxx xxxxxxxx xx xxxxxxxxxxxxx xxxxxxxxxx xxxxx xx


xxx xxxxxxxx xxxxx. Xxxx xxx xxxxxxxx xx xxx xx xxxxxxx xxxxxxxxx
xx xxxx xx xxx xxxxxxxxx xxxx xxxxx:
„„string: var $example-string = "Example";

„„number: var $example-number = 15;

„„boolean: var $example-boolean = ( 15 == 15 );

„„result tree fragment:var $example-rtf = { <system> { <host-


name> "R1"; } }
„„node-set: var $example-node-set = jcs:invoke(“get-interface-information”);

BEST PRACTICE To allow your scripts to be compatible with future Junos script
functionality, always follow these rules when naming variables,
parameters, elements, and templates.

Using Variables
Xxxx xxxxxxxx, x xxxxxx xxx xxx xxx xxxxxxxx xx xxxxxxxxx xxx
xxxxxxxxxxx xxxxx. Xxxx xxxxx xxxxxxxxx xxxxx xxxx xxxx-xxxxxxxxx
xxxx xxxx xx xxxx, xxxxxxxxx xxx xxxxxxxxx xxxxxx xxxx:
match / {
<op-script-results> {
var $router-name = "R1";
<output> $router-name;
}
}

Xxx xxxxx xxxxxxx xxxxx xxx xxxx xxxxxxxx xx xx xx xxxxxx. Xxxx


xxxxxx xxxxxxxx x xxxxxxxx xx $xxxxxx-xxxx xxxx x xxxxxx xxxxx xx “X1”
xxxxxxxx xx xx. Xxx xxxxxx xxxx xxxxxxxx xxxx xxxxxxxx xx xxx
xxxxxxx xx xxx <xxxxxx> xxxxxx xxxx xxxxxxx xxxx xxxxxx “X1” xx xxx
xxxxxxx.

Scope of Variables
Xxxxxxxxx xxx xxxx xxxxxx xxxxxx x xxxxxxx xxxxx. X xxxxx xx xxx
xxxx xxxxxxxxx xx xxxxx x xxxxxxxx xx xxxxxxxx. Xxxx xxxxxxxx xxx
xx xxxx xxxxxx xxx xxx xxxxx, xx xxxx xx xx xxxxx xxxxxxxx xxxxxx
xxxx xxxx xxxx xxxxxx xxx xxxxxxxx xxxxx.
Xxx xxxxxxxxx xxx xxx xxxx xxxxx xx xxxxxx xxx xxxxxxxxx:
„„global variable: refers to any variable declared outside of all
templates. Global variables can be referenced anywhere within the
script.
„„template variable: refers to variables defined within templates, such
as the main template, and have a scope of only their own template.
Template variables cannot be used outside of their own template.
NOTE The script code can declare variables of the same name both globally
and within a template, but only one or the other is usable at a time. The
template variable overrides the global variable within the template that
assigns the template variable.
Xxxx xxxxxxxx xxxxxx xxx xxxx xxxxxxxx. Xx x xxxxxxxx xx xxxxxxxx
xxxxxx xxx xxxx xxxxx xx xxxxxx xx xx xx xxx-xxxx xxxxxxxxx (xxxxx xxx
xxxxxxxxx xxxxx), xxxx xx xx xxxx xxxxxx xxxxxx xxxx xxxx xxxxx; xx
xxxxxx xx xxxxxxxxxx xxxxxxx xx xx.

Global Variables
Xxxx xx x xxxxxxxxx xx xxx Xxxxx Xxxxx xxxxxx xxxxx xxx xxxxxx xx
xxxxxxx xx x xxxxxx xxxxxxxx:
/* hello-world.slax */
version 1.0;
ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
import "../import/junos.xsl";

/* This is a Global Variable */


var $first-string = "Hello World!";

match / {
<op-script-results> {

/* This is a variable with template scope */


var $second-string = "Goodbye World!";

/* Output both variables to the console */


<output> $first-string;
<output> $second-string;
}
}

Xx xxx xxxxx xxxxxxx, xxxx xxx xxxxxx xxxxxxxx $xxxxx-xxxxxx xxx xxx
xxxxxxxx xxxxxxxx (xxxxxxxxx xxxxxx x xxxxx xxxxxxxx) $xxxxxx-xxxxxx
xxx xxxxxxxxx xxx xxx xxxxxx xxx xxxx xxxxxxxx. Xxxxxxx, xx
xxxxxxxxxx xxxxxxxxx xxx xxxxx xx xxx xxxxxx (xx xx xxxxxxxxx xxxxx
xx xxxx xxxxxxx), xxxx xxx xxxxxx xxxxxxxx $xxxxx-xxxxxx xxx xx xxxx
xxxxxx xxxxx.
NOTE Notice that the var statement is declared within the <op-script-results> XML
element. The SLAX processor is able to determine that this is a line of
script code rather than an XML element, and it does not try to write it to
the result tree. It is common to interleave SLAX code and result tree
elements in this manner within Junos scripts.

Operators
XXXX xxxxxxxx x xxxx xxxxxxx xx xxxxxxxxx xx xxxxxxx xxxxxx
xxxxxxxxx. Xxxxx xxxxxxxxx xxxxxx xxx xxxxxx xx xxxxxxx
xxxxxxxxxxxx xxxxxxxxxx, xxxxxxx xxxxxx, xxxxxxx xxxx, xxx xxxxxx
xxxxxxx xxxxxxxxxxx. Xxxxx 3.1 xxxxxxxxxx xxx xxxxxxxxx xxxxxxxxx
xx XXXX.

Table 3.1 SLAX Operators


NOTE There is no operator for “not” as there is in other programming
languages. Instead, there is a not() function that returns the opposite
boolean value of its argument.
NOTE The := operator is only supported in Junos 9.2 and beyond. If you are
using an earlier version you can use the node-set() extension function to
convert a result tree fragment into a node-set. The node-set() function
requires that the “http://xmlsoft.org/XSLT/namespace” namespace be declared,
and the assigned prefix prepended to the function name. For example, if
you assign the namespace to ext (ns ext = “http://xmlsoft.org/XSLT/namespace”;),
then you call the function as ext:node-set(): var $node-set-variable = ext:node-
set( $rtf-variable );

Data Type Conversion


Xxxxxxxxx xx xx xxx xxxxxxxxx xx xxxxxxxxxx xxxxxxx xxxx xxx xxxx
xxxx xxxx xxxxxxx. Xxx xxxxxxx xxxxxxxxx xx xxxx xxxx xx xxxxxxxxxx
xxxx xxxxxx xxxx xxxxxxxx xx xxxx-xxx, xxx xxxxxxxxx xxxx
xxxxxxxxxxx xxxxx xxxxxxxxxxxxx.
Xxxx xxx xxxxxx xxxxxx xxxxx xx xx xxxxxxxx xx x xxxxxxxxx, xxx xxx
xxxxxxxxxx xxxx xxxx xx xxx xx xxx xxxxxxx xxxx, xxx xxxxxx xxxxxx
xxxxxxxx xx xxxxxxxxxxxxx xxxxxxx xx. Xx xx xxxxxxx, xxxx xxx
xxxxxxxx xxxxxxxx xx xxxxxxxxxxx, xxx xxx xxxxxxxxx xxx xxxxxxxxx
xxxx xxxxxxx.
Xxx xxxxxxxxxx xxxxxxx xxxxx xx xxx xxxxxxxxx xxx, xxxxx xx xxx
xxxxxxxx xxxx xxxx:
„„string: strings which consist entirely of appropriate characters for
numeric content are converted into the equivalent number,
otherwise they are converted to NaN (not a number). When
converting to boolean, empty strings convert to false, and non-
empty strings convert to true.
„„number: numbers are converted to strings by converting each digit
into the appropriate character. The numeric value zero is converted
to the boolean value false, all other numeric values are converted to
the boolean value true.
„„boolean: when converted to strings, booleans become either “true”
or “false.” The boolean value false is converted to the numeric value
of 0. True is converted to the numeric value of 1.
„„node-set: a node-set is converted into a string by returning the
string value of the first node in the node-set. The string value is the
text contents of the node as well as all its child nodes. A node-set
converts into a number in a similar fashion. Empty node-sets are
converted to the boolean value of false, node-sets with one or more
nodes are converted to the boolean value of true.
„„result tree fragment: result tree fragments are converted to strings
by returning all the text content within the XML data structure.
Xxx xxxxxxxxx xxxxxx xxxxxxx xxxxx xxx xxxxxxxxx xxxxxxxxxx
xxxxxxx xxxxx x xxxxxx xx xxxxxxxxx xx xxx xxxxxx xxxxxx xxxx xxxx:

/* convert.slax */
version 1.0;
ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
import "../import/junos.xsl";

match / {
<op-script-results> {

/* String variable */
var $numeric-string = "-700";
/* Number variable */
var $number = 100;
/* Output the addition of the two variables to the console */
<output> $numeric-string + $number;
}
}

Xxxx xxxxxxxx, xxxx xxxxxx xxxxxxxx xxx xxxxxx -600 xx xxx xxxxxxx.
Xxx xxxxxx xxxxxx xxxxxxxxxxxxx xxxxxxxx xxx xxxxxx “-700” xxxxxx
xxx xxxxxx xxxx xxx xxxxxxxxxx xxxxxx -700. Xxx xxxxxx xx xxx
xxxxxxxxxx xx -700 + 100 xx xxxx xxxxx.

Try It Yourself: Working with Operators


Create a new script including two variables that are assigned numeric values. Add a third
variable and assign it the product of the first two variables. Display the value of the third
variable on the console.

Parameters
Xxxxxxxxxx xxx xxxxxxxxx xxxxx xxxxx xx xxxxxxxx xx xx xxxxxxxx
xxxxxx. Xxxxx xxxx xxxxx xxxxxxxxxxx xxxx xxxxx xxx xxxx xxxxx xx
xxxxxxxxx, xxx xxx xxx xxx xxxx xx x xxxxxxx xxx.

Default Parameters
Xxxxx xxxxxx xxxxxx xxxx xxx xxxxxxxxxx xxxxxxxxxx, xxxxx xxx
xxxxxxxx xxxxxx xxxxx.xxx. Xxxx xxxxx.xxx xx xxxxxxxx xx xxxx xx xxx
xxxxxxxx xxxxxxxxxxx, xxxxx xxxxxxxxxx xxx xxxxxxxx xx xxxx xxx xxx
xx xxxx xxxxxx xxx xxxxxx.
Xxx xxxxxxx xxxxxxxxxx xxxxxxx xxxxxxxx-xxxx xxxxxxxxxxx xxx
xxxxxxx:
„„$product: contains the name of the local Junos device model
„„$user: is assigned to the name of the user that executed the script
„„$hostname: stores the local hostname of the Junos device
„„$script: contains the name of the script that is currently executing
„„$localtime: stores the local time when the script was executed using
the following format: Tue Jan 20 14:07:33 2009
„„$localtime-iso: provides a different format of local time: 2009-01-20
14:07:33 PST

NOTE In Junos versions prior to 9.6 $localtime-iso is named $localtime_iso. The old
name format will continue to be supported in 9.6 in a deprecated
fashion.

Global Parameters
Xxxxxxxxxx xxxxx xxxxx xx xxx xx Xxxxx xx xxxxxx xxxxxxxxxxxxxx
xxxx xx xxxxxxx xx xxxxxx xxxxxxxxxx. Xxx xxxxxxx xxxxxxxxxx
xxxxxx xxxxx xxx xxxxxxxx xx xxxxxx xxxxxxxxxx. Xx xxxxxxx x xxxxxx
xxxxxxxxx, xxx xxx xxxxx xxxxxxxxx xxx xxxxxxx x xxxx xxx xxx
xxxxxxxxx. Xx xxxx xxxxxxxxx, xxxxxxxxx xxxxx xxxxxx xxxxxxx x
xxxxxxxxx “$”.
version 1.0;
ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
import "../import/junos.xsl";

/* This is a global parameter */


param $interface;

X xxxxxx xxx xxxxxx x xxxxxxx xxxxx xx x xxxxxx xxxxxxxxx. Xxxx


xxxxxxxx x xxxxxxxx xxxxx xx xxx xxxxx xxxx Xxxxx xxxx xxx xxxx x
xxxxx xx xxx xxxxxxxxx. Xx xx xxxxxxx xxxxx xx xxxxxxxx xxx xxxx xx
xxxxxxxx xxxxxx xxxxxx xxxxxxxxxx, xxxx xxx xxxxxxxxx xxxxxxxx xx
xx xxxxx xxxxxx. Xxxx xx xx xxxxxxx xxxxx xxx $xxxxxxxxx xxxxxxxxx
xxxxxxxx xx “xxx0”:
version 1.0;
ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
import "../import/junos.xsl";

/* This is a global parameter with a default value */


param $interface = "fxp0";

Command-line Arguments
Xxxxxx xxxxxxxxxx xxxxxx xx xxxxxxx xxx xxxxxxxxx xxxx xx xxxx
xxxxxxx-xxxx xxxxxxxxx xxxx Xxxxx xx xxx xx xxxxxx. Xxxx xxxxxxxxx
xxxxxxx xxxxxxxxx xxx xxxxxxxxxxx xx x xxxxxx, xx xxxxxxx xxx xx
xxxxxxx xx xxxxxxx xxxxxxxxxxx xxxxx xx xxx xxxxxxxxx xxxxxxxx.

Creating Command-line Arguments


Xxxxxxx-xxxx xxxxxxxxx xxx xxxxxx xxxxxxxxx xx xxxx xxx xxxxx
xxxxx. Xxxx x xxxx xxxxxxxx xx xx xxxxxx xxx xxxxxxxx xxxxxxx-xxxx
xxxxxxxxx, Xxxxx xxxxxxxx xxx xxxxxx xxx x xxxxxx xxxxxxxxx xx xxx
xxxx xxxx (xxxxxxxxx xxx xxxxxx xxxx $) xxx xxxxxxx xxx xxxxx xxxx
xxx xxxxxxx-xxxx xxxxxxxx xx xxx xxxxxxxx xxxxxxxxx.
Xx xx xxxxxxx, xxxxxx x xxxx xxxxxxx xxx xxxxxxxxx xxxxxxx:
user@Junos> op show-interface interface fe-0/0/0.0

Xxxxx xx xxx xxxxxxx-xxxx xxxxx, Xxxxx xxxxxxxx xxx x xxxxxx xxxx-


xxxxx xxxxx $xxxxxxxxx. Xx xxx xxxxxxxxx xx xxxxxxx, xxxx Xxxxx
xxxxxxx xx xxx xxxxxx xxxxx xx “xx-0/0/0.0”.
Xxxx xx xx xxxxxxx xx x xxxxxx xxxx xxxxxxxx xxxxxxx-xxxx
xxxxxxxxx:
/* combine-strings.slax */
version 1.0;
ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
import "../import/junos.xsl";

/* Command-line arguments */
param $string1;
param $string2;

match / {
<op-script-results> {

/* Output the command-line arguments to the console */


<output> $user _ ": Here are your combined strings: " _ $string1 _ $string2;

}
}

Xxxx xxxxxx xxxxx xx xxxxxxx xx xxxx xxxxxxx xxxxxxxxx xxx xxx


xxxxxxx-xxxx xxxxxxxxx. $xxxx xx x xxxxxxx xxxxxxxxx xxxxxxxx xx xxx
xxxx xx xxx xxxx xxxxxxx xxx xxxxxx. $xxxxxx1 xxx $xxxxxx2 xxx xxxxxx
xxxxxxxxxx xxxxx xxx xxxxxxxxx xxxxxxx xxxxxxx-xxxx xxxxxxxxx.
Xxxxxx xxx xxxxxx xxxxxxxx xxxxx xxx xxxxxxxxx xxxxxxx-xxxx:
user@Junos> op combine-strings string1 "Hello" string2 " World!"
user: Here are your combined strings: Hello World!

Xx xxx xxxxxxx xxxxx, xxx xxxxxxx Xxxxx xxx Xxxxx!" xxxx xxxxxxxx
xxxxxxxx xx xxx $xxxxxx1 xxx $xxxxxx2 xxxxxxxxxx xxx xxx $xxxx
xxxxxxxxx xxxxxxxxx xxxxxxxxxx xxx xxxxxxxx xx xxxx.

Op Script Help
Xxxxxxxxxxx xxxxxxx-xxxx xxxxxxxx xxxxx xxx xx xxxxxxxxxx. Xx xx
xxxx xxxx-xxxxxxxx xx xxxxxxx x xxxxx xxxxxxxxx xx xx xxxxx
xxxxxxx-xxxx xxxxxxxxx xxx xxxxxxxxx. Xxxxx xxxxxxxx x xxx xxx xx
xxxxxxx xx xxxxxx xxxxxxxxx xx xxx Xxxxx XXX xxxx xxxxxx xxxx
xxxxxx xxxxx xxxxx xxxxxxxxx xxx xxxxxxxxx xxx xxx xx xxxxxx.
Xx xxxxxxx, Xxxxx xxxxx xxx xxxxx x ? xxxxx x xxxxxxx xx xxx xxx
xxxxxxxxx xxxxxxxxxxx. Xx x ? xx xxxxxxx xxxxxxxxx xxx xx xxxxxx
xxxxxxx xxx xxxxxxxxx xx xxxxxxxxx:
user@Junos> op combine-strings ?
Possible completions:
<[Enter]> Execute this command
<name> Argument name
detail Display detailed output
| Pipe through a command

Xxxx xxxxxxx xxxx xxx xxxx xxx xxxx xx xxxx xxxxxxx-xxxx xxxxxxxxx
xxx xx xxxxxxxx xx xxx xxxxxx. Xxx xxxxxxxx xx xx xxx x xxxxxxx
xxxxxxx xxxxxx xxxxxxxx xxxxx $xxxxxxxxx xxxxxx xxx xx xxxxxx. Xxxxx
xxxxxxxxxxxxx xxxxx xxx xxxx xxxxxxxx xxxx xxxxxxxx xxx xxxx
xxxxxxxx xxx xx xx xxxxxx. Xx xxxxxxxxx xxx xxxxxx xx xxx XXX xxxx
xxxxxxxxx, xx xx xxxxxxxx xx xxx xxxxxxx-xxxx xxxxxxxxx xx xxx xxxx
xxxx.
Xxx xxxxxxxxx xxxxxxxx xxx xxx xx xxxx xxx $xxxxxxxxx xxxxxxxx xx:
<argument> {
<name> "ArgumentName";
<description> "Argument description";

Xxxx x xxxx xx xxx xxxxxx xxxxxx xx xxx xxx xx xx xxxx:


/* combine-strings.slax */
version 1.0;
ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
import "../import/junos.xsl";

/* This variable defines the CLI help text */


var $arguments = {
<argument> {
<name> "string1";
<description> "The first string";
}
<argument> {
<name> "string2";
<description> "The second string";
}
}

/* Command-line arguments */
param $string1;
param $string2;

match / {
<op-script-results> {

/* Output the command-line arguments to the console */


<output> $user _ ": Here are your combined strings: " _ $string1 _ $string2;

}
}
Xxx, xxxxxx xxx xxxxxxxxxx xxxx x xxxx xxxxxxx xxx Xxxxx XXX xxxx:
user@Junos> op combine-strings ?
Possible completions:
<[Enter]> Execute this command
<name> Argument name
detail Display detailed output
string1 The first string
string2 The second string
| Pipe through a command

Try It Yourself: Working with Command-line Arguments


Create a new script with a command-line argument that accepts a number from the user.
Include the $arguments global variable so that the CLI help output includes the command line
argument. Perform a mathematical operation on the command-line argument and output the
result to the console. Execute the op script a few times, with a different number provided on
the command-line to verify that the result changes.

Conditional If Statements
Xxx xxxxxx xxxxxxxx xx xxxx xxxxx xxxx xxxx xxxxxx xxxxx.
Xxxxxxxxxxx xxxx xxxxxxxxx xxxxxx xxxx xxxxxxxx xxxxxxxxxxxxx
xxxx xxx XXXX xx xxxxxxxxx. Xxxxx xxx xx xxxxxxxxx xxxxxxxxx xxx
xxxxxx xxxxxx xx xxxxxxx xxxxxxxx xx xxxx xxxx xxxx xxxxxxx
xxxxxxxxxx xxx xxx. Xxxx xxxxx xxxx xxxxxxx xxx xxxxx xx xxxxxx
xxxxxxx xx xxxx xxxxxxxxx xx xxxx.

If Statements
Xxx xx xxxxxxxxx xxxxxxxx xx xxx xxxxx: x xxxxxxx xxxxxxxxxx xxx x
xxxxxxxxxxx xxxx xxxxx:
if( $mtu == 1500 ) {
<output> "Jumbo Frames are not enabled";
}

Xx xxx xxxxx xxxxxxx xxx xxxxxxx xxxxxxxxxx xx $xxx == 1500. Xx xx


xxxxxxxxx xxxxxx xxxxxxxxxxx xxxxxxxxxxx xxxxxxxxx xxx xx
xxxxxxxxx. Xxxx xxx xxxxxxxxxx xxxxxxxxx xx xxxx xxxx xxx
xxxxxxxxxxx xxxx xxxxx xx xxx xx xxxxxxxxx xx xxxxxxxx. Xxxx xxx
xxxxxxxxxx xxxxxxxxx xx xxxxx xxxx xxx xxxxxx xxxxxx xxxxx xx xxx
xxx xx xxx xxxxxxxxxx xxxx xxxxx xxx xxxxxxxx xxxxxxxxxx xxxx xxxx
xxxxx. Xx xx xxxxxxx, xx xxx $xxx xxxxxxxx xx xxxxxxxx xx xxx xxxxx
1500 xxxx <xxxxxx> "Xxxxx Xxxxxx xxx xxx xxxxxxx" xx xxxxxxx xx xxx xxxxxx
xxxx, xxxxxxxxx xxxx xxxxxx xxxx xxx xxxxxx xx xxx xxxxxxx xxxxxx.

Else If and Else Statements


Xxxxxxxxxx xxxxxxxxxxxxx xxx xx xxxxxxxxx xx xxxxxx xxxx xx xxx/xx
xxxx xxxxxxxxxx:
if( $interface == "fxp0" ) {
<output> "Out of Band Management";
}
else if( $interface == "lo0" ) {
<output> "Loopback Interface";
}
else {
<output> "Other";
}

Xx xxxx xxxx, xxx xxxxxx xxxxxx xxxxxx xxxx xxxxxxx xxxxxxxxxx


xxxxxxxxxxxx. Xxx xxxxx xxxxxxxxxx xxxx xxxxxxxxx xx xxxx xxx xxx
xxxx xxxxx xxxxxxxx. Xx xxxxxxx xxx xx xxx xxx xxxx xx xxxxxxxx xx
xxxx, xxxx xxx xxxx xxxx xxxxx xx xxxxxxxx (xxxx xxxxxxx). Xx xxx
xxxxx, xxx xxxxxx xxxxxx xxxxxxxx x xxxxxxx xx xxx xxxxxxxxxxx xxxx
xxxxx. Xx xxxxxxxx xxxxxxx xxxxxxxxxxx xxxxxxxx xx xxxx, xxx xxxxxx
xxxxxx xxxx xxxxxxx xxx xxxxx.

Conditional Operation Example


Xxxx xx x xxxxxx xxxx xxxxx xxxxxxxxxxx xxxxxxxxx. Xx xxxxxxx xxx
xxxxx xx xxx xxxxxxx xxxxxxxxx, xxxx xxx xxxxxxx xxxxxxxxx xxxxx
xxxxxx xxxxxxx x xxxxxxx-xxxx xxxxxxxx:
/* output-parameter.slax */
version 1.0;
ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
import "../import/junos.xsl";

/* This shows the parameter argument in the CLI help output */


var $arguments = {
<argument> {
<name> "parameter";
<description> "Enter name of parameter, e.g. $user";
}
}

/* Command-line argument */
param $parameter;

match / {
<op-script-results> {
/* Output the selected parameter to the console */
if( $parameter == "$user" ) {
<output> "$user = " _ $user;
}
else if( $parameter == "$hostname" ) {
<output> "$hostname = " _ $hostname;
}
else if( $parameter == "$product" ) {
<output> "$product = " _ $product;
}
else if( $parameter == "$script" ) {
<output> "$script = " _ $script;
}
else if( $parameter == "$localtime" ) {
<output> "$localtime = " _ $localtime;
}
else if( $parameter == "$localtime-iso" ) {
<output> "$localtime-iso = " _ $localtime-iso;
}
/* If nothing matches then give this message instead */
else {
<output> "This is not a valid default parameter: " _ $parameter;
}
}
}
Now let’s see this script in action:
user@Junos> op output-parameter parameter $user
$user = user

user@Junos> op output-parameter parameter $script


$script = output-parameter.slax

Conditional Variable Assignment


Xxx xxxxxx xxx xxx xxx xx xxxxxxxxx xx xx xxxxxxxxxxxxx xxxxxx
xxxxxxxx xxxxxx. Xxxxxxx x xxxxxxxx’x xxxxxxxxx xxxxxxxx xxxxx
xxxxxx xx xxxxxxxxxx, xx xx xxxxxxx xx xx xxxx xxxxxxxxx xx xxx
xxxxx xxxxx xx x xxxxxxxx. Xxxx xxx xx xxxx xx xxxxxxxxx xxxx x
xxxxxxxx xxxx xxxx xxx xxxxx xxxxxxxx xx xx xx xxxxxxxxx:
var $user-type = {
if( $user == "john" ) {
expr "operator";
}
else if( $user == "tom" ) {
expr "admin";
}
else {
expr "unknown";
}
}

Xxxxxxx xxx xxxxxxxxx xxxxxx xx xxx xxxxx xxxx. Xxxxx, xx xxxxx xx


xxxxxxxxxxxxx xxxxxx x xxxxxxxx xxx xxxxxx xx xxxxxxxxx xxx xxx
xxxxxxxx xxxx xx xxx xxxx xxxxxxxxxx xxxx xxx xx xxxxxxxx xxxxxx
xxxxx xxxxxx { }. Xxxxxx, xxxx xxx xxx xx x xxx xxxxxxxxx xxxx, xxxxx
xx xxxx xx xxxxx xxxx xx xxx xxxxxx xxxx. Xxxx xxx xxxx xxxxx
xxxxxxxx xxxx xx xxxxx x xxxxxxxxxxxxx xxxxxxxx xxxxxx xx xxx
xxxxxx xxxx. Xxx xxxx xxxxxx xx xxxxxxxxxx xx xxx $xxxx-xxxx xxxxxxxx
xxxxxx xx x xxxxxx xxxx xxxxxxxx.
Xxxxxxx xxx $xxxx xxxxxxx xxxxxxxxx xxxxxx “xxxx” xxxx xxx “xxxxxxxx”
xxxxxx xx xxxxxxx xx xxx xxxxxxxx $xxxx-xxxx xx x xxxxxx xxxx
xxxxxxxx. Xxxxxx x xxxx xxxx xx xxxxxx xxxx xxxxxxxx xx xxxxx xx x
xxxxxx xxxx xxx xxxxx xxx xxxxxxxx xxxxxxx xxx xxxxxx xxxxxx
xxxxxxxxxxxxx xxxxxxxx xxx xxxx xxxx xxxxxx xxxx xxxxxxxx xx x
xxxxxx xxxxxxxx xxxxxxxxx. Xxxxxxx xx xxxx, xxx xxxxxx xxx xxxxx
xxx xxxxxx xxxx xxxxxxxx xx xx xx xxx xxxx x xxxxxx xxxxxx xxxxxxxx.

Try It Yourself: Conditionally Assigning Variable Values


Create a new script with a command-line argument that can be set to either + or - , signifying
the mathematical operation to perform. Create a variable that is assigned conditionally, based
on the value of the command-line argument. If the command-line argument is specified as a +
then two values should be added together and assigned to the variable. If the command-line
argument is specified as a - then subtraction should be performed between the two values and
assigned to the variable. Output the result to the console.

Named Templates
Xxx xxxxxxxx xxxxxxxx xx xxx xxxx xxxxxxxx xxxx xxx xxxx xxxxxxxx.
Xxxx xx xxxxxxxxxxx xxxxx xxxxx xxxxxx xxxxxx. Xxxxxxx, xx xxx
xxxxxxxxxx xx x xxxxxx xxxxxxxxx xx xxxxxxx xxxx xxxxxxxxxxxx xx
xxxxxxxxxx xx xx xxxxxxxx xxxx xx xxx xxxxxxxxxxxxx xxxx xxx xxxx
xxxxxxxx xxx xxxxxxx xxx xxxx xxxx xxxxx xxxxxxxxx xxxxxxx.
X xxxxx xxxxxxxx xx x xxxxxxx xx xxxx xxxxx xxx xx xxxxxx xxxx
xxxxxxxx xx xxx xxxxxx xx xxxxxxxxx xx xxx xxxx. Xxxx xxxx xxxxxx,
xxx xxxxxx xxxxxx xxxxxx xxx xxxxx xx xxx xxxx xxxxxx xxx xxxxxxxx
xxxxxxxx xxxxx xxx xxxxxx xxxxxxxxx. Xxxx xxx xxxxxx xxxxxx
xxxxxxx xx xxx xxxxxxx xxxxxxxx xxx xxxxxxxxx xxxxxxxxxx xxxx
xxxxx xx xxxx xxx xxxxxx.
Xxxxx xxxxxxxxx xxx xxxxxxx xxxxxxx xxxxxxx xx xxx xxxxxxxxx xxxx:
„„code re-use: if a particular code stanza has to be repeated multiple
times throughout your script then it makes sense to place it within a
named template instead. This reduces the size of your script and
simplifies changes.
„„self-documentation: named templates with descriptive names clarify
the script actions. A script that is written in this way is simpler to
read and understand than one in which all the operations are
performed in a single large main template.
„„recursion: a useful capability of named templates is their ability to
call themselves. By looping through a section of code as many times
as necessary, you can program the script to reach a specific end
goal.

Named Templates Syntax


Xx xxxxxx x xxxxx xxxxxxxx xxx xxx xxx xxxxxxxx xxxxxxxxx, xxxx xx x
xxxx, xxx xxxxxxx xxx xxxxx xxxxx xxxxxxxx xxxx xxxxx:
template example-template {
/* Template code goes here */
}

Xx xxxx x xxxxxxxx xxx xxx xxxx xxxxxxxxx xxx xxxxxxx xxx xxxx xx xxx
xxxxxxx xxxxxxxx:
call example-template;

Xxxx xx xx xxxxxxx xx x xxxxxx xxxx xxxx x xxxxx xxxxxxxx:


/* show-user.slax */
version 1.0;
ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
import "../import/junos.xsl";

match / {
<op-script-results> {

/* Call the display-user template */


call display-user;
}
}

/* This template outputs the username to the console */


template display-user {
<output> "Your user name is " _ $user;
}

Xx xxxx xxxxxxx, xxx xxxx xxxxxxxx xxxxx xxx xxxxxxx-xxxx xxxxx


xxxxxxxx. Xxx xxxxxx xxxxxxxx xx xxxx xxxxxxxx, xxxxxxx xxx <xxxxxx>
xxxxxxx xx xx xxxxxxx xx xxx xxxxxx xxxx xxxxx xxxx xxx xxxxxxxx
xxxxxx. Xxxxxxxx xxxx xx x xxxxxx xxxxxxx, xx xxxxxxxxxx x
xxxxxxxxxxx xxxx xxxxx xxxxx xxxxxxxxx: xxx xxxxxxxx xxxx xxx
xxxxxxx xx xxx xxxxxx xxxx xx x xxxxx xxxxxxxx xxx xxxxxxxx xx xxx
xxxxx xxx xxxxxxxx xx xxxxxx.
Xxx xxxx xxxxxxxx xxxx xxxxxx xxx <xx-xxxxxx-xxxxxxx> xxxxxxx xx xxx
xxxxxx xxxx, xxx xxxxxx xxxxx xx xx xxxxx xxx xxxxxxx-xxxx xxxxxxxx.
Xxx xxxxxxx-xxxx xxxxxxxx xxxx xxxxxxxx xxx xxxxxxxxxxxx xx xxxxxxx
xxx <xxxxxx> xxxxxxx xx x xxxxx xxxxxxx xx <xx-xxxxxx-xxxxxxx>. Xxx
xxxxx xxxxxx xxxx xxxx xx Xxxxx xx:
<op-script-results> {
<output> "Your user name is " _ $user;
}

Template Parameters
Xxxxxxxx xxxxxxxxxx xxx xxxxxxx xx xxxxxx xxxxxxxxxx – xxxxx xxxxx
xx xxx xxxxxxx xx xxx xxxxxxxx. Xxxxxxx, xxxxxx xxxx xxxxx xxx xx
Xxxxx xxxx xxx xxx xx xxx xxxxxx xxxx xxxx xx xxxxx xxx xxxxx
xxxxxxxx.
Xx xxxxxxx xxxxxxxx xxxxxxxxxx, xxxxxxx xxxx xxxxxx xxxxxxxxxxx
xxxxxxxxx xxx xxxxxxxx xxxx:
template display-user( $full-name ) {
/* Template code goes here */
}

X xxxxxxx xxxxx xxx xx xxxxxxxx xx xxx xxxx xxx xx x xxxxxx


xxxxxxxxx. Xx xxx xxxxxx xxxx xxxxxxxx xx xxxxxxx xxxxx, xxx xxx
xxxxxxxx xxxx xxxx xxx xxxxxx x xxxxxxxxx xxxxx, xxxx xxx xxxxxxxx
xx xxxxxx, xxxx xxx xxxxxxxxx xx xxx xx xx xxxxx xxxxxx.
template display-user( $full-name = "John Doe" ) {
/* Template code goes here */
}

NOTE An alternate, more verbose, method to declare parameters is to use the


param statement in the lines immediately following the template name.

Xxxxxxxxx xxxxxx xxx xxxxxxxx xxxxxx xxx xxxx xxxxxxxxx xxxx xxxxx
xxx xxxxx xxxxxxxx. Xxx xxxxxxxxxxx xxx xxxx xx xxxx, xxx xx
xxxxxxxx:
call display-user( $full-name = "Jane Doe" );

Xxxx xxxxxxxxx xxx xxxxxx xxxxxx xx xxxx xxx xxxxxxx-xxxx xxxxxxxx


xxx xx xxxx xxx $xxxx-xxxx xxxxxxxxx x xxxxx xx “Xxxx Xxx”.
NOTE An alternate, more verbose, method to assign template parameter
values when calling a named template is to use the with statement in the
following manner:
call display-user { with $full-name = "Jane Doe";}

Xxxx xxxxxx xxxxxxx xxxxx xxx xx xxx xxxxxxxx xxxxxxxxxx:


/* show-time.slax */
version 1.0;
ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
import "../import/junos.xsl";

match / {
<op-script-results> {

/* Call the display-time template and set the $format parameter */


call display-time( $format = "normal");
}
}

/* Output the localtime to the console in either iso (default) or normal format */
template display-time( $format = "iso" ) {
if( $format == "iso" ) {
<output> "The iso time is " _ $localtime_iso;
}
else {
<output> "The time is " _ $localtime;
}
}

Xx xxxx xxxxxxx, xxx xxxxxxx-xxxx xxxxxxxx xxxxx xxx xxxxxxxxx xxxx xx


xxx xxxxxx xx xxxxxx xxx xxxxxxx XXX xxxxxx xx xxx xxxxxx xxxxxx.
Xxxx xxx xxxxxx xx xxxxxx xxx $xxxxxx xxxxxxxxx xx xxx xx “xxxxxx”
xxxxxxxxx xx xxx xxxxxx xxxx xxxxx xxxxxxxxx xx xxx xxxxxxx.
Xxxx xx xxxxxx xxxxx xx xxxx xxxxxx xx xx xxxxxxx xxx xxxx xx xxxxxx
xxx xxxxxx. Xxx xxxxxxxxx xxxx x xxxxxxx-xxxx xxxxxxxx xxx $xxxxxx
xxxx xxxx xxx xxxx xx xx:
/* show-time.slax */
version 1.0;
ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
import "../import/junos.xsl";

/* This is imported into the Junos CLI help text */


var $arguments = {
<argument> {
<name> "desired-format";
<description> "Choose either iso or normal";
}
}

/* Command-line argument */
param $desired-format;

match / {
<op-script-results> {

/* Call the display-time template and set the $format parameter */


call display-time( $format = $desired-format );
}
}

/* Output the localtime to the console in either iso (default) or normal format */
template display-time( $format = "iso" ) {
if( $format == "iso" ) {
<output> "The iso time is " _ $localtime_iso;
}
else {
<output> "The time is " _ $localtime;
}
}

Xxxx xxxxxxxx xxxxxx xxxxxxxx x xxx xxxxxxx-xxxxxx xxxxxxx-xxxx


xxxxxxxx, xxxxxxxx xxx xxxx xx xxxxxx xx xxxxx xxxxxx xx xxxxxxx xxx
xxxx. Xxxx xxx xxxxxxx-xxxx xxxxxxxx xx xxxxxx xxx $xxxxxx xxxxxxxxx xx
xxx xx xxx xxxxx xx xxx $xxxxxxx-xxxxxx xxxxxx xxxxxxxxx.
Xxxx xx xx xxxxxxx xx xxx xxxxxx:
user@Junos> op show-time display-format iso
The iso time is 2009-05-12 21:01:10 PDT

user@Junos> op show-time display-format normal


The time is Tue May 12 21:01:13 2009

NOTE If the calling template includes variables or parameters with the same
name as the parameter of the called template, then the parameter can
be listed without applying an assignment. The script engine
automatically sets it to the value of the variable or parameter within the
calling template. For example:
var $display-string = "Example String";call show-string( $display-string );

SHORT CUT There is an easier way to write the script on the previous page.
Remember that global parameters and variables are accessible in the
entire script, not just in the main template. This means that it is not
necessary to pass the $format value to the display-time template as a
template parameter. Instead, the display-time template can simply use the
global parameter. The Appendix included in the PDF version of this book
provides an example that uses the global parameter. The script operates
in the same manner as the preceding one, but in this case the named
template accesses the global parameter instead of relying on the main
template to pass the format as a template parameter.

Redirecting the Result Tree


Xxxxxxxx xxxxxxxxx xxxx xxxxxxx x xxxxxx xx xxx xxxxxx xxxx xx
xxxxxx xxx xxxx xxxxxxxxxxxxxx xxx xxxx-xxxxxxxxxxxxx.
Xxxxxxxxxxxx, xxxxx xxx xxxx xxxxx xxxx xxx xxxxxxx xxxxxxxx xxx
xxxxxxx x xxxxxxx xxxxxx xxxx xxx xxxxxx xxxxx xxxxxxxx. Xx xxxx
xxxxxxxx, xxx xxxxxx xxxxxxxx xx xxxxxxxx xx xxxxxxx x xxxxxxxx
xxxxxxxxx xxx xxxx xxxxxx xxx xxxxxx. Xxxxx xxxxxxxxx (xxxxxx
xxxxxxxxx xx xxxxx xxxxxxxxx) xx xxx xxxx x xxxxxx xxxxxxxxx xxx
xxxxxxxxx xxxxxx; xxxxxxx, xxxx xxx xxxx xx xxxxx xx xxx xxxxxx
xxxx, xxx xx xx xxxxxxxx xx xxxxxxxx xxx xxxxxx xxxx xx x xxxxxxxx.
Xxxxx xxxx xxxxxx xxxxxx xxxxxxxxx xx xxxxxxxxxxx xxxxxx x xxxxxx
xxxxx xx xxx xxxxxxx xxxxxxxx xx xxxxxxx xx xxx xxxxxx xxxx. Xxx
xxxxxxx xxxxxxxx xxxx xxxxxxxxx xxx xxxxxx xxxx xxxxxx xxxx x
xxxxxxxx. Xxxx xx xx xxxxxxx xx xxx xx xx xxxx:
/* show-day.slax */
version 1.0;
ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
import "../import/junos.xsl";

match / {
<op-script-results> {

/* get-day-of-week returns the day – assign it to $day-of-week */


var $day-of-week = { call get-day-of-week(); }

/* Output day string to the console */


<output> $day-of-week;
}
}

/* Extract the day of week string from the $localtime global parameter */
template get-day-of-week {
/* Write the first three characters of the $localtime to the result tree */
expr substring( $localtime, 1, 3 );
}

Xxx xxx-xxx-xx-xxxx xxxxxxxx xxxxxxxx xxx xxx xxxxxx xxxx $xxxxxxxxx xxx
xxxxxx xx xx xxx xxxxxx xxxx. Xxx xxxxxxx xxxxxxxx xxx xxxx
xxxxxxxx xxx xxxxxx xxxx xxxxxx xxx xxxxx xx xxxxxx x xxxxxxxx
xxxxxxx. Xx xxxx xx xxx xxxxxx, xxx xxxxxx xxxx xx xxxxxxxxxx xxxx
xx xxxxxxx xx xxx xxxxxx xxxx xxx xxxxxxxxxxx xxxxxxxx xxxxxxxxxx.
Xx xxxx xxxxx xxx xxxxxx xxxxxxxx xxx xxx xx xxxxx xxxxxx xxxxxx
xxx xxxx, xxxxx xxxxxx xx xxx xxxxxx xxxx:
var $day-of-week = { call get-day-of-week(); }

Xx xxxxxxxxxx xxx xxx xxxxxx xxxx $xxxxxxxxx xxx xxxxxxx xx xx xxx


xxxxxx xxxx xxxxxxx x xxxxx xxxxxxxx, xxx xxxxxx xxx xxxx xxxx xxxxx
xxxxxxxx xxxxxxxx xxxxx. Xxx xxxxx xxxxxxxx xxx xxxx xx xxxxxx
xxxxxx xxxx xxx xxxxxx xxxx xxxxxxx xxxx xxxxxxxx xxxxxxx
xxxxxxxxxxxxx. Xx xxxxxxxx xxx xxx xxxxxx xxx xxxxxx xxxxx
xxxxxxxxx xx xxx xxxxxxxxx() xxxxxxxx xxxxxx xxx xxx-xxx-xx-xxxx
xxxxxxxx. Xxx xxxx xxxxxxx xx xxxx xxxxxxx xxxxxx xxxxx xxxxxxxxx.

Try It Yourself: Working with Named Templates


Create a new script that contains a named template. The template should write a string to the
result tree. Redirect this into a variable in the calling template and output the variable value
to the console.

Functions
Xxxxxxxxx xxx xxxxx xxxxxxxxxx xxxxxx xxx xxxxxx xxxxxx. X xxxxxx
xxx xxxxxx xxxxxxxxx, xxxxx xxxx xxxxxxxxx, xxxxxxx x xxxxxxxx
xxxxxx, xxx xxxxxx xxx xxxxxx. Xxxx xxxxxxx xxxxx xxxxx xxxxxxx xx x
xxxxx xxxxxxxx, xxx xxxxx xxx xxxxx xxxxxxxxxxx xxxxxxx xxx xxx:
„„A named template is actual script code, whereas a function is part of
the underlying Junos operating system itself.
„„Values are provided to named templates through the use of
parameters, which are assigned by name, but functions use
arguments where a precise order is mandated.
„„Functions actually return results, whereas named templates can only
write to the result tree and have that result tree fragment redirected
to a variable in the calling function.
Xxx xxxxxx xx xxxxxxxxx xxxxxxx xxxx xxxx xx xxxxx xxxxxxxxx xx
xxxx. Xxx xxxx xxxxxxxxx xx xxx xxxx; xxxx xxx xxxxxxxx xxxx xx
xxxxxxxx xxx xxx xxxxxxxx xxxxxxxxx xxxxxxxxx xxxxxx xxxxxxxxxxx:
expr substring( $localtime, 1, 3 );

Xxxxxxxxx xxxxxx xxxxxx, xx xx xxxxxxx xxx xxxxxxxxx() xxxxxxxx


xxxxxxx x xxxxxx. Xxx xxxxx xxxx xxxxxx xxx xxxxxx xxxxx xx xxx
xxxxxx xxxx. Xxx xxxxxx xxxx xxxxx xxxxxx xxx xxxxxx xxxxx xx x
xxxxxxxx xxxxxxx xxxxx xxx xxxxxxxxx xxxxxx:
var $day-string = substring( $localtime, 1, 3 );

Xxxx xxx xxxxxxxxxx xxxxxxx xxxxxxxxx x xxxxx xx x xxxxxxxx xxxx x


xxxxx xxxxxxxx xxxxxx xxxx x xxxxxxxx:
var $day-of-week = { call get-day-of-week(); }

String Functions
Xxxxxx xxxxxxxxx xxx xxxx xxxxxxxxx xxxxxx xxxxxxx. Xxxxx 3.2 xxxxx
xxxx xx xxx xxxx xxxxxx xxx xxxxxx xx xxx xxxxxx xxxxxxxxx.
Table 3.2 String Functions

MORE? This chapter only covers a portion of the available functions. Additional
functions are in the Configuration and Diagnostic Automation Guide at
www.juniper.net/techpubs.

jcs:printf()
Xxxxxxxx xxxxxxxxxxx xxxxxx xx xxx xxxxxx xx xxxxxxxxxx xxx xxxx
xxxxxxx, xxx xx xxxx xxxxx xx xx xxxx xxxx-xxxxxxxx xx xxxx
xxxxxxxxx xxxxxx xxxxxx xxxxx xxxx xxxx xxxxxxx xxx xxxx xxxxxx
xxxxxxx. Xxx xxx:xxxxxx() xxxxxxxx xx xxxx xx xx xxxxxxx xxx xxxx
xxxxxxx. Xx xxxxxxx x xxxxxx xxxxx xx xxx xxxxxxxxxx xxxxxxxxxxxx
xxx xxxxxx xxxxxxxx xx xxx xxxxxxxxx.
NOTE The jcs:printf() function does not output directly to the console, it only
returns a formatted string. This string can then be output to the console
as desired.
Xxx xxxxxx xxx xxx:xxxxxx() xx xxx xxxxxxxxx:
jcs:printf( "expression", value1, value2, ..., valuex );

Xxx xxxxxx xxxxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxxxxxx xxxx


xxxxxxxx xxxxx xxxx xxxxx xxxxxx xx xxxxxxxx, xx xxxx xx xxx xxxxxx
xx xxxxx xxxx xxxxxx xx xxxxxx. Xxxx xx xx xxxxxxx:
<output> "123456789012345678901234567890";
<output> jcs:printf("%-10s%-10s","OSPF","ISIS" );
<output> jcs:printf("%10s%10s", "OSPF", "ISIS" );

Xxxxx xxx xxx xxxxxxxx xxxxxxxxxxxx xx xxx xxxxxxxxxx xx xxxx xx


xxxxx xxx:xxxxxx() xxxxxxxx xxxxx. Xx xxxxxxxx xxxxxxxxxxx xx
xxxxxxxxx xx x % xxxxxxxx xx xxx xxxxx, xxx xxxxx xx xxx xxxxx, xxx
xxx xxxxx xxxx. Xx xxx xxxxx xxxx:
<output> jcs:printf("%-10s%-10s", "OSPF", "ISIS" );

Xxx %-10x xxxxxxxxx xxxx x xxxxxx xxxxx xx xxxxxxxx xx x 10 xxxxx


xxxxxx xxxx xx xxxx xxxxxxxxx. Xxxx xx xxxxxxxx xxxxx, xxxx xxx
“XXXX” xxx xxxx xxx “XXXX”. Xx xxx xxxxxx xxxx:
<output> jcs:printf("%10s%10s", "OSPF", "ISIS" );

Xxx xxxx xxx xxxxxx xx xxxxxx xxx xxx xxxx xxx xxxx xxxx xxx – xxxx,
xxxxx xxxxxx xxxx xx xx xxxxx xxxxxxxxx. Xxxx xx xxx xxxxxx xxxx xx
xxxxxxxxx xxxxx xx xxx xxxxx xxxxx xx xxxx xxxxx:
user@Junos> op show-pretty-output
123456789012345678901234567890
OSPF ISIS
OSPF ISIS

Xxxxxxx xxxxxx xxxxx xx xxx xxx:xxxxxx() xxxxxxxx xx xx xxxxxx xxx


xxxxxxx xxxxxx xxxx xxxxx xxxx xx xxxx xxxxxxxxx xx xxx xxxxxx
Xxxxx xxxxxxxxxxx xxxxxxxx.

Try It Yourself: Working with Functions


Create a new script with a variable assigned to the value “Juniper Networks”. Output the
following to the console on separate lines:
1. The variable value
2. The variable value - right justified in a 20 space field
3. The string length of the variable
4. The substring before the space
5. The string converted entirely into uppercase
Chapter 4: Communicating with Junos 47
46 This Week: Applying Junos Automation

Xxxxxxxx 2 xxx 3 xxxxxxx xxxx xx xxx xxxxxxxxx XXXX xxxxxx xxx


xxxxxxxxxx xxxx xx xxxxx xxxxxxxxxx xxxxxxx, xxx xxx xxxx xxxxxxxxx
xx Xxxxx xxxxxxxxxx xx xxxxxxxxxxxx xxxxxxx xxxxxx xxxxxxxxxxxxx
xxxx Xxxxx xxxxxxx. Xxxx xxxxxxx xxxxxxxxx xxx xxxxxxx xxxx xxxxxx
xxx xxxxxx xx xxxxxxxx xxxx x Xxxxx xxxxxx, xxxxxxxxx xxxxxxxxx xx
xxxxxxxxxxx xxxxxxxxxxx, xxxxxxx xx xxx xxxxxx, xxx xxxxxxx xxxx
xxx xxxxxxxxxxxxx.

Invoking Operational Commands


Xxxx xxxxxxxxxxx xxxxxxxx xxxx xxx xx xxxxxxxx xxxxxxxx xx xxx
Xxxxx XXX xxxxxx xxx xxxx xx xxxxxxx xxxxxx xx xxxxxxxxxx xxxxxx.
Xxxxx xxxxxxxxx xxx xxxxxxxx xx xxx xxxx xxxxxx xx xx xxxx xxxx xxx
xxxx xxx XXX. Xxxxxxx, Xxxxx xxxxxxxxx xxxxx xxxxxx xx XXX xxx
xxxxxxxx xx xx xxx xxxxxx. Xxx xxxxxx xxx xxxx xxxxx xxx xxxxxxx xxx
xxxxxxx xxx xxxxxxx xxxxxxx xxxxx xx xxx xxxxxxxx xxxxxxxxxxx.

Junos XML API


Xxxxxxxx xxxxxxxxxxx xxxxxxxx xx Xxxxx xx xxxxxxxx xxxxxxx xxx xx
xxx Xxxxx XXX XXX. Xxx xxxxxx xxxx xxxxx XXX Xxxxxxxx xx Xxxxx,
xxxxx xxxx xxxxxxxxx xxx xxxxxxxx xxxxxxxx, xxxxxxxx xxx
xxxxxxxxxx xxxxxxx, xxx xxxxxxx xxx xxxxxxx xx xxx xxxxxx.
Xxxx xxxxxxxxxxx xxxxxxxx xxx xxxxxx xxxxxxxx xx xx XXX Xxxxxxx.
Xxx xxxxxxx, xxx “xxxxx xxxxxxxxxx xxxxxxxxxx” XXX xxxxxxx xx xxxxxx xx
<xxxxx-xxxxxxxxxx-xxxxxxxxxx>. Xx xxx xxx xxxx xx xxxxxxx xxxxxxx XXX
xxxxxxxx xxx XXX Xxxxxxxx xxxxxxx xxx Xxxxx XXX Xxxxxxxxxxx XXX
Xxxxxxxxx Xxxxx (xxxx xxxxxxxx xxx xx Xxxxx 4.1). Xxxxxxxxxxx
xxxxxxxx xxxx xx xxx xxxx x xxxxxxxx XXX Xxxxxxx xxx xx xxxxxxxx xx
xxxxx xxx <xxxxxxx> xxxxxxx xxxx xxx XXX xxxxxxx xx xxx xxxx
xxxxxxx:
<command> "show route";

Table 4.1 API Element Examples

jcs:invoke()
Xxx Xxxxxx xxxx xxxxx XXX xxxxxxxx xx Xxxxx xx xxxxxxx xxx
xxx:xxxxxx() xxxxxxxx xxx xxxxxxxxx xxx xxxxxxx xx xx xxxxxxxx. Xxx
XXX Xxxxxxx xxx xx xxxxxxxxx xxxxxx xxxxxxx x xxxxxx xxxx xxxxxxxx
xxxxxxxx, xx xx xxx xx x xxxxxx xxxxxxxxxx xxx XXX Xxxxxxx’x xxxx.
Xxx xxxxxxx xxxx xxx:xxxxxx() xxx xxxxxxxx xx x xxxx-xxx xxx xxxxxx xx
xxxxxxxx xx x xxxxxxxx:
var $clear-statistics-rpc = <clear-interfaces-statistics-all>;
var $results = jcs:invoke( $clear-statistics-rpc );
or
var $results = jcs:invoke( "clear-interfaces-statistics-all" );

Xx xxxx xxxxx, xxx xxxxx xxxxxxxxxx xxxxxxxxxx xxx xxxxxxx xx xxxxxxx, xxx
xxx XXX xxxxxxx xxx xxxxxxxx xx xxx $xxxxxxx xxxxxxxx. Xxx
xxxxxxxxxx xxxxxxx xxxxxxxxxx xxx XXX Xxxxxxx xx XXX xxxxxx
xxxxxxxxx xxx xxxxxx xxxx xx xxxx XXX xxxxxxxxxx, xxxx xxxxxxx, xxx
xxxxx xxxxxxxx xxx xxxx xx xxxxxxxx xxxx xxx XXX Xxxxxxx xx
xxxxxxxxx xx xx XXX xxxx xxxxxxxxx xxxxxxxx xx x xxxxxxxx xxxx xx
xxxxxx xx xxx:xxxxxx(). Xxxxx xxxx xxxxx xxx xxxxxxxxx xx xx xxxxxxx xx
xxxxxxxx xx x xxxxxxx-xxxx xxxxxxxx:
/* clear-statistics.slax */
version 1.0;
ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
import "../import/junos.xsl";

/* This is imported into the Junos CLI help text */


var $arguments = {
<argument> {
<name> "interface";
<description> "Clear the specified interface statistics";
}
}

/* Command-line argument */
param $interface;

match / {
<op-script-results> {
/* Junos XML API Element to clear specific interface statistics */
var $clear-statistics-rpc = <clear-interfaces-statistics> {
<interface-name> $interface;
}

/* Send XML API Element to Junos through jcs:invoke() */


var $results = jcs:invoke( $clear-statistics-rpc );

/* Copy XML contents of $results to the result tree */


copy-of $results;

}
}

Xx xxxx xxxxxxx, xxx <xxxxx-xxxxxxxxxx-xxxxxxxxxx> XXX Xxxxxxx xx xxxx


xx xxxxx xxx xxxxxxxxxx xx xxx xxxxxxxxx xxxx xx xxxxxxxxx xxxxxx
xxx xxxxxxx-xxxx xx xxx xx xxxxxx. Xxx XXX Xxxxxxx xx xxxx xx Xxxxx
xx xxx xxx:xxxxxx() xxxxxxxx xxx xxx xxxxxxx xx xxx xxxxxxxxx xxx
xxxxxx xx xxx $xxxxxxx xxxxxxxx.
Xxxxxxx, x xxx xxxxxxxxx xxx xx xxxx xx xxx xxxxxx: xxxx-xx. Xxx xxxx-xx
xxxxxxxxx xx xxxx xx xxxx xxx xxxxxxxx xx x xxxxxx xxxx xxxxxxxx
xxxxxxxx xx x xxxx-xxx xx xxx xxxxxx xxxx. Xxx xxxxxx xxxx xxxxx
xxxx xxxx xx xxxxxxxxxxx xxx xxxxx xxxxxxxx. Xx <xxxxx-xxxxxxxxxx-
xxxxxxxxxx> xxxxxxxx xxxxxxxxxxxx xxxx xx xxxxxx xx xxxxxxxx, xxx xx
xxxxx xx xx xxxxx xxxx x <xxx:xxxxx> xxxxxxx xx xxxxxxxx xxxx x
<xxxxxxx> xxxxx xxxxxxx. <xxx:xxxxx> xx x xxxxx xx xxxxxx xxxxxx xxxx
xxxxxxx, xx xxxxxxx xx xx xxx xxxxxx xxxx xxxxxx xxx xxxxxxxx
<xxxxxxx> xx xx xxxxxxxxx xx xxx xxxxxxx xx xx xxxxx xxxxxxx:
user@Junos> op clear-statistics interface ge-13/0/0
error: device ge-13/0/0 not found

NOTE The Junos device processes the received API Elements from jcs:invoke()
immediately rather than waiting for the script to terminate as with the
result tree.
ALERT! All Junos commands and configuration requests performed through op
scripts follow the same permission process as if the command were
entered at the CLI. In both cases, Junos checks permission levels to verify
that the user has access to that command or configuration hierarchy.
Try It Yourself: Invoking Junos Operational Commands

Following the example of the clear-statistics op script shown in this section, create an op script
that reboots the system. (Hint: The XML API Element needed is <request-reboot>).

Retrieving Data
Xx xxx xxxx xxxxxxx, xxx xxxxx xxxxxxxxxx xxxxxx xxxx xxx xxxx-xx
xxxxxxxxx xx xxxx xxx XXX xxxxxxxx xx xxx $xxxxxxx xxxxxxxx xx xxx
xxxxxx xxxx. Xxx xxxx xxxxxxx xxxx xxxxx xxxxxxxx? Xxx xxxxxxxx xxx
xx xxx xxxx XXX xxxxxxx xxx xxxxxxxx xxxx xxx:xxxxxx() xx xx xxx xxx
xxxxxxx xxxxxxxx xxxx | xxxxxxx xxx xxxxxxxx:
user@Junos> op clear-statistics interface ge-13/0/0 | display xml
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/9.0R4/junos">
<xnm:error xmlns="http://xml.juniper.net/xnm/1.1/xnm">
<source-daemon xmlns="">
ifinfo
</source-daemon>
<message xmlns="">
device ge-13/0/0 not found
</message>
</xnm:error>
<cli>
<banner></banner>
</cli>
</rpc-reply>

Xxxx xxx:xxxxxx() xxxxxxx xxx XXX xxxxxx, xx xxxxxxx xxx xxxxx xxxxxxx
xx <xxx-xxxxx> xx xxx $xxxxxxx xxxxxxxx. Xx xxxx xxxx xxxx xx
Xx xxx xxxxx xxxxxxxxxx xxxxxx xxx xxxxxxxx XXX xxxx
<xxx:xxxxx>.
xxxxxxxxx xx xxxx xxxxxx xxxx xxx xxxxxx xxxx. Xxx xxxxxxxx xxx
xxxxxxxxx xxxxxxxxxxxx, xxxxx xxxxxx x xxxxxxx xxxxxxx xx xx
xxxxxxxxx xxxx xx xxxxx xxxxxx:
/* clear-statistics.slax */
version 1.0;
ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
import "../import/junos.xsl";

/* This is imported into the Junos CLI help text */


var $arguments = {
<argument> {
<name> "interface";
<description> "Clear the specified interface statistics";
}
}

/* Command-line argument */
param $interface;

match / {
<op-script-results> {

/* Junos XML API Element to clear specific interface statistics */


var $clear-statistics-rpc = <clear-interfaces-statistics> {
<interface-name> $interface;
}

/* Send XML API Element to Junos through jcs:invoke() */


var $results = jcs:invoke( $clear-statistics-rpc );

/*
* Check if <xnm:error> is part of $results, if it is then
* copy the output to the console. Otherwise show the success
* message.
*/
if( $results/..//xnm:error ) {
copy-of $results;
}
else {
<output> "Statistics Cleared";
}
}
}

Xxx xxxxxx xxxx xx xxx xxxxxxxx xx xx xx xxxxxxxxx xxxx xxx


xxxxxxxxx xxxx: $xxxxxxx/..//xxx:xxxxx. Xxxx xx xx xxxxxxx xx x xxxxxxxx
xxxx xxxx xxxxx xxxx xxxx xxx XXX xxxx xxxxxxxxx xxx xxxxxxx xx xx
xxx $xxxxxxx xxxxxxxx. Xx x <xxx:xxxxx> xxxxxxx xx xxxxxxx xx xxx
xxxxxxx xxxx xxx xxxxxxxxxx xxxxxxxxx xx xxxx xxx xxx XXX xxxxxxxx
xx $xxxxxxx xxx xxxxxx xx xxx xxxxxx xxxx. Xxxxxxxxx "Xxxxxxxxxx
Xxxxxxx" xx xxxxxx xx xxx xxxxxxx xxxxxxx xxxx xxx xx xxxxxx xxx
xxxxxxxxxxxx xxxxxxx xxx xxxxxxxxx xxxxxxxxxx.

Location Paths
Xxxxxxxx xxxxx xxx xxxx xx xxxxxxx xxxx xxxx xx XXX xxxxxxxxx. Xxxx
xxxxxx x xxxxx xxxxxx xxxx xxxxxxxx xxxxx xxxxx xxxxxx xx xxxxxxxxx
xxx xxxxxxxx xxxxxx xxx xxxxxx. Xxx xxxxxxx xx x xxxxxxxx xxxx xxx
xxxxxxxxxxxx xx x xxxx-xxx xxxx xxx xx xxxxxxxx xx x xxxxxxxx xx
xxxx xxxxxx x XXXX xxxxxxxxx xxxx xx xx xx xxx-xxxx.
Xxxx xxxxxxx xxxxx xxxxxx xxxxxxxxxx xxx xxxxxxx xxx xxxxx xx
xxxxxxxx xxxxx. Xxxxxxxx xxx xxxxxxxxx XXX xxxx xxxxxxxxx:
<system-uptime-information xmlns="http://xml.juniper.net/junos/9.0R4/junos">
<current-time>
<date-time junos:seconds="1242673659">2009-05-18 12:07:39 PDT</date-time>
</current-time>
<system-booted-time>
<date-time junos:seconds="1242424838">2009-05-15 15:00:38 PDT</date-time>
<time-length junos:seconds="248821">2d 21:07</time-length>
</system-booted-time>
<protocols-started-time>
<date-time junos:seconds="1242424912">2009-05-15 15:01:52 PDT</date-time>
<time-length junos:seconds="248747">2d 21:05</time-length>
</protocols-started-time>
<last-configured-time>
<date-time junos:seconds="1242424900">2009-05-15 15:01:40 PDT</date-time>
<time-length junos:seconds="248759">2d 21:05</time-length>
<user>root</user>
</last-configured-time>
<uptime-information>
<date-time junos:seconds="1242673659">12:07PM</date-time>
<up-time junos:seconds="248851">2 days, 21:07</up-time>
<active-user-count junos:format="2 users">2</active-user-count>
<load-average-1>0.00</load-average-1>
<load-average-5>0.00</load-average-5>
<load-average-15>0.00</load-average-15>
</uptime-information>
</system-uptime-information>

Xxxx xx xxx XXX xxxxxx xx xxx xxxxxxxxxxx xxxxxxx xxxx xxxxxx xxxxxx
(xxx XXX Xxxxxxx xx <xxx-xxxxxx-xxxxxx-xxxxxxxxxxx>). Xxxx xxxx xxxxxxx
xx xxxxxxxx xx xxx:xxxxxx() xxx <xxxxxx-xxxxxx-xxxxxxxxxxx> xxxxxxx xx
xxxxxxxx xx xxx XXX xxxxxx. Xxxx xxxx XXX xxxx xxx xxxx xxxxxxxxx
xxx xxxxxx xxxx x xxxx-xxx xxxxxxxx xx xx xxxxxxxx xxx xxxxxxxx
xxxxx xx xxxxxxx xxx xxxxxxxx xxxxxxxxxxx.
Xxxxx xxxxxxxx xxxxx xx xxxxxxx xx xxxxxxxx xxxxx xxxxxx x xxxx
xxxxxx. Xxx xxxxxx xxxxxx xx x xxxxxxxxxx xxxxxxxxx xxxxx xxx xxx
xxx xx xxx xxxxxxx xxxxx / xxxxxxxxx xxxx xxx xxxxxx xxxx xxxx xxxx
xx x xxxxx xx xxx xxxxxxx xxxxxxxxx xxxxx. Xx xx xxxxxxx, xxxxxx
xxxx $xxxxxx xx xxx xxxx xx xxx xxxx-xxx xxxxxxxx xxxxx xxx xxxx
xxxxxxxx xxx xxxxx XXX xxxx xxxxxxxxx. Xx xxx xxxx-xxxx xxxxx xx
xxxxxxx xxxx xx xxx xx xxxxxxxxx xxxx xxx xxxxxxxxx xxxxxxxx-xxxx:
$results/system-booted-time/date-time

Xxxx xxxxxxx xxxx xxxxx xx xxxxxxxx xx xxxxxxx xxxxxxxx:


var $date-time = $results/system-booted-time/date-time;

Xx xxx xxxx xxxxx xx xxx xxxx-xxxx xxxxxxx xxxx xxxxx xx xxxxxx xx


xxx xxxxxxx:
<output> $results/system-booted-time/date-time;

Xxxxxxxxx xxx xxxxxxxx xxxx xxxxx xxxxx, $xxxxxxx xxx x xxxxxxx


xxxxxxxxx xxxxx xx xxx <xxxxxx-xxxxxx-xxxxxxxxxxx> xxxxxxx xxxx. Xxxx
xx xxx xxxxxxxx xxxxxxx xxxx xxxx xxxxx xxx xxxxxxxx xxxxx xxxxxxx
xxxxx xxxx xxxxxxxx xxx xxxxx.
TIP An easy way to verify the starting reference point of a variable is to use
the name() function. For example: <output> name( $results ); would display the
XML element name to the console.
Xxx / xxxxxxxxx x xxxxxxxx xxxx xxxx. Xxxx xxxxxx x xxxx, xxx xxxxxxx
xxxxxx xx xx xxxx xx xxx xxxxx xx xxx xxxxxxx xxxx. Xxx xxxxxxxx
xxxx xxxxxxx xxxxxxxxx <xxxxxx-xxxxxx-xxxx> xx xxx xxx xxxxx xxxxx xx
<xxxxxx-xxxxxx-xxxxxxxxxxx> xxxx xxx xxxxx <xxxxxx-xxxxxx-xxxx> xxx
xxxxxxxx (xx xxxx xxxx, xxxx xxx). Xxxx xxx xxxxxx / xxxxxxxxx
xxxxxxx xxxxxxxx xxxx xxxx. Xxx xxxxxxx xxxx xxxxxx xxx xxxxxxxx
xxxx xxxxxxx xx xxxx xxxx, xxx xx xxx xxxxxx xxx <xxxxxx-xxxxxx-xxxx>
xxxxxxx. Xxxx xxxxx xxx xxxxxxx xxxx xx xxxx xx xxxxxx xxx x xxxxx
xxxxxxx xxxxx <xxxx-xxxx> (xxxxx xx xxxx xxx xx xxxx xxxxxx). Xxxx xx
xxx xxx xx xxx xxxxxxxx xxxx xx xxx <xxxx-xxxx> xxxxxxx xxxx xx
xxxxxxxx. Xxxxxxxx xx xxxxxxxx xxxxx xxxxx xxx xxxxx XXX xxxx
xxxxxxxxx:
Xxx xxx xxxxxx xxxxxx xxxx xxxx?
If( contains( $results/system-booted-time/date-time, "2009" ) ) {
/* conditional code goes here... */
}

Xxx xxxx xxxxx xxx xxxxxxxxx xxxxxx?


var $user-count = $results/uptime-information/active-user-count;
NOTE A // can be used instead of a / if the location path should match on the
desired child node, no matter how deep into the hierarchy it appears. For
example $results//active-user-count would return the same output as
$results/uptime-information/active-user-count.

Parent Axis
Xx xxxxxxx, xxx xxxxx xxxx xx xxxx xxx xxxx xxxxxxxx xxxx xxxx, xxx
xxxx xx xxx xxxxxx xxxxx xx xx xx xxx xxxxxxxx xxxxxxxxx?
Xxxxxx xxx xxxxxxxxx xxx xxxx xxx xx xxx xxxxxxxx-xxxxxxxx:
var $results = jcs:invoke( "get-system-uptime-information" );
var $date-time = $results/system-booted-time/date-time;
call display-boot-time( $date-time );

Xxx xxxxxxx-xxxx-xxxx xxxxxxxx xxx xxxx xxxxxx xxxx xxx $xxxx-xxxx


xxxxxxxxx xxx xx xxx $xxxx-xxxx xxxxxxxx xx xxx xxxxxxx xxxxxxxx,
xxxxx xxxxxxxx xx x xxxxxx xxxxxxx xxxx <xxxx-xxxx>. Xxx xxx xxxxxxx-
xxxx-xxxx xxxxxxxx xx xxxxxxxx xx xxxxxxx xxxx xxx <xxxx-xxxx> xxxx
xxxxx xx xxxx xx xxx xxxxxxx xxxxxxx <xxxx-xxxxxx>. Xx xxxxx xx xx
xxxx, xxxxx xxxx xx xxxx xxx xx xxxxxxxx <xxxx-xxxxxx> xxxxx xxxxxxxx
xxxx <xxxx-xxxx> xx x xxxxxxxxx xxxxx.
Xxx xxxxxxxx xx xx xxx xxx xxxxxx xxxx xxxxxxx xx xxx xxxxxxx xxxxx
xxxx. Xxxx xx xx xxxxxxx xx xxx xxx xxxxxxxx xxxxx xx xxxxxxx xx
xxxxxx xxxx xx xxx xxxxxxx xxxx xxxxxx:
template display-boot-time( $date-time ) {
<output> "Here is the boot time: " _ $date-time;
<output> "Here is the time length: " _ $date-time/../time-length;
}

Xxxx xxxxxxxx xxxxxxx xxxx xxx <xxxx-xxxx> xxxxxxx xxxx xxxxx xx


xxx xxxxxxx xxx xxx <xxxx-xxxxxx> xxxxxxx xxxx xxxxx. Xxx $xxxx-xxxx
xxxxxxxxx xx xxxxxxxxxxx xx xxx <xxxx-xxxx> xxxx xx xxx xxxxx xxxxxx
xxxx xxx xx xxxxxxx xx xxxxxxxxx xx xxx xxxxxxxx xxxxxx. Xxx xxx
xxxxxx xxxx x xxx xxxxxxxx xxxx xxxxxxxx xx xxxxxxxxxx: xxx .. xxxxxx
xxxx xxxxxxxxxxxx. Xxxx xxxx xxxx x xxxx xxxxxx xx .. xxxxxxx xxx ..
xxxxxx xxx xxxxxxxx xxxx xx xxxxxx xxx xxxxxx xx xxx xxxxxxx xxxx
xxxxxx xxxx xxx xxxxxxxx. Xx xxx xxxx xxxx xxxx <xxxx-xxxx> xx xxx
<xxxxxx-xxxxxx-xxxx> xxxxxx. X xxxxxxxxx / xxxxxxxxx xxxxxxx xxxx, xxxx
xxxx xxxxx xxx xxxxxxx xxxxx xxxx, xxxxx xxxxx xxx xxxxxxx xxxx
<xxxx-xxxxxx> xx xxxxxxxx.

Attribute Axis
Xxx xxxxx xxx xxxxxx xxxx xxx xxx xxxx xxxxxxxx xxxx xxxx xxxxxx
xxxxxxxx xxxxx. Xxx xxxx xxxx xxxxxx xxxx xx xxx xxxxxxxxx xxxx. Xx
xx xxxxxxx xxxx xxxx xxxx xxxxxxxxx xxxxx xxx xx xxxxxxxxx xxxx XXX
xxxx xxxxxxxxxx.
Xxxx x xxxx xx xxx <xxxxxx-xxxxxx-xxxxxxxxxxx> XXX xxxxxx xxxxx xxx
xxxx xxx xxxxxx xx xxxxx:xxxxxxx xxxxxxxxxx xxxx xxx xxxxxxxx. Xxx
xxxxx xxxx xxxxxx xxxxx xx xxxx x xxxxxxxxxxxxx xxxxx:xxxxxxx
xxxxxxxxx xxxxxxx xx xxx xxxxxxx. Xxxx xxxxxxxxx xxxxxxxx xxx
xxxxxx xxxxx xx xx xxxxxxxxxxx xx xxx xxxxxxxx xxxx/xxxx xxxxxx.
Xx xxxx xxxxxx xxxxx xx xxxxxxx xxxxxxx xx xxx xxxx xxxxxxx xxxxxx
xxxx xx xxx xx xxxxxxxxx xxxxxxx xxx xxxxxxxxx xxxx, xxxxx xx
xxxxxxxxx xx xxxxx xxx @ xxxxxxxxxxxx:
var $results = jcs:invoke( "get-system-uptime-information" );
var $date-time = $results/system-booted-time/date-time/@junos:seconds;
<output> "Boot time seconds: " _ $date-time;

Xx xxxx xxxx xx xxxxxxxxxx xxxxxxxx xxxx xxxx xxx xxxx xxxxx.


Xxxxxx xxxx xxxxxxxx xx xxx xxxx-xxxx xxxx, xxx xxxxxxxx xxxx xxxx
xxxxxxx xxx xxxxxxxxx xxx xxxxx:xxxxxxx xxxxxxxxx xxxx xx xxxxx xxx
xxxxxxxxx xxxx xx xxxxxxx xx xxx @. Xx x xxxxxx, xxx $xxxx-xxxx
xxxxxxxx xx xxxxxxxx xx xxx xxxxxxxxxxxx xxxxx, xxxxx xx xxxx
xxxxxx xx xxx xxxxxxx.
MORE? There are thirteen different axes that can appear in a location path but
most are rarely used. To read about the other location path axes consult
the XPATH specification: http://www.w3.org/TR/xpath#axes/.
Predicates
Xx xx xxxxx xxxxxxxxx xx xx xxxx xxxxxxxxx xxxxx xxxxx xxxxx xxx
xxxxxxxxx xxxx xx xxxxx xx xxx xxxxx xxxxxxxx. Xx xxxxx xxx
xxxxxxxx xxxxxxxxxxx xx x xxxx xx xxx xxxx xxxx xxxx xxxxxxxx xxxxx,
xxxxx xx xxx xxxxxx xxxxx, xxxxx xxxxxx xxx xx xxxx xxxxxxx xx xxxx
x xxxxxx xxxx. Xx xxx xxxx xx xx xxxxxxx xxx xx xxx xxxxxxxx xxxxx xx
xxx xxxx xxxxxx xxxx xxxx xxxxx xx xxx xxxxxxx xxxxxxxx. Xxx xx xxx
xxxxxx xx xx xxxx xxxxxxx x xxxxxxxx xxxx xxxxx xxxxxxxxxxx xxxxx
xxxxx xxxx x xxxxxxxxx xxxx xx xxxx xx xxxxxxxx xxxx xxxxxx xxx
xxxxxxxx xxxx.
Xxx xxxxxxx, xxx xxxxxx xx xxxx xxxxxxxxx xxxxx xxxxxxxx xxx xxx
xxxxxxxxxx xxxxxxxxx xx xxx Xxxxx xxxxxx. Xxx xxxxxxxxxxxxx <xxx-
xxxxxxxxx-xxxxxxxxxxx> XXX Xxxxxxx xxxxxxx xxx xxxx xxxx xx
xxxxxxxxxx. Xxxx xxxxx xx xxxx x xxxxxx xxxxx, xx xx xxxxx xxx. Xx’x
xxxxxxxxx xx xx xxxxx xx xxx xxxxxxx xxxxxxxx – xxxxx xx xx xxxxxx
xxx xx xxx xxxxx xxxx xxx xxxx xxxx – xxx xx xxxx xxx xx xxxxxxx xxx
xxxxxxxx xxxx xxxxx xxxxxxxxxx xxxx x xxxx xxxxxxxx xxxxx xx
xxxxxxx.
Xxxxxxxxxx xxx xxxxxxx xxxx xxxxxxx xxx-xxxxxxxx xxxxx xxxx xxxxx
xxxxxxxx xx xxx xxxxxxxx xxxx xxxxxx. Xxx xxxxxxxxx xxxxxxxxxx xx
xxxxxxxx xxxxxx xxxxxxxx [ ] xxx xxxxxxx:
var $get-interface-rpc = <get-interface-information> {
<terse>;
}
var $results = jcs:invoke( $get-interface-rpc );
var $ge-node = $results/physical-interface[name=="ge-1/0/0"];

Xxxx xx xxx XXX xxxxxx xx <xxx-xxxxxxxxx-xxxxxxxxxxx> <xxxxx> :


<interface-information>
<physical-interface>
<name>ge-1/0/0</name>
<admin-status>up</admin-status>
<oper-status>up</oper-status>
<logical-interface>
<name>ge-1/0/0.0</name>
<admin-status>up</admin-status>
<oper-status>up</oper-status>
<address-family>
<address-family-name>inet</address-family-name>
<interface-address>
<ifa-local junos:emit="emit">1.1.1.1/24</ifa-local>
</interface-address>
</address-family>
<address-family>
<address-family-name>iso</address-family-name>
</address-family>
<address-family>
<address-family-name junos:emit="emit">mpls</address-family-name>
</address-family>
</logical-interface>
</physical-interface>
... repeated for every interface
</interface-information>

Xx x xxxxxx xxxx xxx xxxxxxx x xxxxxxxxx, xxx xxxxxxxx xxxx


$xxxxxxx/xxxxxxxx-xxxxxxxxx xxxxxxx x xxxx-xxx xxxx xxx <xxxxxxxx-
xxxxxxxxx> xxxxxxx xxxxx xxx XXX xxx xxxxxxxxxx xx xxx Xxxxx xxxxxx.
Xxx xxxxxxx xxx xxxxxx xxxxxxxx xxx [xxxx==”xx-1/0/0”] xxxxxxxxx, xxx
xxxxxxxx xxxx xx xxxxxxxxxx xx xxxx xxxxxxx xxx <xxxxxxxx-xxxxxxxxx>
xxxxxxx xxxxx xx xxx xxxxxxxx xxxx-xxx xx xxxx xxxx x xxxxx xxxxx
<xxxx> xxxxx xxxxx xx “xx-1/0/0”. Xx x xxxxxx, xxx xxxxxxxx xxxx xxxx
xxxxxxx x xxxxxx <xxxxxxxx-xxxxxxxxx> xxxxxxx xxxx: xxx xx-1/0/0
xxxxxxxxx.Xxxxxxxx xxxxxxxxxx xxx xx xxxxxxxx xxxxxx x xxxxxxxx
xxxx. Xxxx xxxx xxxx xxx xxxxxxxxx xx xxxxxxx xxxx xxx xxxx xxxx
xxxx xx xxxxx. Xxx xxxxxxxxxxx xxxxxx xxx xx xxx xxxxxxxxxx xxxx
xxxxxxxx xx xxxx xx xxx xxxxxxxxx xxxxxxxx xxxx xx xxx xxxxxxxx xx
xxx xxxxxxxx xxxx xxxxxx.
Xxxx xx xxxxxx xxxxx xxx xxxxxxxxxx xxx xx xxxx xx xxxxxxxx xxxxx
xx xxxxxxx xxx xxxxxxx. Xxxxxxxxxx xxx xxxxxx xxxxxxxx xxx xxxxx
xxxxxx xx xxxx x xxxxxx xxxxxxxxx xx xxx xxxxxxx:
/* show-admin-status.slax */
version 1.0;
ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
import "../import/junos.xsl";

/* This is imported into the Junos CLI help text */


var $arguments = {
<argument> {
<name> "interface";
<description> "Show admin status of interface";
}
}

/* Command-line argument */
param $interface;

match / {
<op-script-results> {

/* Junos XML API Element for show interface terse */


var $get-interface-rpc = <get-interface-information> {
<terse>;
}

/* Retrieve the results of the API request */


var $results = jcs:invoke( $get-interface-rpc );

/* Assign all matching nodes from the results to the $admin-status variable */
var $admin-status = $results/physical-interface[name==$interface]/admin-status;

/* Output the interface admin status to the console */


<output> "The admin status of " _ $interface _ " is " _ $admin-status;
}
}

Xxx xx xxxxxx xxxxxx xxx xxxxxxxxx xx xx xxxxxx xxxxxxx x xxxxxxx-


xxxx xxxxxxxx. Xxxx, xxxxx xxxxxxxxxx xxx <xxx-xxxxxxxxx-xxxxxxxxxxx>
xxxxxx xxxx xxx xxx:xxxxxx() xxxxxxxx, xxx xxxxx xxxxxx xx xxxx xxx
xxxxxxxx xxxxxxxxx xx xxxxxxxxx xxxxxxx x xxxxxxxx xxxx xxxx x
xxxxxxxxx xxxxxxxx. Xxx xxxxxx xx xxx xxxxxx xxxxx:
user@Junos> op show-admin-status interface ge-1/0/0
The admin status of ge-1/0/0 is up

Location Path Operators, Abbreviations, and Wildcards


Xxxxx 4.2 xxxxx xxx xxxxxxxxx xxxx xxxxxx xxxxxxxx xxxxx.
Table 4.2 Location Path Operators

Try It Yourself: Retrieving Information from Junos


Create a script similar to the show-admin-status.slax example script above, but instead of the
Admin Status report the MTU of a physical interface to the screen. The interface to be
displayed should be selected through a command-line argument.

Looping with For-each


Xx xxx xx xxxxxxxxx xx xxxx xxxxxxx xxxxxxx xxxxxxxx xxxxx xxxxxx x
xxxx-xxx xx x xxxxxx xx xxxxxxxx xxxxx. Xxx xxx-xxxx xxxxxxxxx xxxx
xxxx. Xx xxxxxxxxx xxx xxxxxx xxxxxx xx xxxxxxx x xxxx xxxxx xxx xxx
xxxxx xxxx xxx xxxx xxxx xxxx xxxxxxx xxx xxxx xxxxx xxx xxxxx xxxx
xxxxx xxx xxxx xxxx xx xxxxxxxxx, xx xxxxx xxxxx xxx xxxxxx xxxxxx
xxxxxxxxx xxxx xxx xxx-xxxx xxxxxxxxx.
Xxx xxxxxx xx x xxx-xxxx xxxx xx xxxxxxx xx xx xx xxxxxxxxx xxx xxx
xxxxxxxx xxxxxx xxx xxxxxxxxxxx xxxxxxx xx x xxxxxxxx xxxx xx xxxx-
xxx xxxxxxxx xxxxxx xxxx x xxxxxxxxxxx xxxxxxxxxx:
for-each( $results/physical-interface/mtu ) {
/* looped code */
}

Xxx $xxxxxxx/xxxxxxxx-xxxxxxxxx/xxx xxxxxxxx xxxx xx xxxxxxxxx xxx x xxxx


xx xxxxx xxxxxxxx. Xxx xxx-xxxx xxxx xxxxx xx xxxx xxxxxxxx xxx xxxx
xxxx xx xxx xxxx xxxx. Xxxx xx x xxxxxx xxxx xxxxxxxx xxx xxx xx xxx
xxxxxxxx xxxxxxxxxx xx xxx xxxxxx:
/* show-mtu.slax */
version 1.0;
ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
import "../import/junos.xsl";

match / {
<op-script-results> {

/* Send Junos XML API Element via jcs:invoke */


var $results = jcs:invoke( "get-interface-information" );

/* Create node list based on location path, loop through each node */
for-each( $results/physical-interface/mtu ) {

/* Output the MTU for all interfaces that don’t have Unlimited MTU */
if( . != "Unlimited" ) {
<output> "The MTU for " _ ../name _ " is " _ .;
}
}
}
}

Xxxxx xxx <xxx-xxxxxxxxx-xxxxxxxxxxx> XXX Xxxxxxx xx xxxx xx xxxxxxxx


xxx xxxxxxx xxxxxxxxxxx, x xxxxxxxx xxxx xxxxx xx xxx xxxxxxxx XXX
xxxx xx xxxxxxxx xx xxx xxx-xxxx xxxxxxxxx. Xxxx xxxxxxxx xxxx
xxxxxxxx x xxxxxx xx xxx xxx <xxx> xxxxxxx xxxxx xxxx xxx xxxxxxxx
xx x <xxxxxxxx-xxxxxxxxx> xxxxxxx xxxx. Xx xxxxx xxxxx, xxx xxx <xxx>
xxxxx xx xxxxxxxx xxxxxxxxxx xxx xxxxxxxx.
Xxxx xxxx xxxx xx xxxxxxxxx xx xxx xxx-xxxx xxxx xxx xxxx xxxx
xxxxxxx xxx xxxx xxx xxx xxx xxx xxxxxxxxx xx xxxxxx xx xxx xxxxxx.
Xx xx xxxxxxxxx xxxxxxxxx xxxx xxxxxxxxxx xxxxxxx x xxxxxxx XXX
(xxxxx XXX xx xxxxxx xx “Xxxxxxxxx”) xxx xxx xxxxx.
NOTE This same behavior is enforced through a location path predicate
instead: $results/physical-interface[ mtu != “Unlimited” ]
Xxx xxxx xxxxxxx xxxx xxx . xxxxxxxxxxxx xx xxxxx xx xxx xxxxxxx
xxxx. Xxxx xxxx xxxxxxx xxx xxxx xxx xxxxxxx xxxx xxxxxxx xx x xxx
xxxx xx xxxxxxxx xxxx xxx xxxx xxxx. Xxx xxxxxxxxxxx xxxxxxxxxx . !=
“Xxxxxxxxx” xx xxxxxxx xx xxx xxxxxxx <xxx> xxxxxxx xxxx xxx x xxxxx
xx “Xxxxxxxxx” xx xxx. Xxxx xx xxxx, xxxx xxx XXX xx xxx xxxxx xx xxx
xxxxxxx.
Xxxx xxx xxxxxxxx xx xxx xxx-xxxx xxxxxxxxx x xxx xxxxxxxxx xxxxx,
xxxxxxx xxxxxxxxx, xx xxx xxxxxxxxx xxx xxxxxxxx xxxxx. Xxxx
xxxxxxxxx xxxxxxx xxx xxxx xxxxx xxxx x xxxxxxxxx xxxxxxx xxxx.
Xxxx xxxxxxx xxxx xx xxx xxxxxxxxx xxxxx xxx xxx xxxxxxxx xxxxx
xxxx xxx xxx xxxxx xx x xxxxxxxx. Xxxx xxxxx xx xxxx xxxx xxxx xxx
xxxxxx:
<output> “The MTU for “ _ ../name _ “ is “ _ .;
Xxx . xx xxx xxx xx xxx xxxxxxxx xxxxxx xx xxx xxxxxxx <xxx> xxxxxxx
xxxx. Xxxxxxxxxxxxx xxx xxxxxxx xxxx xx x xxxxxx xxxxxx xxx xxxxx
xx xx xxxxxxxx. Xxxx, xxxx xxx xxx ../xxxx xxxxxxxx xxxx xx xxxxxxxx
xxxxxxx xxx xxxxxxxx xxxxxxxx. Xxxxxxx, xxx ../xxxx xxxxxxxx xxxx xx
xxxxxxxx xxxxxxx xxx <xxx> xxxxxxx xxxx. Xxxx xxxxxx xxx xxxx xx
xxxxxx xxxxx xxx xxxxxx <xxxxxxxx-xxxxxxxxx> xxxx xx xxx <xxx> xxxx xxx
xxxx xx xxxxxx xxx <xxxx> xxxxx xxxx. Xxx xxxxxx xx xxxx xxx xxxx
xxxx xx xxx xxxxxxxx xxxxxxxxx xx xxxxxxxx xx xxx xxxxxx xxxxxx.

Try It Yourself: Retrieving Information from Junos


Create a script that displays the logical interface MTU of all interfaces within your Junos
device.

Interactive Input
Xxxxxxx 3 xxxxxxxxxxxx xxx xxxxx xxx xx xxxxx xx xxx xx xxxxxx
xxxxxxx xxxxxxx-xxxx xxxxxxxxx. Xxxxxxxxx xx Xxxxx 9.4 xx xx xxxx
xxxxxxxx xx xxxxxx xxxx xxxxx xxxxxxxxxxxxx xxxxxx xxx xxxxxx
xxxxxx xx xxxxx xxx xxx:xxx-xxxxx() xxxxxxxx. Xx Xxxxx 9.6 xxx xxx:xxx-
xxxxxx() xxxxxxxx xxx xxxx xxxxx xx xxxxxx xxx xxxxx xxxxx xxxxxx xxx
xxxxxxx xxxxxx xxxx xxx xxxx.

jcs:get-input() / jcs:input()
Xxx xxx:xxx-xxxxx() xxxxxxxx (xxxxx xx xxx:xxxxx() xx Xxxxx 9.4 xxx 9.5)
xxxxxx x xxxxxx xx xx xxxxxxxxx xx xxx xxxxxxx xxxxx xxx xxxxxx
xxxxxx xxxxxx xxx xxx xxxx xx xxxx x xxxxxxxx xxxx xx xxxxxxxxxx xx
xxx xxxxx xxx. X xxxxxx xxxxxx xx xxxxxxxxx xx xxx xxxx xxxxxxxx xx
xxx xxxxxxxx, xxx xxxxxxx xxxxxx xx xxxxxxxx xx x xxxxxx:
var $user-input = jcs:get-input(“Enter your favorite protocol: “);

NOTE jcs:input() requires Junos 9.4 or above. Starting in Junos 9.6, use jcs:get-
input() instead.

X xxxx xxx xxx xxx:xxx-xxxxx() xx xx xxxxxx xxxxxx xxxxxxxxxxx xxxx


xxxxxxx xxxxxxx-xxxx xxxxxxxxx. Xx xx xxxxxxx, xxxx xx x xxxxxxxx
xxxxxx xxxx xxxxxxxx xxx xxxxx xxxxxx xx xx xxxxxxxxx. Xx xxx x
xxxxxx xxxxxxx-xxxx xxxxxxxx xx xxxxxxxxx. Xx xxx xxxxxxx-xxxx
xxxxxxxx xx xxxxxxx xxxx xxx xxxxxx xxxx xxx:xxx-xxxxx() xx xxxxx xxx
xxxxxxxxx xxxxx:
/* show-admin-status.slax */
version 1.0;
ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
import "../import/junos.xsl";

/* This is imported into the Junos CLI help text */


var $arguments = {
<argument> {
<name> "interface";
<description> "Show admin status of interface";
}
}

/* Command-line argument */
param $interface;

match / {
<op-script-results> {

/* Junos XML API Element for show interface terse */


var $get-interface-rpc = <get-interface-information> {
<terse>;
}

/* Retrieve API results through jcs:invoke */


var $results = jcs:invoke( $get-interface-rpc );

/* Use the command-line argument if provided otherwise ask user through jcs:get-input()
*/
var $interface-value = {
if( string-length( $interface ) > 0 ) {
expr $interface;
}
else {
expr jcs:get-input("Enter interface: ");
}
}

/* Locate the matching node and assign to $admin-status */


var $admin-status = $results/physical-interface[name==$interface-value]/admin-status;

/* Output the interface and status to the console */


<output> "The admin status of " _ $interface-value _ " is " _ $admin-status;
}
}
Xxx xxxxxxxxxx xxxxxxx xxx xxx xxxxxx xxx xxx xxxxxxxx xxxxxxx xx
xxx xxxxxxxx xx xxx $xxxxxxxxx-xxxxx xxxxxxxxxxxxx-xxx xxxxxxxx. Xx
xxx $xxxxxxxxx xxxxxxxxx xxx xxxx xxxxxxx xxxxxxx xxx xxxxxxx-xxxx
(xx xxxxxxxxx xx xxxxxx x xxxxxx-xxxxxx xxxxxxx xxxx 0) xxxx xxx
xxxxxxx xxxxx xx xxxx. Xxxxxxxxx, xxx xxx:xxx-xxxxx() xxxxxxxx xx
xxxxxxx xxxx x xxxxxx xx “Xxxxx xxxxxxxxx:”. Xxx xxxx xxxxx xx xxx
xxxxxxxxx xxxx xxx xxxxxxx xxxxx, xxxxx xxxxx xxx xxxxxxxx xxxxxx
xx xxxxxxxx xx xxx $xxxxxxxxx-xxxxx xxxxxxxx. Xxxx xxx xxxxxxxx xx xxx
xxxx xx xxx xxxxxxxxx xxxxx xx xxxxxxxxx xxxxxxxx xxx xxxxxxxxx
xxxxx xxxxxx xxxx xxx $xxxxxxx xxxxxxxx xxx xx xxxxx xxx xxxxxxxxx
xxxx xx xxx xxxxxxx.
user@Junos> op show-admin-status interface fxp0
The admin status of fxp0 is up

user@Junos> op show-admin-status
Enter interface: fxp0
The admin status of fxp0 is up

TIP The result tree is only processed after a script is executed, but the jcs:get-
input() and jcs:get-secret() functions run as part of the script processing. This
might cause your output to appear in the incorrect order because any
use of the <output> result tree element is only displayed after the script
terminates. An alternative method of writing to the console, which occurs
during script processing, is to use the jcs:output() function. Here is an
example :note that it must always be preceded by the expr statement:
expr jcs:output(“Hello World!”);

jcs:get-secret()
Xxx xxx:xxx-xxxxxx() xxxxxxxx xxxxx xx xxx xxxx xxx xx xxx:xxx-xxxxx()
xxxxxx xxxx xxx xxxx xxxxx xx xxx xxxxxx xx xxx xxxxxx. Xxxx xxxxx
xxx xxxxxxxx xxxxx xxxx xxx xxxx xxxx xxxxx xxxxxxxxx xxxxxxxxxxx
xxxx xx xxxxxxxxx.
ALERT! jcs:get-secret() requires Junos 9.6 or later.

Try It Yourself: Interacting with the User


Modify your script displaying the MTU of a single physical interface. Add a check to see if the
command-line argument for the interface has been entered. If it has not, then request the
information from the user through the jcs:get-input() function.

Writing to the Syslog


Xxxxx xxxxxxx xxx xxxxx xxxxxxxx xx xxx xxxxxx xx xxxxx xxx
xxx:xxxxxx() xxxxxxxx. Xxxx xxxxxxxx xxx xxxxxxxxx. Xxx xxxxx xx x
xxxxxx xxxx xxxxxxx xxx xxxxxxxx xxx xxxxxxxx xx xxxxx xxx xxxxxxx
xxxxxx xx xxxxxx. Xxx xxxxxx xx xxx xxxxxxx xxxxxx xx xx xxxxxx.
X xxxxxx xxxxxx xxxxxxxxx xxx xxxxxxxx xxx xxxxxxxx xxxx x xxxxxx
xxxxxxxxx, xxx xxxxxxx “xxxxxxxx.xxxxx” xx “xxxxxx.xxxx”. Xxx
xxxxxxxxx xxxxxxxxxx xxx xxxxxxxxxx xxx xxxxxx xx Xxxxxx 4.3 xxx
4.4.

Table 4.3 Syslog Facilities


Table 4.4 Syslog Severity Levels

Xxxx xxxxxxxxx xxx xxx:xxxxxx() xxxxxxxx xx x xxxxxx xx xxxx xx


xxxxxxxx xx xxx xxxx xxxxxxxxx. Xxxxx xxxxx xx xx xxxxxx xxxxxxxx xx
xxxxx xx xxx xxxxxx xxxx, XXXX xxxxxxxx xxxx xxxxxxx xxx xx xx
xxxxxxxxx xxxx xxxxxxxx xxxxxxx, xxxx xx xxxx xxx xxxxxx xxxxx:
expr jcs:syslog("external.warn", "The script changed the configuration" );

Xxx xxxxx xxxx xxxxx xxxxxx xx xxx xxxxxxxxx xxxxx xxxxxx xx xxx
xxxxxx:
May 21 21:45:13 Junos cscript: %EXTERNAL-4: The script changed the configuration

Xxxxxx xxxxxxxx xxxx Xxxxx xxxxxxx xxxxxx xxxxx xxxx xxxxxxx: . Xxx
%XXXXXXXX-4 xx xxxxxxx xxxxxxx xxxxxxxx-xxxxxxxx xxx xxxx
xxxxxxxxx xx xxx xxxxxxxxxxxxx xxx xxx xxxxxx xxxx. Xx xxxxx xxxx
xxx xxxxxxx xxx xxxxxx xx xxx xxxxxxx xxxxxxxx xx xxx xxxxxxx
xxxxxxxx.
Xxxx xx xx xxxxxxx xxxxxx xxxx xxxxxx xxx xxxxxxx xxxxxx xxxxxxx xx
xx xxxxxx xxxx xxx XXX. Xxx xxxxxxxx, xxxxxxxx, xxx xxxxxxx xxx xxx
xxxxxxx xxxxxxx xxxxxxx-xxxx xxxxxxxxx:
/* log-message.slax */
version 1.0;
ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
import "../import/junos.xsl";

/* This is imported into the Junos CLI help text */


var $arguments = {
<argument> {
<name> "facility";
<description> "Facility for the syslog message";
}
<argument> {
<name> "severity";
<description> "Severity level of the syslog message";
}
<argument> {
<name> "message";
<description> "Message to send to syslog";
}
}

/* Command-line arguments */
param $facility;
param $severity;
param $message;

match / {
<op-script-results> {

/* Assemble the facility-severity string */


var $facility-severity = $facility _ "." _ $severity;

/* Log message to syslog */


expr jcs:syslog( $facility-severity, $message );
}
}

Xx xxx xxx-xxxxxxx.xxxx xxxxxx xx xxx xxxx xxx xxxxxxxxx xxxxxxxxx:


user@Junos> op log-message facility user severity notice message "Test Message"

Xxxx xx xxxx xxxx xx xxx xxxxxx (xxxx xxxxxxxx-xxxxxxxx xxx):


May 21 21:50:18 Junos cscript: %USER-5: Test Message

NOTE jcs:syslog() requires Junos 9.0 or later.


Try It Yourself: Writing to the Syslog
Create an op script that logs the user name, script, product, and hostname to the syslog from
the user facility with a severity level of info.

Reading the Configuration


Xxxxx xxxxxxx xxx xxxxxxxx xxx xxxxxxx xxxxxxxxxxxxx xx xxxxxxx
xxx <xxx-xxxxxxxxxxxxx> XXX Xxxxxxx xx xxx:xxxxxx():
var $configuration = jcs:invoke( "get-configuration" );

Xxxxx xxx x xxxxxx xx xxxxxxxxxx xxxxxxxxx xxx <xxx-xxxxxxxxxxxxx>,


xxx xxxx xxxxxx xx xxxxx xx xxxxxxxx. Xx xxx xx xxx xx xxxxxx xxxxxxxxx
xx xxxxxxxxx, xxx xx xxxxxxxxx xxxxx xxxxxxxxxxxxx xxxxxxxx xxxxxx
xx xxxxxxxx. Xxx xxxxxxxxx xxxxxxxx xx xxxxxxxx xx xxxxxxx xx xxx
xxxxxxxx xxxxxxxxx xx xxxxxxx.
var $rpc = <get-configuration database="committed">;
var $committed-configuration = jcs:invoke( $rpc );

MORE? Additional attributes is used with the <get-configuration> API Element.


Consult the Junoscript API Guide in the Junos documentation at
www.juniper.net/techpubs/ for more information.
Xxx xxxxxx xxxxxxxxxxxxx xx xxxxxxxx xx XXX xxxxxx xxxxxxxx xxxxxx
x xxxxxx <xxxxxxxxxxxxx> xxxxxxx. Xx xxx xxx XXX xxxxxxxxx xx xxx
xxxxxxxxxxxxx xx x Xxxxx xxxxxx, xxxxxx | xxxxxxx xxx xx xxx xxxx
xxxxxxxxxxxxx xxxxxxx:
user@Junos> show configuration | display xml
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/9.6I0/junos">
<configuration ...attributes were cut... >
<version>9.6I0 [builder]</version>
<groups>
<name>re0</name>
<system>
<host-name>Junos</host-name>
<time-zone>America/Los_Angeles</time-zone>
<snip>

Xxx <xxx-xxxxxxxxxxxxx> XXX Xxxxxxx xxxx xxx xxxx xx xxxxxx xxx


xxxxxx xxxxxxxxxxxxx. Xxxx xxx xxxxxx xxxxxxxx xxxx xxxxxxxx xx
xxx xxxxxxxxxxxxx xxxx xxxxxxx xxxxx xxxxxxxxxxx xxxxxx <xxx-
xxxxxxxxxxxxx>:
var $rpc = <get-configuration database="committed"> {
<configuration> {
<protocols> {
<bgp>;
}
<policy-options>;
}
}
Xx xxxxx xxxxx, xx xxxxxxx x xxxxxx xx xxx xxxxxxxxxxxxx, xxxxxxx
xxx xxxxxxx xxxxxxxxxxx xxxxxx x <xxxxxxxxxxxxx> xxxxx xxxxxxx xx
xxx <xxx-xxxxxxxxxxxxx> XXX Xxxxxxx. Xxx xxxxxxx xxxxx xxxx xxxxxxxxx
xxx xxx xxx xxxxxx-xxxxxxx xxxxxxxxx xxxxxx.
Xxxxxxxxxxxxx xxxxxxxx xxx xx xxxxxxxxx xxxxxxx xxxxxxxx xxxxx xx
xxx xxxx xxx xx xxxxxxxxxxx xxxxxxx. Xxxx xxxxxxx xxxxx xxx xx xx
xx:
/* show-name-servers.slax */
version 1.0;
ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
import "../import/junos.xsl";

match / {
<op-script-results> {

/* Junos XML API Element to retrieve the configuration */


var $config-rpc = <get-configuration> {
<configuration> {
<system>;
}
}

/* Request configuration and assign to $config variable */


var $config = jcs:invoke( $config-rpc );

/* Extract the name-servers from the config and assign to variable */


var $name-servers = $config/system/name-server;

/*
* If no name-servers are present then output message, otherwise
* output all the name-server names/addresses.
*/
if( jcs:empty( $name-servers ) ) {
<output> "There are no name servers defined.";
}
else {
<output> "Here are the name-servers:";
for-each( $name-servers ) {
<output> ./name;
}
}
}
}

Xxx xxxxxx xxxxxx xx xxxxxxxxxx xxx xxxxxxx xxxxxxxxxxxxx xx xxx


xxxxxx xxxxxxxxx. Xxx $xxxxxx xxxxxxxx xxx xxx <xxxxxxxxxxxxx> xxxxxxx
xxxx xx xxx xxxxxxxxx xxxxx, xx xxx xxxxx xxxx xx xxx xxxxxxxx xxxx
xx xxx xxxx xxxxxxxxx xxxxx (xx xxx xxxxxxx: xxxxxx). Xxx xxxxxx xxxx
xxxxx xxx xxx <xxxx-xxxxxx> xxxxxxx xxxxx xxxx xxx xxxxxx xxxxxxxxx
xxxx x xxxx-xxx xxxxxxxx $xxxx-xxxxxxx. Xxxx xxxxxxx xxxx xxxxxxx xx
xxx xxxxx xx $xxxx-xxxxxxx. Xxx xxx:xxxxx() xxxxxxxx xxxxxxx xxxx xx xxx
xxxx-xxx xxxxxxxx xx xxxxx, xxxxxxxxx xx xxxx xxxxxx xxxxx. Xx xxx
xxxxxx xxxx, xx xxx $xxxx-xxxxxxx xxxxxxxx xx xxxxx, xx xxx:xxxxx()
xxxxxxx xxxx, xxxx xxx xxxxxx xxxxxx xxxx xxxxxxx xxxx xxxxx xxx xx
xxxx-xxxxxxx. Xxxxxxxxx, xx xxxx-xxxxxxx xxx xxxxxxx xx xxx
xxxxxxxxxxxxx xxxx x xxx-xxxx xxxxxxxxx xxxx xxxx xxxxxxx xxxxx
xxxxxxx xxxx xxxxxx xxx $xxxx-xxxxxxx xxxxxxxx xxx xxxxxx xxx xxxxxxx
xx xxx xxxx-xxxxxx. Xxxx xx xxx xxxxxx:
user@Junos> op show-name-servers
Here are the name-servers:
192.168.16.10
192.168.35.10

Xxxx xxxxxx xxxxxxx xxxxx xx xxx xxxxxxx-xxxxxxx xxxxxxxxx xxxxx. Xx


xxxxxx xx xxx xx xx xxxxxxxxxx-xxxxxx xxxxxx xxx xxxx xxxxxxxxxx
xxx xxxxxxx xx xxx xx xxxxxxx xx xxx. Xx xxxx xxxxxxx xxx xxxxxx
xxxxxx xxxx xxxx xxxx xxxxxxxxxx:
/* show-routing-options.slax */
version 1.0;
ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
import "../import/junos.xsl";

match / {
<op-script-results> {

/* API Element to retrieve the routing-options configuration in XML */


var $config-rpc = <get-configuration> {
<configuration> {
<routing-options>;
}
}

/* Send API Element to Junos via jcs:invoke and retrieve config in XML format */
var $config = jcs:invoke( $config-rpc );

/* Extract the ASN from the configuration using a location path */


var $asn = $config/routing-options/autonomous-system/as-number;

/* If the ASN is defined then output it to the console */


if( jcs:empty( $asn ) ) {
<output> "There is no ASN defined.";
}
else {
<output> "The ASN is: " _ $asn;
}

/* Extract all the static routes from the configuration using a location path */
var $static-routes = $config/routing-options/static/route;

/* If there are static routes present then loop through and display them */
if( jcs:empty( $static-routes ) ) {
<output> "There are no static routes.";
}
else {
for-each( $static-routes ) {
<output> "There is a static route to " _ name _ " with next-hop " _ next-hop;
}
}
}
}

Xx xxx xxxxxxx-xxxxxxx xxxxxxxxxxxxx xxxxx xxxx xxxx:


<configuration>
<routing-options>
<static>
<route>
<name>10.1.0.0/16</name>
<next-hop>192.168.1.1</next-hop>
</route>
<route>
<name>10.2.0.0/16</name>
<next-hop>192.168.1.1</next-hop>
</route>
</static>
<autonomous-system>
<as-number>65500</as-number>
</autonomous-system>
</routing-options>
</configuration>

Xxxx xxxx xxxx xx xxx xxxxxx xxxx xxx xxxxxx:


user@Junos> op show-routing-options
The ASN is: 65500
There is a static route to 10.1.0.0/16 with next-hop 192.168.1.1
There is a static route to 10.2.0.0/16 with next-hop 192.168.1.1

Try It Yourself: Reading the Junos Configuration

Create an op script that reads the configuration and outputs all the syslog file names to the
console.

Changing the Configuration


Xxxxx xxxxxxx xxx xxxxxxx xx xxxxxxxx, xx xxxx xx xxxxxxx, xxx
xxxxxxxxxxxxx. Xxxx xxxx xx xxxx xxxxxx xx xxxxxxx xxx xxxxxxx
xxxxxxxxxx xxxxxxxxxxxxx xxxxxxx, xxxxxxxx xxxxx xxxx xxxx Xxxxx
xxxxxxxxxxx xx xxxxxx xxxxx xxx xxxxxxxxxxxxx. Xx xx xxxxxxx,
xxxxxxxx x xxxxxxxxxxxx xxxxxx xxxx xxxxx xxx xxxxxxxx xxxxxxxxx
xxx x xxx xxxxxxxxxx xxx xxxx xxxxxxxxxxxxx xxxxxx xxx xxxxxx
xxxxxxxxxxxxx. Xxxx xxxxxxxxx xxx xxxxxxxxxx xx xxxxxx xxx
xxxxxxxxx xxxx xxxx xxxxxxxxxxxxx xxxxxxxx xxx xx xxxxx, xxx xx
xxxxxxxxxx xxxx xxx xxxxxxxxx xxx xxxxx xx xxx xxxxxxxxxxxxx xxxxx
xxx xxxxxxxxxxx xxxxxxxxxx.
Xx xxxxxx xxx xxxxxxxxxxxxx xxx xxx xxx:xxxx-xxxxxxxxxxxxx xxxxxxxx.
Xxxx xxxxxxxx xx xxxxxxxx xx xxx xxxxx.xxx xxxxxxx xxxxxx xxxx xxx
xx xxxxxxxxx xxx xxx xx xxx xx xxxxxxx (xx Xxxxx 9.3 xxx xxxxx).
Xxxxxx xxxxx xxx:xxxx-xxxxxxxxxxxxx x xxxxxxxxxx xxxx xx xxxxxx. Xxxx
xx xxxxxx xxxxxxx xxxxxxxx xxxxx xxxx xxxxx xxx x xxxxxxxxxxxxx
xxxxxx xx xx xxxxxxxxxx:
„„The configuration database is locked.
„„The configuration changes are loaded.
„„The configuration is committed.
„„The configuration database is unlocked.
Xxx xx xxxxx xxxxxxx xxxx xx xxxxxxxxx xx x xxxxxxxx xxxx xx
xxxxxxxxxxxx xxxx xxxxx xxxxx xx xxxxxxx. Xxxxx xxxx xxxxxxxxxxx
xx xxxxxx xxxx xxx xxxxx xxx xxxxxxxxx xxxxxxxx xxxxxx xxxx xx
xxxxxxxxx. Xxxxx xxxxxxxxxxx xxx xxxxx xxxxxxx xx xxx xxx:xxxx()
xxxxxxxx, xxxxx xxxxxxx x xxxxxxxxxx xxxxxxxxxx. Xxxx xxx xxxxxx xx
xxxxx xx xxxx x xxxxxxxxxxxxx xxxxxx xx xxxxxx xxxx xxxxxxxxxx xx
xxx xxx:xxxx-xxxxxxxxxxxxx xxxxxxxx. Xxxxx xxx xxxxxxx xxxx xxxx
xxxxxxxxx, xxx xxxxxxxxxx xxxxxx xx xxxxxx xx xxxxx xxx xxx:xxxxx()
xxxxxxxx.
NOTE The jcs:open() and jcs:close() functions and the jcs:load-configuration template
are only available in Junos 9.3 and beyond.
Xxxxxxxxxxxxx xxxxxxx xxxx xxxx xxx xxx:xxxx-xxxxxxxxxxxxx xxxxxxxx
xxx xxxx xx xxxxxxxxx xxxxxxxxxxxxx xxxx. Xx xxx xxxxx xxx
xxxxxxxxx xxxxxxx xxx xxxxxxxxxxxxx xx xx xxx xxxxxxxx xx
xxxxxxxxx xxxxxx xxxx xxx xxxxxxxxx xxxxxxx xxxx. Xxx xxx:xxxx-
xxxxxxxxxxxxx xxxxxxxx xxxxx xxxxx xxx xxxxxxxx; xx xxxx xxxxx xxx
xxxxxxxxxxxxx xxxxxx, xxxxxxxx x xxxxxx, xxx xxxxxxx xxx xxxxxxxx.
Xxx xxxxxx xxxx xxxxxxx xxx xxxxxxxxxx, xxx xxx xxxxxxxxxxxxx
xxxxxxx xxx xxx:xxxx-xxxxxxxxxxxxx xxxxxxxx xxxxxxx xxx xxxxxxxxxx. Xxx
xxxxxx xx xxxxxxxxx xx XXXX xxxxxxxxxxx XXX xxxxxx xxx xx
xxxxxxxx xxxxxx x <xxxxxxxxxxxxx> xxxxxxx. Xxx xxxxxx xxxxxxxxx
xxxxx xxxx xx xxxxxxxx xxx xxx xxxxxx, xxxxx xx xxxxxx xxxx xxx
xxxxxxxx xxxxxxxxxxxxx:
<configuration> {
<routing-options> {
<static> {
<route> {
<name> "10.3.0.0/16";
<next-hop> "192.168.1.1";
}
}
}
}
Xxx xxxxx XXX xxxxxxxxx xxxxx xx xxxx xx xxx x xxx xxxxxx xxxxx xxx
10.3.0.0/16.
Xxx xxxxxxxx xxxxxxxxxx xxxx xx xxx:xxxx-xxxxxxxxxxxxx xxx $xxxxxxxxxx
xxx xxx xxxxxxxxxx xxx $xxxxxxxxxxxxx xxx xxx xxxxxxxxxxxxx xxxxxx.
Xx xxxxxxx xx xxx xxxxx xxxxxx xx xxxx x xxxxxxxxxxxxx xxxxxx xxx
xx xxxx xx xxx xxxxxxxxx:
/* The configuration change must be defined */
var $configuration-change = <configuration> {
<routing-options> {
<static> {
<route> {
<name> "10.3.0.0/16";
<next-hop> "192.168.1.1";
}
}
}
}

/* A connection must be opened */


var $connection = jcs:open();

/*
* The connection and change are set as parameters to the jcs:load-configuration
* template which performs the change. The := operator is used to ensure that the
* $results variable is a node-set rather than a result tree fragment.
*/
var $results := { call jcs:load-configuration( $connection, $configuration = $configuration-
change ); }
/* Check for errors – report them if they occurred */
if( $results//xnm:error ) {
for-each( $results//xnm:error ) {
<output> message;
}
}

/* The connection is closed */


var $close-results = jcs:close($connection);

NOTE The location path used to check for errors from templates like jcs:load-
configuration is different than the location path for errors from functions like
jcs:invoke(). With jcs:load-configuration the location path is: “$results//xnm:error”.
With jcs:invoke() the location path is “$results/..//xnm:error”. (Both of these
examples assume that the variable name used is $results.)
MORE? Find more examples of op scripts – including a script for configuring
static routes, a script that extracts a policy chain, a script that lets user
self-serve their local account by changing their password, and a script to
change the default behavior of standard operational mode commands –
in the Appendices of this book.

Chapter 5: Introducing Event Scripts 71


70 This Week: Applying Junos Automation

Xxx Xxxxx xxxxxxxxxx xxxxxxx xx x xxxxxxxx xxxx xx xxx Xxxxx


xxxxxxxxx xxxxxx xxxxxxxxx xx xxx Xxxxx xxxxxxxxx xxxxxxxxx
xxxxxxx, xxxxxxxx, xxx xxxxxxxx xxxxxxx. Xxxx Xxxx Xxx xxxxxxxxx
xxxxxxxx xxx xxxx xxxxxxxx xx Xxxxx xxxxxxxxxx xxxxx xx xxx xxxxx
xxxx, Xxxxxxxx Xxxxx Xxxxxxxxxx Xxxxxxxxxx. Xx xxxxxxxx xxx XXXX
xxxxxxxxx xxxxxxxx xxx xxxxxxxxx xxx xx xxx xx xxxxxxx, xxxxx xxx
xxx xxxx xx Xxxxx xxxxxxxxxx xxxxxx. Xxxx, xx xxxxxxxx xxx xx
xxxxxxxxx xxxxxxxxx xxxxxxxxx xx xxxxxx xxxxxx xxxxxxx xxxxx
xxxxxxxx xxx xxxxx xxxxxxx.

Junos Automation Overview


Xxxxx xxxxxxxxxx xxxxxxx xx xxxxxxxxxxxx xx xxxxx xxx xxxxxx xx
xxxxxxxxx xxx xxxxxxxxxx xx xxxxxxxxxx xxxxxxxx xxxx Xxxxx
xxxxxxx:
„„Business rules automation: Compliance checks can be enforced.
Change management helps avert human error.
„„Provisioning automation: Abstracts and simplifies complex
configurations. Automatically corrects errors.
„„Operations automation: Creates customized commands and outputs
to streamline tasks and ease troubleshooting.
„„Event Automation: Pre-defines responses for events, allowing the
Junos device to monitor itself and react as desired.
Xxxxxxx xxxxxxxxxx, Xxxxx xxxxxxxx xxxxxxx xxxxxxxxx xx xxxxx xx
xxxxxxxxxxx xxxxxxx xxxxx, xxxxxxxxxx xxxxxx, xxx xxxxxxxxxx
xxxxxxxxxxx xxxxxxxxxx.

Event Scripts
Xxxx Xxx, Xxxxxxxx Xxxxx Xxxxxxxxxx Xxxxxxxxxx, xxxxxxxxx xxxxx xx
xxxxxxx. Xx xx xxxxxx xx x xxxxxxxxxx xxxxxxx xxxx xxx xx xxxxxxxx
xxxx xxx XXX xxxxxx xx xxx xxxx xxx xx x xxxxxxxx Xxxxx xxxxxxx. Xx
xxxxxxx xxx xxxx xx xxxxxx xxx xxxxxxx xxxxxxx xxxxxxxxxxx, xx
xxxxxxx xxxxxxxxxx xxxxxxxxxxxxx xxxxxxx, xx xx xxxxxxx x xxxxx xx
xxxxxxxxxxx xxxxxxxx. Xxx Xxxxx xxxxxx x xxxx xxx xx xxxxxxxxxx
xxxxxxxxxxxx xxxxxx xxxx xx xxxxxxx xxxxx xxx xxxxxxx. Xx xxxxxxx
xxx xxx xxxxxxxx xxxxxxx xxxxxxxxxx xx xxx XXX xxxxxx, xx xxxx xxxx
xxxxx; xxxx xxx xxxxxxxx xx xx xxxxxxxxxxx xxx xxx xxxxxx xx xxxxx
xxxxxxxxxxxxx xx x xxxxxx xxxxx.
Xxxx xxxxxx xxxx xx Xxxxx xxxxxxxxxx, xxx xxxxxxx xx xxxxx xx
xxxxxx xxxxxx, xx xxx xxxxx xx xxxxx xxxxxxx xxx xxxxx xxxxxxxx.
Xxxxx xxxxxxxxxxxxx xxxxxxxx xxxxx xxxxxxx xx xxxxxxxx xx x xxxxxx
xxxxx. Xxxxx xxxxxx, xxxxx xxx xxxxxx xx xx xxxxxxxxx xxxxxxxx,
xxxxxxx xxxxxx xxxxxxxx, XXXX xxxxx, xxxxxxx xxxxxx, xxx xxxxxxxx
xxxxxx.
Xxxxxxxx xx xxxxxxx xxxxxxx xxxxxxxx xx xxxxxxxx xx x xxxxxxx, xxx
xxxxx xxxxxxx xxxxxxxxxxxxx xxxxxxx xx xxxxxxxx xx xx xxxxx, xxx
xxx xxxxx xx xxxxxxx xxxxxxxxx xxxxx xxxx xxxxxxxxxxxx. Xxxx xxxxx
xx xxxxxxx xxx xxxxxxx xxxxx xxx xxxx xxxxxxxxx xxxxxxxx (XXXX xx
XXXX), xxx xxxx xxxxxx xxx xxxx xxxxxxxxxxx xxxxx xxx xxxxxxxxxx.
Xx xxxx, xx x xxxx xxxxx xx xx xxxxxxxxxxx xx xxxxx xx xx xxxxx
xxxxxx xx xxxxxx xx xx xxxxxx xxxx xx xxxxxxxxxxxxx xxxxxxxx xx xxx
Xxxxx xxxxxx xxxxxxx xx xxxxx xxxxxxxx xxxxxxx xx x xxxx.
Xxxxxxx 8 xxxxxxxxx xxx xxxxxx xxxxxxxxxxxxxxx xxx xxxxxxxxxxxx
xxxxxxxxx xx xxxxx xxxxxxx, xxx xxxx xxxxxxx xxxxx xxxx xx xxxx
xxxxxxxxx xx xxxx xxxxx xxxxxxxxxxxxx. Xxx xxx xxxxx xxxxx xxxxxxx,
xxx xxxx xxxxx xxxxxxxxxxx xxx xxxx xxx xxxx xxxxxx xxxxx. Xx xx
xxxx xxx xxxxxx xx xxxxx xxx xxxxxxx xxx xxxxxxxx – xx xxxxxx xxxxxx
xxxxxxxxx – xxxx xxxxxxxxxxxxx xxxx xx xxxxxx xx xx xxxxxx xx xx
xxxxx xxxxxx.

Event Script Examples


Xxxxx xxxxxxx xxx xxxxxxxx x xxxxxxxx xx xxxxxx xxx xxxxx xx xxx
Xxxxx xxxxxx, xxx xx xxxx xxxxxxxxx xxxxxxxxxxxx, xxx xxxxxxx:
„„In response to a protocol fault, an event script could gather trouble-
shooting information from the local Junos device as well as its
protocol peers. The device could store this information locally or
automatically transmit it to a remote server for storage and
analysis.
„„In response to the time-of-day, an event script could perform
configuration changes, such as automatically enabling specific
firewall filter terms for night time use only.
„„An event script could perform a comprehensive daily configuration
audit to verify the active configuration against a remotely stored
baseline. Execution of the script could correct violations
automatically, or generate a syslog message to report the problem.
„„At hourly intervals, an event script could inspect the Junos device for
ongoing issues requiring operation attention such as core dump files
or active chassis alarms. Appropriate syslog messages could be
logged, reminding operational staff that they must login and
troubleshoot the problem.
MORE? To see more script examples go to the online script library at
www.juniper.net/scriptlibrary.

Advanced Insight Solutions


Xxxxxxxx Xxxxxxx Xxxxxxxxx (XXX) xxxxxxxx xxxx Xxxxxxx Xxxxxxxx
xxx x xxxx xxxxxxx xx xxx xxxxxxxxxxxxx xxxx xxxxx xxxxxxx xxxxxxx
xx xxxxx xxxxxxxxxxxxxxx xxxxxxxxxxxx xxxx Xxxxx xxxxxxx. XXX xx
x xxxxxxx xxxxxxxxxx xxxxxxxx xxx Xxxxx xxxx xxxxxxxxxxx xxx
xxxxxxxxx, xxxxxxxxx, xxx xxxxxxxxxx xx xxxxxxx xxxxxx xxx
xxxxxxxxx. Xxx Xxxxxxxx Xxxxxxx xxxxx xxxxxxx xxx x xxx xxxxxxxxx
xx XXX. Xxxxx xxxxx xxxxxxx xxxxxx xxxx 300 xxxxxx xxxxxx
xxxxxxxxxxxxx, xxxxxxxxx xx xxx xxxxxxxxxxx xxxx xxxxxxxxx xx xxx
Xxxxxxx Xxxxxxxx Xxxxxxxxx Xxxxxxxxxx Xxxxxx (XXXX). Xxxx x
xxxxxxx xxxxxx, xxx xxxxx xxxxxxx xxxxxxxxxxxxx xxxxxx xxx xxx
xxxxxx xxxxxxxxxxxxxxx xxxxxxxxxxx xxx xxxxxx xx xx x xxxxxxxxxxx
xxxxxx. Xxxx xxxxxxxxxxx xxx xxxx xx xxxxxxxxxxxxx xxxxxx xx xx
XXXX xxx xxxx xxxxxxxx xxx xxxxxxx xxxxxxxxxx. Xxxxxxxxxxxx, XXX
xxxx xxxxx xxxxxxx xx xxxxxxxxxxx xxxxxxx xxx Xxxxx xxxxxxx,
xxxxxxx xxx xxxxxxxxx xxxxxxxx.
MORE? For more information on AIS see this webpage:
www.juniper.net/techpubs/software/management/ais/.

Event Policies
Xxxxx xxxxxxx xxx xxx xxxx-xxxxxxxxx, xxxx xxx xxxxxxxxxxxxx
xxxxxxxxx xx xxxxx xxxxxxxx. Xxxxx xxxxxxxx xxx xxxx xx xxx Xxxxx
xxxxxxxxxxxxx; xxxx xxxxxxxx xxx xxxxx xxxxxxxxxx xxxxxx xx
xxxxxxx xxxxxxxx xxxxxxx xx xxxxxxxx xx xxxxxx xxxxxx. Xxxxxxxxx
xx xxxxx xxxxxx xx xxx xx xxx xxxxxxxx xxxxx xxxxxx xxxxxxx xx
xxxxxxxx xx xxxxx xxx xxxxx xx xxxx xxxx. Xxxxxxxx 6 xxx 7 xxxxxxx
xxxxx xxxxxxxx xx xxxxx.
NOTE The Junos operating system divides its functionality into multiple
software processes, known as daemons. This modularization improves
the overall reliability of Junos, as any failures are contained within a
single process rather than affecting the entire operating system. The
event processing daemon is named eventd; it is responsible for handling
all system events. This task includes relaying syslog messages as well
as triggering event policies.

Configuration / Storage
Xxx xx xxxxx xxxxxx xx xxxxxxx xx xxxxx xxxxxx, xxx xxxxxx xxxx xx
xxxxxx xx xxx Xxxxx xxxxxx xxx xxxxxxx xx xxx xxxxxx xxxxxxxxxxxxx.
Xxxxx xxx xxx xxxx xx xxxxx xxx xxxxxx xxxxx xxxxxxx; xxx xxxxxx
xxxx xxxxxxx xx xxx Xxxxx xxxxxxxx xxxxxxx xx xxx xxxxxx. Xx xxxx
xxxxx xxxx xxxxx-xxxxx, xxxxx xxxx xxx xxx xxxxxxxxxx xxx, xx xxxxx
xxxx xxxx xxxx xxxxx xxx xxxxxxxxxxx xxxxxxxxxx xxx xxx xxxxxxxxx xx
xxxxxx xx xxxxxxx Xxxxx xxxxxxx xx xxx xxxxxxxxxxxxx.
MORE? For more information on configuration permissions, see the System
Basics manual within the Junos documentation at
www.juniper.net/techpubs.
TIP Devices with multiple routing-engines must have the script file copied
into the event script directory on all routing-engines. The script must also
be enabled within the configuration of each routing-engine. Typically the
configuration on the other routing-engine is done automatically through
configuration synchronization, but if the configurations are not
synchronized between routing-engines then the script must be manually
enabled on both routing-engines manually.

Before Junos 9.0


Xxxxx xx Xxxxx 9.0, xxxxx xxxxxxx xxxx xxxxxx xxx xxxxxxx xx xxx
xxxx xxxxxx xx xx xxxxxxx. Xxxx xx, xxxx xxxx xxxxx xx xxx
/xxx/xx/xxxxxxx/xx xxxxxxxxx xxx xxxxxxx xxxxx xxx xxxxxx xxxxxxx xx
xxxxxxxxx xxxxx. Xxx xxxxxxx:
set system scripts op file example-event-script.slax

Xxxx xxxxx xxxx xxxxxx, xx xxxxxxxxxx xxxxxx xx xxx xxx


xxxxxxxxxxxxx xxxxxx xxx xxxxxxxxxx xx xx xxxxxx xxx xx xxxxx
xxxxxx. Xxxxx xxx xxxxxx xx xxxxx xxxxxx xxx xx xxxx xxxx xxxx xxx
xxxxxxx xxxx xx xxx xxxx xxx xx x xx xxxxxx. Xxxx xx xxxxxxx xxxxx
xxxxx xxxxxxx xxx xxxxxxxxxxx xx xxxxxxx xxxxxxxx xx xx xxxxx
xxxxxx, xxxxxx xxxx xxxx xxxxx xxxxxxx. Xxx, xxxxxxx xxxx xxxxxxx
xxxxxxxxxxxxx, xxxx xxx xxxxx xxxxxxxx xx xx xxxxx xxxxxxx,
xxxxxxxx xxxx xxxx xxxx xx xxx xxxxx xxxxxx xxxxxxxxxxxx xxxxxxxxx
xx Xxxxxxx 8.

Junos 9.0 and Beyond


Xxxxxxxxx xx Xxxxx 9.0, xxx Xxxxxxx xxxxxxxxxxx xxxxx xxxxx xxx
xxxxxxxxxxxx xx xxxxx xxxxxxx xxxx xxxxxxx xxxxxxxxxxxxx xxxx xxxx
xx xxxxxxx. Xxxxxxx xx xxx xxx xxxxxxxxxxxxx xx xxx xxxxxxxxx xx
xxxx xxxxxxx xxxxxxxxxxxxx xxxxxxx xx xxxxxxx xxx xxxxx xxxxxxx
xxxxxxx x xxxxxxxxx xxxxxxx xxxxxxxx xxx xxxxxxxx xxxxxxxxxxxxx
xxxxxxxxx. Xxxxx 5.1 xxxxxxxxxx xxxxx xxxxxxx.
Xx Xxxxx 9.0 xxx xxxxxxx xxxxxxxx xx xxxxx xxxxxxx xxxxxxx xx
/xxx/xx/xxxxxxx/xxxxx, xxx xxx xxxxxxxxxxxxx xx xxxxxx xxxx xxx xxxxx
xxxxx xxx xxxxx-xxxxxxx xxxxx-xxxxxx xxxxxxxxx. Xxx xxxxxxx:
set event-options event-script file example-event-script.slax

Xxxxx xxx xxx xxxxx xxx xxx xxx xxxxxxx xxx xxxxxxxxxxxxx xxxxxx
xxx xxxxx xxxxxxx, Xxxxxxx xxxxxxxxxx xxxx xxx xxxxxx xxx xxx
xxxxxxxx xx xxx xxxxxxx xxxxx Xxxxx 9.0 xx xxxxx xxxxxxxx. Xxxx xxx
xxxxxx xxxxx xxxxx xxxxxxx xxxxxx xx xxxxxxxx xxxxxxxxxxxx
xxxxxxxxx xx Xxxxxxx 8:
„„Embedded event policies
„„The <event-script-input> XML data
NOTE The <event-script-input> XML data is provided to event scripts starting with
Junos 9.3.
Table 5.1 Event Script Storage and Enablement

BEST PRACTICE Use the new methods to store and enable event scripts unless a Junos
version prior to 9.0 is in use.
NOTE All event policy configuration examples in this book also include the
configuration necessary to enable the event script under event-options
event-script. This statement should be ignored if the event script is being
enabled under system scripts op.

Event Script Execution Message


Xxxxxxxx xx Xxxxx 9.6, Xxxxx xxxx x xxxxxxx xx xxx xxxxxx xxxx xx
xxxxxxxx xx xxxxx xxxxxx. Xxxx xxxxxx xxxxxxx xxxxxxxxx xx xxx
xxxxx xxxxxx xx xxxxx xxxx xxxx /xxx/xx/xxxxxxx/xxxxx (xxx xx x xxxx
xxxxx xxxxxx) xx xxxx /xxx/xx/xxxxxxx/xx.
Xxxx xxx xxxxxxxx xx xxx xxxxxx xxxxxxx:
„„When executed from /var/db/scripts/op:
Aug 19 15:18:55 Junos eventd[949]: EVENTD_ESCRIPT_EXECUTION: Trying to execute the script 'log-message.slax'
from '/var/db/scripts/op/'
„„When executed from /var/db/scripts/event:
Aug 19 15:23:08 Junos eventd[949]: EVENTD_ESCRIPT_EXECUTION: Trying to execute the script 'log-message.slax'
from '/var/db/scripts/event/'

Event Script Boilerplate


Xxxx xxxxxxx Xxxxx xxxxxxx, xx xx xxxx xx xxxxxx xxxx xxxx xxx
xxxxxxxx xxxxxxxxxxx. Xxxx xxxxxxx xxxxxxxxxx xxxxxx xxxxxxx, xx
xxxxx xx xx xxxx xx xxxxxxxx xxx xxxxxxxxx xxxx-xxxxx XXXx.
Xxxxxxx, xxxx xxxx xxx xxxxx xxx xxxxxxxxxxx xxx xxx xxxx xxxxxx
xxxx xxxxxx xx. Xxx xxxxxxxxxxx xxxx xxx xxxxxxx xxxxx xxxxxxx xx
xxxxxx xxxxxxxxx xx xxx xxxxxxxxxxx xxxx xxx xx xxxxxxx. Xxx xxxx
xxxxxxxxxx xx xxx xxx-xxxxx xxxxxx xxxx xxxxxxx, xxxxx xx xxxxxxxx
xx xxx xxxxxxxxxxx. Xx xxxxxxx xxx <xx-xxxxxx-xxxxxxx> xxx xxxx xxx-
xxxxx xxxxxxx, xxx xxxxx xxxxxxx xxx <xxxxx-xxxxxx-xxxxxxx>. Xxxx xx
xxx xxxxxxxxxxx xx xxx xxxx xxxxxxx xxxxx xxxxxxx:
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match / {
<event-script-results> {

/* Your script code goes here */

}
}

xxxxxxx: xxxxx xxxxxxx 1.0 xx xxxxxxxxx xxx xxxx xxxxxxxxx xxxxxxx


xx xxx XXXX xxxxxxxx, xxx xxxxxxx xxxx xx xxxxxxxx xx xxx xxxxxxxxx
xx xxx Xxxxx xxxxxxx.
xx: x xx xxxxxxxxx xxxxxxx x xxxxxxxxx xxxxxx xxx xxx xxxxxxxxxx
xxxxxxxxx XXX. Xxx xxxxxxxxx xxxxx xxxxxxxxxx xxxx xx xxxxxxxx xx
xxx Xxxxx xxxxxxx:
„„ns junos = "http://xml.juniper.net/junos/*/junos";
„„ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
„„ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
Xx xx xxxxxxx xx xxxx xxxx xxx xxxxx xxxxx xxxxxxxxxx xxxx xxxx xxx
xxxxxx xx xxxx xx xxx xxxxxxxxxxx xxxxxx xxxx xxxxxx xx xxxx xxxx
xxx xx xxxx.
xxxxxx: xxx xxxxxx xxxxxxxxx xx xxxx xx xxxxxx xxxx xxxx xxx xxxxxx
xxxx xxx xxxxxxx xxxxxx. Xx xxx xxxxx.xxx xxxxxx xxxxxxxx xxxxxx
xxxxxxx xxxxxxxxx xxx xxxxxxxxxx, xxx xxxxxxx xxxxxx xxxxxx xxxx
xxxx. Xxx xxxxxx "../xxxxxx/xxxxx.xxx"; xxxx xxxx xxx xxxxxxxxxxx xx xxx x
xxxxxx xxxxx xx xxxxxxxxxx xxxx.
xxxxx /: xxxx xxxx xxxxx xx xxx xxxx xxxxxxxx xx xxx xxxxx xxxxxx. Xx
xxx xxxxxxxx xxxxxxxxxxx xx xxxxxxxx xxx <xxxxx-xxxxxx-xxxxxxx> xxxxxx
xxxx xxxxxxx:
match / {
<event-script-results> {

/* Your script code goes here */

}
}

Xxx xxxxxxxxxxx xxxxxxxx xxx <xxxxx-xxxxxx-xxxxxxx> xxxxxxx xx


xxxxxxxx xxxxxxx xxxxx xxxxxxx. Xxx xxx xxxxxxx XXXX xxxxxxxxxx
xxxxxx xxx <xxxxx-xxxxxx-xxxxxxx> xxxx xxxxx xxxxxxx xxxxxxxxxxx xxxx
xxx xxxxxxx xxxxxx xxxx. Xxx xxxxxx xxxxxxxxx xxx xxxxxxxxxxxxx
xxxxxxx xxxxxxxxxx xxxx xxxxxx xx xxxxxxxx xxx XXX xxxxxxxx xxxx
xxxxxx xx xxxxx xx xxx xxxx. Xxx xxxxxxx <xxxxx-xxxxxx-xxxxxxx> xxxxxx
xxxxxx xx xxx xxx-xxxxx xxxxxxx xx xx xxxxx xxxxxx xxxxxx xxxx. Xxxx
xxxxxxx xxxxxxxxx xx Xxxxx xxxx xxx xxxxxx-xxxx xxxxxxxxxxxx
xxxxxxxxxx xxxx xx xxxxx xxxxxx. Xxxxx xx xx xxxxxx xxxxxxxxx xx
xxx <xxxxx-xxxxxx-xxxxxxx> xxxxxxx, xx xxxxxx xxxxxxxx xxx xxxxx
xxxxxxxx. Xxx xxxxx xxxxxxxx xx <xxxxx-xxxxxx-xxxxxxx> xxxxxxx
xxxxxxxxxxxx xxxx Xxxxx xxxxxxxxx xxxxx xxx xxxxxx xxx xxxxxxxxxx.
NOTE Event scripts enabled under system scripts op should follow the op script
boilerplate and use the <op-script-results> top-level result tree element
instead of the <event-script-results> element.
Chapter 6: Configuring Event Policies 77
76 This Week: Applying Junos Automation
Xxxxx xxxxxxxxxx xxxxxxx xxx xxxxxxxx xxxx xxxxxxxxx xxxxx xx
Xxxxx. Xxxxx xxxxxxxx xxx xxxxx xxxxxxx xxxx xxxxxxxx xx xxxxxxxx
xxx Xxxxx xxxxxxxx xx xxxxxx xxxxxx. Xxx xxxxx xxxxxx xxxxxxxx xxx
xxxxxxxxxxxx xxx Xxxxx xx xxx, xxx xx xx xxx xxxxx xxxxxx –
xxxxxxxxxxxx xxx xxxxx xxxxxxxxxx xxxxxx – xxxx xxxxxxx Xxxxx xxxx
xx xxxxxxx xxx xxxxx xxxxxx. Xxxx xxxxxxx xxxxxx xx xxxxxxxxxx xxxx
xxxxxx xxx xxx xxx xx xxxxxxxx xxxx. Xx xxxx xxxxxxxx xx xxxxxxxx xx
xxxxx xxxxxxx xxx xxxxx xxxxxxxxxxxxx.

Events Overview
Xx xxx Xxxxx xxxxxxxxx xxxxxx xx xxxxx xxx xx x xxxxxx xxxxxxx, x
XXXX xxxx, x xxxxxxx xxxxx, xx xx xxxxxxxx xxxx-xxxxx xxxxxxx. Xxxxx
xxxxxxxx xxxxxxx:
„„Configuration commits
„„Interfaces going up or down
„„New hardware components being inserted or removed
„„Protocol adjacency changes
Xxxx xxxxxx xxxx xxxxxxxx xxxxx XXx, xxxxx xxx xxxxxx xxxxx xxxx
xxx xx xxxx xx xxx xxxxxx xxxx:
Jul 22 10:19:52 Junos mgd[3578]: UI_DBASE_LOGIN_EVENT: User 'user'' entering
configuration mode
Jul 22 10:19:53 Junos mgd[3578]: UI_COMMIT: User 'user' requested 'commit' operation
(comment: none)
Jul 22 10:19:56 Junos mgd[3578]: UI_DBASE_LOGOUT_EVENT: User 'user' exiting
configuration mode

Xxxx xxxx xxxxx xxxxx x xxxxxx xxxxx. Xxx xxxxx xxxxxx xxx:
„„UI_DBASE_LOGIN_EVENT: A user-entered configuration mode
„„UI_COMMIT: A configuration commit was performed
„„UI_DBASE_LOGOUT_EVENT: A user exited configuration mode
Xxx xxxxx XX xxxxxxx xx xxxxxxxxx xxxxxxxxx xxx xxxxxx xxxx (xxx xx
xxx xxxxx xxxxxxx) xxx xxxxxxx XX xx xxxxxxxxxx. X xxxxxxx
xxxxxxxxx xxxxxxx xxx xxxxx XX, xxxx xxxxxxx xxxxxxxx xxxx
xxxxxxxxxxx xx xxx xxxxx xxxx xxxxxxxx.
BEST PRACTICE Syslog messages from the event processing daemon (eventd) are not
treated as system events. They should never be included in an event
policy configuration.
NOTE As discussed in Chapter 5, Junos is modularized into multiple software
processes known as daemons. Some of the commonly known Junos
daemons include the routing daemon (rpd), the management daemon
(mgd), the chassis daemon (chassisd), and the event processing daemon
(eventd).

Event Attributes
Xxxxxx xxxxxxx xxxxxxxxxx xxxx xxxxxxx xxxxxxxxxx xxxxxxxxxxx xx
xxxxxxxx xxx xxxxx. Xxx xxxxxxx, xxx xxxxx xxxxxx xxxxx xx xxx xxxxx
xxxxxxx xxxx xxxxxxx xx xxxxxxxxx xx xxxxxxxx. Xxxx xxxxxxxxx
xxxxxxxxx xxxxx xxxx xxxxxxx xxxxxxx xxxxxxxxxxxxx xxxx, xxxxxxxxx
xxx xxxxxx, xxx xxxx xxxx xxxxxxxxxxxxx xxxx. Xxx xxxxx xxxxxxx
xxxxxxxx xx xxxxxxxxxx xxxxx xxxxx xxxxxxxx xx xxxx xxxxx xxxxxxxx
xxx xxxx xx xxx xxxxx XX xxxxxx, xxx xxxx xx xxxxxxxx
xxxxxxxxxxxxxxx xx xxx xxxxx. Xx xxx xxxxx xxxxxxxx xx xxx xxxxx
xxxxxxx, xxxxx xxxxxxxx xxxxx xxxxx xxxxxxxxxxx xxxxx xx xxxx xxxx
xxxxxxxxx xxx xxxxxx xx xxxxxxx xxx xxxxxx xxxxxxxxxxxxx xxxx.

Identifying Events and Attributes


Xxxxxx xxxxx xxxxxxx x xxxxxx xx xxx xxxxxx xxxx xxxx xxxxxxx
xxxxxxxx xx Xxxxx xxxxxxx. Xxxxxxxxx xxxxx xxxxxx xxxxx xxxxxxx
xxx xxxxx XX xxxx xxxxxxxxxxx xx xxxx xx xxxxx xxxx xxxxxx. Xxx x
xxxxxxxx xxxx, xxxxxxx xxx xxxx xxxxxx Xxxxx XXX xxxxxxx. Xx xxxxxxxx
xxx xxx xxxxxxxxx xxxxxx xxxxxx xx xxx Xxxxx xxxxxx xx xxxxx xx
xxxxx xxxxxx xxx xxxxx:
user@Junos> help syslog
Syslog tag Help
ACCT_ACCOUNTING_FERROR Error occurred during file processing
ACCT_ACCOUNTING_FOPEN_ERROR Open operation failed on file
ACCT_ACCOUNTING_SMALL_FILE_SIZE Maximum file size is smaller than record size
ACCT_BAD_RECORD_FORMAT Record format does not match accounting profile
ACCT_CU_RTSLIB_ERROR Error occurred obtaining current class usage statistics
ACCT_FORK_ERR Could not create child process
ACCT_FORK_LIMIT_EXCEEDED Could not create child process because of limit
...
Xx xxxxx xxxxx, xxxxxxxxx xxx xxxx xxxxxx xxxxxxx xxxxxxx xxx
xxxxxxxxx xxxxx xxx xxxxxxxx xxxxxxx xx xxxxx XXx xxxxx xxxx xxxxx
xxxxx xxxxxxxxxxx. Xxxxxxxxx x xxxxxxxx xxxxx XX xx xx xxxxxx xx
xxx xxxx xxxxxx xxxxxxx xxxxx xxx xxxx xxxxxxxxxxx xx xxx xxxxx:
user@Junos> help syslog UI_COMMIT
Name: UI_COMMIT
Message: User '<username>' requested '<command>' operation (comment: <message>)
Help: User requested commit of candidate configuration
Description: The indicated user requested the indicated type of commit operation on the candidate configuration and
added the indicated comment. The 'commit' operation applies to the local Routing Engine and the 'commit
synchronize' operation to both Routing Engines.
Type: Event: This message reports an event, not an error
Severity: notice
Xxxx xxxxxx xxxxxxxx xxx xxxxx XX (xxx xxxx xx xxx xxxxx), xxxxxxx
xxxxxx, xxxxxx xxxxxxxx, xxx xxxxx xxxxxxxxxxx xxxxxx.
Xxxxxxxxxxxx, xxx xxxxxx xxxxxxxx xxxxx xxxxxxxxxx xxxxxxxxx xx
xxx xxxxxxx xxxxxx, xxxxx xxxx xxxxxxxxx xx xxxxxxxx xxxxxx < >.
Xxx xxxxx xxxxxx xxxxx xxxx xxx XX_XXXXXX xxxxx xxx xxx xxxxxxxxx
xxxxxxxxxx:
„„username
„„command
„„message
Xxx xxxx xxxxxx xxx xx xxxx xx xxxxx xxx xxxxxxxxxx xx xxx
XX_XXXXX_XXXXX_XXXXX xxxxx xx xxx xxxxx xxxxxx xxxxx:
user@Junos> help syslog UI_DBASE_LOGIN_EVENT
Name: UI_DBASE_LOGIN_EVENT
Message: User '<username>' entering configuration mode
Help: User entered configuration mode
Description: The indicated user entered configuration mode (logged into the configuration database).
Type: Event: This message reports an event, not an error
Severity: notice
Xx xxx xxxxxx xxxxx, xxxx xxxxx xxxx xxx x xxxxxx xxxxxxxxx:
„„username
Syslog Structured-Data
Xxxxxxx xxx xx xxxxx xxxx xxxxxxxxxx xxxxxxxxxx xx xx xxxxx xx xx
xxxxxx xxxxxxxxxx-xxxx xxx x xxxxxx xxxx. Xxxx xxxx xxxxxxxxx xx
xxxxxxxx xx xxx xxxxxx xxxxxxxxxxxxx xxx Xxxxx xxxxxx xxxx x xxxx
xxxxxxx xxxxxx xx xxx xxx xxxxxx xxxxxxxx:
system {
syslog {
file syslog {
any notice;
structured-data;
}
}
}
Xxxx xxx xxx xxxx xxxxx xxxxxx xxxx xxxx xxxxx xxxxxxxxx, xxx xxx
xxx xxxxxx xxxx xxxx xxx xxxxxxxxxx-xxxx xxxxxx, xxxxx xxxxxx xxxx
xxxxxxxxxxx xx xx xxxxxxxx xx xxxx xxxxxx xxxxxxx:
<189>1 2009-07-22T10:41:38.611-07:00 Junos mgd 3578 UI_DBASE_LOGIN_EVENT [junos@2636.1.1.1.2.2
username="roy"] User 'roy' entering configuration mode

<189>1 2009-07-22T10:41:40.645-07:00 Junos mgd 3578 UI_COMMIT [junos@2636.1.1.1.2.2 username="roy"


command="commit" message="none"] User 'roy' requested 'commit' operation (comment: none)

<189>1 2009-07-22T10:41:44.041-07:00 Junos mgd 3578 UI_DBASE_LOGOUT_EVENT [junos@2636.1.1.1.2.2


username="roy"] User 'roy' exiting configuration mode

Xxxx xxxx xxxxxxx xxxxxx xxx xxx xxxxxxxxx xx xxxxxxx xxx xxxx xxx
xxxxx xxxxxxxxxx xxx xxxx xxx xxxxxxxxx xxxxxx. Xxx xxxxxxxxx
xxxxx xxx xxxxxx xxxxxx xxx xxxxx XX xxx xxx xxx xxxxxxxx xxxxxx
xxxxxx xxxxxxxx. Xx xxx xxxxxxx xxxxx, xxx xxxxxxxxx xxxxxxxxxxx
xxx xx xxxxxxx xx xxxxxxxxx xxx xxxxx xxxxxxxxxx:
„„The user "roy" entered configuration mode.
„„The user "roy" committed the configuration using the "commit"
command with no message included.
„„The user "roy" exited configuration mode.

Nonstandard Events
Xxx xxx xxxxxx xxxx xx xxxxxxxx xxxxx XX. Xxxx xxxxxx xxx xxxxxxx
xxxxxx xxxxx xxxxxxx XXx xxxx xxxxxxxx xxxxx xxxxxx. Xxxx xx xxxxx
xxxxxxxxxxx xxxxxx, xxxxxxxxx xxxxxx xxxxxx xxxxxx, xxxx x xxxxxx
xxxxxxxxx xxxxxx xxxxxxx xxxx xxxxxxxx xxx xxxxxx xxxxxxx xxxx xx
xxxxxx xxxx xxx xxxxx xxxxxx. Xxxx xxxxxxxx xxxxxx xxx xxxxx xxx
xxxx xxxxxxx xxxxx XX, xxxxx xxxxxxxx xxxx xx xxxx xxx xxx xxxxxxx
xxxxxx xxxxxxx xx xxxxxxxx xxx xxxxx xx xxx xxxxxxx xxxxxxxxx xx
xxxxx xxxxxx. X xxxxx xxxxxxx xx xxxx xxxxxxx xxxxxxxxx xxx xx
xxxxxxxxx xxxxxxxxx xxxxxxxxxxx xxxxxx xxxxx xxxxxxxx. Xxxx xxxxxx
xxxxxx Xxxxx xxxxxxx xx xxxxx xx x xxxxxxxx xxxxx, xxxx xxxxxx xxxx
xxxxx xxxxxx xx XX xxxx xxxxx xxxxxx xxxxxx. Xxx xxxxx xxxxx
xxxxxxxxxx xxx xxxxxxxxxxx xxxxx XXx:
Nonstandard Event IDs
Xxxxx 6.1 xxxxxxx xxx xxxxxxx xxxxx XXx xxx xxxxx xxxxxxxxxxxx.
Table 6.1 Event ID Descriptions

Xxxx xxx xxxxxxxx xx xxxxxx xxxxxxxx xxxx xxxxxxxxxxx xxxxxx:


Jul 22 11:43:49 Junos /kernel: fxp1: link DOWN 100Mb / full-duplex
Jul 22 11:43:50 Junos /kernel: fxp1: link UP 100Mb / full-duplex
Jul 22 11:47:05 Junos xntpd[5595]: kernel time sync enabled 2001

Xxx xxxxx xxx xxxxxx xxx xxxx xxx xxxxxx, xxxxx xxxxx xxxx xxx
xxxxxx xxxxx xxx XXXXXX xxxxx XX. Xxx xxxxx xxxxx xx xxxxxx xxxx x
xxxxxx xxx xxxxx x xxxxxxxx xxxxx XX. Xxx xxxxx xx xxxxxxx xxxxxx
xxxxx xxx XXXXXX xxxxx XX. Xxxx xx xxxxx xxxxxx xxx xx xxxxxxx xx
xxxxxxxxx xx xxxxx xxxxxxx xxxxxxxxx xx xx xxxxxxxx xxxxxxx
xxxxxxxxxxxx.

Logger
Xxx xxxxxxx xxxxxxx xx xx xxxxxxxxx xxxx xx xxxxxxxx xxxxx
xxxxxxxx xxx xxxxx xxxxxxx, xxx xxxxxxx xxxx xxxxxx xxx xx xxxxxx xx
xxxx xxx xxxxxxxxx xx xxxxxxxx xxxxxxxx. Xxxxxxx, Xxxxx xxxxx xxxx
x xxxx xxxxxxx xxxxx xx xxxxxx xxxx xxx xxxxxxxxxxxx xxxxxxxx xxx
xxxxxx xxxxx. Xxxxxx xxxxx xx xxxxxxxx xx xxxx xxxxx xxxxxxxx xxx
xxxxx xxxxxxx xxxxxxxxxxxx xxxxxxxxxx xx xxxxxxx xxx xxxxxxx xxxxx
xx xxxxxx xx xxxxxx.
NOTE Logger is a Junos shell program that is unsupported and should not be
used on production devices. But logger is well suited for use in lab
environments where event policies and event scripts are being
developed and verified.
ALERT! Logger should be used only in Junos 9.3R4 and later. Unexpected failure
may occur if used in a prior version.
How to use the logger test utility
1. Xxx xxxxxx xxxxxxx xx x xxxxx xxxxxxx, xxx xx xxx xxxx xxxx xxxxx
xxxxx x xxxxxx xxxxx xx xxxxxxxx xxx xxxxx xxxxx xxxxxxx:
user@Junos> start shell
%
2. Xxx xxxxxx xxxxxxx xxx xxx xxxxxxxxx xxxxxxx xxxxxx:
logger -e EVENT_ID -p SYSLOG_PRIORITY -d DAEMON -a ATTRIBUTE=VALUE MESSAGE
Xxxx xxx XXXXX_XX xx xxxxxxxx, xxx xx xxxx xx xxxxxxx xxxxxxxx xx
xxxxxxxxx:
% logger -e UI_COMMIT

Xxx xxxxx xxxxxxx xxxxxx x XX_XXXXXX xxxxx xx xx xxxxxxxxx,


xxxxxxxxxx xxxx xxx xxxxxx xxxxxx, xxxx xx xxxxxxxxxx, xx xxxxxxx,
xxx x xxxxxx xxxxxxxx/xxxxxxxx xx xxxx/xxxxxx.
Xxx xxxxxxx xxxxxxxx xxx xx xxxxxxx xx xxxxx xxx xx xxx xxxxxxxx
xxxxxxx xxxx xxxxxxxxx.
3. Xxx xx xxxxxxxxx xxxxxx xxxxxxxx/xxxxxxxx xxx xxx -x xxxxxxxx xxx
xxxxxxx xxx xxxxxxxx/xxxxxxxx xx xxx xxxx xxxxxxxx.xxxxxxxx xxxxxx
xxxx xx xxx xxx:xxxxxx() xxxxxxxx:
% logger -e UI_COMMIT –p external.info

MORE? See Part One: Applying Junos Operations Automation for a table that lists
the valid syslog facilities and severities for the jcs:syslog() function.
4. Xx xxxxx xxxx xxxxxx xxxxxxxxx xxx xxxxx, xxx xxx -x xxxxxxxx:
% logger -e UI_COMMIT –d mgd

5. Xxxxxxx xxxxxxxxxx xxx xxx xxxxx xx xxxxx xxx -x xxxxxxxx. Xxx


xxx xxxxxxxx xxxxxxxx xxxxx xx xxxx xxxx xxx xxxxxxxxx xx xxxxxx.
Xxx xxxxxxxxx xxxx xxxx xx xx xxxxxxxxx xxx xxxxxx xx xxxxxxxx xx
xx xxxxx xxxx xxx xxx xxxxxxx xxxxx:
% logger -e UI_COMMIT -a username=user -a command=commit

6. Xxx xxxxxx xxxxxxx xxxxxxx xxx xxx xxxxxxx xxxx xxxxxxxxx.


Xxxxxx xxx xxx xxxxxxxx xxx xxx xxxxxxxxxxx xxx xxxxxxx:
% logger -e UI_COMMIT -d mgd "This is a fake commit."

Xxx xxxxx xxxxxxx xxxxxx xxx xxxxxxxxx xxxxxxx xx xx xxxxx xx xxx


xxxxxx:
Jul 22 12:47:03 Junos mgd: UI_COMMIT: This is a fake commit.

NOTE When using the logger utility the event ID must always be in uppercase
and the attribute names must always be in lowercase.
Try it Yourself: Simulating Events with the Logger Utility

1. Use help syslog to identify an event of interest and its attributes.


2. Configure a syslog file to use structured-data format.
3. Using the logger utility, generate an artificial version of the selected event including values
for all of its attributes.
4. Verify that the event was created as expected by viewing the structured-data syslog file.
Event Policy Overview
Xxxxx xxxxxxxx xxx xxxxxxx xxxxxx xxx Xxxxx xxxxxxxxxxxxx xx
xxxxxxxx Xxxxx xx xxxxxxx xxxxxxxx xxxxxxx xx xxxxxxxx xx xxxxxx
xxxxxx. Xxxx xxxxx xxxxxx xx xx xx-xxxx xxxxxxxxx. Xxx xx xxxxxxx xx
xxx xxxxxx xxxxxxxx xx xxx xx xxxx xxxxx xxxxxxxxxx. Xx xxxxx xxxxx
xxxxxxxxxx xxx xxxxxxxxx xxx, xxxx Xxxxx xxxxxxxx xxx xxxxxxx
xxxxxxxxx xxxxx xxx xxxx xxxxxxxxx. X xxxxxx xxxxx xxx xxxxxxx xxxx
xxxx xxx xxxxx xxxxxx. Xxx Xxxxx xxxxx xxxxxxxxxx xxxxxx xxxxxxxxx
xxx xxxxx xxxxxxxx xxxxxxxxxxxx, xx xxxxxxxxxxxxx xxxxx, xxx
xxxxxxxx xxx xxxxxxx xx xxx xxxxxxxx xxxxxxxx xx xxxxxxxx xx xxx
xxxxx.

Figure 6.1 The Flow of Event Processing

Xxxxx xxxxxxxx xxx xxxxxxxxxx xxxxx xxx xxxxx-xxxxxxx xxxxxxxxx


xxxxx. Xxxx xxxxx xxxxxx xx xxxxxxx xxxx x xxxxxx xxxx xxx xxxxxxxx
x xxxxxxxx xxxxx XX xx xxxx xx x xxxx xxxxxxxxx xxxx xxxxxxxxxxxx xx
xxxxxxx xx xxxxxxxx xx xxx xxxxxxxx xxxxxx.

Basic Configuration
Xxx xxxxxxx xxxxxxxxxxxxx xxx xx xxxxx xxxxxx xx xx xxxxxx xxxxxxxxx
xxx xx xxxxx xxx xxxx xxxxxx:
event-options {
policy example {
events ui_commit;
then {
event-script example-script.slax;
}
}
event-script {
file example-script.slax;
}
}

NOTE The configuration necessary to enable the event script is also included in
this and all other event policy examples. See Chapter 5 for further
details.
Xxx xxxxxxx xxxxx xxxxxxx xx xxxxx xxxxxx xxxxx xxxxxxx. Xxxx xxxxxx
xxxxxxx xx xxx XX_XXXXXX xxxxx, xxxxx xx xxxxxxxx xx xx xxx xxxxxxx
xxxxx xxx xxx xxxxxx. Xxxxxxx xxx xxxxxxx xxxxx xxxxxx, Xxxxx
xxxxxxxxxxxxx xxxxxxxx xxx xxxxxxx-xxxxxx.xxxx xxxxx xxxxxx.
Xxxxxxxx xxxxxx xxx xx xxxxxxxxxx xxxxxx xxx xxxx xxxxx xxxxxx.
Xxxx xxxxxxxx xxxxxx xxx xxxxxxxxxx, xxx xxxxxx xxx xx xxxxxxxxx xx
xxx xxx xx xxx xxxxxx:
event-options {
policy example {
events [ ui_dbase_login_event ui_dbase_logout_event ];
then {
event-script example-script.slax;
}
}
event-script {
file example-script.slax;
}
}

Xxx xxxxxxx xxxxx xxxxxx xxxxx xxxxxxxx xxx xxxxxxx-xxxxxx.xxxx xxxxx


xxxxxx xxxxxxx xxxxxx x XX_XXXXX_XXXXX_XXXXX xx XX_XXXXX_XXXXXX_XXXXX
xxxxx xxxxx.
TIP While the trigger event can be in uppercase or lowercase, lowercase
provides the advantage that command completion can be used to auto-
complete the event ID.

Maximum Policy Count


Xxxxx xxx xxx x xxxxxxx xx 15 xxxxx xxxxxxxx xx xxx xxxx xxxx. Xxxx
xxxxx xx xxxxxxx xx xxxxxxxx xxxxxxxxx xxx xxxxxxx xxxxx xxxxxxx.
Xx xxx xxxxxx xx xxxxxxx xxxxx xxxxxxxx xxx xxxxxxx xxx xxxxx,
Xxxxx xxxx xxx xxx xxxxxxx xxxxxxxx xxx xxxxxxx xxxxxx xxx
xxxxxxxxx xxxxxxx xx xxx xxxxxx:
EVENTD_POLICY_LIMIT_EXCEEDED: Unable to execute policy <name> because current
number of policies (15) exceeds system limit (15)

Your First Event Script


Xxxx xx xx xxxxxxx xx x xxxxx xxxxx xxxxxx xxxxxx xxx-xxxxx-xxxxx.xxxx.
Xxxx xxxxxxxx, xxxx xxxxxx xxxx xxx xxxxxxx "Xxxxx Xxxxx!" xx xxx
xxxxxx:
/* log-hello-world.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match / {
<event-script-results> {

/* Send Hello World! to syslog from facility external with severity info */
expr jcs:syslog("external.info", "Hello World!");

}
}

Xxx xxxx xxxx xx xx xxxxxx xxx xxxxxx xxxxx xxxxxx xx xxxxxxx Xxxxx
xx xxxxxxx xxx xxxxx xxxxxx xx xxxxxxxx xx xxx xxxxxxx xxxxx.
Xxxxxxx xxx xxxxxxx xxxxx xxxxxx xx xxxx xxxxxxx xxx xxxxx
xxxxxxxxx Xxxxx xx xxxxxxx xx xxxxxxxxx xxx xx xxx xxxxxxxx xx
xxxxxxxxx xxxxxx, xxx xx xxxx xxxxxxx xxx XX_XXXXXX xxxxx xx xxx
xxxxxxx xxxxx:
event-options {
policy hello-world {
events ui_commit;
then {
event-script log-hello-world.slax;
}
}
event-script {
file log-hello-world.slax;
}
}
Xxxx xxx xxxxxx xxxxxxxxx xxxxxx xxx xxx xxxxx xxxxx xxxxxx
xxxxxxxxxx, xxx Xxxxx xxxxxx xxxxxx "Xxxxx Xxxxx!" xx xxx xxxxxx xxxxx
xxxx x xxxxxx xx xxxxxx:
[edit]
user@Junos# commit
commit complete

user@Junos> show log messages | match cscript


Jul 8 14:35:34 Junos cscript: %EXTERNAL-6: Hello World!

MORE? For more information on the usage of the jcs:syslog() function refer to the
Part One: Applying Junos Operations Automation book. The function can
be used the same way in op, event, or commit scripts.
Try it Yourself: Logging a Syslog Message in Response to an Event

1. Using the log-hello-world.slax script as an example, create an event script that logs a message
to the syslog.
2. Copy the event script to the Junos device and enable the script in the configuration.
3. Select an event ID of interest and configure an event policy that executes the event script in
response to the system event.
4. Use the logger utility to simulate the event and verify that the desired message is logged to
the syslog.

Correlating Events
Xxxxx xx xx xxxxx xxxxxxxx xx xxxxxxxxx xxxxx xxxxxxxx xxxxxxxxx
xx xxxx x xxxxxx xxxxx, xxxxx xxxxx xxxxxxxx xxxxxx xxxx xxxxxxx
xxxx xxxxxxxx xxxxxx xxxxx xx xxxxx xxxxxxxx xx xxxx xxxxx.
Xx xx xxxxxxx, xxxxxx xxxx xx xxxxxxxxxxxx xxxxxx xx xxxxxx xxx
xxxxxx xxxxxxxxxxxxxx xxxx xxxxxxxx xx x xxxx xx xxxxxxxxxxxx xx
xxxxx xxxxxxxxxx xxxxxxx. Xxxx xxxx x XXX (Xxxx-Xxxx Xxxxxxxxxxx
Xxxxxxxxxx) xxxx xxxxx xxxx xxxxxxxx xxx xxxxxxxxxxxx xx xxx
xxxxxxxxxx xxxxxxx xxxxx xxxxxx, xxx xxxxx xxxxxxxxx xxxxxx xxxxxx
xxxxxxx xxxxx xxx xxxxxx xxxxxxxxx XXX xxxxxxx (xxxxxxxx xxx
xxxxxxxxxxxxx xx xxxxxxxxxxxxx xxxxxxxx xx xxx xxxxxxxxxxxxx
xxxxxx xxxxxxx xxxxxxxxxxxx). Xxx xxxx xx xxx xxxxxxxxxx xx xxx xxx
Xxxxx xxxxxx xx xxxx xxx xxxxxxxxxxxxx xxxxxxxxxx xx xxx xxxxxxxxx
xxxxxxxx xx x xxxxxxxx xxxxxxxx xxx xxxxx xxxxxxxxxxx. Xxxx xxxx
xxx xx xxxxxxxxxxxx xx xxxxx xx xxxxx xxxxxx xxx xxxxx xxxxxx.
MORE? For more information on Real-Time Performance Monitoring configuration
see the Services Interfaces manual within the Junos documentation at
www.juniper.net/techpubs/.
MORE? For more information on the commit confirmed command see the CLI User
Guide within the Junos documentation at www.juniper.net/techpubs/.
Xxx xxxxx xxxxxx xx xxxxx xxxx-xxxxxxxx.xxxx. Xxxx xxxxx xxxxxx xxxxxx
xxx /xxxxxx/xxxxxxx.xxxx.1.xx xxxxxxxx xxxx xx xxx /xxx/xxx xxxxxxxxx xxx
xxxxxxxxx xxxxxxx xx xxx xxxxxx xxxxxxxxxxxxx.
Xxx xxxxx xxxx xxxxxx xxxx x xxxxxx xxxxxxxxx xx xxxxxxxxxxxxx
xxxxxx xxxx xx: XX_XXXXXX_XXX_XXXXXXXXX. Xxx xxxxxxxx xxxxxxxx, xxxx
xxxx xxxxxxxxx xxxxxxxx xxxxx xxxxxx xxxxxxxxxxxxxx xxxx xxx xx
xxxxxxxxx xxxx xxxxxx xx xxxx xxx xxxxxxxxxxxx’x xxxxxxxxxx xxxx.
Xxx xxxxxxx xxxxxxxx xxx xxxxx xx xxxx xxxxx xxxxx xxx xx xxxxxxxxx
xxxxxx xxx xxxxx xxxxxxxxxxxxx xx xxxxxxxxxxxx.
X xxxxx xxxxxxx xxxxx xxxx xxxx xxx xxxxxxxxx:
policy faulty-rollback {
events ui_commit_not_confirmed;
then {
event-script save-rollback.slax;
}
}

Xxx xxxxx xx x xxxxxxx xxxx xxx xxxxx xxxxxx: xxx xxxxxx xx


xxxxxxxxx xxxxx xxxx x XX_XXXXXX_XXX_XXXXXXXXX xxxxxx. Xxxx xxxxx
xxxx xxxxxxxx xxx xx x xxxx xx xxxxxxxxxxxx, xxx xx xxxx xxxxx xxxx
xxxxxxxx xxx x xxxxxxxxx xxxxxx. Xxxxxxx xxx xxxxxxxxxxxx xxx
xxxxxxxxxx xx xxx xxxxxxxx, xxx xxxxxxx. Xx xxxxxx xxx xxxxxx, xxx
XX_XXXXXX_XXX_XXXXXXXXX xxxxx xx xxxxxx xxxxxx xxxxxxxxxxx xxx xxx
xxxxxx xxx xxx xxxxxxxxx. Xxxx xxxxxxxxxxx xxxxx xx xx xxxxxxxxxx
xxxxxxx xxxxx xxxxxxx.
Xx xxx xxxxxxx xxxxxxxx, xxx xxxx xxxxxx xxx xxxx xxxxxxxxxxx xx xx
xxxxx xx x XXXX_XXXX_XXXXXX xxxxx xxx xxxxxxxx xxxxxxxx. X
XXXX_XXXX_XXXXXX xxxxx xxxxxx xxxxx xxxx xxx XXX xxxx xx xxx
xxxxxxxxxx xxxxxxx xxxxx. Xxxx xx xxxxxx xx x xxx xx xxxxxxxxx xxx
XX_XXXXXX_XXX_XXXXXXXXX xxxxx xxxx xxx XXXX_XXXX_XXXXXX xxxxx. Xxxxx
xxxx xxxxx xxxx xxxx xxxx x xxxxxx xxxx xxxxxxxxxxx, xxx xxxx xxx
xxxxxxxxxx xxxxxxx xxxxxxxxxxxx xxx xxxx xx xxx xxxx xxxx.
Xxxx xxxxxxxxxxx xxxxxxx xxxxxxxx xxxxxx xx xxxxxxxxxxxx xx xxxxx
xxx xxxxxx xxxxxxxxx. Xxxx xxxxxxxxx xxxxxxxx xx x xxxx xxxxx (xx
xxxxxxx) xxx xxx xx xxxx xxxxxxxxxxx xxxxxx. Xxx Xxxxx xxxxx xxxxxx
xxx xx xxxx xxxxxxxx xxx xx xxx xxxxxx xxxxxxxxxxx xxxxxx xxxxxx
xxx xxxxx xxxx xxxxx, xx Xxxxx xxxx xxx xxxxxxx xxx xxxxx xxxxxx.
Xxxx xx xxx xxxxxx xxxxxxx xx xxxxxxxx xxx xxxxxx xxxxx xxxxxx:
policy faulty-rollback {
events ui_commit_not_confirmed;
within 60 events ping_test_failed;
then {
event-script save-rollback.slax;
}
}
Xxx xxxxxxx xxxxx xx xxxx xxxxxx xx XX_XXXXXX_XXX_XXXXXXXXX xxx xxx
xxxxxx xxx x xxxxxxxxxxx xxxxx xx XXXX_XXXX_XXXXXX, xx xxx xxxxx
xxxxxx xx xxxx xxxxxxxxx xxxx x XX_XXXXXX_XXX_XXXXXXXXX xxxxx xxxxxx
xx x XXXX_XXXX_XXXXXX xxxxx xxx xxxxxxxx xxxxxx xxx xxxx 60 xxxxxxx.
Xxxx xxxxx xx xxxxxx xxxx xxx xxxxx xxxxxxx xx xxx xxxxx xxxxxx
xxxx xxxx xxxx xxxxxxxxxxxx xxx xxxxxxxx xxxx xxxx, xxx xxx xxxxxxx
xxxxx xxxxxxx xxxx xxx xxxxxx. Xxxx x xxxxxx xxxxxxxxx xxxxxxxx
xxxxxxx, xxx XX_XXXXXX_XXX_XXXXXXXXX xxxxx xxxxxxxx xxxxxx xxxxx.
Xxx xxxxx xxxx xx xx xxxxxxxxxxxx xxxx xxx xxxxxxxx xx xxxxx xx xx
xxxxxxxxx, xxx xxx xxxxxx xxxx xx xx xxxxxxxxxx xxxx xxx xxxxxxxx xx
xxxxxxxx. Xxxx xxx xxxxxxxx xx xxx xxx xxxxxx xxxxxxxx xxxx xxxx
xxxxx xxxxxx:
UI_COMMIT_NOT_CONFIRMED: Commit was not confirmed; automatic rollback in process
UI_COMMIT_NOT_CONFIRMED: Commit was not confirmed; automatic rollback complete
Xxxxx xx xxx xxxxxxxxxxxxx xxxxx, xxx xxxxx xxxxxx xxxxx xxxxxxx
xxxxx, xxxx xxxx xxx xxxxxxxx xxx xxxxxxxx, xxx xxxx xxxx xxx
xxxxxxxx xxx xxxxxxxx. Xxx x xxxxxxx xxxxxxxxxxxx xx xxxx xxx xxxxx
xxxxxxxxx xx xxx xxxxxx xxxxx xxxxx xxxxx xx xxx xxxxxxxx, xxxxx xxx
xxxxxxx.xxxx.1.xx xxxx xxxxx xxxxxxxx xxx xxxxxxxx xxxxxxxxxxxxx
xxxxxxx xx xxx xxx xxxxxxxxxxxxx, xx xxx xxxxx xxxxxxxxxxxxx xxxx
xxxxx xx xxxxxxxx. Xxxxxxx xx xxxx, xx xx xxxxxxxxx xx xxxxxx xxxx
xxx xxxxx xxxxxx xx xxxx xxxxxxxx xxx xxx xxxxxx
XX_XXXXXX_XXX_XXXXXXXXX xxxxx, xxx xxx xxx xxx xxxxx. Xxxx xxx xx xxxx
xx xxxxxxxx xxxxx xxxxxxx xx xxx xxxxx xxxx xx xxxxxxxxxx xx xxx
xxxxxx xxxxxxx xxxxxx xx xxx xxxxx. Xxxxx xxxxxxxxxxxxx xxx
xxxxxxx xx xxxxxxxx xxxxxxxx xx xxxx xxxx. Xxx xxx xxx xxx’x
xxxxxxxxx xxx xx xxxxxxx xxx xxxxxx xxxxxx xxxxx xxxxx xxxxx xxxx
xxx xxxxx XX.
Xxx xxxxx xxxxxx xxxxxx xxxx xxx xxxx xxxx x XXXX_XXXX_XXXXXX xxxxx
xxx x XX_XXXXXX_XXX_XXXXXXXXX xxxxx xxxx xxxxxxxx xxxxxxxx. Xxxx xx
xxx xxxxx xxxxxxx xx xxxxxxxx xxx xxxxxx xxxxx xxxxxx:
policy faulty-rollback {
events ui_commit_not_confirmed;
within 60 events [ ping_test_failed ui_commit_not_confirmed];
then {
event-script save-rollback.slax;
}
}

Xxxx xxxxx xxxxxx xx xxxxxxxxxx xx xxx xxxx xxxx xxxxxx x


XXXX_XXXX_XXXXXX xxxxx xx x XX_XXXXXX_XXX_XXXXXXXXX xxxxx xxxx
xxxxxxxx xx xxx xxxx 60 xxxxxxx, xxx xxxx xx xxx xxxx xx xxx
xxxxxxxxxxxxx: xxxxx xx xx XX xxxxxxxxxxxx xxxxxxx xxxxxxxx
xxxxxx xxxxxxxxxx xx xxx xxxx xxxxxx xxxxxxxxx.
Xxx xxxxx xxxxxx xxxxxx xxxx xxx xxxx xxxx xxx XXXX_XXXX_XXXXXX xxx
xxx XX_XXXXXX_XXX_XXXXXXXXX xxxxxx xxxx xxxxxxxx xxxxxxxx, xxx xxxx
xxx xx xxx xxxxx. Xxx xxxxxxx xxx xx xx xxxx xx xxxx xxx xxxxxxxx
xxxxxx xxxxxxxxxx. Xx XXX xxxxxxxxxxxx xxxxxx xxxxxxx xxxxxxxx
xxxxxx xxxxxxxxxx, xxx xxxxx xxxxxx xxxxxxxxx xxxx xxxx xxx xxxxxxxx
xxxxx xxxx xxxxxxxx xxxxxx xxx xxxxxxxxxx xxxx xxxxx xx xxxxx xxx
xxx xxxxx xxxxxx xx xxx.
Xxx xxxxx xx xxxx xxxxxx xxxxxxxxx xxxx xxxx, xx xxxx xxxx 50 xxxxxxx
xx xxxx xx xxx xxxx-xxxxx xx xxxxx x XX_XXXXXX_XXX_XXXXXXXXX xxxx
xxxx xxxx xxxxxxxx, xxxxx xxxxxxxxxxxxxx xx xxxx xxx 60 xxxxxxx
xxxxxxx xxx xxx XXXX_XXXX_XXXXXX xxxxx.
Xxx, xxxxxx xxxx xxxxxxx xxx xxx xxxxxx xxxxx xxxxxxxx, xxx xxxxx
xxxxx xxxxxx xxx xxxxx xxxxxx xxx xxxxxxxxx xxxxx:
event-options {
policy faulty-rollback {
events ui_commit_not_confirmed;
within 60 events ping_test_failed;
within 50 events ui_commit_not_confirmed;
then {
event-script save-rollback.slax;
}
}
event-script {
file save-rollback.slax;
}
}
Xxxx xx xxx xxxx-xxxxxxxx.xxxx xxxxx xxxxxx xxxx xx xxxxxxxx xx x
xxxxxx xx xxxx xxxxx xxxxxx:
/* save-rollback.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match / {

/* Get system time with hyphens instead of spaces */


var $modified-time = translate( $localtime, " ", "-" );

/* Use time to differentiate saved rollback versions */


var $filename = "saved-rollback-" _ $modified-time _ ".gz";

/*
* Copy the file using the <file-copy> API Element. This is the XML
* API form of the "file copy" CLI command.
*/
var $file-copy-rpc = <file-copy> {
<source> "/config/juniper.conf.1.gz";
<destination> "/var/tmp/" _ $filename;
}
var $results = jcs:invoke( $file-copy-rpc );

/* Report any errors or success */


if( $results/..//xnm:error ) {
for-each( $results/..//xnm:error ) {
expr jcs:syslog( "external.error", "File Copy Error: ", message );
}
}
else {
expr jcs:syslog( "external.info", "Faulty rollback configuration saved." );
}
}
Xxxx xxx xxxxx xxxxxxxxxxxxx, xxx xxxxx xxxxxx xxxxxxxx xxx xxxx-
xxxxxxxx.xxxx xxxxxx xx xxxxxxxx xx x XX_XXXXXX_XXX_XXXXXXXXX xxxxx
xxxx xxxx x XXXX_XXXX_XXXXXX xxxxx xxx xxxxxxxx xx xxx xxxx 60
xxxxxxx xxx x XX_XXXXXX_XXX_XXXXXXXXX xxxxx xxx xxxxxxxx xx xxx xxxx
50 xxxxxxx.

Within NOT Events


Xxx xxxxx xxxxxxx xxxxxx xxx xx xxx xx xxxxx xxxxxx xx x
xxxxxxxxxxx xxxxx xxxxxxxx xxxxx xx xxx xxxxxxx xxxxx, xxx
xxxxxxxxx xxx xxxxxxxx xx xxxxxxxx. Xx xxxxx, xxx xxxxxxx xxxxxxxxx
xxxxx xx xx xxxx xxxxxxx xxx xxxxxxx xx xx xxxxx xxxxxx xx xxxxxxx
xxxxx xxx xxx xxxxxxxx xxxxxx x xxx xxxx xxxxxx. Xxx xxxxxxxxxxxxx
xxxxxx xx xxxx xxxxx xx xxxxxxx, xxxxxx xxx xxxxxxx xxx xx xxxxxxxx
xx xxxxxxxx xxxx xxxxxxx xx xxx xxxxxxxxxxx xxxxx xxxxxx xxx xxxx-
xxxxx xxxxxx xxx xxxxxx xxx xx xx xxxxxxxxx:
within <seconds> not events [ <correlating events> ]
Xx xx xxxxxxx, xxxxxx xxxx xx xx xxxxxxx xxxxxx xx xxxx xxxxxxx
xxxxxxx xxxxxx x xxx xxxx xxxxxxxxxxx xxxxxx xx xxx xxxxxx xx xxx
xxxxx. Xxxxxxx xxxxxxx xx xxxx xxxxxx xxxxxx xxxxxx xx xxxxxx
xxxxx xxxxxxxx xxxx xxx xx xxxxxxxx xx xx xxxxx xx xxxxxxxxxx
xxxxxxxxxx. Xx xxxxxxxxxx xxxx xxxxxx x xxxx xxxxxxxx-xxxxx xx
xxxxxxx xxxxxx XXXXXXXXXXX-XXXXX. Xxxx xxxxxxxx-xxxxxx xxx xxxxxxx
xxxxx xx xxxx xxxxxxx, xxx xxx xxxx xx xxxxx xxxx xxxxx xxx xx 23:00
xxx XXXXXXXXXXX-XXXXX xxxxx xx xxxxxxxxx.
Xx xxxxx xxxxxx xx xxxxxxx xxxx xxxxxxxx xx xxx XX_XXXXXX xxxxx. Xxx
xxx xxxxxx xxx x xxxxxxxxxxx xxx xxxxx xx XXXXXXXXXXX-XXXXX xxxx x
xxxxxx xxxx xx 2 xxxxx. Xxxx xxxxx xxxx xxx xxxxxx xxxxxxxx xxx xxxxx
xxxxxx, xxxxxx xxx xxxxxx xx xxxxxx xxx xxxxx xx xxx XXXXXXXXXXX-
XXXXX xxxxx. Xxxx xxxxxxxx, xxx xxxxx xxxxxx xxxxxx x xxxxxxx xx xxx
xxxxxx xxxxxxxxxx xxxx x xxxxxx xxx xxxx xxxxxxx xx xxx xxxxxxxx
xxxxx.
Xxxx xx xxx xxxxx xxxxxx xxxxxx xx xxxxxxxx xxxx xxxxxx:
event-options {
policy off-time-commit {
events ui_commit;
within 7200 {
not events maintenance-start;
}
then {
event-script log-syslog-error.slax;
}
}
event-script {
file log-syslog-error.slax;
}
}

Here is the log-syslog-error.slax event script that is executed as a result of this event policy:
/* log-syslog-error.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match / {
<event-script-results> {

/* Send syslog error message */


expr jcs:syslog("external.error", "Commit performed out of maintenance window.");
}
}

Matching Event Attributes


X xxxx xxxxxxx xxxxx xxxxxx xxx xx xxxxxxx xx xxxxxxxxx xxx xxxxx
xxxxxxxxxx xxxxxxx xxxxxxx xxxxxx. Xxxx xxxxxx xxxx xxx xx xxxx
xxxxxxxxxx xxxx xxx xx xxxxxxxxxx xxxxxx xxx xxxxx xxxxxx. Xxxx xxx
xxxxx xxxxxx xxxxxxxx xxxxxxxxxx, Xxxxx xxxxxxxxx xxx xxxx xxx
xxxxxxxxxx xx x xxxxxx xxxxx, xxx xxxx xxx xxxxx xx xxx xxxxx’x
xxxxxxxxxx xx xxxx.
Xx xxxxx xxxxx xxxxxxxxxx, xxx xxx xxxxxxxxxx-xxxxx xxxxxxxxx xxxxx
xxx xxxxx xxxxxx:
attributes-match {
<event1.attribute> equals <event2.attribute>;
<event1.attribute> starts-with <event2.attribute>;
<event.attribute> matches <regular-expression>;
}

Xxxxxxxxx xxxxxx xxx xx xxxxxxxx xx xxxxx xxxx:


„„equals: The two attributes must share the same value.
„„starts-with: The first attribute must start with the value of the
second attribute.
„„matches: The attribute must match the regular expression.
Xxx xxxxxx xxxxxxxxxx xx xxxxxxxxxx-xxxxx xxxxxxxxxx xxxx xx xxxxxx
xxx xxxxxxx xxxxx xx xxx xxxxxxxxxxx xxxxxx xxxxxxxx xx xxx xxxxx
xxxxxx’x xxxxxx xxxxxxxxxx. Xxxx xxxxxxxxxxx xxxxxxx xx xxx
xxxxxxxxxxx:
„„The equals and starts-with attribute comparisons can only be used
when a within statement is present in the event policy.
„„The matches comparison can be used without a within statement, but
only if the event referenced is a trigger event for the event policy.
Xxx’x xxxxxx xx xxx xxxx-xxxxxxxx.xxxx xxxxxxx xx xxxxxxxxxx xxx
xxxxxxxxxx xx xxxxxxxxx xxxxx xxxxxxxxxx. Xx xxxx xxxxxxx, xxx
xxxxxxxxx xxxxx xxxxxx xxx xxxx:
event-options {
policy faulty-rollback {
events ui_commit_not_confirmed;
within 60 events ping_test_failed;
within 50 events ui_commit_not_confirmed;
then {
event-script save-rollback.slax;
}
}
event-script {
file save-rollback.slax;
}
}
Xxx xxxxx xxxxxx xxx x xxxxxxxxx xxxxxxx: xxx xxxxxx xxxx
xxxxxxxxx xxxxxxxxx xxxx x xxxxxx XXX xxxx xx xxxxxxxxxx. Xx
xxxxxxxx XXX xxxxx xxx xxxxxxx xx xxx Xxxxx xxxxxx xxxx xxx xxxxx
xxxxxx, xx xxxxxxxxx xxxxxxxxxx, xxx xx xxx xx xxxxxx xxxxx xxxx xxx
xxxxxx.
Xxx, xxx XXXX_XXXX_XXXXXX xxxxx xxx xxx xxxxxxxxxx xxxx xxx xx xxxx
xx xxxxx xxxx xxxxxxx:
„„test-owner – The RPM probe owner
„„test-name – The RPM test name
Xx xxx xxxxx xxxxxx xx xxxxxxxxxx xx xxxx xxxxx xxxx x
XXXX_XXXX_XXXXXX xxxxx xxx x xxxxxxxx xxxx-xxxxx xx xxxx-xxxx, xxxx xxx
xxxxxxx xx xxxxx XXX xxxxx xxxx xxx xxxxx xxx xxxxxxxx xxxxxxx xx
xxx xxxxx xxxxxx.
Xxxxxx, xxx xxxxxxx, xxxx xxx XXX xxxxxxxxxxxxx xxxx x xxxxx xxxx
xx "Xxxxxxxxxxxx" xxx x xxxx xxxx xx "Xxxxxxxxxx." Xxx xxxxxxxxx xxxxx
xxxxxx xxxxxxxxxxxxx xxxxx xx xxxx xx xxx Xxxxx xxxxxx xx xxxxxxx
xxxxxxxxx xxxx xxxxx XXX xxxxx:
event-options {
policy faulty-rollback {
events ui_commit_not_confirmed;
within 60 events ping_test_failed;
within 50 events ui_commit_not_confirmed;
attributes-match {
ping_test_failed.test-owner matches "^Connectivity$";
ping_test_failed.test-name matches "^Management$";
}
then {
event-script save-rollback.slax;
}
}
event-script {
file save-rollback.slax;
}
}
Xx xx xxxxx xx xxx xxxxxxxxx xx xx xxxxxxxxxx-xxxxx
xxxxxxxxx xxxx xxx
xxxxxxxxxx xxx xxx xxxxxxxx. Xx xxx xxxxx xxxxxxx xxxxx xxx xxx
xxxxxx xxxxxxxxxx xx xxx xxxxxx:
„„UI_COMMIT_NOT_CONFIRMED
„„PING_TEST_FAILED
Xxxx xxxxxxxx xx x XXXX_XXXX_XXXXXX xxxxx xxx xxxxxxxx xxxxxx xxx
xxxx 60 xxxxxxx (xx xxxx xxx xxxxxxx xx xxx xxxxxx 60 xxxxxxxxx), xxx
xxx xxxxxxxxxx-xxxxx xxxxxxxxxx xxxxxxx xxx xxxxxx xx xxx
XXXX_XXXX_XXXXXX xxxxx’x xxxxxxxxxx. Xxx, xxxx xxxxxxxxxxx xx x
XX_XXXXXX_XXX_XXXXXXXXX xxxxx xxx xxx xx xxx xxxxxxx xxxxx xx xxx
xxxxxxxx xxxxx xxx xxx xxxxxx 50 xxxxxxxxx, xx xxxxxxxxx xxxxxxxxxxx
xxx xxxxxxxxx xxxxxxx xxxx xxxxx xx xxx xxxxxxxxxx xx xx xxxxxxxxxx-
xxxxx xxxxxxxxx.

Matching Nonstandard Events


Xxxxxxxxx xxxxxxx xxx xxxxxx xxx xxxx xxxxx xxxxxxxx, xxx xxxx xxx
xxxxxxxxxx xxxxxxxxx xxxx xxxxxx xx xxxxx xx x xxxxxxxxxxx xxxxx.
Xx xxxxxxxxx xxxxxxx xx xxxx xxxxxxx, x xxxxxxxxxxx xxxxx xxxx xxx
xxxx x xxxxxx xxxxx XX. Xxxxxxx xxxxx xxxxxx xxxxx xx XX xxxx xxxxx
xxxxxxxxxxx xxxxxx xx xxx xxxx xxxxxx. Xxx xxxx xxx xxx xx xxxxx
xxxxxx xx xxxxxxxxxxxxx xxxxxxx xxxxx xxxxxx xx xx xxxxxxxxx xxxxx
xxxxxxx xxxxxxxxx xxxxxxx xxx xxxxxxx xxxxxx xxxxxxx.

Xxx xxxxxxx, xxxxxxxx xxx xxxxxxxxx xxxxxx xxxxxxx xxxx xxxxxx


xxxxxxx xx x xxxxxx xxxxx xxxxxx:
Jul 29 11:41:13 Junos craftd[1168]: Major alarm set, Power Supply B not providing power

Xxxx xx x xxxxxxxxxxx xxxxx xxxx xxxxx x xxxxxxxx xxxxx XX. Xxx


xxxxx xx xxxxxxxxxx xx xxx xxxxxx xxxxxx, xxxxx xxxx xxx XXXXXX xxxxx
XX xxx xxxxxxxxxxx xxxxxx. Xx xxxxx xxxxxx xxxxx xxxxx xx xxxx
xxxxxxxxxxx xxxxx xxxx xxx xxxxxxxxx xxxxxxxxxxxxx:
event-options {
policy catch-power-supply-alarm {
events SYSTEM;
attributes-match {
system.message matches "Major alarm set, Power Supply . not providing power";
}
then {
...
}
}
}

Try It Yourself: Matching Nonstandard Events

Find a nonstandard event that has been logged to the syslog of your Junos device. Craft an
event policy that matches this event and executes an event script. The event script should
write a message to the syslog indicating that the script was executed.

Count-Based Triggers
Xxxx xxxxx xxxxxxxx xxxxxx xxxx xxx xxxx xxx xxxxxxx xxxxx(x) xxxx
xxxxxxxx x xxxxxxx xxxxxx xx xxxxx xxxxxx x xxxxxxxxxx xxxxxxxxx.
Xxx xxxxxxx: xxxx xxxxxxx xxx xxxxxx xxxxxxx xx xxx xxxxxxx xxxxx(x)
xxxx xxxxxxxx 5 xxxxx, xx xx xxx xxxxxxx xxxxx(x) xxxx xxxxxxxx xxxx
xxxx 3 xxxxx. Xxxx xxxxxxxx xx xxxxxxxxxx xx xxxxx xxx xxxxxxx
xxxxxxxxx. Xxxx xxxxxxxxx xxxxxxxx xxxx x xxxxx xx xxxxxxxxx xxxxx
xxxx xxx xx xxx xxxxxxxxx xxxxxxxxxxxx:
„„on – Run the policy if the occurrence count equals the configured
count.
„„until – Run the policy if the occurrence count is less than the
configured count.
„„after – Run the policy if the occurrence count exceeds the configured
count.
Xxx xxxxxxx xxxxxxxxx xx xxxxxxxx xxxxxx x xxxxxx xxxxxxxxx xxxx
xxxxxxxx xxx xxxxxxxxx:
within <seconds> {
trigger (on # | until # | after # );
}
Xxx xxxxxxx, xxx xxxxxxxxx xxxxx xxxxxx xx xxx xx xxx xxxx "xxxx"
xxxx xx xxxx xxxx xxxxx xxxxx xxxxxx x xxx xxxxxx xxxxxx:
policy lots-of-logins {
events ui_login_event;
within 10 {
trigger after 3;
}
attributes-match {
ui_login_event.username matches jnpr;
}
then {
...
}
}

Generating Time-Based Events


Xxxxxx xxxx xxxx xxx x xxxxxx xxxxx xx xxxxx, xxxxx xxxxxxxx xxx xx
xxx xx x xxxx-xxxxxxxx xx xx x xxxxxxxx xxxx xx xxx. Xxxx-xxxxx
xxxxxx xxx xxxxxxx xxxxxxx xxx xxxxxxxx-xxxxx xxxxxxxxxxxxx
xxxxxxxxx. Xxxxx xxxx-xxxxx xxxxxx xxxxx xxxxxx xx xxxxxxx xxxxx
xxxxxxxx; xxxx xx xxx xxxxxx xx x xxxxxx xxxxxxx xxxx xxxx xxx
xxxxxxxxx.
Xxxxx xxx xxx xxxxx xx xxxxxxxxx xxxxxx:
„„time-interval – Event is generated at a specific interval configured in
seconds. (Minimum: 60, Maximum: 604800).
„„time-of-day – Event is generated at a specific time of day configured in
24-hour format: HH:MM:SS.
NOTE Time-of-day events are relative to the local Junos device time.
Xxxx xx xx xxxxxxx xxxxx xxxx xx xxxxxxxxx xxxxx xxxx xxxxx:
event-options {
generate-event {
every-5-hours time-interval 18000;
}
}
Xxxx xxxxx xx xxxxxxxxx xx 5:00 xx xxxxx xxx:
event-options {
generate-event {
daily-05:00 time-of-day "05:00:00 +0000";
}
}

NOTE Junos automatically generates the time-zone offset number for the time-of-
day statement if the offset is not specified. This offset is based on the
local time-zone of the Junos device.
Xxxxx xxxxxxxx xxx xxxxx xxxxx xxxxxxxxx xxxxxx xx xxx xxxx xxx
xxxx xxxxx xxxxxx xxxxxx. Xxx xxxxxx xxxxxxxxx xxxx xxx xxxxxxxxx
xxxxx xxxx xx xxxxx xx xx xxxxx XX:
policy match-5-hours {
events every-5-hours;
then {
...
}
}

ALERT! Junos devices can have a maximum of 10 configured generated events.


This includes both time-interval as well as time-of-day events.
Xxxx-xxxxx xxxxxx xxxxx x Xxxxx xxxxxx xx xxxxxxx xxxxxxxx xxxxxxx
xx xxxxxxx xxxxx. Xx xx xxxxxxx, xxx xxxxx xxxxx xxxxxx xxxx x
xxxxxx xxxxxxx xxxxxxx xx xxx /xxx xxxxxxxxxx xxx xxxxxxxx 75%
xxxxxxxxxxx. Xxx xxxxx xxxxxx xx xxxxxxxx xxxxx xxxx xx xxx xxxxx
xxxxxx.
Xxxx xx xxx xxxxxxxxxxxxx xxx xxx xxxxxxxx-xxxxx xxx xxxxx xxxxxx:
event-options {
generate-event {
every-hour time-interval 3600;
}
policy check-var-utilization {
events every-hour;
then {
event-script check-var-utilization.slax;
}
}
event-script {
file check-var-utilization.slax;
}
}

Xxxx xx xxx xxxxx-xxx-xxxxxxxxxxx.xxxx xxxxx xxxxxx:


/* check-var-utilization.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match / {
<event-script-results> {

/* Get show system storage */


var $system-storage = jcs:invoke( "get-system-storage" );

/* Retrieve the /var percent */


var $percent = $system-storage/filesystem[mounted-on=="/var"]/used-percent;

/* Is it too high? Then log a warning. */


if( $percent > 75 ) {
var $percent-string = normalize-space( $percent ) _ "%";
var $syslog-message = "Warning: /var utilization is at " _ $percent-string;
expr jcs:syslog( "external.warning", $syslog-message );
}
}
}
Xxxx xxxx xxxxxxxxxxxxx Xxxxx xxxxxxxxx xxx xxxxx-xxxx xxxxx xxxxx
xxxx, xxxxx xxxxxx xxx xxxxx-xxx-xxxxxxxxxxx xxxxx xxxxxx xx xxxxxxx
xxºx xxxxx-xxx-xxxxxxxxxxx.xxxx xxxxx xxxxxx. Xxx xxxxxx xxxx xxxxxxxxx
xxx xxxxxx xxxxxxx xxxxxxxxxxx xxx xxxx x xxxxxxx xx xxx /xxx
xxxxxxxxx xxx xxxxxx xxxxxx xxxxxxxx.
NOTE This script might have to be modified to run correctly on some Junos
devices, as not all devices have a /var mount point, and "show system
storage" returns slightly different results on certain platforms such as the
EX4200 Virtual Chassis.
How to Change the Junos Configuration at a Specific Time of Day
Xxx xxxxxxxxx xxxxx xxx xx xxxxxxxxx x Xxxxx xxxxxx xx xxxxxx xxx
XXX-1 XXX xxxxxxxx xxxx 6:00 xx xx 6:00 xx, xxx XXX-2 xxxx 6:00 xx xx
6:00 xx.
1. Configure two separate time-based events: one generated at 6:00 am
and one generated at 6:00 pm.
generate-event {
06:00 time-of-day "06:00:00 +0000";
18:00 time-of-day "18:00:00 +0000";
}
2. Xxxxxxxxx xx xxxxx xxxxxx xx xxxxxxx xxx-xxxxxx.xxxx xx xxxx xxx
xxxxxx xxxxxxx xxxxxxx xx xxxxxx XXX-1.
policy prefer-isp-1 {
events 06:00;
then {
event-script day-policy.slax;
}
}
3. Xxxxxxxxx xx xxxxx xxxxxx xx xxxxxxx xxxxx-xxxxxx.xxxx xx xxxx xxx
xxxxxx xxxxxxx xxxxxxx xx xxxxxx XXX-2.
policy prefer-isp-2 {
events 18:00;
then {
event-script night-policy.slax;
}
}

NOTE Configuration changes are performed by event scripts in the same


manner as op scripts. For details on how to perform configuration
changes refer to Part One: Applying Junos Operations Automation.
Xxxx xx xxx xxxx xxxxxxxxxxxxx xxx xxx xxxxxxxx-xxxxxx xxx xxxxx
xxxxxx:
event-options {
generate-event {
06:00 time-of-day "06:00:00 +0000";
18:00 time-of-day "18:00:00 +0000";
}
policy prefer-isp-1 {
events 06:00;
then {
event-script day-policy.slax;
}
}
policy prefer-isp-2 {
events 18:00;
then {
event-script night-policy.slax;
}
}
event-script {
file day-policy.slax;
file night-policy.slax;
}
}

Here are the day-policy.slax and night-policy.slax event scripts:


/* day-policy.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match / {
<event-script-results> {

/* open connection */
var $connection = jcs:open();

/* configuration change to prefer ISP-1 */


var $change = {
<configuration> {
<policy-options> {
<policy-statement> {
<name> "isp-1-import";
<then> {
<local-preference> {
<local-preference> 150;
}
}
}
<policy-statement> {
<name> "isp-2-import";
<then> {
<local-preference> {
<local-preference> 50;
}
}
}
}
}
}

/* load and commit the change */


var $results = {
call jcs:load-configuration( $connection, $configuration = $change );
}

/* Report any errors or success */


if( $results//xnm:error ) {
expr jcs:syslog( "external.error", "Couldn’t make policy changes.");
}
else {
expr jcs:syslog( "external.info", "Import policies now prefer ISP-1" );
}

/* Close the connection */


expr jcs:close( $connection );
}
}

/* night-policy.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match / {
<event-script-results> {

/* open connection */
var $connection = jcs:open();

/* configuration change to prefer ISP-2 */


var $change = {
<configuration> {
<policy-options> {
<policy-statement> {
<name> "isp-2-import";
<then> {
<local-preference> {
<local-preference> 150;
}
}
}
<policy-statement> {
<name> "isp-1-import";
<then> {
<local-preference> {
<local-preference> 50;
}
}
}
}
}
}

/* load and commit the change */


var $results = {
call jcs:load-configuration( $connection, $configuration = $change );
}

/* Report any errors or success */


if( $results//xnm:error ) {
expr jcs:syslog( "external.error", "Couldn’t make policy changes.");
}
else {
expr jcs:syslog( "external.info", "Import policies now prefer ISP-2" );
}

/* Close the connection */


expr jcs:close( $connection );
}
}

Xx 6:00 xx Xxxxx xxxxxxxxx xxx 06:00 xxxxx xxxx xxxxxxxx xxx xxxxxx-
xxx-1 xxxxx xxxxxx xxx xxxxxxxx xxx xxx-xxxxxx.xxxx xxxxx xxxxxx. Xxxx
xxxxxx xxxxxxx xxx xxxxxxxxxxxxx xx xxxxxx xxxxxx xxxx XXX-1. Xxxx,
xx 6:00 xx xxx 18:00 xxxxx xx xxxxxxxxx, xxxxxxxxxx xxx xxxxxx-xxx-2
xxxxxx xxxx xxxxxxxx xxx xxxxx-xxxxxx.xxxx xxxxx xxxxxx. Xxxx xxxxx
xxxxxx xxxxxxxx xxx xxxxxxxx xx xxx xxx-xxxxxx.xxxx xxxxxx. Xxxxxx
xxxx xxxxxxxxxx XXX-1, xxx xxxxx-xxxxxx.xxxx xxxxx xxxxxx xxxxxxxxxx
Xxxxx xx xxxxxx XXX-2 xxxx XXX-1.
NOTE These event scripts assume that the correct routing policy is present
when the event policies and event scripts are first added to the Junos
device. The event scripts do not check the configuration until one of the
time-based events occurs.

Changing the System Time


Xx xxx xxxx xx xxxxxxxx xxxxxxx xx xxx Xxxxx xxxxxx xxxxxxx xxx xxx
xxxx xxxxxxx xxxx xxx xxxxxxxxx xxxxxx xxxx xx xxxxxxxxxxxx xx xxxx
xxxxxx xxx xxxxxxxxx. Xx xxxxxxx xxx xxxxxxxxx xxxxxx xxx xxx xx
xxx xxxxxxxxx xxxxxxxx:
„„commit full
„„restart event-processing
„„request system scripts event-scripts reload
Try It Yourself: Time-based Configuration Changes

Create a local user account called test-user on your Junos device. Create the necessary
generated events, event policies, and event scripts to have the test-user automatically
assigned to the super-user class from 8am to 5pm and the read-only class from 5pm to 8am.
Chapter 7: Additional Policy Actions 99
98 This Week: Applying Junos Automation

Xxxxxxx 6 xxxxxxx xxx xxxxxx xxxxx xx xxx XXXX xxxxxxxxx. Xxxxxxx


5 xxxxxxxxxxxx xxx xxx xx xxxxx xxxxxxxx xx xxxxxxxxxxxxx xxxxxxx
xxxxx xxxxxxx xx xxxxxxxx xx xxxxxx xxxxxx. Xxxx xxxxxxx xxxxxxxxx
xxx xxxxx xxxxxxx xxxx xx xxxxx xxxxxx xxx xxxxxxx: xxxxxxxxx
xxxxxxxxxxx xxxxxxxx, xxxxxxxxx xxxxx xx xxxxxx xxxxxxxxxxxx,
xxxxxxx XXXX xxxxx, xxx xxxxxxxx xxxxxx xxxxxx.
TIP Multiple actions can be configured within an event policy unless the ignore
action is being used. When used, ignore must be the only action
performed by an event policy.

Executing Commands
Xxxxxxxxxxx xxxxxxxx xxx xxxxxxxxxxxxx xxxxxxx xx xxxxxxxx xx x
xxxxxx xxxxx xxx xxxxx xxxxxxx xxx xx xxxxxx xxxxxx xxxxxxx xx
xxxxxxxx. Xxxx xxxxxxxxxxxxx xxxxxx Xxxxx xx xxxxxxxxxxx xxxxxx
xxxxxxxx xxxxxxxxxxx xx xxxxxxxx xx x xxxxxx xxxxx xxxxxx xxxx
xxxxxxx xxx xxxxx xxxxxxxxxxxxxxx xx xxxxx xxxxxxxxx.
Xx xxxxxxxxx xxxx xxxxxx xxxxxx, xxx xxx xxxxxxx-xxxxxxxx xxxxxxxxx.
Xxx xx xxxx xxxxxxxx xxx xx xxxxxxxxx xxxxx xxxx xxx xxxxxxx
xxxxxxxxxxx xx xxxxx xxx xxxxxxx.
Xxx xxxxxxxxx xxxxxxx xxxxxxxxxxxx xxx xx xxx xxx xxxxxxx-xxxxxxxx
xxxxxxxxx xxxxxx xx xxxxx xxxxxx. Xx xxxx xxxxxxx, xxx xxxxx xxxxxx
xxxxxxx xxx xxxxxxx xx x xxx xx XXXX xxxxxxxx xxxxxxx xx XXXX
xxxxxxxx xxxx xxxx:

event-options {
policy ospf-neighbor-down {
events rpd_ospf_nbrdown;
then {
execute-commands {
commands {
"show ospf neighbor extensive";
"show ospf interface extensive";
"show ospf statistics";
}
output-filename ospf-down-output;
destination local;
output-format text;
}
}
}
destinations {
local {
archive-sites {
/var/tmp;
}
}
}
}
X xxxxxx xx xxxxxxxxxxxxx xxxxxxxxxx xxx xxxx xxxx xxx xxxxxxx-
xxxxxxxx xxxxxxxxx xx xxxxxxx xxxxx xxxxxxxx xx xxxxxxx, xxx xxxxxx
xxxxxx xx xxx, xxx xxx xxxxxxx xxxxxxxxxxx xx xxxxx xxx xxxxxx. Xxx
xxxxxxxxx xxxxxxxx xxxxxxx xxxxx xxxxxxxx.

Selecting Commands
Xxx xxxxxxxx xxxxxxxx xx xxx xxxxx xxxxxx xxx xxx xxxxxxxx xxxxx
xxxxxxx-xxxxxxxx xx xxxxx xxx xxxxxxxx xxxxxxxxx. Xxx xx xxxx xxxxxxxx
xxx xx xxx, xxx xxxx xxxx xxx xx xxxxxxxxxxx xxxx xxxxxxxx.
NOTE Configuration changes have to be made through scripts. Execute-
commands can only be used for operational mode commands.
event-options {
policy ospf-neighbor-down {
events rpd_ospf_nbrdown;
then {
execute-commands {
commands {
"show ospf neighbor extensive";
"show ospf interface extensive";
"show ospf statistics";
}
...
}
}
}
}

Xx xxx xxxxx xxxxxxx, "xxxx xxxx xxxxxxxx xxxxxxxxx", "xxxx xxxx xxxxxxxxx
xxxxxxxxx", xxx "xxxx xxxx xxxxxxxxxx" xxx xxx xxxxxxxx xxxxxxxxxxxx.

Configuring a File Destination


Xxxx xxxxxxxxx xxxxxxxx, xxx xxxxx xxxxxx xxxx xxxxxxx
xxxxxxxxxxxxx xxxxxxxxxx xxxxxxx x xxxxx xx xxxxxx xxxxxxxxxxx xx
xxxxx xxx xxxxxx xx xxx xxxxxxxx xxxxxxxx. Xxxx xx xx xxxxxxx xx x
xxxxx xxxxxxxxxxx xxxxx xxxxx:
event-options {
destinations {
local {
archive-sites {
/var/tmp;
}
}
}
}

Xxx xxxxxxxxxxx xxxx xxxx xx xxxxxxxxxx xxxxxx xxx xxxxxxx-xxxxxxxx


xxxxxxxxx:
event-options {
policy ospf-neighbor-down {
events rpd_ospf_nbrdown;
then {
execute-commands {
...
destination local;
...
}
}
}
}

Xxx xxxx-xxxxxxxx-xxxx xxxxx xxxxxx xxxxxxx xxxxx xxx xx xxx xxxxx xxxx
xxxxxxxxxxx xx xxx xxxxxx xxxx xxxxxxxxxxx. Xxxxxxxxxxxxx, xxxxxx
xxxxxxx xxxxxxxxx xxx xx xxxxxxxxxx xx xxxxxxxxxx xxx xxxxxxx-xxxx
xx x XXX, xxxxxx xxxx x xxxxx xxxxxxxxx. Xxxxx xxxxxxxxxxxx
xxxxxxxxx xxxx xx xxxxxxxxxxx xxxxxxx xxx Xxxxx xxxxxx xxx xxx
xxxxxx xxxxxxx xxxxxxx XXXX, XXX, xxx XXX. Xxxx xx xx xxxxxxx xx x
xxxxxx xxxxxxxxxxx xxxxx xxxxxx-xxx xxxx xxxx XXX xx xxx
xxxxxxxxxxxx xxxxxxxx:
event-options {
destinations {
remote-scp {
archive-sites {
"scp://user@10.0.0.1:/var/tmp" password "$9$oSaDk.mT3/tfTIESyKvaZG";
}
}
}
}

MORE? For more information on configuring archive destinations see the


Configuration and Diagnostic Automation Guide within the Junos
documentation at www.juniper.net/techpubs/.

Specifying an Output Filename


Xx xxxxxx xxxxxxxx xxxx xxxx xx xxxxxxxxxx xxxxxx xxxxxxx-xxxxxxxx xx
xxxxxxxx xxx xxxxxx xx xxx xxx xxx xxxxxx xxxxx xxxxxxxxx xx xxx
xxxxxx. Xxxx xx xxxxxxxxxxxx xx xxx xxxxxx-xxxxxxxx xxxxxxxxx:
event-options {
policy ospf-neighbor-down {
events rpd_ospf_nbrdown;
then {
execute-commands {
...
output-filename ospf-down-output;
...
}
}
}
}
Xxx xxxxxx xxxxxxxx xxxxxxx xx xxx xxxxxx xx x xxxxxxxxxxx xx xxx
xxxxxxxxx:
„„hostname
„„output-filename string
„„date and time
„„unique sequence number (if needed to distinguish between files)
Xxxxx xxx xxxxxxxx xx xxx xxxxxxxxx xxxxxx:
hostname_filename_YYYYMMDD_HHMMSS_index-number
Xxx xxxxxxx, xxxx x xxxxxxxx xx Xxxxx xxx xx xxxxxx xxxx xxxx xx
xxxx-xxxx-xxxxxx xxx xxxxx xxxxxx xxxxx xxxxxx xxx xxxxxxxxx xxxxxx
xxxx xxxxx:
Junos_ospf-down-output_20090718_111648
Junos_ospf-down-output_20090718_111912
Junos_ospf-down-output_20090718_122021

Choosing an Output Format


Xx xxxxxxx, Xxxxx xxxxxx xxx xxxxxx xx xxxxxxxx xxxxxxxx xx XXX
xxxx. Xx xxxx xxxxxx xx xxxxxxx xxxxxxx, xxxx xxx xxx xxxxxx-xxxxxx
xxxxxxxxx xx xxxxxx xxxx xxxxxx xxxxxx xxxx xxx:
event-options {
policy ospf-neighbor-down {
events rpd_ospf_nbrdown;
then {
execute-commands {
...
output-format text;
...
}
}
}
}

Executing as a Different User


Xxx xxxx xxxx xxxxxxxx xxx xxxxxxxx xx xxxxxxx. Xx xxx xxxxx xxxxxx
xxxxxx xxxxxxx xxx xxxxxxxx xxxxx x xxxxxxxxx xxxx xxxxxxx xxxx
xxxxxxxx xxxx xx xxxxxxxxx xxx xxxx-xxxx xxxxxxxxx:
event-options {
policy ospf-neighbor-down {
events rpd_ospf_nbrdown;
then {
execute-commands {
...
user-name operator;
...
}
}
}
}

Using Event Policy Variables


Xxxx xxxxxxxxxx xxx xxxxxxxx xx xxxxxxx, xx xx xxxxxxxx xx xxx
xxxxx xxxxxx xxxxxxxxx xx xxxxxxx xxxxx xxxxxxxxxx xxxxxx xxx
xxxxxxxx xxxxxxxxxx. Xxxxx xxxxxxxxx xxxxxxxxx xxx xxxxxxxxx:
„„{$$.attribute}: This variable refers to an attribute of the trigger event.
„„{$event.attribute}: This variable refers to an attribute of the most
recent occurrence of the specified event ID.
„„{$*.attribute}: This variable refers to an attribute of the most recent
correlating event from a within clause of the event policy.
Xx xxxxxxxxx xxxxx xxxxxx xxxxxxxxx, xxx xxxxxxxx xxxxxxxx xxx xx
xxxxxxx xx xxxxxx xxx xxxxxxxx xxxxxxxxxxx xxxxxxx - xxxxx xx xxx
xxxxxx xxxxx xxxx xxxxxxxx. Xxx xxxxxxx, xxx xxxxxxxxx
xxxxxxxxxxxxx xxxx xx xxxxx xxxxxx xxxxxxxx xx xxxxxx xxx xxxx
xxxxxxxxx xxxxxxxxx xxxxxx xxxx xx xxxxxxxxx xxxx xxxx xxxx xxxx:
event-options {
policy save-interface-output {
events snmp_trap_link_down;
then {
execute-commands {
commands {
"show interfaces extensive {$$.interface-name}";
}
...
}
}
}
...
}

Xxx {$$.xxxxxxxxx-xxxx} xxxxx xxxxxx xxxxxxxx xxxxxxx xxx


XXXX_XXXX_XXXX_XXXX xxxxxxx xxxxx, xxxxx xxx xx xxxxxxxxx-xxxx
xxxxxxxxx. Xxx xxxxxxx:
„„If so-2/0/0 went down the policy triggers the output of the show
interfaces extensive so-2/0/0 command.

„„If ge-1/0/1 went down the policy triggers the output of the show
interfaces extensive ge-1/0/1 command.

Xx xxxxxxxx xxxxxxxxxx xxxx xxx xxxx xxxxxx xxxxxxxxxx xx xxx


xxxxxxxxx xxxxx, xxx xxx {$xxxxx.xxxxxxxxx} xxxxxxxx. Xx xx xxxxxxx,
xxxxxx xxxx x Xxxxx xxxxxx xxx x xxxxxxxxxx xxxx-xx-xxx xxxxxxxx-
xxxxx xxxxxx XXXXXXXXXXX-XXXX. Xxxx xxxx xxxxx xxxxxx, xx xxx
xxxxxxxxx xxx xxxx xx xx xxxx xx xxx xxxx xxxx–xx xxxxxxxxx xx x
XXXX_XXXX_XXXX_XX xx XXXX_XXXX_XXXX_XXXX xxxxx–xxxxx xxx xxxxxx
xxxxxxxx xxx xxxx xxxxxxxxxx xxxxxxx xx xxxxxxx xxx xxxx xxxxxxxxx xx
xx xx, xx xxxx xx xxx xxxx xxxxxxxxx xx xx xxxx. Xxx xxxxx xxxxx
xxxxxx xxxxx x xxxxxxxx xxxxxxxxxxxxx:
event-options {
policy save-interface-output {
events maintenance-stop;
within 3600 events [ snmp_trap_link_down snmp_trap_link_up ];
then {
execute-commands {
commands {
"show interfaces {$snmp_trap_link_up.interface-name}";
"show interfaces {$snmp_trap_link_down.interface-name}";
}
...
}
}
}
...
}

NOTE Versions of Junos prior to 9.6 require the event ID to be capitalized within
the event policy variable. Starting with Junos 9.6 the event ID can be
configured in either upper or lower case. The attribute name must
always be configured in lower case.
TIP The {$event.attribute} variable always selects the most recent occurrence
of the event ID. When using an attributes-match statement in the event
policy, be aware that the event that fulfilled the attributes-match might not
be the most recent occurrence of the event ID.
Xxx xxxx xx xxxx xxx xxxx xxxxxx xxxxxxxxx xx xx xx xx xxxx xx
xxxxxx xxx xxx xxxxxxxxx xxxxxx? Xx xxxx xxxx, xxx {$*.xxxxxxxxx}
xxxxxxxx xx xxx xxxxxxxxxxx xxxxxxxx xx xxx. Xxxx xxxxxxxx
xxxxxxxxxx xx xxxxxxxxx xx xxx xxxx xxxxxx xxxxxxxxxxx xxxxx, xxxxx
xxxxx xx xxxxxx XXXX_XXXX_XXXX_XX xx XXXX_XXXX_XXXX_XXXX xx xxx
xxxxxxxxxxxxx xxxxx. Xxxx xx xx xxxxxxx xx xxx xxxxxxxxxxxx
xxxxxxxxx xx xxxxx xxxx xxx xxxxxxxxx xxxxxx, xxxxxx xxx xxxxxxxxx
xxxx xxxx xx xx xxx xxxxxxxxx xxxx xxxx xxxx, xx xx xxxxxxxx xx xxx
xxxxx xxxxxx xxxxxx:
event-options {
policy save-interface-output {
events maintenance-stop;
within 3600 events [ snmp_trap_link_down snmp_trap_link_up ];
then {
execute-commands {
commands {
"show interfaces extensive {$*.interface-name}";
}
...
}
}
}
...
}

TIP The {$*.attribute} variable always selects the most recent occurrence of a
correlating event. When using an attributes-match statement in the event
policy, be aware that the event that fulfilled the attributes-match might not
be the most recent correlating event.
BEST PRACTICE Do not use an event policy variable to refer to a correlating event that is
subject to an attributes-match for the event policy.

Try It Yourself: Executing Commands

Create an event policy that reacts to a UI_COMMIT event by storing the configuration of the user
account that performed the commit. The output file should be saved locally in the /var/tmp
directory in XML format.
Uploading Files
Xx xxxxx, xx xx xxxxxxxxxxx xxx xx xxxxx xxxxxx xx xxxxxx xx
xxxxxxxx xxxx xxxx xxx Xxxxx xxxxxx xx x xxxxxx xxxxxx. Xxxx xxxx
xxxxx xx x xxxxxxxxxxxxx, xxx xxxx, xxxx-xxxx, xx xxx xxxxx xxxxx
xxxx xxxx xxxxxx xx xxxxxx xxxxxxxx.
Xx xxxxxxxxx xxxx xxxxx xxxxxx xxxxxx, xxx xxx xxxxxx xxxxxxxx
xxxxxxxxx. Xxxx xxxxx xx, xxxxxxx xxx xxxx xx xxxx xx xxxx xx xxx
xxxxxxxxxxx xx xxxxx Xxxxx xxxxxx xxxxxx xxx xxxx. Xxxx xx xx
xxxxxxx xx xx xxxxx xxxxxx xxxx xxxxxxx xxx xxxxxx xxxx xxxxx xx x
xxxxxx xxxxxxxxxxx xx xxxxxxxx xx xx xxxxxx xxxx-xxxx:
event-options {
policy save-core {
events kernel;
attributes-match {
kernel.message matches "(eventd).*(core dumped)";
}
then {
upload filename /var/tmp/eventd.core* destination remote-host;
}
}
...
}

TIP The remote-host archive destination must also be configured in the same
manner as shown in the previous section.
MORE? For more information on the upload file event policy action see the
Configuration and Diagnostic Automation Guide within the Junos
documentation at www.juniper.net/techpubs/.
Try It Yourself: Uploading Files

Create an event policy that uploads the messages log file to a remote server every day.

Raising SNMP Traps


Xx xxxxxxxx xx xxx xxxxxxx xxxxxxxxx xx xxxxx xxxxxxxx, Xxxxx
xxxxxxx xxx xx xxxxxxxxxx xx xxxxxxxx x XXXX xxxx xx xxxxxxxx xx x
xxxxxx xxxxx. Xxx xxxxxxxxxxxxx xxxxxxxxx xx xxxxxxx xxxx xxxxxx
xx xxxxx-xxxx. Xxx xxxxxx xx xxx XXXX xxxx xx xxxxxxxxx xx xxx xxx-
xxxxxx.xxx. Xxx xxxx xxxxxxxx xxx xxxxxx xxxxxxx, xxxxx XX,
xxxxxxxxxx xxx xxxxx xxxxxx, xx xxxx xx xxx xxxxxx xxxxxxxx xxx
xxxxxxxx.
Xxxx xx x xxxxxx xxxxxxx xx xx xxxxx xxxxxx xxxx xxxxxxxxx x xxxx
xxxxx xxxx x xxxxxx xx xxxxxxxxx:
event-options {
policy commit-trap {
events ui_commit;
then {
raise-trap;
}
}
}

MORE? For more information on the raise-trap event policy action see the
Configuration and Diagnostic Automation Guide within the Junos
documentation at www.juniper.net/techpubs/.
Try It Yourself: Raising SNMP Traps

Create an event policy that raises an SNMP trap every time a user enters or leaves the
configuration database.

Ignoring Events
Xx xxxx xxxxx xxx xxxxxx xxxxxx xxxxxxx Xxxxx xx xxxxxxx xx xxxxx
xxxx x xxxxxxx xxxxxx xx xxxxx. Xxx xxxxxx xxxxxxxxx xxxxxx xxx
xxxxx xxxxxxxxxx xxxxxx xx xxxx xxxxx xxxxxxxxxx xxx xxx xxxxxxx
xxxxx. Xxxxx xxxx xxx xxxxxxx xxx xxxxx xxxxxxxx xxxx xxxxx xxxxx
xx xxx xxxxxxxxxxxxx, xxx xx xxxx xx xxxxxxxx xx xxx xxxxxx xxx xxx
xxxxx.
ALERT! The ignore statement must be the only action configured for the policy.
Xxx xxxxxx xxxxxx xx xxxxxxxxx xxxx xxxxx xxxx xxx xxxxxxx xxxxx
xxxxxxxx xxxxxxxxx xx xxxxxx xxxxxx. Xxxx xxxxxxxx xxxxxxx xxxx xx
xxxxx xx xxxx xxxxxxxxx x xxxxxxx xxxxxx xx xxxxx xxxxxx xxx
xxxxxxxxxx xxxxxxxxx. Xx xxx xxxx xxx xxxxxxxxxx xx xxxxx xx
xxxxxxxx, xxxx xxx xxxxx xxxxxxxxxx xxxxxx xxxxxxx xxx xxxxxxx
xxxxxxxxxxx xx xxx xxxxx xxxxxx xxx xxxxx xxxxxxxxx. Xxx xxxxxxx xx
xxxxx xxxxxxxxx xxxxx xx xxxxxx xx x xxxxxxxx xxxxx xxxx
xxxxxxxxxx xxxxx xxx xxxxxx. X xxxxxx xxxx xxxxxx Xxxxx xx xxxxxx
xxx xxxxx xxxxx x xxxxxxxxxx xxxxxx xx xxxxxxxxxxx xxxxx xxxx xx
xxxxxxxx xxx xxxxxx xx xxxxxx xxxxxxxxx. Xxxxxxx xxxxxxx xx
xxxxxxxxxxx Xxxxx xx xxxx xxxxxxx xxx xxxx-xxxxxxxx-xxxx xxxxx xxxxxx
x xxxxxxx xx xxxx xxxxx xxxxxx x xxxx xxxxxx xxxxxx:
event-options {
policy ignore-ospf-neighbor-down {
events rpd_ospf_nbrdown;
within 300 {
trigger after 5;
}
then {
ignore;
}
}
policy ospf-neighbor-down {
events rpd_ospf_nbrdown;
then {
execute-commands {
commands {
"show ospf neighbor extensive";
"show ospf interface extensive";
"show ospf statistics";
}
output-filename ospf-down-output;
destination local;
output-format text;
}
}
}
destinations {
local {
archive-sites {
/var/tmp;
}
}
}
}

Xxx xxxxxx-xxxx-xxxxxxxx xxxxxx xxxx xxxx xx xxx XXX_XXXX_XXXXXXX xxxxx


xxxxxx xxxx xxxx xxxx xxxxx xxxxxx x xxxx xxxxxx xxxxxx. Xxxx xxxx
xxxxxxx, xxx xxxxxx xxxxxx xxxxxx xxx xxxxx xx xx xxxxxxx. Xxxx
xxxxx xxxx xxx xxxxxxxxx xxxx-xxxxxxxx-xxxx xxxxxx xxxx xxx xxx xxx x
xxxxxx xxxxxxx xx xxx xxxxxx xx xxx xxxxx.
Try It Yourself: Ignoring Events

Add an ignore-event policy before the event policy that was created in the Executing Commands
section. This ignore-event policy should run if a commit is performed more than once per
minute.

Chapter 8: Event Script Capabilities 109


108 This Week: Applying Junos Automation
Xxx xxxxxxxx xxxxxxxx xxxxxx xxxxxxxx xx xxxxxx xxxxx xxxxxxx. Xx
xxxxx xxxx xxxxxxxx xxxxxxxxxxxx, xxxxx xxxxxxx xxx xxxxxxxxx xx
xxxxxxx xxxx xxx xxxxxxxx xxxxxxxxxxxxx xx xxxxxxxx xx x xxxxxx
xxxxx. Xxxx xxxxxxxxxx xxxxx xxxxxxx xxx xx xxxxxxx xx xxxx xxx, xxx
xxxx xxxxxxx xxxxxxxxxx xxxx xxxxxx xxxxx xxxxxx xxxxxxxxxxxx.
Xxxxx xxx xxxxxxxxxxxx xxxxx xxxxx xxxxxxx xx xxx xx xxxx xxxx xx
xxxxxxxxxxxxx xxxxxxxx xx xxxxxx xxxxxx, xxx xxxx xxxxxxxx xxx
xxxxxxxxxxxxx xxx xxxxx xxxxxxx.
Xx xxxxxxxx, xxxx xxxxxxx xxxxxxxxx xxxxxxx xxxxx xxxxxx xxxxxxxx
xxxxxx xxxx xxxxxx xxxx xx xxxx xxxxx xxxxxxx, xxxxx xxx xxxxxxx
xxxxx xxxxx-xxxxxxx xxxxx-xxxxxx, xxx xx xxxxxxxxxxxxx xxxxxxxx xx
xxxxxxx, xxxxx xxx xxxxxxx xxxxx xxxxxx xxxxxxx xx. Xxxxxx xxxx xxx
xxxxxxxx xx xxxxx xxxxxxx xxxxxxx xxxxx xxxxx-xxxxxxx xxxxx-xxxxxx
xxxx xxxx xxxxxxxxxxx xxxxx xxxxxx xxxxx xxxxxxx.
NOTE See Chapter 5 for the different storage/enable methods.

Executing Event Scripts


Xxxxx xxxxxxx xxx xxxxxxxxxxxxx xxxxxxxx xx xxxxxxxxxxx xxxx xx xx
xxxxxx xx xx xxxxx xxxxxx:
event-options {
policy example {
events ui_commit;
then {
event-script example-script.slax;
}
}
event-script {
file example-script.slax;
}
}
Xxxx xxxx xxx xxxxx-xxxxxx xxx xx xxxxxxxx xx x xxxxxx xxxxxx:
event-options {
policy example {
events ui_commit;
then {
event-script example-script.slax;
event-script example-script-2.slax;
}
}
event-script {
file example-script.slax;
file example-script-2.slax;
}
}

Event Script Output


Xxxxxx xx xxxxxxx, xxxxx xxxxxxx xxxx xx xxx xx xxxxxx xxxx xx xxx
xxxx xxxxxxx. Xx xxxxxxx xxx xxxxxxxx xxxxxxxx xx xxxxx, xxxxxx
xxxxx xxxx xxxxxxx. Xxxx xxxxxxx xxx x xxxxxxxxxxxxx xxxxxxx xxxx
xxx xx xxxxxx xxx xxxxx xxxx xx. Xx xxxxxxxx, xxxxx xxxxxxx xxx
xxxxxxxx xxxxxxxxxxxxx xx xxx xxxxx xxxxxxxxxx xxxxxx. Xxxx xxx
xxx xxxxxxxx xxxxxx x xxxxxx xxxx xxxxxxx, xx xxxxx xx xx xxxxxxx
xxxxxxxxx xxx xxxxx xxxxxxx xx xxxxx xx.
Xxx, xx xxxxxxxxx xxxxxx xxxxxx xxxxxx xxx xxxxx xxxxxxx. Xxxxx
xxxxxxx xxx xx xxxxxxxxxx xx xxxxx xxxxx xxxxxx xx x xxxx, xxxxx xx
xxxxxx xxxxxxx xx xxxxxxxx, xx xxx xxxx xxx xxxx xxx xxxxxxx-xxxxxxxx
xxxxx xxxxxx xxxxxx xxxxxx xxx xxxxxx. Xxx xxxxxxxxxxxxx xxxx xx
xxxx xxxxxxxxx xx xxx xxxxxxx-xxxxxxxx xxxxxxxxx xxxxxxxxx xx Xxxxxxx
7. Xxx xxxxx xx xxxxx xxxxx xxxxxx xxxxxx xx x xxxx xxx:
„„A destination is configured – pointing at either a local file directory or
a remote URL.
„„The destination is referenced under the event-script policy action
statement along with an output filename string.
Xx xxxxxxxxx xx Xxxxxxx 7, xxx xxxxxx xxxxxxxx xx xxxxxxx xx
xxxxxxxxx xxx Xxxxx xxxxxx xxxxxxxx xxxx xxx xxxxxxxxxx xxxxxxxx
xxxxxx, xxx xxxx xxx xxxx, xxx x xxxxxx xxxxx xxxxxx, xx xxxxxxxxx.
Xxxx xx xx xxxxxxx xx xxx xxxxx xxxxxx xxxxxxxxx xx xxx xxx xxxxx-
xxxxx.xxxx xx xxxxxx (xxxxx xx Xxxx Xxx: Xxxxxxxx Xxxxx Xxxxxxxxxx
Xxxxxxxxxx) xx xx xxxxx xxxxxx:
event-options {
policy hello-login {
events ui_login_event;
attributes-match {
ui_login_event.username matches "^jnpr$";
}
then {
event-script hello-world.slax {
output-filename hello-world-output;
destination local;
output-format xml;
}
}
}
destinations {
local {
archive-sites {
/var/tmp;
}
}
}
event-script {
file hello-world.slax;
}
}
Xx xxxx xxxxxxx, xxx xxxxx-xxxxx.xxxx xxxxxx xx xxxxxxxxxx xx xxxxxxx
xxxxxxx xxx xxxx xxxx xxxx xxxx xxx Xxxxx xxxxxx. Xxx xxxxxx xxxx
xxxxx-xxxxx-xxxxxx xx xxx xxxxxx xxxxxxxx xxxxxx xxx xxxxxx xxx xxxxxx
xxxxx xx /xxx/xxx. Xxx xxxxxxxx xxxxxx xxxxxx xx XXX xxxxxx xxxx xxxx.
Xxxx x xxxxxxxx xx Xxxxx, xxx xxxxxx xxxxxx xxxxxxxxx xxxxxx xx
/xxx/xxx xxxxx xxxx xxxxxxx xx xxxx:
Junos_hello-world-output_20090803_224719

Xxx xxxxxx xxxxxx xx xxxx xxxxx: xx xxxxxxx Xxxxx Xxxxx! Xxxx xx xx


xxxxxxx xx xxxx xxx xxxxxx xxxx xxxxxxxx xxxx xxxx (xxxxx xxxxx xxx
xxxx xxxxx xxx xxxxxxxxxxx):
<event-script-results>
<output>Hello World!</output>
</event-script-results>

Output Format and Executing User


Xxx xxxxxx xxxx xxx xxx xxxxx xxxxxx xxxxxx xxxx xx xxxxxxxxxx
xxxxx xxx xxxxxx-xxxxxx xxxxxxxxx xx xxx xxxx xxx xx xxx xxxxxxx-xxxxxxxx
xxxxxx xxxxxx, xxx xxx xxxxxxx xxxxxx xxx xxxxx xxxxxxx xx xxxx
xxxxxx xxxx xxx. Xxx xxxx-xxxx xxxxxxxxx xxx xx xxxxxxxxxx xxx xxx
xxxxx xxxxxx xx xxxx, xx xxxxx xxxx xxx xxxxx xxxxxx xxxxxxxx xxx
xxxxxx xxxxx xxx xxxxxxxxx xxxx xxxxxxx xxxxxx xxxx xxx xxxxxxx
xxxx xxxx.
ALERT! The output-format and user-name statements can only be used with event
scripts that are enabled under system scripts op (see Chapter 1 for the
different event script enabling methods). The statements do not function
correctly for event scripts enabled under event-options event-script. In the
latter case, the xml output-format is always used whether the output-format
statement is included or not, and the scripts must be executed by the
root user so the user-name statement should not be used.

Event Script Arguments


Xxxxx xxxxxxx xxx xxxxxxx xxxxxxxxx xx xxxxxxxxx xxxx xx x xxxxxxx
xxxxxx xx xx xxxxxxx. Xxxxxx xxx xxxxxx xxxxxx, xxx xxxxxxxxx xxx
xxxxxxxxx xx xxxxxxxx xxxxxxxxxx xx xxx xxxx xxxx. Xxx xxxxxxx, xx
xxxxxxx xx xxxxxxxx xxxxx xxxxxxx xxx xxxxx xxxxxx xxxxx xxxxxxx xxx
xxxxxxxxx xxxxxx xxxxxxxxx :
param $message;

Xxxx xx xxxxxxx, xxxxxxxxxxxxxx xxxxxxx xxx xxxxxxxxx xx xxx


xxxxxx xx xxxxxxxx xxxx xx xxx xxxxxxx-xxxx, xxx xxxxx xxxxxx
xxxxxxxxx xxx xxxxxxxx xxxx xxx xxxxx xxxxxx xxxxxxxxxxxxx xxxxxx.
Xxx xxxxx xxxxxx xxx xxxxxxx xx xxxxxxxxx xxxxxxxxx xxxxxxxxxx xxx
xxxxx-xxxxxx xxxxxxxxx xxx xxxxxxx xxxxxxxx xxxxxxxxx:

event-options {
policy log-root-login {
events login_root;
then {
event-script log-message.slax {
arguments {
severity notice;
facility external;
message "Login by root";
}
}
}
}
event-script {
file log-message.slax;
}
}
Xx xxx xxxxxxx xxxxx, xxxxx xxxxxxxx xxxxxxxxx xxx xxxxxxxx xx xxx
xxx-xxxxxxx.xxxx xxxxxx xxxx xx xxxxxxxx. Xx xxx xxx xxxxxxxxx, xxx xxx-
xxxxxxx.xxxx xxxxxx xxxx xxxx xxx xxxxxxxxx xxxxxx xxxxxxxxxx
xxxxxxxx:
param $severity;
param $facility;
param $message;

Xxxxxxxxx xxx xxxxxxx xxxxx xxxxxx xxxxxxxxx xx xxxx xxxxx


xxxxxxxx xxxxxxxxxxx xx xxx xxxxx xxxxxx xx xxxx. Xxxxx xxxxxxx xxx
xxx xxxx xx xxx xxxxxxxxx xxxxxxxxx xxx xxx xxxxxxx-xxxxxxxx xxxxxx
xxxxxx :
„„{$$.attribute} - This variable refers to an attribute of the trigger event.
„„{$event.attribute} - This variable refers to an attribute of the most
recent occurrence of the specified event ID.
„„{$*.attribute} - This variable refers to an attribute of the most recent
correlating event from a within clause of the event policy.
NOTE Versions of Junos prior to 9.6 require the event ID within the event policy
variable to be capitalized. Starting with Junos 9.6, the event ID can be
configured in either upper or lower case. The attribute name must
always be configured in lower case.
TIP The {$event.attribute} and {$*.attribute} variables always select the most
recent occurrence of their particular events. When using an attributes-match
statement in the event policy, be aware that the event that fulfilled the
attributes-match might not be the most recent correlating event.

BEST PRACTICE Do not use an event policy variable to refer to a correlating event that is
subject to an attributes-match for the event policy.
Xxxx xx xx xxxxxxx xx xx xxxxx xxxxxx xxxx xxxxxx xxxxx xxxxxx
xxxxxxxxx xx xx xxxxx xxxxxx xxxxxxx xxxxxxxxx. Xxx xxxx xx xxxx
xxxxx xxxxxx xxx xxxxx xxxxxx xx xx xxxxxxxxxxxxxxxx xxxxxxx xxx
xxxxx xxxxxxxx xxxxxxxxxx xxxx xx xxx xxxxxxx xxxx xxx
xxxxxxxxxxxxx xxxxxxx. Xxxx xx xxxxxxxxxxxx xx xxxxxxx xxx xxxx xx
xxx xxxxx xxxxxx xxxxxxxxx xx xxx xxxxx xxxxxx, xxxxx xxxxx xxxxxx
xx xxx xxxxxxxxxxxxx xx xxxxxxx xxx xxx xxxxxxxxx. Xx xxx xxxxxxxxx
xx xxx xxxxxxxxxx xxxx xxx xxxxx xxxxxx xxxx x xxxxxxx xxxxxxxxx
xxxxx xxx xxxxxxxxx xxx xxxxxxx xxx xxxxxx.
Xxxx xx xxx xxxxx xxxxxx xx xxxxxxx xxxx xxxxxx:
event-options {
policy set-admin-down {
events chassisd_ifdev_create_notice;
then {
event-script set-admin-down.slax {
arguments {
interface "{$$.interface-name}";
}
}
}
}
event-script {
file set-admin-down.slax;
}
}
Xxx xxxx xx xxx xxxxx xxxxxx:
/* set-admin-down.slax */
version 1.0;
ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
import "../import/junos.xsl";

/* Event Script Argument */


param $interface;

match / {
<event-script-results> {

/* Retrieve the current configuration */


var $configuration = jcs:invoke( "get-configuration" );

/* If the interface is not configured then administratively disable it */


if( jcs:empty( $configuration/interfaces/interface[name==$interface] ) ) {
var $change = {
<configuration> {
<interfaces> {
<interface> {
<name> $interface;
<disable>;
}
}
}
}

/* Load and commit the configuration change */


var $connection = jcs:open();
var $results := {
call jcs:load-configuration( $connection, $configuration = $change );
}
var $close-results = jcs:close( $connection );

/* Report either errors or success */


if( $results//xnm:error ) {
for-each( $results//xnm:error ) {
expr jcs:syslog( "external.error", "Commit Error: ", message );
}
}
else {
expr jcs:syslog( "external.info", $interface, ".0 has been disabled." );
}
}
else {
expr jcs:syslog( "external.info", $interface, ".0 is already configured." );
}
}
}

ALERT! Prior to Junos 9.5R2, in some cases a space would be appended to the
argument’s value. This occurs to event scripts that are enabled under
event-options event-script (See Chapter 1 for the different event script
enabling methods). Event scripts that receive arguments and are
expected to be run on Junos versions prior to 9.5R2 should be written to
handle the possible extra space character.
Try it Yourself: Logging Out Users
Using the clear bgp neighbor command without specifying a peer address causes all BGP peers to
be reset. Write an event policy and event script that automatically disconnects any user who
runs this command without including a peer address.

jcs:dampen()
Xxxxxxx 7 xxxxxxxxx xxx xx xxx xxx xxxxxx xxxxxx xxxxxx xx xxxxxx
xxxxx xxxxxxxx. Xx xxxxxxxxxxx xxxxxx xxxx xxxxxx xxxxxxx xxx xxx
xxxxxxxxxx xx xxxxxx xxxxxxxxxx xx xxx xxx:xxxxxx() xxxxxxxx. Xxxx
xxxxxxxx xx xxxxxx xxxx xx xxxxxxxxxxx xxxxxx xxx. Xxx xxxxxxxx
xxxxxx xxx xxxxx xx xxx xxxx xxxx xxx xxxxxx x xxxxx xxxxxxxxx xxx
xxxxxxx xx xxx xxxxxxx xxxxx xxxxxx xx xxxxxxxxx xxxxxx xx xxxxxxx.
Xxxx xx xxx xxxxxx xx xxx:xxxxxx():
var $result = jcs:dampen( string-tag, maximum, within-minutes);
Xxx xxxxxx-xxx xxxxxxxx xx x xxxxxx xxxx xxxxxxxx xxxxxxxxxx xxx
xxxxxxxxx xxx xxxxxx xxxxx xx xxxxxx. Xxx xxxxxxx xxx xxxxxx-xxxxxxx
xxxxxxxxx xxxxxxxxx xxxx xxxxxxxxx xxxxxx xxxx xxxxxx. Xx
xxx:xxxxxx() xx xxxxxx xxxx x xxxxxx-xxx xxxx xxxx xxx xxxxxxx xxxxx
xxxxxxx xxxxxx xxx xxxxxxxxx xxxxxxxxx, xxxx xxx xxxxxxxx xxxxxxx x
xxxxxxx xxxxx xx xxxxx. Xxxxxxxxx, xxx:xxxxxx() xxxxxxx x xxxxxxx
xxxxx xx xxxx xx xxxxxx xxxx xxxxxxxxx xxxxxx xxx xxxx xxxxxx xxx.
Xx xx xxxxxxx, xxx’x xxxx xxx xxxx-xxxxxxxx-xxxx xxxxx xxxxxx xxxx xxx
xxxxxxx xx xxx xxxxxxxxx xx Xxxxxxx 7. Xxx xxxx xxxxxxx xxx
xxxxxxxx, xxx xxx xxxx xxx xxxxxxxx xxxxxxx xx xxxxx xxxxxx xxxxxx
xxxx xxxxxxx xxx xxxxxxx-xxxxxxxx xxxxxxxxx. Xxx xxx:xxxxxx() xxxxxxxx xx
xxxx xxxxxx xxx xxxxx xxxxxx xx xxxxxxx xxx xxxxxxx xxxx xxxxx
xxxxxxxx xxxx xxxx xxxxx xxxxx xxxxxx x xxxxxx.
Xxxx xx xxx xxxxx xxxxxx xxxx:
event-options {
policy ospf-neighbor-down {
events rpd_ospf_nbrdown;
then {
event-script gather-ospf-outputs.slax {
output-filename ospf-output;
destination local;
output-format xml;
}
}
}
event-script {
file gather-ospf-outputs.slax;
}
}

And here is the event script:

/* gather-ospf-outputs.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match / {
<event-script-results> {

/* If dampening is not in effect then gather the outputs */


if( jcs:dampen( "gather-ospf", 3, 1 ) ) {
var $neighbor-extensive-rpc = {
<get-ospf-neighbor-information> {
<extensive>;
}
}
var $neighbor-extensive = jcs:invoke( $neighbor-extensive-rpc );
var $interface-extensive-rpc = {
<get-ospf-interface-information> {
<extensive>;
}
}
var $interface-extensive = jcs:invoke( $interface-extensive-rpc );
var $statistics = jcs:invoke( "get-ospf-statistics-information" );

/* Copy their XML output to the output file */


copy-of $neighbor-extensive;
copy-of $interface-extensive;
copy-of $statistics;
}
}
}

Xxx xxx:xxxxxx() xxxxxxxx xx xxxxxx xxxx x xxxxxx-xxx xx "xxxxxx-xxxx", x


xxxxxxx xx 3 xxx x xxxxxx-xxxxxxx xx 1. Xxxx xxxxx xxxx xx xxx Xxxxx
xxxxxx xxxxxxx xxxx xxxx xxxxx xxxxx xx xxx:xxxxxx() xxxx xxxx xxxxxx-
xxx xxxxxx x xxxxxx, xxxx xxx xxxxxxxx xxxxxxx xxxxx, xxxxxxxxx xx
xxxxxxx xxxx.
Xx xxxxxxx, x xxxx xxxxxx xxxx xxx:xxxxxx() xxxxxxxxx xxxx xxx xxxxxx
xxx xxx xxxxxxxx xxx xxxxx, x xxxxx xxxxxx xxxxxxxxx xxxx xx xxx
xxxxxxxx xxx xxxxx xxx xxxxxxxxx xxxxxx xx xxxxxxxx.
Try it Yourself: Dampening Event Reactions

Chapter 7 included a save-core event policy that demonstrated the upload filename policy action.
Using that event policy as a guideline, create a policy that executes an event script in
response to an eventd core dump. The event script should upload all eventd core files to a
remote server, but the action should be dampened by the jcs:dampen() function to a maximum
of 1 time per minute. When this limit is exceeded a syslog message should be logged instead,
indicating that the core upload process was dampened.

Embedded Event Policy


Xx xx xxxx xxxxx, xxx xxxxxxxx xxxxxx xxxx xxxx xxxx xxxxxxxx xxxx
xxx xxxxx xxxxxx xxxx xx xxxxxxx xx xxxxx xxxxxx xx xxxxxxxx xxxxxx
xxx Xxxxx xxxxxxxxxxxxx. Xxx, xxxxxxxx xxxx Xxxxx 9.0, xx xx
xxxxxxxx xx xxxxx xxx xxxxxx xxxxx xxxxxx xxxxxx xxx xxxxx xxxxxx
xxxxxx. Xxxx xxxxxx xxxxx xxxx xxxxxxxxxx:
„„Reduced configuration size: Because the event policy is no longer a
part of the configuration file, the event-options configuration hierarchy
is smaller, especially when multiple event scripts are in use.
„„Easier deployment: By integrating the event policy within the event
script, installation becomes a matter of copying the script to the
Junos device and enabling the script under event-options. The actual
event policy is distributed within the event script and does not have
to be configured on each device.
„„Consistent event policies: Because the event policy is embedded
within the event script, all Junos devices that enable the script share
a consistent policy configuration.
NOTE Embedded event policies are only supported in Junos 9.0 and later and
can only be used when the script is enabled under event-options event-script.
See Chapter 5 for the different storage/enable methods.

$event-definition
Xxxxx xxxxxxx xxx xxxxxxx xxxxxxxx xxxxx xxxxxxxx xxxxxx x xxxxxx
xxxxxxxx xxxxxx $xxxxx-xxxxxxxxxx. Xxx xxxxxxxx xxxxxx xx xxx XXX
xxxxxxxxxxxxxx (xx XXXX xxxxxxxxxxx xxxxxx) xx xxx xxxxxx xxxxx
xxxxxx xxx xxxxx xxxxxxx xxxxx xxxxxxxxxxxxx, xxx xxxxx x xxx-xxxxx
xxxxxxx xx <xxxxx-xxxxxxx>. Xxxx x xxxxxx xxxxxx, Xxxxx xxxxx
xxxxxxx xxx xxxxx xxxxxxx xxxxxxx xxxxx xxxxx-xxxxxxx xxxxx-xxxxxx,
xxxxxxxxx xxx xxxxxxxx xxxxx xxxxxx xxxx xxx xxxxxxxx $xxxxx-
xxxxxxxxxx xxxxxx xxxxxxxxx, xxx xxxxxxx xxx xxxxxxxx xxxxx
xxxxxxxxxxxxx xx xxxx xx xxx xxxxxx xxxxxxxxxxxxx.
Xxx xxxxxxx, xxx’x xxx xxx xxxxx xxxxxx xxxx xxx xxxx-xxxxxxxx-xxxx
xxxxxxx:
event-options {
policy ospf-neighbor-down {
events rpd_ospf_nbrdown;
then {
event-script gather-ospf-outputs.slax {
output-filename ospf-output;
destination local;
output-format xml;
}
}
}
}

Xxx xxxxxxxxx xxxxxxx xxxxx xxx XXX xxxxxx xx xxxx xxxxxxxxxxxxx:


user@Junos> show configuration event-options policy ospf-neighbor-down | display xml
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/10.1I0/junos">
<configuration junos:commit-seconds="1250877249" junos:commit-localtime="2009-
08-21 10:54:09 PDT" junos:commit-user="jnpr">
<event-options>
<policy>
<name>ospf-neighbor-down</name>
<events>rpd_ospf_nbrdown</events>
<then>
<event-script>
<name>gather-ospf-outputs.slax</name>
<output-filename>ospf-output</output-filename>
<destination>
<name>local</name>
</destination>
<output-format>xml</output-format>
</event-script>
</then>
</policy>
</event-options>
</configuration>
<cli>
<banner></banner>
</cli>
</rpc-reply>

Converting the displayed XML output into the SLAX abbreviated format gives us the
following:
<event-options> {
<policy> {
<name> "ospf-neighbor-down";
<events> "rpd_ospf_nbrdown";
<then> {
<event-script> {
<name> "gather-ospf-outputs.slax";
<output-filename> "ospf-output";
<destination> {
<name> "local";
}
<output-format> "xml";
}
}
}
}

Xxxx xx xxx xxxxxx-xxxx-xxxxxxx.xxxx xxxxxx, xxxx xxxx xxxxx xx xxxxxxxx


xxxxx xxxxxx:
/* gather-ospf-outputs.slax */
version 1.0;
ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

var $event-definition = {
<event-options> {
<policy> {
<name> "ospf-neighbor-down";
<events> "rpd_ospf_nbrdown";
<then> {
<event-script> {
<name> "gather-ospf-outputs.slax";
<output-filename> "ospf-output";
<destination> {
<name> "local";
}
<output-format> "xml";
}
}
}
}
}

match / {
<event-script-results> {

/* If dampening is not in effect then gather the outputs */


if( jcs:dampen( "gather-ospf", 3, 1 ) ) {
var $neighbor-extensive-rpc = {
<get-ospf-neighbor-information> {
<extensive>;
}
}
var $neighbor-extensive = jcs:invoke( $neighbor-extensive-rpc );
var $interface-extensive-rpc = {
<get-ospf-interface-information> {
<extensive>;
}
}
var $interface-extensive = jcs:invoke( $interface-extensive-rpc );
var $statistics = jcs:invoke( "get-ospf-statistics-information" );

/* Copy their XML output to the output file */


copy-of $neighbor-extensive;
copy-of $interface-extensive;
copy-of $statistics;
}
}
}
Xxxxxxxxx xxx xxxxx xxxxxx xxxxxx xxx xxxxx xxxxxx xxxxxx xxx
xxxxxx xx xx xxxxxxx xxxx xxx xxxxxxxxxxxxx, xxxxxxx Xxxxx xxx
xxxxx xxx xxxxxx xxxxxx xxxx xxx xxxxxx xxxxxx xx xxxxxx xxxx.
Xxxxx xxxx xxx xxxxx xxxxxxxxxxx, xxx xxxx xxxxxxxxxxxxx xxxxxx xx
xxx xxx xxxxx xxxxx xxxxxx xx xx xxxxxx xxx xxxxxx xxxxx xxxxx-xxxxxxx
xxxxx-xxxxxx:
event-options {
event-script {
file gather-ospf-outputs.slax;
}
}

TIP The event script can embed the destination configuration within the
$event-definition variable along with the ospf-neighbor-down event policy if
desired.
Xx xxxxxxxx xx xxx xxxxx xxxxxxxx, xx xxxxx xxxxxx xxx xxxx xxxxx
xxxxxxxxxx xxxxx xxxxxxxxxxxxx. Xxx xxxxxxx, xxxx xxxxxxx xx xxx
xxxxx-xxx-xxxxxxxxxxx.xxxx xxxxxx xxxxxx xxxx xxx xxxxx xxxxxx xxx xxx
xxxxxx xxxxxxxxx xxxxx:
/* check-var-utilization.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

var $event-definition = {
<event-options> {
<generate-event> {
<name> "every-hour";
<time-interval> "3600";
}
<policy> {
<name> "check-var-utilization";
<events> "every-hour";
<then> {
<event-script> {
<name> "check-var-utilization.slax";
}
}
}
}
}

match / {
<event-script-results> {

/* Get show system storage */


var $system-storage = jcs:invoke( "get-system-storage" );

/* Retrieve the /var percent */


var $percent = $system-storage/filesystem[mounted-on=="/var"]/used-percent;

/* Is it too high? Then log a warning. */


if( $percent > 75 ) {
var $percent-string = normalize-space( $percent ) _ "%";
var $syslog-message = "Warning: /var utilization is at " _ $percent-string;
expr jcs:syslog( "external.warning", $syslog-message );
}
}
}

Viewing Embedded Policies


Xx xxxx xxx xxxxxxxx xxxxx xxxxxxxxxxxxx xxx xxx xxxxxxxxx XXX
xxxxxxx:
show event-options event-scripts policies

Xxxx xxxxxxx xxxxxxxx xxx xxxxx xxxxxxxxxxxxx xxxxxxxx xxxxxx xxx


xxxxxxx xxxxx xxxxxxx xx xxx Xxxxx xxxxxx:
user@HOST> show event-options event-scripts policies
## Last changed: 2009-07-28 14:10:39 UTC
event-options {
policy ospf-neighbor-down {
events rpd_ospf_nbrdown;
then {
event-script gather-ospf-outputs.slax {
output-filename ospf-output;
destination local;
output-format xml;
}
}
}
}

Refreshing Embedded Policies


Xxxx xx xx xxxx xx xxxxx xx xxxxxxxx xxxxxx, xxx xxxxxx xxxxx xxxxxx
xxxx xx xxxxxx xxx xxxx xxxxxx xxxx xxx xxx xxxxxxx xx xxx Xxxxx
xxxxxx. Xxx xxxx xxxxxx xx xxxxxx xxxx xxx xxxxxx xxx xxxxx xxxxxx.
Xx xxxxxxx xxx xxxxxxxx xxxxx xxxxxxxxxxxxx xxxx xxxxxxx xxxxx
xxxxxxx, xxx xxx xx xxx xxxxxxxxx xxxxxxxx:
„„request system scripts event-scripts reload: Operational mode command that
refreshes embedded configuration.
„„commit full: Configuration mode command that recommits the entire
configuration including any embedded configuration.
„„restart event-processing: Operational mode command that restarts the
event processing daemon.
Xxx xxxxxxx:
user@HOST> request system scripts event-scripts reload
Event scripts loaded

Try it Yourself: Embedding Event Policy

Choose an event policy and event script that you created in one of the prior Try it Yourself
exercises. Remove the event policy from the configuration and embed the policy within the
event script.

<event-script-input>
Xx xxxxxxx xxxxxxx xx xxxx xxxxxxx xxxxxxxxx xxx xxxxx xxxxxx
xxxxxxxxx xxx xxxx xxxxxxxxxxx xxxx xxx xxxxx xxxxxxxxxx xxxx xxx
xxxxxx. Xxxxxxxx xx Xxxxx 9.3, x xxxx xxxxxxxxxxxxx xxxxxx xx
xxxxxxxxx xx xxxxxxxx xxxxxxxxxxx xxxxx xxx xxxxxxx xxxxx xxx
xxxxxxxx xxxxxx. Xxxx xxxx xx xxx xxxxxxxx xx xxxxx xxxxxxx xxxxxx
xx <xxxxx-xxxxxx-xxxxx> xxxxxxx xxxx xx xxxxxxxx xx xxx XXX xxxxxx
xxxx xxxxxxxx xx xxxxx xxxxxxx xx xxxxx xxxxxxxxx xxxx.
NOTE Starting in Junos 9.3 the <event-script-input> element is available to event
scripts, but only for those enabled under event-options event-script . See
Chapter 1 for the different event script enabling methods.

Source Tree
Xxx xxxxxx xxxx xx xxx xxxxxxx xx xxx xxxxxx xxxx. Xx xxxxxxxxx xx
Xxxx Xxx: Xxxxxxxx Xxxxx Xxxxxxxxxx Xxxxxxxxxx, xxx xxxxxx xxxx xx
x XXX xxxx xxxxxxxxx xxxxx xx x xxxxxx xxx xxxxxxxxx xx Xxxxx xxx
xxxxxxxxxx xx xxxxxx xxxxxxxxxxx. Xxxx x xxxxxx xxxx, xxxxxxx, xx xx
Xxxxx xxxx xxxxxxxx xxx XXX xxxx xxxxxxxxx xx xxx xxxxxx, xxx xxxx
xx xxxx xxxx xxx xxxxxx xxxxx xxxxxx xxxxxx xxxx xxxx xx xxxxxxxxxx.
Xx xxxxxxx xxx xxxx xx xxxxxx xxxxx xx Xxxx Xxx xxxxxxx xxxx
xxxxxxx xxxxxxx xx xx xxxxxxx xxx xx xxxxxxx xx xxx xxxxxxx xxx
xxxxxx xxxx xxxx xx xxxxxxx.
Xxx xxxxx xxxxxx xxx xxxxxxx xxxxxxxxxxx xxxx xxxx xxxxxx xxxx
xxxx xx xxx xxxx xxx xx xx xxxx xxxx xxx xxxxx XXX xxxx xxxxxxxxx
xxx xxx xxxx xxxxxxx xxxxxxxxxxxx xxx xx xx xxxx.

Trigger Event Data


Xxxx xx xx xxxxxxx xx xxx <xxxxx-xxxxxx-xxxxx> xxxxxxx xxx xx xxxxx
xxxxxx xxxx xxx xxxxxxxxx xx xxx XX_XXXXXX xxxxx:

<event-script-input>
<trigger-event>
<id>UI_COMMIT</id>
<type>syslog</type>
<generation-time junos:seconds="1245311597">2009-06-18 07:53:17
UTC</generation-time>
<process>
<name>mgd</name>
<pid>8720</pid>
</process>
<hostname>Junos</hostname>
<message>UI_COMMIT: User 'user' requested 'commit' operation (comment:
none)</message>
<facility>interact</facility>
<severity>notice</severity>
<attribute-list>
<attribute>
<name>username</name>
<value>user</value>
</attribute>
<attribute>
<name>command</name>
<value>commit</value>
</attribute>
<attribute>
<name>message</name>
<value>none</value>
</attribute>
</attribute-list>
</trigger-event>
</event-script-input>
Xxx <xxxxxxx-xxxxx> xxxxx xxxxxxx xxxxxxxx xxxxxxxxxxx xxxxx xxx
xxxxx xxxx xxxxxxxxx xxx xxxxx xxxxxx, xxxxxxxxx xxx xxxxxxxxx:
„„id: The event ID.
„„type: The type of event (syslog, pseudo, internal).
„„generation-time: When the event occurred.
„„process: The name of the process that logged the event (and PID if
appropriate).
„„hostname: The hostname of the event source.
„„message: The syslog message logged for the event.
„„facility: The syslog facility of the event.
„„severity: The syslog severity of the event.
„„attribute-list: If present, this list includes all event attributes .
„„attribute name: The name of the attribute.
„„attribute value: The value of the attribute.
Xxxxxxxx xxxxx xxxxxx xxxxx xx xxx xxx-xxxxx <xxxxx-xxxxxx-xxxxx>
xxxxxxx xx xxxxx xx xxxxxxx xxxxxxxxxxx xxxx xxx xxxxxx xxxx. Xxxx
xxx xxxxxxxx xx xxxx xx xxxxxxxx xxxxxxxxxxx xxxx xxx xxxxx <xxxxx-
xxxxxx-xxxxx> xxxxxxx:

Xxxxxxxxxx xxx xxxxxxx xxxx:


var $process-name = event-script-input/trigger-event/process/name;

Xxxxxxxxxx xxx xxxxxx xxxxxxxx:


var $facility-name = event-script-input/trigger-event/facility;

Xxxxxxxxxx xxx xxxxxxxx xxxx xxxxxxxxx xxx xxxxxx:


var $committing-user = event-script-input/trigger-event/attribute-
list/attribute[name=="username"]/value;

Xxx xxx xxxxxx xxxx xxxxxxxxxx. Xxxx xx xx xxxxxxx xx xx <xxxxx-


xxxxxx-xxxxx> xxx xx xxxxx xxxxxx xxxx xxxxxxx xx x xxxxxxxxx xxxxx
xxxxxx xxxxxx:
<event-script-input>
<trigger-event>
<id>MINUTE</id>
<type>internal</type>
<generation-time junos:seconds="1248795322">2009-07-28 15:35:22
UTC</generation-time>
<process>
<name>eventd</name>
<pid>492</pid>
</process>
<hostname>Junos</hostname>
<message>Internal event created by eventd</message>
<facility>user</facility>
<severity>notice</severity>
<attribute-list>
</attribute-list>
</trigger-event>
</event-script-input>

Received Event Data


Xx xxxxxxxx xx xxx xxxxxxx xxxxx, xxxx xxxxx xxxxxx xxxxxx xxxxxxxxx
xxxx xxxx x xxxxxxxx xxxxxxxx xxxxx xx xxxxx xxx xxx xxxxx xxxxxx xx
xx xxxxxxxxx.
TIP Each within statement results in a single received event. The received
event is the most recent of any of the potential correlating events for the
within statement. If multiple within statements are included then multiple
received events are present, one per within statement.
Xxxxx xxxxxxxx xxxxxx xxx xxxx xxxxxxxx xx xxx <xxxxx-xxxxxx-xxxxx>
xxxxxx xxxx xxxxxxx. Xxxx xxxxx xx xxxxxxxx xx x xxxxxxxx <xxxxxxxx-
xxxxx> xxxxxxx, xxxxx xx x xxxxx xx xxx <xxxxxxxx-xxxxxx> xxxxxxx.
Xx xx xxxxxxx, xxxxxxxx xx xxxxx xxxxxx xxxx xxx xxxxxxxxx xxxxxx
xxxxxxxxx xxx xxxxxx xxxxxxxxxx:
policy example {
events rpd_task_begin;
within 300 events ui_commit;
within 200 events chassisd_ifdev_detach_fpc;
...
}

Xxxx xxxxx xxxxxx xx xx <xxxxx-xxxxxx-xxxxx> xxxxxxx xxxxxxx xx xxxx:


<event-script-input>
<trigger-event>
<id>RPD_TASK_BEGIN</id>
<type>syslog</type>
<generation-time junos:seconds="1245401205">2009-06-19 08:46:45
UTC</generation-time>
<process>
<name>rpd</name>
<pid>41439</pid>
</process>
<hostname>Junos</hostname>
<message>RPD_TASK_BEGIN: Commencing routing updates, version 9.3R2.8, built
2008-12-17 22:48:00 UTC by builder</message>
<facility>daemon</facility>
<severity>notice</severity>
<attribute-list>
</attribute-list>
</trigger-event>
<received-events>
<received-event>
<id>CHASSISD_IFDEV_DETACH_FPC</id>
<type>syslog</type>
<generation-time junos:seconds="1245401202">2009-06-19 08:46:42
UTC</generation-time>
<process>
<name>chassisd</name>
<pid>41437</pid>
</process>
<hostname>Junos</hostname>
<message>CHASSISD_IFDEV_DETACH_FPC: ifdev_detach(9)</message>
<facility>daemon</facility>
<severity>notice</severity>
<attribute-list>
<attribute>
<name>fpc-slot</name>
<value>9</value>
</attribute>
</attribute-list>
</received-event>
<received-event>
<id>UI_COMMIT</id>
<type>syslog</type>
<generation-time junos:seconds="1245401153">2009-06-19 08:45:53
UTC</generation-time>
<process>
<name>mgd</name>
<pid>34740</pid>
</process>
<hostname>Junos</hostname>
<message>UI_COMMIT: User 'user' requested 'commit' operation (comment:
none)</message>
<facility>interact</facility>
<severity>notice</severity>
<attribute-list>
<attribute>
<name>username</name>
<value>user</value>
</attribute>
<attribute>
<name>command</name>
<value>commit</value>
</attribute>
<attribute>
<name>message</name>
<value>none</value>
</attribute>
</attribute-list>
</received-event>
</received-events>
</event-script-input>

Xxxxxxxx xxxxxx xxxxxxx xxx xxxx xxxxxxxxxxx xx xxx xxxxxxx xxxxx,


xxx xxx xxxxxx xxx xxxxxxxx xxxxxxxxxxx xx xxx xxxx xxx.
Xxx xxxxxxx, xxxxxxxxxx xxx XXXXXXXX_XXXXX_XXXXXX_XXX xxxx xxxxxx:
var $slot = event-script-input/received-events/received-
event[id=="CHASSISD_IFDEV_DETACH_FPC"]/attribute-list/attribute[name==fpc-
slot]/value;
Xxxx xx xx xxxxxxx xx x xxxxxx xxxx xxxxx xxxxxxxxx xx xxx <xxxxx-
xxxxxx-xxxxx> xxxx xx xxxxxxxxxx xxx xxxxxx xxxx. Xxx xxxxxx xx-xxxx
xxxxxx xxxxxxxx xx x xxxxxx xxxxxxxx xxxxx. Xxxx xxxxx xx xxxxxx xx
xxxxxxxxxx xxxxx x xxxxxxx xxxxxxxxxx xxxxxx xxxxxx xxxxxxx xxx
xxxxxx xxxxxxxx xx x xxxxxxxx xxxxxxxx xxxxx xxxx xxx xx xxx
xxxxxxxx xxxxxx xx x xxx xxxxxxxx xxxxx. Xxx xxxxxxx, xx xxxxxxx
Xxxxx xxxx xxx XXXX_XXXX_XXXX_XX xxxxx xx xxx xxxx xxxxx, xxxxxxx xx
xxxx xxx XXXX_XXXX_XXXX_XXXX xxxxx xx xxx xxxxxx xxxxx. Xx x xxxxxx
xxxxxx xxxx xxxxxxxx xxxxxx xxxxx xxxxxxxx xxxx xx xxxx xxx xxxxxxx
xxx xxxxxxxxxx xxxx xxx xxxx xxxx xxxx xx.
Xxxx xxxxx xxxxxx xxxxxxxx x xxxxxxxxx xxxxxxxx xx xxxx xxxxxxx.
Xxxxx xxx xxx xxxxxx xxxxxxxxx xxxxx xx xx xxxxxxx, xxx xxxxxx xxx
xx-xxx xxx XXXX_XXXX_XXXX_XX xxxxx xxxxx xxxxxx xxxxxxxx xxxxxx xxxx
xxx xxxxxxxx xxxx xxxxxxxx xxxxx.
NOTE This script only reproduces the syslog message text. The full structured
format of the original syslog message is not replicated.
Xxx xxxx xxxxx xxxxxxxxxxxxx xxxxxxxx xx xxxxxxxx xxx xxxxx
xxxxxx:
event-options {
event-script {
file change-syslog-severity.slax;
}
}
Xxxx xx xxx xxxxx xxxxxx, xxxx xxx xxxxxxxx xxxxx xxxxxx:
/* change-syslog-severity.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

/* Embedded event policy */


var $event-definition = {
<event-options> {
<policy> {
<name> "change-syslog-severity";
<events> "snmp_trap_link_up";
<then> {
<event-script> {
<name> "change-syslog-severity.slax";
}
}
}
}
}

match / {
<event-script-input> {

/* Record the facility */


var $facility = event-script-input/trigger-event/facility;

/* Get the process-name */


var $process-name = event-script-input/trigger-event/process/name;

/* Get PID */
var $pid = event-script-input/trigger-event/process/pid;

/* Get the syslog message */


var $message =event-script-input/trigger-event/message;
/* Assemble message */
var $final-message = {
expr $process-name;

/* If they have a PID then include it */


if( string-length( $pid ) > 0 ) {
expr [" _ $pid _ "]";
}

expr ": ";


expr $message;
}

/* New priority */
var $new-priority = $facility _ ".notice";

/* Now re-syslog it with the new facility */


expr jcs:syslog( $new-priority, $final-message );
}
}

Xxx xxxxx xxxxxx xxxxx xxx xxxxxxxx, xxxxxxx-xxxx, xxxxxxx-xx, xxx xxxxxx
xxxxxxx xxxx <xxxxx-xxxxxx-xxxxx>. Xxx xxxxxx xxxx xxxxxx xxx xxxx
xxxxxx xxxxxxx xx xxx xxxxxx xxxxxxxx xxxxx xxxxxx xxxx xxx xxxx
xxxxxxxx xxxxx.
NOTE When using this approach, do not attempt to re-log events generated by
the cscript process. This is the process used by scripts to create syslog
messages. Re-logging these events would result in a loop, as the re-
logged event is then re-logged, etc.
Try it Yourself: Using <event-script-input>

Revise your earlier event script that automatically logged out users using the clear bgp neighbor
command without specifying a peer address. Remove the event policy from the configuration
and embed the policy within the event script’s $event-definition variable. Remove any command-
line arguments used to communicate which user performed the command and instead use the
<event-script-input> source tree element to determine which user should be logged out.ih

Chapter 9: Introducing Commit Scripts 129


128 This Week: Applying Junos Automation

Xxx Xxxxx xxxxxxxxxx xxxxxxx xx x xxxxxxxx xxxx xx xxx Xxxxx


xxxxxxxxx xxxxxx xxxxxxxxx xx xxx Xxxxx xxxxxxxxx xxxxxxxxx
xxxxxxx, xxxxxxxx, xxx xxxxxxxx xxxxxxx. Xxxx xxxx xxxxxxxxx
xxxxxxxx xxx xxxx xxxxxxxx xx Xxxxx xxxxxxxxxx xxxxx xx xxx xxxxx
xxx xxxxx: Xxxxxxxx Xxxxx Xxxxxxxxxx Xxxxxxxxxx xxx Xxxxxxxx
Xxxxx Xxxxx Xxxxxxxxxx. Xxx xxxxx xxxx xxxxxxxx xxx XXXX
xxxxxxxxx xxxxxxxx xxx xxxxxxxxx xxx xx xxx xx xxxxxxx, xxx xxxx xx
Xxxxx xxxxxxxxxx xxxxxx. Xxx xxxxxx xxxx xxxxxxxx xxx xx xxxxxxxx
xxxxxx xxxxxxx xxxxx xxxxxxxx xxx xxxxxxx. Xxxx xxxxx xxxx xx xxx
xxxx, xxxxxxxxx xxx xxxxxx xxxxxxx xxxxxxxx xxx xxxxxx xxxxxxx,
xxxxxx xxxxxxxxxxxxxx xxxxxxx xxxx xxxx xxxxxxxxxxxxx xx xxxxxxx
xx xxxxx Xxxxx xxxxxx.

Junos Automation Overview


Xxxxx xxxxxxxxxx xxxxxxx xx xxxxxxxxxxxx xx xxxxx xxx xxxxxx xx
xxxxxxxxx xxx xxxxxxxxxx xx xxxxxxxxxx xxxxxxxx xxxx Xxxxx
xxxxxxx:
„„Business rules automation - enforces best practices and changes
management to avert human factors.
„„Provisioning automation - simplifies and abstracts complex
configurations to minimize errors.
„„Operations automation - customizes command output to streamline
operation and troubleshooting.
„„Event automation - performs automatic changes and responses in
reaction to observed events.
Xxxxxxx xxxxxxxxxx, Xxxxx xxxxxxxx xxxxxxx xxxxxxxxx xx xxxxx xx
xxxxxxxxxxx xxxxxxx xxxxx, xxxxxxxxxx xxxxxx, xxx xxxxxxxxxx
xxxxxxxxxxx xxxxxxxxxx.

Commit Scripts
Xxxxx Xxx xxx Xxx xx xxxx xxxx, xxxxxxxxx xxx xxxxxxxxxxx xx xx xxx
xxxxx xxxxxxx. Xx xx xxxxxx xx x xxxxxxxxxx xxxxxxx xxxx
xxxxxxxxxxxxxx xxx xxxxxxx xxxx xxx XXX xxxxxx (xxx xxxxx xxxxxxx
xxx xxxx) xx xxx xxxx xxx xx x xxxxxxxx Xxxxx xxxxxxx. Xx xxxxxxx
xxx xxxxxx xxx xxxxxxx xxxxxxx xxxxxxxxxxx, xxxxxxx xxxxxxxxxx
xxxxxxxxxxxxx xxxxxxx, xx xxxxxxx x xxxxx xx xxxxxxxxxxx xxxxxxxx.
Xxxxx xxxxxxx xxx xxxx xx xxxxxxxxxxx xxxx xxxxx xxxxxxxx xx
xxxxxxxx xxxxxxxxx xx xxxxxx.
Xxxxxx xxxxxxx xxxx xxx xxxxx xxxx xx Xxxxx xxxxxxxxxx xx
xxxxxxxxx x xxx xx xxx xxxxxxxxxx xxxxxxxxxxxx xx xxxx xx xxx
xxxxxx xxxxxxx. Xxxxx xxxxxxxx xxx xxxxxx xxxxxxx xxxxxxxxxxxxx
xxxx xxxx xx xxxxxxxxxxxxx xxxxxxx xxx xxxxxxxxxxxxx. Xxxxxx
xxxxxxx xxx xxxxxxx xxx xxxxxx xxxxxxx xx xxxxxxxx xxxx xxxxxxx
xxxx xxxxxx xxxxxxx xxxxxxxx xx xxxxxxx xxxxxxxxxxxxx xxxxxxx
xxxxx xx xxx xxxxxxxx xx xxxxxxxxxxxxx xxxxxx.

Commit Script Examples


X xxx xxxxxxxx xx xxx xxxxxx xxxxxxx xxx xxxxxxx xxxxxxxxxxxxx
xxxxxxx:
„„Verifying essential configuration hierarchies whenever a user
changes the configuration. If a user accidently deletes any of these
hierarchies the script can instruct Junos to halt the commit process
and issue an error message. This prevents network outages caused
by human error.
„„Checking for descriptions of interfaces or BGP peers at each commit
time. An improperly formatted description can result in a warning
message, advising the user to fix it.
„„Reducing the number of statements required in complex
configurations. Configuration macros can act as customer-
standardized configuration syntax and expand into complex
configuration structures at commit time.
„„Enforcing scaling limits for critical settings. For example, a script can
generate a commit error (or warning) when the configuration
exceeds the maximum number of permitted peers.
MORE? To see more script examples go to the online script library at
www.juniper.net/scriptlibrary.

Commit Process
Xxx Xxxxx xxxxxx xxxxxxx xxx xxxx xxxxxxx xxxxxxxxxxxxxx xx
xxxxxxx xxx xxxxxxx xxxxxx xxxxxxxxxx x xxxxxx, xx xxxx xxxxxxx
Xxxxx xx xxxxxxxx xxx xxxxxx xxx xxxxx xx xxx xxxxxxxxx
xxxxxxxxxxxxx xxxxxx xxxxxxxx xx. Xxxx x xxxxxx xx xxxxxxxxx,
Xxxxx xxxxx xxxxxxxx xxxxxxxxxxx xx xxx xxxxxxxxx xxxxxxxxxxxxx xx
xxxxxxxxxxx xxx xxxxxxxxxxxxx xxxxxx xxxx xxxxx xxxxxxxxxxx
xxxxxxxxxxx xxx xxxxxxxx xxx xxxxxxxx xxxxxxxxxx. Xxx xxxx-
xxxxxxxxxxx xxxxxxxxxxxxx xx xxxx xxxxxxx xxx xx Xxxxx xxx xxx
xxxxxxxxxxxxx xxxxxx xx xxxxxxxx. Xxxx xxxxxx xxx xxxxxxxx xxx
xxxxxxxxx xx xxx xxxxxxxxxx xxxxxxxxxxxxx, xxx xxxxxx xxxx xxxxx
Xxxxx xx xxxx xxx xxxxxx.
Xxxxxx xxxxxxx xxxx xxxxx x xxx xx xxxxxxxxx xxx xxxxxxxxxx
xxxxxxx xx xxxxx xxxxxxxxxxxxxx xx xxxxxxxxxx xxxx xxxxx xxx
xxxxxxxxx xxx xxxxxxxx. Xxxxx xxxxxxxxxx xxxxxx xxxxxxx
xxxxxxxxxx xxxx xxx xxxxxx xxxxxxx, xxxxxxxx xxx xxxxxxx xx xxxxx
xxx xxxxxx xxx xxxxxxxxxxxxx xxxxx xx xxx xxxxx xxxxxxxxxxxx
xxxxxxxxx xx Xxxxx. Xxxxxx 9.1 xxxxx xxxxx xxxxxx xxxxxxx xxx xx
xxx xxxxxx xxxxxxx.
Xxx xxxxxxxxx xx xxxxxx xxxxxxx xxxxxx xxxxx xxxxxxxxxxx xxx xxxx
xxxxxxxxx xx xxx xxxxxxxxxxxxx, xx xxx xxxxxx xxxxxxx xxx xxxxxxxx
xxx xxxx-xxxxxxxxxxx xxxxxxxxxxxxx xx xxx xxxxx xx xxxxx
xxxxxxxxxx. Xxxx xxxxxx xxxxxx xxxxxx xx xxxx xxxx-xxxxxxxxxxx
xxxxxxxxxxxxx xx xx xxxxxxxxxx xxxx xxxxxxx, xx xxx, xxxx xx xx
xxxxxxxxx. X xxxxxx xxx xxxxxxx (xxx xxxxxxxxx) xxxx xxxxxx-
xxxxxxxx xxxxxxx:
„„Displaying a warning to the committing user (Chapter 10).
„„Logging a message to the syslog (Chapter 10).
„„Generating a commit error and canceling the commit (Chapter 10).
„„Changing the configuration (Chapters 11 and 12).
„„Transiently changing the configuration (Chapters 11 and 12).
Xxxxxx xxxxxxx xxxxxxxxxxx xxxxxxxxx xxxxxxx xx Xxxxx xx
xxxxxxxxx xxxxxxxxxxxx xx xxxxx xxxxxx xxxx. Xxxx xxxxxx xxxxxx xx
xxxxxxxx xxxxxxxxxxxx xxx xxx xxxxxx xxxx xx xxxxxxxx xx Xxxxx
xxxx xxx xxxxxx xxxxxxxxxx. Xxxx xxx xxxxxx xxxxxxx xxxx xxxx
xxxxxxxx, Xxxxx xxxx xxxxxxxxx xxx xx xxx xxxxxxx’ xxxxxxxxxxxx.
Xxxxx xx xxxxx xxxxxxxxxxxx, Xxxxx xxxxx xxxx xxx xxxxxx, xxxxxxx
xxxxxxx xxxxxxxx, xx xxxxx xxx xxxxxxxxxxxxx.
Xx xxx xxxxxx xxxxxxx xx xxx xxxxxx xx x xxxxxx xxxxxx, xxxx Xxxxx
xxxxxxx xxx xxx xxxxxx xxxxxx xxxxxxx xxx xxxxxxxx xxx xxxxx
xxxxxxxxxx xx xxx xxxxxxxx xxxxxxxxxxxxx. Xxx x xxxxxxxxxxxxx xxxx
xxxxxx xxx xxxxxx, Xxxxx xxxxxxxxx xxx xxx xxxxxxxxxxxxx xx xxx
xxxxxx.

Figure 9.1 Commit Model with Commit Scripts

Xxx xxxxxxxxx xx xxxxxx xxxxxxx xxxxxx xxx xxxxxx xxxxxxx, xxx


xxxxx xxxxxxx xx xxxxxx xxxxxxxxxxxx xx xxxxxxxxx xxxx xxxxxxx,
xxxxxxxx xxxxxxxxxxxxxx xxxx xxxxxxxxxxx xxx xxxxxxxx xxxxxxx
xxxx xxx xxxxx xxxxxxxxxxxxxx xxxxxxxxx xx Xxxxx xxxxxxx.

Configuration/Storage
Xxxxxxxxxxxxxx xxx xxx xxxxxx xxxxxxx xx xxxxxxxx xxxx xxxxxx xxx
xxxxxxxxxxxxx xxx xxxxxxx xxxx xx xxx Xxxxx xxxxxx xx xxx
/xxx/xx/xxxxxxx/xxxxxx xxxxxxxxx. Xxx xxxxxxx xx xxxxxx xxx xxxxxxx
xx:
xxx xxxxxx xxxxxxx xxxxxx xxxx xxxxxxx-xxxxxx-xxxxxx.xxxxXxx xxx
xxxxxxxxx xxx:
„„Storage Location: /var/db/scripts/commit

„„Configuration Location: [edit system scripts commit]


NOTE Beginning in Junos 9.4, the Juniper EX Series began storing
configurations in /config/db/scripts rather than /var/db/scripts. /var/db/scripts
links to the new /config/db/scripts directory so files that are copied into
/var/db/scripts are still placed in the correct location.

NOTE The load-scripts-from-flash configuration command changes the script


storage location from /var/db/scripts to /config/scripts. If you are using this
configuration statement, store the commit scripts in /config/scripts/commit.
Xxxx xxxxx-xxxxx, xxxxx xxxx xxx xxx xxxxxxxxxx xxx, xx xxxxx xxxx
xxxx xxxx xxxxx xxx xxxxxxxxxxx xxxxxxxxxx xxx xxx xxxxxxxxx xx
xxxxxx xx xxxxxxx Xxxxx xxxxxx xxxxxxx xx xxx xxxxxxxxxxxxx.
ALERT! The Junos management process executes commit scripts with root
permissions, not the permission level of the committing user. If the user
has the necessary access permissions to commit the configuration, then
Junos performs all actions of the configured commit scripts, regardless of
the privileges of the committing user.
NOTE In devices with multiple routing-engines (including EX4200 Virtual
Chassis), each routing engine performs the commit process separately.
Because of this, the script file must be copied into the commit script
directory, and enabled on every routing-engine. Typically the
configuration of all routing-engines is done automatically through
configuration synchronization, but if the configurations are not
synchronized between routing-engines then the script must be enabled
on all routing-engines manually.

allow-transients
Xxxxxx xxxxxxx xxx xxxxxxx xxxxxxxxxxxxx xxxxxxx xxxx xxxxxx xxx
xxxxxxxxx xx xxx Xxxxx xxxxxx xxx xx xxx xxxxxx xx xxx
xxxxxxxxxxxxx xxxx. Xxxxx xxxxxxx xxx xxxxxxxx xx xx xxxxxxxxx
xxxxxxxxxxxxx xxxxxxx xxx xxx xx xxxx xx xxxxxxxxxxx xxxx
xxxxxxxxxxxxx xxxxxx xx xxxxxx xxxxxx xxxxxxxxxxxxx xxxxxx.
Xxxxxxxxx xxxxxxxxxxxxx xxxxxxx xxx xxxxxxxxx xx Xxxxxxxx 11 xxx
12 xxx xxx xxx xxxxxxxxx xx xxxxxxx. Xx xxxxx xxxx, xxxxx xxx
xxxxxxxxx xxxxxxxxxxxxx xxxxxxx:
set system scripts commit allow-transients

Commit Script Boilerplate


Xxxx xxxxxxx Xxxxx xxxxxxxxxx xxxxxxx, xx xx xxxxxx xxxx xx xxxx
xxxx xxx xxxxxxxx xxxxxxxxxxx. Xxxx xxxxxxx xxxxxxxxxx xxxxxx
xxxxxxx, xx xxxxx xx xx xxxx xx xxxxxxxx xxx xxxxxxxxx xxxx-xxxxx
XXXx. Xxxxxxx, xxxx xxxx xxx xxxxx xxx xxxxxxxxxxx xxx xxx xxxx
xxxxxx xxxx xxxxxx xx. Xxx xxxxxxxxxxx xxxx xxx xxxxxxx xxxxxx
xxxxxxx xx xxxxxxx xx xxx xxxxxxxxxxx xxxx xxx xx xxx xxxxx xxxxxxx
xxxx xxx xxxxxxxxxxx xxxxxxxxxxx xxxx xxx xxxxxxxxx xx xxxxxxxxx
xxxxxxxx. Xxxx xx xxx xxxxxxxxxxx xxxx xxxxxx xx xxxx xxxx xxxxxxx
xxxxxx xxxxxxx:
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

/* Your script code goes here */

}
„„version: While version 1.0 is currently the only available version of
the SLAX language, the version line is required at the beginning of
all Junos scripts.
„„ns: a ns statement defines a namespace prefix and its associated
namespace URL. The following three namespaces must be included
in all Junos scripts:
„„ns junos = "http://xml.juniper.net/junos/*/junos";
„„ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
„„ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
TIP It is easiest to just copy and paste these namespaces into each new
script as part of the boilerplate rather than trying to type them out by
hand.
xxxxxx: Xxx xxxxxx xxxxxxxxx xx xxxx xx xxxxxx xxxx xxxx xxx xxxxxx
xxxx xxx xxxxxxx xxxxxx. Xx xxx xxxxx.xxx xxxxxx xxxxxxxx xxxxxx
xxxxxxx xxxxxxxxx xxx xxxxxxxxxx, xxx xxxxxxx xxxxxx xxxxxx xxxx
xxxx. Xxx xxxxxx "../xxxxxx/xxxxx.xxx"; xxxx xxxx xxx xxxxxxxxxxx xx xxx x
xxxxxx xxxxx xx xxxxxxxxxx xxxx.
xxxxx xxxxxxxxxxxxx: Xxxx xxxx xxxxx xx xxx xxxx xxxxxxxx xx xxx
xxxxxx xxxxxx.

<commit-script-input>
Xx xxxxxxxxx xx xxx xxxxxxxx xxxxxxx, xxxxx xxx xxx xxxxxxxxxxx
xxxxxxxxxxx xxxxxxx xxx xxxxxxxxxxxx xxxx xxx xx xxx xxxxx xxxxxxx
xxx xxx xxxxxxxxxxx xxxx xxx xxxxxx xxxxxxx. Xxxx xx xxxxx
xxxxxxxxxxx xxxxx xx xxxxxxxx xxxxxx xxxxxxx xxx xxx xxxxxxxxx xx
xxxx xxx xxxxxxxxxx xxxxxxxx.
Xxx xxxxx xxxxxxxxxx xxxxxxx xxx xxxxxxxxxxxx xx xxxx xx xxx xxxxx
xxxxxxx xxxxx xxxx x xxxxx / xxxx xxxxxxxx, xxxxx xxxxxx xxxxxxx
xxxxx xxxxx xxxxxxxxxx xx x xxxxx xxxxxxxxxxxxx xxxx xxxxxxxx.
Xxx xxxxx xxxxxxxxxxxxx xxxxxxxx xx xxxx xx xxxxxx xxxxxxx xxxxxxx
xx xxxxxxxxxx xxx xxxxxxxxx xx XXX xxxx xxxx xxx xxxx-xxxxxxxxxxx
xxxxxxxxx xxxxxxxxxxxxx xxxxxxxx xx xxxxxx xxxxxxx xx xxxxx xxxxxx
xxxx xxxxxx x xxx-xxxxx xxxxxxx xxxxx <xxxxxx-xxxxxx-xxxxx>. Xxxx
xxxxxxxxxxxxxx xxxxxx xxxxxxxxxxxxx xxxxxxxxxxx xx xx xxxxxxxxx
xx xxxxxxxxxxx xx xxxxxxxx xxxx xxx xxx-xxxxx xxxxxxxxxxxxx
xxxxxxxxx. Xxx xxxxxxx, xxx xxxxxx xxxx-xxxx xxx xx xxxxxxxxx xxxx
xxx xxxxxxxxx xxxx:
var $configured-host-name = system/host-name;

NOTE The source tree was discussed in volume two of this series, Day One:
Applying Junos Event Automation. For event scripts, the source tree
consists of a top-level element named <event-script-input>. Location
paths in event scripts that refer to this element must include the entire
path:
var $process-name = event-script-input/trigger-event/process/name;
Xxxxxxxxx xxxxxx xxx <xxxxxx-xxxxxx-xxxxx> xxxxxx xxxx xxxxxxx xx
x xxxxx xxxxxxx xxxxx <xxxxxxxxxxxxx> xxxx xxxxx xxx xxxxxx xxxx-
xxxxxxxxxxx xxxxxxxxx xxxxxxxxxxxxx. Xx xxxxxx xxxxxxx xxxx x
xxxxx / xxxxxxxx xxxx xx xxx xxxxx xxxxxxx xx, xxxx xx xxxxx xx
xxxxxxxxx xx xxxxxxx xxx xxxx xxxxxx xxxx xxxx xx xxx xxxxxxx
xxxxxxxxxxxxx xxxx:
var $location = commit-script-input/configuration/snmp/location;
Xxxxxx xxxxxxx xxxxxxxxx xxxx xxxxxxxxx xxxxxxx xxxx xxx
xxxxxxxxxxxxx xxxx, xxx xxxxxxxxx xxx xxxx xxxx xx xx xxxxxxxxx
xxxxx xx xxxxxxx xxx xxxxxx xxxxxxx. Xxx xxxxxxxx xxx xx xxxxxx x
xxxxxxxx xxxxx / xxxxxxxx xxxxxx xxx xxxxx.xxx xxxx:
<xsl:template match="/">
<commit-script-results>
<xsl:apply-templates select="commit-script-input/configuration"/>
</commit-script-results>
</xsl:template>

Xxx xxxxx xxxx xxxx xxx xxxxx.xxx xxxxxx xxxx xx xxxxxxx xx XXXX,
xxx xxxx xx xxx xxxxxxxxxxxxx XXXX xxxx:
match / {
<commit-script-results> {
apply-templates commit-script-input/configuration;
}
}

Xxxxxxx xxx xxxxxxx xxxxxx xxx xxxxx.xxx xxxx, xxxx xxxxxxx


xxxxxxxx xxxxxxx xxxx xx xxxxx xxxxxx xxxxxx’x xxxx.
NOTE Op and event scripts observe no ill effect from the inclusion of a match /
template in the junos.xsl file because their local match / template
overrides the imported template.
Xxxx x xxxxxx xxxxx xxxxxx, Xxxxx xxxxxxxx xxx xxxx xxx x xxxxxxxx
xxxx xxxxxxx xxx xxxxxxx xxxxxx xxxx xxxx. Xxx xxxxx xxxx xxxxxxx
xx xxx xxxx xxxx, xxxxx xxxxxxx xxx xxxxx / xxxxxxxx xxxxxxx Xxxxx xx
xxxxx xxxxxxxxx xxx xxxx xxxxx xxxxxx xxxx xxxxxxxx.
Xx x xxxxxxxx xxxx xx xxxxxxx xxxx xxxx xxxxxxx xxx xx xxxxxxxx xx
xxxxx xxx xxxxx-xxxxxxxxx xxxxxxxxx, xxxxx xxxxxx xxx xxxxxx xxxxxx xx
xxxxxx xxx x xxxxxxxx xxxx xxxxxxx xxx xxxxxxxx xxxxxxxx xxxx. Xx
xxx xxxxxxxxx xxxxx xxxxx, xxxxx-xxxxxxxxx xxxxxx-xxxxxx-xxxxx/xxxxxxxxxxxxx
xx xxxxxxxxxxx Xxxxx xx xxxx x xxxxxxxx xxxx xxxxxxx xxx
<xxxxxxxxxxxxx> xxxx, xxxxxx, xxx xxxxx xxxxxxxxxxxxx xxxxxxxx xxxx
xxxxxx xxxxxx xxxxxx xxxxxxxxx.
MORE? For more information on unnamed match templates (for example, match
configuration) see the Configuration and Diagnostic Automation manual
of the Junos documentation at www.juniper.net/techpubs/.
Xxxxxxxxx xxxx xxxxxxx xxx xxxxxxxx’x xxxxx xxxxxxxxx xxxxxxx xxx
xxxxxxx xxxxxxx xxxx xxxxxx xxxx xxxxxxxx. Xxx xxxxxxxx xxxxx
xxxxx xxxx x xxxxxxxxx xxxxx xx xxxx xxxxxxx xxxxxxx xxxx, xxxxxx
xxxx xxx xxxxx xx x xxxx-xxx xxxxxxxx, xxx xxxxx xx x xxxxxxxx
xxxxxx, xx xxxxxx xxxxxx xxx-xxxx xxxxx.
NOTE In the case of event scripts, using a match / main template causes the
context node to be the root node, so all location paths use the full path
to the desired information:
var $process-name = event-script-input/trigger-event/process/name;
Xxxxxxx xxxxxx xxxxxxx xxxxx xxxx x xxxxxxx xxxx xx <xxxxxxxxxxxxx>,
xxxxx xxxxxxxx xxxxx xxx xxxxx xxxx xxx xxxxxxxx xxx-xxxxx
xxxxxxxxxxxxx xxxxxxxxx:
var $location = snmp/location;
Xxxx xx xxxxxxxxxx xx xxx xxxxxxxxx xxxx-xxxxx xxxx xxxx xxx Xxxxx
xxxxxxxxx xxxxxxxxxxxxx:
/commit-script-input/configuration/snmp/location

Post-inheritance Configuration
Xx xxxxxxxxx xxxxxxxxxx, xxx xxxxxxxxx xxxxxxxxxxxxx xxxxxxxx xx
xxxxxx xxxxxxx xxxxxx xxx <xxxxxx-xxxxxx-xxxxx> xxxxxx-xxxx xxxxxxx xx
xxx xxxx-xxxxxxxxxxx xxxx. Xxxx xxx xxx xxxxxxxxxxxx:
„„The configuration groups inherit into the configuration hierarchies,
and the [edit groups] hierarchy is not included in the post-
inheritance configuration.
„„No inactive statements are present in the post-inheritance
configuration.
Xxxxxxxxx xxxx xx xxx xxxxxxxx x xxxxxx xxxxxx xxxxxxx xxxxxxx xx
xx xxxx xxxxxxxxx xxxx xxx xxxxxx xxxxxxxxxxxxx xxxx xxxx xx
xxxxxxxxx xxxx xxx xxxxxx. Xxx xxxx xxxxxx xxxxxxx xxxx xx xxxxxx
xxx [xxxx xxxxxx] xxxxxxxxx xxx/xx xxxx xxx xxxxxxxx xxxxxxxxxx
xxxxxxx xx xxx xxxxxxxxxxxxx. Xx xxxxx xxxxxxxxx, xxx xxx-
xxxxxxxxx xxxxxxxxx xxxxxxxxxxxxx xxxx xx xxxxxxxxx xxxxxxx xxx
<xxx-xxxxxxxxxxxxx> XXX xxxxxxx:
var $configuration = jcs:invoke( "get-configuration" );
Xxx xxxxxxxxx xxxxxxxx xxx xxxx xx xxxxxx xx xxxx xxx xxxxxxxx
xxxxxxxxxxxxx xxxx xx xxxxxxxx:
var $re0-group = $configuration/groups[name == "re0"];

ALERT! Do not use the <get-configuration> API element within a commit script prior
to the following releases: 9.3S5, 9.4R4, 9.5R3, 9.6R2, or 10.0R1, as it can
cause the Junos device to hang while booting. For further details refer to
PR 452398.

junos:changed
Xxx xxxx-xxxxxxxxxxx xxxxxxxxxxxxx xxxxxxxx xx xxxxxx xxxxxxx
xxxxxxxxx xxxx xxxxxxx xxx xxxxxxx xx xxx xxxxxxxxx xxxxxxxxxxxxx
xx xxxxxxxxx xxx xxxxx:xxxxxxx xxxxxxxxx, xxxx x xxxxx xx "xxxxxxx", xx
xxx xxxxxxx xxxxx xx xxxx xx xx xxxxx xxxxxx xxx xxxxxxxx xxxxx.

<system junos:changed="changed"> {
<host-name junos:changed="changed"> "juniper1";
<login> {
<user> {
<name> "admin";
<uid> "2001";
<class> "superuser";
<authentication> {
<encrypted-password> "$1$usVGUcj1$JA/9xEqNrFDImo02nP9tN.";
}
}
}
<services> {
<ssh>;
}
<syslog> {
<file> {
<name> "messages";
<contents> {
<name> "any";
<any>;
}
}
}
}

Xxx xxxxx xxxxxxx xxxxx xxx xxxx-xxxxxxxxxxx xxxxxxxxxxxxx xx x


xxxxxx xxxxxx xx xxxxx xxx xxxxxx’x xxxxxxxx xxx xxxx xxxxxxx. Xxx
xxxxx:xxxxxxx xxxxxxxxx xx xxxx xxx <xxxx-xxxx> xxxxxxx xx xxxx xx xx
xxx xxxxxx <xxxxxx> xxxxxxx xxxxxxxxx xxxx xxxxxx.
ALERT! When a Junos daemon generates a commit warning, it does not remove
the junos:changed attributes from the changed elements, and they persist
through following commits. This makes the attribute unreliable as an
indication of new changes because it actually reflects changes that
occurred since the last daemon-warning-free commit, rather than
changes that occurred since the last commit. (Commit script
<xnm:warning> messages, discussed in Chapter 10, do not cause the same
impact to the junos:changed attribute that Junos daemon warning
messages do).

junos:group
Xxxxxxxxxxxxx xxxxxx xxx xxxx xx xxxxxxxxxxxx xx xxxxxx
xxxxxxxxxxxxx xxxxxxxxxx xxxx xxxxxxx xxxx xxxxxxxx xxxxxxxxxxxxx
xxxxxxxxxxx. Xxxxxxxx xxx xxxxx xxxxxxxxx xx xxx xxxxxxx xx xxx
xxxx-xxxxxxxxxxx xxxxxxxxxxxxx xxxxxxxx xx xxxxxx xxxxxxx, xx xx
xxxxxxxx xx xxxxxxxxx xxx xxxxxx xxxx xxxxxx xxx xx xxx
xxxxxxxxxxxxx xx xxxxxxx xxx xxx xxxxx:xxxxx xxxxxxxxx. Xxxx
xxxxxxxxx xx xxxxxxxx xx xxxxx xxxxxxxxxxxxx xxxxxxx xxxx
xxxxxxxxxx xxxx x xxxxxxxxxxxxx xxxxx. Xxx xxxxx xx xxx xxxxx:xxxxx
xxxxxxxxx xx xxx xxxxxxxxxxxxx xxxxx xxxx xx xxx xxxxxxxxx xxxx.
<snmp junos:group="re0"> {
<community junos:group="re0"> {
<name junos:group="re0"> "public";
<authorization junos:group="re0"> "read-only";
}
}

Xx xxxx xxxxxxx, xxx xxxxxx [xxxx xxxx] xxxxxxxxx xxx xxxx xxxxxxxxx
xxxx xxx xx0 xxxxxxxxxxxxx xxxxx, xx xxxxxxxxx xx xxx xxxxxxxx xx
xxx xxxxx:xxxxx xxxxxxxxx xx xxxxx xxxxxxxxxxxxx xxxxxxx xxxx x xxxxx
xx "xx0".

<commit-script-results>
Xx xxxxxxxx xx xxxxx x xxxxxxxxx xxxxx xxxxxxxx, xxx xxxxxx xxxxxx
xxxxxxxxxxx xxxx xxxxxxx xxxx xx xxx xxxxx xxxxxxx xxxxxxx xx xxxx
xxx xxxxxxx x xxxxxx xxxx xxx-xxxxx xxxxxxx. Xx xxxxxxx xxxx <xx-
xxxxxx-xxxxxxx>, xxx xxxxx xxxxxxx xxxx <xxxxx-xxxxxx-xxxxxxx>, xx xxx
xxxxx’x xxx xxxxxx xxxxxx xxxxxxxxxxx xxxxxxx x <xxxxxx-xxxxxx-
xxxxxxx> xxxxxxx?

Xxx xxxxxx xx xxxx xxxx xxxxxxx xxxxxxx xx xxx xxxxxxxxx xxxxxx xxx
xxxxxxxxxxx xxxxxxx xxx xxxxx / xxxxxxxx xx xxx xxxxx.xxx xxxxxx xxxx
xxxxxxxxxxxxx xxxxxx xx xx xxx xxxxxx xxxx. Xxx xxxxxxxx xxx xxxxx
xxxxxxx xx xxxx xxxxxxx:
match / {
<commit-script-results> {
apply-templates commit-script-input/configuration;
}
}

Xxxxxx xxxxxx xxxxxxxxx xxxxxx xxxx xxxx xxxxxxxx, xxxxxxx xxx


<xxxxxx-xxxxxx-xxxxxxx> xxxxxxx xx xxxxxx xx xxxxxxx xx xxx xxx-xxxxx
xxxxxxx xx xxx xxxxxx xxxx. Xxx xxxxx xxxxxxxxxxxxx xxxxxxxxxxx
xxxxxxxx xx xxxxxx xxxxxxx xxx xxxxx-xxxxxxxxx xxxxxxxxx, xxx xxx
xxxxxxxx xxxxxxx xx xxx xxxxxx xxxx xx xxx xxxxxx xxxxxx xxx
xxxxxxxx xxxxxxxxx xxxxxx <xxxxxx-xxxxxx-xxxxxxx>.
Xx xx xxxxxxx, xxx xxxxxx xxxxxx xxxx xxxxxxxx xxxx xx xxxxxx
xxxxxxx xxx <xxx:xxxxxxx> xxx <xxx:xxxxx> (xxxx xxx xxxxxxxxx xx
Xxxxxxx 10), xxx x xxxxxx xxxxxx xxxx xxx xxx xxxxxxxxx xxxxx
xxxxxxxxxxxxx xxxxxxxx:
match configuration {
<xnm:warning> {
<message> "This is a warning message.";
}
<xnm:error> {
<message> "This is an error message.";
}
}
Creates this result tree:
<commit-script-results> {
<xnm:warning> {
<message> "This is a warning message.";
}
<xnm:error> {
<message> "This is an error message.";
}
}

Result Tree Interaction


Xxx xxxxxx xxxxx xxx xxxxxx x xxxxxx xxxx, xxx xxxxxx xxxxxxx xxxx
xxxx xxxxxxxxx xxx xx xxxx xxxxxxxxxxxxx xxxx xx Xxxxx xxxx xxxxxx
xx xx xxxxx xxxxxxx. Xx xxx xxxxx xxxxxxx xxxx xxx xxx xxxxxx xxxx
xx xxxxxxx xxxxxx. Xxxx xxxxxxxxxxxxx xxxxxxx Xxxxx xxx xx xxx
xxxxx xxxxxxx xxxxxx xxxxxxx xxxxxxxxx, xxx xxxxxxx xxx xxxxxx
xxxx.
Xxxxxxx, xxx xxxxxxxxx xx xxxxxx xxxxxxx xxxxxx xxx xxxxxx xxxxxxx
xxxxx xxxxx xxxxxx xxxx xxxxxx xxxxxxxxx xxxxxxxxx. Xxx xxxxxx
xxxx xxxxxxxx xxx xxxxxxxxxxxx xxx Xxxxx xx xxxxxx xxx
xxxxxxxxxxxxx, xx xxxxxxx xxxxxxx xxxxxxxx, xx xxx xxxxxx xxxxxxxx,
xx xx xxxxxx xxx xxxxxx xxxx xx xxxxx. Xxxxx xxxxxx xxxxxxx xxx xxx
xxx xxxx xxxxxxxxx xxx xxx xxxxxxxx xxxx xxx Xxxxx XXX xx xxx xxxx
xxxxxx xx xx xxx xxxxx xxxxxxx, xxxx xxx xx xxx xxxxxx. Xxx xxxxxxx
xxxxxx xxxxxx xxxxxxxx xxx xxxxxxxxxx xx xxxxx xxxx xxx xxxx-
xxxxxxxxxxx xxxxxxxxx xxxxxxxxxxxxx xx xxxxx xxx xxxxxxx xxx
xxxxxxxxxxxx xxx Xxxxx xx xxx xxxxxx xxxx.

Boot-up Commit
Xx x Xxxxx xxxxxxx xxxxx, xx xxxx xxxxxxx x xxxxxx xx xxxxxxxxxx xxx
xxxxxxx xxxx xxx xxxxxx xxxxxxxxxxxxx. Xx xxxx xx x xxxxxxx xxxxxx,
xxx xxxxxx xxxxxxxx xxx xxx xxx xxxxxx xxxxxxx xxxx xxxxxx xxxx
xxxxxxx.
Xxxx xxxx-xx xxxxxx xxxxxxx xxx xxxx xxxxxxx xx xxx xxxxxxxx xxxxxx
xxxxxxx, xxxxxxxxx xxx xxxxxxxxx xx xxxxxxxxxx xxxxxx xxxxxxx.
Xxxxx xxx xxx xxxxxxxxx xxxxxxxxxxxx xx xxx xxxx-xx xxxxxx:
„„Some information, such as chassis components, is not available
during the boot-up commit.
„„Commit errors during the boot-up commit cause the device to boot
with no configuration.
Xx xxxxxxxxxx xxx xxxxx xxxxxx, xxxxxxxx xxxxxxx xxxxxxxxxx. Xxxx
xxx xxxxxxxxxxxxx xx xxxxx xxxxxxxxx xxxxxx xxx xxxx-xx xxxxxxx xxx
xxxxxxx xxxxxxxxxx xxxx xxx xxx xxxx xxxxxxxxxxx, xx xxx xxxxxxx-
xxxxxxx xxxxxxxxxxx xx xxx xxxxxxxxx. Xx x xxxxxx xxxxxx xxxxxxxxx
x xxxxxx xxxxx xxx xx xxxx xxxx xx xxxxxxxxxxx, xxxx xxx xxxxxx
xxxxx xxxx xx xxxxxxxxxxxxx. Xxx xxxxxx xxxxxxx xx xxxx xxxxx
xxxxx xx xxxxxxxx xxxxxxxx xxxxxxxx xxx xxxxxxx.
Xxxx xxxx xx xxxx xx xxx xxxx xxxxxxx xxx xxxxxxxxx xxxxxxxx xxx
xxxxx xx xxxx xx xxx xxxxxx xxxxxxx xxxxxx xxxx xxx xxxxxxx. Xxxx
xx xxxx xxxxxx xxxxxx xxxxxx xxxxxxx xxxxxx xxxxxxx xxxxxxxxxxxxx
xx xxx xxxx-xx xxxxxx xxx xxx xxxx xxxxxx xxxxxx xxxxxxxx xx xx.

Commit Script Checklist


Xxx xxxxxxxxx xxxxxxxxx xxx xxxxxxxxxxx xx xxxxxx xx xxxxxxx xxxx
xxxxxx x xxx xxxxxx xxxxxx:
1. Xxx xxx xxxxxx xxxx xxxxxx xx /xxx/xx/xxxxxxx/xxxxxx xx xxx xxxxxxx-
xxxxxxx
2. Xxx xxx xxxxxx xxxx xxxxxxx xxxxx [xxxx xxxxxx xxxxxxx xxxxxx] xx
xxx xxxxxxx-xxxxxxx?
3. Xx xxxxxxxxx xxxxxxx xxx xxxx, xx xxxxx-xxxxxxxxxx xxxxxxxxxx
xxxxx [xxxx xxxxxx xxxxxxx xxxxxx]?
4. Xx Xxxxx XXX xxxxxxxxxxx xxxxxxxx xxx xxxxxxxxx, xxxx xxx xxxxxx
xxxx xxxxxxxxx xxxxxx xxx xxxx-xx xxxxxx
5. Xx Xxxxx XXX xxxxxxxxxxx xxxxxxxx xxx xxxxxxxxx, xxxx xxx xxxxxx
xxxxxx xx x xxxxxxxxxx xxxxxxxxxxxxx xxxxxxx xxx xxxxxx xxxxxxx-
xxxxxx xxx xxx xxxxx xxxxxxx-xxxxxxx? (Xxx xxxxx xxxxxxx-xxxxxxx
xxxxx xxx xxxx xxxxxx xx xxx xxxx xxxxxxxxxxx xx xxx xxxxxx.)
Chapter 10: Commit Feedback and Control 141
140 This Week: Applying Junos Automation

Chapter 10
Commit Feedback and Control

<xnm:warning> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . 140

<edit-path>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . 142

<statement>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . 144

<syslog>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . 145

<xnm:error>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . 147

Feedback and Control Options. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .


. . . . . . 150

Element and Template Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .


. . . . . . 151

Xxxxxxxxx xxxxxx xxxxxxx xxxxxx xxx xxxxxx xxxxxxx xxxxxxxx xxx


xxxxxxx xx xxxxx xxx xxxxxx xxxxxxx xx xx xxxxxxx xxxxxxxx xx xxx
xxxxxxxxxx xxxx xxxxxxx xxxxxxxxxxxxx xxx xxxxxxxx. Xxxxx xx xxx
xxxxx xxxxxxx xxx xxx <xxxxxx> xxxxxx xxxx xxxxxxx xx xxx
xxx:xxxxxx() xxxxxxxx xx xxxxxxx xxxxxx xx xxx xxxxxxx xx xxxxxx
xxxxx xxxxxx xxxx xxxxxxxxxxxx, xxx xxxxxx xxxxxxx xxxxxx xxx xxxxx
xxxxxxx xx xxxxxxx xxxxxxxx xx xxxxxxxxxx xxxxx. Xxxxxxx, xxxxxx
xxxxxxx xxx xxx xx xxxxx xxxxxx xxxx xxxxxxxx xx xxxxxxx xxxxxxxx
xx xxxx xx xxxxxx xxxxxxx: <xxx:xxxxxxx>, <xxxxxx>, xxx
<xxx:xxxxx>. Xxxx xxxxxxx xxxxxxxxx xxxxx xxxxx xxxxxx xxxx
xxxxxxxx, xxxxx xxxxxxxx xxxxx xxxxxxxx, xxx xxx xx xxx xxxx.

<xnm:warning>
Xx xxx xxxx xxxxxxx, xxx <xxx:xxxxxxx> xxxxxxx xxxxxx x xxxxxxx
xxxxxxx xx xx xxxxxxxxx xx xxx xxxxxxx xx xxx xxxxxxxxxx xxxx. Xxx
xxxxxx xxxxxxx xx xxx xxxxxxxx xx <xxx:xxxxxxx> xxxxxxxx xxx
xxxxxxxxx xxxxxxxxxxxx xxxxxx xxxxx xxxxxx xxx xxxxx. Xxxx xxx
xxxx xxxxxxxx xxxx xxx <xxx:xxxxxxx> xxxxxxxx:
„„Drawing attention to configuration problems that should be
corrected.
„„Indicating that the commit script is making an automatic change or
performing another action that the user should be aware of.
„„Informing the committing user that the commit script is not
performing its usual actions due to a problem with the configuration,
system, or Junos version in use.
Xx xxxxxxx x xxxxxxx xxxxxxx, xxxxx xxx <xxx:xxxxxxx> xxxxxxx xx xxx
xxxxxx xxxx xxxx x xxxxx xxxxxxx xx <xxxxxxx> xxxx xxxxxxxx xxx xxxx
xx xxxxxxx. Xx xxxxx xxx xxxxxxxxxxx Xxxxx Xxxxx! xxxxxxx, xxx
xxxxxxxxx xxxx:
match configuration {
<xnm:warning> {
<message> "Hello World!";
}
}
... xxxxxxxx xxxx xxxxxxx xx xxxx xx xxx xxxxxx xxxxxxx:
[edit]
jnpr@host1# commit
warning: Hello World!
commit complete

Warn If fxp0 Isn’t Inherited


X xxxx xxxxxx xxxxxxx xxxxx xx xx xxxxxxx x <xxx:xxxxxxx> xxxx xxx
xxx0 xxxxxxxxx xx xxx xxxxx xxxxxxxxx xxxx xxx xx0 xx xx1
xxxxxxxxxxxxx xxxxx. Xxx0 xx xxx xxx-xx-xxxx xxxxxxxxxx xxxxxxxxx
xxx xxxx Xxxxx xxxxxxx. Xxx xx0 xxx xx1 xxxxxxxxxxxxx xxxxxx xxxx x
xxxxxx xxxxxxxxxxxxxx xx xxxx xxxx xxx xxxxxxxxx xxxx xx xxx
xxxxxxxxx xxxxxxx xxxxxx. Xx, xx x xxxxxxxxxxxxx xx xxxxx
xxxxxxxxx xx xxxxxxx-xxxxxx 0, xx xxxxxxx xxx xxxxxxxx xx
xxxxxxxxxxxxx xxxxx xx1, xxx xxxx xxxxx.
Xxx xxxxxxxxx xx xxxx xxxxxxxx xx xxxx xx xxxxxx xxxxxxx-xxxxxx
xxxxxxxx xxxxxxxxxxxxx xx xx xxxxxxxx xxxxxx x xxxxxxxxxxxxx xxxx
xxxx xx xxxxxx xxxxxxx xxxx xxxxxxx-xxxxxxx.
MORE? For more information on the re0 and re1 configuration groups see the CLI
User Guide within the Junos documentation at
www.juniper.net/techpubs/.
Xxx xxxxxxx-xxxxxx xxxxxxxx xxxx xxxx xx xxxxxxxx xxxxxxxx xxxxxx
xxx xx0 xxx xx1 xxxxxx xx xxx xxxxxxxxx xxx0 xxxxxxxxxxxxx. Xxx
xxxxxx xxxxxx xxxxxxx xxxxx xxxxx xx xxx xxx0 xxxxxxxxx xx xxxxxxx,
xxx xx xxx xxxxxxxxx xx xxxxxxx, xxx xxxxxx xxxxxxxx x xxxxxxx
xxxxxxx xx xxx xxxxxxxxxxxxx xx xxx xxxxxxxxx xxxx xxxxxx xxx xx0
xx xx1 xxxxxxxxxxxxx xxxxx.
/* check-fxp0-inheritance.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

var $fxp0-interface = interfaces/interface[name == "fxp0"];

/* If fxp0 is configured, but not inherited from re group, then display warning */
if( $fxp0-interface &&
jcs:empty( $fxp0-interface[@junos:group=="re0" || @junos:group=="re1"] ) ) {
<xnm:warning> {
<message> "fxp0 configuration is present but not inherited from re group";
}
}

Xxxxxxx 1 xxxxxxxx xxxx xxx xxxx-xxxxxxxxxxx xxxxxxxxx


xxxxxxxxxxxxx xxxxxxxx xx xxxxxx xxxxxxx xxxxxxxxx xxxxx
xxxxxxxxxxx xxxxxxx xxx xxxxx:xxxxx xxxxxxxxx. Xxxxx xxxxxxxxxxxxx
xxxxxxx xxxx xxxxxxxxxx xx x xxxxx xxx xxxx xxxxx’x xxxx xxxxxx xx
xxx xxxxxxx xx xxx xxxxx xx xxx xxxxx:xxxxx xxxxxxxxx.
Xxx xxxxx xxxxxx xxxxxx xxxxx xxxxxxxxx xx xxxx xxxxxxxx xx
xxxxxxxxx xxx x xxxxx:xxxxx xxxxxxxxx xx xxx xxx0 xxxxxxxxx xxxx xxxx
x xxxx xx xxxxxx xx0 xx xx1. Xx xxx xxx0 xxxxxxxxx xx xxxxxxx, xxx
xx xxxxx x xxxxx:xxxxx xxxxxxxxx xxxx xxx xx xxxxx xxxxxx, xxxx xxx
xxxxxxxxx xxxxxxx xx xxxxxxxxx xxxx xxx xxxxxxxxxxxxx xx
xxxxxxxxx:
[edit]
jnpr@host1# commit
warning: fxp0 configuration is present but not inherited from re group
commit complete
Try It Yourself: Host-name Should Inherit from Configuration Group

Create a commit script that generates a commit warning message if the host-name is not
inherited from the re0 or re1 configuration groups.

<xnm:warning> Child Elements


Xxx <xxxxxxx> xxxxx xxxxxxx xx xxxxxxxx xxx xxx <xxx:xxxxxxx>
xxxxxxxx. Xxxx xxxx xx xxxxxxxxx xx xxx xxxx xxxx xx xxx "xxxxxxx:"
xxxxxxxxx. Xxxxx xx xx xxxxx xxxxxxxxxx xxx xxxxxx xxxxxxxx xx
xxxxxxx xxxx x <xxxxxxx>, xx xxxxx xx xx xxxxxxx xx xxxxxxx
xxxxxxxxxx xxxxxxxxxxx xxxxxxx xxxx xx xxx xxxxxxxx xxxxx xxxxxxxx
xx <xxx:xxxxxxx>. Xxx xxx xxxx xxxxxxxx xxxx xxxxx xxxxxxxx, xxxxx
xxx xxxx xxxxxxxxx xx xxx xxxxxxxxx xxxxxxxx, xxx <xxxx-xxxx> xxx
<xxxxxxxxx>. Xxxxx xxx xx xxxx xx xxxxxxx xxxxxx xxxxxxx xxxxxxxx
xxxx xx xxx xxxxxxxxx:
[edit]
jnpr@host1# commit
[edit interfaces ge-0/0/1 unit 0 family inet]
'address 10.0.0.1/24'
warning: identical local address is found on different interfaces
commit complete
Xx xxxx xxxxxxx, xxx xxxxxxx xxxxxxx xxxxx xx xxxxxxxxx xxxxx
xxxxxxx xx xxxxx xx xxxxxxxxx xxxxxxxxxx, xxx xxxxx xxx xxxxxxxxxx
xxxxx xx xxxxxxxxxxx xxxxxxxxx xx xxxx. Xxx xxxxx xxxx xxxxxxxx
xxx xxxxxxxxx xxxxx xxx xxxxxxx xxxxxxxxxxxxx xx xxxxxxx, xxxxxx
xxxxxxxx, xxx xx xxxxxxx xx xxxxx xxx <xxxx-xxxx> xxxxxxx. Xxx xxxxxx
xxxx xxxxxx xxx xxx xxxxx xxxxxxxxxxxxx xxxxxxxxx xxxx xxxxxx xxx
xxxxxxx. Xx xx xxxxxxx xx xxxxx xxx <xxxxxxxxx> xxxxxxx xxx xxxxxxx
xx x xxxxxxxx xxxxxxxx xxxxxx xxxxxxxx xx xxxxxx xxxxxx xxx
xxxxxxxx.
MORE? To learn about additional child elements of <xnm:warning> see the
Configuration and Diagnostic Automation Guide within the Junos
documentation at www.juniper.net/techpubs/.

<edit-path>
Xx xxxxx xx xxx xxxxx xxxxxxx, xxx [xxxx xxxxxxxxxx xx-0/0/1 xxxx 0 xxxxxx
xxxx] xxxxxx xxxx xx xx xxxxxxx xx <xxxx-xxxx> xxxxxx.

Xxxx xxxxxxx xxxxx xxx xxxxxxx xxxxxxxxx xxxxx xxx xxx xx xxxx
xxxxxx xxxx xxxxx xxx xxxxxxxx xxxxxxxxx xxxxxx xxx xxxxxxxxxxxxx
xxxx xxxxx xx xxx xxxxxx xx xxx xxxxxxx. Xxxxxxxx xxxx xxxxxxxxx
xxxxxxxxxxxxx, xx xxxxxxxxxxxx xxxxx, xxx xxxxxxxx xx xxxxx xxx
<xxxx-xxxx> xxxxxxx xxx xx xxxxxxx.

Xxx xxxxxxxxx xxxxxx xxxxxxxx x xxxxxxx xxxxxxx xxxx xxx xxxxx


xxxxx xxx xxxx xxxxxxxx xxx xxx xxxxxxxxxx xxx. Xx xxxx xxx <xxxx-
xxxx> xxxxxxx xx xxxxxxx xxx xxxxxxxxx xx xxx xxxxxxx xxxxx xxxxx:
/* check-permissions.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
import "../import/junos.xsl";

match configuration {
/* Warn about any login classes with the all permission bit */
for-each( system/login/class[ permissions == "all" ] ) {
<xnm:warning> {
<edit-path> "[edit system login class " _ name _ "]";
<message> "Permission all is assigned to invalid class.";
}
}
}
With this script enabled, assigning any login class the all permission bit results in the
following warning message:
[edit]
jnpr@host1# commit
[edit system login class sandbox]
warning: Permission all is assigned to invalid class.
commit complete

jcs:edit-path
Xxx xxxxx-xxxxxxxxxxx.xxxx xxxxxx xxxxxxx xx xxxx xx <xxxx-xxxx> xxx
<xxxxxxx> xxxx xxxxx xxxxxxxxx xxxxxx xxx xxxxxxx xxxxxxx. Xxx xxx
<xxxx-xxxx> xxxxxx xxx xxxxx xxxxxxxx xx xxx xxxxxx, xxxxx xxx xx
xxxxxxx xxx xxxx xxxxxxxxxxx. X xxxx xxxxxxxxx xxxxxx xx xxxxxxxxx
xx <xxxx-xxxx> xxxxxxx xx xx xxxx xxx xxx:xxxx-xxxx xxxxxxxx xxx xxxxx
xx xx xxxxxxxxxxxxx xxxxxxxx xxx <xxxx-xxxx> xxxxxxx.
Xxx xx xxx xxxxxxx xxxxxxxxx xxxxxxxx xxxxxx xxxxx.xxx xx xxx:xxxx-
xxxx, xxxxx xx xxxxxx xx xxx xxxxxx xxxxxx. Xxx xxxxxxxx xxxxx xx
xxxxxxxx xxx xxxxxxxxx xx xxx xxxxxxx xxxx xxxxxxxxxxx xxx
xxxxxxxxx xxx xxxxxx xxxxxx xxxxxx xx <xxxx-xxxx> xxxxxxx. Xxxx
xxxxx xx xxxxx xx xxx xxxxxx x xxx-xxxx xxxx xxxxx xxxx xxxxxxxxx
xxxxxxx xxx xxxx xxxxxx xxx xxxxxxx xxxx. Xx xxx xxxx xxxx xxxxxx
xx xxxxxxxxx xx <xxxx-xxxx> xx xxx xxxx xx xxx xxx-xxxx xxxx’x xxxxxxx
xxxx xxxx xxx:xxxx-xxxx xxx xxxxxxxxx xxx xxxx xx xxxxxxx, xxx xx xxx
xxxxxxx xxxx xxxx xxx xxxxxxx xxx xxxx xxxx xxxxxx xx xxxxxxxx xxxx
xxx $xxx xxxxxxxxx xx xxx:xxxx-xxxx xxx xx xxx xx xxx xxxxxxx xxxx.
Xxx xxxxxxxxx xxxxxx xxxxx xxx xxx:xxxx-xxxx xxx xxxxxxxx xxx
xxxxxxxx xx xx <xxxx-xxxx> xx x <xxx:xxxxxxx> xxxxxxx. Xxxx xxxxxx xx
xxxxxxxx xx xxxxxxx x xxxxxxx xxxxxxx xxxxx xxx xxxxxxx xxxxxxxxx
xxxx xxxx xxx xxxx x xxxxxxxxxxx xxxxxxxxxx:
/* check-descriptions.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

/* Loop through all logical interfaces */


for-each( interfaces/interface/unit ) {

/* Missing description */
if( jcs:empty( description ) ) {
<xnm:warning> {
call jcs:edit-path();
<message> "Interface description is missing.";
}
}
}
}

Xxx xxxxx-xxxxxxxxxxxx.xxxx xxxxxx xxxxxxx xx xxxxxxx xxxxxxxx


xxxxxxx xx xxxx xxxx xxx xxxxxxxxx xxxxxxxxxxxx xxx xxxxxxx:
[edit]
jnpr@host1# commit
[edit interfaces interface ge-0/0/3 unit 0]
warning: Interface description is missing.
[edit interfaces interface ge-0/1/0 unit 0]
warning: Interface description is missing.
commit complete
Xxxxx xxx xxx:xxxx-xxxx
xxxxxxxx xxxxxx xxx xxxx xxxxxxxxx xx xxx
xxxxxxx xxxx xx xx xxxxxxxxx xxxxx xxx xxxxxxx xxxxxxx. Xxxx xxxxx
xx xxxxx xx xxx xxxx xxxxxxx xxxx xxxxxxxxx xxx xxxx xxxxx xx xx
xxxxxxxxx xx xxxxxx xxx xxxxxxx.
Try It Yourself: ISIS Interface Lacks Family Iso

Create a warning message for every interface enabled for the ISIS protocol that does not have
family iso configured. Include an <edit-path> to better document the problem.

<statement>
Xxx <xxxxxxxxx> xxxxxxx xxxxxxxxx xxx xxxxx xxxxxxxxxxxxx xxxxxxxxx
xxxx xxxxxx xxx xxxxxxx. Xxxxxxxxx xx xxx xxxxxx xxxxxxx xxxxxxx
xxxxx xxxxxxx xx xxx xxxxxxx, xxx 'xxxxxxx 10.0.0.1/24' xxxx xx xxx
xxxxxxxxx xx xxx xxxxxxx xxxxxxx:
[edit]
jnpr@host1# commit
[edit interfaces ge-0/0/1 unit 0 family inet]
'address 10.0.0.1/24'
warning: identical local address is found on different interfaces
commit complete
Xxx xxxxxxxxx xxx xx xxxxxxxxx xxxxxxxx, xxxxxxx xx xxx <xxxx-xxxx>
xxxxxxx, xx xxxxxxxxx xxx <xxxxxxxxx> xxxxxxx xxxx xxx xxxxxxxxxxx
xxxxx xxxxxx xxx <xxx:xxxxxxx> xxxxxxx. Xx xxxxxxxx, xxx xxx:xxxxxxxxx
xxxxxxxx xxx xx xxxxxx xx xxxxxxxxxxxxx xxxxxxxx x <xxxxxxxxx>
xxxxxxx xxxxx xx xxx xxxxxxx xxxx, xx xxx xxxxxxxx’x $xxx xxxxxxxxx
xxx xx xxx xx xxxxxx x xxxxxxxxx xxxx.
Xxxx xxxxxxx xxxxxx xxxxxxxx x xxxxxxx xxx xxxxx xxxxxxx xxxx xxx
xxxxxxxxxx xxxxxx xx xxxxx xxxxxx, xxx xxx xxx xxxxxxx xxxxxx xxx
xxxxxxxxxxxxx. Xx xxxxxxxx xxxx xx <xxxx-xxxx> xxx x <xxxxxxxxx>
xxxxxx xxx <xxx:xxxxxxx> xxxxxxxx:
/* check-event-scripts.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

/* Save these hierarchy nodes */


var $event-options = event-options;
var $system = system;

/* Look for any referenced event scripts */


for-each( event-options/policy/then/event-script ) {

/* Record event-script name */


var $name = name;

/* Check if enabled in either location */


var $under-event-options = $event-options/event-script/file[name == $name];
var $under-system-scripts = $system/scripts/op/file[name == $name];

/* If it isn't enabled in either location then log an warning */


if( jcs:empty( $under-event-options ) and jcs:empty( $under-system-scripts ) ) {
<xnm:warning> {
call jcs:edit-path( $dot = ancestor::policy );
call jcs:statement();
<message> "Event script is not enabled.";
}
}
}
}

Xxxx xxxxxx xxxx xxx xxx:xxxx-xxxx xxx xxx:xxxxxxxxx xxxxxxxxx xx xxxxxx


xxxxxx <xxxx-xxxx> xxx <xxxxxxxxx> xxxxxxxx xxxxx xx xxx xxxxxxx xxxx
xx x xxxxxxxx xxxxxxxxx xxxx. Xxx <xxxxxxxxx> xxxxxx xxxxx xx xxx
xxxxx-xxxxxx xxxxxxxxxxxxx xxxxxxxxx xx xxx xxx:xxxxxxxxx xxxxxxxx
xxx xxx xxx xxxxxxx xxxx xx xxx xxx-xxxx xxxx. Xxx <xxxx-xxxx> xxxxxxx,
xxxxxx xx xxx xx xxx xxxxx xxxxxx xxxx xxxxxxxx xxx xxxxx xxxxxx.
Xxxx xx xxxxxxxxxxxx xx xxxxxxx xxx $xxx xxxxxxxxx xx xxx
xxxxxxxxxxx xxxxx xxxxxx xx xxxxx xxx xxxxxxxx xxxx xx xxx xxxxxxxx
xxxx.
Xxxx xx xxx xxxx xxxxxxx xxxxxxx xxxx xx xxxxxxxxx xxxx xx xxxxx
xxxxxx xx xxx xxxxxxxx xxxxxxx. Xx xxxxxxxx xxx xxx xxxxxxxxxxx
xxxxxxxx xx xxxxxxxx xxxxxxx xxxx xxxxx xx xx xxxxxxxx:
[edit]
jnpr@host1# commit
[edit event-options policy save-core-files]
'event-script save-core-files.slax;'
warning: Event script is not enabled.
commit complete

<syslog>
Xxxxx xxx <xxx:xxxxxxx> xxxxxxx xxxxxx x xxxxxxx xxxxxxx xx xxx
xxxxxxx xx xxx xxxxxxxxxx xxxx, xxx <xxxxxx> xxxxxxx xxx xx xxxx xx
xxxxxxxx xxxx xxxxxxxxx xxxxxxxx xx xxxxxxx xxxx xx xxx xxxxxx.
Xxx <xxxxxx> xxxxxxx xxx x xxxxxx <xxxxxxx> xxxxx xxxxxxx xxxx
xxxxxxxx xxx xxxxxx xxxx xx xx xxxxxx xx xxx xxxxxx. Xxx xxxxxx
xxxxxxxx xxxxxxxxx xx xxxx xxxxxxx xxx xxxx xxxx xxx xxxxxx
xxxxxxxx xxxx x xxxxxx xxxxxxx.
NOTE No syslog message is generated by the <syslog> element in the following
two circumstances:
„„When a commit check is being performed.
„„During the initial boot-up commit.
Xxx xxxxxxxxx xxxxxx xxxxxxxxxxxx xxx xx xxx xxx <xxxxxx> xxxxxxx
xx xxxxx xxxxxxx xxxxxxxx xx xxx xxxxxx:
/* check-loopback-filter.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {
var $lo0-interface = interfaces/interface[name == "lo0"];
if( jcs:empty( $lo0-interface/unit[name=="0"]/family/inet/filter/input ) ) {
<syslog> {
<message> "Warning: no lo0.0 firewall filter is assigned.";
}
}
}
Xxxx xx xxxxxxxx xxxxxx xx xxxxxxxxxx xxx xxx xx0.0 xxxxxxxxx xxx
xxxxxxxxx xxxxxxx xx xxxx xx xxx xxxxxx:
Nov 19 22:02:43 host1 cscript: Warning: no lo0.0 firewall filter is assigned.

Comparison to jcs:syslog()
The <syslog> result tree element for commit scripts performs a role
similar to the jcs:syslog() function, which is available to all script types, in
that the <syslog> element causes its text to be written to the syslog. One
difference between the two approaches, though, is that unlike the
jcs:syslog() function, the <syslog> result tree element has no control over its
facility and severity; it always logs messages from the daemon facility at
warning severity. In other words, the <syslog> message:
<syslog> "This is a syslog message";
Is equivalent to:
expr jcs:syslog( "daemon.warning", "This is a syslog message" );
Xxxxx xxxxxxxxxxx xxx x xxxxxx xx xxxx xxx xxxxxxxxxxx xx
xxxxxxxxx xx Xxxxx. Xxx xxx:xxxxxx() xxxxxxxx xxxx xxx xxxxxxx xx xxx
xxxxxx xxxxxxxxxxx, xxxxx xxx xxxxxx xx xxxxx xxxxxxxxx, xxx xxx
<xxxxxx> xxxxxxx xx xxxx xxxxxxxxx xxxx xxx xxxxxx xxxxxx xxxxxx
xxxxx xxx xxxxxxxx xx xxx Xxxxx xxxxxxxxxx xxxxxx xxxxxxxxx xxx
xxxxxxxxxx xx xxx xxxxxx xxxxxxx. Xxxx xxx xxx xxxxxxxxxxxx:
„„Syslog messages from <syslog> are only logged if the commit process
is successfully completed. A <xnm:error> element in the result tree
causes the syslog message to not be logged. The jcs:syslog() function
is always logged, whether the commit results in an error or not.
„„Syslog messages from jcs:syslog() are logged before messages from
<syslog>. This affects their order within the syslog message file even
if the <syslog> elements occur earlier in the commit script than the
jcs:syslog() function.

Xxxxx xxxxxxxxxxx xxxxx, xxx xx xxxxx xxx xxxxx xx Xxxxx 10.1:


Table 10.1 Comparison of <syslog> and jcs:syslog()

Try it Yourself: Compare Syslog Methods

Create a commit script that logs two syslog messages, one using <syslog> and the other using
jcs:syslog(). Compare the syslog results when a commit is performed versus a commit check.

<xnm:error>
Xx xxx xxxx xxxxxxx xxx xxxxxxxx xxx xx xxxxxxx xxxxxxxx xxxx xxx
xxxxxx xxxxxxx xx xxx xxxx xx xxxxxxx xxxxxxxx xxxxxxxxx xx xxx
xxxxxxx xx xxxx xx xxx xxxxxx. Xxx xx xxxxxxxx xx xxxxxx xxxxxxxx,
xxxxxx xxxxxxx xxx xxxx xxxxxxx xx xxx xxxxxx xxxxxxx xxxxxx. Xx x
xxxxxx xxxxx x xxxxx xxxx xxxxxx xxx xxxxxxxxx xxxxxxxxxxxxx xxx
xxxxxx xxx xxxx xxx xxxxxx xxxxxxx, xxxxxxxxxx xxxxxxxxxxx xx xxx
xxxxxxxxx xxxxxxxxxxxxx. Xxxx xxxxxxx xx xxxxxxxx xx xxxxx xxx
<xxx:xxxxx> xxxxxx xxxx xxxxxxx.

Xxx <xxx:xxxxx> xxxxxxx xx xxxx xx xxx xxxx xxx xx <xxx:xxxxxxx> xxx xxx
xxxxxxxxx xxxxx xxxxxxxx. Xxxx <xxx:xxxxxxx> xxx <xxx:xxxxx> xxxxxxx
xxxxxxxx x <xxxxxxx> xxxxx xxxxxxx xxxx xxxxxxxx xxx xxxx xx xxxxxxx
xx xxx xxxxxxxxxx xxxx. Xxx xxxxxx x <xxx:xxxxxxx> xxxxxxx, x
<xxx:xxxxx> xxxxxxx xxxxx xxx xxxxxx xxxxxxx. Xxxxxxx xxxxxxxx
xxxxxx xxxxx xx xxx xxxxx xxxxx xx xxxx xxxxxxxxx xx xxxxx xx xxx
xxxxxxxxxxxxx xxxx xxxx xx xx xxxxx. Xx xxx xxxxxxxxxxxxx xxxxxx
xxxxx xx xxxxxxxxx xx xxxxxx xx xxx xxxxxxx xxxx, xxxxxx xxx xxxx.
Xxxx xxxxxxxxx xxxxx xxxxx xxxxxxx xx xxxxxxxxxxxx xxxxxxxxxxxxx
xxxxxx, xxxx xx x xxxxxxxxxx xxxxxxx xxxxxxxxx, xx xx xxx xxxxxx xx
xxxx xxxxxx xxxxxxxx xxxx xxxxxxx xx xxxxxxxxxxxx’x xxxxxxxx.

Basic Sanity Checking


Xxx xxxxxxxx xxx xxx <xxx:xxxxx> xx xx xx xxxxx xxxxxx xxxxxxxx. Xx
xxxxxxxxx xx xxx xxxx xxxxxxx, xxxx xxxxx xxxxxxx xx xxxxxxxx xxxx
xxxxxxx xxxxxxxxxxx xxx xxxxxx xxxxxxx, xxxx xx xxx [xxxx xxxxxxxxxx]
xx [xxxx xxxxxxxxx] xxxxxxxxx. Xx xx xxxxx xxx xxxxxx, xxxxxxxxx xxxx x
xx0 xxx xx1 xxxxxxxxxxxxx xxxxx xx xxxxxxxxxx, xx xxxx xxxx xx
xxxxxxx xx xxx xxxx xxxxxxxxxx.
Xxxxxxxx xxx xxxxxxxxx xxxxxxx xxxx xxxxxxxx xxxx xxx XXX xxxxxxx
xx xxxxxxx, xxxx xxx 'xxxx' xxxxxxx xx xxxxxxxxxx, xxx xxxx xxx xxx0
xxxxxxxxx xxx xxxx xxxxxxxx xx XX xxxxxxx:
/* basic-sanity-check.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";
match configuration {

/* Ensure that ssh is enabled */


if( jcs:empty( system/services/ssh ) ) {
<xnm:error> {
<message> "SSH must be enabled.";
}
}

/* Ensure that user account jnpr exists */


if( jcs:empty( system/login/user[name == "jnpr"] ) ) {
<xnm:error> {
<message> "The jnpr user account must be created.";
}
}

/* Verify that fxp0 has an IP address */


var $fxp0-interface = interfaces/interface[name == "fxp0"];
if( jcs:empty( $fxp0-interface/unit[name=="0"]/family/inet/address/name ) ) {
<xnm:error> {
<message> "fxp0 must have an IP address.";
}
}
}

Xx xxx xxxxx-xxxxxx-xxxxx.xxxx xxxxxx, xxxxx xxxxxxxx xxxxx xxx


xxxxxxxxx xxx x <xxx:xxxxx> xxxxxxx xx xxxxxxx xx xxx xxxxxx xxxx xx
xxx xxxxxxxx xxxx. X xxxxxx <xxx:xxxxx> xxxxxxx xx xxxxxxxxxx xx
xxxx xxx xxxxxx, xxx xx xxx xxxxx xxxx xxxxxxxx xxx xxxxx xxxxxx
xxxxx xxxxx:
[edit]
jnpr@host1# commit
error: SSH must be enabled.
error: The jnpr user account must be created.
error: fxp0 must have an IP address.
error: 3 errors reported by commit scripts
error: commit script failure

Try It Yourself: Sanity Checking

Write a commit script that generates a <xnm:error> if the [edit system], [edit interfaces], or [edit
protocols] hierarchies are missing.

<edit-path> and <statement>


Xxx xxxxx xxxxxxxx xxxxxxxxx xx <xxx:xxxxxxx> xxx xxxxxxxxx xx
<xxx:xxxxx> xx xxxx, xxxxxxxxx xxx <xxxx-xxxx> xxx <xxxxxxxxx> xxxxxxxx.
Xxxx, xxx xxx:xxxx-xxxx xxx xxx:xxxxxxxxx xxxxxxxxx xxx xx xxxx xx xx
xxxxxxxxx xxxxxx xx xxx <xxx:xxxxxxx> xxxxxxx.
Xxx xxxxxxxxx xxxxxx xxxxxxxxxxxx xxx xxx xx xxx xxx:xxxx-xxxx
xxxxxxxx xxxx x <xxx:xxxxx> xxxxxxx. Xx xxxxxx xxx xxx XXXX xxxxx
xxxx xx xxx xxxx x xxxxxxxxxx xxxxxx-xxxxx xxx xxxxxxxx xxxx xx
xxxxx xxxxxx xxx xxxxxx xxx xxxxxxx:
/* check-ebgp-peers.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

/* Retrieve AS Number */
var $asn = routing-options/autonomous-system/as-number;

/* Scroll through all EBGP peers */


for-each( protocols/bgp/group[ peer-as != $asn ]/neighbor ) {

if( jcs:empty( family/inet/unicast/prefix-limit/maximum ) &&


jcs:empty( ../family/inet/unicast/prefix-limit/maximum ) ) {
<xnm:error> {
call jcs:edit-path();
<message> "EBGP peer must have prefix limit defined.";
}
}
}
}

Xxx xxxxx-xxxx-xxxxx.xxxx xxxxxx xxxxxxx xxxx xxx xxxx-xx xx xxxxxxx


xx xxx XXX xxxxx xxxxxx xxxx xx xxx xxxxxxxx xxxxx, xxx xxxx xx
xxxxxxxxxx-xxxxxx xxx xxxx xxxxxxx xxxxxx [xxxx xxxxxxx-xxxxxxx].
(Xxxxx xxx xxxxxxxxxxx xxxxx xxxx xxxx xxxx xxxxxxxx xx xxx xxxxxx
xxxxxx xxxxxx). Xxx xxxxxx xxxxxxxx xxxx xxx XXXX xxxxx xxxx x
xxxxxx-xxxxx xxxxxxx xx xxxxxx xxx xxxxxxxx xx xxxxx xxxxx. Xx xxx
xxxxx xxxx xxx xxxxx xxx xxxxxx xxxxxxxx xx xxxxx xxxxxxx xxxxxxxxx
xxx <xxxx-xxxx> xxxxxxxxxx xxx xxxxxxxx xxxxxxxxx, xxx xxxxx xxx
xxxxxx:
[edit]
jnpr@host1# commit
[edit protocols bgp group AS65535 neighbor 10.0.0.2]
EBGP peer must have prefix limit defined.
error: 1 error reported by commit scripts
error: commit script failure
Try It Yourself: Incorrect Autonomous-system Number

Write a commit script that generates a <xnm:error> if the autonomous-system number is not set
to 65000. Include <edit-path> and <statement> elements to better document the problem.

Errors Based on Chassis Components


Xxxxxx xxxxxxx xxxx xxxxxx xx xxx xxxx Xxxxx XXX xxxxxxxx xx xx xxx
xxxxx xxxxxxx, xxxxx xxxxx xxxx xxxx xxx xx xxxxxxxxxx xx xxxxxxxx
<xxx:xxxxx> xxxxxxxx xxxxx xx xxx xxxxxxxxxxxxx xx xxxx xx xx xxxxx
xxxxxxx xxxx xx xxxx XXXx xxx xxxxxxxxx, xxx.
Xxx xxxxxxx xxxx xxxxxxxxxxx xxxx xxxxxxx. Xxxxxxxxxxx xxxx xxx
XXX xx xxx xxxxxx xxxxxxxxx xxx xxxxxx xxxxxxx xxxx xx xx
xxxxxxxxxx xx xxxxxx xxxx xxxxxxxx xxxxxxx xxxxxxxxx. Xxx xxxxxxx,
xxxxxx xxx xxxx-xx xxxxxx xxxx XXX xxxxxxxx xx xxx xxxxxx xxxx, xx
xxx xxxxxxxx xxxxxxx xxxx xxx xxx xxxxxxxxxxx. Xxxx xxxxxxxx xxxx
xxxxxx xxxxxxx xxx xx xxx xxxxxxx-xxxxxxx xx xxx xxxxxx, xxx xxxx
xxxxx xxxx xxx xxxxxx xxxxxxx-xxxxxx xxx xxxxxx xx xxx xxx
xxxxxxxxxxx xxxxxxxxx xxxx xxx XXX. Xxxx xxxxx xx xxxx xxxxxxxx
xxx x xxxxxx xxxxxx xxxx xxxxxxxx XXX xxxxxxxxxxx xxx xx xxxxxxx xx
xxx xxxxxxx-xxxxxx xx xxxxx x xxxxxxxxx xxxxxxxx xxxx xxx xxxx
xxxxxx xxxxxx xxxxxxx xx xxxxxxx xxxxxxx-xxxxxx, xxxxx xxx xxxx xx
xxxxxxxxxxxxx xxxxxx xxx xxxxxxx-xxxxxxx. Xx xxxxxxxx, XXXx xxx
xxxxx, XXXx xxx xxxxxxx, xxx xxxxx xxxxxxx xxxxx, xxx xxxxxxx xx xxx
xxxxxx xxxxxxx. Xxxxx xxxxxxx xxx xx xxxx xx xxxxx xxx xxxxx
xxxxxxx, xxx xxxxxxxx xxxx xxxxxx xxxxxxx xx xxx xxx xxx xxxxxxx
xxxxx xxx xxxx xxxxxx xx xxxxxxxxx.
Xxxxx xx xxx xxxxx xxxxx, xx xx xxxxxxx xxxx xx xxxx xxxxxx xxxxxxx
xxxxx xxxxx xxxxxxxxxxx xxxx Xxxxx XXX xxxxxxxx xxxx xxxxxx xxxxx
xxxxxxxxxxxxx xxxxxxx xxxxxxxxx.

Feedback and Control Options


Xxxx xxxxxxx xxx xxxxxxxxx xxxxxxxx xxxxxxxx xx xxxxxx xxxxxxx
xxxx xxxxxxx xxxxxxxx xx xxxxxxx xxx xxxxxxxxxxxxx xxxxxxx xxx
<xxx:xxxxxxx>, <xxxxxx>, xxx <xxx:xxxxx> xxxxxx xxxx xxxxxxxx. Xxxxx
10.2 xxxxx x xxxx xx xxx xxxxxxxxx xxxxxxx xxxxxxxxxx xxx xxxxxxx
xxxxx:
Table10.2 Examples from This Chapter
Xxxxxxxx xxx xxxxxxxx xxxx xxxx xxxx, xxx xxxxxxxxxx xxxx xxxx
xxxxxxx, xxx xxx xxxxxxxxx xxxxxxx. Xx xx xxxxxxxxxx xxx x xxxxxx
xxxxxx xx xxxx xxx xxxxx xxxxxxxxxx? Xx xxx xxxxxxx xxxx
xxxxxxxxxxx? Xxx xxxxxx xx xxxxx xxxxxxxxx xxxxxx xxx xxxx xxxxxxx
xxxxxxx xxx xxxxxxx xxxxxxxxxxxxxx xxxx xxxxxxxxx xxxxxxxx xxxxx
xxxx xxxxxx xxx xxxxxx xxx xx xxxxxxx xxxxxx xxxxx xxxxxxxxxxxxx.
Xxxxxxxxxx xxxxxxxxxxxxxx xxxx xxx xxxx xxxxxxxxx xxxxxxxxx xx
xxxxx xxxxxxxxxx xxx xxxxxxxxxxx xxxxxx xxx xxxxxxx xxxxxxxx xxx
xxxxx xxxxxxxxxxxxx xxxxx xxxxxx xxxxxx xx xxxxxx xxxxxx.
Xxxx xx xxxx xxxxx Xxxxx xxxxxx xxxxxxx xx xxxxxx – xxxx xxxxx
xxxxxxxxxxxxxx xxxx xxxx xxxxxxx xx xxxxxx xxx xxxxxxxxxx xxxx
xxxxxxxx xxx xxxxxxxxx xxx xxxx xxxxxxxxxxxxx xxxxxxxx xxxxx xxxxx
xxxxxx xxxxxx. Xxxxxx xxxxxxx xxxxxxx xxx xxxxx xxxxxxxxx xx
xxxxxxxx xxx xxxxxx xxxxxxx xx xxx xx x xxx xxxx xxxxx xxxx xxx xxxx
xxxxxxxxxx xxxxxxx.
Try It Yourself: Brainstorm Warnings and Errors

Write a list of configuration problems that would be of interest for your network. Note if they
should result in a <xnm:warning>, <syslog>, or <xnm:error>.

BEST PRACTICE Creating feedback and control options is an ongoing process. Many
configuration violations are readily apparent, but other problems might
only be realized after a human error has resulted in a disruption. When
correcting configuration errors, always consider if the addition of new
commit script checks could prevent the issue from occurring again.

Element and Template Summary


Xxxxxx 10.3 xxx 10.4 xxxxxxxxx xxx xxxxxxxxxxxxx xxxxxxxx xxx
xxxxxxx xxxxxx xxxx xxxxxxxx xxx xxxxxxxxx.
Table 10.3 Feedback and Control Result Tree Elements

Table 10.4 Feedback and Control Templates


Chapter 11: Changing the Configuration 155
154 This Week: Applying Junos Automation

Xxxxxxx 10 xxxxxxxxxxxx xxx xxx xx <xxx:xxxxxxx>, <xxxxxx>, xxx


<xxx:xxxxx> xx xxxxxxx xxxxxxxxxxxxx xxxxxxxx xxx xxxxxxx. Xxxxx
xxxxxxxxxx xxx xx xxxx xx xxxxx xxxxxxxx xx xxx xxxxxxxxx xx xxx
xxxxxxxxxx xxxx, xxx xxx xxxx xxxxxxx xxxx xxxxxxxx.
Xxx xxxx xxxxxxxxxxxxx xxxxxx xx xxx xxxxxxx xxxxxx xxxxxxxxxxxx.
Xxx xxxxxxx xx xxxxxxxx xxxxxxxxxxxxx xxxxxxx xx x xxxxxxxx
xxxxxxxxxx xx xxxxxx xxxxxxx. Xxxx xxxxx xxxx xxxxxxx xx xxxxxx
xxx xxxx xx xxx xx xxxxx, xxx xxxxxx xxxxxx xxxxxxxx xxx xxxxxxx
xxxxxxxxxxxxx, xxxxxxxx xxxx xxx xxxxxxxxxxxxx xx xxxxxxxxxx
xxxxxxxxx xx xxx xxxxxxx’x xxxxxxxx xxx xxxxxxx.

Adding/Editing/Replacing
Xxxxxxxxxxxxx xxxxxxx xxx xxxx xx xxxxxx x <xxxxxx> xxxxxxx xx xxx
xxxxxx xxxx. Xxx <xxxxxx> xxxxxxx xxxxxxxx xxx xxxxxxxxxxxxx
xxxxxxxxx xxx xxx xxxxxxxxx xxxx xxxxxx xx xxxxxxx:
<change> {
<system> {
<host-name> "host2";
}
}
Xxxxxx xxxx xxx xxxx xxxxxxxxx xx xxxxxxxx, xxxxxxxx xx xxx xxx-
xxxxx. Xxx xxxxxxxxxxxxx xxxx xxxx xxxxxxx xx xxxx xxx xxxx xxx, xx
xxxxxxxxx xxx xxxx xxxxxxxxx xx xxx xxxxxxx xxxxxx. Xx xxx <xxxxxx>
xxxxxxx xxxxx, xx xxxx-xxxx xx xxxxxxx xx xxx xxxxxxxxxxxxx xxxx xx xx
xxxxxxx xx "xxxx2", xxxxxxxxx xxxx-xxxx xx xxxxx xx xxx xxxxxxxxxxxxx
xxxx "xxxx2" xx xxx xxxxx.
MORE? To learn more about the load configuration mode command see the CLI
User Guide within the Junos documentation at
www.juniper.net/techpubs/.
Xx xxxxxxxxxx xxxxx xx Xxxxxx 9.1, xxxxxxxxxxxxx xxxxxxx xxxxxx xxx
xxxxxxxxx xxxxxxxxxxxxx. Xxxx xx xxx xxxx xxxxxxxxxxxxx xxxx xxx
xxxx xxx xxxxxx xxx xxxxxxxxx xx xx xxxxxxxxx. Xxxxx xxx xxxxxx
xxxxxxx xx xxxxxxxxx, xxx xxxxxxx xxxxxxxxx xx xxxxxx xxxxxxx xxx
xxxxxxxx xxxxxx xxx xxxxxxxxx xxxxxxxxxxxxx, xxxx xx xx xxxx xxx
xxxx xxxx xxxxxxxx xx x xxxx.
Xxx xxxx xxxx <xxxxxx> xxxxxxxx xxxxxx xxx xxxxxxxxx xxxxxxxxxxxxx
xx xxxx xxxxxxxx xx xxxxx xxx xxxxxx xxxxx xxxxxxx. Xxxx xxxxxxxx x
xxxxxx xx xxxxx xxx xxxxxx, xxx xxxx xxx xxxxxxxx xxxxx xxx
xxxxxxxxx xxxxxxxxxxxxx. Xxx xxx <xxxxxx> xxxxxxxx xxx xxxxx
xxxxxxx xx xxx xxxxxxxxx xxxxxxxxxxxxx. Xxx xxxxxxx, xxxx xxx
xxxxx <xxxxxx> xxxxxxx xx xxxxxx xxxx x xxxxxx xxxxxx xxx x xxxxxx
xxxxx xx xxxxxxxxx, xxx xxxxxxxxx xxxxxx xx xxxx:
[edit]
jnpr@host1# show system host-name
host-name host1;

[edit]
jnpr@host1# commit check
configuration check succeeds

[edit]
jnpr@host1# show system host-name
host-name host2;
Xxxxxx xxxxx xxx xxxxxx xxxxx xx xxxxxxxxx xxxx xxx xxxx-xxxx xxxxxx
xxx xxxxxxxxxxxxx xx xxx xxx xx xxxx2, xxx xxx xxxxxx xxxxx xxxx
xxxx1. Xxxx xx xxxxxxx xxx xxxxxxxxx xxxxxxxxxxxxx xxx xxx
xxxxxxx, xxxx xxx xxxxxxxxx xxxxxxxxxxxxx xxx xxxxxxx. Xx xxx
xxxxxx xxxxxx xxxxxxx xxxx xxxxxxxxxx xx xxxxxxxxx xxxxxxx x
xxxxxxxxxx xxxxxx xxxxxxx xx xxx xxxxxxxxx xxxxxxxxxxxxx xxxxxxxx
xxx xxxxxxxxx xxxxxxxxxxxxx, xxx xxxxxxx xxxxxx xxxxx xxxx xxx xxxxxx
xxx xxxxxxxx xxxxxx xxxxxxx xx xxxxxx xxx xxxxxxx xx <xxxxxx>
xxxxxxxx xx xx xxxxxxx xxxxx.
Try It Yourself: Commit Check and the <change> Element

Write a simple commit script that changes a single configuration setting. Perform a commit
check and verify that the candidate configuration is altered, but that the committed
configuration remains unchanged. Perform a normal commit and verify that the change is now
visible in the committed configuration.

Automatically Add Missing Configuration


Xxxxxxx 10 xxxxxxxx xx xxxxxxx xxxxxx xxxxxx xxxxx-xxxxxx-
xxxxx.xxxx xxxx xxxxxxx xxx xxx xxxxxxxxx xxxxx xxxxxxxxxx xxx
xxxxxx xxx xxxxxx xxxx xx xxxxx xx xxxx xxxx xxxxxxx:
„„SSH service is enabled
„„"jnpr" user account is present
„„Fxp0 interface has an IPv4 address
Xxxxxxxxx xx xxxxx xxxxxxx xxx xxxxxx xxx xxxx xx xxx xxx xxxxxxxx
xx x xxxxx xxxxxxxx, xxx xx xxx xxxxxxx xxxxxxxxxxxxx xx
xxxxxxxxxxxx xxxx xxx xxx xxxx xxx xxxxxx xxxxxx xxx xxx xxxxxxx
xxxxxxxxxxxxx? Xx xxxxx xxx xx xxxxxxxx xx xxxxxxxx xxx xxx0
xxxxxxxxx xxxxxxxxxxxxx, xxxxxxx xxx xxxxxxx xx xxxxxxxxx xxx
xxxxx xxxxxx. Xxxxx, xxxxxxxx XXX xxx xxxxxx xxx "xxxx" xxxx
xxxxxxx xxxxxx xx xxxxxxxxxxxx, xxx xxxx xxxxxx xxxxx xx xxxxxxxxx
xx xxx xxxxxx xxxxxx xxxxxxx xx xxxxxxxxx xxxxxx xxxxxxxxxxxx.
Xxx xxxxxxxxx xxxxxx xxxxxx xxxxxxxx xxx xxxxx-xxxxxx-xxxxx.xxxx
xxxxxx xxx xxxxxxxxxxxxx xxxxx xxx xxxxxxxxxxxx xxxxxxxx:
/* basic-sanity-check-and-fix.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

/* Ensure that ssh is enabled - if not then enable it */


if( jcs:empty( system/services/ssh ) ) {
<change> {
<system> {
<services> {
<ssh>;
}
}
}
<xnm:warning> {
<message> "Enabling ssh";
}
}

/* Ensure that user account jnpr exists - if not then add it */


if( jcs:empty( system/login/user[name == "jnpr"] ) ) {
<change> {
<system> {
<login> {
<user> {
<name> "jnpr";
<class> "super-user";
<authentication> {
<encrypted-password> "$1$RHL6So3y$kcOy3vb6YiWf6FAJzHi7j1";
}
}
}
}
}
<xnm:warning> {
<message> "Adding jnpr user account";
}
}

/* Verify that fxp0 has an IP address */


var $fxp0-interface = interfaces/interface[name == "fxp0"];
if( jcs:empty( $fxp0-interface/unit[name=="0"]/family/inet/address/name ) ) {
<xnm:error> {
<message> "fxp0 must have an IP address.";
}
}
}
Xxx xxxxxxxx xxxxxx xxxxx xxxxxx xxx xxx xxxx xxxxxxxx, xxx xxx
xxxx XXX xx xxx xxxxxxx xx xxx xxxx xxxxxxx xx xxxxxxx xx xxxx x
<xxxxxx> xxxxxxx xx xxx xxxxxx xxxx xxx xxxxx xxx xxxxxxx
xxxxxxxxxxxxx. Xxx <xxx:xxxxx> xxxxxxx xxx xxxx xxxxxxx xx x
<xxx:xxxxxxx> xxxxxxx xx xxxxxx xxx xxxxxxxxxx xxxx xxxx xxx xxxxxx
xxxx xxxxxxxxx xxxxxxxxxxxxx xxxxxxx.
BEST PRACTICE Include a <xnm:warning> element when making automated changes to
notify the user that the script has changed the configuration.
Xxx xxxxx xx xxx xxx0 xxxxxxxxx xxxxxxx xxx xxxx xx xxx xxxxxxxx
xxxxxx. Xx xx XXx4 xxxxxxx xx xxxxxxxxxx xxxx x <xxx:xxxxx> xxxxxxx
xx xxxxxxxxx, xxxxx xxxxx xxx xxxxxx xxx xxxxxxxx xxxxxx
xxxxxxxxxxxx. Xx xxxxx xx xxxxxxxx xx xxxxxxxx xxx xxxxxx xxxxxxx
xxxx xxx xxxxxx xxx xxx xxx xxxxxxx xxxxxxxxxxxxx, xxx xxxx xxxxx
xxxxxx xx x xxxxxxxx xxxxxx xxx xxxx Xxxxx xxxxxx. Xxxxxxxxxxxxx,
xx xxx xxx0 xxxxxxx xx xxxxxxxx xx x xxxxxxxxxxxxx xxxxxxx xxxxx xx
xxxx xxxxx xxxx xxx xxxxxx xxx xxxxxx (xxxx xx xxx xxxx-xxxx), xxxx
xx xxxxx xx xxxxxxxx xxx xxx xxxxxx xx xxxxxxxx xx xxxxxxxxxxxxx.
Xx xxx xxxx xx xxx xxxxxx xxxxx, xxxx xxxxxxxxx xxxxx xxxxxxx xx
xxxxx xxx xxxxxxxx xxx xxxx’x xxxxxxxxx xx xxx.
Try It Yourself: Automated Configuration Fixes

Identify a standard part of your configuration that should always be present. Write a commit
script that automatically adds it when missing and generates a <xnm:warning> message
informing the user of the change.

Replacing Configuration
Xxxxx xxx <xxxxxx> xxxxxxx xx xxxxxxxxxx xx xxxxx xxx xxxx xxxxxxx
xxxxxxxxxxxxx xxxxxxx. Xx xxxxxxx, xxxxxxxxxxxxx xxxxxxx xx
xxxxxx xxxx xxx xxxxxxxxxxxxx, xxx xxxxx xxx xxxxx, xxx xxxxxxxxxxx
xxxxxxxxxx xxx xxxxxxxxxx. Xxx xx xxxx xxx xxxx xxxxxxx
xxxxxxxxxxxxx xxxx xxxxxxx, xx xx xxxxxxxx xx xxxxxxxx xxxx xxx
xxxxxxxx xxxxxxxxxxxxx xxxxxx xxxxxxx xxx xxxxxxxx xxxxxxxxxxxxx,
xxxxxx xxxx xxxxxx xxxxxxx xxxx xx. Xxxx xx xxxx xx xxxxxx xxx
xxxxxxx xxxxxxxxx xx xxx xxxxxxx xxxxxxxxxxxxx xxxxxxx xxxx x xxxxx
xx "xxxxxxx".
MORE? To learn more about the load replace configuration mode command see the
CLI User Guide within the Junos documentation at
www.juniper.net/techpubs/.
Xxxxxxxx xxx xxxx xx x Xxxxx xxxxxx xxxx xxxxxx xxxxxx xxxx xxx
xxxxxx xxxxxxxx xxxx xxxxxxxxxx xx xxx xxxxxxxxx xxxxxx:
file messages {
any notice;
}
Xx xxxxx xxxxxxxxxx xxxxxx xx xxxxxxxxxx xxx xx xxxxx xxxxxx
xxxxxxx xxxxxx xx xxxxxxxx. Xx x xxxxxx xxxxxx xx xxxxxxxxxx xx
xxxxxxx xxxx xxxxxxxxxxxxx xx xxxxxxxx xxx xxxxxxxxx
xxxxxxxxxxxxx xxxxxxxxxx xxxxx xxx xxxxxxxx xxxx xxx xxxxxxx x
<xxxxxx>xxxxxxx, xxxxxxx xxxxx xxx xxxxxxx="xxxxxxx" xxxxxxxxx, xxxx
xxx xxxxxxx xxxxxx xx xxx xxxxxxxx.
Xxxx xx xxx xxxxxxx xxxxxx xxxxxx xxxxxx:
/* faulty-check-syslog-messages.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

var $messages-file = system/syslog/file[name == "messages"];


if( jcs:empty( $messages-file ) || count( $messages-file/* ) > 2 ||
jcs:empty( $messages-file/contents[ name == "any" ]/notice ) ) {

<change> {
<system> {
<syslog> {
<file> {
<name> "messages";
<contents> {
<name> "any";
<notice>;
}
}
}
}
}
<xnm:warning> {
<message> "Syslog messages file configuration corrected";
}
}
Xxx xxxxxx xxxxxxxxx xxxxxxx xx xxxxxxxxxx xxxxxxxxxx xxxxxxxx
xxxx, xxx xx xxxx xxx xxxxxx xxx xxxxxxxxxxxxx xxxxxxxxx. Xxxx xxx
xxxxxxxxx xxxxxxxxxxxxx xxx-xxxxxx:
file messages {
any any;
daemon verbose;
}
Xxx xxxxxxxxxxxxx xx xxxxxxx xx xxx xxxxxxxxx xx xxx xxxxxx xxxxxx:
file messages {
any notice;
daemon verbose;
}
Xxx xxx xxxxxxxx xx xxxxxxxxx xxxxxxx xx xxx xxx xxxxxx xxxxxxxx,
xxx xxx xxxxxx xxxxxxxx xx xxx xxxxxxx. Xxxx xx xxxxxxx xxx xxxxxx
xxx xxxxxx xxxx xxx xxxxxxxx xxxxxxxxxxxxx; xx xxx xxx xxxxxxx xx.
Xx xxx xxxxxxxx xxxxxxxxxxxxx xxxxxxxxxx xxxx xxxx xxx xxxxxxxxxx
xx xxxxxx xxxxxxxxxx xxxxxx.
Xx xxxxx xx xxxxxxx xxx xxxxxxxx xxxx xxxxxxxx xxxxxxxxx, xxx
xxxxxxx xxxxxxxxx xx xxxxx xxxx x xxxxx xx "xxxxxxx". Xxxx xx xxx
xxxxxxx xxxxxx xxxxxx:
/* check-syslog-messages.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

var $messages-file = system/syslog/file[name == "messages"];


if( jcs:empty( $messages-file ) || count( $messages-file/* ) > 2 ||
jcs:empty( $messages-file/contents[ name == "any" ]/notice ) ) {

<change> {
<system> {
<syslog> {
<file replace="replace"> {
<name> "messages";
<contents> {
<name> "any";
<notice>;
}
}
}
}
}
<xnm:warning> {
<message> "Syslog messages file configuration corrected";
}
}
}
Xxxxxxx xxx xxxxxxx xxxxxxxxx xx x xxxxxxxxxxxxx xxxxxxx xxxxxx
xxxx xxxxxxx xxx xxx xxx xxxxxxxxxxx xx xx xxxxxxxx xxxxxx xxx
xxxxxxxxxxxxx xx xxx xxx xxxxxxxxxxxxx. Xx xxx xxxxxxxx xxxx
xxxxxxxxxxxxx xx xxx xxxxxxxxx xxxxx xx xxx xxxxxx:
file messages {
any any;
daemon verbose;
}
Xx xxxxxxx xxx xxxxxxxxx xxxxx xxx xxxxxx xxxxxx xxx xxxxxxxx xxx
xxxxxxxx xxxx xxxxxxxx xxxxxxxxx:
file messages {
any notice;
}

Try It Yourself: Replacing Configuration Hierarchies

Create a commit script that enforces the requirement that the ospf configuration should
consist solely of an assignment of all interfaces into area 0.

jcs:emit-change
Xx xxx xxxxx xxxxxxx xxxxxxxxx, xxx <xxxxxx> xxxxxxx xxxx xxxxxxx
xxx xxxxxxxx xxxxxxxxx xx xxx xxxxxxxxxxxxx xxxxxxxxx. Xxx
xxxxxxx xxxx xxx xxxx xxx xxxxx xxxx xxxx xx xxx xx xxxxx, xxx xx xxx
xxxxxx xxxxxxxx xxxx xxx xxxxxx xx xxxx xxxxxx x xxxxxxxxx.
Xxxxxxxx xxx xxxxxx xxxxxxxx xx xxx xx xxxxxxx xxxxxxxx xxxxxx xx
xxx xxxxxxxx xxxxxxxxx:
<change> {
<interfaces> {
<interface> {
<name> "lo0";
<unit> {
<name> "0";
<family> {
<inet> {
<filter> {
<input> {
<filter-name> "ingress";
}
}
}
}
}
}
}
}
Xxx xxxxxxxxx xx xxxx xxxxxxxxxxxxx xxxxxxx xxx xx xxxxx xx
xxxxxxx xx xxxxx xxx xxx:xxxx-xxxxxx xxxxxxxx, xxxxxx xxxx xx xxxxxxxx
xxxxxxxx <xxxxxx> xxxxxxxx xxxx xxx xxxx xxxxxx xxxxxxxxx. Xxx
xxx:xxxx-xxxxxx xxxxxxxx xxxxxxx x <xxxxxx> xxxxxxx xxxxxx xxxxx xx
xxxxxx xxx xxxxxxxxx xx xxx xxxxxxx xxxx xxx xxxx xxxxxxxx xxx
xxxxxxxxx xxxxxx xx xxxx xxxxxxxxx xxxxx. Xxxxxxx xx xxx xxx:xxxx-
xxxx xxx xxx:xxxxxxxxx xxxxxxxxx xxx xxx:xxxx-xxxxxx xxxxxxxx xxxx xxx
xxxxxxx xxxxxxx xxxx, xx xxxxxx xx xxxxxxxxx xxxx xx xx xxxxxxxxx
xxxxxxx xxx $xxx xxxxxxxxx. Xxx $xxxxxxx xxxxxxxxx xx xxxxxxxx xxx
xxxxxxxx xxx xxxxxx xxxx xxxxxx xx xxxxxxx xx xxx xxxxxxx xxxx
xxxxxxxxx. Xxx xxxxx xxxxxxxxx xxxx xxx xx xxxx xx xxx $xxx
xxxxxxxxx xxxxx xxxxxx xxx xxxxxxx <xxxxxx> xxxxxxx xx xx
xxxxxxxxxxx xxxx x <xxxxxxxxx-xxxxxx> . Xxxxxxxxx xxxxxxx xxx
xxxxxxxxx xx xxx xxx xx xxxx xxxxxxx.
Xxxxxxxx xxx xxxxxxxxx xxxxxx xxxx xxxx xxx xxx:xxxx-xxxxxx xxxxxxxx
xx xxxxxx x xxxxxxxx xxxxxx xx xxx xx0 xxxxxxxxx:
/* add-loopback-filter.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

var $lo0-interface = interfaces/interface[name=="lo0"]/unit[name=="0"];


if( jcs:empty( $lo0-interface/family/inet/filter/input[filter-name == "in"] ) ) {
/* Create the change */
var $change = {
<filter> {
<input> {
<filter-name> "in";
}
}
}
call jcs:emit-change( $dot = $lo0-interface/family/inet, $content = $change );
<xnm:warning> {
<message> "Adding lo0 input filter.";
}
}
}

Xxx xxx-xxxxxxxx-xxxxxx.xxxx xxxxxx xxxxxxx xx xxxxx xxxxxxxx


xxxxxx xxx xx0.0 xx xxx xxxxxxx xxxxxxxx. Xxx xxxx xxxxx xxxxxxxxx
xx xxx $xxx xxxxxxxxx xx xxxxxxxx xxx xxxxxx xx xxxxxxxxx xxxx xxxx
xx xxxxxxxx xxxxxx xxx xxxxxxxxxxxxx xxxxxx. Xxxxxxx xxx $xxx xx
xxx xx xxx xxxxxx xxxx xxxxx, xxx xxxx xxxxxx xxx xx xxxxxxx xxx
xxxx xxxxxxxxx xxx xxx xxxxx xxxx x xxxxxxxxx xx xxx <xxxxxx>
xxxxxxx. Xxxx xxx $xxx xxxxxxxxx xxx, xxx xxx $xxxxxxx xxxxxxxxx
xxxxxxxx xx xxx xxxxxxxxxxxxx xxxxxx, xxx xxx:xxxx-xxxxxx xxxxxxxx xxx
xxxxxx xxx xxxxxxxxx <xxxxxx> xxxxxxx xxxx xxx xxxxxx xxxxxxxxxxxxx
xxxxxxxxx xxx xxx xxxxxxx xxxxxx.
ALERT! The $dot parameter must refer to an existing node within the
configuration. With the above script, if the lo0 interface is not currently
configured, or lacks a unit 0 with family inet, then the jcs:emit-change
template generates a commit error:
error: jcs:emit-change called with invalid location (dot)

Xxx xxx-xxxxxxxx-xxxxxx.xxxx xxxxxx xxxxxxxx xxxxxxx x <xxx:xxxxxxx>


xxxxxxx xx xxxxxxxx xxxx xxx xxxxxxxxxxxxx xxx xxxx xxxxxxx, xxx
xxxx xx xxx xxxxxxxxx xxxx xxxxx xxx xxx:xxxx-xxxxxx xxxxxxxx. Xxx
xxxxxxxx xxx x $xxxxxxx xxxxxxxxx xxxx xxx xxxxxxxxxxxxx xxxxxx x
<xxx:xxxxxxx> xxxxxxx xx xxxxxxx xx xxx xxxxxxxxxx xxxx. Xxx
xxxxxxxxx xxxxx xx xxxx:
call jcs:emit-change( $dot = $lo0-interface/family/inet, $content = $change );
<xnm:warning> {
<message> "Adding lo0 input filter.";
}
Could have been written instead as:

var $message = "Adding lo0 input filter.";


call jcs:emit-change($dot = $lo0-interface/family/inet, $content = $change, $message);
Try It Yourself: Family MPLS on LDP Interfaces

Create a commit script that calls the jcs:emit-change template to add family mpls to every
interface, configured under [edit protocols ldp], that lacks it.
Deleting
Xx xxxx xxxxx, xxx xxxxxxx xx xxx, xxxx, xxx xxxxxxx xxxxxxxxxxxxx
xxx xxxx xxxxxxxxxxxx, xxx xx xx xxxx xxxxxxxx xx xxxxxx
xxxxxxxxxxxxx xxxxxxxxxx xx xxxx xx xxxxxxxx xxxxxxxxxxxxx
xxxxxxxxxxx. Xxxx xxxxxx xx xxxxxxxxxxxx xx xxxxxxxxx xxx xxxxxx
xxxxxxxxx xx xxx xxxxxxxxxxxxx xxxxxxx xxxx xxxxxx xx xxxxxxx
xxxxxx xxx <xxxxxx> xxxxxxx, xxx xxxxxxx xxx xxxxxxxxx’x xxxxx xx
"xxxxxx".

Xxx xxxxxxx, x xxxxxxxxxx xxxx-xxxx xxxxx xx xxxxxxx xx xxxxx xxxx


<xxxxxx> xxxxxxx:
<change> {
<system> {
<time-zone delete="delete">;
}
}

Xxx xxxxxx xxxxxxxxx xxx xxxx xxxxxx xxxxxxxx xxxxxxxxxxxxx


xxxxxxxxxxx. Xxxx xxxxxxx xxxxxxx xxx [xxxx xxxxxxxxx xxxx xxxxxxxxxxxx]
xxxxxxxxxxxxx xxxxxxxxx:
<change> {
<protocols> {
<ospf> {
<traceoptions delete="delete">;
}
}
}
Xxxxxxxxxxxxx xxxxxxxxxxx xxxx xxxxxxxxxxx xxx xx xxxxxxx xx
xxxxxxxxx xxx xxxxxx xxxxxxxxx xx xxx xxxxxxxxxxxxx xxxxxxx xxx
xxxx xxxxxxxxx xxx xxxxxxxxxx xxxxxxx xx x xxxxx xxxxxxx
(xxxxxxxxx <xxxx>). Xxxx <xxxxxx> xxxxxxx xxxxxxx xxx xx-0/0/0
xxxxxxxxx xxxx xxx xxxxxxxxxxxxx. Xxx xxxxxx xxxxxxxxxxxxx
xxxxxxx xx <xxxxxxxxx>, xxx xxx xxxxx xxxxxxx <xxxx> xxxxxxxxxx xxx
xxxxxxxx xxxxxxxxx xxxxxxxxxxxxx xx xxxxxx:
<change> {
<interfaces> {
<interface delete="delete"> {
<name> "ge-0/0/0";
}
}
}
Xxxx xxxxxxxxxxxxx xxxxxxxxxx xxx xxxx xxxxxxxx xxxxxx. Xx xxxxxx
x xxxxxx xxxxx xxxx x xxxxxxxx-xxxxx xxxxxxxxx, xxxxxxx xxx xxxxxx
xxxxxxxxx xxx xxx xxxxxxxxx’x xxxxxxxxxxxxx xxxxxxx xxx xxxx
xxxxxxx xxx xxxxxxxxx’x xxxxx. Xxx xxxxxxx, xxxxx xxxxxxx xxx
xxxxxx xxxxxxxx xxxxxxxxxx xxxx. Xxx xxxxxxxxx <xxxxxx> xxxxxxx
xxxxxxx xxxx xxx "xxx" xxxxxxxxxx xxx xxxx xxx "xxxxx" xxxxx xxxxx:
<change> {
<system> {
<login> {
<class> {
<name> "admin";
<permissions delete="delete"> "all";
}
}
}
}

Xxx xxxxxxxxx xxxxxxx xxxxx xxx xxxx-xxx0-xxxxxxxx.xxxx xxxxxx.


Xxxx xxxxxx xxxxxx xxxxxxx xxxx xxx xxx0 xxxxxxxxx xx xxxxxxxx
xxxxx xxxx 0 xx x xxxxxxxx xxxxxxxxx xxx xxx xxxxx xxx xxxxx xxxxx:
/* ospf-fxp0-disabled.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";
match configuration {

/* Loop through all ospf areas */


for-each( protocols/ospf/area ) {

/* Area 0, verify that fxp0 is disabled */


if( name == "0.0.0.0" && jcs:empty( interface[name=="fxp0.0"]/disable ) ) {
/* Add the statement since it's missing */
var $content = {
<interface> {
<name> "fxp0.0";
<disable>;
}
}
var $message = "Adding fxp0.0 disable";
call jcs:emit-change( $content, $message );

}
/* All other areas, fxp0 not allowed */
else if( name != "0.0.0.0" && interface[name=="fxp0.0"] ){
var $content = {
<interface delete="delete"> {
<name> "fxp0.0";
}
}
var $message = "Removing fxp0.0";
call jcs:emit-change( $content, $message);
}
}
}
Xxx xxxxxx xxxxxx xxxxx xxxxxxx xxx xxx xxxx xxxxx. Xx xxx xxxxxxx
xxxx xx 0.0.0.0 xxxx xxx xxxxxx xxxxxx xx xxx0 xx xxxxxxxx xx x
xxxxxxxx xxxxxxxxx. Xx xx xx xxx xxxxxxx xx xxxxxxxx xxxx, xxxx xxx
xxx:xxxx-xxxxxx xxxxxxxx xx xxxx xx xxxxxxxx xxx xxxxxx <xxxxxx>
xxxxxxx xx xxx xxx xxxxxxx xxxxxxxxxxxxx. Xx $xxx xxxxx xx xx xxx
xxxxxxx xxx xxxxxxx xxxx xx xxx xxxx xxxx xxx xxx $xxxxxxx xxxxxx xx
xxxxxxxx xxx xxxx xxxxxxxxx xxxxx.
Xxx xxxxx xxxxx, xxx xxxxxx xxxxxx xxxxxx xx xxx0 xx xxxxxxxxxx, xxx
xx xx xx xxx xxxxxx xxxx xxx:xxxx-xxxxxx xx xxxxxx x <xxxxxx> xxxxxxx
xxxx xxxxxxx xx.
Xxxxxx xxx xxxxxxxxxxxxx xxxxx xx xxxxxx xx xxx xxxxxxxxx:
[edit]
jnpr@host1# show protocols ospf
area 0.0.0.0 {
interface lo0.0;
interface ge-0/0/0.0;
}
area 0.0.0.1 {
interface ge-0/0/1.0;
interface fxp0.0;
}
Xxx xxxxxxxxx xxxxxxx xxxxxxxx xxx xxxxxxxxx xx xxx xxxxxxxxxx
xxxx:
[edit]
jnpr@host1# commit
[edit protocols ospf area 0.0.0.0]
warning: Adding fxp0.0 disable
[edit protocols ospf area 0.0.0.1]
warning: Removing fxp0.0
commit complete
Xxx xxx xxxx xxxxxxxxxxxxx xx xxxxxxxxxxxx xxxxxxx:
[edit]
jnpr@host1# show protocols ospf
area 0.0.0.0 {
interface lo0.0;
interface ge-0/0/0.0;
interface fxp0.0 {
disable;
}
}
area 0.0.0.1 {
interface ge-0/0/1.0;
}
NOTE As the output example above shows, using the $message parameter of
jcs:emit-change to display a warning message automatically includes an
<edit-path> with the context node used as the hierarchy level. This is why
[edit protocols ospf area 0.0.0.0] and [edit protocols ospf area 0.0.0.1] are included in
the output.
Try It Yourself: Deleting Invalid Name-servers

Create a commit script for an organization whose name-servers all fall within the 10.0.1.0/24
subnet. Delete any configured name-servers from outside that subnet.

Activating/Deactivating
X xxxxxx xxxxxx xxx xxxxxxxx xx xxxxxxxxxx xxxxxxxxxxxxx xx
xxxxxxxxx x xxxxxxx xxxxxx xx xxxxxxxx. Xx xxxxxxxx xxxxxxxxxxxxx,
xxx xxx xxxxxx xxxxxxxxx xxxx x xxxxx xx "xxxxxx". Xx xxxxxxxxxx
xxxxxxxxxxxxx, xxx xxx xxxxxxxx xxxxxxxxx xxxx x xxxxx xx "xxxxxxxx".
Xxx xxxx xxxxxxxx xx xxxx xxx xxxx xxxx xx xxxxxxxxxxxxx xxxxxxx
xxxx xxx xxxxxx xxxxxxxxx. Xxx xxxxxxx, xx xxxxxxxxxx xxx [xxxx xxxx]
xxxxxxxxx, xxx xxx xxxxxxxxx <xxxxxx> xxxxxxx:
<change> {
<snmp inactive="inactive">;
}
Xx, xx xxxxxxxx xxx "xxxx" xxxx xxxxxxx, xxx xxxxxxxxx <xxxxxx>
xxxxxxx xxx xx xxxx:
<change> {
<system> {
<login> {
<user active="active"> {
<name> "jnpr";
}
}
}
}

Deactivating
Xxxxxxxxxxxx xxxxxxxx xxxxxxxxxxxxx xx xx xxxxxxxxxxx xx
xxxxxxxxxx x <xxx:xxxxx> xxx xxxxxxxxx xxx xxxxxx xxxxxx xxxxxxx.
Xxxxxx xxx xxxxx-xxxx-xxxxx.xxxx xxxxxx xxxx Xxxxxxx 10 xxxx
xxxxxxxxx xx xxxxx xx xxx XXXX xxxxx xxxxxx x xxxxxx-xxxxx. Xxx
xxxxxxxxx xxxxxx xxxxxx xxxxx x xxxxxxxxx xxxxxxxx, xxxxxxx xx
xxxxxxx xxx xxxxxx xx xxxxxxxxxxx xxx xxxxxxx XXXX xxxx xxx
xxxxxxxxx x xxxxxxx xxxxxxx. Xxx xxxx xx xxx xxxxxxx xx xx xxxxxx
xxxxx xxx xxxxxx-xxxxx xx xxx xx xxxxx, xxx xxxx xxxxxxx xxxx xxx
xxxxxxx xxxxx xxxxxxxxxxxxx xxxxxxx xxxx xxxxxx xxxxxx.
/* deactivate-ebgp-peers.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

/* Retrieve AS Number */
var $asn = routing-options/autonomous-system/as-number;

/* Scroll through all EBGP peers */


for-each( protocols/bgp/group[ peer-as != $asn ]/neighbor ) {

if( jcs:empty( family/inet/unicast/prefix-limit/maximum ) &&


jcs:empty( ../family/inet/unicast/prefix-limit/maximum ) ) {
var $content = {
<neighbor inactive="inactive"> {
<name> name;
}
}
var $message = "EBGP peer is missing prefix limit. Deactivating.";
call jcs:emit-change( $dot = .., $content, $message );
}
}
}
Xxx XXXX xxxxxxxx xx xxxxxxxxxxx xx xxxxxxx xxx xxxxxxxx xxxxxxxxx
xx "xxxxxxxx" xxx xxx xxxxxxxx xxxxxxx xxx xxxxxxxxx xxx <xxxx>
xxxxxxxxxx xxxxxxx. Xxx $xxx xxxxxxxxx xxx xxx:xxxx-xxxxxx xx xxx xx
xxxxx xxx xxxxxxxxxxxxx xxxxxx xx xx xxxxx xx xxx xxxxxx XXX xxxxx
xxxxxxxxx xxxxxx xxxx xxx xxxxxxx <xxxxxxxx> xxxxxxx xxxx. X
xxxxxxx xx xxxxxxxx xx xxx xxx:xxxx-xxxxxx xxxxxxxx xx xxx xxxxxxxxxx
xxxx xxxx x xxxxxxx xxxxxxx xx xxx xxxxxxxxx:
[edit]
jnpr@jhost1# commit
[edit protocols bgp group EBGP neighbor 10.0.0.2]
warning: EBGP peer is missing prefix limit. Deactivating.
commit complete

Activating
Xxxxxxxxxx xxxxxxxxxxxxx xx xxxx xx xxx xxxx xxx xx xxxxxxxxxxxx
xxxxxxxxxxxxx, xxxxxx xxxx xxx xxxxxx xxxxxxxxx xx xxxxx, xxxxxx
xxxx xxx xxxxxxxx xxxxxxxxx, xxx xxx xxxxx xx xxx xx "xxxxxx". Xxx
xxxxxxxxx xxxx xx xxxx xxxxxxx xx xxxxxxx xxxxxxx xx xxx xxx
xxxxxxxxxxxxx xxxxx xx xx xxxxxxxxx, xxxxxxx xxxxxxxx
xxxxxxxxxxxxx xx xxx xxxxxxx xxxxxx xxx xxxx-xxxxxxxxxxx
xxxxxxxxxxxxx xxxxxxxx xx xxx xxxxxx xxxxxx.
Xx xx xxxxxxxx xx xxxxxxxx xxx xxxxxxxxxxxxx, xxxxxxxxx xxxxxxxx
xxxxxxxxxx, xx xxxxx xxx <xxx-xxxxxxxxxxxxx> Xxxxx XXX xxxxxxx, xxxxx
xxxxxxx xxx xxx-xxxxxxxxxxx xxxxxxxxx xxxxxxxxxxxxx xx xxxxxxx.
Xxx xxxxxxxx xxxxxxxx xxxxxx xxxx xxxxxxxxxxxxx xxxx xx xxxxxxxx
xxxxxxxxx xxxx x xxxxx xx "xxxxxxxx".
Xxx xxxxxxxxx xxxxx xx xxxxxxx xx x xxxxxx xxxxxx xxxx xxxxxxxxx
xxx xxxxxxxxx xxxxxxxxxxxxx xx xxxxxx xx xxx xxxxxxxxxx-xxxxxx xx
xxxxxxxxxxx, xxx xx xx xx xxxxxxxx xxx xxxxxx xxxxxxxxx xxx
xxxxxxxxx <xxxxxx> xxxxxxx xx xxxxxxxx xx:
/* activate-asn.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

/* Retrieve the current configuration, when doing this be aware of PR 452398 */


var $configuration = jcs:invoke( "get-configuration" );

if( $configuration/routing-options/autonomous-system[@inactive] ) {
<change> {
<routing-options> {
<autonomous-system active="active">;
}
}
<xnm:warning> {
<message> "Activating ASN configuration.";
}
}
}

ALERT! Do not use the <get-configuration> API element within a commit script prior
to the following releases: 9.3S5, 9.4R4, 9.5R3, 9.6R2, or 10.0R1, as it can
cause the Junos device to hang while booting. For further details refer to
PR 452398.

Reordering
Xxxxx xxx xxxxx xx xxxx xxxxxxxxxxxxx xxxxxxxxxx xx xxxxxxxxxxx,
xxxx xxxxx xx xxx xxxxxxxxxxxxx, xxxx xx xxxxxxxx xxxxx, xxx
xxxxxxxxx xxxxxxxxxxxx xxx xxxx xx xx xxx xxxxxx xxxxx. Xxxxxx
xxxx xxx xxxxxxxxx xxxxxxx-xxxxxx xxx xxxx xxxxxxxxxx:
policy-statement accept-ospf {
term reject {
then reject;
}
term ospf {
from protocol ospf;
then accept;
}
}
Xxx xxxxxxxxx xx xxx xxxxxx xx xx xxxxx XXXX xxxxxx xxx xxxxxx xxx
xxxxxx, xxx xxx xxxxxx xxxx xxxxx xxxxxx xxx xxxxxx xx xx xxxxxxxx.
Xx xxxxxxx xxxx xxx xxxx xxxx xxxx xx xxxxxxxx xxxxx xx xxx xxxxxx
xxxx. Xx xxxxxxxxxxxxx xxxx xxx xxxxxxxxx xxxxxxx xxx xx xxxx:
[edit policy-options policy-statement accept-ospf]
jnpr@host1# insert term ospf before term reject
Xxxxxxxxx xxxx xxxxxxx, xxx xxxxxx xxx xxxxx:
policy-statement accept-ospf {
term ospf {
from protocol ospf;
then accept;
}
term reject {
then reject;
}
}
Xxxxxx xxxxxxx xxx xxxx xxxxxxx xx xxxxxx xxxxxxxx xxxxxx xx xxxxx
xxxxx xxxxxxxx xxxxxx xxx xxxxxxxxxxxxx. Xx xxxx xxxxxxxxxxxxx
xxxxxxxxxxx, xxxx xx xxx xxxxxxxxx xxxxxx xxxxx, xxx xxx xxxxxxxxx
xxxxxx:
<element insert="after | before" identifier-element="reference-element-name"> {
<identifier-element> "moving-element-name";
}
Xxx xxxxxxxxxxxxx xxxxxxx xx xxxxxxxxxx xx xxxxxxxxx xxx xxxxxx
xxxxxxxxxxx xxxxxxx (xxxxxxxxx xxxxxx xxxx):
<term> {
<name> "ospf";
}
Xxx xxxxxx xxxxxxxxxxx xxxx xx xxxxxxxx xxxx xx xxxxxxxxx xxxxx xx
xx xxxxxxxxx, xxx xxx xxxxxxxxx xx xxx xx "xxxxxx" xx "xxxxx" xx xxxx
xxxxx xx xxxxxx xx xxxxxx xx xxxxxxxxx xx xxx xxxxx xxxxxxx.
<term insert="before"> {
<name> "ospf";
}
Xxxxxxx, xxx xxxxxxxxx xxxxxxx xx xxxxxxxxxx xx xxxxxxxxx xxx
xxxxxxxxxx xxxxxxx xxxx xx xx xxxxxxxxx (xx xxx xxxxx xxxxxxx, xxxx
xx "xxxx") xxxx xxx xxxxxxxxx xxxxxxx’x xxxxx:
<term insert="before" name="reject"> {
<name> "ospf";
}
Xxx xxxx <xxxxxx> xxxxxxx xx xxxxxxxxxx xxxx xx xxx xxxxxxxxx:
<change> {
<policy-options> {
<policy-statement> {
<name> "accept-ospf";
<term insert="before" name="reject"> {
<name> "ospf";
}
}
}
}
Xxxxxxxxxx xxxxx xxxxxxxx xxxxxx xxx x xxxxxx xxxxxxxxxxxxx
xxxxxxxxx xxxxxxx xxxxxxxx xxxx xxx xxxxx xxxxxxxx xxxxxxx xxx
xxxxxxx xxxxxxxx xxxx xx xxxxxxxxxxx xxxxx xxxxxxxx, xxx xxxxxxx
xxxxxx xxxx xx xxxxx xxxxxxxx xxxxxx. Xx xxxx xxxx, xxx xxxxxx xxxx
xx xxx xxxxxxxxx:
<element insert="after | before" name="reference-value"> "moving-value";
Xxxxxxxx xxx xxxxxxx xxxxxx-xxxxx xxxx-xxxx:
<routing-options> {
<static> {
<route> {
<name> "192.168.1.0/24";
<next-hop> "10.0.0.1";
<next-hop> "10.0.0.2";
}
}
}
Xx xxxxx xxx 10.0.0.2 xxxx-xxx xx xx xxxxx xx xxxxx xx xxx 10.0.0.1
xxxx-xxx xxx xxxxxxxxx xxxx xxx xx xxxx:
<change> {
<routing-options> {
<static> {
<route> {
<name> "192.168.1.0/24";
<next-hop insert="before" name="10.0.0.1"> "10.0.0.2";
}
}
}
}

MORE? For more information on reordering configuration elements see the


Junoscript API Guide within the Junos documentation at
www.juniper.net/techpubs/.
Xxx xxxxxx xxxxxx xx xxxxxxx xx xx x xxxxxx xxxxxx xx xxxxxx
xxxxxxxx xxxxx, xxxxxx xxxxx, xx xxxxx xxxxxxxxxxxxx xxxxxxxx xxxx
xxxx xxxx xx xxxxxx xxxxxx xxxxx xxxxxx xxxxx. Xxxxxx xxx xxxxxx
xxxxxx xxxxxxxxx xx xxxxx xxxxxxxx, xxx xxx xxxxxxxx xxx xxxxxxxx
xx xxx xxxxxxxx xxxxxxx. Xx xxxx xxxxx xxxx xxxxxxxxx xx xxxxxxxxx
xxx xxxx xx xxxxx xxxxxxx xxxxxx xxxxxxxxxx. Xxx xxxxxxx, xxx
xxxxxxxxx xxxxxx xxxx x "xxxxx-xxxxxxx-xxxxxx" xxxxxx xx xxx XXXX xxxxx
xxxx xxxx xx, xxx xxxxxxx xxxx xxx xxxxx xxxxxx xx xxxxxx xx xxx
xxxxxxxxx xx xxx xxxxxx xxxxxx xxxxx.
/* add-block-privates.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

/* Retrieve AS Number */
var $asn = routing-options/autonomous-system/as-number;

/* Scroll through all EBGP groups */


for-each( protocols/bgp/group[ peer-as != $asn ] ) {
if( jcs:empty( import[1][. == "block-private-ranges" ] ) ) {
var $content = {
/* Add and insert at beginning */
if( count( import ) > 0 ) {
var $current-first = import[1];
<import insert="before" name=$current-first> "block-private-ranges";
}
/* Just add */
else {
<import> "block-private-ranges";
}
}
var $message = "Adding block-private-ranges import policy.";
call jcs:emit-change( $content, $message );
}
}
}
Xxx xxx-xxxxx-xxxxxxx-xxxxxx.xxxx xxxxxx xxxxxxxx xxxxxxx xxxxx
XXXX xxxxx xxx xxxxxxxx xxxx xxx "xxxxx-xxxxxxx-xxxxxx" xxxxxx xx
xxxxxxx xx xxx xxxxx xxxxxx. Xx xxx xxxx xx xxxx xxx xxxxxx, xxx xx
xxxxx xxxxxxxx xxx xxxxxxx xx xxxxxxxx xxx xxxxxx xx xxx xxxx xxxx.
Try It Yourself: Reorder Firewall Terms
Create a commit script that adds a term to a firewall filter, if missing, and then inserts it at the
beginning of the filter.

Renaming
Xxx xxxxx xxxx xx xxxxxxxxxxxxx xxxxxx xx xxxxxxxx. Xxxx xxxxxx xx
xxx xxxx xxxxxx xxxxxxxxx xx xxxxx xxx xxxxxx xxxxxxx xx
xxxxxxxxxxxxx xxxx:
[edit protocols bgp]
jnpr@host1# rename group AS65535 to group AS65495
Xx xxxxxx xx xxxxxxx, xxx xxx xxxxxx xxxxxxxxx xxxx xxx xxxxxxxxx
xxxxxx:
<element rename="rename" name="new name"> {
<identifier-element> "old name";
}
Xxx xxxxxxx, xxxxxxxx x XXX xxxxx xxxxx xx xxxx xxxx xxxx:
<change> {
<protocols> {
<bgp> {
<group rename="rename" name="AS65495"> {
<name> "AS65535";
}
}
}
}
Xxx xxxxx xxxx xxxxxxx xxx xxxxxxxx XXX xxxxx XX65535 xx x xxx
xxxx xx XX65495.
Xxx xxxxxxxxx xxxxxx xxxxx xxx xxxxxxxxxxx xx xxx xxxxxx xxxxxx
xxxxxxxx xxxxxxxxxx. Xxx xxxxxx xxxxxx xxxxxxx-xx-xxxxxxx.xxxx xx
xxxxxxxx xx xxxxxxx x xxxxxxxxxxxx xxxxxxxxxxxx’x xxxxxx xxxx xxx
xxxxxx-xxxxx xxx xxxxxxx xxxxxx xxxx xxxxxxxxxxx xxxxxx xxxxx
xxxxx.
/* convert-to-hyphens.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

/* Loop through all prefix-lists */


for-each( policy-options/prefix-list ) {

/* Do they have an underscore in their name? */


if( contains( name, "_" ) ) {

/* Translate _ to - */
var $new-name = translate( name, "_", "-" );
var $content = {
<prefix-list rename="rename" name=$new-name> {
<name> name;
}
}
var $message = "Translating _ to -";
call jcs:emit-change( $dot=.., $content, $message );
}
}
}

Xxxx xxxxxxx xxxxxxxxxxxxx:


[edit policy-options]
jnpr@host1# show
prefix-list CUST_A {
10.0.0.0/24;
10.0.1.0/24;
}
prefix-list CUST_B {
192.168.100.0/24;
192.168.200.0/24;
}
Xxxxxxx xx xxx xxxxxxxxx xxxxxxx xxxxxxxx xx xxxxxx:
[edit]
jnpr@jhost1# commit
[edit policy-options prefix-list CUST_A]
warning: Translating _ to -
[edit policy-options prefix-list CUST_B]
warning: Translating _ to -
commit complete
Xxx xxx xxxxxxxxxxxxx xx xxxxxxx:
[edit policy-options]
jnpr@host1# show
prefix-list CUST-A {
10.0.0.0/24;
10.0.1.0/24;
}
prefix-list CUST-B {
192.168.100.0/24;
192.168.200.0/24;
}
Xxx xxxxxxx-xx-xxxxxxx.xxxx xxxxxx xxxxxx xxxxx xx xxxxxxx xxxxxxx
xxx xxxxxx-xxxxx xxx xxxxxxxxx xxx xxxxx xxxx xxxxxxx xxxxxxxxxxx.
Xxxxx xxxx xxxxxxx xxx xxxxxxxxx xxxxxxx xxx xxxxxxxxx() xxxxxxxx
xxxx xxxxxxxxxx xx xxxxxx xxx xxxx xxx xxx:xxxx-xxxxxx xxxxxxxx xx
xxxx xx xxxxxxxx x<xxxxxx> xxxxxxx xxxx xxx xxxxxxxxxxx xxxxxxxx
xxxxxxxxxxxx.
Xxxxxxx, xxxx xxxxxx xx xxxxxx xx xxxx xxxxx xxx xxxxxx-xxxxx xxx
xxxxxxx, xxxxx xxxxxxxxxx xx xxxxxx-xxxxxxxxxx xxx xxxxxxxx
xxxxxxx xxx xxx xxxxxxx. Xxxxxxx xxxxxxxxxx, xxxx xxxxxxx xx x
xxxxxx xxxxx xxxx xxx xxxxxxxxxx xxxxxx-xxxx xx xxx xxxxx xxxxxx
xxx xxxxxx xxxxxxx. Xxx xxxxxxxxx Xxx xx Xxxxxxxx xxxxxxx xxxxxxxx
xxxx xxxxx. Xxx Xxxxxxxx xxx xx xxxxxxxxx xx xxx xxx xxxxxxxx xx xxx
xxxxxxxx.
Try It Yourself: Modify Convert-to-hyphens.slax

Xxxxxx xxx xxxxxxx-xx-xxxxxxx.xxxx xxxxxx xxxxxx. Xxxxx xxxx


xxxxxxxx xxx xxxxxx-xxxx, xxx xxxxxxxxxx xx xxx xxxxxx-xxxx xx
xxxxxx-xxxxxxxxxx xxx xxxxxxxx xxxxxxx xxxxxx xxxx xx xxx xx xxx
xxx xxxx.

Transient Changes
Xx xx xxxx xxxxx xxxx xxxxxxxxxx xxxxxxxxxxxxx xxxxxxx xxxx xxxx
xxxxxxxxx. Xxxxxxxxxx xxxxxxx xxx xxxx xxxxx xxx <xxxxxx> xxxxxx
xxxx xxxxxxx. Xxxx xxxxxxxx xxxxxx xxx xxxxxxxxx xxxxxxxxxxxxx,
xxx xxx xxxxxxxx xxxxxx xxx xxxxxx xxxxxxxxxxxxx xxxx xxxx xxxxxx
xxxxxxxxxxxxx xxxxxxx.
Xxxxxxx, xx xxxxxxxx xx xxxxxxxxxx xxxxxxx xxxxxx xxxxxxx xxxx
xxxx xxx xxxxxxx xx xxxxxxx xxxxxxxxx xxxxxxx, xxxxx xxx xxxxxxx
xxxx xxxxxx xxx xxxxxxxx xxxxxxxxxxxxx xxxxxxx xx xxx Xxxxx
xxxxxxx xxx xxxxx xxxx xx xx xxx xxxxxx xxxxxxxxxxxxx xxxx.
Xxxxxxxxx xxxxxxx xxxx xxx xxxxxxxxx xxxxxxxxxxxxxxx:
„„Created by the <transient-change> result tree element.
„„Require allow-transients to be configured under [edit system scripts commit].

„„Do not affect the candidate configuration, only affect the checkout
configuration.
„„Do not appear in the committed configuration file.
„„Recreated by commit scripts during each commit. To remove a
transient change, remove the commit script.
Xx xxxxxxx, x xxxxxxxxx xxxxxx xx x xxxxxxxxxxxxx xxxxxx xxxx xx
xxxx xxxxxxx xx Xxxxx, xxx xx xxx xxxxx. Xxxxxxxxx xxxxxxx xxx xxxx
xxxxxxxxx xx xxxxxxxxxxx xxxx xxxxxxxxxxxxx xxxxxx, xx xxxxxxxxx
xx Xxxxxxx 12, xxx xxx xxxx xxxxxx xx xxxxx xxx xxxxx xxxxxxxxxxxxx
xxxxxxxxxx xxxx xxxxxx xx xxxxxx xxxx xxx xxxxxxxxxxxxx xxxx. Xx
xxxxxxx xx xxxx xxxxx xx xxxxx xxxx xxxxxxxxxxxxxx xxxx.
Xxxxxxxx xxx xxxxxxxxx xxxx xxxxxxx xxxxxxxxxxxxx:
user jnpr {
uid 2000;
class super-user;
authentication {
ssh-dsa "ssh-dss
XxXXXxX5XXXxXxXXxXXX4XXXxxX2xxxxXxXXxXxxxxxXXxXxxxXxXX7X1XXxxxX+XxXx35x
xX4xxXXxxXxxXxxxxX4XXxx8xx5XXxXx/xXxXXXxxxXXXXXxxXxX5Xx5+xxX1x3x9x0XxX7+
Xx6xxxxXxXX6X9xXXX8xxXXXXXXXxxXXXXX8XxXxXXXx2xx+xxxXxxXXXXXXx2X7x9XXX9X
xx1XxXxXx0XXxXx0xx/x5XXxXXX22xx2x9xXxxxxXxxXxXX9xXXxXxx1XX3xxx8Xx9XxxXXxX
xXXx4xx8xxXx5XxxxXX7xX+XxXxxxxx+XxxXXXXXxXXxXXx6XXXXxXXxX84xXXXxxxX9xxx
XXXxxxXx2xXXXXXxXXXXXX2xXxX+xXXXxxxxxx8xXXXx2X+XxxXXxxXXXXXXXXxxX1xXxx
5+xxXxX7X9X1XX/xxxxXXxXX//XxXXxx+29XXxXXXx9x0xXxXxxxXxXxxX86xXxx1Xx9x3xXx
xxxxX8X/xXxx8Xx5X7xXxXX6xxXXx+7x2xXxxX6XxXxXXxXxX== xxxxxxx"; ## XXXXXX-
XXXX
}
}

Xxxxxx xxxx xxxxxxxx xxxx xxx xx xxxxxxx xx xxx xxxxxxxxxxxxx, xx


xx xxxxxxxx xx xxxxx xx xxxxxx x xxxxxx xxxxxx, xxx xxxx xxx xxxxxx
xxxxxxxxxxx xxx xxx xxx xx xxx xxxxxxxxxxxxx xx xxxxxx xxxx. Xxxx
xx xx xxxxxxx xx xxx xxxx xxx xx xxxx:
/* add-user-key.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {
<transient-change> {
<system> {
<login> {
<user> {
<name> "jnpr";
<authentication> {
<ssh-dsa> {
<name> "ssh-dss AAAAB3NzaC1kc3MAAACBAM5Yu7v/VlAYXzZ5" _
"XUDmBwAGgARS4ILMlhU2ozpfSePZmMqfqsvMCeSsssYt" _
"TX7W1DEnbvA+SdWg35zhS4utAYnlAjzJtaqoB4EYmk8x" _
"t5DCeNd/vSwTMOhlsXFXYHkxOnO5Va5+etQ1c3j9d0Wo" _
"O7+Mu6yxzgJnBN6I9lLYK8jbAAAAFQCkjYEHTB8PnKkX" _
"UBf2yk+aykSeaQAAAIAe2I7x9TYC9Eas1BqMgZb0BGgX" _
"r0jo/a5ZJdFIY22in2t9yAhaqbVbgSpPN9lIDtOab1JG" _
"3bzb8Gb9OpvKBiOtMKj4vd8fhUm5SzujJW7sP+FkWixe" _
"vi+EnfUFQRIgLTeKKe6QDAPxOUcH84pWKMuxiW9xlcXA" _
"JzvuGb2iQQBNLwAAAIAE2tJjK+dJZWoudzvv8pDWWk2H" _
"+QxzEGpsCWJQJNVAarY1nCgy5+pbXyX7M9I1FC/fjmaC" _
"BwZR//JuYRfo+29LTsCMAk9b0fSrToszXvXgtJ86nWzn" _
"1Sz9w3yDgtxpoD8R/mUqa8Xf5J7uGwOT6ypBMa+7u2sG" _
"rqD6RiSvCGxGbQ== example";
}
}
}
}
}
}
}

Xxx xxx-xxxx-xxx.xxxx xxxxxx xxxx xxx 'xxxx' xxxx’x xxx xxx xxx
xxxxxxxxxxx xx xxx xxxxxxxxxxxxx. Xx xxxxxx xx, xxx xxxxx-xxxxxxxxxx
xxxxxxxxxxxxx xxxxxxxxx xxxx xx xxxxxxxxxx:
system {
scripts {
commit {
allow-transients;
file add-user-key.slax;
}
}
}
Xxxx xxx xxxxx xxxxxx xx xxxxx, xxx 'xxxx' xxxx xxxxxxx xxxxxxxx xxxx
xxx xxxxxxxxx xxxxxxxxxxxxx xxxxxxx xxx xxxxxxxxxxxxxx xxx xx
xxxxx xxxxxxxxxxx:
user jnpr {
uid 2000;
class super-user;
}

jcs:emit-change
Xxx xxx:xxxx-xxxxxx xxxxxxxx xxx xx xxxx xx xxxxxxxx <xxxxxxxxx-xxxxxx>
xxxxxxxx xx xxx xxxx xxx xx <xxxxxx> xxxxxxxx. Xxx xxxxxxxxxx xx
xxxx xxx $xxx xxxxxxxxx xxxx xx xxx xx "xxxxxxxxx-xxxxxx" xx xxx xxxxxxx
xxxxxxxx xx xx xxxxxxxx x <xxxxxx> xxxxxxx.
call jcs:emit-change( $content, $tag = "transient-change" );

Viewing Transient Changes


Xxxxx xxxxxxxxx xxxxxxxxxxxxx xxxxxxx xx xxx xxxxxx xx xxx xxxxxx
xxxxxxxxxxxxx xxxx, xx xx xxxxxxxx xx xxxx xxxx xx xxxxxx | xxxxxxx
xxxxxx-xxxxxxx xx xxx xxxx xxxxxxx xx xxxxxxxxxxxxx xxxx xx xxx xxxx
xxxxxxxxxxxxx xxxxxxx xx xxxxxxxxxxx xxxx.

Xxx xxxxxxx, xxx xxxx 'xxxx' xxxx xxxxxxx xxxxxxxxxxxxx xxx xx xxxx
xxxxx xxxx xxx xxxxxxx xx xxx xxx-xxxx-xxx.xxxx xxxxxx xx xxxx
xxxxxx:
[edit]
jnpr@host1# show system login | display commit-scripts
user jnpr {
uid 2000;
class super-user;
authentication {
ssh-dsa "ssh-dss
XXXXX3XxxX1xx3XXXXXXXX5XXxXXXxX5XXXxXxXXxXXX4XXXxxX2xxxxXxXXxXxxxxxXXxX
xxxXxXX7X1XXxxxX+XxXx35xxX4xxXXxxXxxXxxxxX4XXxx8xx5XXxXx/xXxXXXxxxXXXXXx
xXxX5Xx5+xxX1x3x9x0XxX7+Xx6xxxxXxXX6X9xXXX8xxXXXXXXXxxXXXXX8XxXxXXXx2xx
+xxxXxxXXXXXXx2X7x9XXX9Xxx1XxXxXx0XXxXx0xx/x5XXxXXX22xx2x9xXxxxxXxxXxXX9
xXXxXxx1XX3xxx8Xx9XxxXXxXxXXx4xx8xxXx5XxxxXX7xX+XxXxxxxx+XxxXXXXXxXXxXXx
6XXXXxXXxX84xXXXxxxX9xxxXXXxxxXx2xXXXXXxXXXXXX2xXxX+xXXXxxxxxx8xXXXx2X+
XxxXXxxXXXXXXXXxxX1xXxx5+xxXxX7X9X1XX/xxxxXXxXX//XxXXxx+29XXxXXXx9x0xXxX
xxxXxXxxX86xXxx1Xx9x3xXxxxxxX8X/xXxx8Xx5X7xXxXX6xxXXx+7x2xXxxX6XxXxXXxXxX
== xxxxxxx"; ## XXXXXX-XXXX
}
}

ALERT! At the time of this writing, using the replace attribute within a <transient-
change> does not work correctly and the change is merged rather than
replaced. Viewing the output of show configuration | display commit-scripts
makes it appear that the replace operation was successful, but it does
not accurately reflect the committed configuration in this scenario.
Try It Yourself: Transient Root Authentication Key

Create a commit script that adds the root authentication key transiently to the configuration.
Use the jcs:emit-change template to do so.

Element and Template Summary


Xxxxx 11.1, 11.2, xxx 11.3 xxxxxxxxx xxx xxxxxxxxxxxxx xxxxxx xxxxxx
xxxx xxxxxxxx, xxxxxxxxxxxxx xxxxxxx xxxxxxxxxx, xxx xxxxxx
xxxxxxxxx.
Table 11.1 Configuration Change Result Tree Elements

Table 11.2 Configuration Change Attributes


Table 11.3 Configuration Change Template Parameters

Chapter 12: Configuration Macros 177


176 This Week: Applying Junos Automation

Xxx xxxx xxxxx xxxxxxxx xxxx xxxxx xxx xxxxxx xxxxxxx xxx xxxxxxxx
xxxxxxxxxxxxxx xx xxxxxxxxx xxxxxxxx, xxxxxxx xxx xxxxxx xx
xxxxxxx xxxxxxxxxxxxxx, xxx xxxxxxxxxx xxxxxxxxxxxxx xxxxxxx. Xxx
xxx xxxxxx xxxxxx xxxxx xxxxx xx xxx xxx xxxx xxxxx xx xxx xxxxxxxx
xx xxx xxxxxxxxxxxxx xxxxxx. Xxxx xx xxxxx xxxxxxxxxx, xxx xxxxxx
xxxxxxx xxx xx xxxx xxxx xxxxxxxx xx xxxxxx xxxxxxxxxxxxx xxxxxx xx
xxxxxxx xxxx xxx xxxx xxxx xxxx xxxxxxxxx xxxx xxxxxxx xx xxxxxxx
xx xxxx xxx xxxxxxxx xxxxxxxxxxxxx xxxxxx.

Overview
Xxxxxxxxxxxxx xxxxxx xxxxxxx xxxxxxxxx xxxxxxxxxxx xxxx xxx xx
xxxxxxxx xxxxxx x xxxxxxxxxxxxx. Xxx xxxx xxxxx xxx xxxxxx
xxxxxxxx xxxxxxxxxx xxxxxxx xxx xxxxxx xxx xxxxxxxx xxxx xxxx,
xxxxxx xxxxxx xxx xxxxxxxxxxxxx. Xxx xxxxxx xxxxxxxxxxx xxxxx
xxxxx xxxxxxxx xxxx xxxxxx xxxxxxx, xxxxx xxx xxxxx xx xxx xxxx
xxxxxx xxx xxxxxxxxxxxxx xxxxxx.

Configuring Macros
Xxxxxx xxx xxxxxxxxxx xx xxxxx xxx xxxxx-xxxxx xxxxxxxxxxxxx
xxxxxxxxx:
[edit]
jnpr@host1# set apply-macro example

Xxx xxxxx xxxxxxxxxxxxx xxxxxxx xxxx x xxxxx xxxxx "xxxxxxx" xx xxx


xxx-xxxxx xx xxx xxxxxxxxxxxxx xxxxxxxxx. Xxxxxx xxx xx xxxxx xx
xxx xxxxxxxxxxxxx xxxxxxxxx xxx xxxxxxxx xxxxxx xxx xx xxxxxxx xx
xxx xxxx xxxxxxxxx xx xxxx xx xxxx xxxx xxxxxxxxx xxxxx:
interfaces{
lo0 {
apply-macro macro1;
apply-macro macro2;
}
}

ALERT! The apply-macro command does not show up in the command help and
cannot be auto-completed. It is not a hidden command; the reason it
doesn’t appear in the command help is to prevent all the different apply-*
statements from cluttering up the help of every hierarchy level. The
same result is seen with the apply-flag command. In both cases, although
they are supported configuration statements, the full command must be
typed out and is not shown in the help output.
Xxxx xxxxxx xxxx xxxxxxx xx xxxxx xxxx, xxx xx xx xxxx xxxxxxxx xx
xxxxxxxxx xxxxx xxxxxxxxxx. Xxxx xxxxxxxxx xxxx xxxx x xxxx xxx
xxx xxxxxxxxxx xxxx x xxxxx xx xxxx. Xxxxxxxx xxxxxxxxxx xxx xx
xxxxxxxxxx xxx xxxx xxxxxxxxx xxx x xxxxxxxxxx xxxxx xxxx xxxx x
xxxxxx xxxx:
apply-macro customer-1 {
interface ge-0/0/0.0;
protocol bgp;
service-level gold;
}
apply-macro customer-2 {
interface ge-2/0/1.0;
protocol static;
service-level silver;
}

Working with Macros


Xxxxxxxxxxxxx xxxxxx xxx xx xxxxxxxxx xxxx xx xxxxx xx xxx
xxxxxxxxxxxxx xx xxx xxxx xxx xx xxx xxxxx xxxxxxxxxxxxx xxxxxxx.
Xxxx xxx xxx xxx xxxxxxxx xxxxxx xxxx xxxx xxxxx xx xxx xxxx
xxxxxxx, xxxx xxxx xxxxx xx XXX xxxxxx:
<apply-macro> {
<name> "customer-1";
<data> {
<name> "interface";
<value> "ge-0/0/0.0";
}
<data> {
<name> "protocol";
<value> "bgp";
}
<data> {
<name> "service-level";
<value> "gold";
}
}
<apply-macro> {
<name> "customer-2";
<data> {
<name> "interface";
<value> "ge-2/0/1.0";
}
<data> {
<name> "protocol";
<value> "static";
}
<data> {
<name> "service-level";
<value> "silver";
}
}

Xxxx xxxxx xx xxxxxxxxxx xx xxx <xxxx> xxxxxxx. Xxx xxxx xxxxxxxxx


xxxxxx x xxxxx xx xxxxxxxxxxx xx x <xxxx> xxxxxxx xxxx xxx xxxx xxx
xxxxx, xx x xxxxx xx xxxxxxx, xxxxxx xx xxx <xxxx> xxx <xxxxx> xxxxx
xxxxxxxx.
Xxxxxxxx xxxxx xxxxxx xxx xxxxxx xx xxx xxx-xxxxx xx xxx
xxxxxxxxxxxxx, xxxx xxxxx xx xxxxxxxxx xxxxx xxx xxxxxxxxx xxxx:
„„Retrieve the interface value of the customer-1 macro:
var $interface = apply-macro[name == "customer-1"]/data[name=="interface"]/value;
„„Loop through all protocol parameters of macros that start with
“customer”:
for-each( apply-macro[ starts-with( name, "customer")]/data[name=="protocol"] ) {
....
}
„„The following example shows the <change> element necessary to add
a “time-interval” macro to the ge-0/0/0 interface stanza:
<change> {
<interfaces> {
<interface> {
<name> "ge-0/0/0";
<apply-macro> {
<name> "time-interval";
<data> {
<name> "start-time";
<value> "08:00";
}
<data> {
<name> "stop-time";
<value> "13:00";
}
<data> {
<name> "default-down";
}
}
}
}
}
Xxx xxxxx <xxxxxx> xxxxxxx xxxx xxx xxxxxxxxx xxxxx-xxxxx xx xxx
xxxxxxxxxxxxx:
apply-macro time-interval {
default-down;
start-time 08:00;
stop-time 13:00;
}

Macro Uses
Xxxxxx xxxxxx xx xxx xxxxxxxxxxxxx xxx xx xxxxxxx xxxxxx xxxxxxx
Xxxxx xxxxxxx xxx xxxxxx xxx xxxxx xxxxxxxxxx xxxxxxxxxx. Xx xx
xxxx xxxxxxx Xxxxx xxxxxxxxxx xxxxxxx xxxx xxxxxx xxxx xxxxx
xxxxxxxxxxxx.
Xxxxx xxxxxxxxxxxxx xxxxxx xx xxxxxxxx xxxxxxxxx xxx xx xx xxx
xxxxxx xxxxxx, xxx xxxx xxx xxxxxxxxx xxxx xxx xxx xxxxxxxxx:
„„Data storage
„„Instruction sets
„„Exception flags
„„Custom configuration syntax
Xxxx xx xxxxx xxxxxxxxxxxxx xx xxxxxxxxx xx xxx xxxxxxxxx xxxxxxxx
xx xxxx xxxxxxx.

Data Storage
Xxx xxxxx xxx xxx xxxxxxxxxxxxx xxxxxx xx xxxxxxxxx xxxx xxxxxxx.
Xx xxxx xxxx xxx xxxxxx xxxxx xxxxxx xx x xxxxxxxxxx xxxxxxxx xx
xxxxx xxxxxxxxxxx xxxxxx xxx xxxxxxxxxxxxx. Xxxx xxx xxxxxxx
xxxxxx xxxxxx xxxxxxx, xx xx xxxxxxx xx xxxxx xxxxxxx xxxxx xxxx
xxxxxx xx xxxxxx xxxxxxxxxxx xx xxx xxxxxxxxxxxxx xx xxxx.
Xxxxxxxx xx xxxxxxxx xxx xx xxxxxx xxxxxx x xxxxxxxxxxxxx xxxxx xx
xxxx xx xx xxxx xx xxx xxxxxxxxx xxxx xxx xxxxx xxxxxx. Xxx
xxxxxxxxx xxxxxx xxxxx xx xxxxxxx xx xxx xxxxxxxxxxxxx xxxxxx xxx
xx xxxx xx xxxxx xxxxxx xxxxxxxxxxx xxxxxx xxx xxxxxxxxxxxxx. Xx
xxxx xxxx, xxx xxxxxx xxxxxx xxx xxxx xxxx xxxx XXXX xxxx xxx xxxxx
xx xxx xxxxxxxxxxxxx, xx xxxx xx xxx xxxx xxxx xxxxx xx:
/* record-bgp-commit-info.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
import "../import/junos.xsl";

var $macro-name = "commit-info";

match configuration {

/* Retrieve AS Number */
var $asn = routing-options/autonomous-system/as-number;

/* Grab the date */


var $date = substring-before( $localtime_iso, " " );

/* Loop through each EBGP peer */


for-each( protocols/bgp/group[ peer-as != $asn ]/neighbor ) {

/* Are they missing their commit-info macro? */


if( jcs:empty( apply-macro[name == $macro-name] ) ) {

/* Add the apply-macro to it */


var $content = {
<apply-macro> {
<name> $macro-name;
<data> {
<name> "date";
<value> $date;
}
<data> {
<name> "user";
<value> $user;
}
}
}
var $message = "Adding commit information";
call jcs:emit-change( $content, $message );
}
}
}
Xxx xxxxx xxxx xxxx XXXX xxxx xx xxxxx xx xxx xxxxxxxxxxxxx xxx
xxxxxx xxxxxx xxxxxxx xxxx xx xxxxx xxx "xxxxxx-xxxx" xxxxxxxxxxxxx
xxxxx xxx xxxxxxxxx xxx xxxxxxxxxxxxx xxxxxx xxxxxxxxx xx xxx xxx
xxxxx xxxx xxx xxxxxxx xxxx xxx xxx xxxxxxxxxx xxxx.
Xx x xxxxxx, xxx xxxxxxxxxxxxx xxxxxxxx xxxxxxxxxx xxxxxxxxxxx
xxxxx xxx xxxxxxxx xx xxxx xxxx, xxxxx xxx xx xxxx xx xxx xxx
xxxxxxx:
[edit protocols bgp]
jnpr@host1# show
group AS65535 {
peer-as 65535;
neighbor 10.0.0.1 {
apply-macro commit-info {
date 2009-11-25;
user jnpr;
}
}
neighbor 10.0.0.2 {
apply-macro commit-info {
date 2009-11-10;
user roy;
}
}
}

Instruction Set
Xxx xxxxxx xxx xx x xxxxxxxxxxxxx xxxxx xx xxxxxxx x xxxxxx xxxxxx
xx xxxxxxx xxxxxxxx xxxxxxx xxx xxxx xxxxxx xxx xxxxx. Xxx xxxxxxxx
xx xxx xxxxx xx x xxxxxxx xxxxxxxxx xx xxx xxxxxxxxxxxxx xxxxx xx
xxxxxx xxxxxxxxxxx xxx xxx xxxxxx xxxxxx xx xxxxxxx xxx xxxxxx, xx
xxx xxxxx xxxxx xxxxxxx xxx xx xxxx xxxxxxxxxx xxxx xxxxxxx
xxxxxxxxxx xxxxxxxxxxx xxxxx xxxx xxxxx xxx xxxxxx xxxxxx xxxxxx
xxxxxxx.
Xxx xxxxxxxxx xxxxxx xxxxxx xxxxx xx xxxxxxx xx x xxxxxxxxxxxxx
xxxxx xxxxxxx xxx xxxx xxxxxxx. Xxxxxxxx xxx xxxxxxxxxxxxx
xxxxxxxxx xxxxx-xxxxx xxx-xxxx-xxxxxxxxx xx xxxxxxx xx xx xxxxxxxxx xxx
xxxxxxxxx xxxxxxxxxxxxx xxxxxxx xxx xxxx xx xxx xxxxxx:
„„Add family mpls to interface
„„Add family iso to interface
„„Enable interface for MPLS protocol
„„Enable interface for LDP protocol
„„Enable interface for ISIS protocol
„„Remove macro
/* set-core-interface.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

var $macro-name = "commit-info";

match configuration {

/* Look for instruction macro */


for-each( interfaces/interface/unit[ apply-macro/name == "set-core-interface"] ) {

/* Add families and remove macro */


var $content = {
<apply-macro delete="delete"> {
<name> "set-core-interface";
}
<family> {
<iso>;
<mpls>;
}
}
var $message = "Setting as core interface...";
call jcs:emit-change( $content, $message );

/* Assemble interface name */


var $name = ../name _ "." _ name;

/* Add to protocols */
<change> {
<protocols> {
<mpls> {
<interface> {
<name> $name;
}
}
<ldp> {
<interface> {
<name> $name;
}
}
<isis> {
<interface> {
<name> $name;
}
}
}
}
}
}

Xxx xxxxx xx xxxxx xx xxx xxxxxxx xxxxxxxxx xxxxx xx xxx xxxxxx:


[edit interfaces ge-1/0/0 unit 0]
jnpr@host1# show
apply-macro set-core-interface;
family inet {
address 10.0.1.1/24;
}

Xxx xxxxxxxxx xxx xxxxxx, xxx xxxxx xxx xxxx xxxxxxx xxx xxx
xxxxxxxx xxxxxxx xxxx xxxx xxx xx xxxxx xxx xxx xxxxxxxxx xx
xxxxxxxx xx x xxxx xxxxxxxxx:
[edit interfaces ge-1/0/0]
jnpr@host1# show
unit 0 {
family inet {
address 10.0.1.1/24;
}
family iso;
family mpls;
}

[edit]
jnpr@host1# show protocols
mpls {
interface ge-1/0/0.0;
}
isis {
interface ge-1/0/0.0;
}
ldp {
interface ge-1/0/0.0;
}
Try It Yourself: MTU Changes

Design a configuration macro with two parameters. The first parameter refers to the desired
MTU value and the second is a regular expression for all interfaces that should be assigned the
MTU value. Create a commit script that looks for the configuration macro in the [edit
interfaces] hierarchy and makes the instructed MTU changes in response. The configuration
macro should be removed as part of the configuration change.

Exception Flag
Xxx xxxxx xxx xx xxxxxxxxxxxxx xxxxxx xx xx xxxxxxxxx xxxx xxxxx,
xxxxx xx xxxx xx xxxxxxxx xxxx x xxxxxxxxxxxxx xxxxxxx xxxxxx xx
xxxxxxx xx xxxxxx xxxxxxx. Xxxx xxxxx xx xxxxxx xxxx x xxxxxx
xxxxxx xxxxx xx xxx xxxxxxxxxxx xx x xxxxxxxxxx xxxxxxxxxxxxx, xxxx
xx xxx xxxxxxxxxx, xxx xxxxxxxx xxx xxxx xxxxxxxxx xx xxx xx xxxx xx
xxxxxxx.
Xxxxx xx xxxxxxx xx x xxxxxx xxxxxx xxxx xxxxxxxx xxxxxxxxx
xxxxxxxxxxxxx, xxx xxxxxx xxxxx xxxxxx xxx xxxxxxx xx x xxxxxxxxxx
xxxxx xxxxx xx xxxxxxxx xxx xxxxxxxxx. Xxxx xxx, xx xxx xxxxxx’x
xxxxxxxxxxxxxx xx xxx xxxx x xxxxxx xx xxxxx xxxxxxxxxx xx xx
xxxxxxxx xx xxx xxxxxx xxxx xxx xxx xxx xxxxx xx xxxxx xxxxxxxxxx,
xxxxx xxxx xxxxx xxxx xx xxxxx xx xxxxxxxxx xx xxx xxxxxx xxxxxx
xxxxxx xxxxxxxxxx.
Xxxxxx xxx xxxxx-xxxx-xxxxx.xxxx xxxxxx xxxxxx xxxxx xx Xxxxxxx 10
xxxx xxxxxxxxx x <xxx:xxxxx> xx xxx XXXX xxxxx xxxxxx x xxxxxx-xxxxx.
Xxxx xxxxxx xxx xxx xxxx xxxxxxxx xx xxx xxx xxxxx "xxxx-xxxxxx-xxxxx-
xxxxx" xx xx xxxxxxxxx xxxx:
/* check-ebgp-peers-with-exception.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

/* Retrieve AS Number */
var $asn = routing-options/autonomous-system/as-number;

/*
* Scroll through all EBGP peers - do not worry about peers with
* "skip-prefix-limit-check" macro applied.
*/
for-each( protocols/bgp/group[ peer-as != $asn ]/neighbor ) {
if( jcs:empty( family/inet/unicast/prefix-limit/maximum ) &&
jcs:empty( ../family/inet/unicast/prefix-limit/maximum ) &&
jcs:empty( apply-macro[name == "skip-prefix-limit-check"] ) ) {
<xnm:error> {
call jcs:edit-path();
<message> "EBGP peer must have prefix limit defined.";
}
}
}
}

Xxxx xxx xxxxxxxx xxxxxxx xx xxxx xxxxxx xxxxxx xx xxxxx, xxx


xxxxxxxxx xxxxxxxxxxxxx xx xxxxxxx xx xxx xxxxxx xxxxxx xxxxxxx
xxx xxxxx xxxxxxx xxx xxxxxxxx 10.0.0.2 xxxxxx xxx xxxxxx xx xxxxxx
xxx xxxxxxx xxxxxx xxxx:
bgp {
group AS65535 {
peer-as 65535;
neighbor 10.0.0.1 {
family inet {
unicast {
prefix-limit {
maximum 10000;
}
}
}
}
neighbor 10.0.0.2 {
apply-macro skip-prefix-limit-check;
}
}
}

Custom Configuration Syntax


Xxx xxxxxx xxx xxxxx xxx xxx xxxxxx xx xxxxxxxx xxxxxx
xxxxxxxxxxxxx xxxxxx xx xxxxxxx xxxxx-xxxxx xxxxxxxxxx xxxx
xxxxxxxxx xxxxxxxxxxxxx xxxxxxx.
Xxx xxxxx-xxxxx xxxxxxxxxx xxxxxx xxxxxxxxxxx xx xxx xxxxxxxxxxxxx,
xxx xxxx xxx xxxxx xx xxxx xx xxx xxxxx xxxx xxx xxx xxxxxx
xxxxxxxxxxxxx xxxxxxxxxx. Xxx xxx xxxxxx xxxxxx xxxxxxxxxx xxx
xxxxxx xxxx xxxxx xxxxxxxxxx Xxxxx xxxxxxxx xxx xxxxxxxx xxx xxxx
Xxxxx xxxxxxxxxxxxx xxxxxxxxxxx xx xxx xxxxxxx.
Xxxx xx x xxxxxxxx xxxxxxxxxx xxxx xxxxxx xxxxxxxxxxxxxx xx xx
xxxxxxxxxxxx xx xxxx xx xxxxxxxxxx. Xxx xxxxxxxxxxxxxxx xxxxx
xxxxxxx xxx xxxx xxxxxxxxxxxxx xxxxxxxxx xx xxxxxxxxx, xxxxx
xxxxxxxx xxxxx xxxxx. Xxx xxx xxxxxxxxxxxxxx xxxxx xxxx xxx xxxxxx
xx xxxxxxxxxxxx xxxxxxxxxxxxx xxxx xxx xx xxxxxx xxxx xxxxxx xxxx.
Xxxxxxxxxxxx xxxxxxxxxx xx x xxxxxxx xxx xx xxxx xxxx xx
xxxxxxxxxxxxx xxxxx. Xx xxxxxxxxxxx xxx xxxxxxxxxxxxx xxxxxxx
xxxx x xxxxxx xxxxxxxxx xx xxxx xxx xxxxx xxxxx, xxxxxx xxxxxxx xxxx
xxxx xxxx xxxxx xxxxxx xxx xxxxxx xxx xxxxxxxxxxx xxxxxxxxxxxxx
xxx xx xxxxxxxxxx xxx xxxxxxxxxxxx xxxxxxxxx.
Xxxx xx xx xxxxxxx xxxx xxxxxxxx xxx xxxxxx xxxx xx xxxxxxx
xxxxxxxxx xxxxxx xxxx xxxx xxx xxxx.0 xxx xxxx.2 xxxxxxx xxxxxx, xxx
xxxxxxxxxxxx xxx xxx xxxxx xxxx x xxxxxx xxxxx-xxxxx xxxx-xxxx
xxxxxxxxx.
Xxx xxxxxxxxxxxxx xxxxxxxx:
routing-options {
apply-macro both-ribs;
static {
route 172.0.0.0/8 next-hop 172.25.45.1;
}
}

Xxx xxxxxx-xxxx-xxxx.xxxx xxxxxx xxxxxx:


/* expand-both-ribs.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

/* If both-ribs macro is present, then expand the configuration transiently */


if( routing-options/apply-macro[ name == "both-ribs" ] ) {
<transient-change> {
<routing-options> {
<interface-routes> {
<rib-group> {
<inet> "both-ribs";
}
}
<rib-groups> {
<name> "both-ribs";
<import-rib> "inet.0";
<import-rib> "inet.2";
}
}
}
}
}

Xxx xxxxxxxx xxxxxxxxxxxxx xxxxxxxx xx Xxxxx xxxxxxx:


routing-options {
apply-macro both-ribs;
interface-routes {
rib-group inet both-ribs;
}
static {
route 172.0.0.0/8 next-hop 172.25.45.1;
}
rib-groups {
both-ribs {
import-rib [ inet.0 inet.2 ];
}
}
}

Xxxx xxx xxxxxxxxxx xxxxxxx xxx xxxxxxxxxxxxx xx xxxx xx xxx xxxx,


xxx xxx xxxxxx xxxxxxxxxxxxx xxxx xx xxxxxxxxx xxx xxxxxxxx xx
Xxxxx xxxxxxx. Xxx xxxxxxx xxxxxxxxxxxxx xx xxxxxxx xxxxxxx xxx
xxxxxxxxxxxx xxxxxxxx xx xxx xxxxxxxx xxxxxxxxxxxxx xx xxx xxxx xx
xx xxxxxx. Xxxx x xxxx’x xxxxxxxxxxx, xxx xxxxx-xxxxx xxxx-xxxx
xxxxxxxxx xxxxxxx x xxxx-xxxx xxx-xxxxx xxx xxxxxx xxx xxxxxxxxx
xxxxxx xxxx xxxx xxxx.0 xxx xxxx.2.
Try It Yourself: Custom Firewall Filter

Design a configuration macro that has two parameters, one that indicates the control protocol
between PE and CE (BGP, OSPF, etc.), and the other that indicates the policer bandwidth.
Create a commit script that transiently creates a firewall filter for each logical interface with
that macro configured. The firewall filter should allow all packets from the control protocol in
the first term, and allow all packets in the second term, but rate-limit them to the bandwidth
specified in the macro.
MORE? Find another example of custom configuration syntax in the Appendices.
Appendices 187
186 This Week: Applying Junos Automation

Appendix A: Supplemental Junos Automation Information from Part One


Xxxx Xxxxxxxx xxxxxxxxxxx xxx xxxxxxxxxxx xxxxxxxxxx xxxxxxxxx xx
Xxxx Xxx xx xxxxxxxxx xxxx xxxxxxxxxx xx xxxxxxx xx xxxx xx xxxxxxx
xxxxxxxxx xx xxx Xxx Xx Xxxxxxxx xxxxxxxx.
Op Script Examples
Xxxx xxxxx xxxxxxx xx xxx Xxxxxxxx xxxxxxxx xxxx xxxxxxxxxx
xxxxxxx, xxxxx xxxxxxxxx xxx xxxxxxxxxxxxx xxxx xx xxxxxxx xxxxxxx
xxx xxxxx xxx xx xxx xxxxxxx xxxxxxx xx xxxx xxxxxx. Xxxxxxxxx
xxxxxxxx xxx xxxxxxxx xxxxxx xxx xxxxxxx xx xxxxxxx xxxxxxxxxxxxx
xx xxxxx xxxxxxxxx.

Display Time
Xx xxxx xxxxx xxxxxxx, xxx xxxxxxx-xxxx xxxxxxxx xxxxxx xxx xxxxxxx
xxxxxxx xx Xxxxxxx 3 xx xxxxxxxxx xx xxxxxx xxx xxx xxx xxxx xx
xxxxxx xxx XXX xxxxxx xx xxx xxxxxx xxxxxx.
Xx xxx xxxxx xxxxxxx xxx xxxxxxx-xxxxxx xxxxxxx-xxxx xxxxxxxx xxx
xxxxx, xxxxxxxx xxx xxxx xx xxxxxx xxxx xxxxxx xx xxxxx xx xxxxxxx
xxx xxxx. Xxxx xxx xxxxxxx-xxxx xxxxxxxx xx xxxxxx xxx $xxxxxx
xxxxxxxxx xx xxx xx xxx xxxxx xx xxx $xxxxxxx-xxxxxx xxxxxx xxxxxxxxx.
Xxxxx xx xx xxxxxx xxx xx xxxxx xxx xxxxxx xx xxx xxx xxxx xxxxxx
xxx xxxxxx. Xxxxxxxx xxxx xxxxxx xxxxxxxxxx xxx xxxxxxxxx xxx
xxxxxxxxxx xx xxx xxxxxx xxxxxx, xxx xxxx xx xxx xxxx xxxxxxxx. Xxxx
xxxxx xxxx xx xx xxx xxxxxxxxx xx xxxx xxx $xxxxxx xxxxx xx xxx
xxxxxxx-xxxx xxxxxxxx xx x xxxxxxxx xxxxxxxxx. Xxxxxxx, xxx xxxxxxx-xxxx
xxxxxxxx xxx xxxxxx xxx xxx xxxxxx xxxxxxxxx.
Xxx xxxxxx xxxxxxxx xx xxx xxxx xxxxxx xx xxx xxxxxx xx Xxxxxxx 3,
xxx xx xxxx xxxx xxx xxxxx xxxxxxxx xxxxxxxx xxx xxxxxx xxxxxxxxx
xxxxxxx xx xxxxxxx xx xxx xxxx xxxxxxxx xx xxxx xxx xxxxxx xx x
xxxxxxxx xxxxxxxxx:
/* show-time.slax */
version 1.0;
ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
import "../import/junos.xsl";

/* This is imported into the Junos CLI help text */


var $arguments = {
<argument> {
<name> "display-format";
<description> "Choose either iso or normal";
}
}

/* Command-line argument */
param $display-format;

match / {
<op-script-results> {

/* Call the display-time template */


call display-time;

}
}

/* Output the localtime to the console in either iso (default) or normal format */
template display-time {
if( $display-format == "iso" ) {
<output> "The iso time is" _ $localtime_iso;
}
else {
<output> "The time is" _ $localtime;
}
}
Xxx xxxxxx xx xxx xxxx xx xxxxxxxx xx xxx xxxxxxx xx Xxxxxxx 3:
user@Junos> op show-time display-format iso
The iso time is 2009-05-12 21:01:10 PDT

user@Junos> op show-time display-format normal


The time is Tue May 12 21:01:13 2009
Static route
Xxx xxxx xxxxxx xx xxxx xx xxx x xxxxxx xxxxx. Xxxxx xxx xxx:xxx-xxxxx()
xxxxxxxx xx xxxx xx xxxxx xxx xxxxxx xxxxx xxx xxxx xx xx xxxx xxxxx
xx xxxxx xxx xxxx-xxx. Xxxx xxxxx xxx xxxxxx xxx xxxxx xxx xxxxxx
xxxxxxxxx xxxxxxxxxxxxx xxxxxxx, xxxx xxxxx xxx xxxxxxx xxx xxxxxx:
/* add-route.slax */
version 1.0;
ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
import "../import/junos.xsl";

match / {
<op-script-results> {

/* Ask for the static route */


var $static-route = jcs:get-input("Enter the static route: ");

/* Ask for the next-hop */


var $next-hop = jcs:get-input("Enter the next-hop: ");

/* Create the configuration change */


var $configuration = <configuration> {
<routing-options> {
<static> {
<route> {
<name> $static-route;
<next-hop> $next-hop;
}
}
}
}

/* Open a connection */
var $connection = jcs:open();

/* Call jcs:load-configuration and provide the connection and configuration


* change to make.
*/
var $results := { call jcs:load-configuration( $connection, $configuration ); }

/* Check for errors – report them if they occurred */


if( $results//xnm:error ) {
for-each( $results//xnm:error ) {
<output> message;
}
}

/* If there are no errors then report success */


if( jcs:empty( $results//xnm:error ) ) {
<output> "Committed without errors.";
}

/* Close the connection */


var $close-results = jcs:close($connection);
}
}

Xxxx xx xx xxxxxxx xx xxx xxx-xxxxx xx xxxxxx xx xxxxxxxxx:


user@Junos> op add-route
Enter the static route: 10.6.0.0/16
Enter the next-hop: 192.168.1.4
Committed without errors.

Xxx xxxx xx xxx xxxxxxxxxxxxx xxxxx xxx xxxxxxxx xxxxxx (xxx xxxxxx
xxxx xxxxxxx xxxxxxx):
user@Junos> show configuration routing-options
static {
route 10.1.0.0/16 next-hop 192.168.1.1;
route 10.2.0.0/16 next-hop 192.168.1.1;
route 10.6.0.0/16 next-hop 192.168.1.4;
}
autonomous-system 65500;
show-bgp-policy
Xxxx xx xx xxxxxxx xx x xxxxxx xxxx xxxxxxx xxxx xxx xxxxxxx xx
xxxxxxx Xxxxx xxxxxxxxx. Xxx xxxx xx xxxx xxxxxx xx xx xxxxxxx xx
xxxx xxx xx xxxxxx xxx xxxxxxxx xxxxxx xxxxx xx x XXX xxxx. Xxxx
xxxxxxxx XXX xxxxxxxx xx xx xxxxxx xx xxxxxx xxxxxx xxxxx, xx xxx
xxxxxx xxxxxxxxxxx xx xxxxxxxxx xxxxxxx xxxx xx xx x xxxxxx xx
xxxxxxxx/xxxxxxxx xx xxx xxxxxxxx xxxxxxxxx xx xxx xxxxxx xx xxx
xxxxxxx xxxxx xxxxxx xxx xxxxxx-xxxxxxx xxxxxxxxxxxxx.
Xxxx xxxxxx xxxxxxxx xxx xxxxxx xxxxx xxx xxx xxxxxxxx xxxx xx xxx
xxxxxx xx xxxxxx xxxxxxxxx. Xx xxxx xxxxxxxxx xxx xxxxxxxxxxxxx
xxxx xxx xxxx xxxxxx, xxx xxxxxxxx xx xx xxx xxxxxxx xx xxxxxxxxxx
xxxxx. Xxx x xxxx xxxx xxx xx xxxxxxx xxx xx xxxxxx xxx xx xxx xxxx
xxxx xxx xxxxxxxx xxxxxx xxxxx xxxx xxxxx xx xxxxxx.
Xxxx xxxxx xxx xxxxxx xx xxx xxxxxx xxxx xxxxx xx xxxxxx xxx xxxxxx
xxxxxxxx xxx xxxx 10.0.0.1:
user@Junos> op show-bgp-policy neighbor 10.0.0.1 direction import
BGP Neighbor: 10.0.0.1 in group EBGP
Import Policies: block-private set-local-pref accept-by-community
Policy: block-private
policy-statement block-private {
from {
route-filter 192.168.0.0/16 orlonger;
route-filter 10.0.0.0/8 orlonger;
route-filter 172.16.0.0/12 orlonger;
}
then reject;
}
Policy: set-local-pref
policy-statement set-local-pref {
term default {
then {
local-preference 50;
}
}
term pref-75 {
from community pref-75;
then {
local-preference 75;
}
}
term pref-100 {
from community pref-100;
then {
local-preference 100;
}
}
}
Policy: accept-by-community
policy-statement accept-by-community {
term accept {
from community from-64500;
then accept;
}
term reject {
then reject;
}
}

Xx xxxxxxxxxx xxxxxxx xx xxxx xxxxxx xx xxxx x xxxx xxx xxx xxx


xxxxxxxx xxxxxxx-xxxx xxxxxxxx xx xxxxxx xxxxxxx xxx xxxxxxxxx
xxxxxxxxxxxxx xxx xxx xxxxxxxxx xxxxxxxxxxxxx. Xxx xxxxxxxxx
xxxxxxxxxxxxx xx xxxx xx xxxxxxx. Xxxxxxx, xxx xxxxxx xx xxxx xxx
xxxxxx xxxxx xx xxx xxxxxxxxx xxxxxxxxxxxxx xx xxxxxx xx xxxxxx xxx
XXX xxxxxx xxxxxxxxxxxxx xxxxx xx xxxxxxxxxx xxx xxxxxx xxxxxxx.
Xxx xxxxxx xxxx xxx xxxx-xxx-xxxxxx.xxxx xxxxxxx:
/*
* This op script displays the full chain of policy configuration for a given
* neighbor and import/export direction. Either the candidate or the committed
* database can be used, with the committed database used by default.
*
* Usage: op show-bgp-policy neighbor 10.0.0.1 direction import
*
*/

version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

/*
* The $arguments global variable is a special variable which Junos reads to build
* the CLI help for the script. The command-line arguments will appear within the help
* message along with their description if the following format is followed.
*/
var $arguments = {
<argument> {
<name> "neighbor";
<description> "Required: The BGP neighbor address";
}
<argument> {
<name> "direction";
<description> "Required: Policy direction, either import or export";
}
<argument> {
<name> "database";
<description> "Optional: Specify either the [committed] or candidate configuration
database";
}
}

/* These global parameters are assigned based on their corresponding command-line


arguments */
param $neighbor;
param $direction;
param $database="committed";

match / {
<op-script-results> {

/*
* The script first sanity checks the $neighbor and $direction command-line arguments. If
they
* have not been set correctly then the script exits by using the <xsl:message>
command element
* and specifying that the script should end by setting the terminate attribute to "yes".
Note
* that <xsl:message> is not a result tree element, it is one of the few elements that is
* processed immediately rather than written to the result tree.
*/
if( jcs:empty( $neighbor ) or jcs:empty( $direction ) or
( $direction != "import" and $direction != "export" ) ) {
<xsl:message terminate="yes"> "The neighbor address and policy direction must be
specified.";
}

/*
* The database should be set to either "committed" or "candidate", if not then exit the
script
* with an error
*/
if( $database != "committed" and $database != "candidate" ) {
<xsl:message terminate="yes"> "The database is not set correctly.";
}

/*
* This API element is used to retrieve the configuration. Either the candidate or the
committed
* configuration can be used. The choice is based on the $database command-line
argument. In
* addition the inherit attribute has been set. This is used to request that the
configuration be
* retrieved in inherited mode meaning that all configuration from configuration groups
will be
* inherited into its proper hierarchy level. This is done so that the script has an accurate
view
* of the current BGP policy configuration.
*/
var $get-bgp-rpc = <get-configuration database=$database inherit="inherit"> {
<configuration> {
<protocols> {
<bgp>;
}
}
}

/*
* The assembled API element is sent to Junos through jcs:invoke and the XML response
is stored in
* $bgp-config
*/
var $bgp-config = jcs:invoke( $get-bgp-rpc );

/*
* The BGP neighbor is extracted from the configuration through a location path. The
last()
* function is used to guarantee that only one element node will be returned. It returns
true
* only if the node is the last in the node list so only one node can be selected and
assigned to
* $bgp-neighbor.
*/
var $bgp-neighbor = $bgp-config/protocols/bgp//neighbor[name == $neighbor ][last()];

/*
* Error check, if the $bgp-neighbor is missing than jcs:empty() will return true and the
script
* will be terminated with an error message.
*/
if( jcs:empty( $bgp-neighbor ) ) {
<xsl:message terminate="yes"> "BGP Neighbor " _ $neighbor _ " isn’t configured.";
}

/*
* Begin the output. The BGP neighbor will be shown first as well as the BGP group it is
in.
*/
<output> "BGP Neighbor: " _ $neighbor _ " in group " _ $bgp-neighbor/../name;

/*
* The BGP policy list will now be retrieved. To do this the jcs:first-of() function is used.
* This is necessary because a BGP peer’s policy can be configured at up to three
different
* hierarchy levels: the neighbor level, the group level, or the bgp level. The peer uses
the
* policy configuration at the most specific level. jcs:first-of() works by checking multiple
* node-set arguments. The first node-set that is not empty will be returned. So in this
case
* three separate location paths are provided (each of which results in a node-set). The
first
* location path refers to any policies at the neighbor level, the second pulls policies at
the
* group level, and the last pulls policies at the bgp level. The most specific location that
has
* policies will be returned and assigned to the $policy-list variable.
*/
var $policy-list = jcs:first-of( $bgp-neighbor/*[name()==$direction],
$bgp-neighbor/../*[name()==$direction],
$bgp-neighbor/../../*[name()==$direction] );

/*
* Error check, if there are no policies then the script can terminate.
*/
if( jcs:empty( $policy-list ) ) {
<xsl:message terminate="yes"> "There are no " _ $direction _ " policies for " _
$neighbor;
}

/*
* The policy chain is now output to the console. This is done all within one line by writing
* the text strings to a single <output> element through the expr statement.
*/
<output> {
if( $direction == "import" ) {
expr "Import Policies:";
}
else {
expr "Export Policies:";
}
for-each( $policy-list ) {
expr " " _ .;
}
}

/* A for-each will now loop through each policy individually to allow them to be displayed
*/
for-each( $policy-list ) {

/* Output the policy name */


<output> "\nPolicy: " _ .;

/*
* The script must retrieve the text version of each policy one by one. By default the
* returned configuration is always in XML format. To see the configuration in text
format
* use the format attribute and set it to "text".
*/
var $get-policy-rpc = <get-configuration format="text" database=$database
inherit="inherit"> {
<configuration> {
<policy-options> {
<policy-statement> {
<name> .;
}
}
}
}

/* Send assembled API element to Junos through jcs:invoke(); */


var $policy-text = jcs:invoke( $get-policy-rpc );

/*
* The returned configuration will include the entire hierarchy including the policy-
options
* statement and enclosing brackets. This is extra clutter that is not needed so it is
removed
* by using the substring-after and substring functions to remove all the unnecessary
* characters. The complete text policy is then output to the console.
*/
var $cropped-text =substring-after( $policy-text, "policy-options {" );
<output> substring( $cropped-text, 1, string-length( $cropped-text )-2 );
}
}
}

change-password
Xxxx xxxx xxxxxxx xxxxx x xxxxxx xxxx xxxxxxxx xx xxxxxxxxx
xxxxxxxxxxxxx xxxxxx. Xxxx xxxxxx xxxxxx x xxxx xx xxxx-xxxxx xxxxx
xxxxx xxxxxxx xx xxxxxxxx xxxxx xxxxxxxx xxxx xxx xxxxxxx-xxxx. Xxx
xx xxxx xxxxxx xxxxxxxx xxxx xxx xxxx xxx xxx xxxxxxxxx xxxxxxxxxx
xx xxxx xxxxxxxx xxxxxxx (xxx Xxxxxxx 4). Xxx xxxxxxx xxxxxxx
xxxxxxxx xx XXXXX 9.6, xx xx xxxxx xxx xxx:xxx-xxxxxx() xxxxxxxx xx
xxxxx xxx x xxx xxxxxxxx. Xxxx xx xx xxxxxxx xx xxx xxxxxx xx xxx
xxxxxx:
user@Junos> op change-password
Enter the new password:
Reenter the new password:
Password changed.
Xxxx xx xxx xxxxxx xxxx xxx xxxxxx-xxxxxxxx.xxxx:
/*
* This op script changes the password for the current user. The password is
* learned using jcs:get-secret() for security purposes so the minimum Junos version
* is 9.6
*/
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match / {
<op-script-results> {

/*
* Query the user for the new password. Use jcs:get-secret() so that the password
* is not shown on the screen. Ask twice and compare the entries. Terminate the
* script if they are not the same.
*/
var $new-password = jcs:get-secret("Enter the new password: ");
var $new-password2 = jcs:get-secret("Reenter the new password: ");

if( $new-password != $new-password2 ) {


<xsl:message terminate="yes"> "The passwords do not match.";
}
if( string-length( $new-password ) == 0 ) {
<xsl:message terminate="yes"> "The password is blank.";
}

/*
* Assemble the configuration change needed to change the password. Pull in the
* user name from the $user default global parameter.
*/
var $configuration = {
<configuration> {
<system> {
<login> {
<user> {
<name> $user;
<authentication> {
<plain-text-password-value> $new-password;
}
}
}
}
}
}

/* Open a connection */
var $connection = jcs:open();

/*
* Send the configuration change and connection to jcs:load-configuration, it will load
* the change and commit it.
*/
var $result := { call jcs:load-configuration($connection, $configuration); }

/* Check for commit errors - report them if found */


if( $result//xnm:error ) {
<output> jcs:output("Error changing the password");
for-each( $result//xnm:error ) {
<output> message;
}
}
else {
<output> "Password changed.";
}

/* Close the connection */


var $close-results = jcs:close( $connection );
}
}

safe-bgp-clear
Xxxx xxxx xxxxxxx xxxxx xxx xxxxxxx xxx xxxx xxxxxx xxxxxxxx
xxxxxxxxxxx xxxx xxxxxxxx xx xxxxx xxxxx xxxxxxx xxxxxxxx. Xxxx
xxxxx xxxxx xxxxx xxx xxxxxxxx xxxx xxx XXX xxxxxxx xxxxxxxx xxx
xxxxxxxxx. Xxxx xxxxxx xxxxx xxx xxxxxxx xxxxx xx xxxxxxxxx xxxxx
xx xxxxxxx xxxx xxxx xxxxxx xx xxxx xx xxxxxxx xxx xxxxx xxxxxxxx.
Xxx xxxxxxx xxxxxxx xxxxxxxx xx Xxxxx 9.6 xxxxxxx xxx xxx:xxx-xxxxx()
xxxxxxxx xx xxxx xx xxxxxxx xxxxxxxxxxxx.
Xxxx xx xx xxxxxxx xx xxx xxxxxx xx xxx xxxxxx:
user@Junos> op safe-bgp-clear peer all
This will clear ALL BGP sessions
Are you sure? (yes/[no]): yes
Cleared 2 connections

Xxxx xx xxx xxxxxx xxxx xxx xxxx-xxx-xxxxx.xxxx:


/*
* This script provides a safe version of the "clear bgp neighbor" command. That command
* allows an operator to accidently clear all BGP neighbors when no address is specified.
* This script requires "peer all" to be specified in order to clear all BGP neighbors,
* and it requires confirmation from the operator that they do indeed wish to clear all
* of their BGP peers.
*
* Minimum Junos version is 9.6 due to the jcs:get-input() function. (This can be performed
* in Junos 9.4 and 9.5 by using the deprecated jcs:input() function.)
*/

version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

/*
* The $arguments global variable is a special variable which Junos reads to build
* the CLI help for the script. The command-line arguments will appear within the help
* along with their description as long as the following format is followed.
*/
var $arguments = {
<argument> {
<name> "peer";
<description> "Neighbor address to drop or ‘all’ for all sessions";
}
}
/* This global parameter will have its value set based on the matching command-line
argument */
param $peer;

match / {
<op-script-results> {

/*
* The script requires that a peer be specified. If the user did not enter a peer on the
* command-line then display an error and exit.
*/
if( string-length( $peer ) == 0 ) {
<xsl:message terminate="yes"> "You must specify which BGP peer you want to clear.";
}

/*
* If peer ‘all’ was entered on the command-line then the user will need to confirm the
choice
* before clearing all the BGP peers.
*/
if( $peer == "all" ) {

/*
* Request confirmation from user before clearing all the BGP peers. In Junos 9.4 & 9.5
* jcs:input() can be used instead.
*/
var $prompt = "This will clear ALL BGP sessions\nAre you sure? (yes/[no]): ";
var $response = jcs:get-input( $prompt );

if( $response == "yes" ) {


/*
* The user confirmed they wish to clear all sessions so call the execute-command
* template.
*/
call execute-command();
}
else {
/*
* If they decided not to clear all the sessions then display that choice to the
* console.
*/
<output> "Clear all cancelled";
}
}
else {
/* There is no need to confirm the clearing of a specific peer, just execute the clear
* command by calling the execute-command template.
*/
call execute-command();
}
}
}

/*
* This template will invoke the clear bgp neighbor command and display any output to the
console.
*/
template execute-command() {

/* There is no mapped API Element for clear bgp neighbor so the <command> element
will be used */
var $command = {
/* If all is specified then just do the normal command, otherwise include the peer address
*/
if( $peer == "all" ) {
<command> "clear bgp neighbor";
}
else {
<command> "clear bgp neighbor " _ $peer;
}
}

/* Execute the command and retrieve the results */


var $results = jcs:invoke( $command );

/* Copy output to the result tree so that it will be displayed on the console */
copy-of $results;
}

Try It Yourself Sample Solutions


Xxxx xxxxxxx xx xxx Xxxxxxxx xxxxxxxx xxxxxx xxxxxxxxx xxx xxxx xx
xxx Xxx Xx Xxxxxxxx xxxxxxxx xx Xxxxxxxx 1 xxxxxxx 4.

Chapter 1:Try It Yourself: Viewing Junos Configuration in XML


Show the following configuration hierarchy levels in XML on a Junos device:
(e.g. show configuration system | display xml)

[system]
[interfaces]
[protocols]

user@Junos> show configuration system | display xml


<rpc-reply xmlns:junos="http://xml.juniper.net/junos/9.0R4/junos">
<configuration junos:commit-seconds="1248125252" junos:commit-localtime="2009-07-
20 14:27:32 PDT" junos:commit-user="user">
<system>
<host-name>Junos</host-name>
<login>
<user>
<name>user</name>
<authentication>
<encrypted-password>pVFST7cOl4Hu2</encrypted-password>
</authentication>
</user>
</login>
</system>
</configuration>
<cli>
<banner></banner>
</cli>
</rpc-reply>

user@Junos> show configuration interfaces | display xml


<rpc-reply xmlns:junos="http://xml.juniper.net/junos/9.0R4/junos">
<configuration junos:commit-seconds="1248125420" junos:commit-localtime="2009-07-
20 14:30:20 PDT" junos:commit-user="user">
<interfaces>
<interface>
<name>lo0</name>
<unit>
<name>0</name>
<family>
<inet>
<address>
<name>10.3.3.3/32</name>
</address>
</inet>
<iso>
<address>
<name>47.0000.3333.3333.3333.00</name>
</address>
</iso>
</family>
</unit>
</interface>
</interfaces>
</configuration>
<cli>
<banner></banner>
</cli>
</rpc-reply>

user@Junos> show configuration protocols | display xml


<rpc-reply xmlns:junos="http://xml.juniper.net/junos/9.0R4/junos">
<configuration junos:commit-seconds="1248125504" junos:commit-localtime="2009-07-
20 14:31:44 PDT" junos:commit-user="user">
<protocols>
<ospf>
<area>
<name>0.0.0.0</name>
<interface>
<name>ge-1/0/0.0</name>
</interface>
</area>
</ospf>
<pim>
<interface>
<name>ge-1/0/0.0</name>
</interface>
</pim>
</protocols>
</configuration>
<cli>
<banner></banner>
</cli>
</rpc-reply>

Chapter 1:Try It Yourself: Writing XML in the SLAX Abbreviated Format


Rewrite the following configuration using the SLAX abbreviated XML format:

system {
host-name r1;
login {
message "Unauthorized access prohibited.";
}
}

<system> {
<host-name> "r1";
<login> {
<message> "Unauthorized access prohibited.";
}
}

Chapter 2:Try It Yourself: Adding Comments to the Hello World Script


Make the following modifications to the Hello World script:
1. Add a multi-line comment at the beginning that describes the purpose of the script.
2. Add an additional comment before the <output> "Hello World!"; line which states that the script
is writing to the console.
After the two modifications have been made, replace the prior version of hello-world.slax on
your Junos device with the new version. Execute the script again and verify that the new
comments did not change the operation.
/*
* hello-world.slax – This script will output "Hello World!" to the console.
*/
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";
match / {
<op-script-results> {
/* This writes the string to the console. */
<output> "Hello World!";
}
}

Chapter 2:Try It Yourself: Adding Additional Output to the Hello World Script
Modify the Hello World script once again. This time, add two additional lines of output to the
console above the Hello World! string.
Replace the prior version of hello-world.slax on your Junos device with the changed version.
Execute the script again and see the affect the new <output> elements have on the script
output.

/*
* hello-world.slax – This script will output "Hello World!" to the console.
*/
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match / {
<op-script-results> {
/* This writes the string to the console. */
<output> "I have a message for you.";
<output> "Here is the message:";
<output> "Hello World!";
}
}

Chapter 2:Try It Yourself: Writing Your Own Script Using the Boilerplate
Using the configuration boilerplate, create a new op script that outputs three separate lines of
text to the console. Copy this script to your Junos device and enable it. Now you can verify it
by executing it from the command-line.

version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match / {
<op-script-results> {
<output> "One";
<output> "Two";
<output> "Three";
}
}

Chapter 3:Try It Yourself: Working with Operators


Create a new script including two variables that are assigned numeric values. Add a third
variable and assign it the product of the first two variables. Display the value of the third
variable on the console.
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";
match / {
<op-script-results> {
var $first-variable = 100;
var $second-variable = 5;
var $third-variable = $first-variable * $second-variable;
<output> "Result: " _ $third-variable;
}
}

Chapter 3:Try It Yourself: Working with Command-line Arguments


Create a new script with a command-line argument that accepts a number from the user.
Include the $arguments global variable so that the command-line argument will be included in
the CLI help output. Perform a mathematical operation on the command-line argument and
output the result to the console. Execute the op script a few times, with a different number
provided on the command-line each time to verify that the result changes according to the
entered number.
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

var $arguments = {
<argument> {
<name> "number";
<description> "The number to multiply.";
}
}

param $number;

match / {
<op-script-results> {
<output> "Result: " _ $number * 55;
}
}

Chapter 3:Try It Yourself: Conditionally Assigning Variable Values


Create a new script with a command-line argument which can be set to either + or - signifying
the mathematical operation that you wish to perform. Create a variable that is assigned
conditionally based on the value of the command-line argument. If the command-line
argument is specified as a + then two values should be added together and assigned to the
variable. If the command-line argument is specified as a - then subtraction should be
performed between the two values and assigned to the variable. Output the result to the
console.
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

var $arguments = {
<argument> {
<name> "operator";
<description> "Either + or -";
}
}

param $operator;

match / {
<op-script-results> {
var $first = 31;
var $second = 14;

var $conditional = {
if( $operator == "+" ) {
expr $first + $second;
}
else if( $operator == "-" ) {
expr $first - $second;
}
}
<output> $conditional;
}
}

Chapter 3:Try It Yourself: Working with Named Templates


Create a new script that contains a named template. The template should write a string to the
result tree. Redirect this into a variable in the calling template and output the variable value to
the console.
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match / {
<op-script-results> {

var $redirected = { call output-string(); }

<output> $redirected;
}
}

template output-string() {
expr "Here is the output string";
}

Chapter 3:Try It Yourself: Working with Functions


Create a new script with a variable assigned to the value "Juniper Networks". Output the
following to the console on separate lines:
1. The variable value
2. The variable value - right justified in a 20 space field
3. The string length of the variable
4. The substring before the space
5. The string converted entirely into upper-case.
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match / {
<op-script-results> {

var $variable = "Juniper Networks";


<output> $variable;
<output> jcs:printf( "%20s", $variable );
<output> string-length( $variable );
<output> substring-before( $variable, " " );
<output> translate( $variable, "abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" );
}
}

Chapter 4:Try It Yourself: Invoking Junos Operational Commands


Following the example of the clear-statistics op script shown in this section, create an op script
that reboots the system. (Hint: The XML API Element needed is <request-reboot>).
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match / {
<op-script-results> {

var $result = jcs:invoke( "request-reboot" );

}
}

Chapter 4:Try It Yourself: Retrieving Information from Junos


Create a script similar to the show-admin-status.slax example script above, but instead of the
Admin Status report the MTU of a physical interface to the screen. The interface to be
displayed should be selected through a command-line argument.
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

var $arguments = {
<argument> {
<name> "interface";
<description> "Show MTU of interface";
}
}

param $interface;

match / {
<op-script-results> {

var $results = jcs:invoke( "get-interface-information" );

var $mtu = $results/physical-interface[name==$interface]/mtu;

/* Output the interface mtu to the console */


<output> "The mtu of " _ $interface _ " is " _ $mtu;
}
}

Chapter 4:Try It Yourself: Retrieving Information from Junos


Create a script that displays the logical interface MTU of all interfaces within your Junos
device.
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match / {
<op-script-results> {

var $results = jcs:invoke( "get-interface-information" );

for-each( $results/physical-interface/logical-interface/address-family/mtu ) {

if( . != "Unlimited" ) {
<output> "The family " _ ../address-family-name _ " MTU for " _ ../../name _ " is " _ .;
}
}
}
}

Chapter 4:Try It Yourself: Interacting with the User


Modify your script that displays the MTU of a single physical interface. Add a check to see if
the command-line argument for the interface has been entered. If it has not then request the
information from the user through the jcs:get-input() function.
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

var $arguments = {
<argument> {
<name> "interface";
<description> "Show MTU of interface";
}
}

param $interface;

match / {
<op-script-results> {

var $interface-value = {
if( string-length( $interface ) > 0 ) {
expr $interface;
}
else {
expr jcs:get-input( "Enter interface: " );
}
}

var $results = jcs:invoke( "get-interface-information" );

var $mtu = $results/physical-interface[name==$interface-value]/mtu;

/* Output the interface mtu to the console */


<output> "The mtu of " _ $interface-value _ " is " _ $mtu;
}
}

Chapter 4:Try It Yourself: Writing to the Syslog


Create an op script that logs the user name, script, product, and hostname to the syslog from
the user facility with a severity level of info.
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match / {
<op-script-results> {

var $syslog-message = "User: " _ $user _ " Script: " _ $script _ " Product: " _
$product _ " Hostname: " _ $hostname;
expr jcs:syslog( "user.info", $syslog-message );
}
}

Chapter 4:Try It Yourself: Reading the Junos Configuration


Create an op script that reads the configuration and outputs all the syslog file names to the
console.
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match / {
<op-script-results> {

var $configuration = jcs:invoke( "get-configuration" );

for-each( $configuration/system/syslog/file ) {
<output> "Syslog File: " _ name;
}
}
}
Appendix B: Supplemental Junos Automation Information from Part Two
Xxxx Xxxxxxxx xxxxxxxxxxx xxx xxxxxxxxxxx xx Xxxx Xxx xx xxxxxxxxx
xxxxx xxxxxxxxxx xxxxx xxxxxxx, xx xxxx xx xxxxxxx xxxxxxxxx xx xxx
Xxx Xx Xxxxxxxx xxxxxxxx.

Event Script Examples


Xxxx xxxxx xxxxxxx xx xxx Xxxxxxxx xxxxxxxx xxxxx xxxxxxxxxx
xxxxxxx, xxxxx xxxxxxxxx xxx xxxxxxxxxxxxx xxxx xxxxx xxxxxxx
xxxxx xxx xxxx xxx xx xxx xxxxxxx xxxxxxx xx xxxx xxxxxx. Xxxxxxxxx
xxxxxxxx xxx xxxxxxxx xxxxxx xxx xxxxxxx xx xxxxxxx xxxxxxxxxxxxx
xx xxxxx xxxxxxxxx.

Save <event-script-input>
Xxxx xxxxxxxxx xx xxxxx xxxxxx xxxx xxxxx xxx xx xxx <xxxxx-xxxxxx-
xxxxx> xxxxxx xxxx xxxx, xx xx xxxxxx xx xxxx x xxxx xx xxx xxxxxxxx
XXX xxxx xxxxxxxxx xxxx xxx xxxxx xxxxxx xxxxx xxxxxxx. Xxx xxxxx
xxxxxxx xx x xxxx xxxxxx xxxxx xxxxxx xx xxxxxx xxx xxxx xxxx xxxx
xxx xxxxx xxxxxxxxx. Xxx xxx xxxxxxx xxxxx xxxxxx, xxxx xxxxx
xxxxxx xx xxx xxxxx xxxxxx xxxxxx xxxx x xxxxxxxxxx xxxxxxxxxxx xxx
xxxxxx-xxxxxxxx xxx xxx xxxxxx-xxxxxx xxx xx xxx. Xxxx, xxxx xxx xxxxx
xxxxxx, Xxxxx xxxxxxxx xxx xxxxxx xxx xxxxx xxx xxxxxx <xxxxx-xxxxxx-
xxxxx> xxxxxxxx xx xxx xxxxxx xxxx xxxxxx xxx <xxxxx-xxxxxx-xxxxxxx>
xxxxxx xxxxxx xxxx xxxxxxx.
Xxx xxxxxxx xxxxxxx xxxxxxxx xx Xxxxx 9.3 xxxxxxx xx xxx xxx xx xxx
<xxxxx-xxxxxx-xxxxx> xxxxxx xxxx xxxxxxx.

Xxxx xx xx xxxxxxx xx xxx xxxxxxxx xxxxxx:


<event-script-results>
<event-script-input>
<trigger-event>
<id>UI_COMMIT</id>
<type>syslog</type>
<generation-time junos:seconds="1251137835">
2009-08-24 11:17:15 PDT
</generation-time>
<process>
<name>mgd</name>
<pid>4192</pid>
</process>
<hostname>Junos</hostname>
<message>UI_COMMIT: User 'user' requested 'commit' operation (comment:
none)</message>
<facility>interact</facility>
<severity>notice</severity>
<attribute-list>
<attribute>
<name>username</name>
<value>user</value>
</attribute>
<attribute>
<name>command</name>
<value>commit</value>
</attribute>
<attribute>
<name>message</name>
<value>none</value>
</attribute>
</attribute-list>
</trigger-event>
</event-script-input></event-script-results>

Xx xxxxxxx xxx xxxxx xxxxxx, xxx xxxxxxxxx xxxxx xxxxxxxxxxxxx xxx


xxxx:
event-options {
policy on-commit {
events ui_commit;
then {
event-script save-event-script-input.slax {
output-filename event-script-input;
destination local;
output-format xml;
}
}
}
event-script {
file save-event-script-input.slax;
}
destinations {
local {
archive-sites {
/var/tmp;
}
}
}
}
Xxxx xx xxx xxxx xxx xxxx-xxxxx-xxxxxx-xxxxx.xxxx:
/*
* This simple script is used to capture the <event-script-input> received by
* an event script and write it in XML format to the output file. It is intended
* to get a glimpse into what data an event script will receive from a particular
* event policy. For example, if you want to check what the <event-script-input>
* would look like for a policy like this:
*
* policy on-commit {
* events ui_commit;
* ....
*}
*
* Then you could configure it like this:
*
*
* policy on-commit {
* events ui_commit;
* then {
* event-script save-event-script-input.slax {
* destination local;
* output-format xml;
* output-filename event-script-input;
* }
* }
*}
*
* Minimum JUNOS version is 9.3 because of the use of <event-script-input>
*
*/

version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match / {
<event-script-results> {

/*
* This copies the entire XML contents of <event-script-input> into
* the result tree as a child element of <event-script-results>.
*/
copy-of event-script-input;
}
}

Change Route Advertisement


Xxxx xxxxx xxxxxx xxxxxx xx xxxxxx xxxxxxx xxxxxx-xxxxxxxxx xxxxx
xx xxx xxxxxx xx xxxxxxxxxxx xxxxxx xxxxx xx xx xxxxxxxxx-xxxxxxxx
xxxxxx. Xxx xxxxxx xx xxxxxxxx xx xxxx xx x xxxxxxxx xxxxxxxx xxx
xxx xx xxxxxxxx xxxxxx xx xxx xxxxx xxxxxxxxx xxxxx xx xxxxxx
xxxxxxx. Xxxx xxx xxx xxxxxxxx xxxxxxxxxxxxx xxxxxxxx xxxx xxx
xxxxx xxxxxx xx xxxxxxxx xx xxxx xxxx:
„„n Aggregate member links are ge-4/1/0 and ge-5/1/0.
„„n Policy-statement is “export”, term is “advertise”.
„„n If both member links are operational then the route is accepted
and local-preference is set to 100.
„„n If one member link is operational then the route is accepted and
local-preference is set to 50.
„„n If no member links are operational then the route is rejected.
Xxx xxxxxxx xxxxxxx xxxxxxxx xxx xxxx xxxxx xxxxxx xx Xxxxx 9.3
xxxxxxx xxxxxxxxxxxxx xxxxxxx xxx xxxxx xxxxxxxxx xxxx xxx xxx:xxxx()
xxx xxx:xxxxx() xxxxxxxxx xxx xxx:xxxx-xxxxxxxxxxxxx xxxxxxxx.
Xxx xxxxx xxxxxx xx xxxxxxxx xxxxxx xxx xxxxx xxxxxx xx xxx xxxx
xxxxxxxxxxxxx xxxxxx xx xxx xxxxxxxxx xx xxxxxx xxx xxxxx xxxxxx:
event-options {
event-script {
file change-route-advertisement.slax;
}
}

NOTE The change-route-advertisement.slax event script assumes that the advertise


term is configured correctly at the time the script is enabled. The event
script does not check the configuration until one of the member links
goes up or down.
Xxxx xx xxx xxxx xxx xxx xxxxxx-xxxxx-xxxxxxxxxxxxx.xxxx xxxxx xxxxxx:
/*
* This script is designed to alter the local preference of an export policy
* based on how many of the ge-links of the aggregate ethernet uplink are
* functional.
*
* The script works with the following configuration:
*
* Aggregate Ethernet link with 2 members: ge-4/1/0, ge-5/1/0
*
* IBGP export policy named: export with term name: advertise
*
* If both links are up then the local-preference is set to 100. If one link
* is up then the local-preference is set to 50, if neither link is up then
* the term is changed from accept to reject.
*
* Minimum JUNOS version is 9.3 because of the use of jcs:open(),
* jcs:load-configuration, and jcs:close().
*
*/

version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

/*
* This is the embedded event policy. The event script will be executed anytime
* either ge-4/1/0 or ge-5/1/0 goes up or down. This is accomplished by matching
* on the SNMP_TRAP_LINK_UP and SNMP_TRAP_LINK_DOWN events.
* These events are matched only for the two interfaces by using attributes-match
* condition statements.
*/
var $event-definition = {
<event-options> {
<policy> {
<name> "change-route-advertisement";
<events> "snmp_trap_link_up";
<events> "snmp_trap_link_down";
<attributes-match> {
<from-event-attribute> "snmp_trap_link_up.interface-name";
<condition> "matches";
<to-event-attribute-value> "(ge-4/1/0.0)|(ge-5/1/0.0)";
}
<attributes-match> {
<from-event-attribute> "snmp_trap_link_down.interface-name";
<condition> "matches";
<to-event-attribute-value> "(ge-4/1/0.0)|(ge-5/1/0.0)";
}
<then> {
<event-script> {
<name> "change-route-advertisement.slax";
}
}
}
}
}

/*
* Note that this script does not include the <event-script-results> element.
* While part of the boilerplate it is not actually required unless the result
* tree will be used by the script. Because this script does not use any result
* tree elements the <event-script-results> element is not necessary. (But it
* would not cause any problems to include it).
*/
match / {

/*
* Gather the interface information, this will tell us if they are up or
* down.
*/
var $interface-rpc = {
<get-interface-information> {
<terse>;
}
}
var $interfaces = jcs:invoke( $interface-rpc );

/*
* The only interfaces we care about are ge-4/1/0 and ge-5/1/0, count how
* many of them are up.
*/
var $up-count = count( $interfaces/physical-interface[name == "ge-4/1/0" ||
name == "ge-5/1/0" ]/logical-interface[oper-status == "up"]);

/*
* No changes should be made if the policy is already correct. Gather the
* current policy configuration for comparison.
*/
var $configuration-rpc = {
<get-configuration database="committed"> {
<configuration> {
<policy-options> {
<policy-statement> {
<name> "export";
}
}
}
}
}
var $current = jcs:invoke( $configuration-rpc );

/* Get the "export policy term advertise then" element node to simplify location paths */
var $then = $current/policy-options/policy-
statement[name=="export"]/term[name=="advertise"]/then;

/*
* This next section checks if any changes are needed and makes them if
* warranted. The results are stored into a variable called $results so
* that any commit errors can be reported.
*/
var $results := {

/* If no interfaces are up then the term should be set to reject. */


if( $up-count == 0 ) {

/* Compare against the current policy, if set to accept then we need to change it */
if( $then/accept ) {
var $configuration = {
<configuration> {
<policy-options> {
<policy-statement> {
<name> "export";
<term> {
<name> "advertise";
<then replace="replace"> {
<reject>;
}
}
}
}
}
}

/* Log a syslog message that the script is making a configuration change. */


expr jcs:syslog( "external.notice", "Changing route advertisement to reject." );

/*
* Open a connection, load and commit the configuration, and close the
connection.
* All results are written to the result tree and will be set as the value of the
* $results variable.
*/
var $connection = jcs:open();
call jcs:load-configuration( $connection, $configuration, $action = "replace" );
copy-of jcs:close( $connection );
}
}
/* If one interface is up then the term should be set to accept with a local-preference
of 50 */
else if( $up-count == 1 ) {

/* Compare against current policy to see if a change is needed */


if( $then/reject || not( $then/local-preference[local-preference=="50"] ) ) {
var $configuration = {
<configuration> {
<policy-options> {
<policy-statement> {
<name> "export";
<term> {
<name> "advertise";
<then replace="replace"> {
<accept>;
<local-preference> {
<local-preference> "50";
}
}
}
}
}
}
}

/* Log a syslog message that the script is making a configuration change. */


expr jcs:syslog( "external.notice", "Changing route advertisement to local-pref
50." );

/*
* Open a connection, load and commit the configuration, and close the
connection.
* All results are written to the result tree and will be set as the value of the
* $results variable.
*/
var $connection = jcs:open();
call jcs:load-configuration( $connection, $configuration, $action = "replace" );
copy-of jcs:close( $connection );
}
}
/* If both interfaces are up set policy to accept with a local-preference of 100 */
else {

/* Compare against current policy to see if a change is needed */


if( $then/reject || not( $then/local-preference[local-preference=="100"] ) ) {
var $configuration = {
<configuration> {
<policy-options> {
<policy-statement> {
<name> "export";
<term> {
<name> "advertise";
<then replace="replace"> {
<accept>;
<local-preference> {
<local-preference> "100";
}
}
}
}
}
}
}

/* Log a syslog message that the script is making a configuration change. */


expr jcs:syslog( "external.notice", "Changing route advertisement to local-pref
100." );

/*
* Open a connection, load and commit the configuration, and close the
connection.
* All results are written to the result tree and will be set as the value of the
* $results variable.
*/
var $connection = jcs:open();
call jcs:load-configuration( $connection, $configuration, $action = "replace" );
copy-of jcs:close( $connection );
}
}
}

/*
* Check for any xnm:error results from the commit operations. If any occur in the
$results
* variable then log them to the syslog
*/
if( $results//xnm:error ) {
for-each( $results//xnm:error ) {
expr jcs:syslog( "external.error", "Error committing advertisement changes: ",
message );
}
}
}

Static Route Next-Hop Watcher


Xxxx xxxxx xxxxxx xxxxxxx xxxxx xxx xx xxxxxx xxx Xxxxx
xxxxxxxxxxxxx xxxxx xx xxx xxxxxxx xx Xxxx-Xxxx Xxxxxxxxxxx
Xxxxxxxxxx (XXX) xxxxx. Xxx xxxxx-xxxx-xxx.xxxx xxxxx xxxxxx
xxxxxxxxx/xxxxxxxxxxx x xxxxxx xxxxx xxxxx xx xxx xxxxxxx/xxxxxxx
xx xxx XXX xxxx xx xxx xxxxx’x xxxx-xxx. Xxx xxxxx xxxxxx xxxx xx
xxxxxxxx xx xxxx xxxx xxx xxxxxxxxx xxxxxxxxxxxxx xxxxxxxx, xxx
xxxxx xx xxxxxxxx xx xxxx xxxx xxxxxxxxx xxxxxx xxxxxx xx XXX
xxxxx:
„„n Static route is 192.168.1.0/24
„„n RPM probe name is: Next-Hop
„„n RPM test name is: 10.0.0.1
Xxx xxxxxxx xxxxxxx xxxxxxxx xx Xxxxx 9.4 xxxxxxx xxx xxxxx xxxxxx
xxxx x xxxxxx xxxxxx xxxxx xx x xxxxxxxxxxx xxxxx, xxxxx xxx
xxxxxxxxxx xx xxxx xxxxxxx.
Xxx xxxxx xxxxxx xx xxxxxxxx xxxxxx xxx xxxxx xxxxxx, xx xxxx xx xxx
xxxx xxxxxxxxxxxxx xxxxxxxxx xx xxxxxxxxx xxx xxxxxx:
event-options {
event-script {
file watch-next-hop.slax;
}
}

NOTE The watch-next-hop.slax event script assumes that the static route is properly
activated or deactivated at the time the script is enabled. The event
script does not check the configuration until the RPM test results change
or the system is rebooted.
Xxxx xx xxx xxxx xxx xxx xxxxx-xxxx-xxx.xxxx xxxxx xxxxxx:
/*
* This event script activates/deactivates a static route based on the success
* or failure of a RPM test to the route’s next hop. When the test is successful
* the route will be activated. When the test fails the route will be deactivated.
*
* This script is hardcoded to work with a single static route and RPM test. These
* could be easily modified to meet any unique requirements:
*
* Static Route: 192.168.1.0/24
* RPM Probe: Next-Hop
* RPM Test: 10.0.0.1
*
* Minimum version is JUNOS 9.4 because of the use of the SYSTEM bootup
* event "Starting of initial processes complete"
*
*/

version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

/*
* The embedded event policy - the script should be executed when a
* PING_TEST_FAILED or PING_TEST_COMPLETED event occur with the indicated
* test-owner and test-name attributes for the event.
*
* within conditions are included in each policy to ensure that the script
* will not be repeatedly called when no change is occurring. The policy
* will only execute the script if the device recently booted or if the RPM
* probe result recently changed from failed to completed or vice versa.
*/
var $event-definition = {
<event-options> {
<policy> {
<name> "next-hop-probe-failed";
<events> "ping_test_failed";
<attributes-match> {
<from-event-attribute> "ping_test_failed.test-owner";
<condition> "matches";
<to-event-attribute-value> "Next-Hop";
}
<attributes-match> {
<from-event-attribute> "ping_test_failed.test-name";
<condition> "matches";
<to-event-attribute-value> "10.0.0.1";
}
<attributes-match> {
<from-event-attribute> "system.message";
<condition> "matches";
<to-event-attribute-value> "Starting of initial processes complete";
}
<within> {
<name> "600";
<events> "ping_test_completed";
<events> "system";
}
<then> {
<event-script> {
<name> "watch-next-hop.slax";
}
}
}
<policy> {
<name> "next-hop-probe-succeeded";
<events> "ping_test_completed";
<attributes-match> {
<from-event-attribute> "ping_test_completed.test-owner";
<condition> "matches";
<to-event-attribute-value> "Next-Hop";
}
<attributes-match> {
<from-event-attribute> "ping_test_completed.test-name";
<condition> "matches";
<to-event-attribute-value> "10.0.0.1";
}
<attributes-match> {
<from-event-attribute> "system.message";
<condition> "matches";
<to-event-attribute-value> "Starting of initial processes complete";
}
<within> {
<name> "600";
<events> "ping_test_failed";
<events> "system";
}
<then> {
<event-script> {
<name> "watch-next-hop.slax";
}
}
}
}
}

match / {
<event-script-results> {
/* Learn the event type, either a PING_TEST_FAILED or PING_TEST_COMPLETED */
var $event-type = event-script-input/trigger-event/id;

/* Retrieve the current configuration for the static route */


var $configuration-rpc = {
<get-configuration database="committed"> {
<configuration> {
<routing-options>;
}
}
}
var $current = jcs:invoke( $configuration-rpc );

/* Grab the routing-options static node to make further location paths shorter */
var $static = $current/routing-options/static;

/* Is the route currently inactive? */


var $inactive = $static/route[name == "192.168.1.0/24"]/@inactive;

/*
* Compare the event type vs the current value of $inactive. If they
* do not match then a configuration change must be performed.
*/

/* RPM test failed but the route is currently active */


if( $event-type == "PING_TEST_FAILED" && jcs:empty( $inactive ) ) {

/* Needed configuration change */


var $configuration = {
<configuration> {
<routing-options> {
<static> {
<route inactive="inactive"> {
<name> "192.168.1.0/24";
}
}
}
}
}

/* Open connection, load and commit the change, and close connection */
var $connection = jcs:open();
var $results := {
call jcs:load-configuration( $connection, $configuration );
copy-of jcs:close( $connection );
}

/* If any errors occurred during the commit process then report them to the syslog
*/
if( $results//xnm:error ) {
for-each( $results//xnm:error ) {
expr jcs:syslog( "external.error", "Error deactivating 192.168.1.0/24: ",
message );
}
}
/* Otherwise, report success */
else {
expr jcs:syslog( "external.notice", "Static route 192.168.1.0/24 disabled." );
}
}
/* RPM test succeeded but the route is currently inactive */
else if( $event-type == "PING_TEST_COMPLETED" && $inactive ) {

/* Needed configuration change */


var $configuration = {
<configuration> {
<routing-options> {
<static> {
<route active="active"> {
<name> "192.168.1.0/24";
}
}
}
}
}

/* Open connection, load and commit the change, and close connection */
var $connection = jcs:open();
var $results := {
call jcs:load-configuration( $connection, $configuration );
copy-of jcs:close( $connection );
}

/* If any errors occurred during the commit process then report them to the syslog
*/
if( $results//xnm:error ) {
for-each( $results//xnm:error ) {
expr jcs:syslog( "external.error", "Error activating 192.168.1.0/24: ",
message );
}
}
/* Otherwise, report success */
else {
expr jcs:syslog( "external.notice", "Static route 192.168.1.0/24 activated." );
}
}
}
}

Try It Yourself Solutions in Part Two


Xxxx xxxxxxx xx xxx Xxxxxxxx xxxxxxxx xxxxxx xxxxxxxxx xxx xxxx xx
xxx Xxx Xx Xxxxxxxx xxxxxxxx xx Xxxxxxxx 5 xxxxxxx 8.

Chapter 5Try It Yourself: Simulating Events with the Logger Utility


1. Use help syslog to identify an event of interest and its attributes.
2. Configure a syslog file to use structured-data format.
3. Using the logger utility, generate an artificial version of the selected event including values
for all of its attributes.
4. Verify that the event was created as expected by viewing the structured-data syslog file.

user@Junos> help syslog RPD_IGMP_JOIN


Name: RPD_IGMP_JOIN
Message: Listener <source-address> sent a join to <destination-address> for group
<group-address> source
<sender-address> on interface <interface-name> at <time>
Help: IGMP join event
Description: IGMP join event.
Type: Event: This message reports an event, not an error
Severity: info

system {
syslog {
file structured {
any any;
structured-data;
}
}
}

user@Junos> start shell


% logger -e RPD_IGMP_JOIN -a source-address=10.0.0.1 -a destination-address=10.0.0.2 -a
group=225.1.1.1

user@Junos> show log structured | match RPD_IGMP_JOIN


<13>1 2009-08-27T07:22:49.394-07:00 JUNOS logger - RPD_IGMP_JOIN
[junos@2636.1.1.1.2.9 source-address="10.0.0.1" destination-address="10.0.0.2"
group="225.1.1.1"]

Chapter 5 Try It Yourself: Logging a Syslog Message in Response to an Event


1. Using the log-hello-world.slax script as an example, create an event script that logs a message
to the syslog.
2. Copy the event script to the Junos device and enable the script in the configuration.
3. Select an event ID of interest and configure an event policy that executes the event script in
response to the system event.
4. Use the logger utility to simulate the event and verify that the desired message is logged to
the syslog.

/* log-syslog.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match / {
<event-script-results> {

/* Send to the syslog */


expr jcs:syslog("external.info", "I‘ve been executed!");

}
}

user@Junos> file list /var/db/scripts/event/log-syslog.slax


/var/db/scripts/event/log-syslog.slax

event-options {
policy log-message {
events rpd_igmp_join;
then {
event-script log-syslog.slax;
}
}
event-script {
file log-syslog.slax;
}
}

user@Junos> start shell


% logger -e RPD_IGMP_JOIN

user@Junos> show log messages | match cscript


Aug 27 07:30:01 JUNOS cscript: I‘ve been executed!

Chapter 5 Try It Yourself: Matching Nonstandard Events


Find a nonstandard event that has been logged to the syslog of your Junos device. Craft an
event policy that matches this event and executes an event script. The event script should
write a message to the syslog indicating that the script was executed.

user@Junos> show log messages | match "becoming master"


Aug 27 08:07:46 JUNOS /kernel: mastership: routing engine 0 becoming master

event-options {
policy log-message {
events kernel;
attributes-match {
kernel.message matches "routing engine.*becoming master";
}
then {
event-script log-syslog.slax;
}
}
event-script {
file log-syslog.slax;
}
}

/* log-syslog.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match / {
<event-script-results> {

/* Send to the syslog */


expr jcs:syslog("external.info", "I‘ve been executed!");

}
}

Chapter 5 Try It Yourself: Time-based Configuration Changes


Create a local user account called "test-user" on your Junos device. Create the necessary
generated events, event policies, and event scripts to have the "test-user" automatically
assigned to the super-user class from 8am to 5pm and the read-only class from 5pm to 8am.
event-options {
event-script {
file change-user-class.slax;
}
}

/* change-user-class.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

/* Embedded event policy */


var $event-definition = {
<event-options> {
<generate-event> {
<name> "08:00";
<time-of-day> "08:00:00 +0000";
}
<generate-event> {
<name> "17:00";
<time-of-day> "17:00:00 +0000";
}
<policy> {
<name> "change-user-class";
<events> "08:00";
<events> "17:00";
<then> {
<event-script> {
<name> "change-user-class.slax";
}
}
}
}
}

match / {
<event-script-results> {
/* Determine which event triggered the script */
var $event-id = event-script-input/trigger-event/id;

if( $event-id == "08:00" ) {


/* Change user to super-user */
var $configuration = {
<configuration> {
<system> {
<login> {
<user> {
<name> "test-user";
<class> "super-user";
}
}
}
}
}
/* Open connection, load and commit, close connection */
var $connection = jcs:open();
var $results := {
call jcs:load-configuration( $connection, $configuration );
copy-of jcs:close( $connection );
}

/* If any errors occurred during the commit process then report them to the syslog
*/
if( $results//xnm:error ) {
for-each( $results//xnm:error ) {
expr jcs:syslog( "external.error", "Error setting test-user to super-user",
message );
}
}
/* Otherwise, report success */
else {
expr jcs:syslog( "external.notice", "test-user set to super-user" );
}
}
else {
/* Change user to read-only */
var $configuration = {
<configuration> {
<system> {
<login> {
<user> {
<name> "test-user";
<class> "read-only";
}
}
}
}
}
/* Open connection, load and commit, close connection */
var $connection = jcs:open();
var $results := {
call jcs:load-configuration( $connection, $configuration );
copy-of jcs:close( $connection );
}

/* If any errors occurred during the commit process then report them to the syslog
*/
if( $results//xnm:error ) {
for-each( $results//xnm:error ) {
expr jcs:syslog( "external.error", "Error setting test-user to read-only",
message );
}
}
/* Otherwise, report success */
else {
expr jcs:syslog( "external.notice", "test-user set to read-only" );
}
}

}
}

Chapter 6Try It Yourself: Executing Commands


Create an event policy that reacts to a UI_COMMIT event by storing the configuration of the user
account that performed the commit. The output file should be saved locally in the /var/tmp
directory in XML format.
event-options {
policy save-user-config {
events ui_commit;
then {
execute-commands {
commands {
"show configuration system login user {$$.username}";
}
output-filename user-config;
destination local;
output-format xml;
}
}
}
destinations {
local {
archive-sites {
/var/tmp;
}
}
}
}

Chapter 6 Try It Yourself: Uploading Files


Create an event policy that uploads the messages log file to a remote server every day.
event-options {
generate-event {
midnight time-of-day "00:00:00 +0000";
}
policy upload-messages {
events midnight;
then {
upload filename /var/log/messages destination remote;
}
}
destinations {
remote {
archive-sites {
"ftp://user@10.0.0.1" password "$9$nWgP6tO1IclvLEcVw2gJZ69C"; ## SECRET-
DATA
}
}
}
}

Chapter 6 Try It Yourself: Raising SNMP Traps


Create an event policy that raises an SNMP trap every time a user enters or leaves the
configuration database.

event-options {
policy raise-trap {
events [ ui_dbase_login_event ui_dbase_logout_event ];
then {
raise-trap;
}
}
}

Chapter 6 Try It Yourself: Ignoring Events


Add an ignore-event policy before the event policy that was created in the Executing
Commands section. This ignore-event policy should run if a commit is performed more than
once per minute.

event-options {
policy ignore-commit {
events ui_commit;
within 60 {
trigger after 1;
}
then {
ignore;
}
}
policy save-user-config {
events ui_commit;
then {
execute-commands {
commands {
"show configuration system login user {$$.username}";
}
output-filename user-config;
destination local;
output-format xml;
}
}
}
destinations {
local {
archive-sites {
/var/tmp;
}
}
}
}

Chapter 8Try It Yourself: Logging Out Users


Using the clear bgp neighbor command without specifying a peer address causes all BGP peers to
be reset. Write an event policy and event script that automatically disconnects any user who
runs this command without including a peer address.
event-options {
policy logout-user {
events ui_cmdline_read_line;
attributes-match {
ui_cmdline_read_line.command matches "^(run )?clear bgp neighbor $";
}
then {
event-script user-logout.slax {
arguments {
username "{$$.username}";
}
}
}
}
event-script {
file user-logout.slax;
}
}

/* user-logout.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

/* Username argument */
param $username;

match / {

/* Logout the user */


var $command = <command> "request system logout user " _ $username;

var $results = jcs:invoke( $command );

/* If any errors occurred then report them to the syslog */


if( $results/..//xnm:error ) {
for-each( $results/..//xnm:error ) {
expr jcs:syslog( "external.error", "Error logging out ", $username, ": ", message);
}
}
else {
var $message = "Logged out " _ $username _ " for clearing all BGP neighbors.";
expr jcs:syslog( "external.notice", $message );
}
}
Chapter 8Try It Yourself: Dampening Event Reactions
Chapter 3 included a save-core event policy that demonstrated the upload filename policy action.
Using that event policy as a guideline, create a policy that executes an event script in
response to an eventd core dump. The event script should upload all eventd core files to a
remote server, but the action should be dampened by the jcs:dampen() function to a maximum
of 1 time per minute. When this limit is exceeded a syslog message should be logged instead,
indicating that the core upload process was dampened.
event-options {
event-script {
file save-cores.slax;
}
}

/* save-cores.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

/* Embedded event policy */


var $event-definition = {
<event-options> {
<policy> {
<name> "save-core";
<events> "kernel";
<attributes-match> {
<from-event-attribute> "kernel.message";
<condition> "matches";
<to-event-attribute-value> "(eventd).*(core dumped)";
}
<then> {
<event-script> {
<name> "save-cores.slax";
}
}
}
}
}

match / {
<event-script-results> {

if( jcs:dampen( "save-core", 1, 1 ) ) {


var $rpc = {
<file-list> {
<path> "/var/tmp/eventd.core*";
}
}
var $file-list = jcs:invoke( $rpc );

/* Pause a few seconds to let the core be gathered */


expr jcs:sleep(5);

for-each( $file-list/directory/file-information/file-name ) {
var $copy-rpc = {
<file-copy> {
<source> .;
<destination> "ftp://user:password@10.0.0.1";
}
}
var $results = jcs:invoke( $copy-rpc );

/* If any errors occurred then report them to the syslog */


if( $results/..//xnm:error ) {
for-each( $results/..//xnm:error ) {
expr jcs:syslog( "external.error", "Error copying eventd cores: ", message );
}
}
}
}
else {
expr jcs:syslog("external.notice", "Dampening eventd core upload." );
}
}
}

Chapter 8 Try It Yourself: Embedding Event Policy


Choose an event policy and event script that you created in one of the prior Try It Yourself
exercises. Remove the event policy from the configuration and embed the policy within the
event script.
event-options {
event-script {
file log-syslog-embedded.slax;
}
}

/* log-syslog-embedded.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

var $event-definition = {
<event-options> {
<policy> {
<name> "log-message";
<events> "rpd_igmp_join";
<then> {
<event-script> "log-syslog-embedded.slax";
}
}
}
}

match / {
<event-script-results> {

/* Send to the syslog */


expr jcs:syslog("external.info", "I've been executed!");

}
}

Chapter 8 Try It Yourself: Using <event-script-input>


Revise your earlier event script that automatically logged out users that used the clear bgp
neighbor command without specifying a peer address. Remove the event policy from the
configuration and embed the policy within the event script’s $event-definition variable. Remove
any command-line arguments used to communicate which user performed the command and
instead use the <event-script-input> source tree element to determine which user should be
logged out.

event-options {
event-script {
file logout-user.slax;
}
}

/* logout-user.slax */
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

var $event-definition = {
<event-options> {
<policy> {
<name> "logout-user";
<events> "ui_cmdline_read_line";
<attributes-match> {
<from-event-attribute> "ui_cmdline_read_line.command";
<condition> "matches";
<to-event-attribute-value> "^(run )?clear bgp neighbor $";
}
<then> {
<event-script> {
<name> "logout-user.slax";
}
}
}
}
}

match / {

/* Get the user name */


var $username = event-script-input/trigger-event/attribute-
list/attribute[name=="username"]/value;

/* Logout the user */


var $command = <command> "request system logout user " _ $username;
º
var $results = jcs:invoke( $command );

/* If any errors occurred then report them to the syslog */


if( $results/..//xnm:error ) {
for-each( $results/..//xnm:error ) {
expr jcs:syslog( "external.error", "Error logging out ", $username, ": ", message);
}
}
else {
var $message = "Logged out " _ $username _ " for clearing all BGP neighbors.";
expr jcs:syslog( "external.notice", $message );
}
}

Appendix C: Supplemental Junos Automation Information from Part Three


Xxxx Xxxxxxxx xxxxxxxxxxx xxx xxxxxxxxxxx xxxxxxxxx Xxxx Xxxxx xx
xxxxxxxxx xx xxxxxxxxxx xxxxxx xxxxxx xxxxxxx xx xxxx xx xxxxxxxx
xx xxxxxxxxx xx xxx Xxx Xx Xxxxxxxx xxxxxxxx.

Commit Script Example


Xxxx xxxxx xxxxxxx xx Xxxxxxxx X xxxxxxxx xx xxxxxxxxxx xxxxxx
xxxxxx xxxxxxxxxxxx xxx xxxxxxxxxxxxx xx xxxxxx xxxxxxx xxx xxxxxx
xxx xx xxx xxxxxxx xxxxxxx xx xxxx xxxxxx. Xxxxxxxxx xxxxxxxx xxx
xxxxxxxx xxxxxx xxx xxxxxx xx xxxxxxx xxxxxxxxxxxxx xx xxx
xxxxxxxxx.

Policy-Based Routing
Xxxxx xxxxxxxx xxxxxx-xxxxx xxxxxxx xxxxxxx xxxxxx-xxxxx
xxxxxxxxxx. X xxxxxxxx xxxxxx xxxx xxxxxxx xxx xxxxxxxx xxxxxxx xx
xx xxxxxxxxx xxxxx xxx xxxxxxxxxx, xxx xxxx xxxxxxxx xxxxxxxxxx
xxxxx xx xxxxxxxxx xxxx xxx xxxxxxxxx xxxxxx xx xxxx xxx xxxxxxx xx
xxx xxxxxxx xxxxxxxxxxx.
Xxx xxxxx-xxxx xxxxxxxx xxxxxx xxxxxx-xxxxx xxxxxxxxxx xxxxxxxx
xxxxx xxxxxxxxxxx, xxx xx xxx xxxxxx xxxxxxxxxx xxxx xxxx x xxxxxx
xxxx-xxx xxxxxxxxx xx xxxxxxx.
Xxx xxxxxx-xxxxx.xxxx xxxxxx xxxxxx xxxxxxxx x xxxxxxxxxx xxxxxx
xx xxxxxx-xxxxx xxxxxxx. Xxx xxxx xxxxxx xxxxxxxxx xx xxxxxx
xxxxxxx xx x xxxxxx xxxxxxxxxxx xx xx xxxxx xxx xxxxxxxxx xxxxx
xxxxx xxx xxxxxxxx xxxxxx xxxx’x xxxx xxxxxxxxx:
apply-macro policy-route {
next-hop x.x.x.x;
}
Xxxx xx xx xxxxxxx xx x xxxxxxxx xxxxxx xxxx xxxx xxxx xxxxx xx
xxxxxx xxxxxxx xxxx xxx xxxxxxxx xxxxxxx xx xxxxxxxxx
xxxxxxxxxxxx:
firewall {
family inet {
filter customer-input {
term source-a {
from {
source-address {
192.168.1.1/32;
}
}
then {
apply-macro policy-route {
next-hop 10.0.0.1;
}
}
}
term source-b {
from {
source-address {
192.168.1.14/32;
}
}
then {
apply-macro policy-route {
next-hop 10.0.0.2;
}
}
}
}
}
}

Xxxxx xxxx xxxxx xxxxxxxxxxxxx xxxxxxx xxx xxxxxx xx xxxxxxxxxxxxx


xxxxxxxxxx xxxx xx xxxxxxxxxxxxx xxxx xxxxx xx xxx xx xxxxxx-xxxxx
xxxxxxx. Xxx xxxxxx xxxxxx xxxx xxx xxxxx xxxxxxxxx xxxxxxxxxxxxx
xxxxxxxxxx xxxxxx xxx xxxxxx xxxxxxx xx xxxxxxxx xx xxx xxxxxxxx xx
xxx xxxxxx-xxxxx xxxxxx. Xxxxx xxxx xxxxx xxxxxxxxxx xxxxxxxxxxx
xx xxxxx xx xxxxxxx xxxxxxxxxx xxx xxxxxxxxxxxxx, xxx xx xxx xxxx
xxxxxxxxx xxxxxxxxxxxxx xxxxxxxxxx xxxx xxxxx xx xxxxxx-xxxxx
xxxxxxx xxx xxx xxxxx-xxxxx xxxxxxxxxx.
NOTE As discussed in Chapter 11, transient changes are communicated to
Junos and affect its operation but do not appear in the configuration file.
Xxxx xx xxx xxxxxxxxxxxxx xxxx xx xxxxx xxxxx xx xxx xxxxx xxxxxxxx
xxxxxx xxx xxx xxxxxx:

routing-options {
interface-routes {
rib-group inet fbf-ribs;
}
rib-groups {
fbf-ribs {
import-rib [ inet.0 fbf-10.0.0.1.inet.0 fbf-10.0.0.2.inet.0 ];
}
}
}
firewall {
family inet {
filter customer-input {
term source-a {
then {
routing-instance fbf-10.0.0.1;
}
}
term source-b {
then {
routing-instance fbf-10.0.0.2;
}
}
}
}
}
routing-instances {
fbf-10.0.0.1 {
instance-type forwarding;
routing-options {
static {
route 0.0.0.0/0 next-hop 10.0.0.1;
}
}
}
fbf-10.0.0.2 {
instance-type forwarding;
routing-options {
static {
route 0.0.0.0/0 next-hop 10.0.0.2;
}
}
}
}

Xxxxxx xxx xxxxxx xxxxxxx Xxxxx xxxxxx xxx xxxxx xxxxxxx xxxx xxx
xxxxxxxx xxxxxxxxxxxxx xx xxxxxxxxx xxxxxxx. Xxxxx xxx xxxxxxx xx
xxx xxxxxx xx xxx xxxxxxxxxxxxx xxxx, xxxxx xxxxxxx xxx xx xxxx xx
xxx xxxxxxx xxxxxx xxxx xxx xxxxxxx xx xxxxxxxxxxx xxx xxx xxx
xxxxxxxxxx xxxxxxxxx:
fbf-10.0.0.2.inet.0: 5 destinations, 5 routes (5 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

0.0.0.0/0 *[Static/5] 00:12:05


> to 10.0.0.2 via ge-2/0/0.0
10.0.0.0/24 *[Direct/0] 00:12:05
> via ge-2/0/0.0
10.0.0.100/32 *[Local/0] 00:12:05
Local via ge-2/0/0.0
192.168.1.0/24 *[Direct/0] 00:12:05
> via ge-4/1/0.0
192.168.1.50/32 *[Local/0] 00:12:05
Local via ge-4/1/0.0

fbf-10.0.0.1.inet.0: 5 destinations, 5 routes (5 active, 0 holddown, 0 hidden)


+ = Active Route, - = Last Active, * = Both

0.0.0.0/0 *[Static/5] 00:12:05


> to 10.0.0.1 via ge-2/0/0.0
10.0.0.0/24 *[Direct/0] 00:12:05
> via ge-2/0/0.0
10.0.0.100/32 *[Local/0] 00:12:05
Local via ge-2/0/0.0
192.168.1.0/24 *[Direct/0] 00:12:05
> via ge-4/1/0.0
192.168.1.50/32 *[Local/0] 00:12:05
Local via ge-4/1/0.0

Xxx xxxxxx-xxxxx.xxxx xxxxxx xxxxxx xxxxxxxxx xxxxxxxxx xxxx xx


xxxxxxxx xxxxxxxxx-xxxxxx xxx-xxxxx, xx xxxx xx xx xxxx xxx xxxx xx xxxxxx-
xxxxxx. Xxxx xx xxx xxxx xxxx xx xxxxxxx:

„„Logical-systems are not supported.


„„Only IPv4 is supported.
„„An import-policy for the interface-routes rib-group is not supported.
„„Deactivating the [edit routing-options] hierarchy will prevent the script
from functioning correctly.
„„The next-hop must be to a direct subnet.
Xxxx xx xxx xxxx xxxxxxx xx xxx xxxxxx-xxxxx.xxxx xxxxxx xxxxxx:
/*
* policy-route.slax is a commit script designed to simplify filter-based
* forwarding (policy-based routing). With this commit script in place, the
* following firewall action can be specified:
*
* then {
* apply-macro policy-route {
* next-hop 10.0.0.1;
* }
*}
*
* The commit script translates the configuration macro at commit time and
* generates the configuration necessary for filter-based forwarding.
*
* Do not configure a terminating action or 'next term' within the same term
* where this macro is applied
* Next-hop must be to a directly connected interface
* Only IPv4 is supported
* Logical-systems are not supported
* Deactivating routing-options blocks the macro from working correctly
*/
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

/*
* Verify that a rib-group with an import-rib is not specified for interface
* routes. This commit script is incompatible with that configuration.
*/
var $interface-routes = routing-options/interface-routes/rib-group/inet;
var $rib-group-config = routing-options/rib-groups[name == $interface-routes];
if( $interface-routes && $rib-group-config/import-policy ) {
<xnm:warning> {
call jcs:edit-path( $dot = $rib-group-config );
call jcs:statement( $dot = $rib-group-config/import-policy );
<message> "policy-route macro cannot be used if interface-routes " _
"rib-group has an import policy";
}
}
/* Otherwise, the configuration is compatible so go ahead */
else {

/*
* Go through all the firewall filters and create the transient filter
* configuration change as well as the routing-instance change. Build
* a set of all the routing-instances for the later interface-routes
* change.
*/
var $macro = "policy-route";
var $results := {
for-each( firewall//filter/term/then/apply-macro[name == $macro] ) {

/* Retrieve next-hop value from the macro */


var $next-hop = data[ name == "next-hop" ]/value;

/* Verify that next-hop is present */


if( jcs:empty( $next-hop ) ) {
<xnm:warning> {
call jcs:edit-path();
<message> "Macro is missing next-hop parameter";
}
}
/* Make changes */
else {
/* Assemble standardized name */
var $instance-name = "fbf-" _ $next-hop;

/* Add routing-instance action */


var $content = {
<routing-instance> {
<routing-instance-name> $instance-name;
}
}
call jcs:emit-change($dot= ..,$content,$tag="transient-change");

/*
* Create routing-instance. It is a forwarding type instance
* with a single 0/0 route pointing to the desired next-hop
*/
<transient-change> {
<routing-instances> {
<instance> {
<name> $instance-name;
<instance-type> "forwarding";
<routing-options> {
<static> {
<route> {
<name> "0.0.0.0/0";
<next-hop> $next-hop;
}
}
}
}
}
}

/* Record routing-instance name */


<instance> $instance-name;
}
}
}

/*
* Copy any <transient-change> elements saved to $results to the result
* tree so the changes can be passed to Junos
*/
copy-of $results/transient-change;
/*
* Copy any <xnm:warning> elements saved to $results as well
*/
copy-of $results/xnm:warning;

/*
* Make routing-options change. The active="active" tag is included
* up until the routing-options hierarchy in case the interface-routes
* statement or its children are deactivated. The macro could have
* activated routing-options automatically as well, but it does not
* due to the possibility that there might be configuration within
* routing-options that must remain deactivated.
*/
if( count( $results/instance ) > 0 ) {
<transient-change> {
<routing-options> {
<interface-routes active="active"> {
<rib-group active="active"> {
<inet active="active"> "fbf-ribs";
}
}
<rib-groups> {
<name> "fbf-ribs";
/* Is there an existing interface-routes rib? */
if( $interface-routes ) {
/* Copy existing ribs to import-rib */
copy-of $rib-group-config/import-rib;
}
else {
/* Just add inet.0 as import rib */
<import-rib> "inet.0";
}

/* Add all the routing-instances as import-ribs */


for-each( $results/instance ) {
<import-rib> . _ ".inet.0";
}
}
}
}
}
}
}

Try It Yourself Solutions


Xxxx xxxx xxxxxxx xx xxx Xxxxxxxx xxxxxxxx xxxxxx xxxxxxxxx xxx
xxxx xx xxx Xxx Xx Xxxxxxxx xxxxxxxx xx xxxx xxxxxxxx xx Xxxxxxxx
10 xxxxxxx 12.

Chapter 10Try It Yourself: Host-Name Should Inherit From Configuration Group


Create a commit script that generates a commit warning message if the host-name is not
inherited from the re0 or re1 configuration groups.
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

if( jcs:empty( system/host-name[@junos:group == "re0" || @junos:group == "re1"])){


<xnm:warning> {
<message> "Hostname is not inherited from re configuration group.";
}
}

Chapter 10Try It Yourself: ISIS Interface Lacks Family Iso


Create a warning message for every interface enabled for the ISIS protocol that does not have
family iso configured. Include an <edit-path> to better document the problem.

version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

/* Record reference point */


var $interfaces = interfaces;

/* Only look for specifically enabled interfaces */


for-each( protocols/isis/interface[ name != "all" ][ jcs:empty( disable )] ) {
var $physical = substring-before( name, "." );
var $logical = substring-after( name, "." );

var $interface = $interfaces/interface[name == $physical]/unit[name == $logical];

if( jcs:empty( $interface/family/iso ) ) {


<xnm:warning> {
call jcs:edit-path();
<message> "Interface does not have family iso configured.";
}
}
}

Chapter 10Try It Yourself: Compare Syslog Methods


Create a commit script that logs two syslog messages, one using <syslog> and the other using
jcs:syslog(). Compare the syslog results when a commit is performed versus a commit check.

version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

<syslog> {
<message> "Logged by result tree element";
}
expr jcs:syslog( "daemon.warning", "Logged by function" );

[edit]
jnpr@host1# run clear log syslog

[edit]
jnpr@host1# commit
commit complete
[edit]
jnpr@host1# run show log syslog | match cscript
Nov 30 09:22:26 host1 cscript: %DAEMON-4: Logged by function
Nov 30 09:22:26 host1 cscript: %DAEMON-4: Logged by result tree element
Nov 30 09:22:37 host1 mgd[1913]: %INTERACT-6-UI_CMDLINE_READ_LINE: User 'jnpr',
command 'run show log syslog | match cscript '

[edit]
jnpr@host1# run clear log syslog

[edit]
jnpr@host1# commit check
configuration check succeeds

[edit]
jnpr@host1# run show log syslog | match cscript
Nov 30 09:22:46 host1 cscript: %DAEMON-4: Logged by function
Nov 30 09:22:58 host1 mgd[1913]: %INTERACT-6-UI_CMDLINE_READ_LINE: User 'jnpr',
command 'run show log syslog | match cscript '

Chapter 10Try It Yourself: Sanity Checking


Write a commit script that generates a <xnm:error> if the [edit system], [edit interfaces], or [edit
protocols] hierarchies are missing.
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

if( jcs:empty( system ) ) {


<xnm:error> {
<message> "[edit system] hierarchy level is missing.";
}
}

if( jcs:empty( interfaces ) ) {


<xnm:error> {
<message> "[edit interfaces] hierarchy level is missing.";
}
}

if( jcs:empty( protocols ) ) {


<xnm:error> {
<message> "[edit protocols] hierarchy level is missing.";
}
}
}

Chapter 10Try It Yourself: Incorrect Autonomous-System Number


Write a commit script that generates a <xnm:error> if the autonomous-system number is not set
to 65000. Include <edit-path> and <statement> elements to better document the problem.

version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

if( routing-options/autonomous-system/as-number != 65000 ) {


<xnm:error> {
call jcs:edit-path( $dot = routing-options/autonomous-system );
call jcs:statement( $dot = routing-options/autonomous-system/as-number );
<message> "ASN must be set to 65000.";
}
}
}

Chapter 11Try It Yourself: Commit Check And The <Change> Element


Write a simple commit script that changes a single configuration setting. Perform a commit
check and verify that the candidate configuration is altered but the committed configuration
remains unchanged. Perform a normal commit and verify that the change is now visible in the
committed configuration.
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

<change> {
<snmp> {
<location> "SLC";
}
}
}

[edit]
jnpr@host1# show snmp
location Denver;

[edit]
jnpr@host1# commit check
configuration check succeeds

[edit]
jnpr@host1# show snmp
location SLC;

[edit]
jnpr@host1# run show configuration snmp
location Denver;

[edit]
jnpr@host1# commit
commit complete

[edit]
jnpr@host1# show snmp
location SLC;

[edit]
jnpr@host1# run show configuration snmp
location SLC;

Chapter 11Try It Yourself: Automated Configuration Fixes


Identify a standard part of your configuration that should always be present. Write a commit
script that automatically adds it when missing and generates a <xnm:warning> message
informing the user of the change.

version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

if( jcs:empty( routing-options/autonomous-system[as-number == 65000 ] ) ) {


<change> {
<routing-options> {
<autonomous-system> {
<as-number> 65000;
}
}
}
<xnm:warning> {
<edit-path> "[edit routing-options]";
<message> "Setting ASN to 65000";
}
}
}
Chapter 11Try It Yourself: Replacing Configuration Hierarchies
Create a commit script that enforces the requirement that the ospf configuration should
consist solely of an assignment of all interfaces into area 0.
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

/* Check if invalid configuration */


if( jcs:empty( protocols/ospf/area[name == "0.0.0.0"]/interface[name == "all"] ) ||
count( protocols/ospf/descendant::* ) != 4 ) {

<change> {
<protocols> {
<ospf replace="replace"> {
<area> {
<name> "0.0.0.0";
<interface> {
<name> "all";
}
}
}
}
}
<xnm:warning> {
<edit-path> "[edit protocols ospf]";
<message> "Assigning all interfaces to area 0.0.0.0";
}
}
}

Chapter 11Try It Yourself: Family Mpls On LDP Interfaces


Create a commit script that calls the jcs:emit-change template to add family mpls to every
interface, configured under [edit protocols ldp], that lack it.
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

/* Save reference */
var $interfaces = interfaces;

for-each( protocols/ldp/interface ) {

var $physical = substring-before( name, "." );


var $logical = substring-after( name, "." );
var $interface = $interfaces/interface[name == $physical]/unit[name == $logical];

if( jcs:empty( $interface/family/mpls ) ) {


var $content = {
<family> {
<mpls>;
}
}
var $message = "Adding family mpls to interface";
call jcs:emit-change( $dot = $interface, $content, $message );
}

}
}

Chapter 11Try It Yourself: Deleting Invalid Name-Servers


Create a commit script for an organization whose name-servers all fall within the 10.0.1.0/24
subnet. Delete any configured name-servers from outside that subnet.
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

/* This script does not work with inherited name-servers */


for-each( system/name-server ) {
if( not( starts-with( name, "10.0.1." ) ) ) {
var $content = {
<name-server delete="delete"> {
<name> name;
}
}
var $message = "Removing invalid name-server";
call jcs:emit-change( $dot = .., $content, $message );
}
}
}

Chapter 11Try It Yourself: Reorder Firewall Terms


Create a commit script that adds a term to a firewall filter, if missing, and then inserts it at the
beginning of the filter.

version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

/* Check if term needs to be added */


var $filter = firewall/family/inet/filter[name == "ingress"];
if( jcs:empty( $filter/term[1][name == "count"] ) ) {
var $content1 = {
<term> {
<name> "count";
<then> {
<count> "counter";
}
}
}
var $term1-name = $filter/term[1]/name;
var $message = "Adding count term to ingress filter";
call jcs:emit-change( $dot = $filter, $content = $content1, $message );
var $content2 = {
<term insert="before" name=$term1-name> {
<name> "count";
}
}
call jcs:emit-change( $dot = $filter, $content = $content2 );
}
}

Chapter 11Try It Yourself: Modify Convert-To-Hyphens.Slax


Modify the convert-to-hyphens.slax commit script. Along with renaming the prefix-list, the
references to the prefix-list in policy-statements and firewall filters should also be set to the
new name.

version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";
match configuration {

/* Not designed for logical systems */

/* Loop through all prefix-lists */


for-each( policy-options/prefix-list ) {
call convert();
}

/* Loop through all policy-statement - prefix-lists */


for-each( policy-options/policy-statement//from/prefix-list ) {
call convert();
}

/* Loop through all firewalls - prefix-lists */


for-each( firewall//filter/term/from/prefix-list ) {
call convert();
}
}

/* Perform conversion at current hierarchy */


template convert() {

/* Do they have an underscore in their name? */


if( contains( name, "_" ) ) {

/* Translate _ to - */
var $new-name = translate( name, "_", "-" );
var $content = {
<prefix-list rename="rename" name=$new-name> {
<name> name;
}
}
var $message = "Translating _ to -";
call jcs:emit-change( $dot=.., $content, $message );
}
}

Chapter 11Try It Yourself: Transient Root Authentication Key


Create a commit script that adds the root authentication key transiently to the configuration.
Use the jcs:emit-change template to do so.

version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {
var $content = {
<root-authentication> {
<ssh-dsa> {
<name> "ssh-dss AAAAB3NzaC1kc3MAAACBAM5Yu7v/VlAYXzZ5" _
"XUDmBwAGgARS4ILMlhU2ozpfSePZmMqfqsvMCeSsssYt" _
"TX7W1DEnbvA+SdWg35zhS4utAYnlAjzJtaqoB4EYmk8x" _
"t5DCeNd/vSwTMOhlsXFXYHkxOnO5Va5+etQ1c3j9d0Wo" _
"O7+Mu6yxzgJnBN6I9lLYK8jbAAAAFQCkjYEHTB8PnKkX" _
"UBf2yk+aykSeaQAAAIAe2I7x9TYC9Eas1BqMgZb0BGgX" _
"r0jo/a5ZJdFIY22in2t9yAhaqbVbgSpPN9lIDtOab1JG" _
"3bzb8Gb9OpvKBiOtMKj4vd8fhUm5SzujJW7sP+FkWixe" _
"vi+EnfUFQRIgLTeKKe6QDAPxOUcH84pWKMuxiW9xlcXA" _
"JzvuGb2iQQBNLwAAAIAE2tJjK+dJZWoudzvv8pDWWk2H" _
"+QxzEGpsCWJQJNVAarY1nCgy5+pbXyX7M9I1FC/fjmaC" _
"BwZR//JuYRfo+29LTsCMAk9b0fSrToszXvXgtJ86nWzn" _
"1Sz9w3yDgtxpoD8R/mUqa8Xf5J7uGwOT6ypBMa+7u2sG" _
"rqD6RiSvCGxGbQ== example";
}
}
}
call jcs:emit-change( $dot = system, $content, $tag = "transient-change" );
}

Chapter 12Try It Yourself: MTU Changes


Design a configuration macro with two parameters. The first parameter refers to the desired
MTU value and the second is a regular expression for all interfaces that should be assigned the
MTU value. Create a commit script that looks for the configuration macro in the [edit interfaces]
hierarchy and makes the instructed MTU changes in response. The configuration macro
should be removed as part of the configuration change.
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

/* Allows multiple set-mtu macros to be present */


for-each( interfaces/apply-macro[ starts-with( name, "set-mtu" ) ] ) {
var $value = data[name == "value"]/value;
var $interfaces = data[name == "interfaces"]/value;

/* Only use if the parameters are present */


if( jcs:empty( $value ) || jcs:empty( $interfaces ) ) {
<xnm:warning> {
call jcs:edit-path();
<message> "Macro is missing its value and/or interfaces parameter";
}
}
else {
/* Scroll through all interfaces that match the regex */
for-each( ../interface[ jcs:regex( $interfaces, name ) ] ) {

var $content = {
<mtu> $value;
}
var $message = "Setting MTU to " _ $value;
call jcs:emit-change( $content, $message );
}

/* Remove the instruction macro */


<change> {
<interfaces> {
<apply-macro delete="delete"> {
<name> name;
}
}
}
}
}
}

Chapter 12Try It Yourself: Custom Firewall Filter


Design a configuration macro that has two parameters, one that indicates the control protocol
between PE and CE (BGP, OSPF, etc.), and the other that indicates the policer bandwidth.
Create a commit script that transiently creates a firewall filter for each logical interface with
that macro configured. The firewall filter should allow all packets from the control protocol in
the first term, and allow all packets in the second term, but rate-limit them to the bandwidth
specified in the macro.
version 1.0;

ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";

import "../import/junos.xsl";

match configuration {

for-each( interfaces/interface/unit/apply-macro[ name == "ingress-filter" ] ) {


var $protocol = data[name == "protocol"]/value;
var $bandwidth = data[name == "bandwidth"]/value;

/* Only use if the parameters are present */


if( jcs:empty( $protocol ) || jcs:empty( $bandwidth ) ) {
<xnm:warning> {
call jcs:edit-path();
<message> "Macro is missing its protocol and/or bandwidth parameter";
}
}
else {
/* Create filter and policer name */
var $filter-name = "ingress-filter-" _ ../../name _ "." _ ../name;
var $policer-name = "ingress-policer-" _ ../../name _ "." _ ../name;

/* Assign to interface */
var $content = {
<family> {
<inet> {
<filter> {
<input> {
<filter-name> $filter-name;
}
}
}
}
}
call jcs:emit-change( $dot = .., $content, $tag = "transient-change" );

/* Create firewall filter and policer */


<transient-change> {
<firewall> {
<family> {
<inet> {
<filter> {
<name> $filter-name;
<term> {
<name> "allow-control";
if( $protocol == "bgp" ) {
<from> {
<protocol> "tcp";
<port> "bgp";
}
}
else if( $protocol == "ospf" ) {
<from> {
<protocol> "ospf";
}
}
else { /* RIP */
<from> {
<protocol> "udp";
<port> "rip";
}
}
<then> {
<accept>;
}
}
<term> {
<name> "police-and-accept";
<then> {
<policer> $policer-name;
<accept>;
}
}
}
}
}
<policer> {
<name> $policer-name;
<if-exceeding> {
<bandwidth-limit> $bandwidth;
<burst-size-limit> "100k";
}
<then> {
<discard>;
}
}
}
}
}
}
}

What to Do Next & Where to Go …


http://www.juniper.net/dayone

Xxx xxx xxx Xxx Xxx xxxxx xxx xxx Xxxx Xxxx xxxxxx, xxx. Xxx xxxx
Xxxxxxx Xxxxxxxx Xxxxx. Xxxxx xxx xxx xxxxxxxxxx xxxxx xx xxxx xxx
xxxxxxxxx.

http://www.juniper.net/automation

The Junos Automation home page, where plenty of useful resources are
available including training class, recommended reading, and a script
library - an online repository of scripts that can be used on Junos
devices.

http://forums.juniper.net/jnet

Xxx Xxxxxxx-xxxxxxxxx X-Xxx Xxxxxxxxxxx xxxxx xx xxxxxxxxx xx


xxxxxxx xxxxxxxxxxx, xxxx xxxxxxxxx, xxx xxxxxxxxx xxxxx Xxxxxxx
xxxxxxxx, xxxxxxxxxxxx, xxx xxxxxxxxx. Xxxxxxxx xx xxxxxxxxxxx xx
xxxx xxxx xxxxx.

http://www.juniper.net/techpubs/en_US/junos/information-products/topic-collections/config-
guide-automation/frameset.html

Xxx Xxxxxxx-xxxxxxxxx xxxxxxx xxxxxxxxxxxxx xx xxxxxx xxxxxxxxxx


xx xxxx xxxx, xxxxxxxxx xxx Xxxxx XXX xxx Xxxxxxxxx Xxxxxxxxxxxxx.

http://www.juniper.net/us/en/products-services/technical-services/j-care/

Xxxxxxxx xx xxx Xxxxx xxxxxxxxxx xxxxxxx, Xxxxxxx Xxxxxxxx


Xxxxxxxx Xxxxxxx Xxxxxxxxx (XXX) xxxxxxxxxx xxxxxxxxxxx xxxx-
xxxxxxxx xxxxxxxxxxxx xxxxxxxx xxxx xxxxxxxxx xxx xx Xxxxx. XXX
xxxxxxxx x xxxxxxxxxxxxx xxx xx xxxxx xxx xxxxxxxxxxxx xxxxxxxx xx
xxxxxx Xxxxxxx Xxxxxxxx Xxxxxxxxx Xxxxxxxx xxxx xxx xxxxxxxxx
xxxxxxxx xx xxxxxxxx, xxxxxxxxx xxxxxxx xxxxxxxxxxxx xxx xxxxxxx
xxxxxxxx.

Вам также может понравиться