From 6284b9e819d74da0530a8aa07640dab010372d87 Mon Sep 17 00:00:00 2001 From: Zachery Lantz Date: Thu, 25 Apr 2024 13:26:49 -0400 Subject: [PATCH 1/2] updated upgradepackage to include newer json data, fixed required_for_post bug, added additional code to unit test for examples of how to do an entire upgrade start to finish, fixed a broken import for wait_for_task --- .../update_packages/upgradepackage.py | 7 ++++ unit_tests/upgrades.py | 41 +++++++++++++++++-- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/fmcapi/api_objects/update_packages/upgradepackage.py b/fmcapi/api_objects/update_packages/upgradepackage.py index 104ae9c..c69786a 100644 --- a/fmcapi/api_objects/update_packages/upgradepackage.py +++ b/fmcapi/api_objects/update_packages/upgradepackage.py @@ -21,6 +21,13 @@ class Upgrades(APIClassTemplate): "upgradePackage", "targets", "pushUpgradeFileOnly", + "readinessCheckOnly", + "enableUpgradeRevert", + "autoUpgradeCancel", + ] + REQUIRED_FOR_POST = [ + "upgradePackage", + "targets" ] VALID_FOR_KWARGS = VALID_JSON_DATA + [] URL_SUFFIX = "/updates/upgrades" diff --git a/unit_tests/upgrades.py b/unit_tests/upgrades.py index 88fd4a8..d0a6f23 100644 --- a/unit_tests/upgrades.py +++ b/unit_tests/upgrades.py @@ -1,16 +1,25 @@ import logging import fmcapi import time -from unit_tests import wait_for_task +from .wait_for_task import wait_for_task def test__upgrades(fmc): logging.info( - "Test UpgradePackages/ApplicableDevices/Upgrades with Task." - " This will copy the listed upgrade file to registered devices" + """Test UpgradePackages/ApplicableDevices/Upgrades with Task. + This will copy the listed upgrade file to registered devices + + Commented lines at the bottom show how to trigger readiness check, the actual upgrade process, + and the post upgrade deployment. + + NOTE: this script will do this to ALL applicable devices based on the package_name given. + example: you have 5 FTDvs and you only want to upgrade 2 of them. Input here is just the package_name. + Script will add all eligible devices for the particular file given to the list of devices to run against. + Potentially resulting in upgrading all 5 FTDv unintentionally. + """ ) - package_name = "Cisco_FTD_Patch-6.3.0.3-77.sh.REL.tar" + package_name = "Cisco_FTD_Patch-7.4.1.1-12.sh.REL.tar" device_list = [] logging.info("All UpgradePackages -- >") @@ -37,8 +46,32 @@ def test__upgrades(fmc): upgrades1.upgrade_package(package_name=package_name) upgrades1.pushUpgradeFileOnly = True + logging.info(f"Pushing upgrade file to {device_list}") response = upgrades1.post() logging.info(response) wait_for_task(fmc=fmc, task=response["metadata"]["task"], wait_time=60) + # BELOW ARE EXAMPLES OF HOW TO TRIGGER READINESS CHECKS AND ACTUAL UPGRADES + # THIS INCLUDES REBOOTS AND DEPLOYMENTS. + + # upgrades1.pushUpgradeFileOnly = False + # upgrades1.readinessCheckOnly = True + + # logging.info(f"Triggering readiness checks on {device_list}") + # response = upgrades1.post() + # logging.info(response) + # wait_for_task(fmc=fmc, task=response["metadata"]["task"], wait_time=60) + + # upgrades1.readinessCheckOnly = False + + # logging.info(f"Triggering REAL UPGRADE on {device_list}") + # response = upgrades1.post() + # logging.info(response) + # wait_for_task(fmc=fmc, task=response["metadata"]["task"], wait_time=60) + + # logging.info(f"Upgrade completed. Triggering deployment to devices") + # deployment = fmcapi.DeploymentRequests(fmc=fmc) + # logging.info(deployment) + # wait_for_task(fmc=fmc, task=deployment["metadata"]["task"], wait_time=60) + logging.info("Test UpgradePackages/ApplicableDevices/Upgrades Complete") From d540004b880c7bf243f72acb29c9375da8b8f78f Mon Sep 17 00:00:00 2001 From: Zachery Lantz Date: Thu, 25 Apr 2024 17:27:44 -0400 Subject: [PATCH 2/2] fixed a typo in upgrades unit test, changed response in deployment request to be the entire response so it can be piped into wait_for_task. This doesn't seem to break anything else in the library but could break code in the wild, but I believe returning the full response from a deployment request to be worth the cost --- fmcapi/api_objects/deployment_services/deploymentrequests.py | 2 +- unit_tests/upgrades.py | 5 +++-- unit_tests/wait_for_task.py | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/fmcapi/api_objects/deployment_services/deploymentrequests.py b/fmcapi/api_objects/deployment_services/deploymentrequests.py index 4b9296c..a78e51d 100644 --- a/fmcapi/api_objects/deployment_services/deploymentrequests.py +++ b/fmcapi/api_objects/deployment_services/deploymentrequests.py @@ -63,7 +63,7 @@ def post(self): response = self.fmc.send_to_api( method="post", url=self.URL, json_data=json_data ) - return response["deviceList"] + return response def put(self): """PUT method for API for DeploymentRequests not supported.""" diff --git a/unit_tests/upgrades.py b/unit_tests/upgrades.py index d0a6f23..bffc961 100644 --- a/unit_tests/upgrades.py +++ b/unit_tests/upgrades.py @@ -71,7 +71,8 @@ def test__upgrades(fmc): # logging.info(f"Upgrade completed. Triggering deployment to devices") # deployment = fmcapi.DeploymentRequests(fmc=fmc) - # logging.info(deployment) - # wait_for_task(fmc=fmc, task=deployment["metadata"]["task"], wait_time=60) + # response = deployment.post() + # logging.info(response) + # wait_for_task(fmc=fmc, task=response["metadata"]["task"], wait_time=60) logging.info("Test UpgradePackages/ApplicableDevices/Upgrades Complete") diff --git a/unit_tests/wait_for_task.py b/unit_tests/wait_for_task.py index c1c43f3..b8d29c6 100644 --- a/unit_tests/wait_for_task.py +++ b/unit_tests/wait_for_task.py @@ -4,7 +4,7 @@ def wait_for_task(fmc, task, wait_time=10): - task_completed_states = ["Success", "SUCCESS", "COMPLETED"] + task_completed_states = ["Success", "SUCCESS", "COMPLETED", "Deployed"] try: status = fmcapi.TaskStatuses(fmc=fmc, id=task["id"]) current_status = status.get()