From 95482604eb15c86314577ecc0f3a299c40f985fb Mon Sep 17 00:00:00 2001 From: Zhiwei Liang <121905282+zliang-akamai@users.noreply.github.com> Date: Mon, 29 Apr 2024 13:45:18 -0400 Subject: [PATCH 1/4] Add VPC IP List Modules (#499) --- README.md | 2 + docs/modules/vpc_ip_list.md | 66 +++++++++ docs/modules/vpcs_ip_list.md | 65 +++++++++ .../module_utils/doc_fragments/vpc_ip_list.py | 27 ++++ .../doc_fragments/vpcs_ip_list.py | 27 ++++ plugins/modules/vpc_ip_list.py | 35 +++++ plugins/modules/vpcs_ip_list.py | 26 ++++ .../targets/vpc_ip_list/tasks/main.yaml | 133 ++++++++++++++++++ 8 files changed, 381 insertions(+) create mode 100644 docs/modules/vpc_ip_list.md create mode 100644 docs/modules/vpcs_ip_list.md create mode 100644 plugins/module_utils/doc_fragments/vpc_ip_list.py create mode 100644 plugins/module_utils/doc_fragments/vpcs_ip_list.py create mode 100644 plugins/modules/vpc_ip_list.py create mode 100644 plugins/modules/vpcs_ip_list.py create mode 100644 tests/integration/targets/vpc_ip_list/tasks/main.yaml diff --git a/README.md b/README.md index 5e31cc81..2633521a 100644 --- a/README.md +++ b/README.md @@ -106,8 +106,10 @@ Name | Description | [linode.cloud.user_list](./docs/modules/user_list.md)|List Users.| [linode.cloud.vlan_list](./docs/modules/vlan_list.md)|List and filter on Linode VLANs.| [linode.cloud.volume_list](./docs/modules/volume_list.md)|List and filter on Linode Volumes.| +[linode.cloud.vpc_ip_list](./docs/modules/vpc_ip_list.md)|List and filter on VPC IP Addresses.| [linode.cloud.vpc_list](./docs/modules/vpc_list.md)|List and filter on VPCs.| [linode.cloud.vpc_subnet_list](./docs/modules/vpc_subnet_list.md)|List and filter on VPC Subnets.| +[linode.cloud.vpcs_ip_list](./docs/modules/vpcs_ip_list.md)|List and filter on all VPC IP Addresses.| ### Inventory Plugins diff --git a/docs/modules/vpc_ip_list.md b/docs/modules/vpc_ip_list.md new file mode 100644 index 00000000..9ca51294 --- /dev/null +++ b/docs/modules/vpc_ip_list.md @@ -0,0 +1,66 @@ +# vpc_ip_list + +List and filter on VPC IP Addresses. + +- [Minimum Required Fields](#minimum-required-fields) +- [Examples](#examples) +- [Parameters](#parameters) +- [Return Values](#return-values) + +## Minimum Required Fields +| Field | Type | Required | Description | +|-------------|-------|--------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `api_token` | `str` | **Required** | The Linode account personal access token. It is necessary to run the module.
It can be exposed by the environment variable `LINODE_API_TOKEN` instead.
See details in [Usage](https://github.com/linode/ansible_linode?tab=readme-ov-file#usage). | + +## Examples + +```yaml +- name: List all IPs of a specific VPC. + linode.cloud.vpc_ip_list: + vpc_id: 12345 +``` + + +## Parameters + +| Field | Type | Required | Description | +|-----------|------|----------|------------------------------------------------------------------------------| +| `vpc_id` |
`int`
|
**Required**
| The parent VPC for the VPC IP Addresses. | +| `order` |
`str`
|
Optional
| The order to list VPC IP Addresses in. **(Choices: `desc`, `asc`; Default: `asc`)** | +| `order_by` |
`str`
|
Optional
| The attribute to order VPC IP Addresses by. | +| [`filters` (sub-options)](#filters) |
`list`
|
Optional
| A list of filters to apply to the resulting VPC IP Addresses. | +| `count` |
`int`
|
Optional
| The number of VPC IP Addresses to return. If undefined, all results will be returned. | + +### filters + +| Field | Type | Required | Description | +|-----------|------|----------|------------------------------------------------------------------------------| +| `name` |
`str`
|
**Required**
| The name of the field to filter on. Valid filterable fields can be found [here](). | +| `values` |
`list`
|
**Required**
| A list of values to allow for this field. Fields will pass this filter if at least one of these values matches. | + +## Return Values + +- `vpcs_ips` - The returned VPC IP Addresses. + + - Sample Response: + ```json + [ + { + "address": "10.0.0.2", + "address_range": null, + "vpc_id": 56242, + "subnet_id": 55829, + "region": "us-mia", + "linode_id": 57328104, + "config_id": 60480976, + "interface_id": 1373818, + "active": false, + "nat_1_1": null, + "gateway": "10.0.0.1", + "prefix": 24, + "subnet_mask": "255.255.255.0", + } + ] + ``` + + diff --git a/docs/modules/vpcs_ip_list.md b/docs/modules/vpcs_ip_list.md new file mode 100644 index 00000000..e994686d --- /dev/null +++ b/docs/modules/vpcs_ip_list.md @@ -0,0 +1,65 @@ +# vpcs_ip_list + +List and filter on all VPC IP Addresses. + +- [Minimum Required Fields](#minimum-required-fields) +- [Examples](#examples) +- [Parameters](#parameters) +- [Return Values](#return-values) + +## Minimum Required Fields +| Field | Type | Required | Description | +|-------------|-------|--------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `api_token` | `str` | **Required** | The Linode account personal access token. It is necessary to run the module.
It can be exposed by the environment variable `LINODE_API_TOKEN` instead.
See details in [Usage](https://github.com/linode/ansible_linode?tab=readme-ov-file#usage). | + +## Examples + +```yaml +- name: List all IPs of all VPCs in the account. + linode.cloud.vpcs_ip_list: {} +``` + + +## Parameters + +| Field | Type | Required | Description | +|-----------|------|----------|------------------------------------------------------------------------------| +| `order` |
`str`
|
Optional
| The order to list all VPC IP Addresses in. **(Choices: `desc`, `asc`; Default: `asc`)** | +| `order_by` |
`str`
|
Optional
| The attribute to order all VPC IP Addresses by. | +| [`filters` (sub-options)](#filters) |
`list`
|
Optional
| A list of filters to apply to the resulting all VPC IP Addresses. | +| `count` |
`int`
|
Optional
| The number of all VPC IP Addresses to return. If undefined, all results will be returned. | + +### filters + +| Field | Type | Required | Description | +|-----------|------|----------|------------------------------------------------------------------------------| +| `name` |
`str`
|
**Required**
| The name of the field to filter on. Valid filterable fields can be found [here](). | +| `values` |
`list`
|
**Required**
| A list of values to allow for this field. Fields will pass this filter if at least one of these values matches. | + +## Return Values + +- `vpcs_ips` - The returned all VPC IP Addresses. + + - Sample Response: + ```json + + [ + { + "address": "10.0.0.2", + "address_range": null, + "vpc_id": 56242, + "subnet_id": 55829, + "region": "us-mia", + "linode_id": 57328104, + "config_id": 60480976, + "interface_id": 1373818, + "active": false, + "nat_1_1": null, + "gateway": "10.0.0.1", + "prefix": 24, + "subnet_mask": "255.255.255.0", + } + ] + ``` + + diff --git a/plugins/module_utils/doc_fragments/vpc_ip_list.py b/plugins/module_utils/doc_fragments/vpc_ip_list.py new file mode 100644 index 00000000..29cb64b8 --- /dev/null +++ b/plugins/module_utils/doc_fragments/vpc_ip_list.py @@ -0,0 +1,27 @@ +"""Documentation fragments for the vpc_ip_list module""" + +specdoc_examples = [""" +- name: List all IPs of a specific VPC. + linode.cloud.vpc_ip_list: + vpc_id: 12345""", +] + +result_vpc_ip_view_samples = [ + """[ + { + "address": "10.0.0.2", + "address_range": null, + "vpc_id": 56242, + "subnet_id": 55829, + "region": "us-mia", + "linode_id": 57328104, + "config_id": 60480976, + "interface_id": 1373818, + "active": false, + "nat_1_1": null, + "gateway": "10.0.0.1", + "prefix": 24, + "subnet_mask": "255.255.255.0", + } +]""" +] diff --git a/plugins/module_utils/doc_fragments/vpcs_ip_list.py b/plugins/module_utils/doc_fragments/vpcs_ip_list.py new file mode 100644 index 00000000..3a9048eb --- /dev/null +++ b/plugins/module_utils/doc_fragments/vpcs_ip_list.py @@ -0,0 +1,27 @@ +"""Documentation fragments for the vpcs_ip_list module""" + +specdoc_examples = [ + """ +- name: List all IPs of all VPCs in the account. + linode.cloud.vpcs_ip_list: {}""", +] + +result_vpc_samples = [""" +[ + { + "address": "10.0.0.2", + "address_range": null, + "vpc_id": 56242, + "subnet_id": 55829, + "region": "us-mia", + "linode_id": 57328104, + "config_id": 60480976, + "interface_id": 1373818, + "active": false, + "nat_1_1": null, + "gateway": "10.0.0.1", + "prefix": 24, + "subnet_mask": "255.255.255.0", + } +]""" +] diff --git a/plugins/modules/vpc_ip_list.py b/plugins/modules/vpc_ip_list.py new file mode 100644 index 00000000..c191d6b5 --- /dev/null +++ b/plugins/modules/vpc_ip_list.py @@ -0,0 +1,35 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +"""This module contains all of the functionality for listing IP addresses of a VPC.""" + +from __future__ import absolute_import, division, print_function + +import ansible_collections.linode.cloud.plugins.module_utils.doc_fragments.vpc_ip_list as docs +from ansible_collections.linode.cloud.plugins.module_utils.linode_common_list import ( + ListModule, + ListModuleParam, +) +from ansible_specdoc.objects import FieldType + +module = ListModule( + result_display_name="VPC IP Addresses", + result_field_name="vpcs_ips", + endpoint_template="/vpcs/{vpc_id}/ips", + result_docs_url="", + examples=docs.specdoc_examples, + result_samples=docs.result_vpc_ip_view_samples, + params=[ + ListModuleParam( + display_name="VPC", + name="vpc_id", + type=FieldType.integer, + ) + ], +) + + +SPECDOC_META = module.spec + +if __name__ == "__main__": + module.run() diff --git a/plugins/modules/vpcs_ip_list.py b/plugins/modules/vpcs_ip_list.py new file mode 100644 index 00000000..9d28f69c --- /dev/null +++ b/plugins/modules/vpcs_ip_list.py @@ -0,0 +1,26 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +"""This module contains all of the functionality for listing IP addresses of all VPCs.""" + +from __future__ import absolute_import, division, print_function + +import ansible_collections.linode.cloud.plugins.module_utils.doc_fragments.vpcs_ip_list as docs +from ansible_collections.linode.cloud.plugins.module_utils.linode_common_list import ( + ListModule, +) + +module = ListModule( + result_display_name="all VPC IP Addresses", + result_field_name="vpcs_ips", + endpoint_template="/vpcs/ips", + result_docs_url="", + examples=docs.specdoc_examples, + result_samples=docs.result_vpc_samples, +) + + +SPECDOC_META = module.spec + +if __name__ == "__main__": + module.run() diff --git a/tests/integration/targets/vpc_ip_list/tasks/main.yaml b/tests/integration/targets/vpc_ip_list/tasks/main.yaml new file mode 100644 index 00000000..3069141d --- /dev/null +++ b/tests/integration/targets/vpc_ip_list/tasks/main.yaml @@ -0,0 +1,133 @@ +- name: vpc_basic + block: + - set_fact: + r: "{{ 1000000000 | random }}" + + - name: Create a VPC + linode.cloud.vpc: + label: 'ansible-test-{{ r }}' + region: us-mia + description: test description + state: present + register: create_vpc + + - name: Assert VPC created + assert: + that: + - create_vpc.changed + - create_vpc.vpc.label == 'ansible-test-{{ r }}' + - create_vpc.vpc.region == 'us-mia' + - create_vpc.vpc.description == 'test description' + + - name: Create a subnet + linode.cloud.vpc_subnet: + vpc_id: '{{ create_vpc.vpc.id }}' + label: 'test-subnet' + ipv4: '10.0.0.0/24' + state: present + register: create_subnet + + - name: Assert Subnet created + assert: + that: + - create_subnet.changed + - create_subnet.subnet.label == 'test-subnet' + - create_subnet.subnet.ipv4 == '10.0.0.0/24' + - create_subnet.subnet.created != None + - create_subnet.subnet.updated != None + - create_subnet.subnet.linodes | length == 0 + + - name: Create a Linode instance with interface + linode.cloud.instance: + label: 'ansible-test-{{ r }}' + region: us-mia + type: g6-nanode-1 + disks: + - label: test-disk + filesystem: ext4 + size: 10 + configs: + - label: cool-config + devices: + sda: + disk_label: test-disk + interfaces: + - purpose: vpc + subnet_id: '{{ create_subnet.subnet.id }}' + primary: true + ipv4: + vpc: 10.0.0.3 + nat_1_1: any + ip_ranges: [ "10.0.0.5/32" ] + wait: false + booted: false + state: present + register: create_instance + + - name: Assert instance created + assert: + that: + - create_instance.changed + + - create_instance.configs[0].interfaces[0].purpose == 'vpc' + - create_instance.configs[0].interfaces[0].subnet_id == create_subnet.subnet.id + - create_instance.configs[0].interfaces[0].vpc_id == create_vpc.vpc.id + - create_instance.configs[0].interfaces[0].ip_ranges[0] == '10.0.0.5/32' + - create_instance.configs[0].interfaces[0].ipv4.nat_1_1 == create_instance.instance.ipv4[0] + - create_instance.configs[0].interfaces[0].ipv4.vpc == '10.0.0.3' + + - name: List VPC IPs + linode.cloud.vpcs_ip_list: + register: all_vpc_ips + + - name: Assert VPC IPs were returned + assert: + that: + - all_vpc_ips.vpcs_ips[0].vpc_id == create_vpc.vpc.id + - all_vpc_ips.vpcs_ips[1].vpc_id == create_vpc.vpc.id + + - name: List VPC IPs for a specific VPC + linode.cloud.vpc_ip_list: + vpc_id: '{{ create_vpc.vpc.id }}' + register: vpcs_ips + + - name: Assert VPC IPs were returned + assert: + that: + - vpcs_ips.vpcs_ips[0].vpc_id == create_vpc.vpc.id + - vpcs_ips.vpcs_ips[1].vpc_id == create_vpc.vpc.id + + always: + - ignore_errors: true + block: + - name: Delete a Linode instance + linode.cloud.instance: + label: '{{ create_instance.instance.label }}' + state: absent + register: delete_instance + + - name: Assert instance delete succeeded + assert: + that: + - delete_instance.changed + - delete_instance.instance.id == create_instance.instance.id + + - name: Delete a subnet + linode.cloud.vpc_subnet: + vpc_id: '{{ create_vpc.vpc.id }}' + label: 'test-subnet' + state: absent + register: delete_subnet + + - name: Delete a VPC + linode.cloud.vpc: + label: '{{ create_vpc.vpc.label }}' + state: absent + register: delete_vpc + + environment: + LINODE_UA_PREFIX: '{{ ua_prefix }}' + LINODE_API_TOKEN: '{{ api_token }}' + LINODE_API_URL: '{{ api_url }}' + LINODE_API_VERSION: '{{ api_version }}' + LINODE_CA: '{{ ca_file or "" }}' From 780e50632374765cdf5338f8aa1f790cc0e2c488 Mon Sep 17 00:00:00 2001 From: Jacob Riddle <87780794+jriddle-linode@users.noreply.github.com> Date: Mon, 29 Apr 2024 14:26:23 -0400 Subject: [PATCH 2/4] add pyenv (#502) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 📝 Description **What does this PR do and why is this change necessary?** Updates `pyenv` to point to local environment setup by devenv. --- .python-version | 1 + 1 file changed, 1 insertion(+) create mode 100644 .python-version diff --git a/.python-version b/.python-version new file mode 100644 index 00000000..5568be3d --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +ansible_linode From 0559ab911fa6bd50a65cab876115072c2bf3b403 Mon Sep 17 00:00:00 2001 From: Lena Garber <114949949+lgarber-akamai@users.noreply.github.com> Date: Wed, 15 May 2024 17:15:58 -0400 Subject: [PATCH 3/4] fix: Add conditional update logic for the `ip_rdns` module (#505) * Add conditional update logic for the ip_rdns module * make gendocs * Add IPv6 support * fix lint --- docs/modules/ip_rdns.md | 2 +- plugins/module_utils/linode_common.py | 2 +- plugins/modules/ip_rdns.py | 63 +++++++++++--- plugins/modules/ssh_key_info.py | 3 + .../targets/ip_rdns/tasks/main.yaml | 31 ++++++- .../targets/ip_rdns_ipv6/tasks/main.yaml | 87 +++++++++++++++++++ 6 files changed, 174 insertions(+), 14 deletions(-) create mode 100644 tests/integration/targets/ip_rdns_ipv6/tasks/main.yaml diff --git a/docs/modules/ip_rdns.md b/docs/modules/ip_rdns.md index 447e4621..4419113e 100644 --- a/docs/modules/ip_rdns.md +++ b/docs/modules/ip_rdns.md @@ -38,7 +38,7 @@ Manage a Linode IP address's rDNS. |-----------|------|----------|------------------------------------------------------------------------------| | `address` |
`str`
|
**Required**
| The IP address. | | `state` |
`str`
|
Optional
| The state of this rDNS of the IP address. **(Choices: `present`, `absent`)** | -| `rdns` |
`str`
|
Optional
| The desired rDNS value. **(Updatable)** | +| `rdns` |
`str`
|
Optional
| The desired RDNS value. **(Updatable)** | ## Return Values diff --git a/plugins/module_utils/linode_common.py b/plugins/module_utils/linode_common.py index 75c26604..c741bd33 100644 --- a/plugins/module_utils/linode_common.py +++ b/plugins/module_utils/linode_common.py @@ -247,7 +247,7 @@ def _get_resource_by_id( ) return self.fail( msg=f"failed to get {resource_name} " - "with id {resource_id}: {exception}" + f"with id {resource_id}: {exception}" ) @property diff --git a/plugins/modules/ip_rdns.py b/plugins/modules/ip_rdns.py index 9216b589..cfb018da 100644 --- a/plugins/modules/ip_rdns.py +++ b/plugins/modules/ip_rdns.py @@ -5,7 +5,8 @@ from __future__ import absolute_import, division, print_function -from typing import Any, Optional +from ipaddress import IPv6Address, ip_address +from typing import Any, Optional, Union import ansible_collections.linode.cloud.plugins.module_utils.doc_fragments.ip_info as ip_docs import ansible_collections.linode.cloud.plugins.module_utils.doc_fragments.ip_rdns as ip_rdns_docs @@ -40,7 +41,7 @@ "rdns": SpecField( type=FieldType.string, editable=True, - description=["The desired rDNS value."], + description=["The desired RDNS value."], ), } @@ -82,28 +83,68 @@ def __init__(self) -> None: required_if=[["state", "present", ["rdns"]]], ) - def update_rdns(self, rdns: str) -> None: + @staticmethod + def _build_default_rdns( + address: str, + ) -> Optional[str]: + """ + Builds the default RDNS address for the given IPv4/IPv6 address. + This is only used for local diffing purposes. + """ + parsed_address = ip_address(address) + + # IPv6 addresses have no default RDNS + if isinstance(parsed_address, IPv6Address): + return None + + return f"{address.replace('.', '-')}.ip.linodeusercontent.com" + + def _should_update_rdns( + self, old_rdns: str, new_rdns: Union[str, ExplicitNullValue] + ) -> bool: + """ + Returns whether the old RDNS value and the proposed new RDNS for the + IP address differ. + """ + + # If the RDNS address is being reset, compare the old RDNS against + # the Linode API default + if isinstance(new_rdns, ExplicitNullValue): + new_rdns = self._build_default_rdns( + self.module.params.get("address") + ) + + return new_rdns != old_rdns + + def _attempt_update_rdns(self, rdns: Union[str, ExplicitNullValue]) -> None: """ Update the reverse DNS of the IP address. """ ip_str = self.module.params.get("address") ip_obj = self._get_resource_by_id(IPAddress, ip_str) - ip_obj.rdns = rdns - ip_obj.save() - ip_obj._api_get() - self.register_action( - f"Updated reverse DNS of the IP address {ip_str} to be {rdns}" - ) + + old_rdns = ip_obj.rdns + + if self._should_update_rdns(old_rdns, rdns): + ip_obj.rdns = rdns + + ip_obj.save() + ip_obj._api_get() + self.register_action( + f"Updated reverse DNS of the IP address {ip_str} from {old_rdns} to {ip_obj.rdns}" + ) self.results["ip"] = ip_obj._raw_json def _handle_present(self) -> None: rdns = self.module.params.get("rdns") + if not rdns: self.fail("`rdns` attribute is required to update the IP address") - self.update_rdns(rdns) + + self._attempt_update_rdns(rdns) def _handle_absent(self) -> None: - self.update_rdns(ExplicitNullValue()) + self._attempt_update_rdns(ExplicitNullValue()) def exec_module(self, **kwargs: Any) -> Optional[dict]: """Entrypoint for reverse DNS module""" diff --git a/plugins/modules/ssh_key_info.py b/plugins/modules/ssh_key_info.py index 0e312d69..a201a52e 100644 --- a/plugins/modules/ssh_key_info.py +++ b/plugins/modules/ssh_key_info.py @@ -92,12 +92,15 @@ def exec_module(self, **kwargs: Any) -> Optional[dict]: params = filter_null_values(self.module.params) + ssh_key = None + if "id" in params: ssh_key = self._get_ssh_key_by_id(params.get("id")) elif "label" in params: ssh_key = self._get_ssh_key_by_label(params.get("label")) self.results["ssh_key"] = ssh_key._raw_json + return self.results diff --git a/tests/integration/targets/ip_rdns/tasks/main.yaml b/tests/integration/targets/ip_rdns/tasks/main.yaml index 9ff919de..822aa0d3 100644 --- a/tests/integration/targets/ip_rdns/tasks/main.yaml +++ b/tests/integration/targets/ip_rdns/tasks/main.yaml @@ -27,7 +27,25 @@ address: '{{ instance_create.instance.ipv4[0] }}' rdns: '{{ new_rdns }}' register: ip_rdns_modified - + + - name: Assert RDNS has been updated for the IP + assert: + that: + - ip_rdns_modified.changed + - ip_rdns_modified.ip.rdns == new_rdns + + - name: Attempt to modify reverse DNS of the IP again + linode.cloud.ip_rdns: + state: present + address: '{{ instance_create.instance.ipv4[0] }}' + rdns: '{{ new_rdns }}' + register: ip_rdns_modified + + - name: Assert RDNS has not been updated for the IP + assert: + that: + - not ip_rdns_modified.changed + - name: Remove reverse DNS of the IP linode.cloud.ip_rdns: state: absent @@ -41,6 +59,17 @@ - ip_rdns_modified.ip.rdns == new_rdns - ip_rdns_removed.ip.rdns != new_rdns + - name: Attempt to remove RDNS of the IP again + linode.cloud.ip_rdns: + state: absent + address: '{{ instance_create.instance.ipv4[0] }}' + register: ip_rdns_removed_again + + - name: Assert RDNS of the IP is unchanged + assert: + that: + - not ip_rdns_removed_again.changed + always: - ignore_errors: true block: diff --git a/tests/integration/targets/ip_rdns_ipv6/tasks/main.yaml b/tests/integration/targets/ip_rdns_ipv6/tasks/main.yaml new file mode 100644 index 00000000..2962e93a --- /dev/null +++ b/tests/integration/targets/ip_rdns_ipv6/tasks/main.yaml @@ -0,0 +1,87 @@ +- name: ip_rdns_ipv6 + block: + - set_fact: + r: "{{ 1000000000 | random }}" + + - name: Create an instance + linode.cloud.instance: + label: 'ansible-test-{{ r }}' + region: us-ord + type: g6-standard-1 + image: linode/ubuntu22.04 + wait: no + state: present + register: instance_create + + - name: Extract the IPv6 SLAAC address + set_fact: + slaac: '{{ instance_create.networking.ipv6.slaac.address }}' + + - name: Compute a new RDNS address + set_fact: + new_rdns: '{{ slaac | replace(":", "-") }}.sslip.io' + + - name: Modify reverse DNS of the IP + linode.cloud.ip_rdns: + state: present + address: '{{ slaac }}' + rdns: '{{ new_rdns }}' + register: ip_rdns_modified + + - name: Assert RDNS has been updated for the IP + assert: + that: + - ip_rdns_modified.changed + - ip_rdns_modified.ip.rdns == new_rdns + + - name: Attempt to modify reverse DNS of the IP again + linode.cloud.ip_rdns: + state: present + address: '{{ slaac }}' + rdns: '{{ new_rdns }}' + register: ip_rdns_modified + + - name: Assert RDNS has not been updated for the IP + assert: + that: + - not ip_rdns_modified.changed + + - name: Remove reverse DNS of the IP + linode.cloud.ip_rdns: + state: absent + address: '{{ slaac }}' + register: ip_rdns_removed + + - name: Assert reverse DNS of IP is removed + assert: + that: + - ip_rdns_removed.ip.address == slaac + - ip_rdns_modified.ip.rdns == new_rdns + - ip_rdns_removed.ip.rdns != new_rdns + + - name: Attempt to remove RDNS of the IP again + linode.cloud.ip_rdns: + state: absent + address: '{{ slaac }}' + register: ip_rdns_removed_again + + - name: Assert RDNS of the IP is unchanged + assert: + that: + - not ip_rdns_removed_again.changed + + always: + - ignore_errors: true + block: + - name: Delete instance + linode.cloud.instance: + label: '{{ instance_create.instance.label }}' + state: absent + + environment: + LINODE_UA_PREFIX: '{{ ua_prefix }}' + LINODE_API_TOKEN: '{{ api_token }}' + LINODE_API_URL: '{{ api_url }}' + LINODE_API_VERSION: '{{ api_version }}' + LINODE_CA: '{{ ca_file or "" }}' + From 8ac62e24d76d8cde6d78a91171854f9a01eee777 Mon Sep 17 00:00:00 2001 From: Lena Garber <114949949+lgarber-akamai@users.noreply.github.com> Date: Mon, 20 May 2024 11:03:12 -0400 Subject: [PATCH 4/4] Fix broken assertion in instance_interfaces_vpc test (#507) --- .../integration/targets/instance_interfaces_vpc/tasks/main.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/targets/instance_interfaces_vpc/tasks/main.yaml b/tests/integration/targets/instance_interfaces_vpc/tasks/main.yaml index 7bdf1686..7fd68484 100644 --- a/tests/integration/targets/instance_interfaces_vpc/tasks/main.yaml +++ b/tests/integration/targets/instance_interfaces_vpc/tasks/main.yaml @@ -93,7 +93,7 @@ assert: that: - subnet_info.subnet.linodes[0].id == update_instance.instance.id - - subnet_info.subnet.linodes[0].interfaces[0].id == update_instance.configs[0].interfaces[1].id + - subnet_info.subnet.linodes[0].interfaces[1].id == update_instance.configs[0].interfaces[1].id - name: Unchanged instance interface linode.cloud.instance: