Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions aci-preupgrade-validation-script.py
Original file line number Diff line number Diff line change
Expand Up @@ -6053,6 +6053,64 @@ def auto_firmware_update_on_switch_check(cversion, tversion, **kwargs):

return Result(result=result, headers=headers, data=data, recommended_action=recommended_action, doc_url=doc_url)


@check_wrapper(check_title="Multi-Pod modular spine bootscript check")
def multipod_modular_spine_bootscript_check(tversion, fabric_nodes, username, password, **kwargs):
result = PASS
headers = ["Pod ID", "Node ID", "Node Name", "Model", "Bootscript Present"]
data = []
recommended_action = "clean reboot on impacted spine"
doc_url = "https://datacenter.github.io/ACI-Pre-Upgrade-Validation-Script/validations/#multipod-modular-spine-bootscript-check"

pod_count_resp = icurl('class', 'fabricSetupP.json?query-target=self&rsp-subtree-include=count')
if (int(pod_count_resp[0]['moCount']['attributes']['count'])) < 2:
return Result(result=NA, msg="Not MultiPod Fabric.")

if not (tversion.same_as("6.1(4h)")):
return Result(result=NA, msg="Target version is not affected")

modular_spine_models = {"N9K-C9408", "N9K-C9504", "N9K-C9508", "N9K-C9516"}
found_modular_spine = any(node["fabricNode"]["attributes"].get("model") in modular_spine_models for node in fabric_nodes)
if not found_modular_spine:
return Result(result=NA, msg="No modular spine found in fabric.")

has_error = False
for node in fabric_nodes:
attr = node["fabricNode"]["attributes"]
if attr.get("role") != "spine":
continue

node_id = attr.get("id")
node_name = attr.get("name")
dn = re.search(node_regex, attr.get("dn", ""))
pod_id = dn.group("pod") if dn else "Unknown"
mgmt_ip = attr.get("address")
model = attr.get("model")

c = Connection(mgmt_ip)
c.username = username
c.password = password
c.log = LOG_FILE
try:
c.connect()
c.cmd("ls -l bootflash/ | grep boots")
bootscript_present = "Yes" if "bootscript" in c.output else "No"
except Exception as e:
ssh_error = f"SSH ERROR: {e}"
data.append([pod_id, node_id, node_name, model, ssh_error])
has_error = True
continue
data.append([pod_id, node_id, node_name, model, bootscript_present])

if has_error:
result = ERROR
elif data:
bootscript_missing = any(row[4] == "No" for row in data)
if bootscript_missing:
result = FAIL_O

return Result(result=result, headers=headers, data=data, recommended_action=recommended_action, doc_url=doc_url)

# ---- Script Execution ----


