Asynchronous parallel SSH client library that enables developers to execute SSH commands across many servers simultaneously with minimal system load on the client host.
—
Flexible per-host configuration system allowing different authentication methods, connection parameters, and proxy settings for individual hosts within parallel operations. Enables fine-grained control over SSH connections and authentication.
Configure individual host settings within a ParallelSSHClient for hosts that require different authentication methods, ports, proxy settings, or other connection parameters.
class HostConfig:
def __init__(self, user=None, port=None, password=None, private_key=None,
allow_agent=None, alias=None, num_retries=None, retry_delay=None,
timeout=None, identity_auth=None, proxy_host=None, proxy_port=None,
proxy_user=None, proxy_password=None, proxy_pkey=None,
keepalive_seconds=None, ipv6_only=None, cert_file=None,
auth_thread_pool=True, gssapi_auth=False,
gssapi_server_identity=None, gssapi_client_identity=None,
gssapi_delegate_credentials=False, forward_ssh_agent=False):
"""
Per-host configuration for ParallelSSHClient.
Parameters:
- user (str, optional): Username for this host
- port (int, optional): SSH port for this host
- password (str, optional): Password for this host
- private_key (str or bytes, optional): Private key file path or key data
- allow_agent (bool, optional): Enable SSH agent for this host
- alias (str, optional): Alias name for this host
- num_retries (int, optional): Retry attempts for this host
- retry_delay (float, optional): Delay between retries for this host
- timeout (float, optional): Connection timeout for this host
- identity_auth (bool, optional): Enable identity file auth for this host
- proxy_host (str, optional): SSH proxy hostname for this host
- proxy_port (int, optional): SSH proxy port for this host
- proxy_user (str, optional): SSH proxy username for this host
- proxy_password (str, optional): SSH proxy password for this host
- proxy_pkey (str or bytes, optional): SSH proxy private key for this host
- keepalive_seconds (int, optional): Keepalive interval for this host
- ipv6_only (bool, optional): IPv6 only mode for this host
- cert_file (str or bytes, optional): Certificate file for authentication
- auth_thread_pool (bool, optional): Use thread pool for auth (default: True)
- gssapi_auth (bool, optional): Enable GSSAPI authentication (ssh client only)
- gssapi_server_identity (str, optional): GSSAPI server identity (ssh client only)
- gssapi_client_identity (str, optional): GSSAPI client identity (ssh client only)
- gssapi_delegate_credentials (bool, optional): Delegate credentials (ssh client only)
- forward_ssh_agent (bool, optional): SSH agent forwarding (default: False)
"""Configure different authentication methods and connection settings for individual hosts within a parallel client.
from pssh.clients import ParallelSSHClient
from pssh.config import HostConfig
# Different authentication per host
hosts = ['web1.example.com', 'web2.example.com', 'db.example.com']
host_config = [
HostConfig(user='web_admin', password='web_pass', port=22), # web1
HostConfig(user='web_admin', private_key='~/.ssh/web_key', port=22), # web2
HostConfig(user='db_admin', private_key='~/.ssh/db_key', port=3306) # db (custom port)
]
client = ParallelSSHClient(hosts, host_config=host_config)
# Different proxy settings per host
host_config = [
HostConfig(user='admin'), # web1 - direct connection
HostConfig( # web2 - through proxy
user='admin',
proxy_host='bastion.example.com',
proxy_user='proxy_user',
proxy_pkey='~/.ssh/proxy_key'
),
HostConfig( # db - through different proxy
user='db_admin',
proxy_host='db-bastion.example.com',
proxy_user='db_proxy',
proxy_password='proxy_pass'
)
]
client = ParallelSSHClient(hosts, host_config=host_config)Configure complex authentication scenarios including GSSAPI, certificate-based authentication, and SSH agent forwarding.
# Mixed authentication methods
host_config = [
HostConfig( # Host 1: SSH key authentication
user='admin',
private_key='/path/to/admin.key',
allow_agent=False,
identity_auth=False
),
HostConfig( # Host 2: SSH agent authentication
user='admin',
allow_agent=True,
identity_auth=True,
forward_ssh_agent=True
),
HostConfig( # Host 3: GSSAPI authentication (ssh client only)
user='admin',
gssapi_auth=True,
gssapi_server_identity='host/server.example.com',
gssapi_client_identity='admin@EXAMPLE.COM',
gssapi_delegate_credentials=True
),
HostConfig( # Host 4: Certificate authentication
user='admin',
cert_file='/path/to/admin.crt',
private_key='/path/to/admin.key'
)
]
# Note: GSSAPI features require pssh.clients.ssh implementation
from pssh.clients.ssh import ParallelSSHClient
client = ParallelSSHClient(hosts, host_config=host_config)Customize connection behavior, timeouts, and retry logic on a per-host basis.
# Different timeout and retry settings per host type
host_config = [
HostConfig( # Local network host - short timeouts
user='admin',
timeout=10,
num_retries=2,
retry_delay=2,
keepalive_seconds=30
),
HostConfig( # Remote host - longer timeouts
user='admin',
timeout=30,
num_retries=5,
retry_delay=10,
keepalive_seconds=120
),
HostConfig( # Unreliable host - very patient settings
user='admin',
timeout=60,
num_retries=10,
retry_delay=30,
keepalive_seconds=240
)
]
client = ParallelSSHClient(hosts, host_config=host_config)Configure network-specific settings including IPv6-only connections and custom port configurations.
# Network-specific configurations
host_config = [
HostConfig( # IPv4 host with standard port
user='admin',
port=22,
ipv6_only=False
),
HostConfig( # IPv6-only host
user='admin',
port=22,
ipv6_only=True
),
HostConfig( # Custom SSH port
user='admin',
port=2222,
ipv6_only=False
),
HostConfig( # Host behind NAT with port forwarding
user='admin',
port=22022, # Forwarded port
timeout=45 # Longer timeout for NAT traversal
)
]
# IPv6 addresses can be used directly
hosts = [
'server1.example.com', # IPv4/IPv6 hostname
'2001:db8::1', # IPv6 address
'192.168.1.100', # IPv4 address
'[2001:db8::2]:2222' # IPv6 address with port
]
client = ParallelSSHClient(hosts, host_config=host_config)Use aliases to identify hosts in output and logging, especially useful when working with IP addresses or complex hostnames.
# Using aliases for better identification
hosts = ['192.168.1.10', '192.168.1.20', '10.0.0.5']
host_config = [
HostConfig(user='admin', alias='web-server-1'),
HostConfig(user='admin', alias='web-server-2'),
HostConfig(user='admin', alias='database-server')
]
client = ParallelSSHClient(hosts, host_config=host_config)
output = client.run_command('hostname')
# Output will show aliases instead of IP addresses
for host_output in output:
print(f"Alias: {host_output.alias}, Host: {host_output.host}")
# Output: Alias: web-server-1, Host: 192.168.1.10HostConfig performs automatic validation of configuration parameters to catch common errors early.
from pssh.config import HostConfig
try:
# Invalid configurations will raise ValueError
config = HostConfig(port="invalid_port") # Should be int
except ValueError as e:
print(f"Configuration error: {e}")
try:
config = HostConfig(num_retries=-1) # Should be positive
except ValueError as e:
print(f"Configuration error: {e}")
try:
config = HostConfig(timeout="not_a_number") # Should be int or float
except ValueError as e:
print(f"Configuration error: {e}")# Prefer key-based authentication over passwords
host_config = [
HostConfig(
user='admin',
private_key='~/.ssh/id_rsa', # Key file
password=None, # No password storage
allow_agent=True # Use SSH agent when available
)
]
# For environments requiring password auth, consider using environment variables
import os
host_config = [
HostConfig(
user='admin',
password=os.getenv('SSH_PASSWORD'), # From environment
allow_agent=False,
identity_auth=False
)
]# Optimize authentication performance
host_config = [
HostConfig(
user='admin',
private_key='~/.ssh/id_rsa',
auth_thread_pool=True, # Use thread pool for auth (default)
allow_agent=False, # Disable if not needed
identity_auth=False, # Disable if using specific key
keepalive_seconds=60 # Reasonable keepalive interval
)
]
# For high-latency connections
host_config = [
HostConfig(
user='admin',
timeout=120, # Longer timeout
keepalive_seconds=300, # Longer keepalive
num_retries=3, # Reasonable retry count
retry_delay=15 # Longer retry delay
)
]# Create reusable configuration templates
def create_web_server_config(user='web_admin', key_path='~/.ssh/web_key'):
return HostConfig(
user=user,
private_key=key_path,
port=22,
timeout=30,
num_retries=3,
keepalive_seconds=60
)
def create_database_config(user='db_admin', key_path='~/.ssh/db_key'):
return HostConfig(
user=user,
private_key=key_path,
port=3306, # Custom port for database hosts
timeout=60,
num_retries=5,
keepalive_seconds=120
)
# Apply templates to host groups
web_hosts = ['web1.example.com', 'web2.example.com']
db_hosts = ['db1.example.com', 'db2.example.com']
hosts = web_hosts + db_hosts
host_config = (
[create_web_server_config() for _ in web_hosts] +
[create_database_config() for _ in db_hosts]
)
client = ParallelSSHClient(hosts, host_config=host_config)Install with Tessl CLI
npx tessl i tessl/pypi-parallel-ssh