Skip to content

Commit ea90729

Browse files
authored
Merge pull request #29 from cisco-en-programmability/provision_bug_fixes
Provision workflow manager validation fix
2 parents 337a8f7 + d518e10 commit ea90729

3 files changed

Lines changed: 1298 additions & 99 deletions

File tree

plugins/modules/provision_workflow_manager.py

Lines changed: 65 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@
318318
default: false
319319
requirements:
320320
- catalystcentersdk >= 3.1.6.0.2
321-
- python >= 3.9
321+
- python >= 3.12
322322
notes:
323323
- SDK Methods used are sites.Sites.get_site,
324324
devices.Devices.get_network_device_by_ip,
@@ -688,7 +688,20 @@ def validate_input(self, state=None):
688688
"elements": "dict",
689689
},
690690
"skip_ap_provision": {"type": "bool", "required": False},
691-
"rolling_ap_upgrade": {"type": "dict", "required": False},
691+
"rolling_ap_upgrade": {
692+
"type": "dict",
693+
"required": False,
694+
"options": {
695+
"enable_rolling_ap_upgrade": {
696+
"type": "bool",
697+
"required": False,
698+
},
699+
"ap_reboot_percentage": {
700+
"type": "int",
701+
"required": False,
702+
},
703+
},
704+
},
692705
"ap_authorization_list_name": {"type": "str", "required": False},
693706
"authorize_mesh_and_non_mesh_aps": {"type": "bool", "required": False, "default": False},
694707
"provisioning": {"type": "bool", "required": False, "default": True},
@@ -735,11 +748,11 @@ def validate_input(self, state=None):
735748

736749
for config_item in self.config:
737750
telemetry_list = config_item.get("application_telemetry", [])
738-
for index, config_item in enumerate(self.config):
751+
for index, config_item in enumerate(self.config, start=1):
739752
telemetry_list = config_item.get("application_telemetry", [])
740753

741754
# Validate each telemetry entry
742-
for entry_index, telemetry_entry in enumerate(telemetry_list):
755+
for entry_index, telemetry_entry in enumerate(telemetry_list, start=1):
743756

744757
if (
745758
"device_ips" not in telemetry_entry
@@ -782,7 +795,7 @@ def validate_input(self, state=None):
782795
"type": "str",
783796
"required": True,
784797
}
785-
for index, config_item in enumerate(self.config):
798+
for index, config_item in enumerate(self.config, start=1):
786799
if (
787800
"site_name_hierarchy" not in config_item
788801
or not config_item["site_name_hierarchy"]
@@ -818,6 +831,36 @@ def validate_input(self, state=None):
818831
)
819832
self.set_operation_result("failed", False, self.msg, "ERROR").check_return_status()
820833

834+
rolling_ap_upgrade = config_item.get("rolling_ap_upgrade")
835+
if rolling_ap_upgrade is not None:
836+
self.log(
837+
"Validating 'rolling_ap_upgrade' in config item at index {0}.".format(index),
838+
"DEBUG",
839+
)
840+
841+
ap_reboot_percentage = rolling_ap_upgrade.get("ap_reboot_percentage")
842+
if ap_reboot_percentage is not None:
843+
allowed_ap_reboot_percentages = frozenset({5, 15, 25})
844+
if not str(ap_reboot_percentage).isdigit():
845+
self.msg = (
846+
"Invalid 'ap_reboot_percentage' value '{0}'. Must be an integer. "
847+
"Supported values are 5, 15, and 25.".format(ap_reboot_percentage)
848+
)
849+
self.set_operation_result("failed", False, self.msg, "ERROR").check_return_status()
850+
elif int(ap_reboot_percentage) not in allowed_ap_reboot_percentages:
851+
self.msg = (
852+
"Invalid 'ap_reboot_percentage' value '{0}'. "
853+
"Supported values are 5, 15, and 25.".format(ap_reboot_percentage)
854+
)
855+
self.set_operation_result("failed", False, self.msg, "ERROR").check_return_status()
856+
else:
857+
self.log(
858+
"Validated 'ap_reboot_percentage' with supported value '{0}' in config item at index {1}.".format(
859+
ap_reboot_percentage, index
860+
),
861+
"DEBUG",
862+
)
863+
821864
if missing_params:
822865
self.msg = "Missing or invalid required parameter(s): {0}".format(
823866
", ".join(set(missing_params))
@@ -2612,11 +2655,12 @@ def get_device_type(self):
26122655
)
26132656

