Skip to content

Commit

Permalink
[minor change] Add support for annotation in aci_rest module (#437)
Browse files Browse the repository at this point in the history
  • Loading branch information
samiib committed Oct 19, 2023
1 parent 96dddfe commit eae0317
Showing 1 changed file with 33 additions and 3 deletions.
36 changes: 33 additions & 3 deletions plugins/modules/aci_rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

# Copyright: (c) 2017, Dag Wieers (@dagwieers) <[email protected]>
# Copyright: (c) 2020, Cindy Zhao (@cizhao) <[email protected]>
# Copyright: (c) 2023, Samita Bhattacharjee (@samitab) <[email protected]>
# 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
Expand Down Expand Up @@ -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,
Expand All @@ -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
Expand All @@ -81,6 +84,7 @@
author:
- Dag Wieers (@dagwieers)
- Cindy Zhao (@cizhao)
- Samita Bhattacharjee (@samitab)
"""

EXAMPLES = r"""
Expand Down Expand Up @@ -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


Expand All @@ -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"""
Expand Down Expand Up @@ -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"]),
Expand All @@ -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
Expand Down Expand Up @@ -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)

Expand Down

0 comments on commit eae0317

Please sign in to comment.