Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions docs/changelog/2025/may.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
May 2025
==========

- Unicon v25.5
------------------------



.. csv-table:: Module Versions
:header: "Modules", "Versions"

``unicon.plugins``, v25.5
``unicon``, v25.5




Changelogs
^^^^^^^^^^
--------------------------------------------------------------------------------
Add
--------------------------------------------------------------------------------

* connection provider
* moved the logic of boot_device to a separate function before designating handles
* added the init_active to handle the learn_hostname instead of having it in designate handles
* Store "current_credentials" under device.credentials when credentials are used

* connection
* Added logging per subconnection for DualRp, Stack and Quad connection


--------------------------------------------------------------------------------
Fix
--------------------------------------------------------------------------------

* generic
* service implementation
* Update the state for debug mode in attach service.


1 change: 1 addition & 0 deletions docs/changelog/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Changelog
.. toctree::
:maxdepth: 2

2025/may
2025/april
2025/march
2025/february
Expand Down
64 changes: 64 additions & 0 deletions docs/changelog_plugins/2025/may.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
May 2025
==========

- Unicon.Plugins v25.5
------------------------



.. csv-table:: Module Versions
:header: "Modules", "Versions"

``unicon.plugins``, v25.5
``unicon``, v25.5




Changelogs
^^^^^^^^^^
--------------------------------------------------------------------------------
Add
--------------------------------------------------------------------------------

* iosxe/cat9k/stackwise_virtual
* Added support for SVL

* iosxe/cat9k/c9500x/stackwise_virtual
* Added support for SVL

* generic
* Add loghandler for subconnections to capture the buffer output


--------------------------------------------------------------------------------
Fix
--------------------------------------------------------------------------------

* generic
* Made it so incorrect login errors will attempt to use fallback credentials

* nxos
* Add support for bash_console with module argument.
* Make l2rib_dt_prompt pattern more strict


--------------------------------------------------------------------------------
New
--------------------------------------------------------------------------------

* nxos
* Added support for configure session
* When using device.configure() you can now pass a session name with session="session_name"
* IE device.configure("...", session="my_session")

* iosxe
* IosXEPatterns
* Updated the recovery-mode regex to match prompt for both mode
* Added the rp-rec-mode regex to match prompt
* Added acm state and transition support to IOS-XE plugin.
* Enhanced Configure and HAConfigure services to support ACM CLI via acm_configlet argument using context-driven state transitions.
* Added context-based transition function to enter ACM mode using acm configlet create <name>.
* Added post-service transition to gracefully return to enable mode after configuration.


1 change: 1 addition & 0 deletions docs/changelog_plugins/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Plugins Changelog
.. toctree::
:maxdepth: 2

2025/may
2025/april
2025/march
2025/february
Expand Down
48 changes: 46 additions & 2 deletions docs/user_guide/services/nxos.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,55 @@ For list of all the other service please refer this:
* mandatory arguments are marked with `*`.


bash_console
------------

Service to execute commands in the router Bash. ``bash_console``
gives you a router-like object to execute commands on using python context
managers.

=========== ====================== ===========================================
Argument Type Description
=========== ====================== ===========================================
timeout int (default 60 sec) timeout in sec for executing commands
target str 'standby' to bring standby console to bash.
enable_bash bool (default: True) enable bash service on device.
module str module to connect to (optional)
command str command to use with `run bash {command}`
(optional)
=========== ====================== ===========================================

Bash service will be enabled by default on devices that require the service to
be configured. Bash configuration will be done on first invocation of the
bash_console service.

You can specify the module name to use rlogin from the bash (root) shell to
connect to the module shell. The command will default to `sudo su`.

.. code-block:: python

with device.bash_console() as bash:
output1 = bash.execute('ls')
output2 = bash.execute('pwd')

with device.bash_console(module='lc1') as bash:
output1 = bash.execute('ls')
output2 = bash.execute('pwd')

To run commands in the root shell, use `command="sudo su"`.

.. code-block:: python

with device.bash_console(command='sudo su') as bash:
output1 = bash.execute('ls')
output2 = bash.execute('pwd')


shellexec
---------

Service to execute commands on the Bourne-Again SHell (Bash).

Service to execute commands on the Bourne-Again SHell (Bash). Similar to
``bash_console``.

