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
62 changes: 62 additions & 0 deletions docs/changelog/2025/october.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
October 2025
==========

October 28 - Unicon v25.10
------------------------



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

``unicon.plugins``, v25.10
``unicon``, v25.10




Changelogs
^^^^^^^^^^
--------------------------------------------------------------------------------
Fix
--------------------------------------------------------------------------------

* unicon
* Modified TestUniconSettings
* Fixed regex pattern to correctly match Invalid input error message in exec command.

* plugins/linux
* Updated unit tests to accommodate the removal of the default 'uptime' command from LINUX_INIT_EXEC_COMMANDS.

* adapters
* Updated the log collection to check for runtime directory before moving

* modified basemultirpconnectionprovider
* Updated token discovery to handle standby locked devices


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

* unicon/bases/linux/connection
* Added peripheral support for Linux OS devices
* Updated BaseLinuxConnection to pass device to Spawn initialization, enabling clearing of busy console lines for Linux-based platforms


--------------------------------------------------------------------------------
Add
--------------------------------------------------------------------------------

* basemultirpconnection
* Added swap_roles in Multi RP connection which is parent class to have it handled for other connections.


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

* iosxe/cat9k/stackwise_virtual
* Enhanced the designate handles for condition where a standby & b active


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/october
2025/september
2025/august
2025/july
Expand Down
47 changes: 47 additions & 0 deletions docs/changelog_plugins/2025/october.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
October 2025
==========

October 28 - Unicon.Plugins v25.10
------------------------



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

``unicon.plugins``, v25.10
``unicon``, v25.10




Changelogs
^^^^^^^^^^
--------------------------------------------------------------------------------
New
--------------------------------------------------------------------------------

* iosxe/c9800

* plugins/linux
* Added uptime command to LINUX_INIT_EXEC_COMMANDS by default.

* unicon
* Added UT for the fix added in unicon

* iosxe
* Updated the disable prompt pattern not to recongnise grub as disable mode prompt.


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

* iosxe
* Updated exec error pattern
* Fixed ACM Configure service end-state handling.

* generic
* Updated syslog pattern to handle RSA key log message


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/october
2025/september
2025/august
2025/july
Expand Down
2 changes: 1 addition & 1 deletion src/unicon/plugins/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "25.9"
__version__ = "25.10"

