diff --git a/aci-preupgrade-validation-script.py b/aci-preupgrade-validation-script.py index 094f0e79..e800b2de 100644 --- a/aci-preupgrade-validation-script.py +++ b/aci-preupgrade-validation-script.py @@ -5978,9 +5978,9 @@ def aes_encryption_check(tversion, **kwargs): @check_wrapper(check_title='Service Graph BD Forceful Routing') def service_bd_forceful_routing_check(cversion, tversion, **kwargs): result = PASS - headers = ["Bridge Domain (Tenant:BD)", "Service Graph Device (Tenant:Device)"] + headers = ["Bridge Domain (Tenant:BD)", "Contract (Tenant:Contract)", "Service Graph (Tenant:Service Graph)", "Node", "Connector"] data = [] - unformatted_headers = ["DN of fvRtEPpInfoToBD"] + unformatted_headers = ["DN of fvRtLIfCtxToBD"] unformatted_data = [] recommended_action = ( "\n\tConfirm that within these BDs there is no bridging traffic with the destination IP that doesn't belong to them." @@ -5995,18 +5995,24 @@ def service_bd_forceful_routing_check(cversion, tversion, **kwargs): return Result(result=NA, msg=VER_NOT_AFFECTED) dn_regex = r"uni/tn-(?P[^/]+)/BD-(?P[^/]+)/" - dn_regex += r"rtvnsEPpInfoToBD-\[uni/tn-(?P[^/])+/LDevInst-\[uni/tn-(?P[^/]+)/lDevVip-(?P[^\]]+)\].*\]" - - fvRtEPpInfoToBDs = icurl("class", "fvRtEPpInfoToBD.json") - for fvRtEPpInfoToBD in fvRtEPpInfoToBDs: - m = re.search(dn_regex, fvRtEPpInfoToBD["fvRtEPpInfoToBD"]["attributes"]["dn"]) + dn_regex += r"rtvnsLIfCtxToBD-\[uni/tn-(?P[^/]+)/" + dn_regex += r"ldevCtx-c-(?P.+?)-g-(?P.+?)-n-(?P.+?)/" + dn_regex += r"lIfCtx-c-(?P[^\]]+)\]" + + fvRtLIfCtxToBDs = icurl("class", "fvRtLIfCtxToBD.json") + for fvRtLIfCtxToBD in fvRtLIfCtxToBDs: + dn = fvRtLIfCtxToBD["fvRtLIfCtxToBD"]["attributes"]["dn"] + m = re.search(dn_regex, dn) if not m: - log.error("Failed to match %s", fvRtEPpInfoToBD["fvRtEPpInfoToBD"]["attributes"]["dn"]) - unformatted_data.append([fvRtEPpInfoToBD["fvRtEPpInfoToBD"]["attributes"]["dn"]]) + log.error("Failed to match %s", dn) + unformatted_data.append([dn]) continue data.append([ "{}:{}".format(m.group("bd_tn"), m.group("bd")), - "{}:{}".format(m.group("ldev_tn"), m.group("ldev")), + "{}:{}".format(m.group("ldevctx_tn"), m.group("contract")), + "{}:{}".format(m.group("ldevctx_tn"), m.group("graph")), + m.group("node"), + m.group("conn"), ]) if data or unformatted_data: diff --git a/tests/checks/service_bd_forceful_routing_check/fvRtEPpInfoToBD.json b/tests/checks/service_bd_forceful_routing_check/fvRtEPpInfoToBD.json deleted file mode 100644 index f9e5438e..00000000 --- a/tests/checks/service_bd_forceful_routing_check/fvRtEPpInfoToBD.json +++ /dev/null @@ -1,54 +0,0 @@ -[ - { - "fvRtEPpInfoToBD": { - "attributes": { - "childAction": "", - "dn": "uni/tn-TK/BD-BD1/rtvnsEPpInfoToBD-[uni/tn-TK/LDevInst-[uni/tn-TK/lDevVip-N9K]-ctx-VRFA/G-N9KctxVRFA-N-BD1-C-one-arm]", - "lcOwn": "local", - "modTs": "2025-04-03T15:48:27.052-07:00", - "status": "", - "tCl": "vnsEPpInfo", - "tDn": "uni/tn-TK/LDevInst-[uni/tn-TK/lDevVip-N9K]-ctx-VRFA/G-N9KctxVRFA-N-BD1-C-one-arm" - } - } - }, - { - "fvRtEPpInfoToBD": { - "attributes": { - "childAction": "", - "dn": "uni/tn-TK/BD-BD_PBR/rtvnsEPpInfoToBD-[uni/tn-TK/LDevInst-[uni/tn-TK/lDevVip-ASAv]-ctx-VRFA/G-ASAvctxVRFA-N-BD_PBR-C-one-arm]", - "lcOwn": "local", - "modTs": "2025-04-04T23:12:34.647-07:00", - "status": "", - "tCl": "vnsEPpInfo", - "tDn": "uni/tn-TK/LDevInst-[uni/tn-TK/lDevVip-ASAv]-ctx-VRFA/G-ASAvctxVRFA-N-BD_PBR-C-one-arm" - } - } - }, - { - "fvRtEPpInfoToBD": { - "attributes": { - "childAction": "", - "dn": "uni/tn-TK/BD-BD_PBR/rtvnsEPpInfoToBD-[uni/tn-TK/LDevInst-[uni/tn-TK/lDevVip-LB]-ctx-VRFA/G-LBctxVRFA-N-BD_PBR-C-one-arm]", - "lcOwn": "local", - "modTs": "2025-04-04T23:26:16.948-07:00", - "status": "", - "tCl": "vnsEPpInfo", - "tDn": "uni/tn-TK/LDevInst-[uni/tn-TK/lDevVip-LB]-ctx-VRFA/G-LBctxVRFA-N-BD_PBR-C-one-arm" - } - } - }, - { - "fvRtEPpInfoToBD": { - "attributes": { - "childAction": "", - "dn": "uni/tn-TK/BD-BD2/rtvnsEPpInfoToBD-[uni/tn-TK/LDevInst-[uni/tn-common/lDevVip-CMN_LB]-ctx-VRFA/G-CMN_LBctxVRFA-N-BD2-C-cluster-if1]", - "lcOwn": "local", - "modTs": "2025-04-05T00:08:15.075-07:00", - "status": "", - "tCl": "vnsEPpInfo", - "tDn": "uni/tn-TK/LDevInst-[uni/tn-common/lDevVip-CMN_LB]-ctx-VRFA/G-CMN_LBctxVRFA-N-BD2-C-cluster-if1" - } - } - } -] diff --git a/tests/checks/service_bd_forceful_routing_check/fvRtLIfCtxToBD.json b/tests/checks/service_bd_forceful_routing_check/fvRtLIfCtxToBD.json new file mode 100644 index 00000000..0c475a2f --- /dev/null +++ b/tests/checks/service_bd_forceful_routing_check/fvRtLIfCtxToBD.json @@ -0,0 +1,93 @@ +[ + { + "fvRtLIfCtxToBD": { + "attributes": { + "childAction": "", + "dn": "uni/tn-TK/BD-BD4/rtvnsLIfCtxToBD-[uni/tn-TK/ldevCtx-c-N9K_PBR_C-g-N9K_PBR-n-N1/lIfCtx-c-provider]", + "lcOwn": "local", + "modTs": "2026-09-04T17:33:01.891-07:00", + "status": "", + "tCl": "vnsLIfCtx", + "tDn": "uni/tn-TK/ldevCtx-c-N9K_PBR_C-g-N9K_PBR-n-N1/lIfCtx-c-provider" + } + } + }, + { + "fvRtLIfCtxToBD": { + "attributes": { + "childAction": "", + "dn": "uni/tn-TK/BD-BD3/rtvnsLIfCtxToBD-[uni/tn-TK/ldevCtx-c-N9K_PBR_C-g-N9K_PBR-n-N1/lIfCtx-c-consumer]", + "lcOwn": "local", + "modTs": "2026-09-04T17:33:01.891-07:00", + "status": "", + "tCl": "vnsLIfCtx", + "tDn": "uni/tn-TK/ldevCtx-c-N9K_PBR_C-g-N9K_PBR-n-N1/lIfCtx-c-consumer" + } + } + }, + { + "fvRtLIfCtxToBD": { + "attributes": { + "childAction": "", + "dn": "uni/tn-TK/BD-BD_PBR/rtvnsLIfCtxToBD-[uni/tn-TK/ldevCtx-c-PBR-g-FW_PBR-n-N1/lIfCtx-c-provider]", + "lcOwn": "local", + "modTs": "2026-07-07T21:34:53.735-07:00", + "status": "", + "tCl": "vnsLIfCtx", + "tDn": "uni/tn-TK/ldevCtx-c-PBR-g-FW_PBR-n-N1/lIfCtx-c-provider" + } + } + }, + { + "fvRtLIfCtxToBD": { + "attributes": { + "childAction": "", + "dn": "uni/tn-TK/BD-BD_PBR/rtvnsLIfCtxToBD-[uni/tn-TK/ldevCtx-c-PBR-g-FW_PBR-n-N1/lIfCtx-c-consumer]", + "lcOwn": "local", + "modTs": "2026-07-07T21:34:53.735-07:00", + "status": "", + "tCl": "vnsLIfCtx", + "tDn": "uni/tn-TK/ldevCtx-c-PBR-g-FW_PBR-n-N1/lIfCtx-c-consumer" + } + } + }, + { + "fvRtLIfCtxToBD": { + "attributes": { + "childAction": "", + "dn": "uni/tn-TK/BD-BD_PBR_inside/rtvnsLIfCtxToBD-[uni/tn-common/ldevCtx-c-CMN_LB_C-g-CMN_LB-n-N1/lIfCtx-c-cluster-if1]", + "lcOwn": "local", + "modTs": "2026-09-04T17:35:11.123-07:00", + "status": "", + "tCl": "vnsLIfCtx", + "tDn": "uni/tn-common/ldevCtx-c-CMN_LB_C-g-CMN_LB-n-N1/lIfCtx-c-cluster-if1" + } + } + }, + { + "fvRtLIfCtxToBD": { + "attributes": { + "childAction": "", + "dn": "uni/tn-TK/BD-BD_PBR_outside/rtvnsLIfCtxToBD-[uni/tn-common/ldevCtx-c-CMN_LB_C-g-CMN_LB-n-N1/lIfCtx-c-cluster-if1]", + "lcOwn": "local", + "modTs": "2026-09-04T17:35:11.123-07:00", + "status": "", + "tCl": "vnsLIfCtx", + "tDn": "uni/tn-common/ldevCtx-c-CMN_LB_C-g-CMN_LB-n-N1/lIfCtx-c-cluster-if1" + } + } + }, + { + "fvRtLIfCtxToBD": { + "attributes": { + "childAction": "", + "dn": "uni/tn-TK/BD-BD1/rtvnsLIfCtxToBD-[unexpected-dn-format]", + "lcOwn": "local", + "modTs": "2026-09-04T17:36:22.456-07:00", + "status": "", + "tCl": "vnsLIfCtx", + "tDn": "unexpected-dn-format" + } + } + } +] diff --git a/tests/checks/service_bd_forceful_routing_check/test_service_bd_forceful_routing_check.py b/tests/checks/service_bd_forceful_routing_check/test_service_bd_forceful_routing_check.py index 5867c884..2cd545aa 100644 --- a/tests/checks/service_bd_forceful_routing_check/test_service_bd_forceful_routing_check.py +++ b/tests/checks/service_bd_forceful_routing_check/test_service_bd_forceful_routing_check.py @@ -12,52 +12,71 @@ test_function = "service_bd_forceful_routing_check" # icurl queries -fvRtEPpInfoToBD = "fvRtEPpInfoToBD.json" +fvRtLIfCtxToBD = "fvRtLIfCtxToBD.json" @pytest.mark.parametrize( - "icurl_outputs, cversion, tversion, expected_result", + "icurl_outputs, cversion, tversion, expected_result, expected_data, expected_unformatted_data", [ # tversion missing ( - {fvRtEPpInfoToBD: read_data(dir, "fvRtEPpInfoToBD.json")}, + {fvRtLIfCtxToBD: read_data(dir, "fvRtLIfCtxToBD.json")}, "5.2(8h)", None, - script.MANUAL + script.MANUAL, + [], + [], ), # Version not affected (both new) ( - {fvRtEPpInfoToBD: read_data(dir, "fvRtEPpInfoToBD.json")}, + {fvRtLIfCtxToBD: read_data(dir, "fvRtLIfCtxToBD.json")}, "6.0(2h)", "6.1(3b)", script.NA, + [], + [], ), # Version not affected (both old) ( - {fvRtEPpInfoToBD: read_data(dir, "fvRtEPpInfoToBD.json")}, + {fvRtLIfCtxToBD: read_data(dir, "fvRtLIfCtxToBD.json")}, "4.2(7s)", "6.0(1h)", script.NA, + [], + [], ), # Version affected with L4L7 service graph BD ( - {fvRtEPpInfoToBD: read_data(dir, "fvRtEPpInfoToBD.json")}, + {fvRtLIfCtxToBD: read_data(dir, "fvRtLIfCtxToBD.json")}, "5.2(8h)", "6.0(2h)", - script.MANUAL + script.MANUAL, + [ + ["TK:BD4", "TK:N9K_PBR_C", "TK:N9K_PBR", "N1", "provider"], + ["TK:BD3", "TK:N9K_PBR_C", "TK:N9K_PBR", "N1", "consumer"], + ["TK:BD_PBR", "TK:PBR", "TK:FW_PBR", "N1", "provider"], + ["TK:BD_PBR", "TK:PBR", "TK:FW_PBR", "N1", "consumer"], + ["TK:BD_PBR_inside", "common:CMN_LB_C", "common:CMN_LB", "N1", "cluster-if1"], + ["TK:BD_PBR_outside", "common:CMN_LB_C", "common:CMN_LB", "N1", "cluster-if1"], + ], + [["uni/tn-TK/BD-BD1/rtvnsLIfCtxToBD-[unexpected-dn-format]"]], ), # Version affected without L4L7 service graph BD ( - {fvRtEPpInfoToBD: []}, + {fvRtLIfCtxToBD: []}, "5.2(8h)", "6.0(2h)", script.PASS, + [], + [], ), ], ) -def test_logic(run_check, mock_icurl, cversion, tversion, expected_result): +def test_logic(run_check, mock_icurl, cversion, tversion, expected_result, expected_data, expected_unformatted_data): result = run_check( cversion=script.AciVersion(cversion), tversion=script.AciVersion(tversion) if tversion else None, ) assert result.result == expected_result + assert result.data == expected_data + assert result.unformatted_data == expected_unformatted_data