Exscript en
Exscript en
0 User Documentation
A scripting language and framework for terminal based protocols
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
CONTENTS 4.6.5 4.6.6 Using Using Priority 5 Operators . . . . . . Priority 6 Operators . . . . . . Hexadecimal Or Octal Numbers Regular Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
CONTENTS . . . . . . . . . . . . . . . . . . . . 8 8 8 9 9 9 9 10 10 10 10 10 11 11 12 12 13 13 13 13 14 14 14 15 16 16 16 16 17 18 19 20 20 23 23 24 24 26 26 29 29 30 30
4.7 4.8
5 Exscript Commands 5.1 Extracting Data From A Response 5.1.1 extract ... into ... . . . . . . 5.1.2 extract ... into ... from ... . 5.1.3 extract ... as ... . . . . . . . 5.2 Using If-Conditions . . . . . . . . . 5.2.1 if ... end . . . . . . . . . . . 5.2.2 if ... else ... end . . . . . . . 5.2.3 if ... else if ... . . . . . . . . 5.3 Loops . . . . . . . . . . . . . . . . 5.4 Loops And Lists . . . . . . . . . . 5.5 Using Functions . . . . . . . . . . . 5.6 Exiting A Script . . . . . . . . . . 5.6.1 fail message . . . . . . . . 5.6.2 fail message if ... . . . . . 5.7 Error Handling . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
6 Trouble Shooting 6.1 Common Pitfalls . . . . . . . . . . . 6.2 Deadlocks . . . . . . . . . . . . . . . 6.3 A Command Is Sent Too Soon . . . 6.4 The Connection Is Closed Too Soon 7 The Python API 7.1 Overview . . . . . . . . . . . . . . . 7.2 Exscript .protocols . . . . . . . . . . 7.2.1 Emulating A Remote Device 7.3 Exscript .Queue . . . . . . . . . . . . A The Standard Library A.1 Module stdlib.connection A.1.1 Functions . . . . . A.2 Module stdlib.crypt . . . A.2.1 Functions . . . . . A.3 Module stdlib.le . . . . . A.3.1 Functions . . . . . A.4 Module stdlib.ipv4 . . . . A.4.1 Functions . . . . . A.5 Module stdlib.list . . . . . A.5.1 Functions . . . . . A.6 Module stdlib.string . . . A.6.1 Functions . . . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
Page 2
CONTENTS
CONTENTS 31 31
Page 3
INTRODUCTION
1 Introduction
1.1 Why Exscript?
Exscript is a script and template language for automating network connections over protocols such as Telnet or SSH. Exscript is targeted at non-developers and developers alike. Exscript is often used to automate sessions with routers from Cisco, Juniper, Huawei, and others. It may be used by an administrator who often congures machines running Linux/Unix, IOS, IOS-XR, JunOS, VRP, or any other operating system that can be used with a terminal. Exscript is in some ways comparable to Expect, but has some unique features that make it a lot easier to use and understand for non-developers.
Page 4
OVERVIEW
2 Overview
2.1 Quick Introduction
With Exscript you can quickly automate a conversation with a device over Telnet or SSH. For example, to execute the ls command on three dierent hosts, create a le with the following content: ls and then run it using exscript my template host1 host2 host3
Page 5
COMMAND LINE SYNTAX show version {extract /(cisco)/ as vendor} {if vendor is cisco} show ip interface brief {extract /(\S+)\s/ as interfaces} {loop interfaces as interface} show running interface $interface configure terminal interface $interface no shut end {end} copy running config startupconfig {end}
Exscript provides additional methods for interacting with the remote host and for receiving information from it. The following chapters include a more complete overview of the template language.
Page 6
LANGUAGE SYNTAX
3.3
2. Save the le. It is assumed that you are aware of the security implications of saving your login passwords in a text le. 3. Start Exscript with the account-pool FILE option. For example: exscript account pool /home/user/my accounts my. exscript host4
4 Language Syntax
4.1 Sending Commands To The Remote Host
The simplest possible template is one that contains only the commands that are sent to the remote host. For example, the following Exscript can be used to retrieve the response of the ls -l and df commands from a unix host: ls l df Save this le as my.exscript and execute it using the following command: exscript my. exscript localhost where localhost is the name of the host on which the ls -l and df commands are executed.
4.2 Comments
Lines starting with a hash (#) are interpreted as comments and ignored. For example:
Page 7
LANGUAGE SYNTAX 1. # This line is ignored . . . 2. {if hostname is test} 3. # . . .and so is this one. 4. {end}
4.3
USING VARIABLES
Page 8
LANGUAGE SYNTAX
4.5
response contains the response of the remote host that was received after the execution of the last command.
Built-in variables are used just like any other variable. You can also assign a new value to a built-in variable in the same way.
Page 9
LANGUAGE SYNTAX
4.7
4.6.4 Priority 4 Operators 1. is tests for equality. If both operators are lists, only the rst item in the list is compared. 2. is not produces the opposite result from is. 3. in tests whether the left string equals any of the items in the list given as the right operator. 4. not in produces the opposite result from in. 5. matches tests whether the left operator matches the regular expression that is given as the right operator. 6. ge tests whether the left operator is (numerically) greater than or equal to the right operator. 7. gt tests whether the left operator is (numerically) greater than the right operator. 8. le tests whether the left operator is (numerically) less than or equal to the right operator. 9. lt tests whether the left operator is (numerically) less than the right operator. 4.6.5 Priority 5 Operators 1. not inverts the result of a comparison. 4.6.6 Priority 6 Operators 1. and combines two tests such that a logical AND comparison is made. If the left operator returns FALSE, the right operator is not evaluated. 2. or combines two tests such that a logical OR comparison is made. If the left operator returns TRUE, the right operator is not evaluated.
Page 10
EXSCRIPT COMMANDS
4.8
5 Exscript Commands
By default, any content of an Exscript is sent to the remote host. However, you can also add instructions with special meanings. Such instructions are enclosed by curly brackets ( and ). The following commands all use this syntax.
Page 11
5.2
USING IF-CONDITIONS
There is no limit to the number of extract statements. 5.1.2 extract ... into ... from ... When used without the from keyword, extract gets the values from the last command that was executed. You may however also instruct Exscript to extract the values from a variable. The following example shows how this may be done. ls l { extract /(.)/ into lines extract /(d.)/ into directories from lines }
5.1.3 extract ... as ... The as keyword is similar to into, the dierence being that with as, the destination variable is cleared before new values are appended. ls l {extract /(d.)/ as directories} as may be used anywhere where into is used.
5.2.2 if ... else ... end You can also add an else condition:
Page 12
EXSCRIPT COMMANDS ls l . profile {extract /(\.profile)$/ as found} {if found is not . profile} ls {else} touch . profile {end}
5.3
LOOPS
5.2.3 if ... else if ... You can perform multiple matches using else if: ls l . profile {extract /(.profile)$/ as found} {if found is . profile} ls {else if found matches /my profile/} ls l p {else} touch . profile {end}
5.3 Loops
You can execute commands multiple times using the loop statement. The following Exscript executes the ls command three times: {number = 0} {loop until number is 3} {number = number + 1} ls $directory {end} Similarly, the while statement may be used. The following script is equivalent: {number = 0} {loop while number is not 3} {number = number + 1} ls $directory {end} Another alternative is using the loop from ... to ... syntax, which allows you to specify a range of integers: # Implicit counter variable . {loop from 1 to 3} ls $directory$counter {end}
Page 13
EXSCRIPT COMMANDS
5.4
Page 14
EXSCRIPT COMMANDS
5.6
EXITING A SCRIPT
Page 15
TROUBLE SHOOTING
If you want to execute the command regardless, you can wrap the ls command in a try block: {try}ls l{end} show ip int brief You can add as many commands as you like in between a try block. For example, the following will also work: {try} ls l df show running config {end} show ip int brief
6 Trouble Shooting
6.1 Common Pitfalls
Generally, the following kinds of errors that may happen at runtime: 1. A script deadlocks. In other words, Exscript sends no further commands even though the remote host is already waiting for a command. This generally happens when a prompt is not recognized. 2. A script executes a command before the remote host is ready. This happens when a prompt was detected where none was really included in the response. 3. A script terminates before executing all commands. This happens when two (or more) prompts were detected where only one was expected. The following sections explain when these problems may happen and how to x them.
6.2 Deadlocks
Exscript tries to automatically detect a prompt, so generally you should not have to worry about prompt recognition. The following prompt types are supported: [sam123@home ]$ sam@knip:/Code/exscript$ sam@MyHost X123$ MyHost ABCCDE123$ MyHost A1$ MyHost A1(config)$ FA /0/1/2/3$ FA/0/1/2/3(config)$ admin@s x a6.a.bc.de. fg:/$
Page 16
TROUBLE SHOOTING
6.3
Note: The trailing $ may also be any of the following characters: $#% However, in some rare cases, a remote host may have a prompt that Exscript can not recognize. Similarly, in some scripts you might want to execute a special command that triggers a response that does not include a prompt Exscript can recognize. In both cases, the solution includes dening the prompt manually, such that Exscript knows when the remote host is ready. For example, consider the following script: 1. 2. 3. 4. show ip int brief write memory {enter} show configuration
Say that after executing line 2 of this script, the remote host asks for a conrmation, saying something like this: Are you sure you want to overwrite the configuration? [confirm] Because this answer does not contain a standard prompt, Exscript can not recognize it. We have a deadlock. To x this, we must tell Exscript that a non-standard prompt should be expected. The following change xes the script: 1. 2. 3. 4. 5. 6. show ip int brief {connection.set prompt(/\[confirm\]/)} write memory {connection.set prompt()} {enter} show configuration
The second line tells Exscript to wait for [conrm] after executing the following commands. Because of that, when the write memory command was executed in line 3, the script does not deadlock (because the remote hosts response includes [conrm]). In line 4, the prompt is reset to its original value. This must be done, because otherwise the script would wait for another [conrm] after executing line 5 and line 6.
Page 17
6.4 down up
MyW N link A
Note that line 3 happens to contain the string Router, which looks like a prompt when it really is just a description. So after receiving the character in line 3, Exscript believes that the router is asking for the next command to be sent. So it immediately sends the next command (show diag summary) to the router, even that the next prompt was not yet received. Note that this type of error may not immediately show, because the router may actually accept the command even though it was sent before a prompt was sent. It will lead to an oset however, and may lead to errors when trying to capture the response. It may also lead to the script terminating too early. To x this, make sure that the conversation with the remote host does not include any strings that are incorrectly recognized as prompts. You can do this by using the connection.set prompt(...) function as explained in the sections above.
Page 18
.protocols provides a clean and simple replacement. Exscript supports the following protocols at this time: 1. Telnet is a Telnet adapter. 2. SSH is an adapter for SSH version 1 and version 2. 3. Dummy is a virtual pseudo device that may be used for testing. The following example shows how to connect to a host using Telnet: from Exscript. protocols import Telnet conn = Telnet() conn.connect(127.0.0.1) # The default port is 21 conn.authenticate(myuser, mypassword) conn.execute(ls l) conn.send(exit\r) conn. close() The example will execute the ls -l command on the remote host, and waits until the remote host has responded with a prompt. Once the prompt was retrieved, the function returns and conn.send(exit ) is reached. Unlike execute(), the send() method returns immediately without waiting for a response from the remote host. This is necessary here, because the remote host does not normally respond to the exit command; it just closes the connection. The above code also works with SSH - just replace Telnet with SSH: from Exscript. protocols import SSH conn = SSH() ... To fetch the response of a remote host, the following code may be used: ... conn.execute(ls l) print The host said :, repr(conn.response)
7.2.1 Emulating A Remote Device Exscript also provides a dummy protocol adapter for testing purposes. It emulates a remote host and may be used in place of the Telnet and SSH adapters: from Exscript. protocols import D m y u m conn =D m y() u m ... In order to dene the behavior of the dummy, you may dene it by providing a Python le that maps commands to responses. E.g.:
Page 19
THE PYTHON API def echo(command): return command. split( , 1)[1] commands = ( ( ls l , rw r 1 sab nmc 1906 Oct 5 11:18 Makefile r rw r 1 sab nmc 1906 Oct 5 11:18 myfile r ) , (r echo [\r\n]+ , echo) )
Note that the command name is a regular expression, and the response may be either a string or a function.
def do something(conn): conn.execute( show ip int brie ) ge interfaces = any match(conn, r (Gigabit\S+)) eval file (conn, mytemplate. exscript , interfaces = ge interfaces) # Read a l i s t of hostnames from a fi le . hosts = get hosts from file( hostlist . txt ) # Open a connection (Telnet, by default) to each of the hosts , and run # do something(). To open the connection via SSH, you may prefix the # hostname by the protocol , e.g. : ssh://hostname , telnet://hostname , # etc . # The max threads keyword indicates the maximum number of concurrent # connections. quickstart(hosts , do something, max threads = 5) This code reads a list of hostnames from hostlist.txt, automatically logs into each of the hosts, and executes the do something once for each of the hosts.
Page 20
The quickstart() function is a shortcut that you can use in most cases. However, there are some more advanced features that you can use. For example, Exscript can generate a report for all of the executed tasks: #!/usr/bin/env python from Exscript import Queue, Logger from Exscript. util . f i l e import get hosts from file , get accounts from file from Exscript. util .report import status , summarize def do something(conn): conn.open() conn.authenticate() conn.execute( show ip int brie ) # Read input data. accounts = get accounts from file( accounts. cfg ) hosts = get hosts from file( hostlist . txt ) # Run do something on each of the hosts. The given accounts are used # round robin. verbose = 0 instructs the queue to not generate any # output on stdout. Using logdir = ... is equivalent to the following : # logger = FileLogger(queue, my/logdir ) # It instructs the queue to automatically log everything to the filesystem ; # one file is created per host. queue = Queue(verbose = 0, max threads = 5, logdir = my/logdir/) logger = Logger(queue) # Logs everything to memory. queue.add account(accounts) # Adds one or more accounts. queue.run(hosts , do something) # Asynchronously enqueues all hosts. queue.shutdown() # Waits until all hosts are completed. # Print a short report. print status(logger) print summarize(logger) Exscript provides additional methods, and also oers protocol-specic options. For a complete list of supported methods please refer to our API documentation.
Page 21
A.1
MODULE STDLIB.CONNECTION
Page 22
A.1
MODULE STDLIB.CONNECTION
Sends the given data to the remote host and waits until the host has responded with a prompt. If the given data is a list of strings, each item is sent, and after each item a prompt is expected. This function also causes the response of the command to be stored in the built-in response variable. Parameters data: The data that is sent. (type=string) execline(scope, data) Like exec(), but appends a newline to the command in data before sending it. Parameters data: The data that is sent. (type=string) guess os(scope) Guesses the operating system of the connected host. The recognition is based on the past conversation that has happened on the host; Exscript looks for known patterns and maps them to specic operating systems. Return Value The operating system. (type=string) send(scope, data) Like exec(), but does not wait for a response of the remote host after sending the command. Parameters data: The data that is sent. (type=string) sendline(scope, data) Like execline(), but does not wait for a response of the remote host after sending the command. Parameters data: The data that is sent. (type=string)
Page 23
A.1
MODULE STDLIB.CONNECTION
Waits until the response of the remote host contains the given pattern. Parameters prompt: The prompt pattern. (type=regex) set prompt(scope, prompt=None) Denes the pattern that is recognized at any future time when Exscript needs to wait for a prompt. In other words, whenever Exscript waits for a prompt, it searches the response of the host for the given pattern and continues as soon as the pattern is found. Exscript waits for a prompt whenever it sends a command (unless the send() method was used). set prompt() redenes as to what is recognized as a prompt. Parameters prompt: The prompt pattern. (type=regex) set error(scope, error re=None) Denes a pattern that, whenever detected in the response of the remote host, causes an error to be raised. In other words, whenever Exscript waits for a prompt, it searches the response of the host for the given pattern and raises an error if the pattern is found. Parameters error re: The error pattern. (type=regex) set timeout(scope, timeout) Denes the time after which Exscript fails if it does not receive a prompt from the remote host. Parameters timeout: The timeout in seconds. (type=int)
Page 24
A.2
MODULE STDLIB.CRYPT
Page 25
A.3
MODULE STDLIB.FILE
Page 26
A.3
MODULE STDLIB.FILE
Reads the given le and returns the result. The result is also stored in the built-in response variable. Parameters filename: A lename. (type=string) Return Value The content of the le. (type=string) rm(scope, lename) Deletes the given le (or les) from the le system. Parameters filename: A lename, or a list of lenames. (type=string) write(scope, lename, lines, mode=[a]) Writes the given string into the given le. The following modes are supported: a: Append to the le if it already exists. w: Replace the le if it already exists. Parameters filename: A lename. (type=string) lines: The data that is written into the le. (type=string) mode: Any of the above listed modes. (type=string)
Page 27
A.4
MODULE STDLIB.IPV4
Page 28
A.4
MODULE STDLIB.IPV4
Converts the given IP mask(s) (e.g. 255.255.255.0) to prex length(s). Parameters masks: An IP mask, or a list of masks. (type=string) Return Value The prex length(s) that result(s) from converting the mask. (type=string) pfxlen2mask(scope, pfxlen) Converts the given prex length(s) (e.g. 30) to IP mask(s). Parameters pfxlen: An IP prex length. (type=int) Return Value The mask(s) that result(s) from converting the prex length. (type=string) pfxmask(scope, ips, pfxlen) Applies the given prex length to the given ips, resulting in a (list of) IP network addresses. Parameters ips: An IP address, or a list of IP addresses. (type=string) pfxlen: An IP prex length. (type=int) Return Value The mask(s) that result(s) from converting the prex length. (type=string)
Page 29
A.4
MODULE STDLIB.IPV4
Given an IP address, this function calculates the remaining available IP address under the assumption that it is a /30 network. In other words, given one link net address, this function returns the other link net address. Parameters local ips: An IP address, or a list of IP addresses. (type=string) Return Value The other IP address of the link address pair. (type=string)
Page 30
A.5
MODULE STDLIB.LIST
Page 31
A.6
MODULE STDLIB.STRING
Page 32
A.7
MODULE STDLIB.SYS
Page 33