supported_chassis = [
'single_rp',
Expand Down
2 changes: 1 addition & 1 deletion src/unicon/plugins/generic/patterns.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def __init__(self):
r"^.*?(%\w+(-\S+)?-\d+-\w+|"
r"yang-infra:|PKI_SSL_IPC:|Guestshell destroyed successfully|"
r"%Error opening tftp:\/\/255\.255\.255\.255|Autoinstall trying|"
r"audit: kauditd hold queue overflow|SECURITY WARNING|"
r"audit: kauditd hold queue overflow|SECURITY WARNING|%RSA key|"
r"(LC|RP)/\d+/\d+/CPU\d+:\w+\s+\d+\s+\d{2}:\d{2}:\d{2}|"
r"\[OK\]"
r").*\s*$"
Expand Down
4 changes: 2 additions & 2 deletions src/unicon/plugins/iosxe/cat9k/c9800/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
from .statemachine import IosXEc9800SingleRpStateMachine
from .settings import IosXEc9800Settings
from .. import service_implementation as svc

from .service_implementation import Rommon

class IosXEc9800ServiceList(IosXEServiceList):
def __init__(self):
super().__init__()
self.reload = svc.Reload
self.rommon = svc.Rommon
self.rommon = Rommon


class IosXEc9800SingleRpConnection(IosXESingleRpConnection):
Expand Down
30 changes: 30 additions & 0 deletions src/unicon/plugins/iosxe/cat9k/c9800/service_implementation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@


from unicon.eal.dialogs import Dialog
from unicon.core.errors import SubCommandFailure
from unicon.plugins.generic.service_implementation import Execute as GenericExecute

class Rommon(GenericExecute):
"""C9800-specific Rommon service.
Requires explicit config_register to be passed when invoked.
No Enable Break parsing (not in C9800 show boot output).
"""
def __init__(self, connection, context, **kwargs):
super().__init__(connection, context, **kwargs)
self.start_state = 'rommon'
self.end_state = 'rommon'
self.service_name = 'rommon'
self.timeout = kwargs.get('reload_timeout', 600)
self.__dict__.update(kwargs)

def pre_service(self, *args, **kwargs):
sm = self.get_sm()
con = self.connection
sm.go_to('enable', con.spawn, context=self.context)
confreg = kwargs.get('config_register', "0x0")
try:
con.configure(f'config-register {confreg}')
except Exception as err:
raise SubCommandFailure(f"Failed to configure config-register {confreg}", err)

super().pre_service(*args, **kwargs)
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
Authors:
pyATS TEAM ([email protected], [email protected])
"""

import re
from unicon.eal.dialogs import Dialog
from unicon.bases.routers.connection_provider import BaseStackRpConnectionProvider

from unicon.plugins.generic.statements import connection_statement_list, custom_auth_statements


class StackwiseVirtualConnectionProvider(BaseStackRpConnectionProvider):
""" Implements Stack Connection Provider,
This class overrides the base class with the
Expand Down Expand Up @@ -49,9 +48,11 @@ def designate_handles(self):
con.log.debug('{} in state: {}'.format(subcon.alias, subcon.state_machine.current_state))

if subcon1.state_machine.current_state == 'enable':
target_con = subcon1
target_alias = subcon1_alias
other_alias = subcon2_alias
elif subcon2.state_machine.current_state == 'enable':
target_con = subcon2
target_alias = subcon2_alias
other_alias = subcon1_alias

Expand All @@ -60,7 +61,6 @@ def designate_handles(self):
con._handles_designated = True

device = con.device

try:
# To check if the device is in SVL state
output = device.parse("show switch")
Expand All @@ -72,7 +72,23 @@ def designate_handles(self):
# There are case when in non-SVL the device connection
# becomes active for both connection and there isn't a standby state
# it would have either active and member state or just active state
super().designate_handles()

# Verify the active and standby
target_con.spawn.sendline(target_con.spawn.settings.SHOW_REDUNDANCY_CMD)
output = target_con.spawn.expect(
target_con.state_machine.get_state('enable').pattern,
timeout=con.settings.EXEC_TIMEOUT).match_output

state = re.findall(target_con.spawn.settings.REDUNDANCY_STATE_PATTERN, output, flags=re.M)
target_con.log.debug(f'{target_con.spawn} state: {state}')
if any('active' in s.lower() for s in state):
con._set_active_alias(target_alias)
con._set_standby_alias(other_alias)
elif any('standby' in s.lower() for s in state):
con._set_standby_alias(target_alias)
con._set_active_alias(other_alias)
else:
raise ConnectionError('unable to designate handles')

except Exception:
con.log.exception("Failed to designate handle for SVL stack")
Expand Down
2 changes: 1 addition & 1 deletion src/unicon/plugins/iosxe/patterns.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def __init__(self):
self.want_continue_confirm = r'.*Do you want to continue\?\s*\[confirm]\s*$'
self.want_continue_yes = r'.*Do you want to continue\?\s*\[y/n]\?\s*\[yes]:\s*$'
self.disable_prompt = \
r'^(.*?)(\(unlicensed\))?(wlc|WLC|Router|RouterRP|Switch|ios|switch|%N)([0-9])?(\(recovery-mode\))?(\(rp-rec-mode\))?(\(standby\))?(-stby)?(-standby)?(\(boot\))?(?<! -)>\s?$'
r'^(?!.*?grub)(.*?)(\(unlicensed\))?(wlc|WLC|Router|RouterRP|Switch|ios|switch|%N)([0-9])?(\(recovery-mode\))?(\(rp-rec-mode\))?(\(standby\))?(-stby)?(-standby)?(\(boot\))?(?<! -)>\s?$'
self.enable_prompt = \
r'^(.*?)(\(unlicensed\))?(wlc|WLC|Router|RouterRP|Switch|ios|switch|%N)([0-9])?(\(recovery-mode\))?(\(rp-rec-mode\))?(\(standby\))?(-stby)?(-standby)?(\(boot\))?#[\s\x07]*$'
self.maintenance_mode_prompt = \
Expand Down
2 changes: 1 addition & 1 deletion src/unicon/plugins/iosxe/service_implementation.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def pre_service(self, *args, **kwargs):
if self.acm_configlet:
self.connection.state_machine.go_to('acm', self.connection.spawn,context={'acm_configlet': self.acm_configlet})
self.start_state = 'acm'
self.end_state = 'acm'
self.end_state = 'enable'

elif self.rules:
if self.connection.connected:
Expand Down
2 changes: 1 addition & 1 deletion src/unicon/plugins/iosxe/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def __init__(self):
self.PROMPT_RECOVERY_COMMANDS = ['\r', '\x1e', '\x03']

self.ERROR_PATTERN = [
r'^%\s*[Ii]nvalid (command|input)',
r'^\s*%\s*[Ii]nvalid (command|input)',
r'^%\s*[Ii]ncomplete (command|input)',
r'^%\s*[Aa]mbiguous (command|input)',
r'% Bad IP address or host name',
Expand Down
2 changes: 1 addition & 1 deletion src/unicon/plugins/linux/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def __init__(self):
""" initialize
"""
super().__init__()
self.LINUX_INIT_EXEC_COMMANDS = []
self.LINUX_INIT_EXEC_COMMANDS = ['uptime']

## Prompt recovery commands for Linux
# Default commands: Enter key , Ctrl-C, Enter Key
Expand Down
4 changes: 2 additions & 2 deletions src/unicon/plugins/tests/mock/mock_device_iosxe.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,10 +275,10 @@ def svl_stack_enable(self, transport, cmd):
for idx, port in enumerate(ports):
if idx == 0:
# standby -> active
self.set_state(port, 'svl_stack_enable')
self.set_state(port, 'svl_post_switchover_active_enable')
elif idx == 1:
# active -> standby
self.set_state(port, 'svl_standby_switchover')
self.set_state(port, 'svl_post_switchover_standby_enable')

def update_show_switch(self, transport):
port = self.transport_handles[transport]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ asr_exec:
"term length 0": ""
"term width 0": ""
"show version": *SV
"show install summary": ""
"enable":
new_state: enable_asr

Expand Down Expand Up @@ -216,6 +217,8 @@ config_asr:
new_state: config_line_asr
"redundancy":
new_state: config_asr_redundancy
"end":
new_state: enable_asr

config_line_asr:
prompt: "%N(config-line)#"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,8 @@ config_c9k2:
new_state: config_line_c9k2
"redundancy":
new_state: config_c9k_redundancy2
"end":
new_state: enable_c9k2

config_line_c9k2:
prompt: "%N(config-line)#"
Expand Down Expand Up @@ -922,6 +924,8 @@ config_c9k:
new_state: config_line_c9k
"line console 0":
new_state: config_line_c9k
"end":
new_state: enable_c9k

config_line_c9k:
prompt: "%N(config-line)#"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ c9k_config4:
"no boot system":
response: "Config session is locked by process '566', user will be pushed back to exec mode. Command execution is locked, Please try later."
new_state: c9k_enable4a
"end":
new_state: c9k_enable4a

c9k_config4a:
prompt: "%N(config)#"
Expand Down
Loading
Loading