Академический Документы
Профессиональный Документы
Культура Документы
By Curtis Call
SPECIAL EDITION
© 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.
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.
Be sure to follow this and other Juniper Networks Books on:Twitter: @Day1Junos
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
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.
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/.
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.
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>
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">
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>
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.
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!
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;
}
}
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";
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!";
}
}
NOTE If you wish to include line-feeds within your text string then use the \n
escape character: <output> “First Line\nSecond Line”;
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.
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> {
}
}
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.
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";
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;
}
}
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";
match / {
<op-script-results> {
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.
/* 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.
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";
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.
/* Command-line arguments */
param $string1;
param $string2;
match / {
<op-script-results> {
}
}
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";
/* Command-line arguments */
param $string1;
param $string2;
match / {
<op-script-results> {
}
}
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
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";
}
/* 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
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.
Xx xxxx x xxxxxxxx xxx xxx xxxx xxxxxxxxx xxx xxxxxxx xxx xxxx xx xxx
xxxxxxx xxxxxxxx:
call example-template;
match / {
<op-script-results> {
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 */
}
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" );
match / {
<op-script-results> {
/* 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;
}
}
/* Command-line argument */
param $desired-format;
match / {
<op-script-results> {
/* 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;
}
}
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.
match / {
<op-script-results> {
/* 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(); }
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 );
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 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
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";
/* 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;
}
}
}
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";
/* Command-line argument */
param $interface;
match / {
<op-script-results> {
/*
* 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";
}
}
}
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
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 );
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;
/* Command-line argument */
param $interface;
match / {
<op-script-results> {
/* Assign all matching nodes from the results to the $admin-status variable */
var $admin-status = $results/physical-interface[name==$interface]/admin-status;
match / {
<op-script-results> {
/* 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 " _ .;
}
}
}
}
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.
/* Command-line argument */
param $interface;
match / {
<op-script-results> {
/* 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: ");
}
}
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.
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";
/* Command-line arguments */
param $facility;
param $severity;
param $message;
match / {
<op-script-results> {
match / {
<op-script-results> {
/*
* 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;
}
}
}
}
match / {
<op-script-results> {
/* Send API Element to Junos via jcs:invoke and retrieve config in XML format */
var $config = jcs:invoke( $config-rpc );
/* 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;
}
}
}
}
Create an op script that reads the configuration and outputs all the syslog file names to the
console.
/*
* 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;
}
}
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.
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 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.
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.
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> {
}
}
}
}
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.
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
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
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
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
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;
}
}
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
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;
}
}
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 / {
/*
* 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 );
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> {
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 {
...
}
}
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 {
...
}
}
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> {
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();
/* 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();
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.
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
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.
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";
}
}
}
}
„„If ge-1/0/1 went down the policy triggers the output of the show
interfaces extensive ge-1/0/1 command.
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.
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.
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;
}
}
}
}
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 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;
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";
match / {
<event-script-results> {
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;
}
}
/* 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> {
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.
$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;
}
}
}
}
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";
}
}
}
}
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> {
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> {
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.
<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:
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-input> {
/* Get PID */
var $pid = event-script-input/trigger-event/process/pid;
/* New priority */
var $new-priority = $facility _ ".notice";
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
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 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.
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
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
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 {
}
„„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;
}
}
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>;
}
}
}
}
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;
}
}
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.
Chapter 10
Commit Feedback and Control
<xnm:warning> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . 140
<edit-path>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . 142
<statement>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . 144
<syslog>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . 145
<xnm:error>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . 147
<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
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 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";
}
}
Create a commit script that generates a commit warning message if the host-name is not
inherited from the re0 or re1 configuration groups.
<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.
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 {
/* Missing description */
if( jcs:empty( description ) ) {
<xnm:warning> {
call jcs:edit-path();
<message> "Interface description is missing.";
}
}
}
}
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 {
<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.
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.
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 {
Write a commit script that generates a <xnm:error> if the [edit system], [edit interfaces], or [edit
protocols] hierarchies are missing.
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;
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.
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.
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.
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 {
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 {
<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 {
<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;
}
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 {
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".
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 {
}
/* 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;
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 {
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";
}
}
}
}
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;
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 {
/* 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 );
}
}
}
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
}
}
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" );
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.
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
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;
}
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";
match configuration {
/* Retrieve AS Number */
var $asn = routing-options/autonomous-system/as-number;
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";
match configuration {
/* Add to protocols */
<change> {
<protocols> {
<mpls> {
<interface> {
<name> $name;
}
}
<ldp> {
<interface> {
<name> $name;
}
}
<isis> {
<interface> {
<name> $name;
}
}
}
}
}
}
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.";
}
}
}
}
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 {
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
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";
/* Command-line argument */
param $display-format;
match / {
<op-script-results> {
}
}
/* 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
match / {
<op-script-results> {
/* Open a connection */
var $connection = jcs:open();
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;
}
}
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";
}
}
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 ) {
/*
* 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> .;
}
}
}
}
/*
* 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: ");
/*
* 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); }
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
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 );
/*
* 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;
}
}
/* Copy output to the result tree so that it will be displayed on the console */
copy-of $results;
}
[system]
[interfaces]
[protocols]
system {
host-name r1;
login {
message "Unauthorized access prohibited.";
}
}
<system> {
<host-name> "r1";
<login> {
<message> "Unauthorized access prohibited.";
}
}
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";
}
}
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;
}
}
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;
}
}
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;
}
}
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> $redirected;
}
}
template output-string() {
expr "Here is the output string";
}
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> {
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> {
}
}
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> {
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> {
for-each( $results/physical-interface/logical-interface/address-family/mtu ) {
if( . != "Unlimited" ) {
<output> "The family " _ ../address-family-name _ " MTU for " _ ../../name _ " is " _ .;
}
}
}
}
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: " );
}
}
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 );
}
}
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> {
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.
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.
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;
}
}
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 := {
/* 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>;
}
}
}
}
}
}
/*
* 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 ) {
/*
* 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 {
/*
* 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 );
}
}
}
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;
/* Grab the routing-options static node to make further location paths shorter */
var $static = $current/routing-options/static;
/*
* Compare the event type vs the current value of $inactive. If they
* do not match then a configuration change must be performed.
*/
/* 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 ) {
/* 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." );
}
}
}
}
system {
syslog {
file structured {
any any;
structured-data;
}
}
}
/* 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> {
}
}
event-options {
policy log-message {
events rpd_igmp_join;
then {
event-script log-syslog.slax;
}
}
event-script {
file log-syslog.slax;
}
}
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> {
}
}
/* 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";
match / {
<event-script-results> {
/* Determine which event triggered the script */
var $event-id = event-script-input/trigger-event/id;
/* 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" );
}
}
}
}
event-options {
policy raise-trap {
events [ ui_dbase_login_event ui_dbase_logout_event ];
then {
raise-trap;
}
}
}
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;
}
}
}
}
/* 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 / {
/* 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";
match / {
<event-script-results> {
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 );
/* 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> {
}
}
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 / {
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;
}
}
}
}
}
}
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
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] ) {
/*
* 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;
}
}
}
}
}
}
/*
* 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";
}
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 {
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 {
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 '
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 {
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 {
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;
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 {
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> {
<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";
}
}
}
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 ) {
}
}
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 {
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 {
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 {
/* 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 );
}
}
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" );
}
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 = {
<mtu> $value;
}
var $message = "Setting MTU to " _ $value;
call jcs:emit-change( $content, $message );
}
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 {
/* Assign to interface */
var $content = {
<family> {
<inet> {
<filter> {
<input> {
<filter-name> $filter-name;
}
}
}
}
}
call jcs:emit-change( $dot = .., $content, $tag = "transient-change" );
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
http://www.juniper.net/techpubs/en_US/junos/information-products/topic-collections/config-
guide-automation/frameset.html
http://www.juniper.net/us/en/products-services/technical-services/j-care/