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