Skip to content
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

issue NewValidation: Check if ports from switches are in "Disabled" status. #132 fixed #177

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
36 changes: 35 additions & 1 deletion aci-preupgrade-validation-script.py
Original file line number Diff line number Diff line change
Expand Up @@ -4224,6 +4224,40 @@ def validate_32_64_bit_image_check(index, total_checks, tversion, **kwargs):
return result


def out_of_service_ports_check(index, total_checks, **kwargs):
title = 'Out-of-Service Ports Check'
result = NA
msg = ''
headers = [ "Pod ID", "Node ID", "Port ID", "State from Switch" ]
data = []
recommended_action = 'Review the list of Disabled Ports by GUI but enabled by CLI, to make sure these do not get disabled upon upgrade'
doc_url = 'https://datacenter.github.io/ACI-Pre-Upgrade-Validation-Script/validations/#out_of_service_ports_check'
print_title(title, index, total_checks)
oospath_regex = r'uni/fabric/outofsvc/rsoosPath-\[topology/pod-(?P<pod>[^/]+)/paths-(?P<node>\d{3,4})/pathep-\[eth(?P<int>.+)\]\]'
##Validate fabricRsOosPath.dn against ethpmPhysIf.dn and ethpmPhysIf.operSt
oospath_api = 'fabricRsOosPath.json'
oospath = icurl('class', oospath_api)
oosports = []
for oosint in oospath:
oosint_array = re.search(oospath_regex, oosint['fabricRsOosPath']['attributes']['dn'])
oosports.append([oosint_array.group("pod"), oosint_array.group("node"), oosint_array.group("int")])
if oosports:
result = PASS
ethpmphysif_api = 'ethpmPhysIf.json'
ethpmphysif = icurl('class', ethpmphysif_api)
for pod, node, interface in oosports:
port_dn = 'topology/pod-'+ pod +'/node-'+ node+'/sys/phys-[eth'+interface+']/phys'
for ethpmport in ethpmphysif:
if ethpmport['ethpmPhysIf']['attributes']['dn'] == port_dn and ethpmport['ethpmPhysIf']['attributes']['operSt'] == 'up':
data.append([pod, node, interface, ethpmport['ethpmPhysIf']['attributes']['operSt']])
else:
continue
if data:
result = FAIL_O

print_result(title, result, msg, headers, data, recommended_action=recommended_action, doc_url=doc_url)
return result

if __name__ == "__main__":
prints(' ==== %s%s, Script Version %s ====\n' % (ts, tz, SCRIPT_VERSION))
prints('!!!! Check https://github.com/datacenter/ACI-Pre-Upgrade-Validation-Script for Latest Release !!!!\n')
Expand Down Expand Up @@ -4304,6 +4338,7 @@ def validate_32_64_bit_image_check(index, total_checks, tversion, **kwargs):
eecdh_cipher_check,
subnet_scope_check,
unsupported_fec_configuration_ex_check,
out_of_service_ports_check,

# Bugs
ep_announce_check,
Expand All @@ -4323,7 +4358,6 @@ def validate_32_64_bit_image_check(index, total_checks, tversion, **kwargs):
lldp_custom_int_description_defect_check,
rtmap_comm_match_defect_check,
static_route_overlap_check

]
summary = {PASS: 0, FAIL_O: 0, FAIL_UF: 0, ERROR: 0, MANUAL: 0, POST: 0, NA: 0, 'TOTAL': len(checks)}
for idx, check in enumerate(checks):
Expand Down
12 changes: 11 additions & 1 deletion docs/docs/validations.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ Items | Faults | This Script
[EECDH SSL Cipher Disabled][c14] | :white_check_mark: | :no_entry_sign: | :no_entry_sign:
[BD and EPG Subnet must have matching scopes][c15] | :white_check_mark: | :no_entry_sign: | :no_entry_sign:
[Unsupported FEC Configuration for N9K-C93180YC-EX][c16] | :white_check_mark: | :no_entry_sign: | :no_entry_sign:

[Out-of-Service Ports check][c17] | :white_check_mark: | :no_entry_sign: | :no_entry_sign:

[c1]: #vpc-paired-leaf-switches
[c2]: #overlapping-vlan-pool
Expand All @@ -136,6 +136,7 @@ Items | Faults | This Script
[c14]: #eecdh-ssl-cipher
[c15]: #bd-and-epg-subnet-must-have-matching-scopes
[c16]: #unsupported-fec-configuration-for-n9k-c93180yc-ex
[c17]: #out_of_service_ports_check


