Unicon Connection Library Plugins
Unicon Plugins is a component of the Cisco pyATS framework, providing extensible platform support and services for the Unicon Connection Library. It enables unified command-line interface (CLI) connection experiences to various network devices, leveraging expect-like programming for multi-vendor support and seamless handling of CLI modes. Originally developed internally by Cisco, it was open-sourced in late 2017 through Cisco DevNet. The current version is 26.3, with releases typically aligning with the pyATS framework's frequent updates, often on a monthly or bi-monthly cadence.
Common errors
-
unicon.core.errors.UniconAuthenticationError: Too many password retries
cause Incorrect credentials (username, password, or enable password) provided for the device, or the device is configured to reject too many login attempts.fixVerify all credentials (username, password, enable password) are correct. Ensure they are correctly passed through environment variables, directly in the script, or via a pyATS testbed file. Check device logs for authentication failures. -
ImportError: No module named 'unicon'
cause The core `unicon` package, which `unicon-plugins` depends on, has not been installed in your Python environment.fixInstall the `unicon` package: `pip install unicon`. -
unicon.core.errors.StateMachineError: Failed while bringing device to "any" state
cause This often occurs when Unicon cannot transition the device through its expected CLI states (e.g., from user exec mode to privileged exec mode or configuration mode), possibly due to unexpected prompts, command failures, or missing credentials for state transitions. It's a high-level error often caused by underlying issues.fixExamine the Unicon connection log (`log_file` parameter in `Connection`) for detailed interaction. This can reveal unexpected prompts, command rejections, or authentication issues at intermediate states. Adjust dialogs or credentials accordingly. -
unicon.core.errors.SubCommandFailure: <service_name> service failed to execute command(s)
cause A specific service (e.g., `execute`, `configure`, `monitor`) failed during execution, likely due to a command being rejected by the device, an unexpected prompt, or a timeout.fixCheck the command(s) being sent for syntax errors on the target device. Review the connection log for any unexpected output or error messages from the device. Adjust the command, add appropriate dialogs, or increase service timeouts if necessary.
Warnings
- breaking Support for Python 3.6 ended in April 2022. Users must migrate to Python versions 3.7, 3.8, 3.9, or 3.10 as pyATS (and thus Unicon Plugins) no longer supports 3.6.
- gotcha Accurate specification of 'os', 'platform', and 'model' is crucial for Unicon to load the most precise connection plugin. Incorrect or generic values might lead to fallback plugins, potentially causing unexpected behavior or missing device-specific features.
- deprecated The 'fxos/ftd' plugin has been deprecated. Users should transition to using other available 'fxos' plugins for FTD devices.
- gotcha When developing new plugins, ensure all mandatory files (like `__init__.py`) are present and correctly structured within your plugin folder. Missing or improperly defined files can prevent auto-discovery and loading of your custom plugin.
Install
-
pip install unicon unicon-plugins
Imports
- Connection
from unicon import Connection
Quickstart
import os
from unicon import Connection
# Example: Connecting to an IOS XE device
# In a real scenario, device details and credentials would typically come from a pyATS testbed YAML file.
# For a quick start, we'll simulate a direct connection.
hostname = os.environ.get('DEVICE_HOSTNAME', 'your_device_ip_or_hostname')
username = os.environ.get('DEVICE_USERNAME', 'admin')
password = os.environ.get('DEVICE_PASSWORD', 'Cisco123')
enable_password = os.environ.get('DEVICE_ENABLE_PASSWORD', 'Cisco123')
# Instantiate a connection object for an IOSXE device
# The 'os' argument directs Unicon to load the appropriate plugin.
# Other parameters like 'platform' and 'model' can further refine plugin selection.
try:
print(f"Attempting to connect to {hostname} (OS: iosxe)...")
connection = Connection(
hostname=hostname,
os='iosxe',
start=['ssh {username}'], # Specifies how to start the connection
log_file='unicon_connection.log', # Optional: logs interaction
init_exec_commands=['terminal length 0', 'terminal width 0'], # Initial commands to run
custom_callbacks={
'password': lambda: password,
'enable_password': lambda: enable_password
}
)
connection.connect()
print(f"Successfully connected to {hostname}")
# Execute a command
output = connection.execute('show version')
print("\n--- show version output ---\n")
print(output[:500]) # Print first 500 characters of output
print("\n---------------------------")
# Configure the device (example - requires 'configure' service for the plugin)
# config_commands = ['interface Loopback100', 'description Test Loopback']
# print(f"\nAttempting to configure: {config_commands}")
# connection.configure(config_commands)
# print("Configuration applied.")
except Exception as e:
print(f"Connection failed: {e}")
finally:
if 'connection' in locals() and connection.is_connected():
connection.disconnect()
print(f"Disconnected from {hostname}")