Skip to content

Commit

Permalink
Merge pull request #151 from CiscoTestAutomation/release_24.1
Browse files Browse the repository at this point in the history
Release 24.1
  • Loading branch information
Taarini authored Jan 31, 2024
2 parents f41eb58 + d96dde9 commit 633c5a0
Show file tree
Hide file tree
Showing 156 changed files with 5,280 additions and 1,030 deletions.
3 changes: 1 addition & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ RELATED_PKGS += genie.libs.filetransferutils
# pinning the version of pysnmp and pyasn1 to fix the type error when using execute_power_cycle_device api
DEPENDENCIES = restview psutil Sphinx wheel asynctest pysnmp-lextudio==5.0.29 pyasn1==0.4.8
DEPENDENCIES += sphinx-rtd-theme==1.1.0 pyftpdlib tftpy\<0.8.1 robotframework
# aiohttp-swagger 1.0.15 requires jinja2==2.11.2 and markupsafe==1.1.1
DEPENDENCIES += Cython==3.0.0 requests ruamel.yaml grpcio protobuf jinja2==2.11.2 markupsafe==2.0.1
DEPENDENCIES += Cython==3.0.0 requests ruamel.yaml grpcio protobuf jinja2
# Internal variables.
# (note - build examples & templates last because it will fail uploading to pypi
# due to duplicates, and we'll for now accept that error)
Expand Down
24 changes: 24 additions & 0 deletions pkgs/clean-pkg/changelog/2024/january.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
--------------------------------------------------------------------------------
Fix
--------------------------------------------------------------------------------

* iosxe
* Modified copy_to_device clean stage, update logic for image mapping when image is already loaded


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

* cheetah
* Added LoadApImage
* Added new clean stage load_ap_image

* stages/iosxe
* Updated connect stage to support rommon boot

* iosxe
* Added configure_type_access_list_action
* API to configure ip/mac access-list with permission


