From 6017e77eff76886f7b826d52216f6771455a83c5 Mon Sep 17 00:00:00 2001 From: Harinadh Saladi Date: Wed, 14 Jan 2026 06:30:03 +0000 Subject: [PATCH] Add apic_m4_l4_db_snapshot_check for CSCwn62369 --- aci-preupgrade-validation-script.py | 46 ++++++++- docs/docs/validations.md | 19 +++- .../eqptCh_l2.json | 13 +++ .../eqptCh_l4.json | 13 +++ .../eqptCh_m4.json | 24 +++++ .../fabricNode_l2.json | 13 +++ .../fabricNode_l4.json | 13 +++ .../fabricNode_m4.json | 24 +++++ .../test_apic_m4_l4_db_snapshot_check.py | 97 +++++++++++++++++++ 9 files changed, 260 insertions(+), 2 deletions(-) create mode 100644 tests/checks/apic_m4_l4_db_snapshot_check/eqptCh_l2.json create mode 100644 tests/checks/apic_m4_l4_db_snapshot_check/eqptCh_l4.json create mode 100644 tests/checks/apic_m4_l4_db_snapshot_check/eqptCh_m4.json create mode 100644 tests/checks/apic_m4_l4_db_snapshot_check/fabricNode_l2.json create mode 100644 tests/checks/apic_m4_l4_db_snapshot_check/fabricNode_l4.json create mode 100644 tests/checks/apic_m4_l4_db_snapshot_check/fabricNode_m4.json create mode 100644 tests/checks/apic_m4_l4_db_snapshot_check/test_apic_m4_l4_db_snapshot_check.py diff --git a/aci-preupgrade-validation-script.py b/aci-preupgrade-validation-script.py index ebe0477..fddccc7 100644 --- a/aci-preupgrade-validation-script.py +++ b/aci-preupgrade-validation-script.py @@ -6004,9 +6004,52 @@ def apic_vmm_inventory_sync_faults_check(**kwargs): data=data, unformatted_headers=unformatted_headers, unformatted_data=unformatted_data, - recommended_action=recommended_action, doc_url=doc_url) + +@check_wrapper(check_title="APIC M4/L4 Model db_snapshot Script Issue") +def apic_m4_l4_db_snapshot_check(tversion, fabric_nodes, **kwargs): + result = FAIL_O + headers = ["Node ID", "APIC Model", "Status"] + data = [] + recommended_action = "Please contact TAC, requires the db_snapshot.sh to be modified" + doc_url = "https://datacenter.github.io/ACI-Pre-Upgrade-Validation-Script/validations/#apic-m4-l4-model-db-snapshot-script-issue" + + # Check 1: Verify target version is provided + if not tversion: + return Result(result=MANUAL, msg=TVER_MISSING) + + # Check 2: Verify target version is affected + # Only applicable to 5.3.x releases older than 5.3(2f) or 6.0.x releases older than 6.0(9c) + # Not impacting 5.2, 4.2, 6.1 or any other major release + if tversion.major_version == "5.3": + if not tversion.older_than("5.3(2f)"): + return Result(result=NA, msg=VER_NOT_AFFECTED) + elif tversion.major_version == "6.0": + if not tversion.older_than("6.0(9c)"): + return Result(result=NA, msg=VER_NOT_AFFECTED) + else: + return Result(result=NA, msg=VER_NOT_AFFECTED) + + # Check 3: Get APIC controllers from fabric_nodes + apics = [node for node in fabric_nodes if node["fabricNode"]["attributes"]["role"] == "controller"] + + if not apics: + return Result(result=ERROR, msg="No controllers found in fabricNode. Is the cluster healthy?", doc_url=doc_url) + + # Check 4: Identify affected APIC models (M4 or L4) + for apic in apics: + apic_model = apic['fabricNode']['attributes']['model'] + node_id = apic['fabricNode']['attributes']['id'] + + if "APIC-SERVER-M4" in apic_model or "APIC-SERVER-L4" in apic_model: + data.append([node_id, apic_model, "Affected"]) + + if not data: + result = PASS + + return Result(result=result, headers=headers, data=data, recommended_action=recommended_action, doc_url=doc_url) + # ---- Script Execution ---- @@ -6168,6 +6211,7 @@ class CheckManager: standby_sup_sync_check, isis_database_byte_check, configpush_shard_check, + apic_m4_l4_db_snapshot_check, ] ssh_checks = [ diff --git a/docs/docs/validations.md b/docs/docs/validations.md index fa1fc0e..9b9f74f 100644 --- a/docs/docs/validations.md +++ b/docs/docs/validations.md @@ -190,7 +190,8 @@ Items | Defect | This Script [Observer Database Size][d25] | CSCvw45531 | :white_check_mark: | :no_entry_sign: [Stale pconsRA Object][d26] | CSCwp22212 | :warning:{title="Deprecated"} | :no_entry_sign: [ISIS DTEPs Byte Size][d27] | CSCwp15375 | :white_check_mark: | :no_entry_sign: -[Policydist configpushShardCont Crash][d28] | CSCwp95515 | :white_check_mark: | +[Policydist configpushShardCont Crash][d28] | CSCwp95515 | :white_check_mark: | +[APIC M4/L4 Model db_snapshot Script Issue][d29] | CSCwn62369 | :white_check_mark: | :no_entry_sign: [d1]: #ep-announce-compatibility [d2]: #eventmgr-db-size-defect-susceptibility @@ -220,6 +221,7 @@ Items | Defect | This Script [d26]: #stale-pconsra-object [d27]: #isis-dteps-byte-size [d28]: #policydist-configpushshardcont-crash +[d29]: #apic-m4l4-model-db_snapshot-script-issue ## General Check Details @@ -2614,6 +2616,21 @@ Due to [CSCwp95515][59], upgrading to an affected version while having any `conf If any instances of `configpushShardCont` are flagged by this script, Cisco TAC must be contacted to identify and resolve the underlying issue before performing the upgrade. +### APIC M4/L4 Model db_snapshot Script Issue + +Due to the defect CSCwn62369, the db_snapshot.sh script on APIC-SERVER-M4 and APIC-SERVER-L4 models requires modification before upgrading to certain versions. This issue affects upgrades to versions earlier than 5.3(2f) in the 5.3 train or earlier than 6.0(9c) in the 6.0 train. The defect does not impact 5.2, 4.2, 6.1, or any other release trains. + +The script checks if: + +* The target APIC version is 5.3.x (but earlier than 5.3(2f)) or 6.0.x (but earlier than 6.0(9c)) +* Any APICs in the cluster are running APIC-SERVER-M4 or APIC-SERVER-L4 hardware models + +If both conditions are met, the db_snapshot.sh script must be modified by TAC before performing the upgrade to avoid potential issues with database snapshot operations. + +!!! important + If this check fails, please contact TAC before upgrading. The db_snapshot.sh script requires modification specific to M4/L4 hardware models. + + [0]: https://github.com/datacenter/ACI-Pre-Upgrade-Validation-Script [1]: https://www.cisco.com/c/dam/en/us/td/docs/Website/datacenter/apicmatrix/index.html [2]: https://www.cisco.com/c/en/us/support/switches/nexus-9000-series-switches/products-release-notes-list.html diff --git a/tests/checks/apic_m4_l4_db_snapshot_check/eqptCh_l2.json b/tests/checks/apic_m4_l4_db_snapshot_check/eqptCh_l2.json new file mode 100644 index 0000000..edfe309 --- /dev/null +++ b/tests/checks/apic_m4_l4_db_snapshot_check/eqptCh_l2.json @@ -0,0 +1,13 @@ +[ + { + "eqptCh": { + "attributes": { + "bootSource": "bootflash", + "cimcVersion": "4.0(2f)", + "descr": "APIC-SERVER-L2", + "dn": "topology/pod-1/node-1/sys/ch", + "model": "APIC-SERVER-L2" + } + } + } +] diff --git a/tests/checks/apic_m4_l4_db_snapshot_check/eqptCh_l4.json b/tests/checks/apic_m4_l4_db_snapshot_check/eqptCh_l4.json new file mode 100644 index 0000000..8f46a0d --- /dev/null +++ b/tests/checks/apic_m4_l4_db_snapshot_check/eqptCh_l4.json @@ -0,0 +1,13 @@ +[ + { + "eqptCh": { + "attributes": { + "bootSource": "bootflash", + "cimcVersion": "4.2(1a)", + "descr": "APIC-SERVER-L4", + "dn": "topology/pod-1/node-1/sys/ch", + "model": "APIC-SERVER-L4" + } + } + } +] diff --git a/tests/checks/apic_m4_l4_db_snapshot_check/eqptCh_m4.json b/tests/checks/apic_m4_l4_db_snapshot_check/eqptCh_m4.json new file mode 100644 index 0000000..c15b860 --- /dev/null +++ b/tests/checks/apic_m4_l4_db_snapshot_check/eqptCh_m4.json @@ -0,0 +1,24 @@ +[ + { + "eqptCh": { + "attributes": { + "bootSource": "bootflash", + "cimcVersion": "4.2(1a)", + "descr": "APIC-SERVER-M4", + "dn": "topology/pod-1/node-1/sys/ch", + "model": "APIC-SERVER-M4" + } + } + }, + { + "eqptCh": { + "attributes": { + "bootSource": "bootflash", + "cimcVersion": "4.2(1a)", + "descr": "APIC-SERVER-M4", + "dn": "topology/pod-1/node-2/sys/ch", + "model": "APIC-SERVER-M4" + } + } + } +] diff --git a/tests/checks/apic_m4_l4_db_snapshot_check/fabricNode_l2.json b/tests/checks/apic_m4_l4_db_snapshot_check/fabricNode_l2.json new file mode 100644 index 0000000..1df45f0 --- /dev/null +++ b/tests/checks/apic_m4_l4_db_snapshot_check/fabricNode_l2.json @@ -0,0 +1,13 @@ +[ + { + "fabricNode": { + "attributes": { + "id": "1", + "name": "apic1", + "role": "controller", + "model": "APIC-SERVER-L2", + "address": "10.0.0.1" + } + } + } +] diff --git a/tests/checks/apic_m4_l4_db_snapshot_check/fabricNode_l4.json b/tests/checks/apic_m4_l4_db_snapshot_check/fabricNode_l4.json new file mode 100644 index 0000000..ca05d21 --- /dev/null +++ b/tests/checks/apic_m4_l4_db_snapshot_check/fabricNode_l4.json @@ -0,0 +1,13 @@ +[ + { + "fabricNode": { + "attributes": { + "id": "1", + "name": "apic1", + "role": "controller", + "model": "APIC-SERVER-L4", + "address": "10.0.0.1" + } + } + } +] diff --git a/tests/checks/apic_m4_l4_db_snapshot_check/fabricNode_m4.json b/tests/checks/apic_m4_l4_db_snapshot_check/fabricNode_m4.json new file mode 100644 index 0000000..18cf051 --- /dev/null +++ b/tests/checks/apic_m4_l4_db_snapshot_check/fabricNode_m4.json @@ -0,0 +1,24 @@ +[ + { + "fabricNode": { + "attributes": { + "id": "1", + "name": "apic1", + "role": "controller", + "model": "APIC-SERVER-M4", + "address": "10.0.0.1" + } + } + }, + { + "fabricNode": { + "attributes": { + "id": "2", + "name": "apic2", + "role": "controller", + "model": "APIC-SERVER-M4", + "address": "10.0.0.2" + } + } + } +] diff --git a/tests/checks/apic_m4_l4_db_snapshot_check/test_apic_m4_l4_db_snapshot_check.py b/tests/checks/apic_m4_l4_db_snapshot_check/test_apic_m4_l4_db_snapshot_check.py new file mode 100644 index 0000000..bd4a81b --- /dev/null +++ b/tests/checks/apic_m4_l4_db_snapshot_check/test_apic_m4_l4_db_snapshot_check.py @@ -0,0 +1,97 @@ +import os +import pytest +import logging +import importlib +from helpers.utils import read_data + +script = importlib.import_module("aci-preupgrade-validation-script") + +log = logging.getLogger(__name__) +dir = os.path.dirname(os.path.abspath(__file__)) + +test_function = "apic_m4_l4_db_snapshot_check" + + +@pytest.mark.parametrize( + "tversion, fabric_nodes, expected_result", + [ + # Test 1: MANUAL - No target version + ( + None, + read_data(dir, "fabricNode_m4.json"), + script.MANUAL, + ), + # Test 2: NA - Target version not affected (5.2 train) + ( + "5.2(7f)", + read_data(dir, "fabricNode_m4.json"), + script.NA, + ), + # Test 3: NA - Target version not affected (4.2 train) + ( + "4.2(7t)", + read_data(dir, "fabricNode_m4.json"), + script.NA, + ), + # Test 4: NA - Target version not affected (6.1 train) + ( + "6.1(3a)", + read_data(dir, "fabricNode_m4.json"), + script.NA, + ), + # Test 5: NA - Target version 5.3(2f) or newer + ( + "5.3(2f)", + read_data(dir, "fabricNode_m4.json"), + script.NA, + ), + # Test 6: NA - Target version 6.0(9c) or newer + ( + "6.0(9c)", + read_data(dir, "fabricNode_m4.json"), + script.NA, + ), + # Test 7: FAIL_O - M4 model with affected 5.3 version + ( + "5.3(2a)", + read_data(dir, "fabricNode_m4.json"), + script.FAIL_O, + ), + # Test 8: FAIL_O - M4 model with affected 6.0 version + ( + "6.0(8a)", + read_data(dir, "fabricNode_m4.json"), + script.FAIL_O, + ), + # Test 9: FAIL_O - L4 model with affected 5.3 version + ( + "5.3(1a)", + read_data(dir, "fabricNode_l4.json"), + script.FAIL_O, + ), + # Test 10: FAIL_O - L4 model with affected 6.0 version + ( + "6.0(5a)", + read_data(dir, "fabricNode_l4.json"), + script.FAIL_O, + ), + # Test 11: PASS - L2 model (not affected) with affected version + ( + "5.3(2a)", + read_data(dir, "fabricNode_l2.json"), + script.PASS, + ), + # Test 12: PASS - L2 model (not affected) with affected version + ( + "6.0(8a)", + read_data(dir, "fabricNode_l2.json"), + script.PASS, + ), + ], +) +def test_logic(run_check, tversion, fabric_nodes, expected_result): + if tversion: + result = run_check(tversion=script.AciVersion(tversion), fabric_nodes=fabric_nodes) + else: + result = run_check(tversion=None, fabric_nodes=fabric_nodes) + assert result.result == expected_result