### Defect Condition Checks
Expand Down Expand Up @@ -1930,6 +1931,15 @@ It is important to remove any unsupported configuration prior to ugprade to avoi
fcotChannelNumber : Channel32
fecMode : ieee-rs-fec <<<
```
### Out-of-Service Ports Check

Any Port that has been disabled in the in the APIC GUI gets a corresponding fabricRsOosPath object which are listed under the "Disabled Interfaces and Decommissioned Switches" view.
A user can enable the ports manually by going to the switch CLI : configure terminal -> interface eth1/X -> no shutdown
This overwrites the APIC policy, but the fabricRsOosPath objects created to disable the interfaces will remain in the configuration policy.

When an upgrade for a switch is triggered, the APICs will push the policies to the switches again. This will push the fabricRsOosPath policy to the switch again, thus disabling the ports-

To avoid this, make sure no fabricRsOosPath Ports is enabled from the switch before the upgrade.

## Defect Check Details

Expand Down
22 changes: 22 additions & 0 deletions tests/out_of_service_ports_check/ethpmPhysIf-neg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[
{
"ethpmPhysIf": {
"attributes": {
"dn": "topology/pod-1/node-103/sys/phys-[eth1/27]/phys",
"operSpeed": "10G",
"operSt": "down",
"usage": "blacklist,epg"
}
}
},
{
"ethpmPhysIf": {
"attributes": {
"dn": "topology/pod-1/node-105/sys/phys-[eth1/27]/phys",
"operSpeed": "10G",
"operSt": "down",
"usage": "blacklist,epg"
}
}
}
]
22 changes: 22 additions & 0 deletions tests/out_of_service_ports_check/ethpmPhysIf-pos.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[
{
"ethpmPhysIf": {
"attributes": {
"dn": "topology/pod-1/node-103/sys/phys-[eth1/27]/phys",
"operSpeed": "10G",
"operSt": "up",
"usage": "blacklist,epg"
}
}
},
{
"ethpmPhysIf": {
"attributes": {
"dn": "topology/pod-1/node-105/sys/phys-[eth1/27]/phys",
"operSpeed": "10G",
"operSt": "down",
"usage": "blacklist,epg"
}
}
}
]
1 change: 1 addition & 0 deletions tests/out_of_service_ports_check/fabricRsOosPath-neg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
32 changes: 32 additions & 0 deletions tests/out_of_service_ports_check/fabricRsOosPath-pos.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[
{
"fabricRsOosPath":
{
"attributes":
{
"dn": "uni/fabric/outofsvc/rsoosPath-[topology/pod-1/paths-103/pathep-[eth1/27]]",
"lc": "blacklist",
"monPolDn": "uni/fabric/monfab-default",
"rType": "mo",
"state": "unformed",
"tCl": "fabricPathEp",
"tDn": "topology/pod-1/paths-103/pathep-[eth1/27]"
}
}
},
{
"fabricRsOosPath":
{
"attributes":
{
"dn": "uni/fabric/outofsvc/rsoosPath-[topology/pod-1/paths-105/pathep-[eth1/27]]",
"lc": "blacklist",
"monPolDn": "uni/fabric/monfab-default",
"rType": "mo",
"state": "unformed",
"tCl": "fabricPathEp",
"tDn": "topology/pod-1/paths-105/pathep-[eth1/27]"
}
}
}
]
Original file line number Diff line number Diff line change
@@ -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__))


# icurl queries
oospath_api = 'fabricRsOosPath.json'
ethpmphysif_api = 'ethpmPhysIf.json'


@pytest.mark.parametrize(
"icurl_outputs, expected_result",
[
(
## NO DISABLED PORTS , ETHPMPHYSIF PORTS all ports DOWN, RESULT = N/A
{oospath_api: read_data(dir, "fabricRsOosPath-neg.json"),
ethpmphysif_api: read_data(dir, "ethpmPhysIf-neg.json")},
script.NA,
),
(
## NO DISABLED PORTS , ETHPMPHYSIF PORTS with one UP, one DOWN, RESULT = N/A
{oospath_api: read_data(dir, "fabricRsOosPath-neg.json"),
ethpmphysif_api: read_data(dir, "ethpmPhysIf-pos.json")},
script.NA,
),
(
## TWO DISABLED PORTS , ETHPMPHYSIF PORTS with one UP, one DOWN, RESULT = UPGRADE FAILS
{oospath_api: read_data(dir, "fabricRsOosPath-pos.json"),
ethpmphysif_api: read_data(dir, "ethpmPhysIf-pos.json")},
script.FAIL_O,
),
(
## TWO DISABLED PORTS , ETHPMPHYSIF PORTS all ports DOWN, RESULT = PASS
{oospath_api: read_data(dir, "fabricRsOosPath-pos.json"),
ethpmphysif_api: read_data(dir, "ethpmPhysIf-neg.json")},
script.PASS,
)
],
)
def test_logic(mock_icurl, expected_result):
result = script.out_of_service_ports_check(1, 1)
assert result == expected_result