diff --git a/plugins/module_utils/utils.py b/plugins/module_utils/utils.py index 8acba289..5bc75bca 100644 --- a/plugins/module_utils/utils.py +++ b/plugins/module_utils/utils.py @@ -7,6 +7,8 @@ __metaclass__ = type +import copy + def generate_api_endpoint(path, **kwargs): """ @@ -28,7 +30,7 @@ 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): +def append_update_ops_data(ops, existing_data, update_path, value, *args, op="replace"): """ Append Update ops payload data. :param ops: Variable which contains the PATCH replace actions for the update operation -> List @@ -36,6 +38,7 @@ def append_update_ops_data(ops, existing_data, update_path, value, *args): :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 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. """ @@ -46,15 +49,26 @@ def recursive_update(data, current_path, keys, new_value): key = keys[0] if len(keys) == 1: + # Update the existing configuration if new_value is not None and data.get(key) != new_value: data[key] = new_value ops.append( dict( - op="replace", + op=op, path="{}/{}".format(current_path, key), - value=new_value, + value=copy.deepcopy(new_value), ) ) + # Clear the existing configuration + elif op == "remove": + data.pop(key, None) + ops.append( + dict( + op=op, + path="{}/{}".format(current_path, key), + ) + ) + elif key in data: recursive_update(data[key], "{}/{}".format(current_path, key), keys[1:], new_value) diff --git a/plugins/modules/ndo_l3out_interface_routing_policy.py b/plugins/modules/ndo_l3out_interface_routing_policy.py index 7d5fbc0c..cfa25267 100644 --- a/plugins/modules/ndo_l3out_interface_routing_policy.py +++ b/plugins/modules/ndo_l3out_interface_routing_policy.py @@ -438,13 +438,11 @@ def main(): # BFD MultiHop Settings if bfd_multi_hop_settings is not None: if bfd_multi_hop_settings.get("state") == "disabled" and proposed_payload.get("bfdMultiHopPol"): - proposed_payload.pop("bfdMultiHopPol", None) - ops.append(dict(op="remove", path="{0}/bfdMultiHopPol".format(interface_routing_policy_path))) + 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"): - proposed_payload["bfdMultiHopPol"] = dict() - ops.append(dict(op="replace", path="{0}/bfdMultiHopPol".format(interface_routing_policy_path), value=dict())) + 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") @@ -477,23 +475,12 @@ def main(): # BFD Settings if bfd_settings is not None: if bfd_settings.get("state") == "disabled" and proposed_payload.get("bfdPol"): - proposed_payload.pop("bfdPol", None) - ops.append(dict(op="remove", path="{0}/bfdPol".format(interface_routing_policy_path))) + 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"): - proposed_payload["bfdPol"] = dict() - ops.append(dict(op="replace", path="{0}/bfdPol".format(interface_routing_policy_path), value=dict())) - - if bfd_settings.get("admin_state") is not None and proposed_payload.get("bfdPol").get("adminState") != bfd_settings.get("admin_state"): - proposed_payload["bfdPol"]["adminState"] = bfd_settings.get("admin_state") - ops.append( - dict( - op="replace", - path="{0}/bfdPol/adminState".format(interface_routing_policy_path), - value=bfd_settings.get("admin_state"), - ) - ) + 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( @@ -516,26 +503,31 @@ def main(): ops, proposed_payload, interface_routing_policy_path, bfd_settings.get("echo_admin_state"), ("bfdPol", "echoAdminState") ) - interface_control_value = ENABLED_DISABLED_BOOLEAN_MAP.get(bfd_settings.get("interface_control")) - - append_update_ops_data(ops, proposed_payload, interface_routing_policy_path, interface_control_value, ("bfdPol", "ifControl")) + append_update_ops_data( + ops, + proposed_payload, + interface_routing_policy_path, + ENABLED_DISABLED_BOOLEAN_MAP.get(bfd_settings.get("interface_control")), + ("bfdPol", "ifControl"), + ) # OSPF Interface Settings if ospf_interface_settings is not None: if ospf_interface_settings.get("state") == "disabled" and proposed_payload.get("ospfIntfPol"): - proposed_payload.pop("ospfIntfPol", None) - ops.append(dict(op="remove", path="{0}/ospfIntfPol".format(interface_routing_policy_path))) + 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"): - proposed_payload["ospfIntfPol"] = dict() - proposed_payload["ospfIntfPol"]["ifControl"] = dict() - ops.append(dict(op="replace", path="{0}/ospfIntfPol".format(interface_routing_policy_path), value=dict())) - ops.append(dict(op="replace", path="{0}/ospfIntfPol/ifControl".format(interface_routing_policy_path), value=dict())) + 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")) - network_type_value = get_ospf_network_type(ospf_interface_settings.get("network_type")) - - append_update_ops_data(ops, proposed_payload, interface_routing_policy_path, network_type_value, ("ospfIntfPol", "networkType")) + append_update_ops_data( + ops, + proposed_payload, + interface_routing_policy_path, + get_ospf_network_type(ospf_interface_settings.get("network_type")), + ("ospfIntfPol", "networkType"), + ) append_update_ops_data( ops, proposed_payload, interface_routing_policy_path, ospf_interface_settings.get("priority"), ("ospfIntfPol", "prio") @@ -565,24 +557,36 @@ def main(): ops, proposed_payload, interface_routing_policy_path, ospf_interface_settings.get("transmit_delay"), ("ospfIntfPol", "transmitDelay") ) - advertise_subnet_value = ENABLED_DISABLED_BOOLEAN_MAP.get(ospf_interface_settings.get("advertise_subnet")) - append_update_ops_data( - ops, proposed_payload, interface_routing_policy_path, advertise_subnet_value, ("ospfIntfPol", "ifControl", "advertiseSubnet") + ops, + proposed_payload, + interface_routing_policy_path, + ENABLED_DISABLED_BOOLEAN_MAP.get(ospf_interface_settings.get("advertise_subnet")), + ("ospfIntfPol", "ifControl", "advertiseSubnet"), ) - bfd_value = ENABLED_DISABLED_BOOLEAN_MAP.get(ospf_interface_settings.get("bfd")) - - append_update_ops_data(ops, proposed_payload, interface_routing_policy_path, bfd_value, ("ospfIntfPol", "ifControl", "bfd")) - - mtu_ignore_value = ENABLED_DISABLED_BOOLEAN_MAP.get(ospf_interface_settings.get("mtu_ignore")) - - append_update_ops_data(ops, proposed_payload, interface_routing_policy_path, mtu_ignore_value, ("ospfIntfPol", "ifControl", "ignoreMtu")) + append_update_ops_data( + ops, + proposed_payload, + interface_routing_policy_path, + ENABLED_DISABLED_BOOLEAN_MAP.get(ospf_interface_settings.get("bfd")), + ("ospfIntfPol", "ifControl", "bfd"), + ) - passive_participation_value = ENABLED_DISABLED_BOOLEAN_MAP.get(ospf_interface_settings.get("passive_participation")) + append_update_ops_data( + ops, + proposed_payload, + interface_routing_policy_path, + ENABLED_DISABLED_BOOLEAN_MAP.get(ospf_interface_settings.get("mtu_ignore")), + ("ospfIntfPol", "ifControl", "ignoreMtu"), + ) append_update_ops_data( - ops, proposed_payload, interface_routing_policy_path, passive_participation_value, ("ospfIntfPol", "ifControl", "passiveParticipation") + ops, + proposed_payload, + interface_routing_policy_path, + ENABLED_DISABLED_BOOLEAN_MAP.get(ospf_interface_settings.get("passive_participation")), + ("ospfIntfPol", "ifControl", "passiveParticipation"), ) mso.sanitize(proposed_payload)