Expand Down Expand Up @@ -6216,6 +6274,7 @@ class CheckManager:
isis_database_byte_check,
configpush_shard_check,
auto_firmware_update_on_switch_check,
multipod_modular_spine_bootscript_check,

]
ssh_checks = [
Expand Down
11 changes: 10 additions & 1 deletion docs/docs/validations.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ Items | Defect | This Script
[ISIS DTEPs Byte Size][d27] | CSCwp15375 | :white_check_mark: | :no_entry_sign:
[Policydist configpushShardCont Crash][d28] | CSCwp95515 | :white_check_mark: | :no_entry_sign:
[Auto Firmware Update on Switch Discovery][d29] | CSCwe83941 | :white_check_mark: | :no_entry_sign:
[Multi-Pod modular spine bootscript check][d30] | CSCwr66848 | :white_check_mark: | :no_entry_sign:

[d1]: #ep-announce-compatibility
[d2]: #eventmgr-db-size-defect-susceptibility
Expand Down Expand Up @@ -224,6 +225,7 @@ Items | Defect | This Script
[d27]: #isis-dteps-byte-size
[d28]: #policydist-configpushshardcont-crash
[d29]: #auto-firmware-update-on-switch-discovery
[d30]: #multipod-modular-spine-bootscript-check

## General Check Details

Expand Down Expand Up @@ -2667,6 +2669,12 @@ To avoid this risk, consider disabling Auto Firmware Update before upgrading to
!!! note
This issue occurs because older switch firmware versions are not compatible with switch images 6.0(3) or newer. The APIC version is not a factor.

### Multi-Pod Modular Spine Bootscript

Due to [CSCwr66848][64], in a Multi-Pod fabric, modular spine switches have `bootscript` file present in their bootflash from the initial bootstrap process. When upgrading to 6.1(4h), if `bootscript` file is missing that can cause traffic loss across pods until the spine in this condition is clean reloaded.

To avoid this issue, verify that `bootscript` file exists in the bootflash of each spine switch prior to upgrading to 6.1(4h). If not found, we have to do clean reboot on impacted spine.


[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
Expand Down Expand Up @@ -2731,4 +2739,5 @@ To avoid this risk, consider disabling Auto Firmware Update before upgrading to
[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/CSCwe83941
[63]: https://www.cisco.com/c/en/us/td/docs/dcn/aci/apic/all/apic-installation-aci-upgrade-downgrade/Cisco-APIC-Installation-ACI-Upgrade-Downgrade-Guide/m-auto-firmware-update.html
[63]: https://www.cisco.com/c/en/us/td/docs/dcn/aci/apic/all/apic-installation-aci-upgrade-downgrade/Cisco-APIC-Installation-ACI-Upgrade-Downgrade-Guide/m-auto-firmware-update.html
[64]: https://bst.cloudapps.cisco.com/bugsearch/bug/CSCwr66848
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[
{
"fabricNode": {
"attributes": {
"address": "10.0.0.1",
"dn": "topology/pod-1/node-1",
"fabricSt": "commissioned",
"id": "1",
"model": "APIC-SERVER-L2",
"monPolDn": "uni/fabric/monfab-default",
"name": "apic1",
"nodeType": "unspecified",
"role": "controller"
}
}
},
{
"fabricNode": {
"attributes": {
"address": "10.0.0.101",
"dn": "topology/pod-1/node-101",
"fabricSt": "active",
"id": "101",
"model": "N9K-C93180YC-FX",
"monPolDn": "uni/fabric/monfab-default",
"name": "leaf101",
"nodeType": "unspecified",
"role": "leaf"
}
}
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
[
{
"fabricNode": {
"attributes": {
"address": "10.0.0.1",
"dn": "topology/pod-1/node-1",
"fabricSt": "commissioned",
"id": "1",
"model": "APIC-SERVER-L2",
"monPolDn": "uni/fabric/monfab-default",
"name": "apic1",
"nodeType": "unspecified",
"role": "controller"
}
}
},
{
"fabricNode": {
"attributes": {
"address": "10.0.0.201",
"dn": "topology/pod-1/node-201",
"fabricSt": "active",
"id": "201",
"model": "N9K-C9316D-GX2",
"monPolDn": "uni/fabric/monfab-default",
"name": "spine201",
"nodeType": "unspecified",
"role": "spine"
}
}
},
{
"fabricNode": {
"attributes": {
"address": "10.0.0.202",
"dn": "topology/pod-2/node-202",
"fabricSt": "active",
"id": "202",
"model": "N9K-C9316D-GX",
"monPolDn": "uni/fabric/monfab-default",
"name": "spine202",
"nodeType": "unspecified",
"role": "spine"
}
}
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
[
{
"fabricNode": {
"attributes": {
"address": "10.0.0.1",
"dn": "topology/pod-1/node-1",
"fabricSt": "commissioned",
"id": "1",
"model": "APIC-SERVER-L2",
"monPolDn": "uni/fabric/monfab-default",
"name": "apic1",
"nodeType": "unspecified",
"role": "controller"
}
}
},
{
"fabricNode": {
"attributes": {
"address": "10.0.0.201",
"dn": "topology/pod-1/node-201",
"fabricSt": "active",
"id": "201",
"model": "N9K-C9504",
"monPolDn": "uni/fabric/monfab-default",
"name": "spine201",
"nodeType": "unspecified",
"role": "spine"
}
}
},
{
"fabricNode": {
"attributes": {
"address": "10.0.0.202",
"dn": "topology/pod-2/node-202",
"fabricSt": "active",
"id": "202",
"model": "N9K-C9508",
"monPolDn": "uni/fabric/monfab-default",
"name": "spine202",
"nodeType": "unspecified",
"role": "spine"
}
}
}
]
Loading