========== ====================== ========================================
Argument Type Description
Expand Down
60 changes: 45 additions & 15 deletions docs/user_guide/supported_platforms.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ the iosxe table, it will fallback to use the generic ``iosxe`` plugin. If

.. tip::

The priority to pick up which plugin is: chassis_type > os > platform > model.
The priority to pick up which plugin is: chassis_type > os > platform > model > submodel.


.. important::
Expand All @@ -30,8 +30,8 @@ the iosxe table, it will fallback to use the generic ``iosxe`` plugin. If

.. csv-table:: Unicon Supported Platforms
:align: center
:widths: 20, 20, 20, 40
:header: "os", "platform", "model", "Comments"
:widths: 20, 20, 20, 20, 40
:header: "os", "platform", "model", "submodel", "Comments"

``apic``
``aireos``
Expand All @@ -46,21 +46,22 @@ the iosxe table, it will fallback to use the generic ``iosxe`` plugin. If
``confd``, ``nfvis``
``dnos6``
``dnos10``
``fxos``,,,"Tested with FP2K."
``fxos``,,,,"Tested with FP2K."
``fxos``, ``fp4k``
``fxos``, ``fp9k``
``fxos``, ``ftd``,,"Deprecated, please use one of the other fxos plugins."
``gaia``, , , "Check Point Gaia OS"
``fxos``, ``ftd``,,,"Deprecated, please use one of the other fxos plugins."
``gaia``, , , , "Check Point Gaia OS"
``hvrp``
``ios``, ``ap``
``ios``, ``iol``
``ios``, ``iosv``
``ios``, ``pagent``,,"See example below."
``ios``, ``pagent``,,,"See example below."
``iosxe``
``iosxe``, ``cat3k``
``iosxe``, ``cat3k``, ``ewlc``
``iosxe``, ``cat8k``
``iosxe``, ``cat9k``
``iosxe``, ``cat9k``,
``iosxe``, ``cat9k``, ``c9500``, ``c9500x``, "See example below."
``iosxe``, ``c9800``
``iosxe``, ``c9800``, ``ewc_ap``
``iosxe``, ``csr1000v``
Expand All @@ -76,26 +77,26 @@ the iosxe table, it will fallback to use the generic ``iosxe`` plugin. If
``iosxr``, ``spitfire``
``ironware``
``ise``
``linux``, , , "Generic Linux server with bash prompts"
``nd``, , , "Nexus Dashboard (ND) Linux server. identical to os: linux"
``linux``, , , , "Generic Linux server with bash prompts"
``nd``, , , , "Nexus Dashboard (ND) Linux server. identical to os: linux"
``nxos``
``nxos``, ``mds``
``nxos``, ``n5k``
``nxos``, ``n7k``
``nxos``, ``n9k``
``nxos``, ``nxosv``
``nxos``, ``aci``
``nso``,,, "Network Service Orchestrator"
``ons``,,, "Optical Networking System"
``sdwan``, ``viptela``,,"Identical to os=viptela."
``nso``,,,, "Network Service Orchestrator"
``ons``,,,, "Optical Networking System"
``sdwan``, ``viptela``,,,"Identical to os=viptela."
``sros``
``staros``
``vos``
``junos``
``eos``
``sros``
``viptela``,,,"Identical to os=sdwan, platform=viptela."
``windows``,,,"Only command shell (cmd) is supported. Powershell is not supported"
``viptela``,,,,"Identical to os=sdwan, platform=viptela."
``windows``,,,,"Only command shell (cmd) is supported. Powershell is not supported"

To use this table - locate your device's os/platform/model information, and fill
your pyATS testbed YAML with it:
Expand Down Expand Up @@ -222,6 +223,35 @@ Example: Stack router
port: 2003
member: 3 <<< peer rp id

Example: Stackwise Virtual Router
---------------------------------

.. code-block:: yaml

devices:
router_hostname:
os: iosxe
platform: cat9k
model: c9500
submodel: c9500x
chassis_type: stackwise_virtual <<< define the chassis_type as 'stackwise_virtual'
credentials:
default:
username: xxx
password: yyy
enable:
password: zzz
connections:
defaults:
class: unicon.Unicon
a:
protocol: telnet
ip: 1.1.1.1
port: 2001
b:
protocol: telnet
ip: 1.1.1.1
port: 2002

