Skip to content

Commit 10a328d

Browse files
committed
[minor change] Add support for annotation in aci_rest module (#437)
1 parent 96dddfe commit 10a328d

File tree

1 file changed

+33
-3
lines changed

1 file changed

+33
-3
lines changed

plugins/modules/aci_rest.py

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
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

89
from __future__ import absolute_import, division, print_function
@@ -62,6 +63,7 @@
6263
default: false
6364
extends_documentation_fragment:
6465
- cisco.aci.aci
66+
- cisco.aci.annotation
6567
6668
notes:
6769
- Certain payloads are known not to be idempotent, so be careful when constructing payloads,
@@ -73,6 +75,7 @@
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.
7679
seealso:
7780
- module: cisco.aci.aci_tenant
7881
- name: Cisco APIC REST API Configuration Guide
@@ -81,6 +84,7 @@
8184
author:
8285
- Dag Wieers (@dagwieers)
8386
- Cindy Zhao (@cizhao)
87+
- Samita Bhattacharjee (@samitab)
8488
"""
8589

8690
EXAMPLES = r"""
@@ -284,7 +288,7 @@
284288
HAS_YAML = False
285289

286290
from 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
288292
from 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+
306328
class 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

336358
def 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

Comments
 (0)