-
Notifications
You must be signed in to change notification settings - Fork 48
New validation for missing vnsRsCIfAttN #394
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: v4.2.0-dev
Are you sure you want to change the base?
Changes from all commits
46f4dfe
b9570ad
a9a1a69
c3e9dcc
99ccead
7112c53
4e493ad
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 |
|---|---|---|
|
|
@@ -6410,6 +6410,107 @@ def svccore_excessive_data_check(**kwargs): | |
| return Result(result=ERROR, msg="Error occurred while fetching svccore object counts: {}".format(str(e)), doc_url=doc_url) | ||
|
|
||
|
|
||
| @check_wrapper(check_title="Check missing vnsRsCIfAttN") | ||
| def vnsrscifattn_missing_check(tversion, **kwargs): | ||
| result = PASS | ||
| headers = ["Tenant", "Device Name", "Cluster Interface", "Missing Concrete Interface", "vnsRsCIfAtt DN"] | ||
| manual_headers = ["Tenant", "Device Name", "Cluster Interface", "Missing Concrete Interface", "vnsLIf DN"] | ||
| data = [] | ||
| recommended_action = ( | ||
| "From 6.0(3) release, Mo vnsRsCIfAtt is deprecated. Before upgrade, reattach any missing concrete interface mapping under the same L4-L7 device cluster interface so the corresponding vnsRsCIfAttN relation exists." | ||
| ) | ||
| doc_url = "https://datacenter.github.io/ACI-Pre-Upgrade-Validation-Script/validations/#check-missing-vnsrscifattn" | ||
|
|
||
| if not tversion: | ||
| return Result(result=MANUAL, msg=TVER_MISSING, doc_url=doc_url) | ||
|
|
||
| if tversion.older_than("6.0(3d)"): | ||
| return Result(result=NA, msg=VER_NOT_AFFECTED, doc_url=doc_url) | ||
|
|
||
| vnsRsCIfAtts = icurl("class", "vnsRsCIfAtt.json?rsp-prop-include=config-only") | ||
| vnsRsCIfAttNs = icurl("class", "vnsRsCIfAttN.json?rsp-prop-include=config-only") | ||
|
|
||
| if not vnsRsCIfAtts and not vnsRsCIfAttNs: | ||
| vnsLIfs = icurl("class", "vnsLIf.json?rsp-prop-include=config-only") | ||
| for vnsLIf in vnsLIfs: | ||
| try: | ||
| lif_dn = vnsLIf["vnsLIf"]["attributes"]["dn"].strip() | ||
| except (KeyError, TypeError, AttributeError): | ||
| continue | ||
| if not lif_dn: | ||
| continue | ||
|
|
||
| match = re.search( | ||
| r"uni/tn-(?P<tenant>[^/]+)/lDevVip-(?P<device>[^/]+)/lIf-(?P<lif>[^/]+)$", | ||
| lif_dn, | ||
| ) | ||
| data.append([ | ||
| match.group("tenant") if match else "", | ||
| match.group("device") if match else "", | ||
| match.group("lif") if match else "", | ||
| "N/A", | ||
| lif_dn, | ||
| ]) | ||
|
|
||
| data.sort(key=lambda row: row[-1]) | ||
|
|
||
| if data: | ||
| msg = "vnsLIf has neither vnsRsCIfAtt nor vnsRsCIfAttN. Manual verification required to avoid service graph inconsistency." | ||
| manual_action = ( | ||
| "Under each impacted L4-L7 device cluster interface, manually verify and reattach concrete interfaces as needed." | ||
| ) | ||
| return Result(result=MANUAL, msg=msg, headers=manual_headers, data=data, recommended_action=manual_action, doc_url=doc_url) | ||
|
|
||
| msg = "Both vnsRsCIfAtt and vnsRsCIfAttN are missing. Manual verification required for service graph interface attachments." | ||
| manual_action = ( | ||
| "Validate L4-L7 device cluster interfaces and reattach concrete interfaces where needed." | ||
| ) | ||
| return Result(result=MANUAL, msg=msg, recommended_action=manual_action, doc_url=doc_url) | ||
|
|
||
| if not vnsRsCIfAtts: | ||
| return Result(result=PASS, msg="No user-configured vnsRsCIfAtt payload found.", doc_url=doc_url) | ||
|
|
||
| new_dn_keys = set() | ||
| for new_mo in vnsRsCIfAttNs: | ||
| try: | ||
| dn = new_mo["vnsRsCIfAttN"]["attributes"]["dn"].strip() | ||
| except (KeyError, TypeError, AttributeError): | ||
| continue | ||
|
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. Can you try this optimized script. new_dn_keys = set() for old_mo in vnsRsCIfAtts:
Contributor
Author
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. The above suggested optimized loop logic works functionally, but without sorting it can return rows in different orders based on API/input order. Our Pytest case compares as an ordered list, so it fails intermittently on order only. I added sorting to make pytest stable and output consistent. |
||
| if dn: | ||
| new_dn_keys.add(dn.replace("/rscIfAttN-[", "/rscIfAtt-[", 1)) | ||
|
|
||
| for old_mo in vnsRsCIfAtts: | ||
| try: | ||
| old_dn = old_mo["vnsRsCIfAtt"]["attributes"]["dn"].strip() | ||
| except (KeyError, TypeError, AttributeError): | ||
| continue | ||
| if not old_dn: | ||
| continue | ||
|
|
||
| if old_dn.replace("/rscIfAttN-[", "/rscIfAtt-[", 1) in new_dn_keys: | ||
| continue | ||
|
|
||
|
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. add this check if none of vnsRsCIfAtt and vnsRsCIfAttN present. only in case Both of Mo missing attached to given vnsLif—> vnsLIf has NEITHER relation - service graph broken, ask Cu to do manual check warning only
Contributor
Author
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. Added manual check warning when both old and new mo config is unavailable. |
||
| match = re.search( | ||
| r"uni/tn-(?P<tenant>[^/]+)/lDevVip-(?P<device>[^/]+)/lIf-(?P<lif>[^/]+)/" | ||
| r"rscIfAtt-\[.*?/cIf-\[(?P<cif>[^\]]+)\]\]", | ||
| old_dn, | ||
| ) | ||
| data.append([ | ||
| match.group("tenant") if match else "", | ||
| match.group("device") if match else "", | ||
| match.group("lif") if match else "", | ||
| match.group("cif") if match else "", | ||
| old_dn, | ||
| ]) | ||
|
|
||
| data.sort(key=lambda row: row[-1]) | ||
|
|
||
| if data: | ||
| result = FAIL_O | ||
|
|
||
| return Result(result=result, headers=headers, data=data, recommended_action=recommended_action, doc_url=doc_url) | ||
|
|
||
|
|
||
| # ---- Script Execution ---- | ||
|
|
||
|
|
||
|
|
@@ -6502,6 +6603,7 @@ class CheckManager: | |
| fabric_link_redundancy_check, | ||
| apic_downgrade_compat_warning_check, | ||
| svccore_excessive_data_check, | ||
| vnsrscifattn_missing_check, | ||
|
|
||
| # Faults | ||
| apic_disk_space_faults_check, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,6 +39,7 @@ Items | This Script | |
| [APIC downgrade compatibility when crossing 6.2 release][g19]| :white_check_mark: | :no_entry_sign: | ||
| [Supported Hardware Compatibility][g20] | :white_check_mark: | :no_entry_sign: | ||
| [Svccore Excessive Data Check][g21] | :white_check_mark: | :no_entry_sign: | ||
| [Check missing vnsRsCIfAttN][g22] | :white_check_mark: | :no_entry_sign: | ||
|
|
||
| [g1]: #compatibility-target-aci-version | ||
| [g2]: #compatibility-cimc-version | ||
|
|
@@ -61,6 +62,7 @@ Items | This Script | |
| [g19]: #apic-downgrade-compatibility-when-crossing-62-release | ||
| [g20]: #supported-hardware-compatibility | ||
| [g21]: #svccore-excessive-data-check | ||
| [g22]: #check-missing-vnsrscifattn | ||
|
|
||
| ### Fault Checks | ||
| Items | Faults | This Script | APIC built-in | ||
|
|
@@ -2769,7 +2771,6 @@ This issue happens only when the target version is specifically 6.1(4h). | |
|
|
||
| To avoid this issue, change the target version to another version. Or verify that the `bootscript` file exists in the bootflash of each modular spine switch prior to upgrading to 6.1(4h). If the file is missing, you have to do clean reboot on the impacted spine to ensure that `/bootflash/bootscript` gets created again. In case you already upgraded your spine and you are experiencing the traffic impact due to this issue, clean reboot of the spine will restore the traffic. | ||
|
|
||
|
|
||
|
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. remove unwanted new lines
Contributor
Author
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. Removed unwanted lines at line numbers 43 and 210 |
||
| ### Inband Management Policy Misconfiguration | ||
|
|
||
| Due to the defect [CSCwh80837][67], starting from version 6.0(4c), mgmtRsInBStNode policy get modified in leaf/spine during Apic upgrade. | ||
|
|
@@ -2797,6 +2798,13 @@ Administrators may be unable to access or operate the APIC GUI, potentially impa | |
|
|
||
| This check will verify the count of the `svccoreCtrlr` Managed Object and raise and alarm with the bug if object count found more than 240. Remove the content or objects of `svccoreCtrlr` or `svccoreNode`. Contact Cisco TAC or upgrade to a release containing the fix for CSCws84232 before proceeding with an upgrade. | ||
|
|
||
| ### Check missing vnsRsCIfAttN | ||
|
|
||
| When upgrading to 6.0(3) and above, 'vnsRsCIfAtt' is deleted without creating 'vnsRsCIfAttN' under 'vnsLIf'. This leaves the service graph interface attachment in an inconsistent state. | ||
|
|
||
| For all impacted DNs in this check, reattach the Concrete interfaces associated with the cluster interface under Devices in the Services > L4-L7 tab. | ||
|
|
||
| Tenant --> Services --> L4-L7 --> Devices (Device_name) --> cluster interface --> Concrete interfaces | ||
|
|
||
| [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 | ||
|
|
@@ -2867,4 +2875,4 @@ This check will verify the count of the `svccoreCtrlr` Managed Object and raise | |
| [66]: https://bst.cloudapps.cisco.com/bugsearch/bug/CSCwr66848 | ||
| [67]: https://bst.cloudapps.cisco.com/bugsearch/bug/CSCwh80837 | ||
| [68]: https://bst.cloudapps.cisco.com/bugsearch/bug/CSCwd40071 | ||
| [69]: https://bst.cloudapps.cisco.com/bugsearch/bug/CSCws84232 | ||
| [69]: https://bst.cloudapps.cisco.com/bugsearch/bug/CSCws84232 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,131 @@ | ||
| import os | ||
| import pytest | ||
| import importlib | ||
| from helpers.utils import read_data | ||
|
|
||
| script = importlib.import_module("aci-preupgrade-validation-script") | ||
|
|
||
| dir = os.path.dirname(os.path.abspath(__file__)) | ||
|
|
||
| test_function = "vnsrscifattn_missing_check" | ||
|
|
||
| # icurl queries | ||
| vnsRsCIfAtt_api = "vnsRsCIfAtt.json?rsp-prop-include=config-only" | ||
| vnsRsCIfAttN_api = "vnsRsCIfAttN.json?rsp-prop-include=config-only" | ||
| vnsLIf_api = "vnsLIf.json?rsp-prop-include=config-only" | ||
|
|
||
| @pytest.mark.parametrize( | ||
| "icurl_outputs, tversion, expected_result, expected_data", | ||
| [ | ||
| # Target version missing | ||
| ( | ||
| {}, | ||
| None, | ||
| script.MANUAL, | ||
| [], | ||
| ), | ||
| # Target version is not affected (< 6.0(3d)) | ||
| ( | ||
| {}, | ||
| "6.0(2h)", | ||
| script.NA, | ||
| [], | ||
| ), | ||
| # Both vnsRsCIfAtt and vnsRsCIfAttN are missing (no vnsLIf rows) | ||
| ( | ||
| { | ||
| vnsRsCIfAtt_api: read_data(dir, "vnsRsCIfAtt_empty.json"), | ||
| vnsRsCIfAttN_api: read_data(dir, "vnsRsCIfAtt_empty.json"), | ||
| vnsLIf_api: [], | ||
| }, | ||
| "6.1(5e)", | ||
| script.MANUAL, | ||
| [], | ||
| ), | ||
| # Both vnsRsCIfAtt and vnsRsCIfAttN are missing while vnsLIf exists | ||
| ( | ||
| { | ||
| vnsRsCIfAtt_api: read_data(dir, "vnsRsCIfAtt_empty.json"), | ||
| vnsRsCIfAttN_api: read_data(dir, "vnsRsCIfAtt_empty.json"), | ||
| vnsLIf_api: read_data(dir, "vnsLIf_only.json"), | ||
| }, | ||
| "6.1(5e)", | ||
| script.MANUAL, | ||
| [ | ||
| [ | ||
| "CSCwj49418", | ||
| "test", | ||
| "intf-cons", | ||
| "N/A", | ||
| "uni/tn-CSCwj49418/lDevVip-test/lIf-intf-cons", | ||
| ], | ||
| [ | ||
| "CSCwj49418", | ||
| "test", | ||
| "intf-prov", | ||
| "N/A", | ||
| "uni/tn-CSCwj49418/lDevVip-test/lIf-intf-prov", | ||
| ], | ||
| ], | ||
| ), | ||
| # All vnsRsCIfAtt relations have matching vnsRsCIfAttN relations | ||
| ( | ||
| { | ||
| vnsRsCIfAtt_api: read_data(dir, "vnsRsCIfAtt_match.json"), | ||
| vnsRsCIfAttN_api: read_data(dir, "vnsRsCIfAttN_match.json"), | ||
| }, | ||
| "6.1(5e)", | ||
| script.PASS, | ||
| [], | ||
| ), | ||
| # One vnsRsCIfAtt relation (cons) missing in vnsRsCIfAttN | ||
| ( | ||
| { | ||
| vnsRsCIfAtt_api: read_data(dir, "vnsRsCIfAtt_match.json"), | ||
| vnsRsCIfAttN_api: read_data(dir, "vnsRsCIfAttN_missing_cons.json"), | ||
|
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. add case for empty vnsRsCIfAttN.
Contributor
Author
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. Added test case for empty vnsRsCIfAttN scenario |
||
| }, | ||
| "6.1(5e)", | ||
| script.FAIL_O, | ||
| [ | ||
| [ | ||
| "CSCwj49418", | ||
| "test", | ||
| "intf-cons", | ||
| "cons", | ||
| "uni/tn-CSCwj49418/lDevVip-test/lIf-intf-cons/rscIfAtt-[uni/tn-CSCwj49418/lDevVip-test/cDev-cdev/cIf-[cons]]", | ||
| ] | ||
| ], | ||
| ), | ||
| # vnsRsCIfAttN is empty; all vnsRsCIfAtt relations are missing | ||
| ( | ||
| { | ||
| vnsRsCIfAtt_api: read_data(dir, "vnsRsCIfAtt_match.json"), | ||
| vnsRsCIfAttN_api: [], | ||
| }, | ||
| "6.1(5e)", | ||
| script.FAIL_O, | ||
| [ | ||
| [ | ||
| "CSCwj49418", | ||
| "test", | ||
| "intf-cons", | ||
| "cons", | ||
| "uni/tn-CSCwj49418/lDevVip-test/lIf-intf-cons/rscIfAtt-[uni/tn-CSCwj49418/lDevVip-test/cDev-cdev/cIf-[cons]]", | ||
| ], | ||
| [ | ||
| "CSCwj49418", | ||
| "test", | ||
| "intf-prov", | ||
| "prov", | ||
| "uni/tn-CSCwj49418/lDevVip-test/lIf-intf-prov/rscIfAtt-[uni/tn-CSCwj49418/lDevVip-test/cDev-cdev/cIf-[prov]]", | ||
| ], | ||
| ], | ||
| ), | ||
| ], | ||
| ) | ||
| def test_logic(run_check, mock_icurl, tversion, expected_result, expected_data): | ||
| result = run_check( | ||
| tversion=script.AciVersion(tversion) if tversion else None, | ||
| ) | ||
| assert result.result == expected_result | ||
| assert result.data == expected_data | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| [ | ||
| { | ||
| "vnsLIf": { | ||
| "attributes": { | ||
| "dn": "uni/tn-CSCwj49418/lDevVip-test/lIf-intf-cons", | ||
| "name": "intf-cons" | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| "vnsLIf": { | ||
| "attributes": { | ||
| "dn": "uni/tn-CSCwj49418/lDevVip-test/lIf-intf-prov", | ||
| "name": "intf-prov" | ||
| } | ||
| } | ||
| } | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| [ | ||
| { | ||
| "vnsRsCIfAttN": { | ||
| "attributes": { | ||
| "dn": "uni/tn-CSCwj49418/lDevVip-test/lIf-intf-prov/rscIfAttN-[uni/tn-CSCwj49418/lDevVip-test/cDev-cdev/cIf-[prov]]", | ||
| "tDn": "uni/tn-CSCwj49418/lDevVip-test/cDev-cdev/cIf-[prov]" | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| "vnsRsCIfAttN": { | ||
| "attributes": { | ||
| "dn": "uni/tn-CSCwj49418/lDevVip-test/lIf-intf-cons/rscIfAttN-[uni/tn-CSCwj49418/lDevVip-test/cDev-cdev/cIf-[cons]]", | ||
| "tDn": "uni/tn-CSCwj49418/lDevVip-test/cDev-cdev/cIf-[cons]" | ||
| } | ||
| } | ||
| } | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| [ | ||
| { | ||
| "vnsRsCIfAttN": { | ||
| "attributes": { | ||
| "dn": "uni/tn-CSCwj49418/lDevVip-test/lIf-intf-prov/rscIfAttN-[uni/tn-CSCwj49418/lDevVip-test/cDev-cdev/cIf-[prov]]", | ||
| "tDn": "uni/tn-CSCwj49418/lDevVip-test/cDev-cdev/cIf-[prov]" | ||
| } | ||
| } | ||
| } | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| [] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| [ | ||
| { | ||
| "vnsRsCIfAtt": { | ||
| "attributes": { | ||
| "dn": "uni/tn-CSCwj49418/lDevVip-test/lIf-intf-prov/rscIfAtt-[uni/tn-CSCwj49418/lDevVip-test/cDev-cdev/cIf-[prov]]", | ||
| "tDn": "uni/tn-CSCwj49418/lDevVip-test/cDev-cdev/cIf-[prov]" | ||
| } | ||
| } | ||
| }, | ||
| { | ||
| "vnsRsCIfAtt": { | ||
| "attributes": { | ||
| "dn": "uni/tn-CSCwj49418/lDevVip-test/lIf-intf-cons/rscIfAtt-[uni/tn-CSCwj49418/lDevVip-test/cDev-cdev/cIf-[cons]]", | ||
| "tDn": "uni/tn-CSCwj49418/lDevVip-test/cDev-cdev/cIf-[cons]" | ||
| } | ||
| } | ||
| } | ||
| ] |
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.
Add cversion check
current code is pre-6.0.3
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.
As discussed, cversion check is not required. When we are providing tversion as 6.0(3) and above if both old mo and new mo are not configured then we are alerting the customer with recommended action. This is equivalent by checking the cversion <6.0(3) and verifying the old and new mo config unavailability and alerting the customer.