From eae03179d46fc63df7ae5e3e1ffc89635c2b4a4d Mon Sep 17 00:00:00 2001 From: samitab Date: Thu, 19 Oct 2023 20:47:30 +1000 Subject: [PATCH 1/8] [minor change] Add support for annotation in aci_rest module (#437) --- plugins/modules/aci_rest.py | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/plugins/modules/aci_rest.py b/plugins/modules/aci_rest.py index ad73cb5bd..4e2442cb4 100644 --- a/plugins/modules/aci_rest.py +++ b/plugins/modules/aci_rest.py @@ -3,6 +3,7 @@ # Copyright: (c) 2017, Dag Wieers (@dagwieers) # Copyright: (c) 2020, Cindy Zhao (@cizhao) +# Copyright: (c) 2023, Samita Bhattacharjee (@samitab) # GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) from __future__ import absolute_import, division, print_function @@ -62,6 +63,7 @@ default: false extends_documentation_fragment: - cisco.aci.aci +- cisco.aci.annotation notes: - Certain payloads are known not to be idempotent, so be careful when constructing payloads, @@ -73,6 +75,7 @@ - XML payloads require the C(lxml) and C(xmljson) python libraries. For JSON payloads nothing special is needed. - If you do not have any attributes, it may be necessary to add the "attributes" key with an empty dictionnary "{}" for value as the APIC does expect the entry to precede any children. +- Annotation set directly in c(src) or C(content) will take precedent over the C(annotation) parameter. seealso: - module: cisco.aci.aci_tenant - name: Cisco APIC REST API Configuration Guide @@ -81,6 +84,7 @@ author: - Dag Wieers (@dagwieers) - Cindy Zhao (@cizhao) +- Samita Bhattacharjee (@samitab) """ EXAMPLES = r""" @@ -284,7 +288,7 @@ HAS_YAML = False from ansible.module_utils.basic import AnsibleModule -from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec +from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec, aci_annotation_spec from ansible.module_utils._text import to_text @@ -303,6 +307,24 @@ def update_qsl(url, params): return url + "?" + "&".join(["%s=%s" % (k, v) for k, v in params.items()]) +def add_annotation(annotation, payload): + """Add annotation to payload only if it has not already been added""" + if annotation: + for val in payload.values(): + att = val.get("attributes", {}) + if "annotation" not in att.keys(): + att["annotation"] = annotation + + +def add_annotation_xml(annotation, tree): + """Add annotation to payload xml only if it has not already been added""" + if annotation: + for element in tree.iter(): + ann = element.get("annotation") + if ann is None: + element.set("annotation", annotation) + + class ACIRESTModule(ACIModule): def changed(self, d): """Check ACI response for changes""" @@ -335,6 +357,7 @@ def response_type(self, rawoutput, rest_type="xml"): def main(): argument_spec = aci_argument_spec() + argument_spec.update(aci_annotation_spec()) argument_spec.update( path=dict(type="str", required=True, aliases=["uri"]), method=dict(type="str", default="get", choices=["delete", "get", "post"], aliases=["action"]), @@ -353,6 +376,7 @@ def main(): path = module.params.get("path") src = module.params.get("src") rsp_subtree_preserve = module.params.get("rsp_subtree_preserve") + annotation = module.params.get("annotation") # Report missing file file_exists = False @@ -388,21 +412,27 @@ def main(): if rest_type == "json": if content and isinstance(content, dict): # Validate inline YAML/JSON + add_annotation(annotation, payload) payload = json.dumps(payload) elif payload and isinstance(payload, str) and HAS_YAML: try: # Validate YAML/JSON string - payload = json.dumps(yaml.safe_load(payload)) + payload = yaml.safe_load(payload) + add_annotation(annotation, payload) + payload = json.dumps(payload) except Exception as e: module.fail_json(msg="Failed to parse provided JSON/YAML payload: {0}".format(to_text(e)), exception=to_text(e), payload=payload) elif rest_type == "xml" and HAS_LXML_ETREE: if content and isinstance(content, dict) and HAS_XMLJSON_COBRA: # Validate inline YAML/JSON + add_annotation(annotation, payload) payload = etree.tostring(cobra.etree(payload)[0], encoding="unicode") elif payload and isinstance(payload, str): try: # Validate XML string - payload = etree.tostring(etree.fromstring(payload), encoding="unicode") + payload = etree.fromstring(payload) + add_annotation_xml(annotation, payload) + payload = etree.tostring(payload, encoding="unicode") except Exception as e: module.fail_json(msg="Failed to parse provided XML payload: {0}".format(to_text(e)), payload=payload) From b5986c0eb6d39647ea04a2d48d04d999c65e6e8a Mon Sep 17 00:00:00 2001 From: samitab Date: Fri, 20 Oct 2023 19:52:14 +1000 Subject: [PATCH 2/8] [ignore] Handle classes that don't support annotation --- plugins/modules/aci_rest.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plugins/modules/aci_rest.py b/plugins/modules/aci_rest.py index 4e2442cb4..20d4f942f 100644 --- a/plugins/modules/aci_rest.py +++ b/plugins/modules/aci_rest.py @@ -291,6 +291,8 @@ from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec, aci_annotation_spec from ansible.module_utils._text import to_text +ANNOTATION_UNSUPPORTED = ["tagTag"] + def update_qsl(url, params): """Add or update a URL query string""" @@ -310,7 +312,9 @@ def update_qsl(url, params): def add_annotation(annotation, payload): """Add annotation to payload only if it has not already been added""" if annotation: - for val in payload.values(): + for key, val in payload.items(): + if key in ANNOTATION_UNSUPPORTED: + return att = val.get("attributes", {}) if "annotation" not in att.keys(): att["annotation"] = annotation @@ -320,6 +324,8 @@ def add_annotation_xml(annotation, tree): """Add annotation to payload xml only if it has not already been added""" if annotation: for element in tree.iter(): + if element.tag in ANNOTATION_UNSUPPORTED: + return ann = element.get("annotation") if ann is None: element.set("annotation", annotation) From 8c5085f07cec9da8fa4029e7a86bf2a0f17e62a6 Mon Sep 17 00:00:00 2001 From: samitab Date: Wed, 25 Oct 2023 07:26:29 +1000 Subject: [PATCH 3/8] [ignore] Added all unsupported annotation classes. --- .../module_utils/annotation_unsupported.py | 832 ++++++++++++++++++ plugins/modules/aci_rest.py | 5 +- 2 files changed, 835 insertions(+), 2 deletions(-) create mode 100644 plugins/module_utils/annotation_unsupported.py diff --git a/plugins/module_utils/annotation_unsupported.py b/plugins/module_utils/annotation_unsupported.py new file mode 100644 index 000000000..469be2bae --- /dev/null +++ b/plugins/module_utils/annotation_unsupported.py @@ -0,0 +1,832 @@ +ANNOTATION_UNSUPPORTED = [ + "aaaADomainRef", + "aaaAProvider", + "aaaARbacRule", + "aaaARetP", + "aaaAuthMethod", + "aaaBanner", + "aaaConfig", + "aaaDefinition", + "aaaEp", + "aaaProviderGroup", + "aaaRbacAnnotation", + "aaaRealm", + "aaaSystemUser", + "aaaUserAction", + "aclACL", + "aclL3ACE", + "actionACont", + "adcomARwi", + "adcomARwiAdvanced", + "adcomATsInfoUnit", + "adepgACont", + "adepgAElement", + "adepgAOrgUnit", + "adepgAResElement", + "adepgContE", + "adepgEntity", + "analyticsACfgSrv", + "analyticsACluster", + "analyticsRemoteNode", + "analyticsTarget", + "apDockerName", + "apPluginName", + "arpAIfPol", + "authASvr", + "authASvrGroup", + "authBaseUsrAccP", + "bfdAIfP", + "bfdAIfPol", + "bfdAInstPol", + "bfdAMhIfPol", + "bfdAMhInstPol", + "bfdAMhNodePol", + "bfdAMicroBfdP", + "bfdANodeP", + "bgpAAsP", + "bgpACtxAfPol", + "bgpACtxPol", + "bgpADomainIdBase", + "bgpAExtP", + "bgpALocalAsnP", + "bgpAPeerP", + "bgpAPeerPfxPol", + "bgpARRP", + "bgpARtTarget", + "bgpARtTargetInstrP", + "bgpARtTargetP", + "bgpASiteOfOriginP", + "callhomeADest", + "callhomeAGroup", + "callhomeASrc", + "cdpAIfPol", + "cloudAAEPg", + "cloudAAFilter", + "cloudAApicSubnet", + "cloudAApicSubnetPool", + "cloudAAwsFlowLogPol", + "cloudAAwsLogGroup", + "cloudAAwsProvider", + "cloudABaseEPg", + "cloudABdiId", + "cloudABgpAsP", + "cloudABgpPeerP", + "cloudABrownfield", + "cloudACertStore", + "cloudACertificate", + "cloudACidr", + "cloudACloudSvcEPg", + "cloudAComputePol", + "cloudAController", + "cloudACtxProfile", + "cloudACtxUnderlayP", + "cloudADomP", + "cloudAEPSelector", + "cloudAEPSelectorDef", + "cloudAExtNetworkP", + "cloudAFrontendIPv4Addr", + "cloudAGatewayRouterP", + "cloudAHealthProbe", + "cloudAHostBootstrapPol", + "cloudAHostIfP", + "cloudAHostRouterPol", + "cloudAIntNetworkP", + "cloudAIpSecTunnelIfP", + "cloudAIpv4AddrP", + "cloudAL3IfP", + "cloudAL3IntTunnelIfP", + "cloudAL3TunnelIfP", + "cloudALDev", + "cloudALIf", + "cloudAListener", + "cloudAListenerRule", + "cloudALoopbackIfP", + "cloudAMapping", + "cloudAMgmtPol", + "cloudANWParams", + "cloudANextHopIp", + "cloudAOspfAreaP", + "cloudAOspfIfP", + "cloudAParamPol", + "cloudAPool", + "cloudAProvResP", + "cloudAProvider", + "cloudARouterP", + "cloudARuleAction", + "cloudARuleCondition", + "cloudASelectedEP", + "cloudASubnet", + "cloudASvcEPg", + "cloudASvcPol", + "cloudATransitHubGwPol", + "cloudAVip", + "cloudAVirtualWanP", + "cloudAVpnGwPol", + "cloudAVpnNetworkP", + "cloudAVrfRouteLeakPol", + "cloudsecACapability", + "cloudsecAControl", + "cloudsecASaKeyP", + "cloudsecASaKeyPLocal", + "cloudsecASaKeyPRemote", + "cloudsecASaKeyStatus", + "cloudsecASaKeyStatusLocal", + "cloudsecASaKeyStatusRemote", + "cloudsecASpKeySt", + "cloudtemplateASubnetPool", + "commComp", + "commDefinition", + "commShell", + "commWeb", + "compAHvHealth", + "compAPltfmP", + "compAPvlanP", + "compASvcVM", + "compAVmmPltfmP", + "compAVmmSecP", + "compAccessP", + "compCont", + "compContE", + "compCtrlrP", + "compDomP", + "compElement", + "compEntity", + "compHost", + "compNameIdentEntity", + "compNic", + "compObj", + "compPHost", + "compPNic", + "compProvP", + "compUsrAccP", + "conditionCondP", + "conditionInfo", + "conditionLoggable", + "conditionRecord", + "conditionRetP", + "conditionSevAsnP", + "conditionSummary", + "configABackupP", + "coppACustomValues", + "coppAProfile", + "ctrlrDom", + "datetimeANtpAuthKey", + "datetimeANtpIFFKey", + "datetimeANtpProv", + "datetimeAPol", + "dbgACRulePCommon", + "dbgANodeInst", + "dbgacEpgCmn", + "dbgacFromEpCmn", + "dbgacFromEpgCmn", + "dbgacTenantSpaceCmn", + "dbgacToEpCmn", + "dbgacToEpgCmn", + "dbgexpExportP", + "dbgexpNodeStatus", + "dbgexpTechSupOnDBase", + "dhcpAInfraProvP", + "dhcpALbl", + "dhcpARelayP", + "dhcpAddr", + "dhcpNode", + "dhcpResp", + "dnsADomain", + "dnsALbl", + "dnsAProfile", + "dnsAProv", + "dnsepgADomain", + "dnsepgAMgmt", + "dnsepgASvr", + "dnsepgASvrGrp", + "dnsepgFault", + "dwdmAOptChnlIfPol", + "edmACapFlags", + "edmAOperCont", + "edmAStatsCont", + "edmCont", + "edmContE", + "edmElement", + "edmEntity", + "edmGroupP", + "edmMgrP", + "edmObj", + "eigrpAAuthIfP", + "eigrpACtxAfPol", + "eigrpAExtP", + "eigrpAIfP", + "eigrpAStubP", + "eptrkEpRslt", + "eqptALPort", + "eqptdiagpASynthObj", + "eqptdiagpCardTestSetOd", + "eqptdiagpExtChCardTsOd", + "eqptdiagpFcTsOd", + "eqptdiagpFpTsOd", + "eqptdiagpHealthPol", + "eqptdiagpLcTsOd", + "eqptdiagpLpTsOd", + "eqptdiagpPol", + "eqptdiagpPortTestSetBt", + "eqptdiagpPortTestSetHl", + "eqptdiagpPortTestSetOd", + "eqptdiagpSupCTsOd", + "eqptdiagpSysCTsOd", + "eqptdiagpTestSet", + "eqptdiagpTestSetBoot", + "eqptdiagpTestSetHealth", + "eqptdiagpTestSetOd", + "eventARetP", + "extdevSDWanASlaPol", + "extnwAInstPSubnet", + "extnwALIfP", + "extnwALNodeP", + "extnwDomP", + "extnwEPg", + "extnwOut", + "fabricACardPGrp", + "fabricACardS", + "fabricALink", + "fabricANode", + "fabricANodeBlk", + "fabricANodePEp", + "fabricANodePGrp", + "fabricANodeS", + "fabricAONodeS", + "fabricAOOSReln", + "fabricAPathIssues", + "fabricAPathS", + "fabricAPodBlk", + "fabricAPodS", + "fabricAPolGrp", + "fabricAPortBlk", + "fabricAPortPGrp", + "fabricAPortS", + "fabricAProfile", + "fabricAProtPol", + "fabricASubPortBlk", + "fabricCardP", + "fabricCardS", + "fabricComp", + "fabricDef", + "fabricDom", + "fabricInfrExP", + "fabricInfrP", + "fabricIntfPol", + "fabricL1IfPol", + "fabricL2BDPol", + "fabricL2DomPol", + "fabricL2IfPol", + "fabricL2InstPol", + "fabricL2PortSecurityPol", + "fabricL2ProtoComp", + "fabricL2ProtoPol", + "fabricL3CtxPol", + "fabricL3DomPol", + "fabricL3IfPol", + "fabricL3InstPol", + "fabricL3ProtoComp", + "fabricL3ProtoPol", + "fabricL4IfPol", + "fabricLeAPortPGrp", + "fabricMaintPol", + "fabricNodeGrp", + "fabricNodeP", + "fabricNodeS", + "fabricNodeToPathOverridePolicy", + "fabricNodeToPolicy", + "fabricPodGrp", + "fabricPol", + "fabricPolGrp", + "fabricPolicyGrpToMonitoring", + "fabricPortP", + "fabricPortS", + "fabricProfile", + "fabricProtoComp", + "fabricProtoConsFrom", + "fabricProtoConsTo", + "fabricProtoDomPol", + "fabricProtoIfPol", + "fabricProtoInstPol", + "fabricProtoPol", + "fabricQinqIfPol", + "fabricSelector", + "fabricSpAPortPGrp", + "fabricUtilInstPol", + "fabricVxlanInstPol", + "faultARetP", + "faultARsToRemote", + "faultAThrValue", + "faultInfo", + "fcAPinningLbl", + "fcAPinningP", + "fcprARs", + "fileARemoteHost", + "fileARemotePath", + "firmwareAFwP", + "firmwareAFwStatusCont", + "firmwareARunning", + "firmwareSource", + "frmwrkARelDelCont", + "frmwrkARelDelControl", + "fvAACrtrn", + "fvAAKeyChainPol", + "fvAAKeyPol", + "fvAAREpPUpdate", + "fvABD", + "fvABDPol", + "fvAClassifier", + "fvACont", + "fvACrRule", + "fvACrtrn", + "fvACtx", + "fvACtxRtSummPol", + "fvADeplCont", + "fvADnsAttr", + "fvADomP", + "fvADyAttr", + "fvAEPSelector", + "fvAEPSelectorDef", + "fvAEPgPathAtt", + "fvAEpAnycast", + "fvAEpDef", + "fvAEpNlb", + "fvAEpRetPol", + "fvAEpTag", + "fvAEpTaskAggr", + "fvAExtRoutableRemoteSitePodSubnet", + "fvAExtRoutes", + "fvAFBRGroup", + "fvAFBRMember", + "fvAFBRoute", + "fvAFabricExpRtctrlP", + "fvAFabricExtConnP", + "fvAIdAttr", + "fvAIntersiteConnP", + "fvAIntersiteConnPDef", + "fvAIntraVrfFabricImpRtctrlP", + "fvAIpAttr", + "fvAKeyChainPol", + "fvAKeyPol", + "fvAMacAttr", + "fvANode", + "fvAPeeringP", + "fvAPodConnP", + "fvAProtoAttr", + "fvAREpPCtrct", + "fvARogueExceptionMac", + "fvARsToRemote", + "fvARsToRemoteFC", + "fvARtSummSubnet", + "fvASCrtrn", + "fvASDWanPrefixTaskAggr", + "fvASiteConnP", + "fvAStAttr", + "fvAStCEp", + "fvAStIp", + "fvATg", + "fvAToBD", + "fvATp", + "fvAUsegAssocBD", + "fvAVip", + "fvAVmAttr", + "fvAttr", + "fvCEPg", + "fvComp", + "fvDef", + "fvDom", + "fvEPg", + "fvEPgToCollection", + "fvEPgToInterface", + "fvEp", + "fvFrom", + "fvL2Dom", + "fvL3Dom", + "fvNp", + "fvNwEp", + "fvPEp", + "fvRtScopeFrom", + "fvSyntheticIp", + "fvTo", + "fvUp", + "fvnsAAddrBlk", + "fvnsAAddrInstP", + "fvnsAEncapBlk", + "fvnsAInstP", + "fvnsAVlanInstP", + "fvnsAVsanInstP", + "fvnsAVxlanInstP", + "genericsARule", + "haHaTest", + "hcloudAExtPfx", + "hcloudAIntPfx", + "hcloudALeakedPfx", + "hcloudASvcResBase", + "hcloudATgStats", + "hcloudRouterStateOper", + "healthAInst", + "healthARetP", + "hostprotASubj", + "hsrpAGroupP", + "hsrpAGroupPol", + "hsrpAIfP", + "hsrpAIfPol", + "hsrpASecVip", + "hvsContE", + "hvsNode", + "hvsUsegContE", + "iaclAProfile", + "igmpAIfP", + "igmpASnoopAccessGroup", + "igmpASnoopPol", + "igmpASnoopStaticGroup", + "infraAAccBndlGrp", + "infraAAccGrp", + "infraACEPg", + "infraACEp", + "infraADomP", + "infraAFcAccBndlGrp", + "infraAFunc", + "infraAIpP", + "infraANode", + "infraANodeP", + "infraANodeS", + "infraAONodeS", + "infraAPEPg", + "infraAPEp", + "infraAPathS", + "infraAccBaseGrp", + "infraAccGrp", + "infraDomP", + "infraDomainToNs", + "infraEPg", + "infraExP", + "infraFcAccGrp", + "infraFexBlk", + "infraFexGrp", + "infraGeNode", + "infraGeSnNode", + "infraLbl", + "infraNodeGrp", + "infraNodeS", + "infraPodGrp", + "infraPolGrp", + "infraPortP", + "infraPortS", + "infraProfile", + "infraSpAccGrp", + "infraToAInstP", + "ipANexthopEpP", + "ipANexthopP", + "ipARouteP", + "ipmcACtxPol", + "ipmcAIfPol", + "ipmcARepPol", + "ipmcASSMXlateP", + "ipmcAStRepPol", + "ipmcAStateLPol", + "ipmcsnoopMcSrc", + "ipmcsnoopRtrIf", + "ipmcsnoopTgtIf", + "ipsecAIsakmpPhase1Pol", + "ipsecAIsakmpPhase2Pol", + "l2AInstPol", + "l2extADomP", + "l2extAIfP", + "l2extAInstPSubnet", + "l2extALNodeP", + "l3extAConsLbl", + "l3extADefaultRouteLeakP", + "l3extADomP", + "l3extAFabricExtRoutingP", + "l3extAIfP", + "l3extAInstPSubnet", + "l3extAIp", + "l3extALNodeP", + "l3extAMember", + "l3extAProvLbl", + "l3extARouteTagPol", + "l4AVxlanInstPol", + "lacpAEnhancedLagPol", + "lacpALagPol", + "leakAPrefix", + "leakARouteCont", + "leakASubnet", + "lldpAIfPol", + "macsecAAIfPol", + "macsecAAKeyChainPol", + "macsecAAKeyPol", + "macsecAAParamPol", + "macsecAIfPol", + "macsecAKeyChainPol", + "macsecAKeyPol", + "macsecAParamPol", + "maintAMaintP", + "maintUserNotif", + "mcpAIfPol", + "mdpAClassId", + "mdpADomP", + "mdpADomainPeeringPol", + "mdpAEntity", + "mdpANodeP", + "mdpAPeeringDomain", + "mdpAService", + "mdpATenant", + "mgmtAInstPSubnet", + "mgmtAIp", + "mgmtAZone", + "mldASnoopAccessGroup", + "mldASnoopPol", + "mldASnoopStaticGroup", + "moASubj", + "moModifiable", + "moOwnable", + "moResolvable", + "moTopProps", + "monATarget", + "monExportP", + "monGroup", + "monPol", + "monProtoP", + "monSecAuthP", + "monSrc", + "monSubj", + "monTarget", + "mplsAExtP", + "mplsAIfP", + "mplsALabelPol", + "mplsANodeSidP", + "mplsASrgbLabelPol", + "namingNamedIdentifiedObject", + "namingNamedObject", + "ndAIfPol", + "ndAPfxPol", + "netflowAExporterPol", + "netflowAFabExporterPol", + "netflowAMonitorPol", + "netflowARecordPol", + "netflowARsInterfaceToMonitor", + "netflowARsMonitorToExporter", + "netflowARsMonitorToRecord", + "netflowAVmmExporterPol", + "nwsAFwPol", + "nwsASrc", + "nwsASyslogSrc", + "oamExec", + "orchsElement", + "orchsEntity", + "ospfACtxPol", + "ospfAExtP", + "ospfAIfP", + "pconsRef", + "pimAIfP", + "pingAExec", + "pkiDefinition", + "pkiItem", + "plannerADomainTmpl", + "plannerAEpg", + "plannerAEpgDomain", + "plannerAEpgFilter", + "plannerAObject", + "plannerATmpl", + "plannerIPs", + "poeAIfPol", + "polAConfIssues", + "polADependentOn", + "polAObjToPolReln", + "polAPrToPol", + "polAttTgt", + "polComp", + "polCompl", + "polComplElem", + "polConsElem", + "polConsIf", + "polConsLbl", + "polCont", + "polCtrlr", + "polDef", + "polDefRoot", + "polDom", + "polIf", + "polInstr", + "polLbl", + "polNFromRef", + "polNToRef", + "polNs", + "polObj", + "polProvIf", + "polProvLbl", + "polRelnHolder", + "poolElement", + "poolPool", + "poolPoolMember", + "poolPoolable", + "ptpAACfg", + "ptpACfg", + "ptpAProfile", + "qosABuffer", + "qosACong", + "qosADot1PClass", + "qosADppPol", + "qosADscpClass", + "qosADscpTrans", + "qosAMplsEgressRule", + "qosAMplsIngressRule", + "qosAQueue", + "qosASched", + "qosAUburst", + "qosClassification", + "qosMplsMarking", + "relnFrom", + "relnInst", + "relnTaskRef", + "relnTo", + "resolutionARsToRemote", + "rtctrlAAttrP", + "rtctrlAMatchAsPathRegexTerm", + "rtctrlAMatchCommFactor", + "rtctrlAMatchCommRegexTerm", + "rtctrlAMatchCommTerm", + "rtctrlAMatchIpRule", + "rtctrlAMatchRtType", + "rtctrlAMatchRule", + "rtctrlASetASPath", + "rtctrlASetASPathASN", + "rtctrlASetComm", + "rtctrlASetDamp", + "rtctrlASetNh", + "rtctrlASetNhUnchanged", + "rtctrlASetOspfFwdAddr", + "rtctrlASetOspfNssa", + "rtctrlASetPolicyTag", + "rtctrlASetPref", + "rtctrlASetRedistMultipath", + "rtctrlASetRtMetric", + "rtctrlASetRtMetricType", + "rtctrlASetRule", + "rtctrlASetTag", + "rtctrlASetWeight", + "rtctrlASubnet", + "rtdmcAASMPatPol", + "rtdmcAAutoRPPol", + "rtdmcABDFilter", + "rtdmcABDPol", + "rtdmcABSRFilter", + "rtdmcABSRPPol", + "rtdmcABidirPatPol", + "rtdmcACtxPol", + "rtdmcAExtP", + "rtdmcAFilterPol", + "rtdmcAIfPol", + "rtdmcAIfPolCont", + "rtdmcAInterVRFEntry", + "rtdmcAInterVRFPol", + "rtdmcAJPFilterPol", + "rtdmcAMAFilter", + "rtdmcANbrFilterPol", + "rtdmcAPatPol", + "rtdmcARPGrpRangePol", + "rtdmcARPPol", + "rtdmcARegTrPol", + "rtdmcAResPol", + "rtdmcARtMapEntry", + "rtdmcARtMapPol", + "rtdmcASGRangeExpPol", + "rtdmcASSMPatPol", + "rtdmcASSMRangePol", + "rtdmcASharedRangePol", + "rtdmcAStaticRPEntry", + "rtdmcAStaticRPPol", + "ruleDefinition", + "ruleItem", + "ruleRequirement", + "ruleSizeRequirement", + "snmpAClientGrpP", + "snmpAClientP", + "snmpACommunityP", + "snmpACtrlrInst", + "snmpACtxP", + "snmpAPol", + "snmpATrapFwdServerP", + "snmpAUserP", + "snmpUser", + "spanACEpDef", + "spanADest", + "spanASpanLbl", + "spanASrc", + "spanASrcGrp", + "spanAToCEp", + "spanAVDest", + "spanAVDestGrp", + "spanAVSrc", + "spanAVSrcGrp", + "statsAALbStats", + "statsAColl", + "statsANWStatsObj", + "statsANlbStats", + "statsAThrP", + "statsATunnel", + "statsDebugItem", + "statsItem", + "stpAIfPol", + "svccoreACore", + "svccorePol", + "synceAAIfPol", + "synceAIfPol", + "syntheticAContext", + "syntheticATestObj", + "syntheticCTestObj", + "syntheticObject", + "syntheticTLTestObj", + "sysdebugFile", + "sysdebugLogBehavior", + "sysdebugRepository", + "sysfileEp", + "sysfileInstance", + "sysfileRepository", + "tagASelector", + "tagAnnotation", + "tagTag", + "taskExec", + "telemetryAFlowServers", + "telemetryAFteEvents", + "telemetryAFteEventsExt", + "telemetryAFteEventsTcpFlags", + "telemetryARemoteServer", + "telemetryAServer", + "telemetryAServerP", + "telemetryAServerPol", + "telemetryAStreamEnable", + "throttlerASub", + "topRoot", + "tracerouteAExec", + "traceroutepTrP", + "trigATriggeredWindow", + "trigExecutable", + "trigInst", + "trigSchedWindow", + "trigSchedWindowP", + "trigSingleTriggerable", + "trigTriggerable", + "trigWindow", + "usegAUsegEPg", + "vmmACapInfo", + "vmmACapObj", + "vmmAUplinkP", + "vmmAUplinkPCont", + "vmmCFaultInfo", + "vmmEpgAggr", + "vmmInjectedObject", + "vnsACCfg", + "vnsACCfgRel", + "vnsAConn", + "vnsAConnection", + "vnsAEPpInfo", + "vnsAFolder", + "vnsAFuncConn", + "vnsAFuncNode", + "vnsAGraph", + "vnsAL4L7ServiceFault", + "vnsALDev", + "vnsALDevCtx", + "vnsALDevIf", + "vnsALDevLIf", + "vnsALIf", + "vnsALIfCtx", + "vnsAMgmt", + "vnsANode", + "vnsAParam", + "vnsATerm", + "vnsATermConn", + "vnsATermNode", + "vnsAVRoutingNetworks", + "vnsAbsTermNode", + "vnsDevItem", + "vnsLBReq", + "vnsNATReq", + "vnsOrchReq", + "vnsOrchResp", + "vsanARsVsanPathAtt", + "vsanARtVsanPathAtt", + "vsvcAConsLbl", + "vsvcAProvLbl", + "vzABrCP", + "vzACollection", + "vzACompLbl", + "vzACtrct", + "vzAFiltEntry", + "vzAFilter", + "vzAFilterable", + "vzAFilterableUnit", + "vzAIf", + "vzALbl", + "vzARuleOwner", + "vzASTerm", + "vzASubj", + "vzATerm", + "vzAnyToCollection", + "vzAnyToInterface", + "vzInterfaceToCollection", + "vzSubjectToFilter", + "vzToRFltP", +] \ No newline at end of file diff --git a/plugins/modules/aci_rest.py b/plugins/modules/aci_rest.py index 20d4f942f..2029330de 100644 --- a/plugins/modules/aci_rest.py +++ b/plugins/modules/aci_rest.py @@ -290,8 +290,9 @@ from ansible.module_utils.basic import AnsibleModule from ansible_collections.cisco.aci.plugins.module_utils.aci import ACIModule, aci_argument_spec, aci_annotation_spec from ansible.module_utils._text import to_text - -ANNOTATION_UNSUPPORTED = ["tagTag"] +from ansible_collections.cisco.aci.plugins.module_utils.annotation_unsupported import ( + ANNOTATION_UNSUPPORTED, +) def update_qsl(url, params): From 0f29c6f2cc678e63090540e5c65b5fbe08214773 Mon Sep 17 00:00:00 2001 From: samitab Date: Thu, 26 Oct 2023 08:02:26 +1000 Subject: [PATCH 4/8] [ignore] Add integration testing for annotation on aci_rest module --- .../module_utils/annotation_unsupported.py | 1664 ++++++++--------- .../targets/aci_rest/tasks/json_inline.yml | 103 + .../targets/aci_rest/tasks/json_string.yml | 103 + .../targets/aci_rest/tasks/xml_file.yml | 70 + .../targets/aci_rest/tasks/xml_files/tag.xml | 1 + .../xml_files/tn-ans_test_annotation.xml | 1 + .../targets/aci_rest/tasks/xml_string.yml | 93 +- .../targets/aci_rest/tasks/yaml_inline.yml | 87 + .../targets/aci_rest/tasks/yaml_string.yml | 87 + 9 files changed, 1376 insertions(+), 833 deletions(-) create mode 100644 tests/integration/targets/aci_rest/tasks/xml_files/tag.xml create mode 100644 tests/integration/targets/aci_rest/tasks/xml_files/tn-ans_test_annotation.xml diff --git a/plugins/module_utils/annotation_unsupported.py b/plugins/module_utils/annotation_unsupported.py index 469be2bae..2d7ca128a 100644 --- a/plugins/module_utils/annotation_unsupported.py +++ b/plugins/module_utils/annotation_unsupported.py @@ -1,832 +1,832 @@ -ANNOTATION_UNSUPPORTED = [ - "aaaADomainRef", - "aaaAProvider", - "aaaARbacRule", - "aaaARetP", - "aaaAuthMethod", - "aaaBanner", - "aaaConfig", - "aaaDefinition", - "aaaEp", - "aaaProviderGroup", - "aaaRbacAnnotation", - "aaaRealm", - "aaaSystemUser", - "aaaUserAction", - "aclACL", - "aclL3ACE", - "actionACont", - "adcomARwi", - "adcomARwiAdvanced", - "adcomATsInfoUnit", - "adepgACont", - "adepgAElement", - "adepgAOrgUnit", - "adepgAResElement", - "adepgContE", - "adepgEntity", - "analyticsACfgSrv", - "analyticsACluster", - "analyticsRemoteNode", - "analyticsTarget", - "apDockerName", - "apPluginName", - "arpAIfPol", - "authASvr", - "authASvrGroup", - "authBaseUsrAccP", - "bfdAIfP", - "bfdAIfPol", - "bfdAInstPol", - "bfdAMhIfPol", - "bfdAMhInstPol", - "bfdAMhNodePol", - "bfdAMicroBfdP", - "bfdANodeP", - "bgpAAsP", - "bgpACtxAfPol", - "bgpACtxPol", - "bgpADomainIdBase", - "bgpAExtP", - "bgpALocalAsnP", - "bgpAPeerP", - "bgpAPeerPfxPol", - "bgpARRP", - "bgpARtTarget", - "bgpARtTargetInstrP", - "bgpARtTargetP", - "bgpASiteOfOriginP", - "callhomeADest", - "callhomeAGroup", - "callhomeASrc", - "cdpAIfPol", - "cloudAAEPg", - "cloudAAFilter", - "cloudAApicSubnet", - "cloudAApicSubnetPool", - "cloudAAwsFlowLogPol", - "cloudAAwsLogGroup", - "cloudAAwsProvider", - "cloudABaseEPg", - "cloudABdiId", - "cloudABgpAsP", - "cloudABgpPeerP", - "cloudABrownfield", - "cloudACertStore", - "cloudACertificate", - "cloudACidr", - "cloudACloudSvcEPg", - "cloudAComputePol", - "cloudAController", - "cloudACtxProfile", - "cloudACtxUnderlayP", - "cloudADomP", - "cloudAEPSelector", - "cloudAEPSelectorDef", - "cloudAExtNetworkP", - "cloudAFrontendIPv4Addr", - "cloudAGatewayRouterP", - "cloudAHealthProbe", - "cloudAHostBootstrapPol", - "cloudAHostIfP", - "cloudAHostRouterPol", - "cloudAIntNetworkP", - "cloudAIpSecTunnelIfP", - "cloudAIpv4AddrP", - "cloudAL3IfP", - "cloudAL3IntTunnelIfP", - "cloudAL3TunnelIfP", - "cloudALDev", - "cloudALIf", - "cloudAListener", - "cloudAListenerRule", - "cloudALoopbackIfP", - "cloudAMapping", - "cloudAMgmtPol", - "cloudANWParams", - "cloudANextHopIp", - "cloudAOspfAreaP", - "cloudAOspfIfP", - "cloudAParamPol", - "cloudAPool", - "cloudAProvResP", - "cloudAProvider", - "cloudARouterP", - "cloudARuleAction", - "cloudARuleCondition", - "cloudASelectedEP", - "cloudASubnet", - "cloudASvcEPg", - "cloudASvcPol", - "cloudATransitHubGwPol", - "cloudAVip", - "cloudAVirtualWanP", - "cloudAVpnGwPol", - "cloudAVpnNetworkP", - "cloudAVrfRouteLeakPol", - "cloudsecACapability", - "cloudsecAControl", - "cloudsecASaKeyP", - "cloudsecASaKeyPLocal", - "cloudsecASaKeyPRemote", - "cloudsecASaKeyStatus", - "cloudsecASaKeyStatusLocal", - "cloudsecASaKeyStatusRemote", - "cloudsecASpKeySt", - "cloudtemplateASubnetPool", - "commComp", - "commDefinition", - "commShell", - "commWeb", - "compAHvHealth", - "compAPltfmP", - "compAPvlanP", - "compASvcVM", - "compAVmmPltfmP", - "compAVmmSecP", - "compAccessP", - "compCont", - "compContE", - "compCtrlrP", - "compDomP", - "compElement", - "compEntity", - "compHost", - "compNameIdentEntity", - "compNic", - "compObj", - "compPHost", - "compPNic", - "compProvP", - "compUsrAccP", - "conditionCondP", - "conditionInfo", - "conditionLoggable", - "conditionRecord", - "conditionRetP", - "conditionSevAsnP", - "conditionSummary", - "configABackupP", - "coppACustomValues", - "coppAProfile", - "ctrlrDom", - "datetimeANtpAuthKey", - "datetimeANtpIFFKey", - "datetimeANtpProv", - "datetimeAPol", - "dbgACRulePCommon", - "dbgANodeInst", - "dbgacEpgCmn", - "dbgacFromEpCmn", - "dbgacFromEpgCmn", - "dbgacTenantSpaceCmn", - "dbgacToEpCmn", - "dbgacToEpgCmn", - "dbgexpExportP", - "dbgexpNodeStatus", - "dbgexpTechSupOnDBase", - "dhcpAInfraProvP", - "dhcpALbl", - "dhcpARelayP", - "dhcpAddr", - "dhcpNode", - "dhcpResp", - "dnsADomain", - "dnsALbl", - "dnsAProfile", - "dnsAProv", - "dnsepgADomain", - "dnsepgAMgmt", - "dnsepgASvr", - "dnsepgASvrGrp", - "dnsepgFault", - "dwdmAOptChnlIfPol", - "edmACapFlags", - "edmAOperCont", - "edmAStatsCont", - "edmCont", - "edmContE", - "edmElement", - "edmEntity", - "edmGroupP", - "edmMgrP", - "edmObj", - "eigrpAAuthIfP", - "eigrpACtxAfPol", - "eigrpAExtP", - "eigrpAIfP", - "eigrpAStubP", - "eptrkEpRslt", - "eqptALPort", - "eqptdiagpASynthObj", - "eqptdiagpCardTestSetOd", - "eqptdiagpExtChCardTsOd", - "eqptdiagpFcTsOd", - "eqptdiagpFpTsOd", - "eqptdiagpHealthPol", - "eqptdiagpLcTsOd", - "eqptdiagpLpTsOd", - "eqptdiagpPol", - "eqptdiagpPortTestSetBt", - "eqptdiagpPortTestSetHl", - "eqptdiagpPortTestSetOd", - "eqptdiagpSupCTsOd", - "eqptdiagpSysCTsOd", - "eqptdiagpTestSet", - "eqptdiagpTestSetBoot", - "eqptdiagpTestSetHealth", - "eqptdiagpTestSetOd", - "eventARetP", - "extdevSDWanASlaPol", - "extnwAInstPSubnet", - "extnwALIfP", - "extnwALNodeP", - "extnwDomP", - "extnwEPg", - "extnwOut", - "fabricACardPGrp", - "fabricACardS", - "fabricALink", - "fabricANode", - "fabricANodeBlk", - "fabricANodePEp", - "fabricANodePGrp", - "fabricANodeS", - "fabricAONodeS", - "fabricAOOSReln", - "fabricAPathIssues", - "fabricAPathS", - "fabricAPodBlk", - "fabricAPodS", - "fabricAPolGrp", - "fabricAPortBlk", - "fabricAPortPGrp", - "fabricAPortS", - "fabricAProfile", - "fabricAProtPol", - "fabricASubPortBlk", - "fabricCardP", - "fabricCardS", - "fabricComp", - "fabricDef", - "fabricDom", - "fabricInfrExP", - "fabricInfrP", - "fabricIntfPol", - "fabricL1IfPol", - "fabricL2BDPol", - "fabricL2DomPol", - "fabricL2IfPol", - "fabricL2InstPol", - "fabricL2PortSecurityPol", - "fabricL2ProtoComp", - "fabricL2ProtoPol", - "fabricL3CtxPol", - "fabricL3DomPol", - "fabricL3IfPol", - "fabricL3InstPol", - "fabricL3ProtoComp", - "fabricL3ProtoPol", - "fabricL4IfPol", - "fabricLeAPortPGrp", - "fabricMaintPol", - "fabricNodeGrp", - "fabricNodeP", - "fabricNodeS", - "fabricNodeToPathOverridePolicy", - "fabricNodeToPolicy", - "fabricPodGrp", - "fabricPol", - "fabricPolGrp", - "fabricPolicyGrpToMonitoring", - "fabricPortP", - "fabricPortS", - "fabricProfile", - "fabricProtoComp", - "fabricProtoConsFrom", - "fabricProtoConsTo", - "fabricProtoDomPol", - "fabricProtoIfPol", - "fabricProtoInstPol", - "fabricProtoPol", - "fabricQinqIfPol", - "fabricSelector", - "fabricSpAPortPGrp", - "fabricUtilInstPol", - "fabricVxlanInstPol", - "faultARetP", - "faultARsToRemote", - "faultAThrValue", - "faultInfo", - "fcAPinningLbl", - "fcAPinningP", - "fcprARs", - "fileARemoteHost", - "fileARemotePath", - "firmwareAFwP", - "firmwareAFwStatusCont", - "firmwareARunning", - "firmwareSource", - "frmwrkARelDelCont", - "frmwrkARelDelControl", - "fvAACrtrn", - "fvAAKeyChainPol", - "fvAAKeyPol", - "fvAAREpPUpdate", - "fvABD", - "fvABDPol", - "fvAClassifier", - "fvACont", - "fvACrRule", - "fvACrtrn", - "fvACtx", - "fvACtxRtSummPol", - "fvADeplCont", - "fvADnsAttr", - "fvADomP", - "fvADyAttr", - "fvAEPSelector", - "fvAEPSelectorDef", - "fvAEPgPathAtt", - "fvAEpAnycast", - "fvAEpDef", - "fvAEpNlb", - "fvAEpRetPol", - "fvAEpTag", - "fvAEpTaskAggr", - "fvAExtRoutableRemoteSitePodSubnet", - "fvAExtRoutes", - "fvAFBRGroup", - "fvAFBRMember", - "fvAFBRoute", - "fvAFabricExpRtctrlP", - "fvAFabricExtConnP", - "fvAIdAttr", - "fvAIntersiteConnP", - "fvAIntersiteConnPDef", - "fvAIntraVrfFabricImpRtctrlP", - "fvAIpAttr", - "fvAKeyChainPol", - "fvAKeyPol", - "fvAMacAttr", - "fvANode", - "fvAPeeringP", - "fvAPodConnP", - "fvAProtoAttr", - "fvAREpPCtrct", - "fvARogueExceptionMac", - "fvARsToRemote", - "fvARsToRemoteFC", - "fvARtSummSubnet", - "fvASCrtrn", - "fvASDWanPrefixTaskAggr", - "fvASiteConnP", - "fvAStAttr", - "fvAStCEp", - "fvAStIp", - "fvATg", - "fvAToBD", - "fvATp", - "fvAUsegAssocBD", - "fvAVip", - "fvAVmAttr", - "fvAttr", - "fvCEPg", - "fvComp", - "fvDef", - "fvDom", - "fvEPg", - "fvEPgToCollection", - "fvEPgToInterface", - "fvEp", - "fvFrom", - "fvL2Dom", - "fvL3Dom", - "fvNp", - "fvNwEp", - "fvPEp", - "fvRtScopeFrom", - "fvSyntheticIp", - "fvTo", - "fvUp", - "fvnsAAddrBlk", - "fvnsAAddrInstP", - "fvnsAEncapBlk", - "fvnsAInstP", - "fvnsAVlanInstP", - "fvnsAVsanInstP", - "fvnsAVxlanInstP", - "genericsARule", - "haHaTest", - "hcloudAExtPfx", - "hcloudAIntPfx", - "hcloudALeakedPfx", - "hcloudASvcResBase", - "hcloudATgStats", - "hcloudRouterStateOper", - "healthAInst", - "healthARetP", - "hostprotASubj", - "hsrpAGroupP", - "hsrpAGroupPol", - "hsrpAIfP", - "hsrpAIfPol", - "hsrpASecVip", - "hvsContE", - "hvsNode", - "hvsUsegContE", - "iaclAProfile", - "igmpAIfP", - "igmpASnoopAccessGroup", - "igmpASnoopPol", - "igmpASnoopStaticGroup", - "infraAAccBndlGrp", - "infraAAccGrp", - "infraACEPg", - "infraACEp", - "infraADomP", - "infraAFcAccBndlGrp", - "infraAFunc", - "infraAIpP", - "infraANode", - "infraANodeP", - "infraANodeS", - "infraAONodeS", - "infraAPEPg", - "infraAPEp", - "infraAPathS", - "infraAccBaseGrp", - "infraAccGrp", - "infraDomP", - "infraDomainToNs", - "infraEPg", - "infraExP", - "infraFcAccGrp", - "infraFexBlk", - "infraFexGrp", - "infraGeNode", - "infraGeSnNode", - "infraLbl", - "infraNodeGrp", - "infraNodeS", - "infraPodGrp", - "infraPolGrp", - "infraPortP", - "infraPortS", - "infraProfile", - "infraSpAccGrp", - "infraToAInstP", - "ipANexthopEpP", - "ipANexthopP", - "ipARouteP", - "ipmcACtxPol", - "ipmcAIfPol", - "ipmcARepPol", - "ipmcASSMXlateP", - "ipmcAStRepPol", - "ipmcAStateLPol", - "ipmcsnoopMcSrc", - "ipmcsnoopRtrIf", - "ipmcsnoopTgtIf", - "ipsecAIsakmpPhase1Pol", - "ipsecAIsakmpPhase2Pol", - "l2AInstPol", - "l2extADomP", - "l2extAIfP", - "l2extAInstPSubnet", - "l2extALNodeP", - "l3extAConsLbl", - "l3extADefaultRouteLeakP", - "l3extADomP", - "l3extAFabricExtRoutingP", - "l3extAIfP", - "l3extAInstPSubnet", - "l3extAIp", - "l3extALNodeP", - "l3extAMember", - "l3extAProvLbl", - "l3extARouteTagPol", - "l4AVxlanInstPol", - "lacpAEnhancedLagPol", - "lacpALagPol", - "leakAPrefix", - "leakARouteCont", - "leakASubnet", - "lldpAIfPol", - "macsecAAIfPol", - "macsecAAKeyChainPol", - "macsecAAKeyPol", - "macsecAAParamPol", - "macsecAIfPol", - "macsecAKeyChainPol", - "macsecAKeyPol", - "macsecAParamPol", - "maintAMaintP", - "maintUserNotif", - "mcpAIfPol", - "mdpAClassId", - "mdpADomP", - "mdpADomainPeeringPol", - "mdpAEntity", - "mdpANodeP", - "mdpAPeeringDomain", - "mdpAService", - "mdpATenant", - "mgmtAInstPSubnet", - "mgmtAIp", - "mgmtAZone", - "mldASnoopAccessGroup", - "mldASnoopPol", - "mldASnoopStaticGroup", - "moASubj", - "moModifiable", - "moOwnable", - "moResolvable", - "moTopProps", - "monATarget", - "monExportP", - "monGroup", - "monPol", - "monProtoP", - "monSecAuthP", - "monSrc", - "monSubj", - "monTarget", - "mplsAExtP", - "mplsAIfP", - "mplsALabelPol", - "mplsANodeSidP", - "mplsASrgbLabelPol", - "namingNamedIdentifiedObject", - "namingNamedObject", - "ndAIfPol", - "ndAPfxPol", - "netflowAExporterPol", - "netflowAFabExporterPol", - "netflowAMonitorPol", - "netflowARecordPol", - "netflowARsInterfaceToMonitor", - "netflowARsMonitorToExporter", - "netflowARsMonitorToRecord", - "netflowAVmmExporterPol", - "nwsAFwPol", - "nwsASrc", - "nwsASyslogSrc", - "oamExec", - "orchsElement", - "orchsEntity", - "ospfACtxPol", - "ospfAExtP", - "ospfAIfP", - "pconsRef", - "pimAIfP", - "pingAExec", - "pkiDefinition", - "pkiItem", - "plannerADomainTmpl", - "plannerAEpg", - "plannerAEpgDomain", - "plannerAEpgFilter", - "plannerAObject", - "plannerATmpl", - "plannerIPs", - "poeAIfPol", - "polAConfIssues", - "polADependentOn", - "polAObjToPolReln", - "polAPrToPol", - "polAttTgt", - "polComp", - "polCompl", - "polComplElem", - "polConsElem", - "polConsIf", - "polConsLbl", - "polCont", - "polCtrlr", - "polDef", - "polDefRoot", - "polDom", - "polIf", - "polInstr", - "polLbl", - "polNFromRef", - "polNToRef", - "polNs", - "polObj", - "polProvIf", - "polProvLbl", - "polRelnHolder", - "poolElement", - "poolPool", - "poolPoolMember", - "poolPoolable", - "ptpAACfg", - "ptpACfg", - "ptpAProfile", - "qosABuffer", - "qosACong", - "qosADot1PClass", - "qosADppPol", - "qosADscpClass", - "qosADscpTrans", - "qosAMplsEgressRule", - "qosAMplsIngressRule", - "qosAQueue", - "qosASched", - "qosAUburst", - "qosClassification", - "qosMplsMarking", - "relnFrom", - "relnInst", - "relnTaskRef", - "relnTo", - "resolutionARsToRemote", - "rtctrlAAttrP", - "rtctrlAMatchAsPathRegexTerm", - "rtctrlAMatchCommFactor", - "rtctrlAMatchCommRegexTerm", - "rtctrlAMatchCommTerm", - "rtctrlAMatchIpRule", - "rtctrlAMatchRtType", - "rtctrlAMatchRule", - "rtctrlASetASPath", - "rtctrlASetASPathASN", - "rtctrlASetComm", - "rtctrlASetDamp", - "rtctrlASetNh", - "rtctrlASetNhUnchanged", - "rtctrlASetOspfFwdAddr", - "rtctrlASetOspfNssa", - "rtctrlASetPolicyTag", - "rtctrlASetPref", - "rtctrlASetRedistMultipath", - "rtctrlASetRtMetric", - "rtctrlASetRtMetricType", - "rtctrlASetRule", - "rtctrlASetTag", - "rtctrlASetWeight", - "rtctrlASubnet", - "rtdmcAASMPatPol", - "rtdmcAAutoRPPol", - "rtdmcABDFilter", - "rtdmcABDPol", - "rtdmcABSRFilter", - "rtdmcABSRPPol", - "rtdmcABidirPatPol", - "rtdmcACtxPol", - "rtdmcAExtP", - "rtdmcAFilterPol", - "rtdmcAIfPol", - "rtdmcAIfPolCont", - "rtdmcAInterVRFEntry", - "rtdmcAInterVRFPol", - "rtdmcAJPFilterPol", - "rtdmcAMAFilter", - "rtdmcANbrFilterPol", - "rtdmcAPatPol", - "rtdmcARPGrpRangePol", - "rtdmcARPPol", - "rtdmcARegTrPol", - "rtdmcAResPol", - "rtdmcARtMapEntry", - "rtdmcARtMapPol", - "rtdmcASGRangeExpPol", - "rtdmcASSMPatPol", - "rtdmcASSMRangePol", - "rtdmcASharedRangePol", - "rtdmcAStaticRPEntry", - "rtdmcAStaticRPPol", - "ruleDefinition", - "ruleItem", - "ruleRequirement", - "ruleSizeRequirement", - "snmpAClientGrpP", - "snmpAClientP", - "snmpACommunityP", - "snmpACtrlrInst", - "snmpACtxP", - "snmpAPol", - "snmpATrapFwdServerP", - "snmpAUserP", - "snmpUser", - "spanACEpDef", - "spanADest", - "spanASpanLbl", - "spanASrc", - "spanASrcGrp", - "spanAToCEp", - "spanAVDest", - "spanAVDestGrp", - "spanAVSrc", - "spanAVSrcGrp", - "statsAALbStats", - "statsAColl", - "statsANWStatsObj", - "statsANlbStats", - "statsAThrP", - "statsATunnel", - "statsDebugItem", - "statsItem", - "stpAIfPol", - "svccoreACore", - "svccorePol", - "synceAAIfPol", - "synceAIfPol", - "syntheticAContext", - "syntheticATestObj", - "syntheticCTestObj", - "syntheticObject", - "syntheticTLTestObj", - "sysdebugFile", - "sysdebugLogBehavior", - "sysdebugRepository", - "sysfileEp", - "sysfileInstance", - "sysfileRepository", - "tagASelector", - "tagAnnotation", - "tagTag", - "taskExec", - "telemetryAFlowServers", - "telemetryAFteEvents", - "telemetryAFteEventsExt", - "telemetryAFteEventsTcpFlags", - "telemetryARemoteServer", - "telemetryAServer", - "telemetryAServerP", - "telemetryAServerPol", - "telemetryAStreamEnable", - "throttlerASub", - "topRoot", - "tracerouteAExec", - "traceroutepTrP", - "trigATriggeredWindow", - "trigExecutable", - "trigInst", - "trigSchedWindow", - "trigSchedWindowP", - "trigSingleTriggerable", - "trigTriggerable", - "trigWindow", - "usegAUsegEPg", - "vmmACapInfo", - "vmmACapObj", - "vmmAUplinkP", - "vmmAUplinkPCont", - "vmmCFaultInfo", - "vmmEpgAggr", - "vmmInjectedObject", - "vnsACCfg", - "vnsACCfgRel", - "vnsAConn", - "vnsAConnection", - "vnsAEPpInfo", - "vnsAFolder", - "vnsAFuncConn", - "vnsAFuncNode", - "vnsAGraph", - "vnsAL4L7ServiceFault", - "vnsALDev", - "vnsALDevCtx", - "vnsALDevIf", - "vnsALDevLIf", - "vnsALIf", - "vnsALIfCtx", - "vnsAMgmt", - "vnsANode", - "vnsAParam", - "vnsATerm", - "vnsATermConn", - "vnsATermNode", - "vnsAVRoutingNetworks", - "vnsAbsTermNode", - "vnsDevItem", - "vnsLBReq", - "vnsNATReq", - "vnsOrchReq", - "vnsOrchResp", - "vsanARsVsanPathAtt", - "vsanARtVsanPathAtt", - "vsvcAConsLbl", - "vsvcAProvLbl", - "vzABrCP", - "vzACollection", - "vzACompLbl", - "vzACtrct", - "vzAFiltEntry", - "vzAFilter", - "vzAFilterable", - "vzAFilterableUnit", - "vzAIf", - "vzALbl", - "vzARuleOwner", - "vzASTerm", - "vzASubj", - "vzATerm", - "vzAnyToCollection", - "vzAnyToInterface", - "vzInterfaceToCollection", - "vzSubjectToFilter", - "vzToRFltP", -] \ No newline at end of file +ANNOTATION_UNSUPPORTED = [ + "aaaADomainRef", + "aaaAProvider", + "aaaARbacRule", + "aaaARetP", + "aaaAuthMethod", + "aaaBanner", + "aaaConfig", + "aaaDefinition", + "aaaEp", + "aaaProviderGroup", + "aaaRbacAnnotation", + "aaaRealm", + "aaaSystemUser", + "aaaUserAction", + "aclACL", + "aclL3ACE", + "actionACont", + "adcomARwi", + "adcomARwiAdvanced", + "adcomATsInfoUnit", + "adepgACont", + "adepgAElement", + "adepgAOrgUnit", + "adepgAResElement", + "adepgContE", + "adepgEntity", + "analyticsACfgSrv", + "analyticsACluster", + "analyticsRemoteNode", + "analyticsTarget", + "apDockerName", + "apPluginName", + "arpAIfPol", + "authASvr", + "authASvrGroup", + "authBaseUsrAccP", + "bfdAIfP", + "bfdAIfPol", + "bfdAInstPol", + "bfdAMhIfPol", + "bfdAMhInstPol", + "bfdAMhNodePol", + "bfdAMicroBfdP", + "bfdANodeP", + "bgpAAsP", + "bgpACtxAfPol", + "bgpACtxPol", + "bgpADomainIdBase", + "bgpAExtP", + "bgpALocalAsnP", + "bgpAPeerP", + "bgpAPeerPfxPol", + "bgpARRP", + "bgpARtTarget", + "bgpARtTargetInstrP", + "bgpARtTargetP", + "bgpASiteOfOriginP", + "callhomeADest", + "callhomeAGroup", + "callhomeASrc", + "cdpAIfPol", + "cloudAAEPg", + "cloudAAFilter", + "cloudAApicSubnet", + "cloudAApicSubnetPool", + "cloudAAwsFlowLogPol", + "cloudAAwsLogGroup", + "cloudAAwsProvider", + "cloudABaseEPg", + "cloudABdiId", + "cloudABgpAsP", + "cloudABgpPeerP", + "cloudABrownfield", + "cloudACertStore", + "cloudACertificate", + "cloudACidr", + "cloudACloudSvcEPg", + "cloudAComputePol", + "cloudAController", + "cloudACtxProfile", + "cloudACtxUnderlayP", + "cloudADomP", + "cloudAEPSelector", + "cloudAEPSelectorDef", + "cloudAExtNetworkP", + "cloudAFrontendIPv4Addr", + "cloudAGatewayRouterP", + "cloudAHealthProbe", + "cloudAHostBootstrapPol", + "cloudAHostIfP", + "cloudAHostRouterPol", + "cloudAIntNetworkP", + "cloudAIpSecTunnelIfP", + "cloudAIpv4AddrP", + "cloudAL3IfP", + "cloudAL3IntTunnelIfP", + "cloudAL3TunnelIfP", + "cloudALDev", + "cloudALIf", + "cloudAListener", + "cloudAListenerRule", + "cloudALoopbackIfP", + "cloudAMapping", + "cloudAMgmtPol", + "cloudANWParams", + "cloudANextHopIp", + "cloudAOspfAreaP", + "cloudAOspfIfP", + "cloudAParamPol", + "cloudAPool", + "cloudAProvResP", + "cloudAProvider", + "cloudARouterP", + "cloudARuleAction", + "cloudARuleCondition", + "cloudASelectedEP", + "cloudASubnet", + "cloudASvcEPg", + "cloudASvcPol", + "cloudATransitHubGwPol", + "cloudAVip", + "cloudAVirtualWanP", + "cloudAVpnGwPol", + "cloudAVpnNetworkP", + "cloudAVrfRouteLeakPol", + "cloudsecACapability", + "cloudsecAControl", + "cloudsecASaKeyP", + "cloudsecASaKeyPLocal", + "cloudsecASaKeyPRemote", + "cloudsecASaKeyStatus", + "cloudsecASaKeyStatusLocal", + "cloudsecASaKeyStatusRemote", + "cloudsecASpKeySt", + "cloudtemplateASubnetPool", + "commComp", + "commDefinition", + "commShell", + "commWeb", + "compAHvHealth", + "compAPltfmP", + "compAPvlanP", + "compASvcVM", + "compAVmmPltfmP", + "compAVmmSecP", + "compAccessP", + "compCont", + "compContE", + "compCtrlrP", + "compDomP", + "compElement", + "compEntity", + "compHost", + "compNameIdentEntity", + "compNic", + "compObj", + "compPHost", + "compPNic", + "compProvP", + "compUsrAccP", + "conditionCondP", + "conditionInfo", + "conditionLoggable", + "conditionRecord", + "conditionRetP", + "conditionSevAsnP", + "conditionSummary", + "configABackupP", + "coppACustomValues", + "coppAProfile", + "ctrlrDom", + "datetimeANtpAuthKey", + "datetimeANtpIFFKey", + "datetimeANtpProv", + "datetimeAPol", + "dbgACRulePCommon", + "dbgANodeInst", + "dbgacEpgCmn", + "dbgacFromEpCmn", + "dbgacFromEpgCmn", + "dbgacTenantSpaceCmn", + "dbgacToEpCmn", + "dbgacToEpgCmn", + "dbgexpExportP", + "dbgexpNodeStatus", + "dbgexpTechSupOnDBase", + "dhcpAInfraProvP", + "dhcpALbl", + "dhcpARelayP", + "dhcpAddr", + "dhcpNode", + "dhcpResp", + "dnsADomain", + "dnsALbl", + "dnsAProfile", + "dnsAProv", + "dnsepgADomain", + "dnsepgAMgmt", + "dnsepgASvr", + "dnsepgASvrGrp", + "dnsepgFault", + "dwdmAOptChnlIfPol", + "edmACapFlags", + "edmAOperCont", + "edmAStatsCont", + "edmCont", + "edmContE", + "edmElement", + "edmEntity", + "edmGroupP", + "edmMgrP", + "edmObj", + "eigrpAAuthIfP", + "eigrpACtxAfPol", + "eigrpAExtP", + "eigrpAIfP", + "eigrpAStubP", + "eptrkEpRslt", + "eqptALPort", + "eqptdiagpASynthObj", + "eqptdiagpCardTestSetOd", + "eqptdiagpExtChCardTsOd", + "eqptdiagpFcTsOd", + "eqptdiagpFpTsOd", + "eqptdiagpHealthPol", + "eqptdiagpLcTsOd", + "eqptdiagpLpTsOd", + "eqptdiagpPol", + "eqptdiagpPortTestSetBt", + "eqptdiagpPortTestSetHl", + "eqptdiagpPortTestSetOd", + "eqptdiagpSupCTsOd", + "eqptdiagpSysCTsOd", + "eqptdiagpTestSet", + "eqptdiagpTestSetBoot", + "eqptdiagpTestSetHealth", + "eqptdiagpTestSetOd", + "eventARetP", + "extdevSDWanASlaPol", + "extnwAInstPSubnet", + "extnwALIfP", + "extnwALNodeP", + "extnwDomP", + "extnwEPg", + "extnwOut", + "fabricACardPGrp", + "fabricACardS", + "fabricALink", + "fabricANode", + "fabricANodeBlk", + "fabricANodePEp", + "fabricANodePGrp", + "fabricANodeS", + "fabricAONodeS", + "fabricAOOSReln", + "fabricAPathIssues", + "fabricAPathS", + "fabricAPodBlk", + "fabricAPodS", + "fabricAPolGrp", + "fabricAPortBlk", + "fabricAPortPGrp", + "fabricAPortS", + "fabricAProfile", + "fabricAProtPol", + "fabricASubPortBlk", + "fabricCardP", + "fabricCardS", + "fabricComp", + "fabricDef", + "fabricDom", + "fabricInfrExP", + "fabricInfrP", + "fabricIntfPol", + "fabricL1IfPol", + "fabricL2BDPol", + "fabricL2DomPol", + "fabricL2IfPol", + "fabricL2InstPol", + "fabricL2PortSecurityPol", + "fabricL2ProtoComp", + "fabricL2ProtoPol", + "fabricL3CtxPol", + "fabricL3DomPol", + "fabricL3IfPol", + "fabricL3InstPol", + "fabricL3ProtoComp", + "fabricL3ProtoPol", + "fabricL4IfPol", + "fabricLeAPortPGrp", + "fabricMaintPol", + "fabricNodeGrp", + "fabricNodeP", + "fabricNodeS", + "fabricNodeToPathOverridePolicy", + "fabricNodeToPolicy", + "fabricPodGrp", + "fabricPol", + "fabricPolGrp", + "fabricPolicyGrpToMonitoring", + "fabricPortP", + "fabricPortS", + "fabricProfile", + "fabricProtoComp", + "fabricProtoConsFrom", + "fabricProtoConsTo", + "fabricProtoDomPol", + "fabricProtoIfPol", + "fabricProtoInstPol", + "fabricProtoPol", + "fabricQinqIfPol", + "fabricSelector", + "fabricSpAPortPGrp", + "fabricUtilInstPol", + "fabricVxlanInstPol", + "faultARetP", + "faultARsToRemote", + "faultAThrValue", + "faultInfo", + "fcAPinningLbl", + "fcAPinningP", + "fcprARs", + "fileARemoteHost", + "fileARemotePath", + "firmwareAFwP", + "firmwareAFwStatusCont", + "firmwareARunning", + "firmwareSource", + "frmwrkARelDelCont", + "frmwrkARelDelControl", + "fvAACrtrn", + "fvAAKeyChainPol", + "fvAAKeyPol", + "fvAAREpPUpdate", + "fvABD", + "fvABDPol", + "fvAClassifier", + "fvACont", + "fvACrRule", + "fvACrtrn", + "fvACtx", + "fvACtxRtSummPol", + "fvADeplCont", + "fvADnsAttr", + "fvADomP", + "fvADyAttr", + "fvAEPSelector", + "fvAEPSelectorDef", + "fvAEPgPathAtt", + "fvAEpAnycast", + "fvAEpDef", + "fvAEpNlb", + "fvAEpRetPol", + "fvAEpTag", + "fvAEpTaskAggr", + "fvAExtRoutableRemoteSitePodSubnet", + "fvAExtRoutes", + "fvAFBRGroup", + "fvAFBRMember", + "fvAFBRoute", + "fvAFabricExpRtctrlP", + "fvAFabricExtConnP", + "fvAIdAttr", + "fvAIntersiteConnP", + "fvAIntersiteConnPDef", + "fvAIntraVrfFabricImpRtctrlP", + "fvAIpAttr", + "fvAKeyChainPol", + "fvAKeyPol", + "fvAMacAttr", + "fvANode", + "fvAPeeringP", + "fvAPodConnP", + "fvAProtoAttr", + "fvAREpPCtrct", + "fvARogueExceptionMac", + "fvARsToRemote", + "fvARsToRemoteFC", + "fvARtSummSubnet", + "fvASCrtrn", + "fvASDWanPrefixTaskAggr", + "fvASiteConnP", + "fvAStAttr", + "fvAStCEp", + "fvAStIp", + "fvATg", + "fvAToBD", + "fvATp", + "fvAUsegAssocBD", + "fvAVip", + "fvAVmAttr", + "fvAttr", + "fvCEPg", + "fvComp", + "fvDef", + "fvDom", + "fvEPg", + "fvEPgToCollection", + "fvEPgToInterface", + "fvEp", + "fvFrom", + "fvL2Dom", + "fvL3Dom", + "fvNp", + "fvNwEp", + "fvPEp", + "fvRtScopeFrom", + "fvSyntheticIp", + "fvTo", + "fvUp", + "fvnsAAddrBlk", + "fvnsAAddrInstP", + "fvnsAEncapBlk", + "fvnsAInstP", + "fvnsAVlanInstP", + "fvnsAVsanInstP", + "fvnsAVxlanInstP", + "genericsARule", + "haHaTest", + "hcloudAExtPfx", + "hcloudAIntPfx", + "hcloudALeakedPfx", + "hcloudASvcResBase", + "hcloudATgStats", + "hcloudRouterStateOper", + "healthAInst", + "healthARetP", + "hostprotASubj", + "hsrpAGroupP", + "hsrpAGroupPol", + "hsrpAIfP", + "hsrpAIfPol", + "hsrpASecVip", + "hvsContE", + "hvsNode", + "hvsUsegContE", + "iaclAProfile", + "igmpAIfP", + "igmpASnoopAccessGroup", + "igmpASnoopPol", + "igmpASnoopStaticGroup", + "infraAAccBndlGrp", + "infraAAccGrp", + "infraACEPg", + "infraACEp", + "infraADomP", + "infraAFcAccBndlGrp", + "infraAFunc", + "infraAIpP", + "infraANode", + "infraANodeP", + "infraANodeS", + "infraAONodeS", + "infraAPEPg", + "infraAPEp", + "infraAPathS", + "infraAccBaseGrp", + "infraAccGrp", + "infraDomP", + "infraDomainToNs", + "infraEPg", + "infraExP", + "infraFcAccGrp", + "infraFexBlk", + "infraFexGrp", + "infraGeNode", + "infraGeSnNode", + "infraLbl", + "infraNodeGrp", + "infraNodeS", + "infraPodGrp", + "infraPolGrp", + "infraPortP", + "infraPortS", + "infraProfile", + "infraSpAccGrp", + "infraToAInstP", + "ipANexthopEpP", + "ipANexthopP", + "ipARouteP", + "ipmcACtxPol", + "ipmcAIfPol", + "ipmcARepPol", + "ipmcASSMXlateP", + "ipmcAStRepPol", + "ipmcAStateLPol", + "ipmcsnoopMcSrc", + "ipmcsnoopRtrIf", + "ipmcsnoopTgtIf", + "ipsecAIsakmpPhase1Pol", + "ipsecAIsakmpPhase2Pol", + "l2AInstPol", + "l2extADomP", + "l2extAIfP", + "l2extAInstPSubnet", + "l2extALNodeP", + "l3extAConsLbl", + "l3extADefaultRouteLeakP", + "l3extADomP", + "l3extAFabricExtRoutingP", + "l3extAIfP", + "l3extAInstPSubnet", + "l3extAIp", + "l3extALNodeP", + "l3extAMember", + "l3extAProvLbl", + "l3extARouteTagPol", + "l4AVxlanInstPol", + "lacpAEnhancedLagPol", + "lacpALagPol", + "leakAPrefix", + "leakARouteCont", + "leakASubnet", + "lldpAIfPol", + "macsecAAIfPol", + "macsecAAKeyChainPol", + "macsecAAKeyPol", + "macsecAAParamPol", + "macsecAIfPol", + "macsecAKeyChainPol", + "macsecAKeyPol", + "macsecAParamPol", + "maintAMaintP", + "maintUserNotif", + "mcpAIfPol", + "mdpAClassId", + "mdpADomP", + "mdpADomainPeeringPol", + "mdpAEntity", + "mdpANodeP", + "mdpAPeeringDomain", + "mdpAService", + "mdpATenant", + "mgmtAInstPSubnet", + "mgmtAIp", + "mgmtAZone", + "mldASnoopAccessGroup", + "mldASnoopPol", + "mldASnoopStaticGroup", + "moASubj", + "moModifiable", + "moOwnable", + "moResolvable", + "moTopProps", + "monATarget", + "monExportP", + "monGroup", + "monPol", + "monProtoP", + "monSecAuthP", + "monSrc", + "monSubj", + "monTarget", + "mplsAExtP", + "mplsAIfP", + "mplsALabelPol", + "mplsANodeSidP", + "mplsASrgbLabelPol", + "namingNamedIdentifiedObject", + "namingNamedObject", + "ndAIfPol", + "ndAPfxPol", + "netflowAExporterPol", + "netflowAFabExporterPol", + "netflowAMonitorPol", + "netflowARecordPol", + "netflowARsInterfaceToMonitor", + "netflowARsMonitorToExporter", + "netflowARsMonitorToRecord", + "netflowAVmmExporterPol", + "nwsAFwPol", + "nwsASrc", + "nwsASyslogSrc", + "oamExec", + "orchsElement", + "orchsEntity", + "ospfACtxPol", + "ospfAExtP", + "ospfAIfP", + "pconsRef", + "pimAIfP", + "pingAExec", + "pkiDefinition", + "pkiItem", + "plannerADomainTmpl", + "plannerAEpg", + "plannerAEpgDomain", + "plannerAEpgFilter", + "plannerAObject", + "plannerATmpl", + "plannerIPs", + "poeAIfPol", + "polAConfIssues", + "polADependentOn", + "polAObjToPolReln", + "polAPrToPol", + "polAttTgt", + "polComp", + "polCompl", + "polComplElem", + "polConsElem", + "polConsIf", + "polConsLbl", + "polCont", + "polCtrlr", + "polDef", + "polDefRoot", + "polDom", + "polIf", + "polInstr", + "polLbl", + "polNFromRef", + "polNToRef", + "polNs", + "polObj", + "polProvIf", + "polProvLbl", + "polRelnHolder", + "poolElement", + "poolPool", + "poolPoolMember", + "poolPoolable", + "ptpAACfg", + "ptpACfg", + "ptpAProfile", + "qosABuffer", + "qosACong", + "qosADot1PClass", + "qosADppPol", + "qosADscpClass", + "qosADscpTrans", + "qosAMplsEgressRule", + "qosAMplsIngressRule", + "qosAQueue", + "qosASched", + "qosAUburst", + "qosClassification", + "qosMplsMarking", + "relnFrom", + "relnInst", + "relnTaskRef", + "relnTo", + "resolutionARsToRemote", + "rtctrlAAttrP", + "rtctrlAMatchAsPathRegexTerm", + "rtctrlAMatchCommFactor", + "rtctrlAMatchCommRegexTerm", + "rtctrlAMatchCommTerm", + "rtctrlAMatchIpRule", + "rtctrlAMatchRtType", + "rtctrlAMatchRule", + "rtctrlASetASPath", + "rtctrlASetASPathASN", + "rtctrlASetComm", + "rtctrlASetDamp", + "rtctrlASetNh", + "rtctrlASetNhUnchanged", + "rtctrlASetOspfFwdAddr", + "rtctrlASetOspfNssa", + "rtctrlASetPolicyTag", + "rtctrlASetPref", + "rtctrlASetRedistMultipath", + "rtctrlASetRtMetric", + "rtctrlASetRtMetricType", + "rtctrlASetRule", + "rtctrlASetTag", + "rtctrlASetWeight", + "rtctrlASubnet", + "rtdmcAASMPatPol", + "rtdmcAAutoRPPol", + "rtdmcABDFilter", + "rtdmcABDPol", + "rtdmcABSRFilter", + "rtdmcABSRPPol", + "rtdmcABidirPatPol", + "rtdmcACtxPol", + "rtdmcAExtP", + "rtdmcAFilterPol", + "rtdmcAIfPol", + "rtdmcAIfPolCont", + "rtdmcAInterVRFEntry", + "rtdmcAInterVRFPol", + "rtdmcAJPFilterPol", + "rtdmcAMAFilter", + "rtdmcANbrFilterPol", + "rtdmcAPatPol", + "rtdmcARPGrpRangePol", + "rtdmcARPPol", + "rtdmcARegTrPol", + "rtdmcAResPol", + "rtdmcARtMapEntry", + "rtdmcARtMapPol", + "rtdmcASGRangeExpPol", + "rtdmcASSMPatPol", + "rtdmcASSMRangePol", + "rtdmcASharedRangePol", + "rtdmcAStaticRPEntry", + "rtdmcAStaticRPPol", + "ruleDefinition", + "ruleItem", + "ruleRequirement", + "ruleSizeRequirement", + "snmpAClientGrpP", + "snmpAClientP", + "snmpACommunityP", + "snmpACtrlrInst", + "snmpACtxP", + "snmpAPol", + "snmpATrapFwdServerP", + "snmpAUserP", + "snmpUser", + "spanACEpDef", + "spanADest", + "spanASpanLbl", + "spanASrc", + "spanASrcGrp", + "spanAToCEp", + "spanAVDest", + "spanAVDestGrp", + "spanAVSrc", + "spanAVSrcGrp", + "statsAALbStats", + "statsAColl", + "statsANWStatsObj", + "statsANlbStats", + "statsAThrP", + "statsATunnel", + "statsDebugItem", + "statsItem", + "stpAIfPol", + "svccoreACore", + "svccorePol", + "synceAAIfPol", + "synceAIfPol", + "syntheticAContext", + "syntheticATestObj", + "syntheticCTestObj", + "syntheticObject", + "syntheticTLTestObj", + "sysdebugFile", + "sysdebugLogBehavior", + "sysdebugRepository", + "sysfileEp", + "sysfileInstance", + "sysfileRepository", + "tagASelector", + "tagAnnotation", + "tagTag", + "taskExec", + "telemetryAFlowServers", + "telemetryAFteEvents", + "telemetryAFteEventsExt", + "telemetryAFteEventsTcpFlags", + "telemetryARemoteServer", + "telemetryAServer", + "telemetryAServerP", + "telemetryAServerPol", + "telemetryAStreamEnable", + "throttlerASub", + "topRoot", + "tracerouteAExec", + "traceroutepTrP", + "trigATriggeredWindow", + "trigExecutable", + "trigInst", + "trigSchedWindow", + "trigSchedWindowP", + "trigSingleTriggerable", + "trigTriggerable", + "trigWindow", + "usegAUsegEPg", + "vmmACapInfo", + "vmmACapObj", + "vmmAUplinkP", + "vmmAUplinkPCont", + "vmmCFaultInfo", + "vmmEpgAggr", + "vmmInjectedObject", + "vnsACCfg", + "vnsACCfgRel", + "vnsAConn", + "vnsAConnection", + "vnsAEPpInfo", + "vnsAFolder", + "vnsAFuncConn", + "vnsAFuncNode", + "vnsAGraph", + "vnsAL4L7ServiceFault", + "vnsALDev", + "vnsALDevCtx", + "vnsALDevIf", + "vnsALDevLIf", + "vnsALIf", + "vnsALIfCtx", + "vnsAMgmt", + "vnsANode", + "vnsAParam", + "vnsATerm", + "vnsATermConn", + "vnsATermNode", + "vnsAVRoutingNetworks", + "vnsAbsTermNode", + "vnsDevItem", + "vnsLBReq", + "vnsNATReq", + "vnsOrchReq", + "vnsOrchResp", + "vsanARsVsanPathAtt", + "vsanARtVsanPathAtt", + "vsvcAConsLbl", + "vsvcAProvLbl", + "vzABrCP", + "vzACollection", + "vzACompLbl", + "vzACtrct", + "vzAFiltEntry", + "vzAFilter", + "vzAFilterable", + "vzAFilterableUnit", + "vzAIf", + "vzALbl", + "vzARuleOwner", + "vzASTerm", + "vzASubj", + "vzATerm", + "vzAnyToCollection", + "vzAnyToInterface", + "vzInterfaceToCollection", + "vzSubjectToFilter", + "vzToRFltP", +] diff --git a/tests/integration/targets/aci_rest/tasks/json_inline.yml b/tests/integration/targets/aci_rest/tasks/json_inline.yml index 3d5c9be48..0260d588e 100644 --- a/tests/integration/targets/aci_rest/tasks/json_inline.yml +++ b/tests/integration/targets/aci_rest/tasks/json_inline.yml @@ -58,6 +58,7 @@ that: - cm_add_tenant is changed - cm_add_tenant.proposed.fvTenant.attributes.name == "ansible_test" + - cm_add_tenant.proposed.fvTenant.attributes.annotation == "orchestrator:ansible" - cm_verify_checkmode_tenant.current == [] - name: Add tenant (normal mode) @@ -72,6 +73,7 @@ assert: that: - nm_add_tenant is changed + - nm_add_tenant.imdata.0.fvTenant.attributes.annotation == "orchestrator:ansible" - nm_add_tenant_again is not changed # CHANGE TENANT @@ -179,3 +181,104 @@ assert: that: - nm_query_non_tenant is not changed + +# VERIFY ANNOTATION SUPPORT +- name: Add tenant with annotation option + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni.json + method: post + annotation: test:inoption + content: + { + "fvTenant": { + "attributes": { + "descr": "Ansible test tenant", + "name": "ansible_test" + } + } + } + register: nm_add_tenant_annotation_option + +- name: Add tenant with annotation in content + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni.json + method: post + content: + { + "fvTenant": { + "attributes": { + "descr": "Ansible test tenant", + "name": "ansible_test", + "annotation": "test:incontent" + } + } + } + register: nm_add_tenant_annotation_content + +- name: Add tenant with annotation in content and option + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni.json + method: post + annotation: test:inoption + content: + { + "fvTenant": { + "attributes": { + "descr": "Ansible test tenant", + "name": "ansible_test", + "annotation": "test:optionincontent" + } + } + } + register: nm_add_tenant_annotation_option_content + +- name: Add tag to tenant with annotation unsupported + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni/tn-ansible_test/tagKey-foo.json + method: post + annotation: test:inoption + content: + { + "tagTag": { + "attributes": { + "value": "bar" + } + } + } + register: nm_add_tag_no_annotation + +- name: Verify annotation support + assert: + that: + - nm_add_tenant_annotation_option.imdata.0.fvTenant.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_content.imdata.0.fvTenant.attributes.annotation == "test:incontent" + - nm_add_tenant_annotation_option_content.imdata.0.fvTenant.attributes.annotation == "test:optionincontent" + - nm_add_tag_no_annotation.imdata.0.tagTag.attributes.annotation is undefined \ No newline at end of file diff --git a/tests/integration/targets/aci_rest/tasks/json_string.yml b/tests/integration/targets/aci_rest/tasks/json_string.yml index 7a1dfd8ce..23e9900fe 100644 --- a/tests/integration/targets/aci_rest/tasks/json_string.yml +++ b/tests/integration/targets/aci_rest/tasks/json_string.yml @@ -59,6 +59,7 @@ that: - cm_add_tenant is changed - cm_add_tenant.proposed.fvTenant.attributes.name == "ansible_test" + - cm_add_tenant.proposed.fvTenant.attributes.annotation == "orchestrator:ansible" - cm_verify_checkmode_tenant.current == [] - name: Add tenant (normal mode) @@ -73,6 +74,7 @@ assert: that: - nm_add_tenant is changed + - nm_add_tenant.imdata.0.fvTenant.attributes.annotation == "orchestrator:ansible" - nm_add_tenant_again is not changed # CHANGE TENANT @@ -180,3 +182,104 @@ assert: that: - nm_query_non_tenant is not changed + +# VERIFY ANNOTATION SUPPORT +- name: Add tenant with annotation option + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni.json + method: post + annotation: test:inoption + content: | + { + "fvTenant": { + "attributes": { + "descr": "Ansible test tenant", + "name": "ansible_test" + } + } + } + register: nm_add_tenant_annotation_option + +- name: Add tenant with annotation in content + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni.json + method: post + content: | + { + "fvTenant": { + "attributes": { + "descr": "Ansible test tenant", + "name": "ansible_test", + "annotation": "test:incontent" + } + } + } + register: nm_add_tenant_annotation_content + +- name: Add tenant with annotation in content and option + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni.json + method: post + annotation: test:inoption + content: | + { + "fvTenant": { + "attributes": { + "descr": "Ansible test tenant", + "name": "ansible_test", + "annotation": "test:optionincontent" + } + } + } + register: nm_add_tenant_annotation_option_content + +- name: Add tag to tenant with annotation unsupported + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni/tn-ansible_test_annotation1/tagKey-foo.json + method: post + annotation: test:inoption + content: | + { + "tagTag": { + "attributes": { + "value": "bar" + } + } + } + register: nm_add_tag_no_annotation + +- name: Verify annotation support + assert: + that: + - nm_add_tenant_annotation_option.imdata.0.fvTenant.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_content.imdata.0.fvTenant.attributes.annotation == "test:incontent" + - nm_add_tenant_annotation_option_content.imdata.0.fvTenant.attributes.annotation == "test:optionincontent" + - nm_add_tag_no_annotation.imdata.0.tagTag.attributes.annotation is undefined \ No newline at end of file diff --git a/tests/integration/targets/aci_rest/tasks/xml_file.yml b/tests/integration/targets/aci_rest/tasks/xml_file.yml index fea63112b..52b67fc7c 100644 --- a/tests/integration/targets/aci_rest/tasks/xml_file.yml +++ b/tests/integration/targets/aci_rest/tasks/xml_file.yml @@ -50,6 +50,7 @@ that: - cm_add_tenant is changed - '"ans_test_create" in cm_add_tenant.proposed' + - cm_add_tenant.proposed.fvTenant.attributes.annotation == "orchestrator:ansible" - cm_verify_checkmode_tenant.current == [] - name: Add tenant using ans_test_create xml template file with normal mode @@ -67,6 +68,7 @@ - nm_add_tenant.imdata.0.fvTenant.attributes.name == "ans_test_create" - nm_add_tenant.imdata.0.fvTenant.attributes.descr == "ans_test_create tenant created successfully" - nm_add_tenant.imdata.0.fvTenant.attributes.dn == "uni/tn-ans_test_create" + - nm_add_tenant.imdata.0.fvTenant.attributes.annotation == "orchestrator:ansible" - nm_add_tenant.imdata.0.fvTenant.children != [] - name: Add tenant using ans_test_create xml template file with normal mode - idempotency works @@ -227,3 +229,71 @@ that: - query_ans_test_delete is not changed - query_ans_test_delete.imdata == [] + +# VERIFY ANNOTATION SUPPORT +- name: Add tenant with annotation option + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni.xml + method: post + annotation: test:inoption + src: "./targets/aci_rest/tasks/xml_files/tn-ans_test_create.xml" + register: nm_add_tenant_annotation_option + +- name: Add tenant with annotation in content + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni.xml + method: post + src: "./targets/aci_rest/tasks/xml_files/tn-ans_test_annotation.xml" + register: nm_add_tenant_annotation_content + +- name: Add tenant with annotation in content and option + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni.xml + method: post + annotation: test:inoption + src: "./targets/aci_rest/tasks/xml_files/tn-ans_test_annotation.xml" + register: nm_add_tenant_annotation_option_content + +- name: Add tag to tenant with annotation unsupported + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni/tn-ans_test_create/tagKey-foo.xml + method: post + annotation: test:inoption + src: "./targets/aci_rest/tasks/xml_files/tag.xml" + register: nm_add_tag_no_annotation + +- name: Verify annotation support + assert: + that: + - nm_add_tenant_annotation_option.imdata.0.fvTenant.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_content.imdata.0.fvTenant.attributes.annotation == "test:incontent" + - nm_add_tenant_annotation_option_content.imdata.0.fvTenant.attributes.annotation == "test:optionincontent" + - nm_add_tag_no_annotation.imdata.0.tagTag.attributes.annotation is undefined \ No newline at end of file diff --git a/tests/integration/targets/aci_rest/tasks/xml_files/tag.xml b/tests/integration/targets/aci_rest/tasks/xml_files/tag.xml new file mode 100644 index 000000000..f5918f0e3 --- /dev/null +++ b/tests/integration/targets/aci_rest/tasks/xml_files/tag.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tests/integration/targets/aci_rest/tasks/xml_files/tn-ans_test_annotation.xml b/tests/integration/targets/aci_rest/tasks/xml_files/tn-ans_test_annotation.xml new file mode 100644 index 000000000..281e6e282 --- /dev/null +++ b/tests/integration/targets/aci_rest/tasks/xml_files/tn-ans_test_annotation.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tests/integration/targets/aci_rest/tasks/xml_string.yml b/tests/integration/targets/aci_rest/tasks/xml_string.yml index d1424bafa..d4a4304bc 100644 --- a/tests/integration/targets/aci_rest/tasks/xml_string.yml +++ b/tests/integration/targets/aci_rest/tasks/xml_string.yml @@ -74,8 +74,10 @@ that: - cm_add_tenant is changed - '"ansible_test" in cm_add_tenant.proposed' + - cm_add_tenant.proposed.fvTenant.attributes.annotation == "orchestrator:ansible" - cm_add_tenant_2 is changed - - '"ansible_test" in cm_add_tenant.proposed' + - '"ansible_test" in cm_add_tenant_2.proposed' + - cm_add_tenant_2.proposed.fvTenant.attributes.annotation == "orchestrator:ansible" - cm_verify_checkmode_tenant.current == [] - name: Add tenant (normal mode) @@ -225,3 +227,92 @@ assert: that: - nm_query_non_tenant is not changed + +# VERIFY ANNOTATION +- name: Add tenant with annotation (normal mode) + cisco.aci.aci_rest: &tenant_annotation + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni.xml + method: post + annotation: test:label + content: + + register: nm_add_tenant_annotation + +# VERIFY ANNOTATION SUPPORT +- name: Add tenant with annotation option + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni.xml + method: post + annotation: test:inoption + content: + + register: nm_add_tenant_annotation_option + +- name: Add tenant with annotation in content + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni.xml + method: post + content: + + register: nm_add_tenant_annotation_content + +- name: Add tenant with annotation in content and option + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni.xml + method: post + annotation: test:inoption + content: + + register: nm_add_tenant_annotation_option_content + +- name: Add tag to tenant with annotation unsupported + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni/tn-ansible_test/tagKey-foo.json + method: post + annotation: test:inoption + content: + + register: nm_add_tag_no_annotation + +- name: Verify annotation support + assert: + that: + - nm_add_tenant_annotation_option.imdata.0.fvTenant.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_content.imdata.0.fvTenant.attributes.annotation == "test:incontent" + - nm_add_tenant_annotation_option_content.imdata.0.fvTenant.attributes.annotation == "test:optionincontent" + - nm_add_tag_no_annotation.imdata.0.tagTag.attributes.annotation is undefined \ No newline at end of file diff --git a/tests/integration/targets/aci_rest/tasks/yaml_inline.yml b/tests/integration/targets/aci_rest/tasks/yaml_inline.yml index 6cd06afcd..50549aa7c 100644 --- a/tests/integration/targets/aci_rest/tasks/yaml_inline.yml +++ b/tests/integration/targets/aci_rest/tasks/yaml_inline.yml @@ -54,6 +54,7 @@ that: - cm_add_tenant is changed - cm_add_tenant.proposed.fvTenant.attributes.name == "ansible_test" + - cm_add_tenant.proposed.fvTenant.attributes.annotation == "orchestrator:ansible" - cm_verify_checkmode_tenant.current == [] - name: Add tenant (normal mode) @@ -97,6 +98,7 @@ assert: that: - nm_add_tenant_descr is changed + - nm_add_tenant.imdata.0.fvTenant.attributes.annotation == "orchestrator:ansible" - nm_add_tenant_descr_again is not changed # ADD TENANT AGAIN @@ -171,3 +173,88 @@ assert: that: - nm_query_non_tenant is not changed + +# VERIFY ANNOTATION SUPPORT +- name: Add tenant with annotation option + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni.json + method: post + annotation: test:inoption + content: + fvTenant: + attributes: + descr: Ansible test tenant + name: ansible_test + register: nm_add_tenant_annotation_option + +- name: Add tenant with annotation in content + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni.json + method: post + content: + fvTenant: + attributes: + descr: Ansible test tenant + name: ansible_test + annotation: test:incontent + register: nm_add_tenant_annotation_content + +- name: Add tenant with annotation in content and option + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni.json + method: post + annotation: test:inoption + content: + fvTenant: + attributes: + descr: Ansible test tenant + name: ansible_test + annotation: test:optionincontent + register: nm_add_tenant_annotation_option_content + +- name: Add tag to tenant with annotation unsupported + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni/tn-ansible_test/tagKey-foo.json + method: post + annotation: test:inoption + content: + tagTag: + attributes: + value: bar + register: nm_add_tag_no_annotation + +- name: Verify annotation support + assert: + that: + - nm_add_tenant_annotation_option.imdata.0.fvTenant.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_content.imdata.0.fvTenant.attributes.annotation == "test:incontent" + - nm_add_tenant_annotation_option_content.imdata.0.fvTenant.attributes.annotation == "test:optionincontent" + - nm_add_tag_no_annotation.imdata.0.tagTag.attributes.annotation is undefined diff --git a/tests/integration/targets/aci_rest/tasks/yaml_string.yml b/tests/integration/targets/aci_rest/tasks/yaml_string.yml index 895045474..beb1fad54 100644 --- a/tests/integration/targets/aci_rest/tasks/yaml_string.yml +++ b/tests/integration/targets/aci_rest/tasks/yaml_string.yml @@ -54,6 +54,7 @@ that: - cm_add_tenant is changed - cm_add_tenant.proposed.fvTenant.attributes.name == "ansible_test" + - cm_add_tenant.proposed.fvTenant.attributes.annotation == "orchestrator:ansible" - cm_verify_checkmode_tenant.current == [] - name: Add tenant (normal mode) @@ -68,6 +69,7 @@ assert: that: - nm_add_tenant is changed + - nm_add_tenant.imdata.0.fvTenant.attributes.annotation == "orchestrator:ansible" - nm_add_tenant_again is not changed # CHANGE TENANT @@ -171,3 +173,88 @@ assert: that: - nm_query_non_tenant is not changed + +# VERIFY ANNOTATION SUPPORT +- name: Add tenant with annotation option + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni.json + method: post + annotation: test:inoption + content: | + fvTenant: + attributes: + descr: Ansible test tenant + name: ansible_test + register: nm_add_tenant_annotation_option + +- name: Add tenant with annotation in content + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni.json + method: post + content: | + fvTenant: + attributes: + descr: Ansible test tenant + name: ansible_test + annotation: test:incontent + register: nm_add_tenant_annotation_content + +- name: Add tenant with annotation in content and option + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni.json + method: post + annotation: test:inoption + content: | + fvTenant: + attributes: + descr: Ansible test tenant + name: ansible_test + annotation: test:optionincontent + register: nm_add_tenant_annotation_option_content + +- name: Add tag to tenant with annotation unsupported + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni/tn-ansible_test/tagKey-foo.json + method: post + annotation: test:inoption + content: | + tagTag: + attributes: + value: bar + register: nm_add_tag_no_annotation + +- name: Verify annotation support + assert: + that: + - nm_add_tenant_annotation_option.imdata.0.fvTenant.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_content.imdata.0.fvTenant.attributes.annotation == "test:incontent" + - nm_add_tenant_annotation_option_content.imdata.0.fvTenant.attributes.annotation == "test:optionincontent" + - nm_add_tag_no_annotation.imdata.0.tagTag.attributes.annotation is undefined \ No newline at end of file From 37f922d0b865cce9dfc1bf9bc7b665f7d0585501 Mon Sep 17 00:00:00 2001 From: samitab Date: Tue, 31 Oct 2023 12:30:21 +1000 Subject: [PATCH 5/8] [ignore] aci_rest add annotation to children and fix some tests --- plugins/modules/aci_rest.py | 11 +++- .../targets/aci_rest/tasks/json_inline.yml | 58 +++++++++++++++++- .../targets/aci_rest/tasks/json_string.yml | 60 ++++++++++++++++++- .../targets/aci_rest/tasks/xml_file.yml | 31 +++++++++- .../tn-ans_test_annotation_children.xml | 6 ++ .../targets/aci_rest/tasks/xml_string.yml | 38 ++++++++++-- .../targets/aci_rest/tasks/yaml_inline.yml | 38 ++++++++++++ .../targets/aci_rest/tasks/yaml_string.yml | 40 ++++++++++++- 8 files changed, 267 insertions(+), 15 deletions(-) create mode 100644 tests/integration/targets/aci_rest/tasks/xml_files/tn-ans_test_annotation_children.xml diff --git a/plugins/modules/aci_rest.py b/plugins/modules/aci_rest.py index 2029330de..43986592a 100644 --- a/plugins/modules/aci_rest.py +++ b/plugins/modules/aci_rest.py @@ -312,13 +312,18 @@ def update_qsl(url, params): def add_annotation(annotation, payload): """Add annotation to payload only if it has not already been added""" - if annotation: + if annotation and isinstance(payload, dict): for key, val in payload.items(): if key in ANNOTATION_UNSUPPORTED: - return + continue att = val.get("attributes", {}) if "annotation" not in att.keys(): att["annotation"] = annotation + # Recursively add annotation to children + children = val.get("children", None) + if children: + for child in children: + add_annotation(annotation, child) def add_annotation_xml(annotation, tree): @@ -326,7 +331,7 @@ def add_annotation_xml(annotation, tree): if annotation: for element in tree.iter(): if element.tag in ANNOTATION_UNSUPPORTED: - return + continue ann = element.get("annotation") if ann is None: element.set("annotation", annotation) diff --git a/tests/integration/targets/aci_rest/tasks/json_inline.yml b/tests/integration/targets/aci_rest/tasks/json_inline.yml index 0260d588e..854950af6 100644 --- a/tests/integration/targets/aci_rest/tasks/json_inline.yml +++ b/tests/integration/targets/aci_rest/tasks/json_inline.yml @@ -275,10 +275,66 @@ } register: nm_add_tag_no_annotation +- name: Remove tenant + cisco.aci.aci_rest: *tenant_absent + +- name: Add tenant with children objects including annotation + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni.json + method: post + annotation: test:inoption + content: + { + "fvTenant": { + "attributes": { + "descr": "Ansible test tenant", + "name": "ansible_test" + }, + "children": [ + { + "fvCtx": { + "attributes": { + "name": "VRF1" + } + } + }, + { + "fvAp": { + "attributes": { + "name": "Application1" + }, + "children": [ + { + "fvAEPg": { + "attributes": { + "name": "WebTier", + "annotation": "test:inchild" + } + } + } + ] + } + } + ] + } + } + register: nm_add_tenant_annotation_children + - name: Verify annotation support assert: that: - nm_add_tenant_annotation_option.imdata.0.fvTenant.attributes.annotation == "test:inoption" - nm_add_tenant_annotation_content.imdata.0.fvTenant.attributes.annotation == "test:incontent" - nm_add_tenant_annotation_option_content.imdata.0.fvTenant.attributes.annotation == "test:optionincontent" - - nm_add_tag_no_annotation.imdata.0.tagTag.attributes.annotation is undefined \ No newline at end of file + - nm_add_tag_no_annotation.imdata.0.tagTag.attributes.annotation is undefined + - nm_add_tenant_annotation_children.imdata.0.fvTenant.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.0.fvAp.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.0.fvAp.children.0.fvAEPg.attributes.annotation == "test:inchild" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.2.fvCtx.attributes.annotation == "test:inoption" \ No newline at end of file diff --git a/tests/integration/targets/aci_rest/tasks/json_string.yml b/tests/integration/targets/aci_rest/tasks/json_string.yml index 23e9900fe..2135c0219 100644 --- a/tests/integration/targets/aci_rest/tasks/json_string.yml +++ b/tests/integration/targets/aci_rest/tasks/json_string.yml @@ -263,7 +263,7 @@ use_ssl: '{{ aci_use_ssl | default(true) }}' use_proxy: '{{ aci_use_proxy | default(true) }}' output_level: '{{ aci_output_level | default("info") }}' - path: /api/mo/uni/tn-ansible_test_annotation1/tagKey-foo.json + path: /api/mo/uni/tn-ansible_test/tagKey-foo.json method: post annotation: test:inoption content: | @@ -276,10 +276,66 @@ } register: nm_add_tag_no_annotation +- name: Remove tenant + cisco.aci.aci_rest: *tenant_absent + +- name: Add tenant with children objects including annotation + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni.json + method: post + annotation: test:inoption + content: | + { + "fvTenant": { + "attributes": { + "descr": "Ansible test tenant", + "name": "ansible_test" + }, + "children": [ + { + "fvCtx": { + "attributes": { + "name": "VRF1" + } + } + }, + { + "fvAp": { + "attributes": { + "name": "Application1" + }, + "children": [ + { + "fvAEPg": { + "attributes": { + "name": "WebTier", + "annotation": "test:inchild" + } + } + } + ] + } + } + ] + } + } + register: nm_add_tenant_annotation_children + - name: Verify annotation support assert: that: - nm_add_tenant_annotation_option.imdata.0.fvTenant.attributes.annotation == "test:inoption" - nm_add_tenant_annotation_content.imdata.0.fvTenant.attributes.annotation == "test:incontent" - nm_add_tenant_annotation_option_content.imdata.0.fvTenant.attributes.annotation == "test:optionincontent" - - nm_add_tag_no_annotation.imdata.0.tagTag.attributes.annotation is undefined \ No newline at end of file + - nm_add_tag_no_annotation.imdata.0.tagTag.attributes.annotation is undefined + - nm_add_tenant_annotation_children.imdata.0.fvTenant.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.0.fvAp.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.0.fvAp.children.0.fvAEPg.attributes.annotation == "test:inchild" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.2.fvCtx.attributes.annotation == "test:inoption" \ No newline at end of file diff --git a/tests/integration/targets/aci_rest/tasks/xml_file.yml b/tests/integration/targets/aci_rest/tasks/xml_file.yml index 52b67fc7c..0da42b009 100644 --- a/tests/integration/targets/aci_rest/tasks/xml_file.yml +++ b/tests/integration/targets/aci_rest/tasks/xml_file.yml @@ -17,7 +17,7 @@ output_path: "/tmp/ansible_output_file.log" - name: Ensure tenant does not exists using ans_test_delete xml template - cisco.aci.aci_rest: + cisco.aci.aci_rest: &tenant_delete <<: *aci_info path: /api/mo/uni.xml src: "./targets/aci_rest/tasks/xml_files/tn-ans_test_delete.xml" @@ -260,6 +260,9 @@ src: "./targets/aci_rest/tasks/xml_files/tn-ans_test_annotation.xml" register: nm_add_tenant_annotation_content +- name: Remove tenant + cisco.aci.aci_rest: *tenant_delete + - name: Add tenant with annotation in content and option cisco.aci.aci_rest: host: '{{ aci_hostname }}' @@ -290,10 +293,32 @@ src: "./targets/aci_rest/tasks/xml_files/tag.xml" register: nm_add_tag_no_annotation +- name: Remove tenant + cisco.aci.aci_rest: *tenant_delete + +- name: Add tenant with children objects including annotation + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni.xml + method: post + annotation: test:inoption + src: "./targets/aci_rest/tasks/xml_files/tn-ans_test_annotation_children.xml" + register: nm_add_tenant_annotation_children + - name: Verify annotation support assert: that: - nm_add_tenant_annotation_option.imdata.0.fvTenant.attributes.annotation == "test:inoption" - - nm_add_tenant_annotation_content.imdata.0.fvTenant.attributes.annotation == "test:incontent" + - nm_add_tenant_annotation_content.imdata.0.fvTenant.attributes.annotation == "test:optionincontent" - nm_add_tenant_annotation_option_content.imdata.0.fvTenant.attributes.annotation == "test:optionincontent" - - nm_add_tag_no_annotation.imdata.0.tagTag.attributes.annotation is undefined \ No newline at end of file + - nm_add_tag_no_annotation.imdata.0.tagTag.attributes.annotation is undefined + - nm_add_tenant_annotation_children.imdata.0.fvTenant.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.0.fvAp.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.0.fvAp.children.0.fvAEPg.attributes.annotation == "test:inchild" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.1.fvCtx.attributes.annotation == "test:inoption" \ No newline at end of file diff --git a/tests/integration/targets/aci_rest/tasks/xml_files/tn-ans_test_annotation_children.xml b/tests/integration/targets/aci_rest/tasks/xml_files/tn-ans_test_annotation_children.xml new file mode 100644 index 000000000..448998bf6 --- /dev/null +++ b/tests/integration/targets/aci_rest/tasks/xml_files/tn-ans_test_annotation_children.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/tests/integration/targets/aci_rest/tasks/xml_string.yml b/tests/integration/targets/aci_rest/tasks/xml_string.yml index d4a4304bc..34e43abb7 100644 --- a/tests/integration/targets/aci_rest/tasks/xml_string.yml +++ b/tests/integration/targets/aci_rest/tasks/xml_string.yml @@ -259,7 +259,7 @@ method: post annotation: test:inoption content: - + register: nm_add_tenant_annotation_option - name: Add tenant with annotation in content @@ -274,7 +274,7 @@ path: /api/mo/uni.xml method: post content: - + register: nm_add_tenant_annotation_content - name: Add tenant with annotation in content and option @@ -290,7 +290,7 @@ method: post annotation: test:inoption content: - + register: nm_add_tenant_annotation_option_content - name: Add tag to tenant with annotation unsupported @@ -302,17 +302,45 @@ use_ssl: '{{ aci_use_ssl | default(true) }}' use_proxy: '{{ aci_use_proxy | default(true) }}' output_level: '{{ aci_output_level | default("info") }}' - path: /api/mo/uni/tn-ansible_test/tagKey-foo.json + path: /api/mo/uni/tn-ansible_test/tagKey-foo.xml method: post annotation: test:inoption content: register: nm_add_tag_no_annotation +- name: Remove tenant + cisco.aci.aci_rest: *tenant_absent + +- name: Add tenant with children objects including annotation + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni.xml + method: post + annotation: test:inoption + content: + + + + + + + register: nm_add_tenant_annotation_children + - name: Verify annotation support assert: that: - nm_add_tenant_annotation_option.imdata.0.fvTenant.attributes.annotation == "test:inoption" - nm_add_tenant_annotation_content.imdata.0.fvTenant.attributes.annotation == "test:incontent" - nm_add_tenant_annotation_option_content.imdata.0.fvTenant.attributes.annotation == "test:optionincontent" - - nm_add_tag_no_annotation.imdata.0.tagTag.attributes.annotation is undefined \ No newline at end of file + - nm_add_tag_no_annotation.imdata.0.tagTag.attributes.annotation is undefined + - nm_add_tenant_annotation_children.imdata.0.fvTenant.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.0.fvAp.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.0.fvAp.children.0.fvAEPg.attributes.annotation == "test:inchild" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.1.fvCtx.attributes.annotation == "test:inoption" \ No newline at end of file diff --git a/tests/integration/targets/aci_rest/tasks/yaml_inline.yml b/tests/integration/targets/aci_rest/tasks/yaml_inline.yml index 50549aa7c..8f4bbef04 100644 --- a/tests/integration/targets/aci_rest/tasks/yaml_inline.yml +++ b/tests/integration/targets/aci_rest/tasks/yaml_inline.yml @@ -251,6 +251,40 @@ value: bar register: nm_add_tag_no_annotation +- name: Remove tenant + cisco.aci.aci_rest: *tenant_absent + +- name: Add tenant with children objects including annotation + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni.json + method: post + annotation: test:inoption + content: + fvTenant: + attributes: + descr: Ansible test tenant + name: ansible_test + children: + - fvCtx: + attributes: + name: VRF1 + - fvAp: + attributes: + name: Application1 + children: + - fvAEPg: + attributes: + name: WebTier + annotation: test:inchild + register: nm_add_tenant_annotation_children + - name: Verify annotation support assert: that: @@ -258,3 +292,7 @@ - nm_add_tenant_annotation_content.imdata.0.fvTenant.attributes.annotation == "test:incontent" - nm_add_tenant_annotation_option_content.imdata.0.fvTenant.attributes.annotation == "test:optionincontent" - nm_add_tag_no_annotation.imdata.0.tagTag.attributes.annotation is undefined + - nm_add_tenant_annotation_children.imdata.0.fvTenant.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.0.fvAp.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.0.fvAp.children.0.fvAEPg.attributes.annotation == "test:inchild" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.2.fvCtx.attributes.annotation == "test:inoption" diff --git a/tests/integration/targets/aci_rest/tasks/yaml_string.yml b/tests/integration/targets/aci_rest/tasks/yaml_string.yml index beb1fad54..f1b6c847b 100644 --- a/tests/integration/targets/aci_rest/tasks/yaml_string.yml +++ b/tests/integration/targets/aci_rest/tasks/yaml_string.yml @@ -251,10 +251,48 @@ value: bar register: nm_add_tag_no_annotation +- name: Remove tenant + cisco.aci.aci_rest: *tenant_absent + +- name: Add tenant with children objects including annotation + cisco.aci.aci_rest: + host: '{{ aci_hostname }}' + username: '{{ aci_username }}' + password: '{{ aci_password }}' + validate_certs: '{{ aci_validate_certs | default(false) }}' + use_ssl: '{{ aci_use_ssl | default(true) }}' + use_proxy: '{{ aci_use_proxy | default(true) }}' + output_level: '{{ aci_output_level | default("info") }}' + path: /api/mo/uni.json + method: post + annotation: test:inoption + content: | + fvTenant: + attributes: + descr: Ansible test tenant + name: ansible_test + children: + - fvCtx: + attributes: + name: VRF1 + - fvAp: + attributes: + name: Application1 + children: + - fvAEPg: + attributes: + name: WebTier + annotation: test:inchild + register: nm_add_tenant_annotation_children + - name: Verify annotation support assert: that: - nm_add_tenant_annotation_option.imdata.0.fvTenant.attributes.annotation == "test:inoption" - nm_add_tenant_annotation_content.imdata.0.fvTenant.attributes.annotation == "test:incontent" - nm_add_tenant_annotation_option_content.imdata.0.fvTenant.attributes.annotation == "test:optionincontent" - - nm_add_tag_no_annotation.imdata.0.tagTag.attributes.annotation is undefined \ No newline at end of file + - nm_add_tag_no_annotation.imdata.0.tagTag.attributes.annotation is undefined + - nm_add_tenant_annotation_children.imdata.0.fvTenant.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.0.fvAp.attributes.annotation == "test:inoption" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.0.fvAp.children.0.fvAEPg.attributes.annotation == "test:inchild" + - nm_add_tenant_annotation_children.imdata.0.fvTenant.children.2.fvCtx.attributes.annotation == "test:inoption" \ No newline at end of file From 50631e843aacc9a3460cc92182561768c9136e26 Mon Sep 17 00:00:00 2001 From: samitab Date: Mon, 4 Dec 2023 13:00:00 +1000 Subject: [PATCH 6/8] [ignore] Fix aci_rest xml_string tests --- tests/integration/targets/aci_rest/tasks/xml_string.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/integration/targets/aci_rest/tasks/xml_string.yml b/tests/integration/targets/aci_rest/tasks/xml_string.yml index 34e43abb7..42fd595be 100644 --- a/tests/integration/targets/aci_rest/tasks/xml_string.yml +++ b/tests/integration/targets/aci_rest/tasks/xml_string.yml @@ -74,10 +74,10 @@ that: - cm_add_tenant is changed - '"ansible_test" in cm_add_tenant.proposed' - - cm_add_tenant.proposed.fvTenant.attributes.annotation == "orchestrator:ansible" + - '"orchestrator:ansible" in cm_add_tenant.proposed' - cm_add_tenant_2 is changed - '"ansible_test" in cm_add_tenant_2.proposed' - - cm_add_tenant_2.proposed.fvTenant.attributes.annotation == "orchestrator:ansible" + - '"orchestrator:ansible" in cm_add_tenant_2.proposed' - cm_verify_checkmode_tenant.current == [] - name: Add tenant (normal mode) From 4afbe0f6747f8a3143d0b523578c0ef4596069b2 Mon Sep 17 00:00:00 2001 From: Samita B <98932546+samiib@users.noreply.github.com> Date: Tue, 5 Dec 2023 16:46:29 +1000 Subject: [PATCH 7/8] [ignore] fix xml_file tests Co-authored-by: Sabari Jaganathan <93724860+sajagana@users.noreply.github.com> --- tests/integration/targets/aci_rest/tasks/xml_file.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/targets/aci_rest/tasks/xml_file.yml b/tests/integration/targets/aci_rest/tasks/xml_file.yml index 0da42b009..7281251ea 100644 --- a/tests/integration/targets/aci_rest/tasks/xml_file.yml +++ b/tests/integration/targets/aci_rest/tasks/xml_file.yml @@ -50,7 +50,7 @@ that: - cm_add_tenant is changed - '"ans_test_create" in cm_add_tenant.proposed' - - cm_add_tenant.proposed.fvTenant.attributes.annotation == "orchestrator:ansible" + - '"orchestrator:ansible" in cm_add_tenant.proposed' - cm_verify_checkmode_tenant.current == [] - name: Add tenant using ans_test_create xml template file with normal mode From c6a7c6c20d66a49f0653fbd9f79251e64db829e0 Mon Sep 17 00:00:00 2001 From: samitab Date: Thu, 21 Dec 2023 10:12:10 +1000 Subject: [PATCH 8/8] [Ignore] Fix aci_rest error_on_input_validation assert after APIC version updates. --- tests/integration/targets/aci_rest/tasks/error_handling.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/targets/aci_rest/tasks/error_handling.yml b/tests/integration/targets/aci_rest/tasks/error_handling.yml index 48a3f92ff..2ea77b46f 100644 --- a/tests/integration/targets/aci_rest/tasks/error_handling.yml +++ b/tests/integration/targets/aci_rest/tasks/error_handling.yml @@ -114,7 +114,7 @@ that: - error_on_input_validation is failed - error_on_input_validation.method == 'POST' - - "error_on_input_validation.msg == 'APIC Error 801: property descr of tn-ansible_test failed validation for value \\'This is an [invalid] description\\''" + - "error_on_input_validation.msg is ansible.builtin.regex('APIC Error 801: property descr of.*tn-ansible_test failed validation for value \\'This is an \\[invalid\\] description\\'')" - 'error_on_input_validation.response == "HTTP Error 400: Bad Request"' - error_on_input_validation.status == 400 - "'current' not in error_on_input_validation"