24 changes: 20 additions & 4 deletions pkgs/clean-pkg/sdk_generator/output/github_clean.json
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@
"module_name": "stages.stages",
"package": "genie.libs.clean",
"uid": "ConfigureReplace",
"url": "https://github.com/CiscoTestAutomation/genielibs/tree/master/pkgs/clean-pkg/src/genie/libs/clean/stages/iosxe/stages.py#L1986"
"url": "https://github.com/CiscoTestAutomation/genielibs/tree/master/pkgs/clean-pkg/src/genie/libs/clean/stages/iosxe/stages.py#L1990"
}
},
"ConfigureRrmDcaChannel": {
Expand All @@ -166,13 +166,18 @@
"url": "https://github.com/CiscoTestAutomation/genielibs/tree/master/pkgs/clean-pkg/src/genie/libs/clean/stages/stages.py#L33"
},
"iosxe": {
"doc": "This stage connects to the device that is being cleaned.\nStage Schema\n------------\nconnect:\n via (str, optional): Which connection to use from the testbed file. Uses the\n default connection if not specified.\n alias (str, optional): Which connection alias to use from the testbed file.\n timeout (int, optional): The timeout for the connection to complete in seconds.\n Defaults to 200.\n retry_timeout (int, optional): Overall timeout for retry mechanism in seconds.\n Defaults to 0 which means no retry.\n retry_interval (int, optional): Interval for retry mechanism in seconds. Defaults\n to 0 which means no retry.\nExample\n-------\nconnect:\n timeout: 60\n",
"module_name": "stages.stages",
"package": "genie.libs.clean",
"sdwan": {
"doc": "This stage connects to the device that is being cleaned.\n\nStage Schema\n------------\nconnect:\n\n via (str, optional): Which connection to use from the testbed file. Uses the\n default connection if not specified.\n\n timeout (int, optional): The timeout for the connection to complete in seconds.\n Defaults to 200.\n\n retry_timeout (int, optional): Overall timeout for retry mechanism in seconds.\n Defaults to 0 which means no retry.\n\n retry_interval (int, optional): Interval for retry mechanism in seconds. Defaults\n to 0 which means no retry.\n\nExample\n-------\nconnect:\n timeout: 60\n",
"module_name": "stages.stages",
"package": "genie.libs.clean",
"uid": "Connect",
"url": "https://github.com/CiscoTestAutomation/genielibs/tree/master/pkgs/clean-pkg/src/genie/libs/clean/stages/iosxe/sdwan/stages.py#L31"
}
},
"uid": "Connect",
"url": "https://github.com/CiscoTestAutomation/genielibs/tree/master/pkgs/clean-pkg/src/genie/libs/clean/stages/iosxe/stages.py#L2046"
},
"linux": {
"wsim": {
Expand Down Expand Up @@ -259,7 +264,7 @@
"module_name": "stages.stages",
"package": "genie.libs.clean",
"uid": "EraseApConfiguration",
"url": "https://github.com/CiscoTestAutomation/genielibs/tree/master/pkgs/clean-pkg/src/genie/libs/clean/stages/cheetah/ap/stages.py#L118"
"url": "https://github.com/CiscoTestAutomation/genielibs/tree/master/pkgs/clean-pkg/src/genie/libs/clean/stages/cheetah/ap/stages.py#L122"
}
}
},
Expand Down Expand Up @@ -371,6 +376,17 @@
"url": "https://github.com/CiscoTestAutomation/genielibs/tree/master/pkgs/clean-pkg/src/genie/libs/clean/stages/iosxe/stages.py#L458"
}
},
"LoadApImage": {
"cheetah": {
"ap": {
"doc": "This stage loads new AP image\n\n Stage Schema\n ------------\n load_ap_image:\n ap_image_path (str): Absolute path where ap image is located\n\n server(str): Server alias which has AP image\n\n protocol(str): protocol through which AP image will be loaded\n\n max_time (int, optional): Maximum time for which this clean stage will try to clean ap.\n Defaults to 1200\n\n\n\n\n Example\n -------\n load_ap_image:\n ap_image_path: \"/auto/wnbu-groups-builds/FAST_BUNDLING/polaris_dev/6640/ap3g3-k9w8-tar.master-cisco.202309180209\"\n server: \"tftp\"\n max_time: \"1200\"\n ",
"module_name": "stages.stages",
"package": "genie.libs.clean",
"uid": "LoadApImage",
"url": "https://github.com/CiscoTestAutomation/genielibs/tree/master/pkgs/clean-pkg/src/genie/libs/clean/stages/cheetah/ap/stages.py#L184"
}
}
},
"LoadPies": {
"iosxr": {
"doc": "This stage installs provided pies onto the device.\n\nStage Schema\n------------\nload_pies:\n\n files (list): List of XR pies to install\n\n server (str, optional): Hostname or IP address of server to use for install\n command. Defaults to None (Looks in the testbed YAML for a TFTP server)\n\n prompt_level (str, optional): Prompt-level argument for install command.\n Defaults to 'none'.\n\n synchronous (bool, optional): Synchronous option for install command.\n Defaults to None.\n\n install_timeout (int, optional): Maximum time in seconds allowed for\n execution of the install command to complete. Defaults to 600.\n\n max_time (int, optional): Maximum time in seconds to wait while verifying\n the pies installed. Defaults to 300.\n\n check_interval (int, optional): Time interval in seconds while verifying\n the pies installed. Defaults to 30.\n\nExample\n-------\nload_pies:\n files:\n - /auto/path/to/image/asr9k-mcast-px.pie-7.3.1.08I\n - /auto/path/to/image/asr9k-mgbl-px.pie-7.3.1.08I\n - /auto/path/to/image/asr9k-mpls-px.pie-7.3.1.08I\n server: 10.1.6.244\n prompt_level: 'all'\n synchronous: True\n timeout: 150\n max_time: 300\n check_interval: 20\n",
Expand Down Expand Up @@ -414,7 +430,7 @@
"module_name": "stages.stages",
"package": "genie.libs.clean",
"uid": "PrimeAp",
"url": "https://github.com/CiscoTestAutomation/genielibs/tree/master/pkgs/clean-pkg/src/genie/libs/clean/stages/cheetah/ap/stages.py#L23"
"url": "https://github.com/CiscoTestAutomation/genielibs/tree/master/pkgs/clean-pkg/src/genie/libs/clean/stages/cheetah/ap/stages.py#L27"
}
}
},
Expand Down
2 changes: 1 addition & 1 deletion pkgs/clean-pkg/src/genie/libs/clean/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
'''

# metadata
__version__ = '23.11'
__version__ = '24.1'
__author__ = 'Cisco Systems Inc.'
__contact__ = ['[email protected]', '[email protected]']
__copyright__ = 'Copyright (c) 2019, Cisco Systems Inc.'
Expand Down
3 changes: 2 additions & 1 deletion pkgs/clean-pkg/src/genie/libs/clean/recovery/recovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,8 @@ def _recovery_steps(device, clear_line=True, powercycler=True,
'ip_address': list,
'subnet_mask': str,
'gateway': str,
'tftp_server': str
'tftp_server': str,
Optional('ether_port'): int,
},
Optional('recovery_password'): str,
Optional('clear_line'): bool,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""Cheetah/AP Image Handler Class"""

from genie.libs.clean.stages.iosxe.image_handler import ImageHandler as IosxeImageHandler
from pyats.utils.fileutils import FileUtils


class ImageHandler(IosxeImageHandler):

def __init__(self, device, images, *args, **kwargs):
super().__init__(device, images, *args, **kwargs)

def update_image_references(self, section):
# section.parameters['image_mapping'] shall be saved in any
# stage that modifies the image name/path
if 'image_mapping' in section.parameters:

for index, image in enumerate(self.image):
# change the saved image to the new image name/path
self.image[index] = section.parameters['image_mapping'].get(image, image)

def update_stamp_ap_image(self, number=''):
"""Update clean section 'stamp_ap_image' with image information"""
stamp_ap_image = self.device.clean.setdefault('stamp_ap_image' + number, {})
if self.override_stage_images:
stamp_ap_image.update({'ap_image_path': self.image[0]})
else:
stamp_ap_image.setdefault('ap_image_path', self.image[0])

def update_copy_to_linux(self, number=''):
"""Update clean section 'copy_to_linux' with image information"""
files = self.device.clean.setdefault('copy_to_linux' + number, {}). \
setdefault('origin', {}).setdefault('files', [])
files.clear()
files.extend(self.image)

def update_load_ap_image(self, number=''):
"""Update clean section 'load_ap_image' with image information"""
load_ap_image = self.device.clean.setdefault('load_ap_image' + number, {})
if self.override_stage_images:
load_ap_image.update({'ap_image_path': self.image[0]})
else:
load_ap_image.setdefault('ap_image_path', self.image[0])


74 changes: 73 additions & 1 deletion pkgs/clean-pkg/src/genie/libs/clean/stages/cheetah/ap/stages.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@
# Python
import logging
import time
import traceback

# Genie
from genie.metaparser.util.schemaengine import Optional
from genie.metaparser.util.schemaengine import Optional, Or
from genie.utils.timeout import Timeout
from genie.libs.clean import BaseStage
from genie.metaparser.util.exceptions import InvalidCommandError

#pyATS
from pyats.utils.fileutils import FileUtils


# Unicon
from unicon.core.errors import SubCommandFailure, ConnectionError, StateMachineError, TimeoutError
Expand Down Expand Up @@ -175,3 +179,71 @@ def erase_configs(self, device, steps, login_credentials_alias, max_time=MAX_TIM
timeout.sleep()
else:
step.failed("Failed to login to device after erasing the AP configs")


class LoadApImage(BaseStage):
"""This stage loads new AP image
Stage Schema
------------
load_ap_image:
ap_image_path (str): Absolute path where ap image is located
server(str): Server alias which has AP image
protocol(str): protocol through which AP image will be loaded
max_time (int, optional): Maximum time for which this clean stage will try to clean ap.
Defaults to 1200
Example
-------
load_ap_image:
ap_image_path: "/auto/wnbu-groups-builds/FAST_BUNDLING/polaris_dev/6640/ap3g3-k9w8-tar.master-cisco.202309180209"
server: "tftp"
max_time: "1200"
"""
# =================
# Argument Defaults
# =================
MAX_TIME = 1200
PROTOCOL = "http"

# ============
# Stage Schema
# ============
schema = {
"server": str,
Optional("ap_image_path"): str,
Optional("protocol"): str,
Optional('max_time'): int,
}

# ==============================
# Execution order of Stage steps
# ==============================
exec_order = [
'load_image'
]

def load_image(self, device, steps, ap_image_path, server, protocol=PROTOCOL, max_time=MAX_TIME):
try:
if not hasattr(device.testbed, 'servers'):
self.failed("Cannot find any servers in the testbed")
fu = FileUtils(testbed=device.testbed)
server_ip = fu.get_server_block(server).get('address')
username, password = fu.get_auth(server)
with steps.start("Load image in to device-{} and verify if its loaded correctly".format(device.name)) as step:
if not ap_image_path.startswith("/"):
ap_image_path = "/" + ap_image_path
full_image_path = "{}://{}:{}".format(protocol, server_ip, ap_image_path)
if not device.api.execute_archive_download(full_image_path, max_time, username, password, reload=True):
step.failed("Failed to load AP image")
except Exception as e:
log.exception(e)
self.failed("Failed to load image on AP")


Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import logging
import unittest
from unittest.mock import patch, Mock


from genie.libs.clean.stages.tests.utils import create_test_device

from pyats.aetest.steps import Steps
from pyats.topology import loader


# Disable logging. It may be useful to comment this out when developing tests.
logging.disable(logging.CRITICAL)


class TestLoadApImage(unittest.TestCase):

def setUp(self):
# Instantiate class object

self.steps = Steps()

# Instantiate device object. This also sets up commonly needed
# attributes and Mock objects associated with the device.
self.device = create_test_device('AP4001.7AB2.C1B6', os='cheetah', platform='ap')
self.device.testbed = loader.load({})
self.device.testbed.servers = {
"credentials": {
"default": {
"username": "username",
"password": "password"
}
},
"address": "1.1.1.1",
"protocol": "tftp",
"custom": {
"collection_upload_server": "tftp"
}
}
self.device.api.execute_archive_download = Mock()

@patch('pyats.utils.fileutils.FileUtils')
def test_load_image(self, mock_file_utils):
# need to import here because we are mocking the pyats.cli.utils.cmd function
from genie.libs.clean.stages.cheetah.ap.stages import LoadApImage

self.cls = LoadApImage()

fu_instance = mock_file_utils.return_value
fu_instance.get_auth.return_value = ('username', 'password')
self.cls.load_image(self.device, self.steps, "/path/to/ap_image_path", self.device.testbed.servers)
self.device.api.execute_archive_download.assert_called_once()
Loading

0 comments on commit 633c5a0

Please sign in to comment.