From e4f6d94ec532488a1baae392550d8b20b9472f00 Mon Sep 17 00:00:00 2001 From: Enrique Estrada Date: Tue, 12 Aug 2025 13:42:21 -0600 Subject: [PATCH] issue244 solved --- aci-preupgrade-validation-script.py | 58 ++++++- docs/docs/validations.md | 15 +- .../global_pg_fvAEPg.json | 40 +++++ .../global_pg_l3extInstP.json | 3 + .../global_vzBrCP_pos.json | 24 +++ .../test_pg_and_shared_svc_contract_check.py | 147 ++++++++++++++++++ 6 files changed, 285 insertions(+), 2 deletions(-) create mode 100644 tests/pg_and_shared_svc_contract_check/global_pg_fvAEPg.json create mode 100644 tests/pg_and_shared_svc_contract_check/global_pg_l3extInstP.json create mode 100644 tests/pg_and_shared_svc_contract_check/global_vzBrCP_pos.json create mode 100644 tests/pg_and_shared_svc_contract_check/test_pg_and_shared_svc_contract_check.py diff --git a/aci-preupgrade-validation-script.py b/aci-preupgrade-validation-script.py index edfee703..99d3dbce 100644 --- a/aci-preupgrade-validation-script.py +++ b/aci-preupgrade-validation-script.py @@ -5297,6 +5297,62 @@ def apic_database_size_check(cversion, **kwargs): result = FAIL_UF return Result(result=result, headers=headers, data=data, recommended_action=recommended_action, doc_url=doc_url) +@check_wrapper(check_title='Shared Services Providers with Preferred Group enabled') +def pg_and_shared_svc_contract_check(cversion, tversion, **kwargs): + result= PASS + headers = ["Shared Service Contract", "Provider in Preferred Group", "PcTag"] + data = [] + recommended_action = 'an EPG in a Contract Preferred Group can consume a shared service contract, but cannot be a provider for a shared service contract.' + doc_url = 'https://datacenter.github.io/ACI-Pre-Upgrade-Validation-Script/validations/#preferred_group_shared_service_provider' + + if not tversion: + return Result(result=MANUAL, msg=TVER_MISSING) + # Configuration becomes faulted after 4.2-6d and 5.1-1h + if tversion.older_than("4.2(6d)"): + return Result(result=NA) + elif tversion.older_than("5.1(1h)"): + return Result(result=NA) + shrd_contracts_api = 'vzBrCP.json' + shrd_contracts_api += '?query-target-filter=and(eq(vzBrCP.scope,"global"))' + shrd_contracts = icurl('class', shrd_contracts_api) + if not shrd_contracts: + return Result(result=NA) + list_of_shrd_contracts =[] + for shrd_contract in shrd_contracts: + list_of_shrd_contracts.append(shrd_contract["vzBrCP"]["attributes"]["dn"]) + # Because of CSCwb32627 # Configuration only becomes faulted for extEPGs after 6.0(1g), normal epgs permitted. + if tversion.older_than("6.0(1g)"): + glbl_epgs_api = 'fvAEPg.json' + glbl_epgs_api += '?query-target-filter=and(le(fvAEPg.pcTag,"16385"),ge(fvAEPg.pcTag,"16"),eq(fvAEPg.prefGrMemb,"include"))' + glbl_epgs_api += '&rsp-subtree=children&rsp-subtree-class=fvRsProv' + glbl_epgs = icurl('class', glbl_epgs_api) + if glbl_epgs: + for glbl_epg in glbl_epgs: + for prov_contract in glbl_epg["fvAEPg"]["children"]: + if prov_contract["fvRsProv"]["attributes"]["tDn"] in list_of_shrd_contracts: + contract = prov_contract["fvRsProv"]["attributes"]["tDn"] + pctag = glbl_epg["fvAEPg"]["attributes"]["pcTag"] + provider = glbl_epg["fvAEPg"]["attributes"]["dn"] + data.append([contract, provider, pctag]) + # Regardless of version, check extEPGs + glbl_ext_epgs_api = 'l3extInstP.json' + glbl_ext_epgs_api += '?query-target-filter=and(le(l3extInstP.pcTag,"16385"),ge(l3extInstP.pcTag,"16"),eq(l3extInstP.prefGrMemb,"include"))' + glbl_ext_epgs_api += '&rsp-subtree=children&rsp-subtree-class=fvRsProv' + glbl_ext_epgs = icurl('class', glbl_ext_epgs_api) + if glbl_ext_epgs: + for glbl_ext_epg in glbl_ext_epgs: + for prov_ext_contract in glbl_ext_epg["l3extInstP"]["children"]: + if prov_ext_contract["fvRsProv"]["attributes"]["tDn"] in list_of_shrd_contracts: + contract = prov_ext_contract["fvRsProv"]["attributes"]["tDn"] + pctag = glbl_ext_epg["l3extInstP"]["attributes"]["pcTag"] + provider = glbl_ext_epg["l3extInstP"]["attributes"]["dn"] + data.append([contract, provider, pctag]) + + if data: + result = FAIL_O + + return Result(result=result, headers=headers, data=data, recommended_action=recommended_action, doc_url=doc_url) + # ---- Script Execution ---- def parse_args(args): @@ -5425,6 +5481,7 @@ def get_checks(api_only, debug_function): aes_encryption_check, service_bd_forceful_routing_check, ave_eol_check, + pg_and_shared_svc_contract_check, # Bugs ep_announce_check, @@ -5452,7 +5509,6 @@ def get_checks(api_only, debug_function): standby_sup_sync_check, stale_pcons_ra_mo_check, isis_database_byte_check, - ] conn_checks = [ # General diff --git a/docs/docs/validations.md b/docs/docs/validations.md index e46a8815..bf730e88 100644 --- a/docs/docs/validations.md +++ b/docs/docs/validations.md @@ -131,7 +131,7 @@ Items | Faults | This Script [Global AES Encryption][c21] | :white_check_mark: | :white_check_mark: 6.1(2) | :no_entry_sign: [Service Graph BD Forceful Routing][c22] | :white_check_mark: | :no_entry_sign: | :no_entry_sign: [AVE End-of-life][c23] | :white_check_mark: | :no_entry_sign: | :no_entry_sign: - +[Preferred Group Shared Service Provider][c23] | :white_check_mark: | :no_entry_sign: | :no_entry_sign: [c1]: #vpc-paired-leaf-switches [c2]: #overlapping-vlan-pool @@ -156,6 +156,7 @@ Items | Faults | This Script [c21]: #global-aes-encryption [c22]: #service-graph-bd-forceful-routing [c23]: #ave-end-of-life +[c24]: #preferred_group_shared_service_provider ### Defect Condition Checks @@ -2221,6 +2222,16 @@ As outlined in the [End-of-Sale and End-of-Life Announcement for Cisco Applicati If planning an upgrade to 6.0+, review the [Cisco ACI Virtual Edge Migration Guide][56] and complete a domain migration prior to performing the upgrade. +### Preferred Group Shared Service Provider + +As detailed in the[ACI Policy Model][59] Starting in 4.2(6d) and later, or 5.1(1h) and later an EPG in a Contract Preferred Group can consume a shared service contract, but cannot be a provider for a shared service contract with an L3Out EPG as consumer. + +Due to the behavior change contracts will no longer be pushed post-upgrade causing a significant datacenter outage. + +The configuration will be faulted: e.g. F0467 Configuration failed for uni/tn-common/brc-shared/contract/epgCont-1/instp-ext-epg due to Invalid Contract Configuration, debug message: invalid-contract-config: Shared service provider cannot be in a Preferred Group. + + +Starting version 6.0(1g), this validation is relaxed for normal EPGs but is still not allowed for External EPGs. ## Defect Check Details @@ -2648,3 +2659,5 @@ Do not upgrade to any affected ACI software release if this check fails. [56]: https://www.cisco.com/c/en/us/td/docs/dcn/whitepapers/cisco-aci-virtual-edge-migration.html [57]: https://bst.cloudapps.cisco.com/bugsearch/bug/CSCwp22212 [58]: https://bst.cloudapps.cisco.com/bugsearch/bug/CSCwp15375 +[59]: https://www.cisco.com/c/en/us/td/docs/switches/datacenter/aci/apic/sw/5-x/aci-fundamentals/cisco-aci-fundamentals-50x/m_policy-model.html#concept_tds_vcc_fy + diff --git a/tests/pg_and_shared_svc_contract_check/global_pg_fvAEPg.json b/tests/pg_and_shared_svc_contract_check/global_pg_fvAEPg.json new file mode 100644 index 00000000..a7af4538 --- /dev/null +++ b/tests/pg_and_shared_svc_contract_check/global_pg_fvAEPg.json @@ -0,0 +1,40 @@ +[ +{"fvAEPg": +{"attributes": +{"annotation":"","childAction":"","configIssues":"","configSt":"applied","descr":"","dn":"uni/tn-common/ap-apptest/epg-epg1","exceptionTag":"","extMngdBy":"","floodOnEncap":"disabled","fwdCtrl":"","hasMcastSource":"no","isAttrBasedEPg":"no","isSharedSrvMsiteEPg":"no","lcOwn":"local","matchT":"AtleastOne","modTs":"2025-08-07T18:05:49.910+00:00","monPolDn":"uni/tn-common/monepg-default","name":"epg1","nameAlias":"","pcEnfPref":"unenforced","pcTag":"5555","pcTagAllocSrc":"idmanager","prefGrMemb":"include","prio":"unspecified","scope":"2261001","shutdown":"no","status":"","triggerSt":"triggerable","txId":"1729382256913953811","uid":"15374","userdom":":all:"},"children":[ +{"fvRsProv": +{"attributes": +{"accessPrivilege":"USER","annotation":"","childAction":"","ctrctUpd":"ctrct","extMngdBy":"","forceResolve":"yes","intent":"install","lcOwn":"local","matchT":"AtleastOne","modTs":"2025-08-07T18:05:49.910+00:00","monPolDn":"uni/tn-common/monepg-default","prio":"unspecified","rType":"mo","rn":"rsprov-AD_C","state":"formed","stateQual":"none","status":"","tCl":"vzBrCP","tContextDn":"","tDn":"uni/tn-common/brc-AD_C","tRn":"brc-AD_C","tType":"name","tnVzBrCPName":"AD_C","triggerSt":"triggerable","uid":"15374","updateCollection":"no","userdom":":all:"}}}]}}, +{"fvAEPg": +{"attributes": +{"annotation":"orchestrator:msc-shadow:no","childAction":"","configIssues":"","configSt":"applied","descr":"","dn":"uni/tn-AJ-PROD/ap-PTC_AP1/epg-PTC_EPG4","exceptionTag":"","extMngdBy":"","floodOnEncap":"disabled","fwdCtrl":"","hasMcastSource":"no","isAttrBasedEPg":"no","isSharedSrvMsiteEPg":"yes","lcOwn":"local","matchT":"AtleastOne","modTs":"2025-08-06T23:29:28.934+00:00","monPolDn":"uni/tn-common/monepg-default","name":"PTC_EPG4","nameAlias":"","pcEnfPref":"unenforced","pcTag":"44","pcTagAllocSrc":"idmanager","prefGrMemb":"include","prio":"unspecified","scope":"2555906","shutdown":"no","status":"","triggerSt":"triggerable","txId":"7493989779944511091","uid":"0","userdom":"all"},"children":[ +{"fvRsProv": +{"attributes": +{"accessPrivilege":"USER","annotation":"orchestrator:msc-shadow:no","childAction":"","ctrctUpd":"ctrct","extMngdBy":"","forceResolve":"yes","intent":"install","lcOwn":"local","matchT":"AtleastOne","modTs":"2025-08-06T23:29:28.934+00:00","monPolDn":"uni/tn-common/monepg-default","prio":"unspecified","rType":"mo","rn":"rsprov-common_contract","state":"formed","stateQual":"none","status":"","tCl":"vzBrCP","tContextDn":"","tDn":"uni/tn-common/brc-common_contract","tRn":"brc-common_contract","tType":"name","tnVzBrCPName":"common_contract","triggerSt":"triggerable","uid":"0","updateCollection":"no","userdom":"all"}}}]}}, +{"fvAEPg": +{"attributes": +{"annotation":"","childAction":"","configIssues":"","configSt":"applied","descr":"","dn":"uni/tn-vavictor_TenantA/ap-eApp_AP/epg-App_EPG","exceptionTag":"","extMngdBy":"","floodOnEncap":"disabled","fwdCtrl":"","hasMcastSource":"no","isAttrBasedEPg":"no","isSharedSrvMsiteEPg":"no","lcOwn":"local","matchT":"AtleastOne","modTs":"2025-07-20T00:45:30.670+00:00","monPolDn":"uni/tn-common/monepg-default","name":"App_EPG","nameAlias":"","pcEnfPref":"unenforced","pcTag":"10932","pcTagAllocSrc":"idmanager","prefGrMemb":"include","prio":"level3","scope":"2818049","shutdown":"no","status":"","triggerSt":"triggerable","txId":"15564440312192537861","uid":"15374","userdom":":all:"},"children":[ +{"fvRsProv": +{"attributes": +{"accessPrivilege":"USER","annotation":"","childAction":"","ctrctUpd":"ctrct","extMngdBy":"","forceResolve":"yes","intent":"install","lcOwn":"local","matchT":"AtleastOne","modTs":"2025-07-20T00:45:30.670+00:00","monPolDn":"uni/tn-common/monepg-default","prio":"unspecified","rType":"mo","rn":"rsprov-BackEnd_Ctrt","state":"formed","stateQual":"none","status":"","tCl":"vzBrCP","tContextDn":"","tDn":"uni/tn-vavictor_TenantA/brc-BackEnd_Ctrt","tRn":"brc-BackEnd_Ctrt","tType":"name","tnVzBrCPName":"BackEnd_Ctrt","triggerSt":"triggerable","uid":"13299","updateCollection":"no","userdom":":"}}}, +{"fvRsProv": +{"attributes": +{"accessPrivilege":"USER","annotation":"","childAction":"","ctrctUpd":"ctrct","extMngdBy":"","forceResolve":"yes","intent":"install","lcOwn":"local","matchT":"AtleastOne","modTs":"2025-07-20T00:45:30.670+00:00","monPolDn":"uni/tn-common/monepg-default","prio":"unspecified","rType":"mo","rn":"rsprov-L3Out_Ctrt","state":"formed","stateQual":"none","status":"","tCl":"vzBrCP","tContextDn":"","tDn":"uni/tn-vavictor_TenantA/brc-L3Out_Ctrt","tRn":"brc-L3Out_Ctrt","tType":"name","tnVzBrCPName":"L3Out_Ctrt","triggerSt":"triggerable","uid":"15374","updateCollection":"no","userdom":":all:"}}}, +{"fvRsProv": +{"attributes": +{"accessPrivilege":"USER","annotation":"","childAction":"","ctrctUpd":"ctrct","extMngdBy":"","forceResolve":"yes","intent":"install","lcOwn":"local","matchT":"AtleastOne","modTs":"2025-07-20T00:45:30.670+00:00","monPolDn":"uni/tn-common/monepg-default","prio":"unspecified","rType":"mo","rn":"rsprov-FrontEnd_Ctrt","state":"formed","stateQual":"none","status":"","tCl":"vzBrCP","tContextDn":"","tDn":"uni/tn-vavictor_TenantA/brc-FrontEnd_Ctrt","tRn":"brc-FrontEnd_Ctrt","tType":"name","tnVzBrCPName":"FrontEnd_Ctrt","triggerSt":"triggerable","uid":"15374","updateCollection":"no","userdom":":all:"}}}, +{"fvRsProv": +{"attributes": +{"accessPrivilege":"USER","annotation":"","childAction":"","ctrctUpd":"ctrct","extMngdBy":"","forceResolve":"yes","intent":"install","lcOwn":"local","matchT":"AtleastOne","modTs":"2025-07-20T00:45:30.670+00:00","monPolDn":"uni/tn-common/monepg-default","prio":"unspecified","rType":"mo","rn":"rsprov-vavictor_from_Scan","state":"formed","stateQual":"none","status":"","tCl":"vzBrCP","tContextDn":"","tDn":"uni/tn-common/brc-vavictor_from_Scan","tRn":"brc-vavictor_from_Scan","tType":"name","tnVzBrCPName":"vavictor_from_Scan","triggerSt":"triggerable","uid":"15374","updateCollection":"no","userdom":":all:"}}}]}}, +{"fvAEPg": +{"attributes": +{"annotation":"","childAction":"","configIssues":"","configSt":"applied","descr":"","dn":"uni/tn-vavictor_TenantA/ap-eApp_AP/epg-Web_EPG","exceptionTag":"","extMngdBy":"","floodOnEncap":"disabled","fwdCtrl":"","hasMcastSource":"no","isAttrBasedEPg":"no","isSharedSrvMsiteEPg":"no","lcOwn":"local","matchT":"AtleastOne","modTs":"2025-04-20T20:22:26.475+00:00","monPolDn":"uni/tn-common/monepg-default","name":"Web_EPG","nameAlias":"","pcEnfPref":"unenforced","pcTag":"5476","pcTagAllocSrc":"idmanager","prefGrMemb":"include","prio":"level3","scope":"2818049","shutdown":"no","status":"","triggerSt":"triggerable","txId":"15564440312192537861","uid":"15374","userdom":":all:"},"children":[ +{"fvRsProv": +{"attributes": +{"accessPrivilege":"USER","annotation":"","childAction":"","ctrctUpd":"ctrct","extMngdBy":"","forceResolve":"yes","intent":"install","lcOwn":"local","matchT":"AtleastOne","modTs":"2025-04-20T20:22:26.475+00:00","monPolDn":"uni/tn-common/monepg-default","prio":"unspecified","rType":"mo","rn":"rsprov-EPG_2_uSeg_Ctrt","state":"formed","stateQual":"none","status":"","tCl":"vzBrCP","tContextDn":"","tDn":"uni/tn-vavictor_TenantA/brc-EPG_2_uSeg_Ctrt","tRn":"brc-EPG_2_uSeg_Ctrt","tType":"name","tnVzBrCPName":"EPG_2_uSeg_Ctrt","triggerSt":"triggerable","uid":"15374","updateCollection":"no","userdom":":all:"}}}, +{"fvRsProv": +{"attributes": +{"accessPrivilege":"USER","annotation":"","childAction":"","ctrctUpd":"ctrct","extMngdBy":"","forceResolve":"yes","intent":"install","lcOwn":"local","matchT":"AtleastOne","modTs":"2025-04-20T20:22:26.475+00:00","monPolDn":"uni/tn-common/monepg-default","prio":"unspecified","rType":"mo","rn":"rsprov-L3Out_Ctrt","state":"formed","stateQual":"none","status":"","tCl":"vzBrCP","tContextDn":"","tDn":"uni/tn-vavictor_TenantA/brc-L3Out_Ctrt","tRn":"brc-L3Out_Ctrt","tType":"name","tnVzBrCPName":"L3Out_Ctrt","triggerSt":"triggerable","uid":"15374","updateCollection":"no","userdom":":all:"}}}, +{"fvRsProv": +{"attributes": +{"accessPrivilege":"USER","annotation":"","childAction":"","ctrctUpd":"ctrct","extMngdBy":"","forceResolve":"yes","intent":"install","lcOwn":"local","matchT":"AtleastOne","modTs":"2025-04-20T21:41:40.628+00:00","monPolDn":"uni/tn-common/monepg-default","prio":"unspecified","rType":"mo","rn":"rsprov-vavictor_from_Scan","state":"formed","stateQual":"none","status":"","tCl":"vzBrCP","tContextDn":"","tDn":"uni/tn-common/brc-vavictor_from_Scan","tRn":"brc-vavictor_from_Scan","tType":"name","tnVzBrCPName":"vavictor_from_Scan","triggerSt":"triggerable","uid":"15374","updateCollection":"no","userdom":":all:"}}}]}}] \ No newline at end of file diff --git a/tests/pg_and_shared_svc_contract_check/global_pg_l3extInstP.json b/tests/pg_and_shared_svc_contract_check/global_pg_l3extInstP.json new file mode 100644 index 00000000..98ffc9f3 --- /dev/null +++ b/tests/pg_and_shared_svc_contract_check/global_pg_l3extInstP.json @@ -0,0 +1,3 @@ +[ +{"l3extInstP":{"attributes":{"annotation":"","childAction":"","configIssues":"","configSt":"applied","descr":"","dn":"uni/tn-common/out-test-L3Out/instP-testExtEPG","exceptionTag":"","extMngdBy":"","floodOnEncap":"disabled","isSharedSrvMsiteEPg":"no","lcOwn":"local","matchT":"AtleastOne","mcast":"no","modTs":"2025-08-11T18:14:54.961+00:00","monPolDn":"uni/tn-common/monepg-default","name":"testExtEPG","nameAlias":"","pcEnfPref":"unenforced","pcTag":"10953","pcTagAllocSrc":"idmanager","prefGrMemb":"include","prio":"unspecified","scope":"2490368","status":"","targetDscp":"unspecified","triggerSt":"triggerable","txId":"1729382256913953508","uid":"15374","userdom":":all:"}, +"children":[{"fvRsProv":{"attributes":{"accessPrivilege":"USER","annotation":"","childAction":"","ctrctUpd":"ctrct","extMngdBy":"","forceResolve":"yes","intent":"install","lcOwn":"local","matchT":"AtleastOne","modTs":"2025-08-11T18:14:54.961+00:00","monPolDn":"uni/tn-common/monepg-default","prio":"unspecified","rType":"mo","rn":"rsprov-AD_C","state":"formed","stateQual":"none","status":"","tCl":"vzBrCP","tContextDn":"","tDn":"uni/tn-common/brc-AD_C","tRn":"brc-AD_C","tType":"name","tnVzBrCPName":"AD_C","triggerSt":"triggerable","uid":"15374","updateCollection":"no","userdom":":all:"}}}]}}] \ No newline at end of file diff --git a/tests/pg_and_shared_svc_contract_check/global_vzBrCP_pos.json b/tests/pg_and_shared_svc_contract_check/global_vzBrCP_pos.json new file mode 100644 index 00000000..ea548bf7 --- /dev/null +++ b/tests/pg_and_shared_svc_contract_check/global_vzBrCP_pos.json @@ -0,0 +1,24 @@ +[ + {"vzBrCP":{ + "attributes":{ + "accessPrivilege":"USER", + "annotation":"", + "childAction":"", + "configIssues":"", + "descr":"", + "dn":"uni/tn-common/brc-AD_C", + "name":"AD_C", + "scope":"global" + } + } + }, + {"vzBrCP":{ + "attributes":{ + "accessPrivilege":"USER", + "dn":"uni/tn-laumende/brc-test", + "name":"test", + "scope":"global" + } + } + } + ] \ No newline at end of file diff --git a/tests/pg_and_shared_svc_contract_check/test_pg_and_shared_svc_contract_check.py b/tests/pg_and_shared_svc_contract_check/test_pg_and_shared_svc_contract_check.py new file mode 100644 index 00000000..e271870d --- /dev/null +++ b/tests/pg_and_shared_svc_contract_check/test_pg_and_shared_svc_contract_check.py @@ -0,0 +1,147 @@ +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 +# shared contracts +shrd_contracts_api = 'vzBrCP.json' +shrd_contracts_api += '?query-target-filter=and(eq(vzBrCP.scope,"global"))' + +# global epgs ( 16 <= pgtag <= 16385) with Preferred group enabled with provided contracts + +glbl_epgs_api = 'fvAEPg.json' +glbl_epgs_api += '?query-target-filter=and(le(fvAEPg.pcTag,"16385"),ge(fvAEPg.pcTag,"16"),eq(fvAEPg.prefGrMemb,"include"))' +glbl_epgs_api += '&rsp-subtree=children&rsp-subtree-class=fvRsProv' + +# global external Epgs ( 16 <= pgtag <= 16385) with Preferred group enabled with provided contracts + +glbl_ext_epgs_api = 'l3extInstP.json' +glbl_ext_epgs_api += '?query-target-filter=and(le(l3extInstP.pcTag,"16385"),ge(l3extInstP.pcTag,"16"),eq(l3extInstP.prefGrMemb,"include"))' +glbl_ext_epgs_api += '&rsp-subtree=children&rsp-subtree-class=fvRsProv' + + +@pytest.mark.parametrize( + "icurl_outputs, cversion, tversion, expected_result", + [ + + # MANUAL cases + ( + { + shrd_contracts_api: read_data(dir, "global_vzBrCP_pos.json"), + glbl_epgs_api: read_data(dir, "global_pg_fvAEPg.json"), + glbl_ext_epgs_api: read_data(dir, "global_pg_l3extInstP.json") + }, + "4.2(4a)", None, + script.MANUAL, + ), + # NA cases + # Target version is lower than 4.2(6d), Result = NA + ( + { + shrd_contracts_api: read_data(dir, "global_vzBrCP_pos.json"), + glbl_epgs_api: read_data(dir, "global_pg_fvAEPg.json"), + glbl_ext_epgs_api: read_data(dir, "global_pg_l3extInstP.json") + }, + "4.2(1a)", "4.2(6c)", + script.NA, + ), + # Target version is lower than 5.1(1h), Result = NA + ( + { + shrd_contracts_api: read_data(dir, "global_vzBrCP_pos.json"), + glbl_epgs_api: read_data(dir, "global_pg_fvAEPg.json"), + glbl_ext_epgs_api: read_data(dir, "global_pg_l3extInstP.json") + }, + "4.2(1a)", "5.1(1g)", + script.NA, + ), + # There are no global contracts, Result = NA + ( + { + shrd_contracts_api: [], + glbl_epgs_api: read_data(dir, "global_pg_fvAEPg.json"), + glbl_ext_epgs_api: read_data(dir, "global_pg_l3extInstP.json") + }, + "4.2(1a)", "6.1(1g)", + script.NA, + ), + # FAIL_O Cases + # Target version is older than 6.0(1g), Result = FAIL_O + ( + { + shrd_contracts_api: read_data(dir, "global_vzBrCP_pos.json"), + glbl_epgs_api: read_data(dir, "global_pg_fvAEPg.json"), + glbl_ext_epgs_api: read_data(dir, "global_pg_l3extInstP.json") + }, + "4.2(1a)", "6.0(1f)", + script.FAIL_O, + ), + # Target version is newer than 6.0(1g), both global_pg EPGs and extEPGs , Result = FAIL_O + ( + { + shrd_contracts_api: read_data(dir, "global_vzBrCP_pos.json"), + glbl_epgs_api: read_data(dir, "global_pg_fvAEPg.json"), + glbl_ext_epgs_api: read_data(dir, "global_pg_l3extInstP.json") + }, + "4.2(1a)", "6.0(1g)", + script.FAIL_O, + ), + # Target version is newer than 6.0(1g), no EPGS, only global_pg extEPGs , Result = FAIL_O + ( + { + shrd_contracts_api: read_data(dir, "global_vzBrCP_pos.json"), + glbl_epgs_api: [], + glbl_ext_epgs_api: read_data(dir, "global_pg_l3extInstP.json") + }, + "4.2(1a)", "6.0(1g)", + script.FAIL_O, + ), + # PASS Cases + # Target version is older than 6.0(1g), no global_pg EPGs or extEPGs , Result = PASS + ( + { + shrd_contracts_api: read_data(dir, "global_vzBrCP_pos.json"), + glbl_epgs_api: [], + glbl_ext_epgs_api: [] + }, + "4.2(1a)", "6.0(1f)", + script.PASS, + ), + # Target version is newer than 6.0(1g), no global_pg EPGs or extEPGs , Result = PASS + ( + { + shrd_contracts_api: read_data(dir, "global_vzBrCP_pos.json"), + glbl_epgs_api: [], + glbl_ext_epgs_api: [] + }, + "4.2(1a)", "6.0(1h)", + script.PASS, + ), + # Target version is newer than 6.0(1g), only global_pg EPGs , no global_pg extEPGs , Result = PASS + ( + { + shrd_contracts_api: read_data(dir, "global_vzBrCP_pos.json"), + glbl_epgs_api: read_data(dir, "global_pg_fvAEPg.json"), + glbl_ext_epgs_api: [] + }, + "4.2(1a)", "6.0(1h)", + script.PASS, + ), + ] +) +def test_logic(mock_icurl, cversion, tversion, expected_result): + result = script.pg_and_shared_svc_contract_check( + 1, + 1, + script.AciVersion(cversion), + script.AciVersion(tversion) if tversion else None + ) + assert result == expected_result