Example: Quad Sup router
------------------------
Expand Down
3 changes: 2 additions & 1 deletion src/unicon/plugins/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
__version__ = '25.4'
__version__ = "25.5"

supported_chassis = [
'single_rp',
'dual_rp',
'stack',
'quad',
'stackwise_virtual'
]

supported_os = [
Expand Down
2 changes: 2 additions & 0 deletions src/unicon/plugins/apic/patterns.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
__author__ = "dwapstra"

from unicon.utils import ANSI_REGEX
from unicon.plugins.generic.patterns import GenericPatterns


class ApicPatterns(GenericPatterns):
def __init__(self):
super().__init__()
self.learn_hostname = r'^.*?({a})?(?P<hostname>[-\w]+)\s?([-\w\]/~:\.\d ]+)?([>\$~%#\]])\s*(\x1b\S+)?$'.format(a=ANSI_REGEX)
self.enable_prompt = r'^(.*?)((\x1b\S+)?\x00)*(%N)#\s*(\x1b\S+)?$'
self.config_prompt = r'^(.*?)((\x1b\S+)?\x00)*(%N)\(config.*\)#\s*(\x1b\S+)?$'
self.shell_prompt = r'^(.*?)((\x1b\S+)?\x00)*\[[-\.\w]+@((%N)\s+.*?\]#)\s*(\x1b\S+)?$'
Expand Down
3 changes: 3 additions & 0 deletions src/unicon/plugins/apic/statemachine.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,16 @@ def create(self):
enable = State('enable', patterns.enable_prompt)
config = State('config', patterns.config_prompt)
shell = State('shell', patterns.shell_prompt)
learn_hostname = State('learn_hostname', patterns.learn_hostname)
setup = State('setup', list(setup_patterns.__dict__.values()))

self.add_state(enable)
self.add_state(config)
self.add_state(learn_hostname)
self.add_state(setup)
self.add_state(shell)

self.add_path(Path(learn_hostname, enable, None, None))
enable_to_config = Path(enable, config, 'configure', None)
config_to_enable = Path(config, enable, 'end', None)

Expand Down
10 changes: 8 additions & 2 deletions src/unicon/plugins/generic/service_implementation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2093,6 +2093,10 @@ def call_service(self, # noqa: C901
lb.setFormatter(logging.Formatter(fmt=UNICON_LOG_FORMAT))
self.connection.log.addHandler(lb)

# logging the output to subconnections
for subcon in con.subconnections:
subcon.log.addHandler(lb)

# Clear log buffer
self.log_buffer.seek(0)
self.log_buffer.truncate()
Expand Down Expand Up @@ -2250,6 +2254,8 @@ def call_service(self, # noqa: C901
self.log_buffer.truncate()

self.connection.log.removeHandler(lb)
for subcon in con.subconnections:
subcon.log.removeHandler(lb)

self.result = True
if return_output:
Expand Down Expand Up @@ -2681,7 +2687,7 @@ class AttachModuleService(BaseService):
with rtr.attach(1) as m:
m.execute('show interface')
m.execute(['show interface 1', 'show interface 2'])
# if we want to go to module_debug state
# if we want to go to lc_shell state
with rtr.attach(1, debug=True) as m:
m.execute('show interface')
m.execute(['show interface 1', 'show interface 2'])
Expand Down Expand Up @@ -2742,7 +2748,7 @@ def __enter__(self):
raise NotImplementedError('Attach module state not implemented')

self.conn.log.debug('+++ attaching module +++')
conn.state_machine.go_to('module_debug' if self.debug else 'module',
conn.state_machine.go_to('lc_shell' if self.debug else 'module',
conn.spawn,
context=self.context,
timeout=self.timeout)
Expand Down
5 changes: 5 additions & 0 deletions src/unicon/plugins/generic/statements.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,11 @@ def incorrect_login_handler(spawn, context, session):
# If credentials have been supplied, there are no login retries.
# The user must supply appropriate credentials to ensure login
# does not fail. Skip it for the first attempt

# Attempt fallback credentials if available
if session['current_credential']:
return

raise UniconAuthenticationError(
'Login failure, either wrong username or password')
if 'incorrect_login_attempts' not in session:
Expand Down
Empty file.
Loading
Loading