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
46 changes: 46 additions & 0 deletions docs/changelog/2024/july.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
July 2024
==========

July 30 - Unicon v24.7
------------------------



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

``unicon.plugins``, v24.7
``unicon``, v24.7

Install Instructions
^^^^^^^^^^^^^^^^^^^^

.. code-block:: bash

bash$ pip install unicon.plugins
bash$ pip install unicon

Upgrade Instructions
^^^^^^^^^^^^^^^^^^^^

.. code-block:: bash

bash$ pip install --upgrade unicon.plugins
bash$ pip install --upgrade unicon

Features and Bug Fixes:
^^^^^^^^^^^^^^^^^^^^^^^




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

* generic
* Updated with `sleep_time` to handle the copy command


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

2024/july
2024/june
2024/may
2024/april
Expand Down
46 changes: 46 additions & 0 deletions docs/changelog_plugins/2024/july.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
July 2024
==========

July 30 - Unicon.Plugins v24.7
------------------------



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

``unicon.plugins``, v24.7
``unicon``, v24.7

Install Instructions
^^^^^^^^^^^^^^^^^^^^

.. code-block:: bash

bash$ pip install unicon.plugins
bash$ pip install unicon

Upgrade Instructions
^^^^^^^^^^^^^^^^^^^^

.. code-block:: bash

bash$ pip install --upgrade unicon.plugins
bash$ pip install --upgrade unicon

Features and Bug Fixes:
^^^^^^^^^^^^^^^^^^^^^^^




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

* iosxe
* add "disable_selinux" parameter to bash_console service, to automatically


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

2024/july
2024/june
2024/may
2024/april
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__ = '24.6'
__version__ = '24.7'

