Basic Usage¶
Picking the right Driver¶
Assuming you are using scrapli to connect to one of the five "core" platforms, you should almost always use the
provided corresponding "core" driver. For example if you are connecting to an Arista EOS device, you should use the
EOSDriver
. You can select this driver "manually" or using the scrapli factory Scrapli
(or the async scrapli
factory AsyncScrapli
).
Importing your driver manually looks like this:
1 |
|
If you are using asyncio, you can use the async variant of the driver:
1 |
|
The core drivers and associated platforms are outlined below:
Platform/OS | Scrapli Driver | Scrapli Async Driver | Platform Name |
---|---|---|---|
Cisco IOS-XE | IOSXEDriver | AsyncIOSXEDriver | cisco_iosxe |
Cisco NX-OS | NXOSDriver | AsyncNXOSDriver | cisco_nxos |
Cisco IOS-XR | IOSXRDriver | AsyncIOSXRDriver | cisco_iosxr |
Arista EOS | EOSDriver | AsyncEOSDriver | arista_eos |
Juniper JunOS | JunosDriver | AsyncJunosDriver | juniper_junos |
All drivers can be imported from scrapli.driver.core
.
If you would rather use the factory class to dynamically select the appropriate driver based on a platform string (as seen in the above table), you can do so as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Note that the Scrapli
and AsyncScrapli
classes inherit from the NetworkDriver
and AsyncNetworkDriver
classes
respectively, so all editor code completion and type indicating behavior should work nicely! For non "core
" platforms please see the scrapli_community project.
If you are working with a platform not listed above (and/or is not in the scrapli community project), you have three options:
- You can use the (base)
Driver
driver directly, which you can read about here - You can use the
GenericDriver
which you can read about here - You can use the
NetworkDriver
which is similar to option 2 but you will need to understand/provide privilege /prompt information so scrapli can properly escalate/deescalate to/from configuration (or other) modes.
In general you should probably simply create a scrapli community platform (read about adding a platform
here, but failing that the GenericDriver
is
probably the simplest path forward.
Note: if you are using async you must set the transport to asyncssh
or asynctelnet
!
Basic Driver Arguments¶
The drivers of course need some information about the device you are trying to connect to. The most common arguments to provide to the driver are outlined below:
Argument | Purpose/Value |
---|---|
host | name/ip of host to connect to |
port | port of host to connect to (defaults to port 22) |
auth_username | username for authentication |
auth_password | password for authentication |
auth_secondary | password for secondary authentication (enable password) |
auth_private_key | private key for authentication |
auth_strict_key | strict key checking -- TRUE by default! |
ssh_config_file | True/False or path to ssh config file to use |
These arguments may be passed as keyword arguments to the driver of your choice, or, commonly are passed via dictionary unpacking as show below:
1 2 3 4 5 6 7 8 9 10 11 |
|
NOTE that scrapli enables strict host key checking by default!
Opening and Closing a Connection¶
scrapli does not open the connection for you when creating your scrapli connection object in normal operations, you
must manually call the open
method prior to sending any commands to the device as shown below.
```python from scrapli.driver.core import IOSXRDriver
my_device = { "host": "172.18.0.11", "auth_username": "scrapli", "auth_password": "scrapli", "auth_strict_key": False, }
conn = IOSXRDriver(**my_device) conn.open() response = conn.send_command("show version")
1 2 3 4 |
|
scrapli also supports using a context manager (with
block), when using the context manager the connection will be
automatically opened and closed for you.
1 2 3 4 5 6 7 8 9 10 11 |
|
Sending Commands¶
When using any of the core network drivers (JunosDriver
, EOSDriver
, etc.) or the GenericDriver
, the send_command
and send_commands
methods will respectively send a single command or list of commands to the device.
When using the core network drivers, the command(s) will be sent at the default_desired_privilege_level
level which is
typically "privilege exec" (or equivalent) privilege level. Please see Driver Privilege Levels
in the advanced usage section for more details on privilege levels. As the GenericDriver
doesn't know or
care about privilege levels you would need to manually handle acquiring the appropriate privilege level for you
command yourself if using that driver.
Note the different methods for sending a single command versus a list of commands!
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Finally, if you prefer to have a file containing a list of commands to send, there is a send_commands_from_file
method
. This method excepts the provided file to have a single command to send per line in the file.
Response Object¶
All command/config operations that happen in the GenericDriver
or any of the drivers inheriting from the
NetworkDriver
result in a Response
object being created. The Response
object contains attributes for the
command sent (channel_input
), start/end/elapsed time, and of course the result of the command sent.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
If using send_commands
(plural!) then scrapli will return a MultiResponse
object containing multiple Response
objects. The MultiResponse
object is for all intents and purposes just a list of Response
objects (with a few
very minor differences).
In addition to containing the input and output of the command(s) that you sent, the Response
object also contains a
method textfsm_parse_output
(for more on TextFSM support see
Textfsm/NTC-Templates Integration) which will attempt to parse and return the
received output. If parsing fails, the value returned will be an empty list -- meaning you will always get
"structured data" returned, however it will just be an empty object if parsing fails.
1 2 3 |
|
Sending Configurations¶
When using any of the core drivers, you can send configurations via the send_config
, send_configs
or
send_configs_from_file
methods which will handle privilege escalation for you. send_config
accepts a single
string, send_configs
accepts a list of strings, and of course send_configs_from_file
accepts a string path to a
file containing configurations to send. Note that send_configs_from_file
-- just like with it's commands sibling
-- will treat each line in the file as a configuration element, in this way it behaves much like send_configs
.
Lastly, it is good to know that send_config
(singular!) will parse the configuration string provided and split it
into lines -- this means that the underlying behavior is the same as send_configs
, however this method returns a
single Response
object. This send_config
method can be used to send entire configurations to devices in a
reliable fashion.
1 2 3 4 5 6 7 8 9 10 11 |
|
If you need to get into any kind of "special" configuration mode, such as "configure exclusive", "configure private
", or "configure session XYZ", you can pass the name of the corresponding privilege level via the privilege_level
argument. Please see the Driver Privilege Levels section for more details!
Lastly, note that scrapli does not exit configuration mode at completion of a "configuration" event -- this is
because scrapli (with the Network drivers) will automatically acquire default_desired_privilege_level
before
sending a "command" -- so there is no need, from a scrapli perspective, to explicitly exit config mode at end of
the configuration session.
Textfsm/NTC-Templates Integration¶
scrapli supports parsing output with TextFSM and ntc-templates. This of course requires installing TextFSM and having
ntc-templates somewhere on your system. When using a platform driver (i.e. IOSXEDriver
) the textfsm-platform will be
set for you (based on the driver device type). If you wish to parse the output of your send commands, you can use the
textfsm_parse_output
method of the response object. This method will attempt to find the template for you
-- based on the textfsm-platform and the channel-input (the command sent). If textfsm parsing succeeds, the
structured result is returned. If textfsm parsing fails, an empty list is returned.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
scrapli also supports passing in templates manually (meaning not using the pip installed ntc-templates directory to
find templates) if desired. The scrapli.helper.textfsm_parse
function accepts a string or loaded (TextIOWrapper
) template and output to parse. This can be useful if you have custom or one off templates or don't want to pip
install ntc-templates.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
NOTE: If a template does not return structured data an empty list will be returned!
NOTE: Textfsm and ntc-templates is an optional extra for scrapli; you can install these modules manually or using the optional extras install via pip:
pip install scrapli[textfsm]
Cisco Genie Integration¶
Very much the same as the textfsm/ntc-templates integration, scrapli has optional integration with Cisco's PyATS /Genie parsing library for parsing show command output. While there are parsers for non-Cisco platforms, this is currently just an option for Cisco platforms within scrapli.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
NOTE: If a parser does not return structured data an empty list will be returned!
NOTE: PyATS and Genie is an optional extra for scrapli; you can install these modules manually or using the optional extras install via pip:
pip install scrapli[genie]
TTP Integration¶
The scrapli response object also contains a ttp_parse_output
method, that, as you may have guessed, uses the
ttp library to parse output received from the device. Other than the obvious
difference that this is in fact a different type of parser, the only difference from a usage perspective is that
the ttp_parse_output
method requires a template string, string path to a template, or loaded (TextIOWrapper
) template string to be passed. This is because there is no index or mapping of platform:command:template as there
is with TextFSM/ntc-templates and genie.
An example ttp file (slightly modified from the great ttp quickstart guide) - in this case we'll pretend this file is called "my_template.ttp":
1 2 3 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
NOTE: If a parser does parse data, ttp will return an empty list (as with the other parser methods)
NOTE: ttp is an optional extra for scrapli; you can install these modules manually or using the optional extras install via pip:
pip install scrapli[ttp]
Handling Prompts¶
In some cases you may need to run an "interactive" command on your device. The send_interactive
method of the
GenericDriver
or its sub-classes (NetworkDriver
and "core" drivers) can be used to accomplish this. This method
accepts a list of "interact_events" -- or basically commands you would like to send, and their expected resulting
prompt. A third, optional, element is available for each "interaction", this last element is a bool that indicates
weather or not the input that you are sending to the device is "hidden" or obfuscated by the device. This is
typically used for password prompts where the input that is sent does not show up on the screen (if you as a
human are sitting on a terminal typing).
This method can accept one or N "events" and thus can be used to deal with any number of subsequent prompts.
One last important item about this method is that it accepts an argument privilege_level
-- the value of this
argument should be the name of the privilege level that you would like to execute the interactive command at
. This is an optional argument, with a default of the default_desired_privilege_level
attribute which is normally
"privilege exec" or similar depending on the platform.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
Telnet¶
scrapli supports telnet as a transport driver via the standard library module telnetlib
or with a custom-built
async telnet transport (creatively called "asynctelnet") built on the standard library asycnio
.
A few things worth noting:
-
You can set the username and password prompt expect string after your connection object instantiation and before calling the
open
method -- this means if you have non-default prompts you cannot use scrapli with a context manager and Telnet (because the context manager calls open for you). You can set the prompts using the following attributes of theChannel
(orAsyncChannel
) object:telnet_username_prompt
which defaults to^(.*username:)|(.*login:)\s?$
telnet_password_prompt
which defaults to^password:\s?$
You can set these values by updating the appropriate attribute, for example:
conn.channel.telnet_username_prompt = "somethingneat"
. -
If you wish to provide custom prompt values you can provide a string to look for "in" the output from the device, or a regular expression pattern that starts with
^
and ends with$
-- if you don't use the line anchors the pattern will bere.escape
'd. - When using telnet you may need to set the
comms_return_char
to\r\n
the tests against the core platforms pass without this, however it seems that some console server type devices are looking for this\r\n
pattern instead of the default\n
pattern.
SSH Config Support¶
scrapli supports using OpenSSH configuration files in a few ways. For "system" SSH transport (default setting
), passing a path to a config file will simply make scrapli "point" to that file, and therefore use that
configuration files attributes (because it is just exec'ing system SSH!). You can also pass True
to let
scrapli search in system default locations for a ssh config file (~/.ssh/config
and /etc/ssh/ssh_config
).
SSH transports other than "system" transport may support some subset of the OpenSSH configuration files, but will not provide full support. Asyncssh, for example, will automatically pick up and handle proxy-jumps, SSH keys, and some other items -- this is a 100% asyncssh feature and has nothing to do with scrapli (other than the fact that scrapli allows you to use asyncssh).
NOTE -- scrapli does NOT disable strict host checking by default. Obviously this is the "smart" behavior, but it
can be overridden on a per host basis in your SSH config file, or by passing False
to the "auth_strict_key
" argument on object instantiation.
1 2 3 4 5 6 7 8 9 10 11 12 |
|