26142657
except Exception as e:
2615-
error_message = "The Device - {0} is already deleted from the Inventory or not present in the Cisco Catalyst Center.".format(
2616-
device["management_ip_address"]
2658+
self.msg = "Device with IP {0} not found in Cisco Catalyst Center.".format(
2659+
ip_address
26172660
)
2618-
self.log(error_message, "WARNING")
2619-
continue
2661+
self.set_operation_result(
2662+
"failed", False, self.msg, "ERROR"
2663+
).check_return_status()
26202664

26212665
if not dev_response or "response" not in dev_response:
26222666
self.log(
@@ -3446,44 +3490,14 @@ def provision_wireless_device(self):
34463490
self.log("'skip_ap_provision' is not specified", "DEBUG")
34473491

34483492
self.log("Processing rolling AP upgrade settings", "INFO")
3449-
allowed_ap_reboot_percentages = {5, 10, 25}
34503493

34513494
if "rolling_ap_upgrade" in prov_params:
34523495
self.log("Found 'rolling_ap_upgrade' in provisioning parameters", "DEBUG")
34533496

34543497
rolling_upgrade_config = {}
34553498
rolling_upgrade_data = prov_params["rolling_ap_upgrade"]
34563499

3457-
if "ap_reboot_percentage" in rolling_upgrade_data:
3458-
reboot_percentage_value = rolling_upgrade_data["ap_reboot_percentage"]
3459-
3460-
if reboot_percentage_value is None or not str(reboot_percentage_value).isdigit():
3461-
self.msg = (
3462-
"Error: Invalid percentage value '{0}'. Must be an integer. "
3463-
"Supported values are 5, 10, and 25.".format(reboot_percentage_value)
3464-
)
3465-
self.set_operation_result("failed", False, self.msg, "ERROR").check_return_status()
3466-
3467-
reboot_percentage_value = int(reboot_percentage_value)
3468-
if reboot_percentage_value not in allowed_ap_reboot_percentages:
3469-
self.msg = (
3470-
"Error: Invalid percentage value '{0}'. "
3471-
"Supported values are 5, 10, and 25.".format(reboot_percentage_value)
3472-
)
3473-
self.set_operation_result("failed", False, self.msg, "ERROR").check_return_status()
3474-
3475-
rolling_upgrade_config["ap_reboot_percentage"] = reboot_percentage_value
3476-
self.log(
3477-
"Processed 'ap_reboot_percentage': {0}".format(reboot_percentage_value),
3478-
"DEBUG",
3479-
)
3480-
3481-
# Process remaining keys in 'rolling_ap¿_upgrade'
34823500
for key, value in rolling_upgrade_data.items():
3483-
if key == "ap_reboot_percentage":
3484-
self.log("Skipping already processed key 'ap_reboot_percentage'", "DEBUG")
3485-
continue
3486-
34873501
if value is not None:
34883502
rolling_upgrade_config[key] = value
34893503
self.log(
@@ -3496,6 +3510,18 @@ def provision_wireless_device(self):
34963510
"DEBUG",
34973511
)
34983512

3513+
# Normalize validated percentage to int for SDK payload schema.
3514+
if rolling_upgrade_config.get("ap_reboot_percentage") is not None:
3515+
rolling_upgrade_config["ap_reboot_percentage"] = int(
3516+
rolling_upgrade_config["ap_reboot_percentage"]
3517+
)
3518+
self.log(
3519+
"Normalized 'ap_reboot_percentage' to int: {0}".format(
3520+
rolling_upgrade_config["ap_reboot_percentage"]
3521+
),
3522+
"DEBUG",
3523+
)
3524+
34993525
payload["rollingApUpgrade"] = rolling_upgrade_config
35003526

35013527
# Process AP authorization list configuration if provided

0 commit comments

Comments
 (0)