supported_chassis = [
'single_rp',
Expand Down
4 changes: 4 additions & 0 deletions src/unicon/plugins/generic/service_implementation.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import collections
import ipaddress
from itertools import chain
import time
import warnings
from datetime import datetime, timedelta

Expand Down Expand Up @@ -1666,6 +1667,9 @@ def call_service(self, reply=Dialog([]), *args, **kwargs): # noqa: C901
for retry_num in range(self.max_attempts):
spawn.sendline(copy_string)
try:
if (sleep_time := kwargs.get('sleep_time')):
con.log.info(f"sleep for {sleep_time} seconds")
time.sleep(sleep_time)
self.result = dialog.process(spawn,
context=copy_context,
timeout=timeout)
Expand Down
3 changes: 2 additions & 1 deletion src/unicon/plugins/iosxe/cat9k/c9800cl/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@

from unicon.plugins.iosxe.cat9k.c9800 import IosXEc9800ServiceList, IosXEc9800SingleRpConnection, IosXEc9800DualRPConnection

from unicon.plugins.iosxe import service_implementation as svc

class IosXEc9800CLServiceList(IosXEc9800ServiceList):
def __init__(self):
super().__init__()
self.rommon = svc.Rommon



Expand Down
22 changes: 22 additions & 0 deletions src/unicon/plugins/iosxe/service_implementation.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,12 @@ def pre_service(self, *args, **kwargs):
handle.context['_chassis'] = kwargs.get('chassis')
else:
handle.context.pop('_chassis', None)
if kwargs.get('disable_selinux') is not None:
handle.context['_disable_selinux'] = kwargs.get('disable_selinux')
elif hasattr(self, 'disable_selinux'):
handle.context['_disable_selinux'] = self.disable_selinux
else:
handle.context.pop('_disable_selinux', None)
super().pre_service(*args, **kwargs)

class ContextMgr(GenericBashService.ContextMgr):
Expand All @@ -176,6 +182,12 @@ def __init__(self, connection, enable_bash=False, timeout=None, **kwargs):

def __enter__(self):

if self.conn.context.get('_disable_selinux'):
try:
self.conn.execute('set platform software selinux permissive')
except SubCommandFailure:
pass

self.conn.log.debug('+++ attaching bash shell +++')
# enter shell prompt
self.conn.state_machine.go_to(
Expand All @@ -190,6 +202,16 @@ def __enter__(self):

return self

def __exit__(self, type, value, traceback):
res = super().__exit__(type, value, traceback)

if self.conn.context.get('_disable_selinux'):
try:
self.conn.execute('set platform software selinux default')
except SubCommandFailure:
pass

return res

class ResetStandbyRP(GenericResetStandbyRP):
""" Service to reset the standby rp.
Expand Down
15 changes: 15 additions & 0 deletions src/unicon/plugins/tests/mock_data/ios/ios_mock_copy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,18 @@ wait_for_recovery:
new_state: enable
response: |
sending keyboard interrupt

copy_src_bootflash:
prompt: "Source filename []? "
commands:
"/c8000aep-universalk9.17.12.04.0.4708.SSA.bin":
new_state: dest_file_name

dest_file_name:
prompt: "Destination filename [c8000aep-universalk9.17.12.04.0.4708.SSA.bin]? "
commands:
"test/c8000aep-universalk9.17.12.04.0.4708.SSA.bin":
new_state: enable
response: |
Copy in progress...CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
787557605 bytes copied in 71.982 secs (10941035 bytes/sec)
2 changes: 2 additions & 0 deletions src/unicon/plugins/tests/mock_data/ios/ios_mock_data.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,8 @@ enable:
new_state: exec_standby
"redundancy switch-activity force":
new_state: confirm_switch_activity
"copy bootflash: usb:":
new_state: copy_src_bootflash
"copy flash: flash-3:":
new_state: copy_src
"copy tftp: bootflash:":
Expand Down
4 changes: 4 additions & 0 deletions src/unicon/plugins/tests/mock_data/iosxe/iosxe_mock_data.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,10 @@ general_enable:
"copy somefile.bin flash:":
new_state: confirm_abort_copy

"set platform software selinux permissive": ""

"set platform software selinux default": ""

general_maintence_mode_confirm:
prompt: "Template default will be applied. Do you want to continue?[confirm] "
commands:
Expand Down
12 changes: 12 additions & 0 deletions src/unicon/plugins/tests/mock_data/iosxe/iosxe_mock_data_isr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,18 @@ enable_isr:
"traceroute vrf MG501":
new_state: traceroute_proto_isr

"set platform software selinux permissive":
response:
- |2
^
% Invalid input detected at '^' marker."

"set platform software selinux default":
response:
- |2
^
% Invalid input detected at '^' marker."

"not a real command":
response:
- |2
Expand Down
11 changes: 11 additions & 0 deletions src/unicon/plugins/tests/test_copy_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,17 @@ def test_copy_error_no_file(self):
timeout=9)
self.assertEqual(err.exception.args[0], 'Copy failed')

def test_copy_to_usb(self):
test_output = self.d.copy(source = 'bootflash:', dest = 'usb:',
source_file = '/c8000aep-universalk9.17.12.04.0.4708.SSA.bin',
dest_file = 'test/c8000aep-universalk9.17.12.04.0.4708.SSA.bin',
sleep_time = 10)
expected_output = self.md.mock_data['dest_file_name']['commands']\
['test/c8000aep-universalk9.17.12.04.0.4708.SSA.bin']['response']
test_output = '\n'.join(test_output.splitlines())
expected_output = '\n'.join(expected_output.splitlines())
self.assertIn(expected_output, test_output)


@patch.object(unicon.settings.Settings, 'POST_DISCONNECT_WAIT_SEC', 0)
@patch.object(unicon.settings.Settings, 'GRACEFUL_DISCONNECT_WAIT_SEC', 0.2)
Expand Down
28 changes: 28 additions & 0 deletions src/unicon/plugins/tests/test_plugin_iosxe.py
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,34 @@ def test_bash_chassis_standby(self):
self.assertIn('WLC1#', c.spawn.match.match_output)
c.disconnect()

def test_bash_disable_selinux(self):
c = Connection(hostname='Router',
start=['mock_device_cli --os iosxe --state general_enable --hostname Router'],
os='iosxe',
credentials=dict(default=dict(username='cisco', password='cisco')),
log_buffer=True
)
with c.bash_console(disable_selinux=True) as console:
self.assertIn('[Router_RP_0:/]$', c.spawn.match.match_output)
console.execute('df /bootflash/')
self.assertIn('set platform software selinux default', c.spawn.match.match_output)
self.assertIn('Router#', c.spawn.match.match_output)
c.disconnect()

def test_bash_disable_selinux_invalid_cmds(self):
c = Connection(hostname='Router',
start=['mock_device_cli --os iosxe --state enable_isr --hostname Router'],
os='iosxe',
credentials=dict(default=dict(username='cisco', password='cisco')),
log_buffer=True
)
with c.bash_console(disable_selinux=True) as console:
self.assertIn('[Router:/]$', c.spawn.match.match_output)
console.execute('ls')
self.assertIn('set platform software selinux default', c.spawn.match.match_output)
self.assertIn('Router#', c.spawn.match.match_output)
c.disconnect()

class TestIosXESDWANConfigure(unittest.TestCase):

def test_config_transaction(self):
Expand Down