diff --git a/aci-preupgrade-validation-script.py b/aci-preupgrade-validation-script.py index b57821c7..ec763ec2 100644 --- a/aci-preupgrade-validation-script.py +++ b/aci-preupgrade-validation-script.py @@ -5558,6 +5558,33 @@ def configpush_shard_check(tversion, **kwargs): return Result(result=result, headers=headers, data=data, recommended_action=recommended_action, doc_url=doc_url) +@check_wrapper(check_title='Port Tracking Minimal Uplink Zero') +def port_tracking_active_fabric_port_check(tversion, **kwargs): + result = NA + headers = ["Admin State", "Port Tracking Active Fabric Ports"] + data = [] + recommended_action = 'Increase Port Tracking Active Fabric Ports to 1 before upgrade' + doc_url = 'https://datacenter.github.io/ACI-Pre-Upgrade-Validation-Script/validations/#port-tracking-active-fabric-port-zero' + + if not tversion: + return Result(result=MANUAL, msg=TVER_MISSING) + + if tversion.same_as("6.0(9d)"): + result = PASS + port_tracking_api = 'uni/infra/trackEqptFabP-default.json' + port_tracking_mo = icurl('mo', port_tracking_api) + if port_tracking_mo: + admin_st = port_tracking_mo[0]['infraPortTrackPol']['attributes']['adminSt'] + minimal_uplink = port_tracking_mo[0]['infraPortTrackPol']['attributes']['minlinks'] + if admin_st == "on" and minimal_uplink == "0": + data.append([admin_st,minimal_uplink]) + else: + return Result(result=NA, msg=VER_NOT_AFFECTED) + if data: + result = FAIL_O + + return Result(result=result, headers=headers, data=data, recommended_action=recommended_action, doc_url=doc_url) + # ---- Script Execution ---- @@ -5719,6 +5746,7 @@ def get_checks(api_only, debug_function): standby_sup_sync_check, isis_database_byte_check, configpush_shard_check, + port_tracking_active_fabric_port_check, ] conn_checks = [ diff --git a/docs/docs/validations.md b/docs/docs/validations.md index e395564f..5f96657f 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: | :no_entry_sign: +[Port Tracking Active Fabric Port Zero][d29] | CSCwp91797 | :white_check_mark: | [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]: #port-tracking-active-fabric-port-zero ## General Check Details @@ -2603,6 +2605,12 @@ 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. +### Port Tracking Active Fabric Port Zero + +Due to [CSCwp91797][62], if port-tracking feature is on and "number of active fabric ports that triggers port tracking" is zero, vPC member may be showing down post upgrade, the interface status become "initializing" by CLI "show interface e1/xx" + +This defect is only applicable to 6.0(9d), change port-tracking "number of active fabric ports that triggers port tracking" to 1 before upgrade can avoid this issue. + [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 @@ -2666,3 +2674,4 @@ If any instances of `configpushShardCont` are flagged by this script, Cisco TAC [59]: https://bst.cloudapps.cisco.com/bugsearch/bug/CSCwp95515 [60]: https://www.cisco.com/c/en/us/solutions/collateral/data-center-virtualization/application-centric-infrastructure/white-paper-c11-743951.html#Inter [61]: https://www.cisco.com/c/en/us/solutions/collateral/data-center-virtualization/application-centric-infrastructure/white-paper-c11-743951.html#EnablePolicyCompression +[62]: https://bst.cloudapps.cisco.com/bugsearch/bug/CSCwp91797 diff --git a/tests/port_tracking_active_fabric_port_check/infraPortTrackPol_neg.json b/tests/port_tracking_active_fabric_port_check/infraPortTrackPol_neg.json new file mode 100644 index 00000000..ce366e3d --- /dev/null +++ b/tests/port_tracking_active_fabric_port_check/infraPortTrackPol_neg.json @@ -0,0 +1,30 @@ +{ + "totalCount": "1", + "imdata": [ + { + "infraPortTrackPol": { + "attributes": { + "adminSt": "off", + "annotation": "", + "childAction": "", + "delay": "120", + "descr": "", + "dn": "uni/infra/trackEqptFabP-default", + "extMngdBy": "", + "includeApicPorts": "no", + "lcOwn": "local", + "minlinks": "0", + "modTs": "2025-10-31T17:13:46.220+11:00", + "name": "default", + "nameAlias": "", + "ownerKey": "", + "ownerTag": "", + "rn": "trackEqptFabP-default", + "status": "", + "uid": "0", + "userdom": "all" + } + } + } + ] +} \ No newline at end of file diff --git a/tests/port_tracking_active_fabric_port_check/infraPortTrackPol_neg1.json b/tests/port_tracking_active_fabric_port_check/infraPortTrackPol_neg1.json new file mode 100644 index 00000000..683f7a52 --- /dev/null +++ b/tests/port_tracking_active_fabric_port_check/infraPortTrackPol_neg1.json @@ -0,0 +1,30 @@ +{ + "totalCount": "1", + "imdata": [ + { + "infraPortTrackPol": { + "attributes": { + "adminSt": "on", + "annotation": "", + "childAction": "", + "delay": "120", + "descr": "", + "dn": "uni/infra/trackEqptFabP-default", + "extMngdBy": "", + "includeApicPorts": "no", + "lcOwn": "local", + "minlinks": "1", + "modTs": "2025-10-31T17:13:46.220+11:00", + "name": "default", + "nameAlias": "", + "ownerKey": "", + "ownerTag": "", + "rn": "trackEqptFabP-default", + "status": "", + "uid": "0", + "userdom": "all" + } + } + } + ] +} \ No newline at end of file diff --git a/tests/port_tracking_active_fabric_port_check/infraPortTrackPol_pos.json b/tests/port_tracking_active_fabric_port_check/infraPortTrackPol_pos.json new file mode 100644 index 00000000..ed137ae5 --- /dev/null +++ b/tests/port_tracking_active_fabric_port_check/infraPortTrackPol_pos.json @@ -0,0 +1,30 @@ +{ + "totalCount": "1", + "imdata": [ + { + "infraPortTrackPol": { + "attributes": { + "adminSt": "on", + "annotation": "", + "childAction": "", + "delay": "120", + "descr": "", + "dn": "uni/infra/trackEqptFabP-default", + "extMngdBy": "", + "includeApicPorts": "no", + "lcOwn": "local", + "minlinks": "0", + "modTs": "2025-10-31T17:13:46.220+11:00", + "name": "default", + "nameAlias": "", + "ownerKey": "", + "ownerTag": "", + "rn": "trackEqptFabP-default", + "status": "", + "uid": "0", + "userdom": "all" + } + } + } + ] +} \ No newline at end of file diff --git a/tests/port_tracking_active_fabric_port_check/test_port_tracking_active_fabric_port_check.py b/tests/port_tracking_active_fabric_port_check/test_port_tracking_active_fabric_port_check.py new file mode 100644 index 00000000..47147a65 --- /dev/null +++ b/tests/port_tracking_active_fabric_port_check/test_port_tracking_active_fabric_port_check.py @@ -0,0 +1,49 @@ +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__)) +infra_port_track_pol_api = 'uni/infra/trackEqptFabP-default.json' +@pytest.mark.parametrize( + "icurl_outputs, tversion, expected_result", + [ + # tversion not given + ( + {infra_port_track_pol_api: []}, + None, + script.MANUAL, + ), + # tversion is not hit + ( + {infra_port_track_pol_api: []}, + "6.0(9e)", + script.NA, + ), + #adminSt is off. + ( + {infra_port_track_pol_api: read_data(dir, "infraPortTrackPol_neg.json")}, + "6.0(9d)", + script.PASS, + ), + #adminSt is on, but minlinks is not zero. + ( + {infra_port_track_pol_api: read_data(dir, "infraPortTrackPol_neg1.json")}, + "6.0(9d)", + script.PASS, + ), + #adminSt is on, and minlinks is zero. + ( + {infra_port_track_pol_api: read_data(dir, "infraPortTrackPol_pos.json")}, + "6.0(9d)", + script.FAIL_O, + ) + ], +) + +def test_logic(mock_icurl, tversion, expected_result): + tversion = script.AciVersion(tversion) if tversion else None + result = script.port_tracking_active_fabric_port_check(1, 1, tversion) + assert result == expected_result \ No newline at end of file