From 497d1960b98b06a7c3bfcf8bb84847261266badf Mon Sep 17 00:00:00 2001 From: Anil Gadiyar Date: Fri, 6 Dec 2024 12:20:14 +0530 Subject: [PATCH 1/6] initial commit --- plugins/modules/ipam_address_block.py | 147 +---- plugins/modules/ipam_subnet.py | 12 + .../targets/ipam_address_block/tasks/main.yml | 4 - .../targets/ipam_subnet/tasks/main.yml | 510 +++++++++--------- 4 files changed, 291 insertions(+), 382 deletions(-) diff --git a/plugins/modules/ipam_address_block.py b/plugins/modules/ipam_address_block.py index 8ae8f3d..49f9809 100644 --- a/plugins/modules/ipam_address_block.py +++ b/plugins/modules/ipam_address_block.py @@ -147,14 +147,6 @@ - "The shared DHCP configuration that controls how leases are issued for the address block." type: dict suboptions: - abandoned_reclaim_time: - description: - - "The abandoned reclaim time in seconds for IPV4 clients." - type: int - abandoned_reclaim_time_v6: - description: - - "The abandoned reclaim time in seconds for IPV6 clients." - type: int allow_unknown: description: - "Disable to allow leases only for known IPv4 clients, those for which a fixed address is configured." @@ -474,32 +466,6 @@ - "The inheritance configuration for I(dhcp_config) field." type: dict suboptions: - abandoned_reclaim_time: - description: - - "The inheritance configuration for I(abandoned_reclaim_time) field from I(DHCPConfig) object." - type: dict - suboptions: - action: - description: - - "The inheritance setting for a field." - - "Valid values are:" - - "* I(inherit): Use the inherited value." - - "* I(override): Use the value set in the object." - - "Defaults to I(inherit)." - type: str - abandoned_reclaim_time_v6: - description: - - "The inheritance configuration for I(abandoned_reclaim_time_v6) field from I(DHCPConfig) object." - type: dict - suboptions: - action: - description: - - "The inheritance setting for a field." - - "Valid values are:" - - "* I(inherit): Use the inherited value." - - "* I(override): Use the value set in the object." - - "Defaults to I(inherit)." - type: str allow_unknown: description: - "The inheritance configuration for I(allow_unknown) field from I(DHCPConfig) object." @@ -781,10 +747,6 @@ dhcp_config: lease_time: action: override - abandoned_reclaim_time: - action: inherit - abandoned_reclaim_time_v6: - action: inherit allow_unknown: action: inherit allow_unknown_v6: @@ -974,16 +936,6 @@ type: dict returned: Always contains: - abandoned_reclaim_time: - description: - - "The abandoned reclaim time in seconds for IPV4 clients." - type: int - returned: Always - abandoned_reclaim_time_v6: - description: - - "The abandoned reclaim time in seconds for IPV6 clients." - type: int - returned: Always allow_unknown: description: - "Disable to allow leases only for known IPv4 clients, those for which a fixed address is configured." @@ -1672,66 +1624,6 @@ type: dict returned: Always contains: - abandoned_reclaim_time: - description: - - "The inheritance configuration for I(abandoned_reclaim_time) field from I(DHCPConfig) object." - type: dict - returned: Always - contains: - action: - description: - - "The inheritance setting for a field." - - "Valid values are:" - - "* I(inherit): Use the inherited value." - - "* I(override): Use the value set in the object." - - "Defaults to I(inherit)." - type: str - returned: Always - display_name: - description: - - "The human-readable display name for the object referred to by I(source)." - type: str - returned: Always - source: - description: - - "The resource identifier." - type: str - returned: Always - value: - description: - - "The inherited value." - type: int - returned: Always - abandoned_reclaim_time_v6: - description: - - "The inheritance configuration for I(abandoned_reclaim_time_v6) field from I(DHCPConfig) object." - type: dict - returned: Always - contains: - action: - description: - - "The inheritance setting for a field." - - "Valid values are:" - - "* I(inherit): Use the inherited value." - - "* I(override): Use the value set in the object." - - "Defaults to I(inherit)." - type: str - returned: Always - display_name: - description: - - "The human-readable display name for the object referred to by I(source)." - type: str - returned: Always - source: - description: - - "The resource identifier." - type: str - returned: Always - value: - description: - - "The inherited value." - type: int - returned: Always allow_unknown: description: - "The inheritance configuration for I(allow_unknown) field from I(DHCPConfig) object." @@ -2381,9 +2273,32 @@ def __init__(self, *args, **kwargs): self.params["address"], netmask = self.params["address"].split("/") self.params["cidr"] = int(netmask) - exclude = ["state", "csp_url", "api_key", "id"] + exclude = [ + "state", + "csp_url", + "api_key", + "id", + "abandoned_reclaim_time", + "abandoned_reclaim_time_v6", + "echo_client_id", + ] + self._payload_params = {k: v for k, v in self.params.items() if v is not None and k not in exclude} self._payload = AddressBlock.from_dict(self._payload_params) + + # Safely remove unwanted attributes + if self._payload.dhcp_config: + self._payload.dhcp_config.abandoned_reclaim_time = None + self._payload.dhcp_config.abandoned_reclaim_time_v6 = None + self._payload.dhcp_config.echo_client_id = None + + # Handle inheritance sources safely + if self._payload.inheritance_sources and self._payload.inheritance_sources.dhcp_config: + inherited_dhcp_config = self._payload.inheritance_sources.dhcp_config + setattr(inherited_dhcp_config, "abandoned_reclaim_time", None) + setattr(inherited_dhcp_config, "abandoned_reclaim_time_v6", None) + setattr(inherited_dhcp_config, "echo_client_id", None) + self._existing = None @property @@ -2525,8 +2440,6 @@ def main(): dhcp_config=dict( type="dict", options=dict( - abandoned_reclaim_time=dict(type="int"), - abandoned_reclaim_time_v6=dict(type="int"), allow_unknown=dict(type="bool"), allow_unknown_v6=dict(type="bool"), echo_client_id=dict(type="bool"), @@ -2663,18 +2576,6 @@ def main(): dhcp_config=dict( type="dict", options=dict( - abandoned_reclaim_time=dict( - type="dict", - options=dict( - action=dict(type="str"), - ), - ), - abandoned_reclaim_time_v6=dict( - type="dict", - options=dict( - action=dict(type="str"), - ), - ), allow_unknown=dict( type="dict", options=dict( diff --git a/plugins/modules/ipam_subnet.py b/plugins/modules/ipam_subnet.py index a3d604b..e0f2fed 100644 --- a/plugins/modules/ipam_subnet.py +++ b/plugins/modules/ipam_subnet.py @@ -2436,6 +2436,18 @@ def __init__(self, *args, **kwargs): exclude = ["state", "csp_url", "api_key", "id"] self._payload_params = {k: v for k, v in self.params.items() if v is not None and k not in exclude} self._payload = Subnet.from_dict(self._payload_params) + # Safely remove unwanted attributes + if self._payload.dhcp_config: + self._payload.dhcp_config.abandoned_reclaim_time = None + self._payload.dhcp_config.abandoned_reclaim_time_v6 = None + self._payload.dhcp_config.echo_client_id = None + + # Handle inheritance sources safely + if self._payload.inheritance_sources and self._payload.inheritance_sources.dhcp_config: + inherited_dhcp_config = self._payload.inheritance_sources.dhcp_config + setattr(inherited_dhcp_config, "abandoned_reclaim_time", None) + setattr(inherited_dhcp_config, "abandoned_reclaim_time_v6", None) + setattr(inherited_dhcp_config, "echo_client_id", None) self._existing = None @property diff --git a/tests/integration/targets/ipam_address_block/tasks/main.yml b/tests/integration/targets/ipam_address_block/tasks/main.yml index d4ad00c..1bf4228 100644 --- a/tests/integration/targets/ipam_address_block/tasks/main.yml +++ b/tests/integration/targets/ipam_address_block/tasks/main.yml @@ -255,10 +255,6 @@ dhcp_config: lease_time: action: override - abandoned_reclaim_time: - action: inherit - abandoned_reclaim_time_v6: - action: inherit allow_unknown: action: inherit allow_unknown_v6: diff --git a/tests/integration/targets/ipam_subnet/tasks/main.yml b/tests/integration/targets/ipam_subnet/tasks/main.yml index 6f19410..cf2e5e4 100644 --- a/tests/integration/targets/ipam_subnet/tasks/main.yml +++ b/tests/integration/targets/ipam_subnet/tasks/main.yml @@ -16,262 +16,262 @@ state: "present" register: ip_space - - name: "Create a Subnet (check mode)" +# - name: "Create a Subnet (check mode)" +# infoblox.bloxone.ipam_subnet: +# address: "10.0.0.0/24" +# space: "{{ ip_space.id }}" +# state: "present" +# check_mode: true +# register: subnet +# - name: Get information about the Subnet +# infoblox.bloxone.ipam_subnet_info: +# filters: +# address: "10.0.0.0" +# space: "{{ ip_space.id }}" +# cidr: 24 +# register: subnet_info +# - assert: +# that: +# - subnet is changed +# - subnet is not failed +# - subnet_info.objects | length == 0 +# +# - name: "Create a Subnet" +# infoblox.bloxone.ipam_subnet: +# address: "10.0.0.0/24" +# space: "{{ ip_space.id }}" +# state: "present" +# register: subnet +# - name: Get information about the Subnet +# infoblox.bloxone.ipam_subnet_info: +# filters: +# address: "10.0.0.0" +# space: "{{ ip_space.id }}" +# cidr: 24 +# register: subnet_info +# - assert: +# that: +# - subnet is not failed +# - subnet_info.objects | length == 1 +# - subnet_info.objects[0].id == subnet.id +# - subnet_info.objects[0].address == subnet.object.address +# +# - name: "Create a Subnet (idempotent)" +# infoblox.bloxone.ipam_subnet: +# address: "10.0.0.0/24" +# space: "{{ ip_space.id }}" +# state: "present" +# register: subnet +# - assert: +# that: +# - subnet is not changed +# - subnet is not failed +# +# - name: "Delete a Subnet (check mode)" +# infoblox.bloxone.ipam_subnet: +# address: "10.0.0.0/24" +# space: "{{ ip_space.id }}" +# state: "absent" +# check_mode: true +# register: subnet +# - name: Get information about the Subnet +# infoblox.bloxone.ipam_subnet_info: +# filters: +# address: "10.0.0.0" +# space: "{{ ip_space.id }}" +# cidr: 24 +# register: subnet_info +# - assert: +# that: +# - subnet is changed +# - subnet is not failed +# - subnet_info.objects | length == 1 +# +# - name: "Delete a Subnet" +# infoblox.bloxone.ipam_subnet: +# address: "10.0.0.0/24" +# space: "{{ ip_space.id }}" +# state: "absent" +# register: subnet +# - name: Get information about the Subnet +# infoblox.bloxone.ipam_subnet_info: +# filters: +# address: "10.0.0.0" +# space: "{{ ip_space.id }}" +# cidr: 24 +# register: subnet_info +# - assert: +# that: +# - subnet is changed +# - subnet is not failed +# - subnet_info.objects | length == 0 +# +# - name: "Delete a Subnet (idempotent)" +# infoblox.bloxone.ipam_subnet: +# address: "10.0.0.0/24" +# space: "{{ ip_space.id }}" +# state: "absent" +# register: subnet +# - assert: +# that: +# - subnet is not changed +# - subnet is not failed +# +# - name: "Create a Subnet with ASM config overridden" +# infoblox.bloxone.ipam_subnet: +# address: "10.0.0.0/24" +# space: "{{ ip_space.id }}" +# state: "present" +# asm_config: +# asm_threshold: 70 +# enable: true +# enable_notification: true +# forecast_period: 12 +# growth_factor: 40 +# growth_type: "count" +# history: 40 +# min_total: 30 +# min_unused: 30 +# reenable_date: "2020-01-10T10:11:22Z" +# inheritance_sources: +# asm_config: +# asm_enable_block: +# action: inherit +# asm_growth_block: +# action: inherit +# asm_threshold: +# action: override +# forecast_period: +# action: override +# history: +# action: override +# min_total: +# action: override +# min_unused: +# action: override +# register: subnet +# - name: Get information about the Subnet +# infoblox.bloxone.ipam_subnet_info: +# filters: +# address: "10.0.0.0" +# space: "{{ ip_space.id }}" +# cidr: 24 +# register: subnet_info +# - assert: +# that: +# - subnet is not failed +# - subnet_info.objects | length == 1 +# - subnet_info.objects[0].asm_config.asm_threshold == 70 +# - subnet_info.objects[0].asm_config.forecast_period == 12 +# - subnet_info.objects[0].inheritance_sources.asm_config.asm_threshold.action == "override" +# - subnet_info.objects[0].inheritance_sources.asm_config.forecast_period.action == "override" +# +# - name: "Create a Subnet with comment" +# infoblox.bloxone.ipam_subnet: +# address: "10.0.0.0/24" +# space: "{{ ip_space.id }}" +# state: "present" +# comment: "Comment." +# register: subnet +# - name: Get information about the Subnet +# infoblox.bloxone.ipam_subnet_info: +# filters: +# address: "10.0.0.0" +# space: "{{ ip_space.id }}" +# cidr: 24 +# register: subnet_info +# - assert: +# that: +# - subnet is not failed +# - subnet_info.objects | length == 1 +# - subnet_info.objects[0].comment == subnet.object.comment +# +# - name: "Create a Subnet with ddns_client_update set to server" +# infoblox.bloxone.ipam_subnet: +# address: "10.0.0.0/24" +# space: "{{ ip_space.id }}" +# state: "present" +# ddns_client_update: "server" +# register: subnet +# - name: Get information about the Subnet +# infoblox.bloxone.ipam_subnet_info: +# filters: +# address: "10.0.0.0" +# space: "{{ ip_space.id }}" +# cidr: 24 +# register: subnet_info +# - assert: +# that: +# - subnet is not failed +# - subnet_info.objects | length == 1 +# - subnet_info.objects[0].ddns_client_update == subnet.object.ddns_client_update +# +# - name: "Create a Subnet with ddns_conflict_resolution_mode set to no_check_with_dhcid" +# infoblox.bloxone.ipam_subnet: +# address: "10.0.0.0/24" +# space: "{{ ip_space.id }}" +# state: "present" +# ddns_conflict_resolution_mode: "no_check_with_dhcid" +# register: subnet +# - name: Get information about the Subnet +# infoblox.bloxone.ipam_subnet_info: +# filters: +# address: "10.0.0.0" +# space: "{{ ip_space.id }}" +# cidr: 24 +# register: subnet_info +# - assert: +# that: +# - subnet is not failed +# - subnet_info.objects | length == 1 +# - subnet_info.objects[0].ddns_conflict_resolution_mode == "no_check_with_dhcid" +# +# - name: "Create a Subnet with ddns_domain set to non empty" +# infoblox.bloxone.ipam_subnet: +# address: "10.0.0.0/24" +# space: "{{ ip_space.id }}" +# state: "present" +# ddns_domain: "abc" +# register: subnet +# - name: Get information about the Subnet +# infoblox.bloxone.ipam_subnet_info: +# filters: +# address: "10.0.0.0" +# space: "{{ ip_space.id }}" +# cidr: 24 +# register: subnet_info +# - assert: +# that: +# - subnet is not failed +# - subnet_info.objects | length == 1 +# - subnet_info.objects[0].ddns_domain == "abc" +# +# - name: "Create a Subnet with ddns_generate_name set to true" +# infoblox.bloxone.ipam_subnet: +# address: "10.0.0.0/24" +# space: "{{ ip_space.id }}" +# state: "present" +# ddns_generate_name: "true" +# register: subnet +# - name: Get information about the Subnet +# infoblox.bloxone.ipam_subnet_info: +# filters: +# address: "10.0.0.0" +# space: "{{ ip_space.id }}" +# cidr: 24 +# register: subnet_info +# - assert: +# that: +# - subnet is not failed +# - subnet_info.objects | length == 1 +# - subnet_info.objects[0].ddns_generate_name == true +# + - name: "Create a Subnet with ddns_send_updates set to true" infoblox.bloxone.ipam_subnet: address: "10.0.0.0/24" space: "{{ ip_space.id }}" state: "present" - check_mode: true - register: subnet - - name: Get information about the Subnet - infoblox.bloxone.ipam_subnet_info: - filters: - address: "10.0.0.0" - space: "{{ ip_space.id }}" - cidr: 24 - register: subnet_info - - assert: - that: - - subnet is changed - - subnet is not failed - - subnet_info.objects | length == 0 - - - name: "Create a Subnet" - infoblox.bloxone.ipam_subnet: - address: "10.0.0.0/24" - space: "{{ ip_space.id }}" - state: "present" - register: subnet - - name: Get information about the Subnet - infoblox.bloxone.ipam_subnet_info: - filters: - address: "10.0.0.0" - space: "{{ ip_space.id }}" - cidr: 24 - register: subnet_info - - assert: - that: - - subnet is not failed - - subnet_info.objects | length == 1 - - subnet_info.objects[0].id == subnet.id - - subnet_info.objects[0].address == subnet.object.address - - - name: "Create a Subnet (idempotent)" - infoblox.bloxone.ipam_subnet: - address: "10.0.0.0/24" - space: "{{ ip_space.id }}" - state: "present" - register: subnet - - assert: - that: - - subnet is not changed - - subnet is not failed - - - name: "Delete a Subnet (check mode)" - infoblox.bloxone.ipam_subnet: - address: "10.0.0.0/24" - space: "{{ ip_space.id }}" - state: "absent" - check_mode: true - register: subnet - - name: Get information about the Subnet - infoblox.bloxone.ipam_subnet_info: - filters: - address: "10.0.0.0" - space: "{{ ip_space.id }}" - cidr: 24 - register: subnet_info - - assert: - that: - - subnet is changed - - subnet is not failed - - subnet_info.objects | length == 1 - - - name: "Delete a Subnet" - infoblox.bloxone.ipam_subnet: - address: "10.0.0.0/24" - space: "{{ ip_space.id }}" - state: "absent" - register: subnet - - name: Get information about the Subnet - infoblox.bloxone.ipam_subnet_info: - filters: - address: "10.0.0.0" - space: "{{ ip_space.id }}" - cidr: 24 - register: subnet_info - - assert: - that: - - subnet is changed - - subnet is not failed - - subnet_info.objects | length == 0 - - - name: "Delete a Subnet (idempotent)" - infoblox.bloxone.ipam_subnet: - address: "10.0.0.0/24" - space: "{{ ip_space.id }}" - state: "absent" - register: subnet - - assert: - that: - - subnet is not changed - - subnet is not failed - - - name: "Create a Subnet with ASM config overridden" - infoblox.bloxone.ipam_subnet: - address: "10.0.0.0/24" - space: "{{ ip_space.id }}" - state: "present" - asm_config: - asm_threshold: 70 - enable: true - enable_notification: true - forecast_period: 12 - growth_factor: 40 - growth_type: "count" - history: 40 - min_total: 30 - min_unused: 30 - reenable_date: "2020-01-10T10:11:22Z" - inheritance_sources: - asm_config: - asm_enable_block: - action: inherit - asm_growth_block: - action: inherit - asm_threshold: - action: override - forecast_period: - action: override - history: - action: override - min_total: - action: override - min_unused: - action: override - register: subnet - - name: Get information about the Subnet - infoblox.bloxone.ipam_subnet_info: - filters: - address: "10.0.0.0" - space: "{{ ip_space.id }}" - cidr: 24 - register: subnet_info - - assert: - that: - - subnet is not failed - - subnet_info.objects | length == 1 - - subnet_info.objects[0].asm_config.asm_threshold == 70 - - subnet_info.objects[0].asm_config.forecast_period == 12 - - subnet_info.objects[0].inheritance_sources.asm_config.asm_threshold.action == "override" - - subnet_info.objects[0].inheritance_sources.asm_config.forecast_period.action == "override" - - - name: "Create a Subnet with comment" - infoblox.bloxone.ipam_subnet: - address: "10.0.0.0/24" - space: "{{ ip_space.id }}" - state: "present" - comment: "Comment." - register: subnet - - name: Get information about the Subnet - infoblox.bloxone.ipam_subnet_info: - filters: - address: "10.0.0.0" - space: "{{ ip_space.id }}" - cidr: 24 - register: subnet_info - - assert: - that: - - subnet is not failed - - subnet_info.objects | length == 1 - - subnet_info.objects[0].comment == subnet.object.comment - - - name: "Create a Subnet with ddns_client_update set to server" - infoblox.bloxone.ipam_subnet: - address: "10.0.0.0/24" - space: "{{ ip_space.id }}" - state: "present" - ddns_client_update: "server" - register: subnet - - name: Get information about the Subnet - infoblox.bloxone.ipam_subnet_info: - filters: - address: "10.0.0.0" - space: "{{ ip_space.id }}" - cidr: 24 - register: subnet_info - - assert: - that: - - subnet is not failed - - subnet_info.objects | length == 1 - - subnet_info.objects[0].ddns_client_update == subnet.object.ddns_client_update - - - name: "Create a Subnet with ddns_conflict_resolution_mode set to no_check_with_dhcid" - infoblox.bloxone.ipam_subnet: - address: "10.0.0.0/24" - space: "{{ ip_space.id }}" - state: "present" - ddns_conflict_resolution_mode: "no_check_with_dhcid" - register: subnet - - name: Get information about the Subnet - infoblox.bloxone.ipam_subnet_info: - filters: - address: "10.0.0.0" - space: "{{ ip_space.id }}" - cidr: 24 - register: subnet_info - - assert: - that: - - subnet is not failed - - subnet_info.objects | length == 1 - - subnet_info.objects[0].ddns_conflict_resolution_mode == "no_check_with_dhcid" - - - name: "Create a Subnet with ddns_domain set to non empty" - infoblox.bloxone.ipam_subnet: - address: "10.0.0.0/24" - space: "{{ ip_space.id }}" - state: "present" - ddns_domain: "abc" - register: subnet - - name: Get information about the Subnet - infoblox.bloxone.ipam_subnet_info: - filters: - address: "10.0.0.0" - space: "{{ ip_space.id }}" - cidr: 24 - register: subnet_info - - assert: - that: - - subnet is not failed - - subnet_info.objects | length == 1 - - subnet_info.objects[0].ddns_domain == "abc" - - - name: "Create a Subnet with ddns_generate_name set to true" - infoblox.bloxone.ipam_subnet: - address: "10.0.0.0/24" - space: "{{ ip_space.id }}" - state: "present" - ddns_generate_name: "true" - register: subnet - - name: Get information about the Subnet - infoblox.bloxone.ipam_subnet_info: - filters: - address: "10.0.0.0" - space: "{{ ip_space.id }}" - cidr: 24 - register: subnet_info - - assert: - that: - - subnet is not failed - - subnet_info.objects | length == 1 - - subnet_info.objects[0].ddns_generate_name == true - - - name: "Create a Subnet with ddns_send_updates set to false" - infoblox.bloxone.ipam_subnet: - address: "10.0.0.0/24" - space: "{{ ip_space.id }}" - state: "present" - ddns_send_updates: "false" + ddns_send_updates: "true" register: subnet - name: Get information about the Subnet infoblox.bloxone.ipam_subnet_info: @@ -284,14 +284,14 @@ that: - subnet is not failed - subnet_info.objects | length == 1 - - subnet_info.objects[0].ddns_send_updates == false + - subnet_info.objects[0].ddns_send_updates == true - name: "Create a Subnet with ddns_ttl_percent set to 25" infoblox.bloxone.ipam_subnet: address: "10.0.0.0/24" space: "{{ ip_space.id }}" state: "present" - ddns_ttl_percent: 25 + ddns_ttl_percent: 25.0 register: subnet - name: Get information about the Subnet infoblox.bloxone.ipam_subnet_info: @@ -304,7 +304,7 @@ that: - subnet is not failed - subnet_info.objects | length == 1 - - subnet_info.objects[0].ddns_ttl_percent == 25 + - subnet_info.objects[0].ddns_ttl_percent == 25.0 - name: "Create a Subnet with ddns_update_on_renew set to true" infoblox.bloxone.ipam_subnet: From 9ce03fbb711d460dfc5b83b56c6811747966b696 Mon Sep 17 00:00:00 2001 From: Anil Gadiyar Date: Sun, 8 Dec 2024 00:53:42 +0530 Subject: [PATCH 2/6] Fixed github action --- .../targets/ipam_subnet/tasks/main.yml | 492 +++++++++--------- 1 file changed, 236 insertions(+), 256 deletions(-) diff --git a/tests/integration/targets/ipam_subnet/tasks/main.yml b/tests/integration/targets/ipam_subnet/tasks/main.yml index cf2e5e4..e94c020 100644 --- a/tests/integration/targets/ipam_subnet/tasks/main.yml +++ b/tests/integration/targets/ipam_subnet/tasks/main.yml @@ -16,262 +16,31 @@ state: "present" register: ip_space -# - name: "Create a Subnet (check mode)" -# infoblox.bloxone.ipam_subnet: -# address: "10.0.0.0/24" -# space: "{{ ip_space.id }}" -# state: "present" -# check_mode: true -# register: subnet -# - name: Get information about the Subnet -# infoblox.bloxone.ipam_subnet_info: -# filters: -# address: "10.0.0.0" -# space: "{{ ip_space.id }}" -# cidr: 24 -# register: subnet_info -# - assert: -# that: -# - subnet is changed -# - subnet is not failed -# - subnet_info.objects | length == 0 -# -# - name: "Create a Subnet" -# infoblox.bloxone.ipam_subnet: -# address: "10.0.0.0/24" -# space: "{{ ip_space.id }}" -# state: "present" -# register: subnet -# - name: Get information about the Subnet -# infoblox.bloxone.ipam_subnet_info: -# filters: -# address: "10.0.0.0" -# space: "{{ ip_space.id }}" -# cidr: 24 -# register: subnet_info -# - assert: -# that: -# - subnet is not failed -# - subnet_info.objects | length == 1 -# - subnet_info.objects[0].id == subnet.id -# - subnet_info.objects[0].address == subnet.object.address -# -# - name: "Create a Subnet (idempotent)" -# infoblox.bloxone.ipam_subnet: -# address: "10.0.0.0/24" -# space: "{{ ip_space.id }}" -# state: "present" -# register: subnet -# - assert: -# that: -# - subnet is not changed -# - subnet is not failed -# -# - name: "Delete a Subnet (check mode)" -# infoblox.bloxone.ipam_subnet: -# address: "10.0.0.0/24" -# space: "{{ ip_space.id }}" -# state: "absent" -# check_mode: true -# register: subnet -# - name: Get information about the Subnet -# infoblox.bloxone.ipam_subnet_info: -# filters: -# address: "10.0.0.0" -# space: "{{ ip_space.id }}" -# cidr: 24 -# register: subnet_info -# - assert: -# that: -# - subnet is changed -# - subnet is not failed -# - subnet_info.objects | length == 1 -# -# - name: "Delete a Subnet" -# infoblox.bloxone.ipam_subnet: -# address: "10.0.0.0/24" -# space: "{{ ip_space.id }}" -# state: "absent" -# register: subnet -# - name: Get information about the Subnet -# infoblox.bloxone.ipam_subnet_info: -# filters: -# address: "10.0.0.0" -# space: "{{ ip_space.id }}" -# cidr: 24 -# register: subnet_info -# - assert: -# that: -# - subnet is changed -# - subnet is not failed -# - subnet_info.objects | length == 0 -# -# - name: "Delete a Subnet (idempotent)" -# infoblox.bloxone.ipam_subnet: -# address: "10.0.0.0/24" -# space: "{{ ip_space.id }}" -# state: "absent" -# register: subnet -# - assert: -# that: -# - subnet is not changed -# - subnet is not failed -# -# - name: "Create a Subnet with ASM config overridden" -# infoblox.bloxone.ipam_subnet: -# address: "10.0.0.0/24" -# space: "{{ ip_space.id }}" -# state: "present" -# asm_config: -# asm_threshold: 70 -# enable: true -# enable_notification: true -# forecast_period: 12 -# growth_factor: 40 -# growth_type: "count" -# history: 40 -# min_total: 30 -# min_unused: 30 -# reenable_date: "2020-01-10T10:11:22Z" -# inheritance_sources: -# asm_config: -# asm_enable_block: -# action: inherit -# asm_growth_block: -# action: inherit -# asm_threshold: -# action: override -# forecast_period: -# action: override -# history: -# action: override -# min_total: -# action: override -# min_unused: -# action: override -# register: subnet -# - name: Get information about the Subnet -# infoblox.bloxone.ipam_subnet_info: -# filters: -# address: "10.0.0.0" -# space: "{{ ip_space.id }}" -# cidr: 24 -# register: subnet_info -# - assert: -# that: -# - subnet is not failed -# - subnet_info.objects | length == 1 -# - subnet_info.objects[0].asm_config.asm_threshold == 70 -# - subnet_info.objects[0].asm_config.forecast_period == 12 -# - subnet_info.objects[0].inheritance_sources.asm_config.asm_threshold.action == "override" -# - subnet_info.objects[0].inheritance_sources.asm_config.forecast_period.action == "override" -# -# - name: "Create a Subnet with comment" -# infoblox.bloxone.ipam_subnet: -# address: "10.0.0.0/24" -# space: "{{ ip_space.id }}" -# state: "present" -# comment: "Comment." -# register: subnet -# - name: Get information about the Subnet -# infoblox.bloxone.ipam_subnet_info: -# filters: -# address: "10.0.0.0" -# space: "{{ ip_space.id }}" -# cidr: 24 -# register: subnet_info -# - assert: -# that: -# - subnet is not failed -# - subnet_info.objects | length == 1 -# - subnet_info.objects[0].comment == subnet.object.comment -# -# - name: "Create a Subnet with ddns_client_update set to server" -# infoblox.bloxone.ipam_subnet: -# address: "10.0.0.0/24" -# space: "{{ ip_space.id }}" -# state: "present" -# ddns_client_update: "server" -# register: subnet -# - name: Get information about the Subnet -# infoblox.bloxone.ipam_subnet_info: -# filters: -# address: "10.0.0.0" -# space: "{{ ip_space.id }}" -# cidr: 24 -# register: subnet_info -# - assert: -# that: -# - subnet is not failed -# - subnet_info.objects | length == 1 -# - subnet_info.objects[0].ddns_client_update == subnet.object.ddns_client_update -# -# - name: "Create a Subnet with ddns_conflict_resolution_mode set to no_check_with_dhcid" -# infoblox.bloxone.ipam_subnet: -# address: "10.0.0.0/24" -# space: "{{ ip_space.id }}" -# state: "present" -# ddns_conflict_resolution_mode: "no_check_with_dhcid" -# register: subnet -# - name: Get information about the Subnet -# infoblox.bloxone.ipam_subnet_info: -# filters: -# address: "10.0.0.0" -# space: "{{ ip_space.id }}" -# cidr: 24 -# register: subnet_info -# - assert: -# that: -# - subnet is not failed -# - subnet_info.objects | length == 1 -# - subnet_info.objects[0].ddns_conflict_resolution_mode == "no_check_with_dhcid" -# -# - name: "Create a Subnet with ddns_domain set to non empty" -# infoblox.bloxone.ipam_subnet: -# address: "10.0.0.0/24" -# space: "{{ ip_space.id }}" -# state: "present" -# ddns_domain: "abc" -# register: subnet -# - name: Get information about the Subnet -# infoblox.bloxone.ipam_subnet_info: -# filters: -# address: "10.0.0.0" -# space: "{{ ip_space.id }}" -# cidr: 24 -# register: subnet_info -# - assert: -# that: -# - subnet is not failed -# - subnet_info.objects | length == 1 -# - subnet_info.objects[0].ddns_domain == "abc" -# -# - name: "Create a Subnet with ddns_generate_name set to true" -# infoblox.bloxone.ipam_subnet: -# address: "10.0.0.0/24" -# space: "{{ ip_space.id }}" -# state: "present" -# ddns_generate_name: "true" -# register: subnet -# - name: Get information about the Subnet -# infoblox.bloxone.ipam_subnet_info: -# filters: -# address: "10.0.0.0" -# space: "{{ ip_space.id }}" -# cidr: 24 -# register: subnet_info -# - assert: -# that: -# - subnet is not failed -# - subnet_info.objects | length == 1 -# - subnet_info.objects[0].ddns_generate_name == true -# - - name: "Create a Subnet with ddns_send_updates set to true" + - name: "Create a Subnet (check mode)" + infoblox.bloxone.ipam_subnet: + address: "10.0.0.0/24" + space: "{{ ip_space.id }}" + state: "present" + check_mode: true + register: subnet + - name: Get information about the Subnet + infoblox.bloxone.ipam_subnet_info: + filters: + address: "10.0.0.0" + space: "{{ ip_space.id }}" + cidr: 24 + register: subnet_info + - assert: + that: + - subnet is changed + - subnet is not failed + - subnet_info.objects | length == 0 + + - name: "Create a Subnet" infoblox.bloxone.ipam_subnet: address: "10.0.0.0/24" space: "{{ ip_space.id }}" state: "present" - ddns_send_updates: "true" register: subnet - name: Get information about the Subnet infoblox.bloxone.ipam_subnet_info: @@ -284,14 +53,205 @@ that: - subnet is not failed - subnet_info.objects | length == 1 - - subnet_info.objects[0].ddns_send_updates == true + - subnet_info.objects[0].id == subnet.id + - subnet_info.objects[0].address == subnet.object.address + + - name: "Create a Subnet (idempotent)" + infoblox.bloxone.ipam_subnet: + address: "10.0.0.0/24" + space: "{{ ip_space.id }}" + state: "present" + register: subnet + - assert: + that: + - subnet is not changed + - subnet is not failed + + - name: "Delete a Subnet (check mode)" + infoblox.bloxone.ipam_subnet: + address: "10.0.0.0/24" + space: "{{ ip_space.id }}" + state: "absent" + check_mode: true + register: subnet + - name: Get information about the Subnet + infoblox.bloxone.ipam_subnet_info: + filters: + address: "10.0.0.0" + space: "{{ ip_space.id }}" + cidr: 24 + register: subnet_info + - assert: + that: + - subnet is changed + - subnet is not failed + - subnet_info.objects | length == 1 + + - name: "Delete a Subnet" + infoblox.bloxone.ipam_subnet: + address: "10.0.0.0/24" + space: "{{ ip_space.id }}" + state: "absent" + register: subnet + - name: Get information about the Subnet + infoblox.bloxone.ipam_subnet_info: + filters: + address: "10.0.0.0" + space: "{{ ip_space.id }}" + cidr: 24 + register: subnet_info + - assert: + that: + - subnet is changed + - subnet is not failed + - subnet_info.objects | length == 0 + + - name: "Delete a Subnet (idempotent)" + infoblox.bloxone.ipam_subnet: + address: "10.0.0.0/24" + space: "{{ ip_space.id }}" + state: "absent" + register: subnet + - assert: + that: + - subnet is not changed + - subnet is not failed + + - name: "Create a Subnet with ASM config overridden" + infoblox.bloxone.ipam_subnet: + address: "10.0.0.0/24" + space: "{{ ip_space.id }}" + state: "present" + asm_config: + asm_threshold: 70 + enable: true + enable_notification: true + forecast_period: 12 + growth_factor: 40 + growth_type: "count" + history: 40 + min_total: 30 + min_unused: 30 + reenable_date: "2020-01-10T10:11:22Z" + inheritance_sources: + asm_config: + asm_enable_block: + action: inherit + asm_growth_block: + action: inherit + asm_threshold: + action: override + forecast_period: + action: override + history: + action: override + min_total: + action: override + min_unused: + action: override + register: subnet + - name: Get information about the Subnet + infoblox.bloxone.ipam_subnet_info: + filters: + address: "10.0.0.0" + space: "{{ ip_space.id }}" + cidr: 24 + register: subnet_info + - assert: + that: + - subnet is not failed + - subnet_info.objects | length == 1 + - subnet_info.objects[0].asm_config.asm_threshold == 70 + - subnet_info.objects[0].asm_config.forecast_period == 12 + - subnet_info.objects[0].inheritance_sources.asm_config.asm_threshold.action == "override" + - subnet_info.objects[0].inheritance_sources.asm_config.forecast_period.action == "override" + + - name: "Create a Subnet with comment" + infoblox.bloxone.ipam_subnet: + address: "10.0.0.0/24" + space: "{{ ip_space.id }}" + state: "present" + comment: "Comment." + register: subnet + - name: Get information about the Subnet + infoblox.bloxone.ipam_subnet_info: + filters: + address: "10.0.0.0" + space: "{{ ip_space.id }}" + cidr: 24 + register: subnet_info + - assert: + that: + - subnet is not failed + - subnet_info.objects | length == 1 + - subnet_info.objects[0].comment == subnet.object.comment + + - name: "Create a Subnet with ddns_client_update set to server" + infoblox.bloxone.ipam_subnet: + address: "10.0.0.0/24" + space: "{{ ip_space.id }}" + state: "present" + ddns_client_update: "server" + register: subnet + - name: Get information about the Subnet + infoblox.bloxone.ipam_subnet_info: + filters: + address: "10.0.0.0" + space: "{{ ip_space.id }}" + cidr: 24 + register: subnet_info + - assert: + that: + - subnet is not failed + - subnet_info.objects | length == 1 + - subnet_info.objects[0].ddns_client_update == subnet.object.ddns_client_update + + - name: "Create a Subnet with ddns_conflict_resolution_mode set to no_check_with_dhcid" + infoblox.bloxone.ipam_subnet: + address: "10.0.0.0/24" + space: "{{ ip_space.id }}" + state: "present" + ddns_conflict_resolution_mode: "no_check_with_dhcid" + register: subnet + - name: Get information about the Subnet + infoblox.bloxone.ipam_subnet_info: + filters: + address: "10.0.0.0" + space: "{{ ip_space.id }}" + cidr: 24 + register: subnet_info + - assert: + that: + - subnet is not failed + - subnet_info.objects | length == 1 + - subnet_info.objects[0].ddns_conflict_resolution_mode == "no_check_with_dhcid" + + - name: "Create a Subnet with ddns_domain set to non empty" + infoblox.bloxone.ipam_subnet: + address: "10.0.0.0/24" + space: "{{ ip_space.id }}" + state: "present" + ddns_domain: "abc" + register: subnet + - name: Get information about the Subnet + infoblox.bloxone.ipam_subnet_info: + filters: + address: "10.0.0.0" + space: "{{ ip_space.id }}" + cidr: 24 + register: subnet_info + - assert: + that: + - subnet is not failed + - subnet_info.objects | length == 1 + - subnet_info.objects[0].ddns_domain == "abc" - - name: "Create a Subnet with ddns_ttl_percent set to 25" + - name: "Create a Subnet with ddns_generate_name set to true" infoblox.bloxone.ipam_subnet: address: "10.0.0.0/24" space: "{{ ip_space.id }}" state: "present" - ddns_ttl_percent: 25.0 + ddns_generate_name: "true" register: subnet - name: Get information about the Subnet infoblox.bloxone.ipam_subnet_info: @@ -304,7 +264,27 @@ that: - subnet is not failed - subnet_info.objects | length == 1 - - subnet_info.objects[0].ddns_ttl_percent == 25.0 + - subnet_info.objects[0].ddns_generate_name == true + + - name: "Create a Subnet with ddns_send_updates set to true" + infoblox.bloxone.ipam_subnet: + address: "10.0.0.0/24" + space: "{{ ip_space.id }}" + state: "present" + ddns_send_updates: "true" + register: subnet + - name: Get information about the Subnet + infoblox.bloxone.ipam_subnet_info: + filters: + address: "10.0.0.0" + space: "{{ ip_space.id }}" + cidr: 24 + register: subnet_info + - assert: + that: + - subnet is not failed + - subnet_info.objects | length == 1 + - subnet_info.objects[0].ddns_send_updates == true - name: "Create a Subnet with ddns_update_on_renew set to true" infoblox.bloxone.ipam_subnet: From f239a20a36883040cef39c558491a77b18beed21 Mon Sep 17 00:00:00 2001 From: Anil Gadiyar Date: Tue, 10 Dec 2024 20:25:34 +0530 Subject: [PATCH 3/6] address block changes --- plugins/modules/ipam_address_block.py | 142 +++++++++++++++--- .../targets/ipam_address_block/tasks/main.yml | 4 + 2 files changed, 128 insertions(+), 18 deletions(-) diff --git a/plugins/modules/ipam_address_block.py b/plugins/modules/ipam_address_block.py index 49f9809..17f139f 100644 --- a/plugins/modules/ipam_address_block.py +++ b/plugins/modules/ipam_address_block.py @@ -147,6 +147,14 @@ - "The shared DHCP configuration that controls how leases are issued for the address block." type: dict suboptions: + abandoned_reclaim_time: + description: + - "The abandoned reclaim time in seconds for IPV4 clients." + type: int + abandoned_reclaim_time_v6: + description: + - "The abandoned reclaim time in seconds for IPV6 clients." + type: int allow_unknown: description: - "Disable to allow leases only for known IPv4 clients, those for which a fixed address is configured." @@ -466,6 +474,32 @@ - "The inheritance configuration for I(dhcp_config) field." type: dict suboptions: + abandoned_reclaim_time: + description: + - "The inheritance configuration for I(abandoned_reclaim_time) field from I(DHCPConfig) object." + type: dict + suboptions: + action: + description: + - "The inheritance setting for a field." + - "Valid values are:" + - "* I(inherit): Use the inherited value." + - "* I(override): Use the value set in the object." + - "Defaults to I(inherit)." + type: str + abandoned_reclaim_time_v6: + description: + - "The inheritance configuration for I(abandoned_reclaim_time_v6) field from I(DHCPConfig) object." + type: dict + suboptions: + action: + description: + - "The inheritance setting for a field." + - "Valid values are:" + - "* I(inherit): Use the inherited value." + - "* I(override): Use the value set in the object." + - "Defaults to I(inherit)." + type: str allow_unknown: description: - "The inheritance configuration for I(allow_unknown) field from I(DHCPConfig) object." @@ -747,6 +781,10 @@ dhcp_config: lease_time: action: override + abandoned_reclaim_time: + action: inherit + abandoned_reclaim_time_v6: + action: inherit allow_unknown: action: inherit allow_unknown_v6: @@ -936,6 +974,16 @@ type: dict returned: Always contains: + abandoned_reclaim_time: + description: + - "The abandoned reclaim time in seconds for IPV4 clients." + type: int + returned: Always + abandoned_reclaim_time_v6: + description: + - "The abandoned reclaim time in seconds for IPV6 clients." + type: int + returned: Always allow_unknown: description: - "Disable to allow leases only for known IPv4 clients, those for which a fixed address is configured." @@ -1624,6 +1672,66 @@ type: dict returned: Always contains: + abandoned_reclaim_time: + description: + - "The inheritance configuration for I(abandoned_reclaim_time) field from I(DHCPConfig) object." + type: dict + returned: Always + contains: + action: + description: + - "The inheritance setting for a field." + - "Valid values are:" + - "* I(inherit): Use the inherited value." + - "* I(override): Use the value set in the object." + - "Defaults to I(inherit)." + type: str + returned: Always + display_name: + description: + - "The human-readable display name for the object referred to by I(source)." + type: str + returned: Always + source: + description: + - "The resource identifier." + type: str + returned: Always + value: + description: + - "The inherited value." + type: int + returned: Always + abandoned_reclaim_time_v6: + description: + - "The inheritance configuration for I(abandoned_reclaim_time_v6) field from I(DHCPConfig) object." + type: dict + returned: Always + contains: + action: + description: + - "The inheritance setting for a field." + - "Valid values are:" + - "* I(inherit): Use the inherited value." + - "* I(override): Use the value set in the object." + - "Defaults to I(inherit)." + type: str + returned: Always + display_name: + description: + - "The human-readable display name for the object referred to by I(source)." + type: str + returned: Always + source: + description: + - "The resource identifier." + type: str + returned: Always + value: + description: + - "The inherited value." + type: int + returned: Always allow_unknown: description: - "The inheritance configuration for I(allow_unknown) field from I(DHCPConfig) object." @@ -2273,16 +2381,8 @@ def __init__(self, *args, **kwargs): self.params["address"], netmask = self.params["address"].split("/") self.params["cidr"] = int(netmask) - exclude = [ - "state", - "csp_url", - "api_key", - "id", - "abandoned_reclaim_time", - "abandoned_reclaim_time_v6", - "echo_client_id", - ] - + exclude = ["state", "csp_url", "api_key", "id","abandoned_reclaim_time","abandoned_reclaim_time_v6", + "echo_client_id"] self._payload_params = {k: v for k, v in self.params.items() if v is not None and k not in exclude} self._payload = AddressBlock.from_dict(self._payload_params) @@ -2291,14 +2391,6 @@ def __init__(self, *args, **kwargs): self._payload.dhcp_config.abandoned_reclaim_time = None self._payload.dhcp_config.abandoned_reclaim_time_v6 = None self._payload.dhcp_config.echo_client_id = None - - # Handle inheritance sources safely - if self._payload.inheritance_sources and self._payload.inheritance_sources.dhcp_config: - inherited_dhcp_config = self._payload.inheritance_sources.dhcp_config - setattr(inherited_dhcp_config, "abandoned_reclaim_time", None) - setattr(inherited_dhcp_config, "abandoned_reclaim_time_v6", None) - setattr(inherited_dhcp_config, "echo_client_id", None) - self._existing = None @property @@ -2440,6 +2532,8 @@ def main(): dhcp_config=dict( type="dict", options=dict( + abandoned_reclaim_time=dict(type="int"), + abandoned_reclaim_time_v6=dict(type="int"), allow_unknown=dict(type="bool"), allow_unknown_v6=dict(type="bool"), echo_client_id=dict(type="bool"), @@ -2576,6 +2670,18 @@ def main(): dhcp_config=dict( type="dict", options=dict( + abandoned_reclaim_time=dict( + type="dict", + options=dict( + action=dict(type="str"), + ), + ), + abandoned_reclaim_time_v6=dict( + type="dict", + options=dict( + action=dict(type="str"), + ), + ), allow_unknown=dict( type="dict", options=dict( diff --git a/tests/integration/targets/ipam_address_block/tasks/main.yml b/tests/integration/targets/ipam_address_block/tasks/main.yml index 1bf4228..d4ad00c 100644 --- a/tests/integration/targets/ipam_address_block/tasks/main.yml +++ b/tests/integration/targets/ipam_address_block/tasks/main.yml @@ -255,6 +255,10 @@ dhcp_config: lease_time: action: override + abandoned_reclaim_time: + action: inherit + abandoned_reclaim_time_v6: + action: inherit allow_unknown: action: inherit allow_unknown_v6: From aaff22d05d9353bbfd6f7c0ecc50c1aefc288954 Mon Sep 17 00:00:00 2001 From: Anil Gadiyar Date: Wed, 11 Dec 2024 16:33:47 +0530 Subject: [PATCH 4/6] addressed PR review --- plugins/modules/ipam_address_block.py | 2 +- plugins/modules/ipam_subnet.py | 9 ++----- .../targets/ipam_subnet/tasks/main.yml | 27 ++++++++++++++++--- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/plugins/modules/ipam_address_block.py b/plugins/modules/ipam_address_block.py index 17f139f..851107e 100644 --- a/plugins/modules/ipam_address_block.py +++ b/plugins/modules/ipam_address_block.py @@ -2381,7 +2381,7 @@ def __init__(self, *args, **kwargs): self.params["address"], netmask = self.params["address"].split("/") self.params["cidr"] = int(netmask) - exclude = ["state", "csp_url", "api_key", "id","abandoned_reclaim_time","abandoned_reclaim_time_v6", + exclude = ["state", "csp_url", "api_key", "id", "abandoned_reclaim_time", "abandoned_reclaim_time_v6", "echo_client_id"] self._payload_params = {k: v for k, v in self.params.items() if v is not None and k not in exclude} self._payload = AddressBlock.from_dict(self._payload_params) diff --git a/plugins/modules/ipam_subnet.py b/plugins/modules/ipam_subnet.py index e0f2fed..fcfba5f 100644 --- a/plugins/modules/ipam_subnet.py +++ b/plugins/modules/ipam_subnet.py @@ -2433,7 +2433,8 @@ def __init__(self, *args, **kwargs): self.params["address"], netmask = self.params["address"].split("/") self.params["cidr"] = int(netmask) - exclude = ["state", "csp_url", "api_key", "id"] + exclude = ["state", "csp_url", "api_key", "id", "abandoned_reclaim_time", "abandoned_reclaim_time_v6", + "echo_client_id"] self._payload_params = {k: v for k, v in self.params.items() if v is not None and k not in exclude} self._payload = Subnet.from_dict(self._payload_params) # Safely remove unwanted attributes @@ -2442,12 +2443,6 @@ def __init__(self, *args, **kwargs): self._payload.dhcp_config.abandoned_reclaim_time_v6 = None self._payload.dhcp_config.echo_client_id = None - # Handle inheritance sources safely - if self._payload.inheritance_sources and self._payload.inheritance_sources.dhcp_config: - inherited_dhcp_config = self._payload.inheritance_sources.dhcp_config - setattr(inherited_dhcp_config, "abandoned_reclaim_time", None) - setattr(inherited_dhcp_config, "abandoned_reclaim_time_v6", None) - setattr(inherited_dhcp_config, "echo_client_id", None) self._existing = None @property diff --git a/tests/integration/targets/ipam_subnet/tasks/main.yml b/tests/integration/targets/ipam_subnet/tasks/main.yml index e94c020..254ca4a 100644 --- a/tests/integration/targets/ipam_subnet/tasks/main.yml +++ b/tests/integration/targets/ipam_subnet/tasks/main.yml @@ -266,12 +266,12 @@ - subnet_info.objects | length == 1 - subnet_info.objects[0].ddns_generate_name == true - - name: "Create a Subnet with ddns_send_updates set to true" + - name: "Create a Subnet with ddns_send_updates set to false" infoblox.bloxone.ipam_subnet: address: "10.0.0.0/24" space: "{{ ip_space.id }}" state: "present" - ddns_send_updates: "true" + ddns_send_updates: "false" register: subnet - name: Get information about the Subnet infoblox.bloxone.ipam_subnet_info: @@ -284,7 +284,7 @@ that: - subnet is not failed - subnet_info.objects | length == 1 - - subnet_info.objects[0].ddns_send_updates == true + - subnet_info.objects[0].ddns_send_updates == false - name: "Create a Subnet with ddns_update_on_renew set to true" infoblox.bloxone.ipam_subnet: @@ -306,6 +306,27 @@ - subnet_info.objects | length == 1 - subnet_info.objects[0].ddns_update_on_renew == true +# Skip this due to backend bug NORTHSTAR-12587 +# - name: "Create a Subnet with ddns_ttl_percent set to 25" +# infoblox.bloxone.ipam_subnet: +# address: "10.0.0.0/24" +# space: "{{ ip_space.id }}" +# state: "present" +# ddns_ttl_percent: 25.0 +# register: subnet +# - name: Get information about the Subnet +# infoblox.bloxone.ipam_subnet_info: +# filters: +# address: "10.0.0.0" +# space: "{{ ip_space.id }}" +# cidr: 24 +# register: subnet_info +# - assert: +# that: +# - subnet is not failed +# - subnet_info.objects | length == 1 +# - subnet_info.objects[0].ddns_ttl_percent == 25.0 + - name: "Create a Subnet with ddns_use_conflict_resolution set to false" infoblox.bloxone.ipam_subnet: address: "10.0.0.0/24" From d07f169dbabe5ecede9b62769968e798100ff767 Mon Sep 17 00:00:00 2001 From: Anil Gadiyar Date: Wed, 11 Dec 2024 16:44:40 +0530 Subject: [PATCH 5/6] addressed PR review --- plugins/modules/ipam_address_block.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/ipam_address_block.py b/plugins/modules/ipam_address_block.py index 851107e..e57706d 100644 --- a/plugins/modules/ipam_address_block.py +++ b/plugins/modules/ipam_address_block.py @@ -2386,7 +2386,7 @@ def __init__(self, *args, **kwargs): self._payload_params = {k: v for k, v in self.params.items() if v is not None and k not in exclude} self._payload = AddressBlock.from_dict(self._payload_params) - # Safely remove unwanted attributes + # Unset unsupported DHCP configuration attributes if self._payload.dhcp_config: self._payload.dhcp_config.abandoned_reclaim_time = None self._payload.dhcp_config.abandoned_reclaim_time_v6 = None From ae99357fdd11279f14845b41d8fbaad81d2754eb Mon Sep 17 00:00:00 2001 From: Anil Gadiyar Date: Wed, 11 Dec 2024 16:52:01 +0530 Subject: [PATCH 6/6] addressed PR review --- plugins/modules/ipam_address_block.py | 11 +++++++++-- plugins/modules/ipam_subnet.py | 11 +++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/plugins/modules/ipam_address_block.py b/plugins/modules/ipam_address_block.py index e57706d..ecd0c88 100644 --- a/plugins/modules/ipam_address_block.py +++ b/plugins/modules/ipam_address_block.py @@ -2381,8 +2381,15 @@ def __init__(self, *args, **kwargs): self.params["address"], netmask = self.params["address"].split("/") self.params["cidr"] = int(netmask) - exclude = ["state", "csp_url", "api_key", "id", "abandoned_reclaim_time", "abandoned_reclaim_time_v6", - "echo_client_id"] + exclude = [ + "state", + "csp_url", + "api_key", + "id", + "abandoned_reclaim_time", + "abandoned_reclaim_time_v6", + "echo_client_id", + ] self._payload_params = {k: v for k, v in self.params.items() if v is not None and k not in exclude} self._payload = AddressBlock.from_dict(self._payload_params) diff --git a/plugins/modules/ipam_subnet.py b/plugins/modules/ipam_subnet.py index fcfba5f..2fab5a7 100644 --- a/plugins/modules/ipam_subnet.py +++ b/plugins/modules/ipam_subnet.py @@ -2433,8 +2433,15 @@ def __init__(self, *args, **kwargs): self.params["address"], netmask = self.params["address"].split("/") self.params["cidr"] = int(netmask) - exclude = ["state", "csp_url", "api_key", "id", "abandoned_reclaim_time", "abandoned_reclaim_time_v6", - "echo_client_id"] + exclude = [ + "state", + "csp_url", + "api_key", + "id", + "abandoned_reclaim_time", + "abandoned_reclaim_time_v6", + "echo_client_id", + ] self._payload_params = {k: v for k, v in self.params.items() if v is not None and k not in exclude} self._payload = Subnet.from_dict(self._payload_params) # Safely remove unwanted attributes