33
44# Copyright: (c) 2017, Dag Wieers (@dagwieers) <dag@wieers.com>
55# Copyright: (c) 2020, Cindy Zhao (@cizhao) <cizhao@cisco.com>
6+ # Copyright: (c) 2023, Samita Bhattacharjee (@samitab) <samitab@cisco.com>
67# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)
78
89from __future__ import absolute_import , division , print_function
6263 default: false
6364extends_documentation_fragment:
6465- cisco.aci.aci
66+ - cisco.aci.annotation
6567
6668notes:
6769- Certain payloads are known not to be idempotent, so be careful when constructing payloads,
7375- XML payloads require the C(lxml) and C(xmljson) python libraries. For JSON payloads nothing special is needed.
7476- If you do not have any attributes, it may be necessary to add the "attributes" key with an empty dictionnary "{}" for value
7577 as the APIC does expect the entry to precede any children.
78+ - Annotation set directly in c(src) or C(content) will take precedent over the C(annotation) parameter.
7679seealso:
7780- module: cisco.aci.aci_tenant
7881- name: Cisco APIC REST API Configuration Guide
8184author:
8285- Dag Wieers (@dagwieers)
8386- Cindy Zhao (@cizhao)
87+ - Samita Bhattacharjee (@samitab)
8488"""
8589
8690EXAMPLES = r"""
284288 HAS_YAML = False
285289
286290from ansible .module_utils .basic import AnsibleModule
287- from ansible_collections .cisco .aci .plugins .module_utils .aci import ACIModule , aci_argument_spec
291+ from ansible_collections .cisco .aci .plugins .module_utils .aci import ACIModule , aci_argument_spec , aci_annotation_spec
288292from ansible .module_utils ._text import to_text
289293
290294
@@ -303,6 +307,24 @@ def update_qsl(url, params):
303307 return url + "?" + "&" .join (["%s=%s" % (k , v ) for k , v in params .items ()])
304308
305309
310+ def add_annotation (annotation , payload ):
311+ """Add annotation to payload only if it has not already been added"""
312+ if annotation :
313+ for _ , val in payload .items ():
314+ att = val .get ("attributes" , {})
315+ if "annotation" not in att .keys ():
316+ att ["annotation" ] = annotation
317+
318+
319+ def add_annotation_xml (annotation , tree ):
320+ """Add annotation to payload xml only if it has not already been added"""
321+ if annotation :
322+ for element in tree .iter ():
323+ ann = element .get ("annotation" )
324+ if ann is None :
325+ element .set ("annotation" , annotation )
326+
327+
306328class ACIRESTModule (ACIModule ):
307329 def changed (self , d ):
308330 """Check ACI response for changes"""
@@ -335,6 +357,7 @@ def response_type(self, rawoutput, rest_type="xml"):
335357
336358def main ():
337359 argument_spec = aci_argument_spec ()
360+ argument_spec .update (aci_annotation_spec ())
338361 argument_spec .update (
339362 path = dict (type = "str" , required = True , aliases = ["uri" ]),
340363 method = dict (type = "str" , default = "get" , choices = ["delete" , "get" , "post" ], aliases = ["action" ]),
@@ -353,6 +376,7 @@ def main():
353376 path = module .params .get ("path" )
354377 src = module .params .get ("src" )
355378 rsp_subtree_preserve = module .params .get ("rsp_subtree_preserve" )
379+ annotation = module .params .get ("annotation" )
356380
357381 # Report missing file
358382 file_exists = False
@@ -388,21 +412,27 @@ def main():
388412 if rest_type == "json" :
389413 if content and isinstance (content , dict ):
390414 # Validate inline YAML/JSON
415+ add_annotation (annotation , payload )
391416 payload = json .dumps (payload )
392417 elif payload and isinstance (payload , str ) and HAS_YAML :
393418 try :
394419 # Validate YAML/JSON string
395- payload = json .dumps (yaml .safe_load (payload ))
420+ payload = yaml .safe_load (payload )
421+ add_annotation (annotation , payload )
422+ payload = json .dumps (payload )
396423 except Exception as e :
397424 module .fail_json (msg = "Failed to parse provided JSON/YAML payload: {0}" .format (to_text (e )), exception = to_text (e ), payload = payload )
398425 elif rest_type == "xml" and HAS_LXML_ETREE :
399426 if content and isinstance (content , dict ) and HAS_XMLJSON_COBRA :
400427 # Validate inline YAML/JSON
428+ add_annotation (annotation , payload )
401429 payload = etree .tostring (cobra .etree (payload )[0 ], encoding = "unicode" )
402430 elif payload and isinstance (payload , str ):
403431 try :
404432 # Validate XML string
405- payload = etree .tostring (etree .fromstring (payload ), encoding = "unicode" )
433+ payload = etree .fromstring (payload )
434+ add_annotation_xml (annotation , payload )
435+ payload = etree .tostring (payload , encoding = "unicode" )
406436 except Exception as e :
407437 module .fail_json (msg = "Failed to parse provided XML payload: {0}" .format (to_text (e )), payload = payload )
408438
0 commit comments