-
Notifications
You must be signed in to change notification settings - Fork 48
Issue299 #342
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Issue299 #342
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6025,6 +6025,61 @@ def apic_downgrade_compat_warning_check(cversion, tversion, **kwargs): | |
|
|
||
| return Result(result=result, headers=headers, data=data, recommended_action=recommended_action, doc_url=doc_url) | ||
|
|
||
| # Connection Base Check | ||
| @check_wrapper(check_title='GX HW_Changes_Bit') | ||
| def gx_hw_changes_bit_check(username, password, fabric_nodes, cversion, tversion, **kwargs): | ||
| result = PASS | ||
| headers = ["Switch ID", "Switch Name", "HW Changes Bits value"] | ||
| data = [] | ||
| recommended_action = 'Review The Bug RNE and apply the workaround before Upgrade' | ||
| doc_url = 'https://datacenter.github.io/ACI-Pre-Upgrade-Validation-Script/validations#gx_hw_changes_bit' | ||
|
|
||
| if not tversion: | ||
| return Result(result=MANUAL, msg=TVER_MISSING) | ||
| if ( | ||
| cversion.older_than("4.2(3a)") or cversion.newer_than("4.2(5a)") | ||
| ) and tversion.newer_than("4.2(5l)"): | ||
| result = NA | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Blocking: Setting |
||
| has_error = False | ||
| # -GX Switches can be Leaf or Spine | ||
| switches = [node for node in fabric_nodes if ( | ||
| node["fabricNode"]["attributes"]["model"] == "N9K-C9316D-GX" or | ||
| node["fabricNode"]["attributes"]["model"] == "N9K-C93600CD-GX" | ||
| )] | ||
| if not switches: | ||
| return Result(result=NA, msg="No affected Switches found", doc_url=doc_url) | ||
|
|
||
| for switch in switches: | ||
| switch_id = switch["fabricNode"]["attributes"]["id"] | ||
| switch_name = switch["fabricNode"]["attributes"]["name"] | ||
| switch_addr = switch["fabricNode"]["attributes"]["address"] | ||
|
|
||
| try: | ||
| c = Connection(switch_addr) | ||
| c.username = username | ||
| c.password = password | ||
| c.log = LOG_FILE | ||
| c.connect() | ||
| except Exception as e: | ||
| data.append([switch_id, switch_name, str(e)]) | ||
| has_error = True | ||
| continue | ||
| try: | ||
| cmd = r"vsh -c 'show sprom cpu-info' | grep 'HW Changes Bits'" | ||
| c.cmd(cmd) | ||
| if "HW Changes Bits : 0x3" in c.output: | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Blocking: This exact substring check treats every other output as safe, including empty/malformed output and a command timeout (Connection.cmd() can return |
||
| data.append([switch_id, switch_name, '0x3 Found!']) | ||
| #has_error = True | ||
| continue | ||
| except Exception as e: | ||
| data.append([switch_id, switch_name, str(e)]) | ||
| has_error = True | ||
| continue | ||
| if has_error: | ||
| result = ERROR | ||
| elif data: | ||
| result = FAIL_UF | ||
| return Result(result=result, headers=headers, data=data, recommended_action=recommended_action, doc_url=doc_url) | ||
|
|
||
| # ---- Script Execution ---- | ||
|
|
||
|
|
@@ -6188,6 +6243,7 @@ class CheckManager: | |
| standby_sup_sync_check, | ||
| isis_database_byte_check, | ||
| configpush_shard_check, | ||
| gx_hw_changes_bit_check, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. High: This check opens SSH connections but is registered in |
||
|
|
||
| ] | ||
| ssh_checks = [ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -193,6 +193,7 @@ Items | Defect | This Script | |
| [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: | | ||
| [GX Hw Changes Bit][d29] | CSCvv04251 | :white_check_mark: | :no_entry_sign: | ||
|
|
||
| [d1]: #ep-announce-compatibility | ||
| [d2]: #eventmgr-db-size-defect-susceptibility | ||
|
|
@@ -222,6 +223,7 @@ Items | Defect | This Script | |
| [d26]: #stale-pconsra-object | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Medium: This fragment does not match the generated Markdown anchor for |
||
| [d27]: #isis-dteps-byte-size | ||
| [d28]: #policydist-configpushshardcont-crash | ||
| [d29]: #gx_hw_changes_bit | ||
|
|
||
|
|
||
| ## General Check Details | ||
|
|
@@ -2647,6 +2649,11 @@ 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. | ||
|
|
||
| ### GX HW Changes Bit | ||
|
|
||
| Due to [CSCvv04251][62] a policy Upgrade on N9K-C9316D-GX and N9K-C93600CD-GX ACI Switches can fail if the Sprom CPU-Info has a '0x3' Value. | ||
| A Workaround needs to be performed on any of the affected switches before proceeding with the a policy upgrade. | ||
|
|
||
|
|
||
| [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 | ||
|
|
@@ -2710,3 +2717,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/CSCvv04251 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| [ | ||
| { | ||
| "fabricNode": { | ||
| "attributes": { | ||
| "adSt": "on", | ||
| "address": "10.1.72.70", | ||
| "annotation": "", | ||
| "apicType": "apic", | ||
| "childAction": "", | ||
| "delayedHeartbeat": "no", | ||
| "dn": "topology/pod-1/node-101", | ||
| "extMngdBy": "", | ||
| "fabricSt": "active", | ||
| "id": "101", | ||
| "lastStateModTs": "2026-01-21T14:24:21.952-05:00", | ||
| "lcOwn": "local", | ||
| "modTs": "2026-01-21T14:24:22.964-05:00", | ||
| "model": "N9K-C93180YC-EX", | ||
| "monPolDn": "uni/fabric/monfab-default", | ||
| "name": "leaf1", | ||
| "nameAlias": "", | ||
| "nodeType": "unspecified", | ||
| "role": "leaf", | ||
| "serial": "FDO221802B0", | ||
| "status": "", | ||
| "uid": "0", | ||
| "userdom": "all", | ||
| "vendor": "Cisco Systems, Inc", | ||
| "version": "n9000-16.0(9d)" | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| "fabricNode": { | ||
| "attributes": { | ||
| "adSt": "on", | ||
| "address": "10.1.72.71", | ||
| "annotation": "", | ||
| "apicType": "apic", | ||
| "childAction": "", | ||
| "delayedHeartbeat": "no", | ||
| "dn": "topology/pod-1/node-103", | ||
| "extMngdBy": "", | ||
| "fabricSt": "active", | ||
| "id": "103", | ||
| "lastStateModTs": "2026-01-20T19:37:36.258-05:00", | ||
| "lcOwn": "local", | ||
| "modTs": "2026-01-20T19:38:54.044-05:00", | ||
| "model": "N9K-C93180YC-EX", | ||
| "monPolDn": "uni/fabric/monfab-default", | ||
| "name": "leaf3", | ||
| "nameAlias": "", | ||
| "nodeType": "unspecified", | ||
| "role": "leaf", | ||
| "serial": "FDO22180284", | ||
| "status": "", | ||
| "uid": "0", | ||
| "userdom": "all", | ||
| "vendor": "Cisco Systems, Inc", | ||
| "version": "n9000-16.0(9d)" | ||
| } | ||
| } | ||
| } | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| [ | ||
| { | ||
| "fabricNode": { | ||
| "attributes": { | ||
| "adSt": "on", | ||
| "address": "10.1.72.70", | ||
| "annotation": "", | ||
| "apicType": "apic", | ||
| "childAction": "", | ||
| "delayedHeartbeat": "no", | ||
| "dn": "topology/pod-1/node-101", | ||
| "extMngdBy": "", | ||
| "fabricSt": "active", | ||
| "id": "101", | ||
| "lastStateModTs": "2026-01-21T14:24:21.952-05:00", | ||
| "lcOwn": "local", | ||
| "modTs": "2026-01-21T14:24:22.964-05:00", | ||
| "model": "N9K-C9316D-GX", | ||
| "monPolDn": "uni/fabric/monfab-default", | ||
| "name": "leaf1", | ||
| "nameAlias": "", | ||
| "nodeType": "unspecified", | ||
| "role": "leaf", | ||
| "serial": "FDO221802B0", | ||
| "status": "", | ||
| "uid": "0", | ||
| "userdom": "all", | ||
| "vendor": "Cisco Systems, Inc", | ||
| "version": "n9000-16.0(9d)" | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| "fabricNode": { | ||
| "attributes": { | ||
| "adSt": "on", | ||
| "address": "10.1.72.71", | ||
| "annotation": "", | ||
| "apicType": "apic", | ||
| "childAction": "", | ||
| "delayedHeartbeat": "no", | ||
| "dn": "topology/pod-1/node-103", | ||
| "extMngdBy": "", | ||
| "fabricSt": "active", | ||
| "id": "103", | ||
| "lastStateModTs": "2026-01-20T19:37:36.258-05:00", | ||
| "lcOwn": "local", | ||
| "modTs": "2026-01-20T19:38:54.044-05:00", | ||
| "model": "N9K-C93600CD-GX", | ||
| "monPolDn": "uni/fabric/monfab-default", | ||
| "name": "leaf3", | ||
| "nameAlias": "", | ||
| "nodeType": "unspecified", | ||
| "role": "leaf", | ||
| "serial": "FDO22180284", | ||
| "status": "", | ||
| "uid": "0", | ||
| "userdom": "all", | ||
| "vendor": "Cisco Systems, Inc", | ||
| "version": "n9000-16.0(9d)" | ||
| } | ||
| } | ||
| } | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,155 @@ | ||
| 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 = "gx_hw_changes_bit_check" | ||
|
|
||
| fabricNodes = read_data(dir, "fabricNode-Pos.json") | ||
| switch_ips = [ | ||
| mo["fabricNode"]["attributes"]["address"] | ||
| for mo in fabricNodes | ||
| if "-GX" in mo["fabricNode"]["attributes"]["model"] | ||
| ] | ||
|
|
||
| sprom_cmd = "vsh -c 'show sprom cpu-info' | grep 'HW Changes Bits'" | ||
| sprom_output_neg = " HW Changes Bits : 0x0" | ||
| sprom_output_pos = " HW Changes Bits : 0x3" | ||
|
|
||
| sprom_output_no_such_file = "" | ||
|
|
||
|
|
||
| @pytest.mark.parametrize( | ||
| "icurl_outputs, fabric_nodes, cversion, tversion, conn_failure, conn_cmds, expected_result, expected_data", | ||
| [ | ||
| # NA, no fabricNode with affected models | ||
| ( | ||
| {}, | ||
| read_data(dir, "fabricNode-Neg.json"), | ||
| "4.2(3b)", | ||
| "4.2(4p)", | ||
| False, | ||
| [], | ||
| script.NA, | ||
| [], | ||
| ), | ||
| # NA, Versions not affected | ||
| ( | ||
| {}, | ||
| read_data(dir, "fabricNode-Neg.json"), | ||
| "4.2(5l)", | ||
| "6.0(1h)", | ||
| False, | ||
| [], | ||
| script.NA, | ||
| [], | ||
| ), | ||
| # NA, Versions not affected | ||
| ( | ||
| {}, | ||
| read_data(dir, "fabricNode-Neg.json"), | ||
| "4.2(1f)", | ||
| "5.2(7f)", | ||
| False, | ||
| [], | ||
| script.NA, | ||
| [], | ||
| ), | ||
| # Connection failure | ||
| ( | ||
| {}, | ||
| fabricNodes, | ||
| "4.2(3b)", | ||
| "4.2(4b)", | ||
| True, | ||
| [], | ||
| script.ERROR, | ||
| [ | ||
| ["101", "leaf1", "Simulated exception at connect()"], | ||
| ["103", "leaf3", "Simulated exception at connect()"], | ||
| ], | ||
| ), | ||
| # Simulated exception at `show sprom cpu-info` command | ||
| ( | ||
| {}, | ||
| fabricNodes, | ||
| "4.2(3b)", | ||
| "4.2(4p)", | ||
| False, | ||
| { | ||
| switch_ip: [ | ||
| { | ||
| "cmd": sprom_cmd, | ||
| "output": "", | ||
| "exception": Exception("Simulated exception at `vsh` command"), | ||
| } | ||
| ] | ||
| for switch_ip in switch_ips | ||
| }, | ||
| script.ERROR, | ||
| [ | ||
| ["101", "leaf1", "Simulated exception at `vsh` command"], | ||
| ["103", "leaf3", "Simulated exception at `vsh` command"], | ||
| ], | ||
| ), | ||
| # PASS Affected Models, cpu-info is correct (0x0) | ||
| ( | ||
| {}, | ||
| fabricNodes, | ||
| "4.2(3b)", | ||
| "4.2(4c)", | ||
| False, | ||
| { | ||
| switch_ip: [ | ||
| { | ||
| "cmd": sprom_cmd, | ||
| "output": "\n".join([sprom_cmd, sprom_output_neg]), | ||
| "exception": None, | ||
| } | ||
| ] | ||
| for switch_ip in switch_ips | ||
| }, | ||
| script.PASS, | ||
| [], | ||
| ), | ||
| # FAIL_UF Affected Models, cpu-info is incorrect (0x3) | ||
| ( | ||
| {}, | ||
| fabricNodes, | ||
| "4.2(3b)", | ||
| "4.2(4p)", | ||
| False, | ||
| { | ||
| switch_ip: [ | ||
| { | ||
| "cmd": sprom_cmd, | ||
| "output": "\n".join([sprom_cmd, sprom_output_pos]), | ||
| "exception": None, | ||
| } | ||
| ] | ||
| for switch_ip in switch_ips | ||
| }, | ||
| script.FAIL_UF, | ||
| [ | ||
| ["101", "leaf1", "0x3 Found!"], | ||
| ["103", "leaf3", "0x3 Found!"], | ||
| ], | ||
| ), | ||
| ], | ||
| ) | ||
| def test_logic(run_check, mock_icurl, fabric_nodes, cversion, tversion, mock_conn, expected_result, expected_data): | ||
| result = run_check( | ||
| username="fake_username", | ||
| password="fake_password", | ||
| fabric_nodes=fabric_nodes, | ||
| cversion=script.AciVersion(cversion), | ||
| tversion=script.AciVersion(tversion) if tversion else None, | ||
| ) | ||
| assert result.result == expected_result | ||
| assert result.data == expected_data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Medium:
Review The Bug RNEis internal terminology and does not give users an actionable, customer-safe remediation. Please point users to the authoritative CSCvv04251 guidance or instruct them to contact Cisco TAC before proceeding, rather than referring to an RNE they may not be able to access.