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: