Skip to content

Commit

Permalink
89 newvalidation mini aci upgrade to 602+ (#93)
Browse files Browse the repository at this point in the history
* Added check for mini aci ugprade to 6.0.2

* Modified mini aci check data on failure

* Modified test case to use parameterized pytest format

* Added documentation to valiations.md
  • Loading branch information
wilsonbc2 authored Apr 24, 2024
1 parent 00462bb commit dd9ee1e
Show file tree
Hide file tree
Showing 5 changed files with 483 additions and 0 deletions.
33 changes: 33 additions & 0 deletions aci-preupgrade-validation-script.py
Original file line number Diff line number Diff line change
Expand Up @@ -2741,6 +2741,38 @@ def oob_mgmt_security_check(index, total_checks, cversion, tversion, **kwargs):
print_result(title, result, msg, headers, data, recommended_action=recommended_action, doc_url=doc_url)
return result

def mini_aci_6_0_2_check(index, total_checks, cversion, tversion, **kwargs):
title = 'Mini ACI Upgrade to 6.0(2)+'
result = FAIL_UF
msg = ''
headers = ["Pod ID","Node ID", "APIC Type", "Failure Reason"]
data = []
recommended_action = "All virtual APICs must be removed from the cluster prior to upgrading to 6.0(2)+."
doc_url = 'Upgrading Mini ACI - http://cs.co/9009bBTQB'

print_title(title, index, total_checks)

if not tversion:
print_result(title, MANUAL, 'Target version not supplied. Skipping.')
return MANUAL

if cversion.older_than("6.0(2a)") and tversion.newer_than("6.0(2a)"):
topSystem = icurl('class', 'topSystem.json?query-target-filter=wcard(topSystem.role,"controller")')
if not topSystem:
print_result(title, ERROR, 'topSystem response empty. Is the cluster healthy?')
return ERROR
for controller in topSystem:
if controller['topSystem']['attributes']['nodeType'] == "virtual":
pod_id = controller["topSystem"]["attributes"]["podId"]
node_id = controller['topSystem']['attributes']['id']
data.append([pod_id, node_id, "virtual", "Virtual APIC must be removed prior to upgrade to 6.0(2)+"])

if not data:
result = PASS
print_result(title, result, msg, headers, data, recommended_action=recommended_action, doc_url=doc_url)
return result



def sup_a_high_memory_check(index, total_checks, tversion, **kwargs):
title = "SUP-A/A+ High Memory Usage"
Expand Down Expand Up @@ -2846,6 +2878,7 @@ def access_untagged_check(index, total_checks, **kwargs):
maintp_grp_crossing_4_0_check,
features_to_disable_check,
switch_group_guideline_check,
mini_aci_6_0_2_check,

# Faults
apic_disk_space_faults_check,
Expand Down
27 changes: 27 additions & 0 deletions docs/docs/validations.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Items | This Script
[Features that need to be disabled prior to Upgrade][g11] | :white_check_mark: | :grey_exclamation: 5.2(c)<br>Only AppCenter Apps | :white_check_mark:
[Switch Upgrade Group Guidelines][g12] | :white_check_mark: | :grey_exclamation: 4.2(4)<br>Only RR spines (IPN connectivity not checked) | :white_check_mark:
[Intersight Device Connector upgrade status][g13] | :white_check_mark: | :white_check_mark: 4.2(5) | :white_check_mark:
[Mini ACI Upgrade to 6.0(2)+][g14] | :white_check_mark: | :no_entry_sign: | :no_entry_sign:

[g1]: #compatibility-target-aci-version
[g2]: #compatibility-cimc-version
Expand All @@ -45,6 +46,7 @@ Items | This Script
[g11]: #features-that-need-to-be-disabled-prior-to-upgrade
[g12]: #switch-upgrade-group-guidelines
[g13]: #intersight-device-connector-upgrade-status
[g14]: #mini-aci-upgrade-to-602-or-later


### Fault Checks
Expand Down Expand Up @@ -306,6 +308,30 @@ If you start an Cisco APIC upgrade while an intersight Device Connector (DC) upg

You can check the status of intersight DC from `System > System Settings > intersight`. If the upgrade of the DC is in progress, wait for a minute and retry the Cisco APIC upgrade. The upgrade of the Intersight Device Connector typically takes less than a minute.

### Mini ACI Upgrade to 6.0(2) or later

Starting with APIC Release 6.0(2), controllers use a new linux operating system which requires any virtual APIC to be redeployed on the target version.

When upgrading from ACI release 6.0(1) or earlier to release 6.0(2) or later, any virtual APICs must be removed from the APIC cluster prior to upgrade. You must follow the documented steps under the [Mini ACI Upgrade Guide][18] for this specific upgrade path. A regular policy upgrade will fail and result in a diverged cluster.

!!! tip
You can check whether any APICs are virtual by querying `topSystem` and looking at the `nodeType` attribute. `unspecified` is used for any physical APIC appliance while `virtual` is used for any virtual APIC.
```
# top.System
address : 10.1.0.2
--- omit ---
dn : topology/pod-1/node-2/sys
lastRebootTime : 2024-04-21T11:35:24.844-04:00
lastResetReason : unknown
lcOwn : local
modTs : 2024-04-21T11:56:04.032-04:00
mode : unspecified
monPolDn : uni/fabric/monfab-default
name : vapic2
nameAlias :
nodeType : virtual
--- omit ---
```

## Fault Check Details

Expand Down Expand Up @@ -1387,3 +1413,4 @@ It is highly recommended not to upgrade your ACI fabric to 6.0(3), 6.0(4) or 6.0
[15]: https://www.cisco.com/c/en/us/td/docs/dcn/aci/apic/6x/release-notes/cisco-apic-release-notes-603.html
[16]: https://www.cisco.com/c/en/us/td/docs/dcn/aci/apic/6x/release-notes/cisco-apic-release-notes-604.html
[17]: https://www.cisco.com/c/en/us/td/docs/dcn/aci/apic/6x/release-notes/cisco-apic-release-notes-605.html
[18]: https://www.cisco.com/c/en/us/td/docs/switches/datacenter/aci/apic/sw/kb/cisco-mini-aci-fabric.html#Cisco_Task_in_List_GUI.dita_2d9ca023-714c-4341-9112-d96a7a598ee6
71 changes: 71 additions & 0 deletions tests/mini_aci_6_0_2/test_mini_aci_6_0_2_check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
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__))


