Python-based, Windows compatible SSH automation client designed to offer a vendor agnostic alternative to Netmiko or `sshpass`.
Project description
pysshpass: A Multiplatform SSH Automation Utility
Overview
pysshpass is a Python-based SSH client designed to offer a multiplatform alternative to sshpass. It aims to address two key challenges:
- Windows Compatibility: Native
sshpassoptions are limited on Windows.pysshpassserves as a versatile replacement. - Specialized Devices Support: Network devices like Palo Alto Firewalls, CloudGenix SD-WAN routers, and F5 load balancers often have unique command-line interfaces and large outputs, which are not fully supported by libraries like Netmiko.
- Vendor and OS Agnostic: Whether you're managing Cisco, Aruba, Palo Alto, or other network devices,
pysshpassallows seamless automation and parsing, making it ideal for mixed-vendor environments.
Key Features
- Comma-Delimited Commands: Execute multiple commands in sequence using comma-separated values.
- Prompt Controls: The script supports custom prompts and prompt counts, offering precise control over when to exit the shell.
- Timeout Management: A timeout feature ensures that the utility doesn't hang while waiting for device responses.
- Quiet Mode: A
quietflag suppresses printed output when running as a library, but retains output in CLI mode. - Cross-Platform: Works across Linux, macOS, and Windows.
Example CLI Usage
pysshpass -h "172.16.1.101" -u "cisco" -p "cisco" -c "term len 0,show users,show run" --invoke-shell --prompt "#" --prompt-count 4 -t 15
This command runs multiple commands in sequence on an SSH device (IOS), waits for four prompts, and applies a 15-second timeout.
Use Cases
- Automating tasks on network devices with large configuration outputs.
- Managing multi-modal command-line interfaces.
- Gathering information during network audits.
- Mixed vendor network environment tooling.
- Linux or IoT automation.
CLI Usage
pysshpass --help
Usage: pysshpass [OPTIONS]
SSH Client for running remote commands.
Options:
-h, --host TEXT SSH Host (ip:port) [required]
-u, --user TEXT SSH Username [required]
-p, --password TEXT SSH Password
-c, --cmds TEXT Commands to run, separated by comma
--invoke-shell/--no-invoke-shell Invoke shell before running the command
[default=True]
--prompt TEXT Prompt to look for before breaking the shell
--prompt-count INTEGER Number of prompts to look for before breaking the shell
-t, --timeout INTEGER Command timeout duration in seconds [default=360]
--disable-auto-add-policy Disable automatically adding the host key [default=False]
--look-for-keys Look for local SSH key [default=False]
-d, --delay FLOAT Delay between sending commands in seconds [default=0.5]
--quiet Suppress output when running as a library
--help Show this message and exit.
Flags Explanation
--host: SSH target (IP or hostname).--user: SSH username.--password: SSH password (can be skipped ifPYSSH_PASSenvironment variable is set).--cmds: Comma-separated commands to run.--invoke-shell: Create an interactive SSH session (default isTrue).--prompt: Specify the shell prompt to look for.--prompt-count: How many times the prompt should be matched before breaking the shell.--timeout: Duration in seconds before the command times out.--disable-auto-add-policy: Disable the auto-add of SSH keys.--look-for-keys: Enable local key lookup for SSH authentication.--delay: Time delay between sending commands.--quiet: Suppress output when running as a library.
Environment Variable Support for Passwords
For added convenience and security, pysshpass allows you to provide the SSH password through an environment variable, avoiding the need to pass it directly via the command line.
- Set the environment variable
PYSSH_PASSto the desired password:
export PYSSH_PASS="yourpassword"
- If the
--passwordoption is omitted,pysshpasswill automatically check for thePYSSH_PASSenvironment variable. This feature is especially useful when running automation scripts where you want to avoid exposing sensitive credentials in the command history.
Example:
export PYSSH_PASS="cisco"
pysshpass -h "172.16.101.100" -u "cisco" -c "show version,show inventory" --invoke-shell --prompt "#" --prompt-count 3 -t 10
If a password is provided both in the environment variable and the command-line option, the command-line value will take precedence.
More Usage Examples
1. Cisco Router
pysshpass -h "192.168.1.1" -u "admin" -p "password" -c "terminal length 0,show version" --invoke-shell --prompt "#" --prompt-count 3 -t 10
2. Aruba Switch
pysshpass -h "192.168.1.2" -u "admin" -p "password" -c "no paging,show interfaces brief" --invoke-shell --prompt ">" --prompt-count 2 -t 10
3. Palo Alto Firewall
pysshpass -h "192.168.1.3" -u "admin" -p "password" -c "set cli pager off,show system info,," --invoke-shell --prompt ">" --prompt-count 2 -t 10
Library Usage
In addition to being used as a CLI tool, pysshpass can also be used as a library:
from PySSHPass.pysshpass import SSHClientWrapper
def automate_device():
ssh_client = SSHClientWrapper(
host="192.168.1.1",
user="admin",
password="password",
cmds="show version",
invoke_shell=True,
prompt="#",
prompt_count=1,
timeout=10,
quiet=True # Suppress output
)
ssh_client.connect()
output = ssh_client.run_commands()
ssh_client.close()
return output
Quiet Mode
The --quiet flag suppresses printed output, making it useful for script-based automation where log files are preferred over console output.
Appendix A: Example Using TTP with pysshpass
This appendix provides a detailed example of how to use the pysshpass library with a TTP (Template Text Parser) helper to parse structured output from network devices. This example demonstrates how to run incremental SSH commands, gather output, and parse it using TTP templates for structured data extraction.
Overview
In this example, the SSHClientWrapper class is used to:
- Connect to a Cisco router.
- Execute the
show versioncommand and parse the version information using a TTP template. - Execute the
show inventorycommand and parse the inventory details.
The TTPParserHelper class is a utility that loads TTP templates and parses raw SSH output into structured data.
Script Example
from time import sleep
from PySSHPass.pysshpass import SSHClientWrapper
from PySSHPass.helpers.ttp_helper import TTPParserHelper
def test_ssh_client_with_ttp():
# Replace with appropriate SSH credentials and commands
ssh_client = SSHClientWrapper(
host="172.16.101.100",
user="cisco",
password="cisco",
invoke_shell=True,
prompt="#",
prompt_count=3,
timeout=5,
delay=0.5,
quiet=True # Suppress console output in quiet mode
)
# Step 1: Connect to the device
ssh_client.connect()
# Step 2: Run 'show version' command and capture output
ssh_client.cmds = "term len 0,show version"
version_output = ssh_client.run_commands()
# Step 3: Parse the 'show version' output using TTP
version_template_file = './templates/show_version.ttp' # Path to the TTP template for show version
version_parser = TTPParserHelper(ttp_template_file=version_template_file)
parsed_version = version_parser.parse(version_output)
print("Parsed Version Output:\n", parsed_version)
# Step 4: Run 'show inventory' command and capture output
ssh_client.prompt_count = 1
ssh_client.cmds = "show inventory"
inventory_output = ssh_client.run_commands()
# Step 5: Parse the 'show inventory' output using TTP
inventory_template_file = './templates/show_inventory.ttp' # Path to the TTP template for show inventory
inventory_parser = TTPParserHelper(ttp_template_file=inventory_template_file)
parsed_inventory = inventory_parser.parse(inventory_output)
print("Parsed Inventory Output:\n", parsed_inventory)
# Step 6: Close the
connection
ssh_client.close()
if __name__ == "__main__":
test_ssh_client_with_ttp()
Key Components
-
SSHClientWrapper:
- Manages the SSH connection and command execution.
invoke_shell=Trueenables interactive sessions, necessary for running multiple commands likeshow versionandshow inventory.- The
quiet=Trueflag suppresses verbose output during library usage.
-
TTPParserHelper:
- Parses SSH output using predefined TTP templates.
- In this example, the
show_version.ttpandshow_inventory.ttptemplates are used to extract structured data from the device output.
TTP Templates
To parse the output, we need two TTP templates: one for the show version command and one for the show inventory command. Below are examples of these templates:
1. TTP Template for show version
File: show_version.ttp
Version: {{ version }}
This template extracts the version information from the output of the show version command.
2. TTP Template for show inventory
File: show_inventory.ttp
NAME: "{{ inventory_name }}", DESCR: "{{ description }}"
PID: {{ product_id }}, VID: {{ version_id }}, SN: {{ serial_number }}
This template extracts details from the show inventory command, such as the product ID, version ID, and serial number.
New Feature: Dynamic Prompt Detection (find_prompt)
In the latest update, pysshpass includes a powerful find_prompt feature, which dynamically detects the shell prompt if not explicitly provided by the user. This is particularly useful when connecting to devices with unknown or varying prompt characters, such as network equipment with custom prompts.
Key Features of find_prompt:
- Automatic Detection: If no prompt is specified,
pysshpasswill attempt to detect common prompt characters like#,>, or$. - Custom Prompt Matching: You can customize the characters or strings to look for when identifying the prompt, allowing flexibility for unique prompt configurations.
- Seamless Integration: The
find_promptmethod is automatically called if the--promptoption is left blank, making it easy to integrate into your existing automation workflows.
Example Usage
If you don’t know the prompt for a device, simply leave the --prompt option blank, and pysshpass will try to find it for you:
pysshpass -h "192.168.1.1" -u "admin" -p "password" -c "show version,show interfaces" --invoke-shell --prompt-count 2 -t 15
If you want to customize the characters that are detected as a prompt, you can specify them when using pysshpass as a library:
ssh_client = SSHClientWrapper(
host="192.168.1.1",
user="admin",
password="password",
invoke_shell=True,
prompt="", # Empty prompt to enable dynamic prompt detection
prompt_count=1,
timeout=10
)
# Connect to the device and dynamically find the prompt (e.g., detecting '#' or '>')
ssh_client.connect()
detected_prompt = ssh_client.find_prompt(ends_with=('#', '>'))
print(f"Detected prompt: {detected_prompt}")
# Continue running commands after detecting the prompt
ssh_client.cmds = "show version"
output = ssh_client.run_commands()
ssh_client.close()
In this example, find_prompt will look for # or > at the end of a line to detect the prompt dynamically. You can easily modify the ends_with parameter to handle custom prompts (e.g., ends_with=('$', '%') for Unix-like systems).
This new feature makes pysshpass more adaptable to diverse environments, ensuring that you can automate SSH interactions even when the exact prompt is not known beforehand.
Appendix B: Build Instructions
To build and test pysshpass locally, follow the steps below:
Step 1: Install Build Tools
Before you can build the package, ensure that setuptools and wheel are installed:
pip install setuptools wheel
Step 2: Build the Package
To build the wheel file, run the following command:
python setup.py bdist_wheel
This will generate a .whl file in the dist/ directory.
Step 3: Test the Wheel Locally
To test the built package locally, run:
pip install dist/pysshpass-0.2.0-py3-none-any.whl
Step 4: Upload the Package to TestPyPI
For testing purposes, you can upload the wheel to TestPyPI:
pip install twine
twine upload --repository-url https://test.pypi.org/legacy/ dist/*
Step 5: Upload the Package to PyPI
Once satisfied with testing, upload the package to PyPI:
twine upload dist/*
Make sure to configure your credentials in ~/.pypirc for automated authentication.
License
PySSHPass is licensed under the GNU General Public License v3 (GPLv3). For more details, see the LICENSE file.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pysshpass-0.2.2-py3-none-any.whl.
File metadata
- Download URL: pysshpass-0.2.2-py3-none-any.whl
- Upload date:
- Size: 23.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.9.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5ef83c43967a7cd78d7f10db6866ae5c7423807f42381397166e1643ff1985c5
|
|
| MD5 |
54a94a960143400ffc06af4c4fd4bffe
|
|
| BLAKE2b-256 |
ef856e8311b2c2ad93e6bb204354b4c45b3267ab418efb5826204ff4ca70615b
|