From df95adee41157f5a35fdb1a44ea7e0611ac27f65 Mon Sep 17 00:00:00 2001 From: Sabari Jaganathan <93724860+sajagana@users.noreply.github.com> Date: Tue, 19 Nov 2024 22:03:10 +0530 Subject: [PATCH] [ignore] Updated the append_update_ops_data function logic --- plugins/module_utils/utils.py | 77 +++++++++++++++---- .../ndo_l3out_interface_routing_policy.py | 77 +++++++++++-------- 2 files changed, 109 insertions(+), 45 deletions(-) diff --git a/plugins/module_utils/utils.py b/plugins/module_utils/utils.py index 5bc75bca..141e3f5f 100644 --- a/plugins/module_utils/utils.py +++ b/plugins/module_utils/utils.py @@ -30,50 +30,101 @@ def generate_api_endpoint(path, **kwargs): return path if not kwargs else "{0}?{1}".format(path, "&".join(["{0}={1}".format(key, value) for key, value in kwargs.items()])) -def append_update_ops_data(ops, existing_data, update_path, value, *args, op="replace"): +def append_update_ops_data(ops, existing_data, update_path, value, *attributes, op="replace"): """ Append Update ops payload data. :param ops: Variable which contains the PATCH replace actions for the update operation -> List :param existing_data: Variable which contains the existing data -> Dict :param update_path: The object path is used to update an existing object -> Str :param value: Input value of the attribute which needs to be updated -> Any - :param args: Extra arguments which is used to compare and update the existing data -> Any + :param attributes: Additional positional arguments which is used to compare and update the existing data based on the sequence of keys -> Any :param op: Defaults to "replace" when not specified, value "remove" is used clear the existing configuration -> Str :return: None If args is not empty then the ops and existing_data are updated with the input value. + + Sample Inputs: + ops = [] + existing_data = { + "name": "L3OutInterfacePolicy", + "bfdMultiHopPol": { + "adminState": "enabled", + "detectionMultiplier": 3, + "minRxInterval": 250, + "minTxInterval": 250 + }, + } + update_path = "/tenantPolicyTemplate/template/l3OutIntfPolGroups/0" + + Sample attributes input format: + To update the "bfdMultiHopPol -> adminState" value: + attributes = "bfdMultiHopPol", "adminState" + + To update the top level key of the existing object: + append_update_ops_data(ops, existing_data, update_path, "L3OutInterfacePolicy_NameUpdated", "name", op="replace") + + To create the nested object from the scratch when the object is not available: + append_update_ops_data(ops, existing_data, update_path, dict(), "ospfIntfPol", op="replace") + append_update_ops_data(ops, existing_data, update_path, dict(), "ospfIntfPol", "ifControl", op="replace") + append_update_ops_data(ops, existing_data, update_path, True, "ospfIntfPol", "ifControl", "ignoreMtu", op="replace") + + After inserting the new object: + existing_data = { + "name": "L3OutInterfacePolicy", + "ospfIntfPol": { + "networkType": "broadcast", + "prio": 1, + "cost": 0, + "ifControl": { + "advertiseSubnet": false, + "bfd": false, + "ignoreMtu": false, + "passiveParticipation": false + }, + "helloInterval": 10, + "deadInterval": 40, + "retransmitInterval": 5, + "transmitDelay": 1 + }, + } + + To update the nested key of the existing object: + append_update_ops_data(ops, existing_data, update_path, True, "ospfIntfPol", "ifControl", "ignoreMtu", op="replace") + + To delete the nested object from the existing object: + append_update_ops_data(ops, existing_data, update_path, None, "ospfIntfPol", "ifControl", op="remove") + + To delete the top level key from the existing object: + append_update_ops_data(ops, existing_data, update_path, None, "ospfIntfPol", op="remove") """ - def recursive_update(data, current_path, keys, new_value): + def recursive_update(data, path, keys, new_value): if len(keys) == 0: return key = keys[0] if len(keys) == 1: # Update the existing configuration - if new_value is not None and data.get(key) != new_value: + if new_value is not None and data.get(key) != new_value and op == "replace": data[key] = new_value ops.append( dict( op=op, - path="{}/{}".format(current_path, key), + path="{}/{}".format(path, key), value=copy.deepcopy(new_value), ) ) # Clear the existing configuration - elif op == "remove": - data.pop(key, None) + elif op == "remove" and key in data: + data.pop(key) ops.append( dict( op=op, - path="{}/{}".format(current_path, key), + path="{}/{}".format(path, key), ) ) elif key in data: - recursive_update(data[key], "{}/{}".format(current_path, key), keys[1:], new_value) + recursive_update(data[key], "{}/{}".format(path, key), keys[1:], new_value) if args: - if isinstance(args[0], tuple): - recursive_update(existing_data, update_path, args[0], value) - else: - recursive_update(existing_data, update_path, args, value) + recursive_update(existing_data, update_path, args, value) diff --git a/plugins/modules/ndo_l3out_interface_routing_policy.py b/plugins/modules/ndo_l3out_interface_routing_policy.py index cfa25267..de89103f 100644 --- a/plugins/modules/ndo_l3out_interface_routing_policy.py +++ b/plugins/modules/ndo_l3out_interface_routing_policy.py @@ -431,21 +431,20 @@ def main(): if mso.existing: proposed_payload = copy.deepcopy(mso.existing) - append_update_ops_data(ops, proposed_payload, interface_routing_policy_path, name, ("name")) + append_update_ops_data(ops, proposed_payload, interface_routing_policy_path, name, "name") - append_update_ops_data(ops, proposed_payload, interface_routing_policy_path, description, ("description")) + append_update_ops_data(ops, proposed_payload, interface_routing_policy_path, description, "description") # BFD MultiHop Settings if bfd_multi_hop_settings is not None: if bfd_multi_hop_settings.get("state") == "disabled" and proposed_payload.get("bfdMultiHopPol"): - append_update_ops_data(ops, proposed_payload, interface_routing_policy_path, None, ("bfdMultiHopPol"), op="remove") - + append_update_ops_data(ops, proposed_payload, interface_routing_policy_path, None, "bfdMultiHopPol", op="remove") elif bfd_multi_hop_settings.get("state") != "disabled": if not proposed_payload.get("bfdMultiHopPol"): - append_update_ops_data(ops, proposed_payload, interface_routing_policy_path, dict(), ("bfdMultiHopPol")) + append_update_ops_data(ops, proposed_payload, interface_routing_policy_path, dict(), "bfdMultiHopPol") append_update_ops_data( - ops, proposed_payload, interface_routing_policy_path, bfd_multi_hop_settings.get("admin_state"), ("bfdMultiHopPol", "adminState") + ops, proposed_payload, interface_routing_policy_path, bfd_multi_hop_settings.get("admin_state"), "bfdMultiHopPol", "adminState" ) append_update_ops_data( @@ -453,7 +452,8 @@ def main(): proposed_payload, interface_routing_policy_path, bfd_multi_hop_settings.get("detection_multiplier"), - ("bfdMultiHopPol", "detectionMultiplier"), + "bfdMultiHopPol", + "detectionMultiplier", ) append_update_ops_data( @@ -461,7 +461,8 @@ def main(): proposed_payload, interface_routing_policy_path, bfd_multi_hop_settings.get("min_receive_interval"), - ("bfdMultiHopPol", "minRxInterval"), + "bfdMultiHopPol", + "minRxInterval", ) append_update_ops_data( @@ -469,38 +470,39 @@ def main(): proposed_payload, interface_routing_policy_path, bfd_multi_hop_settings.get("min_transmit_interval"), - ("bfdMultiHopPol", "minTxInterval"), + "bfdMultiHopPol", + "minTxInterval", ) # BFD Settings if bfd_settings is not None: if bfd_settings.get("state") == "disabled" and proposed_payload.get("bfdPol"): - append_update_ops_data(ops, proposed_payload, interface_routing_policy_path, None, ("bfdPol"), op="remove") + append_update_ops_data(ops, proposed_payload, interface_routing_policy_path, None, "bfdPol", op="remove") elif bfd_settings.get("state") != "disabled": if not proposed_payload.get("bfdPol"): - append_update_ops_data(ops, proposed_payload, interface_routing_policy_path, dict(), ("bfdPol")) + append_update_ops_data(ops, proposed_payload, interface_routing_policy_path, dict(), "bfdPol") - append_update_ops_data(ops, proposed_payload, interface_routing_policy_path, bfd_settings.get("admin_state"), ("bfdPol", "adminState")) + append_update_ops_data(ops, proposed_payload, interface_routing_policy_path, bfd_settings.get("admin_state"), "bfdPol", "adminState") append_update_ops_data( - ops, proposed_payload, interface_routing_policy_path, bfd_settings.get("detection_multiplier"), ("bfdPol", "detectionMultiplier") + ops, proposed_payload, interface_routing_policy_path, bfd_settings.get("detection_multiplier"), "bfdPol", "detectionMultiplier" ) append_update_ops_data( - ops, proposed_payload, interface_routing_policy_path, bfd_settings.get("min_receive_interval"), ("bfdPol", "minRxInterval") + ops, proposed_payload, interface_routing_policy_path, bfd_settings.get("min_receive_interval"), "bfdPol", "minRxInterval" ) append_update_ops_data( - ops, proposed_payload, interface_routing_policy_path, bfd_settings.get("min_transmit_interval"), ("bfdPol", "minTxInterval") + ops, proposed_payload, interface_routing_policy_path, bfd_settings.get("min_transmit_interval"), "bfdPol", "minTxInterval" ) append_update_ops_data( - ops, proposed_payload, interface_routing_policy_path, bfd_settings.get("echo_receive_interval"), ("bfdPol", "echoRxInterval") + ops, proposed_payload, interface_routing_policy_path, bfd_settings.get("echo_receive_interval"), "bfdPol", "echoRxInterval" ) append_update_ops_data( - ops, proposed_payload, interface_routing_policy_path, bfd_settings.get("echo_admin_state"), ("bfdPol", "echoAdminState") + ops, proposed_payload, interface_routing_policy_path, bfd_settings.get("echo_admin_state"), "bfdPol", "echoAdminState" ) append_update_ops_data( @@ -508,41 +510,43 @@ def main(): proposed_payload, interface_routing_policy_path, ENABLED_DISABLED_BOOLEAN_MAP.get(bfd_settings.get("interface_control")), - ("bfdPol", "ifControl"), + "bfdPol", + "ifControl", ) # OSPF Interface Settings if ospf_interface_settings is not None: if ospf_interface_settings.get("state") == "disabled" and proposed_payload.get("ospfIntfPol"): - append_update_ops_data(ops, proposed_payload, interface_routing_policy_path, None, ("ospfIntfPol"), op="remove") + append_update_ops_data(ops, proposed_payload, interface_routing_policy_path, None, "ospfIntfPol", op="remove") elif ospf_interface_settings.get("state") != "disabled": if not proposed_payload.get("ospfIntfPol"): - append_update_ops_data(ops, proposed_payload, interface_routing_policy_path, dict(), ("ospfIntfPol")) - append_update_ops_data(ops, proposed_payload, interface_routing_policy_path, dict(), ("ospfIntfPol", "ifControl")) + append_update_ops_data(ops, proposed_payload, interface_routing_policy_path, dict(), "ospfIntfPol") + append_update_ops_data(ops, proposed_payload, interface_routing_policy_path, dict(), "ospfIntfPol", "ifControl") append_update_ops_data( ops, proposed_payload, interface_routing_policy_path, get_ospf_network_type(ospf_interface_settings.get("network_type")), - ("ospfIntfPol", "networkType"), + "ospfIntfPol", + "networkType", ) append_update_ops_data( - ops, proposed_payload, interface_routing_policy_path, ospf_interface_settings.get("priority"), ("ospfIntfPol", "prio") + ops, proposed_payload, interface_routing_policy_path, ospf_interface_settings.get("priority"), "ospfIntfPol", "prio" ) append_update_ops_data( - ops, proposed_payload, interface_routing_policy_path, ospf_interface_settings.get("cost_of_interface"), ("ospfIntfPol", "cost") + ops, proposed_payload, interface_routing_policy_path, ospf_interface_settings.get("cost_of_interface"), "ospfIntfPol", "cost" ) append_update_ops_data( - ops, proposed_payload, interface_routing_policy_path, ospf_interface_settings.get("hello_interval"), ("ospfIntfPol", "helloInterval") + ops, proposed_payload, interface_routing_policy_path, ospf_interface_settings.get("hello_interval"), "ospfIntfPol", "helloInterval" ) append_update_ops_data( - ops, proposed_payload, interface_routing_policy_path, ospf_interface_settings.get("dead_interval"), ("ospfIntfPol", "deadInterval") + ops, proposed_payload, interface_routing_policy_path, ospf_interface_settings.get("dead_interval"), "ospfIntfPol", "deadInterval" ) append_update_ops_data( @@ -550,11 +554,12 @@ def main(): proposed_payload, interface_routing_policy_path, ospf_interface_settings.get("retransmit_interval"), - ("ospfIntfPol", "retransmitInterval"), + "ospfIntfPol", + "retransmitInterval", ) append_update_ops_data( - ops, proposed_payload, interface_routing_policy_path, ospf_interface_settings.get("transmit_delay"), ("ospfIntfPol", "transmitDelay") + ops, proposed_payload, interface_routing_policy_path, ospf_interface_settings.get("transmit_delay"), "ospfIntfPol", "transmitDelay" ) append_update_ops_data( @@ -562,7 +567,9 @@ def main(): proposed_payload, interface_routing_policy_path, ENABLED_DISABLED_BOOLEAN_MAP.get(ospf_interface_settings.get("advertise_subnet")), - ("ospfIntfPol", "ifControl", "advertiseSubnet"), + "ospfIntfPol", + "ifControl", + "advertiseSubnet", ) append_update_ops_data( @@ -570,7 +577,9 @@ def main(): proposed_payload, interface_routing_policy_path, ENABLED_DISABLED_BOOLEAN_MAP.get(ospf_interface_settings.get("bfd")), - ("ospfIntfPol", "ifControl", "bfd"), + "ospfIntfPol", + "ifControl", + "bfd", ) append_update_ops_data( @@ -578,7 +587,9 @@ def main(): proposed_payload, interface_routing_policy_path, ENABLED_DISABLED_BOOLEAN_MAP.get(ospf_interface_settings.get("mtu_ignore")), - ("ospfIntfPol", "ifControl", "ignoreMtu"), + "ospfIntfPol", + "ifControl", + "ignoreMtu", ) append_update_ops_data( @@ -586,7 +597,9 @@ def main(): proposed_payload, interface_routing_policy_path, ENABLED_DISABLED_BOOLEAN_MAP.get(ospf_interface_settings.get("passive_participation")), - ("ospfIntfPol", "ifControl", "passiveParticipation"), + "ospfIntfPol", + "ifControl", + "passiveParticipation", ) mso.sanitize(proposed_payload)