# icurl queries
topSystems = 'topSystem.json?query-target-filter=wcard(topSystem.role,"controller")'


@pytest.mark.parametrize(
"icurl_outputs, cversion, tversion, expected_result",
[
(
{topSystems: read_data(dir, "topSystem_controller_neg.json")},
"3.2(1a)",
"5.2(6a)",
script.PASS,
),
(
{topSystems: read_data(dir, "topSystem_controller_neg.json")},
"6.0(2e)",
"6.0(5d)",
script.PASS,
),
(
{topSystems: read_data(dir, "topSystem_controller_neg.json")},
"5.2(3a)",
"6.0(3d)",
script.PASS,
),
(
{topSystems: read_data(dir, "topSystem_controller_pos.json")},
"4.1(1a)",
"5.2(7f)",
script.PASS,
),
(
{topSystems: read_data(dir, "topSystem_controller_pos.json")},
"4.2(2a)",
"6.0(2c)",
script.FAIL_UF,
),
(
{topSystems: read_data(dir, "topSystem_controller_pos.json")},
"6.0(1a)",
"6.0(2c)",
script.FAIL_UF,
),
(
{topSystems: read_data(dir, "topSystem_controller_pos.json")},
"6.0(2c)",
"6.0(5c)",
script.PASS,
),
],
)
def test_logic(mock_icurl, cversion, tversion, expected_result):
result = script.mini_aci_6_0_2_check(
1,
1,
script.AciVersion(cversion),
script.AciVersion(tversion) if tversion else None,
)
assert result == expected_result
176 changes: 176 additions & 0 deletions tests/mini_aci_6_0_2/topSystem_controller_neg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
[
{
"topSystem": {
"attributes": {
"address": "10.0.0.1",
"bootstrapState": "none",
"childAction": "",
"clusterTimeDiff": "8185177",
"configIssues": "",
"controlPlaneMTU": "1500",
"currentTime": "2024-04-11T12:41:19.198-04:00",
"dn": "topology/pod-1/node-1/sys",
"enforceSubnetCheck": "no",
"etepAddr": "0.0.0.0",
"fabricDomain": "fab5",
"fabricId": "1",
"fabricMAC": "00:22:BD:F8:19:FF",
"id": "1",
"inbMgmtAddr": "40.5.5.1",
"inbMgmtAddr6": "fc00::1",
"inbMgmtAddr6Mask": "0",
"inbMgmtAddrMask": "24",
"inbMgmtGateway": "40.5.5.254",
"inbMgmtGateway6": "::",
"lastRebootTime": "2024-01-03T20:49:19.892-04:00",
"lastResetReason": "unknown",
"lcOwn": "local",
"modTs": "2024-02-01T15:14:43.241-04:00",
"mode": "unspecified",
"monPolDn": "uni/fabric/monfab-default",
"name": "fab5-apic1",
"nameAlias": "",
"nodeType": "unspecified",
"oobMgmtAddr": "192.168.4.84",
"oobMgmtAddr6": "fe80::2aac:9eff:fe41:fb0e",
"oobMgmtAddr6Mask": "0",
"oobMgmtAddrMask": "24",
"oobMgmtGateway": "192.168.4.1",
"oobMgmtGateway6": "::",
"podId": "1",
"remoteNetworkId": "0",
"remoteNode": "no",
"rlOperPodId": "0",
"rlRoutableMode": "no",
"rldirectMode": "no",
"role": "controller",
"serial": "FCH2209V0FW",
"serverType": "unspecified",
"siteId": "0",
"state": "in-service",
"status": "",
"systemUpTime": "98:18:08:25.000",
"tepPool": "0.0.0.0",
"unicastXrEpLearnDisable": "no",
"version": "6.0(4c)",
"virtualMode": "no"
}
}
},
{
"topSystem": {
"attributes": {
"address": "10.0.0.2",
"bootstrapState": "none",
"childAction": "",
"clusterTimeDiff": "8397050",
"configIssues": "",
"controlPlaneMTU": "1500",
"currentTime": "2024-04-11T12:41:19.203-04:00",
"dn": "topology/pod-1/node-2/sys",
"enforceSubnetCheck": "no",
"etepAddr": "0.0.0.0",
"fabricDomain": "fab5",
"fabricId": "1",
"fabricMAC": "00:22:BD:F8:19:FF",
"id": "2",
"inbMgmtAddr": "0.0.0.0",
"inbMgmtAddr6": "fc00::1",
"inbMgmtAddr6Mask": "0",
"inbMgmtAddrMask": "0",
"inbMgmtGateway": "0.0.0.0",
"inbMgmtGateway6": "::",
"lastRebootTime": "2024-02-13T12:59:46.015-04:00",
"lastResetReason": "unknown",
"lcOwn": "local",
"modTs": "2024-02-13T15:26:21.281-04:00",
"mode": "unspecified",
"monPolDn": "uni/fabric/monfab-default",
"name": "fab5-apic2",
"nameAlias": "",
"nodeType": "unspecified",
"oobMgmtAddr": "192.168.4.32",
"oobMgmtAddr6": "fe80::e6aa:5dff:fe13:b5bc",
"oobMgmtAddr6Mask": "0",
"oobMgmtAddrMask": "24",
"oobMgmtGateway": "192.168.4.1",
"oobMgmtGateway6": "::",
"podId": "1",
"remoteNetworkId": "0",
"remoteNode": "no",
"rlOperPodId": "0",
"rlRoutableMode": "no",
"rldirectMode": "no",
"role": "controller",
"serial": "FCH1937V0ZD",
"serverType": "unspecified",
"siteId": "0",
"state": "in-service",
"status": "",
"systemUpTime": "57:23:38:01.000",
"tepPool": "0.0.0.0",
"unicastXrEpLearnDisable": "no",
"version": "6.0(4c)",
"virtualMode": "no"
}
}
},
{
"topSystem": {
"attributes": {
"address": "10.0.0.3",
"bootstrapState": "none",
"childAction": "",
"clusterTimeDiff": "8270412",
"configIssues": "",
"controlPlaneMTU": "1500",
"currentTime": "2024-04-11T12:41:19.204-04:00",
"dn": "topology/pod-1/node-3/sys",
"enforceSubnetCheck": "no",
"etepAddr": "0.0.0.0",
"fabricDomain": "fab5",
"fabricId": "1",
"fabricMAC": "00:22:BD:F8:19:FF",
"id": "3",
"inbMgmtAddr": "0.0.0.0",
"inbMgmtAddr6": "fc00::1",
"inbMgmtAddr6Mask": "0",
"inbMgmtAddrMask": "0",
"inbMgmtGateway": "0.0.0.0",
"inbMgmtGateway6": "::",
"lastRebootTime": "2024-02-13T13:01:50.077-04:00",
"lastResetReason": "unknown",
"lcOwn": "local",
"modTs": "2024-02-13T15:27:15.193-04:00",
"mode": "unspecified",
"monPolDn": "uni/fabric/monfab-default",
"name": "fab5-apic3",
"nameAlias": "",
"nodeType": "unspecified",
"oobMgmtAddr": "192.168.4.34",
"oobMgmtAddr6": "fe80::e6aa:5dff:fe13:efea",
"oobMgmtAddr6Mask": "0",
"oobMgmtAddrMask": "24",
"oobMgmtGateway": "192.168.4.1",
"oobMgmtGateway6": "::",
"podId": "1",
"remoteNetworkId": "0",
"remoteNode": "no",
"rlOperPodId": "0",
"rlRoutableMode": "no",
"rldirectMode": "no",
"role": "controller",
"serial": "FCH1937V0Z9",
"serverType": "unspecified",
"siteId": "0",
"state": "in-service",
"status": "",
"systemUpTime": "57:23:38:04.000",
"tepPool": "0.0.0.0",
"unicastXrEpLearnDisable": "no",
"version": "6.0(4c)",
"virtualMode": "no"
}
}
}
]
Loading

0 comments on commit dd9ee1e

Please sign in to comment.