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] 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 "" }}'