diff --git a/README.md b/README.md
index 28b65fe5..c7debbca 100644
--- a/README.md
+++ b/README.md
@@ -73,7 +73,7 @@ Name | Description |
[linode.cloud.object_cluster_info](./docs/modules/object_cluster_info.md)|**NOTE: This module has been deprecated because it relies on deprecated API endpoints. Going forward, `region` will be the preferred way to designate where Object Storage resources should be created.**|
[linode.cloud.placement_group_info](./docs/modules/placement_group_info.md)|Get info about a Linode Placement Group.|
[linode.cloud.profile_info](./docs/modules/profile_info.md)|Get info about a Linode Profile.|
-[linode.cloud.ssh_key_info](./docs/modules/ssh_key_info.md)|Get info about the Linode SSH public key.|
+[linode.cloud.ssh_key_info](./docs/modules/ssh_key_info.md)|Get info about a Linode SSH Key.|
[linode.cloud.stackscript_info](./docs/modules/stackscript_info.md)|Get info about a Linode StackScript.|
[linode.cloud.token_info](./docs/modules/token_info.md)|Get info about a Linode Personal Access Token.|
[linode.cloud.type_info](./docs/modules/type_info.md)|Get info about a Linode Type.|
@@ -100,17 +100,17 @@ Name | Description |
[linode.cloud.image_list](./docs/modules/image_list.md)|List and filter on Images.|
[linode.cloud.instance_list](./docs/modules/instance_list.md)|List and filter on Instances.|
[linode.cloud.instance_type_list](./docs/modules/instance_type_list.md)|**NOTE: This module has been deprecated in favor of `type_list`.**|
-[linode.cloud.lke_version_list](./docs/modules/lke_version_list.md)|List Kubernetes versions available for deployment to a Kubernetes cluster.|
+[linode.cloud.lke_version_list](./docs/modules/lke_version_list.md)|List and filter on LKE Versions.|
[linode.cloud.nodebalancer_list](./docs/modules/nodebalancer_list.md)|List and filter on Node Balancers.|
[linode.cloud.object_cluster_list](./docs/modules/object_cluster_list.md)|**NOTE: This module has been deprecated because it relies on deprecated API endpoints. Going forward, `region` will be the preferred way to designate where Object Storage resources should be created.**|
[linode.cloud.placement_group_list](./docs/modules/placement_group_list.md)|List and filter on Placement Groups.|
[linode.cloud.region_list](./docs/modules/region_list.md)|List and filter on Regions.|
-[linode.cloud.ssh_key_list](./docs/modules/ssh_key_list.md)|List and filter on SSH keys in the Linode profile.|
+[linode.cloud.ssh_key_list](./docs/modules/ssh_key_list.md)|List and filter on SSH Keys.|
[linode.cloud.stackscript_list](./docs/modules/stackscript_list.md)|List and filter on StackScripts.|
-[linode.cloud.token_list](./docs/modules/token_list.md)|List and filter on Linode Account tokens.|
+[linode.cloud.token_list](./docs/modules/token_list.md)|List and filter on Tokens.|
[linode.cloud.type_list](./docs/modules/type_list.md)|List and filter on Types.|
-[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.user_list](./docs/modules/user_list.md)|List and filter on Users.|
+[linode.cloud.vlan_list](./docs/modules/vlan_list.md)|List and filter on 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.|
@@ -178,6 +178,31 @@ For more information on Ansible collection usage, see [Ansible's official usage
Use-case examples for this collection can be found [here](./examples/README.md).
+## Development
+
+The following section outlines various information relating to the development of this collection.
+
+### Attaching a Debugger
+
+To quickly and easily attach a debugger to a running module in this collection,
+you can use the [madbg](https://pypi.org/project/madbg/) package:
+
+1. Install `madbg` in your local Python environment:
+
+```shell
+pip install madbg
+```
+
+2. Call `madbg.set_trace(...)` at the location you would like to create a breakpoint at:
+
+```shell
+import madbg; madbg.set_trace()
+```
+
+3. Run the module in either a playbook or a test.
+4. In a separate shell, run `madbg connect`.
+5. You should now be able to remotely debug the module as soon as the breakpoint is triggered.
+
## Licensing
GNU General Public License v3.0.
diff --git a/docs/modules/firewall_info.md b/docs/modules/firewall_info.md
index e3d440f4..162d3334 100644
--- a/docs/modules/firewall_info.md
+++ b/docs/modules/firewall_info.md
@@ -31,12 +31,12 @@ Get info about a Linode Firewall.
| Field | Type | Required | Description |
|-----------|------|----------|------------------------------------------------------------------------------|
-| `id` |
`int` | Optional | The unique id of the Firewall. Optional if `label` is defined. **(Conflicts With: `label`)** |
-| `label` | `str` | Optional | The Firewall’s label. Optional if `id` is defined. **(Conflicts With: `id`)** |
+| `label` | `str` | Optional | The label of the Firewall to resolve. **(Conflicts With: `id`)** |
+| `id` | `int` | Optional | The ID of the Firewall to resolve. **(Conflicts With: `label`)** |
## Return Values
-- `firewall` - The Firewall description in JSON serialized form.
+- `firewall` - The returned Firewall.
- Sample Response:
```json
@@ -93,7 +93,7 @@ Get info about a Linode Firewall.
- See the [Linode API response documentation](https://techdocs.akamai.com/linode-api/reference/get-firewall) for a list of returned fields
-- `devices` - A list of Firewall devices JSON serialized form.
+- `devices` - The returned devices.
- Sample Response:
```json
@@ -111,6 +111,6 @@ Get info about a Linode Firewall.
}
]
```
- - See the [Linode API response documentation](https://techdocs.akamai.com/linode-api/reference/get-firewall-device) for a list of returned fields
+ - See the [Linode API response documentation](https://techdocs.akamai.com/linode-api/reference/get-firewall-devices) for a list of returned fields
diff --git a/docs/modules/firewall_list.md b/docs/modules/firewall_list.md
index 72d26216..98116a32 100644
--- a/docs/modules/firewall_list.md
+++ b/docs/modules/firewall_list.md
@@ -32,21 +32,21 @@ List and filter on Firewalls.
| Field | Type | Required | Description |
|-----------|------|----------|------------------------------------------------------------------------------|
-| `order` | `str` | Optional | The order to list firewalls in. **(Choices: `desc`, `asc`; Default: `asc`)** |
-| `order_by` | `str` | Optional | The attribute to order firewalls by. |
-| [`filters` (sub-options)](#filters) | `list` | Optional | A list of filters to apply to the resulting firewalls. |
-| `count` | `int` | Optional | The number of results to return. If undefined, all results will be returned. |
+| `order` | `str` | Optional | The order to list Firewalls in. **(Choices: `desc`, `asc`; Default: `asc`)** |
+| `order_by` | `str` | Optional | The attribute to order Firewalls by. |
+| [`filters` (sub-options)](#filters) | `list` | Optional | A list of filters to apply to the resulting Firewalls. |
+| `count` | `int` | Optional | The number of Firewalls 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 attributes can be found here: https://techdocs.akamai.com/linode-api/reference/get-ips |
+| `name` | `str` | **Required** | The name of the field to filter on. Valid filterable fields can be found [here](https://techdocs.akamai.com/linode-api/reference/get-firewalls). |
| `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
-- `firewalls` - The returned firewalls.
+- `firewalls` - The returned Firewalls.
- Sample Response:
```json
diff --git a/docs/modules/lke_version_list.md b/docs/modules/lke_version_list.md
index da6f0d54..f7474cc6 100644
--- a/docs/modules/lke_version_list.md
+++ b/docs/modules/lke_version_list.md
@@ -1,6 +1,6 @@
# lke_version_list
-List Kubernetes versions available for deployment to a Kubernetes cluster.
+List and filter on LKE Versions.
- [Minimum Required Fields](#minimum-required-fields)
- [Examples](#examples)
@@ -24,12 +24,21 @@ List Kubernetes versions available for deployment to a Kubernetes cluster.
| Field | Type | Required | Description |
|-----------|------|----------|------------------------------------------------------------------------------|
-| `order` | `str` | Optional | The order to list lke versions in. **(Choices: `desc`, `asc`; Default: `asc`)** |
-| `count` | `int` | Optional | The number of results to return. If undefined, all results will be returned. |
+| `order` | `str` | Optional | The order to list LKE Versions in. **(Choices: `desc`, `asc`; Default: `asc`)** |
+| `order_by` | `str` | Optional | The attribute to order LKE Versions by. |
+| [`filters` (sub-options)](#filters) | `list` | Optional | A list of filters to apply to the resulting LKE Versions. |
+| `count` | `int` | Optional | The number of LKE Versions 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](https://techdocs.akamai.com/linode-api/reference/get-lke-versions). |
+| `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
-- `lke_versions` - The returned LKE versions.
+- `lke_versions` - The returned LKE Versions.
- Sample Response:
```json
diff --git a/docs/modules/ssh_key_info.md b/docs/modules/ssh_key_info.md
index cf643c30..6d193e78 100644
--- a/docs/modules/ssh_key_info.md
+++ b/docs/modules/ssh_key_info.md
@@ -1,6 +1,6 @@
# ssh_key_info
-Get info about the Linode SSH public key.
+Get info about a Linode SSH Key.
- [Minimum Required Fields](#minimum-required-fields)
- [Examples](#examples)
@@ -31,12 +31,12 @@ Get info about the Linode SSH public key.
| Field | Type | Required | Description |
|-----------|------|----------|------------------------------------------------------------------------------|
-| `id` | `int` | Optional | The ID of the SSH key. **(Conflicts With: `label`)** |
-| `label` | `str` | Optional | The label of the SSH key. **(Conflicts With: `id`)** |
+| `label` | `str` | Optional | The label of the SSH Key to resolve. **(Conflicts With: `id`)** |
+| `id` | `int` | Optional | The ID of the SSH Key to resolve. **(Conflicts With: `label`)** |
## Return Values
-- `ssh_key` - The SSH key in JSON serialized form.
+- `ssh_key` - The returned SSH Key.
- Sample Response:
```json
diff --git a/docs/modules/ssh_key_list.md b/docs/modules/ssh_key_list.md
index 479ac4ef..2ca2b0fc 100644
--- a/docs/modules/ssh_key_list.md
+++ b/docs/modules/ssh_key_list.md
@@ -1,6 +1,6 @@
# ssh_key_list
-List and filter on SSH keys in the Linode profile.
+List and filter on SSH Keys.
- [Minimum Required Fields](#minimum-required-fields)
- [Examples](#examples)
@@ -52,21 +52,21 @@ List and filter on SSH keys in the Linode profile.
| Field | Type | Required | Description |
|-----------|------|----------|------------------------------------------------------------------------------|
-| `order` | `str` | Optional | The order to list ssh keys in. **(Choices: `desc`, `asc`; Default: `asc`)** |
-| `order_by` | `str` | Optional | The attribute to order ssh keys by. |
-| [`filters` (sub-options)](#filters) | `list` | Optional | A list of filters to apply to the resulting ssh keys. |
-| `count` | `int` | Optional | The number of results to return. If undefined, all results will be returned. |
+| `order` | `str` | Optional | The order to list SSH Keys in. **(Choices: `desc`, `asc`; Default: `asc`)** |
+| `order_by` | `str` | Optional | The attribute to order SSH Keys by. |
+| [`filters` (sub-options)](#filters) | `list` | Optional | A list of filters to apply to the resulting SSH Keys. |
+| `count` | `int` | Optional | The number of SSH Keys 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 attributes can be found here: https://techdocs.akamai.com/linode-api/reference/get-profile |
+| `name` | `str` | **Required** | The name of the field to filter on. Valid filterable fields can be found [here](https://techdocs.akamai.com/linode-api/reference/get-ssh-keys). |
| `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
-- `ssh_keys` - The returned SSH keys.
+- `ssh_keys` - The returned SSH Keys.
- Sample Response:
```json
diff --git a/docs/modules/token_info.md b/docs/modules/token_info.md
index 88875541..ede98195 100644
--- a/docs/modules/token_info.md
+++ b/docs/modules/token_info.md
@@ -31,12 +31,12 @@ Get info about a Linode Personal Access Token.
| Field | Type | Required | Description |
|-----------|------|----------|------------------------------------------------------------------------------|
-| `id` | `int` | Optional | The ID of the token. **(Conflicts With: `label`)** |
-| `label` | `str` | Optional | The label of the token. **(Conflicts With: `id`)** |
+| `label` | `str` | Optional | The label of the Personal Access Token to resolve. **(Conflicts With: `id`)** |
+| `id` | `int` | Optional | The ID of the Personal Access Token to resolve. **(Conflicts With: `label`)** |
## Return Values
-- `token` - The token in JSON serialized form.
+- `token` - The returned Personal Access Token.
- Sample Response:
```json
@@ -49,6 +49,6 @@ Get info about a Linode Personal Access Token.
"token": "abcdefghijklmnop"
}
```
- - See the [Linode API response documentation](https://techdocs.akamai.com/linode-api/reference/post-personal-access-token) for a list of returned fields
+ - See the [Linode API response documentation](https://techdocs.akamai.com/linode-api/reference/get-personal-access-tokens) for a list of returned fields
diff --git a/docs/modules/token_list.md b/docs/modules/token_list.md
index aacc77af..2e910b1d 100644
--- a/docs/modules/token_list.md
+++ b/docs/modules/token_list.md
@@ -1,6 +1,6 @@
# token_list
-List and filter on Linode Account tokens.
+List and filter on Tokens.
- [Minimum Required Fields](#minimum-required-fields)
- [Examples](#examples)
@@ -32,21 +32,21 @@ List and filter on Linode Account tokens.
| Field | Type | Required | Description |
|-----------|------|----------|------------------------------------------------------------------------------|
-| `order` | `str` | Optional | The order to list tokens in. **(Choices: `desc`, `asc`; Default: `asc`)** |
-| `order_by` | `str` | Optional | The attribute to order tokens by. |
-| [`filters` (sub-options)](#filters) | `list` | Optional | A list of filters to apply to the resulting tokens. |
-| `count` | `int` | Optional | The number of results to return. If undefined, all results will be returned. |
+| `order` | `str` | Optional | The order to list Tokens in. **(Choices: `desc`, `asc`; Default: `asc`)** |
+| `order_by` | `str` | Optional | The attribute to order Tokens by. |
+| [`filters` (sub-options)](#filters) | `list` | Optional | A list of filters to apply to the resulting Tokens. |
+| `count` | `int` | Optional | The number of Tokens 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 attributes can be found here: https://techdocs.akamai.com/linode-api/reference/get-profile |
+| `name` | `str` | **Required** | The name of the field to filter on. Valid filterable fields can be found [here](https://techdocs.akamai.com/linode-api/reference/get-personal-access-tokens). |
| `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
-- `tokens` - The returned tokens.
+- `tokens` - The returned Tokens.
- Sample Response:
```json
diff --git a/docs/modules/user_list.md b/docs/modules/user_list.md
index e770f0d9..81bc1b6d 100644
--- a/docs/modules/user_list.md
+++ b/docs/modules/user_list.md
@@ -1,6 +1,6 @@
# user_list
-List Users.
+List and filter on Users.
- [Minimum Required Fields](#minimum-required-fields)
- [Examples](#examples)
@@ -24,12 +24,21 @@ List Users.
| Field | Type | Required | Description |
|-----------|------|----------|------------------------------------------------------------------------------|
-| `order` | `str` | Optional | The order to list users in. **(Choices: `desc`, `asc`; Default: `asc`)** |
-| `count` | `int` | Optional | The number of results to return. If undefined, all results will be returned. |
+| `order` | `str` | Optional | The order to list Users in. **(Choices: `desc`, `asc`; Default: `asc`)** |
+| `order_by` | `str` | Optional | The attribute to order Users by. |
+| [`filters` (sub-options)](#filters) | `list` | Optional | A list of filters to apply to the resulting Users. |
+| `count` | `int` | Optional | The number of Users 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](https://techdocs.akamai.com/linode-api/reference/get-users). |
+| `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
-- `users` - The returned users.
+- `users` - The returned Users.
- Sample Response:
```json
@@ -47,6 +56,6 @@ List Users.
}
]
```
- - See the [Linode API response documentation](https://techdocs.akamai.com/linode-api/reference/get-account) for a list of returned fields
+ - See the [Linode API response documentation](https://techdocs.akamai.com/linode-api/reference/get-users) for a list of returned fields
diff --git a/docs/modules/vlan_info.md b/docs/modules/vlan_info.md
index 3d31800e..c5ef1d98 100644
--- a/docs/modules/vlan_info.md
+++ b/docs/modules/vlan_info.md
@@ -2,8 +2,6 @@
Get info about a Linode VLAN.
-WARNING! This module makes use of beta endpoints and requires the C(api_version) field be explicitly set to C(v4beta).
-
- [Minimum Required Fields](#minimum-required-fields)
- [Examples](#examples)
- [Parameters](#parameters)
@@ -28,11 +26,12 @@ WARNING! This module makes use of beta endpoints and requires the C(api_version)
| Field | Type | Required | Description |
|-----------|------|----------|------------------------------------------------------------------------------|
-| `label` | `str` | **Required** | The VLAN’s label. |
+| `label` | `str` | Optional | The label of the VLAN to resolve. **(Conflicts With: `id`)** |
+| `id` | `int` | Optional | The ID of the VLAN to resolve. **(Conflicts With: `label`)** |
## Return Values
-- `vlan` - The VLAN in JSON serialized form.
+- `vlan` - The returned VLAN.
- Sample Response:
```json
diff --git a/docs/modules/vlan_list.md b/docs/modules/vlan_list.md
index 893df5a1..38d7579a 100644
--- a/docs/modules/vlan_list.md
+++ b/docs/modules/vlan_list.md
@@ -1,8 +1,6 @@
# vlan_list
-List and filter on Linode VLANs.
-
-WARNING! This module makes use of beta endpoints and requires the C(api_version) field be explicitly set to C(v4beta).
+List and filter on VLANs.
- [Minimum Required Fields](#minimum-required-fields)
- [Examples](#examples)
@@ -40,13 +38,13 @@ WARNING! This module makes use of beta endpoints and requires the C(api_version)
| `order` | `str` | Optional | The order to list VLANs in. **(Choices: `desc`, `asc`; Default: `asc`)** |
| `order_by` | `str` | Optional | The attribute to order VLANs by. |
| [`filters` (sub-options)](#filters) | `list` | Optional | A list of filters to apply to the resulting VLANs. |
-| `count` | `int` | Optional | The number of results to return. If undefined, all results will be returned. |
+| `count` | `int` | Optional | The number of VLANs 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 attributes can be found here: https://techdocs.akamai.com/linode-api/reference/get-vlans |
+| `name` | `str` | **Required** | The name of the field to filter on. Valid filterable fields can be found [here](https://techdocs.akamai.com/linode-api/reference/get-vlans). |
| `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
diff --git a/plugins/modules/firewall_info.py b/plugins/modules/firewall_info.py
index efdf5bc6..ec7b3d01 100644
--- a/plugins/modules/firewall_info.py
+++ b/plugins/modules/firewall_info.py
@@ -1,76 +1,69 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
-"""This module contains all of the functionality for Linode Firewall info."""
+"""This module allows users to retrieve information about a Linode Firewall."""
from __future__ import absolute_import, division, print_function
-from typing import Any, Dict, List, Optional
-
import ansible_collections.linode.cloud.plugins.module_utils.doc_fragments.firewall as docs_parent
import ansible_collections.linode.cloud.plugins.module_utils.doc_fragments.firewall_info as docs
-from ansible_collections.linode.cloud.plugins.module_utils.linode_common import (
- LinodeModuleBase,
-)
-from ansible_collections.linode.cloud.plugins.module_utils.linode_docs import (
- global_authors,
- global_requirements,
+from ansible_collections.linode.cloud.plugins.module_utils.linode_common_info import (
+ InfoModule,
+ InfoModuleAttr,
+ InfoModuleResult,
)
from ansible_collections.linode.cloud.plugins.module_utils.linode_helper import (
- create_filter_and,
paginated_list_to_json,
+ safe_find,
)
-from ansible_specdoc.objects import (
- FieldType,
- SpecDocMeta,
- SpecField,
- SpecReturnValue,
-)
+from ansible_specdoc.objects import FieldType
from linode_api4 import Firewall
-linode_firewall_info_spec = {
- # We need to overwrite attributes to exclude them as requirements
- "state": SpecField(type=FieldType.string, required=False, doc_hide=True),
- "id": SpecField(
- type=FieldType.integer,
- required=False,
- conflicts_with=["label"],
- description=[
- "The unique id of the Firewall.",
- "Optional if `label` is defined.",
- ],
- ),
- "label": SpecField(
- type=FieldType.string,
- required=False,
- conflicts_with=["id"],
- description=["The Firewall’s label.", "Optional if `id` is defined."],
+module = InfoModule(
+ primary_result=InfoModuleResult(
+ field_name="firewall",
+ field_type=FieldType.dict,
+ display_name="Firewall",
+ docs_url="https://techdocs.akamai.com/linode-api/reference/get-firewall",
+ samples=docs_parent.result_firewall_samples,
),
-}
-
-SPECDOC_META = SpecDocMeta(
- description=["Get info about a Linode Firewall."],
- requirements=global_requirements,
- author=global_authors,
- options=linode_firewall_info_spec,
- examples=docs.specdoc_examples,
- return_values={
- "firewall": SpecReturnValue(
- description="The Firewall description in JSON serialized form.",
- docs_url="https://techdocs.akamai.com/linode-api/reference/get-firewall",
- type=FieldType.dict,
- sample=docs_parent.result_firewall_samples,
+ secondary_results=[
+ InfoModuleResult(
+ field_name="devices",
+ field_type=FieldType.list,
+ display_name="devices",
+ docs_url="https://techdocs.akamai.com/linode-api/reference/get-firewall-devices",
+ samples=docs_parent.result_devices_samples,
+ get=lambda client, firewall, params: paginated_list_to_json(
+ Firewall(client, firewall["id"]).devices
+ ),
+ ),
+ ],
+ attributes=[
+ InfoModuleAttr(
+ display_name="ID",
+ name="id",
+ type=FieldType.integer,
+ get=lambda client, params: client.load(
+ Firewall,
+ params.get("id"),
+ )._raw_json,
),
- "devices": SpecReturnValue(
- description="A list of Firewall devices JSON serialized form.",
- docs_url="https://techdocs.akamai.com/linode-api/reference/get-firewall-device",
- type=FieldType.list,
- sample=docs_parent.result_devices_samples,
+ InfoModuleAttr(
+ display_name="label",
+ name="label",
+ type=FieldType.string,
+ get=lambda client, params: safe_find(
+ client.networking.firewalls,
+ Firewall.label == params.get("label"),
+ raise_not_found=True,
+ )._raw_json,
),
- },
+ ],
+ examples=docs.specdoc_examples,
)
-linode_firewall_valid_filters = ["id", "label"]
+SPECDOC_META = module.spec
DOCUMENTATION = r"""
"""
@@ -79,63 +72,5 @@
RETURN = r"""
"""
-
-class LinodeFirewallInfo(LinodeModuleBase):
- """Module for viewing info about a Linode Firewall"""
-
- def __init__(self) -> None:
- self.module_arg_spec = SPECDOC_META.ansible_spec
- self.required_one_of: List[str] = []
- self.results: Dict[str, Any] = {"firewall": None}
-
- super().__init__(
- module_arg_spec=self.module_arg_spec,
- required_one_of=self.required_one_of,
- )
-
- def _get_matching_firewall(self) -> Optional[Firewall]:
- """Gets the Firewall with the param properties"""
-
- filter_items = {
- k: v
- for k, v in self.module.params.items()
- if k in linode_firewall_valid_filters and v is not None
- }
-
- filter_statement = create_filter_and(Firewall, filter_items)
-
- try:
- # Special case because ID is not filterable
- if "id" in filter_items.keys():
- result = Firewall(self.client, self.module.params.get("id"))
- result._api_get() # Force lazy-loading
-
- return result
-
- return self.client.networking.firewalls(filter_statement)[0]
- except IndexError:
- return None
- except Exception as exception:
- return self.fail(msg="failed to get firewall {0}".format(exception))
-
- def exec_module(self, **kwargs: dict) -> Optional[dict]:
- """Entrypoint for Firewall info module"""
-
- firewall = self._get_matching_firewall()
-
- if firewall is None:
- self.fail("failed to get firewall")
-
- self.results["firewall"] = firewall._raw_json
- self.results["devices"] = paginated_list_to_json(firewall.devices)
-
- return self.results
-
-
-def main() -> None:
- """Constructs and calls the Linode Firewall info module"""
- LinodeFirewallInfo()
-
-
if __name__ == "__main__":
- main()
+ module.run()
diff --git a/plugins/modules/firewall_list.py b/plugins/modules/firewall_list.py
index 70a1a11b..9548bdd1 100644
--- a/plugins/modules/firewall_list.py
+++ b/plugins/modules/firewall_list.py
@@ -1,97 +1,26 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
-"""This module allows users to list Linode tokens."""
-from __future__ import absolute_import, division, print_function
+"""This module contains all of the functionality for listing Linode Firewalls."""
-from typing import Any, Dict, Optional
+from __future__ import absolute_import, division, print_function
import ansible_collections.linode.cloud.plugins.module_utils.doc_fragments.firewall_list as docs
-from ansible_collections.linode.cloud.plugins.module_utils.linode_common import (
- LinodeModuleBase,
-)
-from ansible_collections.linode.cloud.plugins.module_utils.linode_docs import (
- global_authors,
- global_requirements,
-)
-from ansible_collections.linode.cloud.plugins.module_utils.linode_helper import (
- construct_api_filter,
- get_all_paginated,
-)
-from ansible_specdoc.objects import (
- FieldType,
- SpecDocMeta,
- SpecField,
- SpecReturnValue,
+from ansible_collections.linode.cloud.plugins.module_utils.linode_common_list import (
+ ListModule,
)
-spec_filter = {
- "name": SpecField(
- type=FieldType.string,
- required=True,
- description=[
- "The name of the field to filter on.",
- "Valid filterable attributes can be found here: "
- "https://techdocs.akamai.com/linode-api/reference/get-ips",
- ],
- ),
- "values": SpecField(
- type=FieldType.list,
- element_type=FieldType.string,
- required=True,
- description=[
- "A list of values to allow for this field.",
- "Fields will pass this filter if at least one of these values matches.",
- ],
- ),
-}
-
-spec = {
- # Disable the default values
- "state": SpecField(type=FieldType.string, required=False, doc_hide=True),
- "label": SpecField(type=FieldType.string, required=False, doc_hide=True),
- "order": SpecField(
- type=FieldType.string,
- description=["The order to list firewalls in."],
- default="asc",
- choices=["desc", "asc"],
- ),
- "order_by": SpecField(
- type=FieldType.string,
- description=["The attribute to order firewalls by."],
- ),
- "filters": SpecField(
- type=FieldType.list,
- element_type=FieldType.dict,
- suboptions=spec_filter,
- description=["A list of filters to apply to the resulting firewalls."],
- ),
- "count": SpecField(
- type=FieldType.integer,
- description=[
- "The number of results to return.",
- "If undefined, all results will be returned.",
- ],
- ),
-}
-
-SPECDOC_META = SpecDocMeta(
- description=["List and filter on Firewalls."],
- requirements=global_requirements,
- author=global_authors,
- options=spec,
+module = ListModule(
+ result_display_name="Firewalls",
+ result_field_name="firewalls",
+ endpoint_template="/networking/firewalls",
+ result_docs_url="https://techdocs.akamai.com/linode-api/reference/get-firewalls",
examples=docs.specdoc_examples,
- return_values={
- "firewalls": SpecReturnValue(
- description="The returned firewalls.",
- docs_url="https://techdocs.akamai.com/linode-api/reference/get-firewalls",
- type=FieldType.list,
- elements=FieldType.dict,
- sample=docs.result_firewalls_samples,
- )
- },
+ result_samples=docs.result_firewalls_samples,
)
+SPECDOC_META = module.spec
+
DOCUMENTATION = r"""
"""
EXAMPLES = r"""
@@ -99,34 +28,5 @@
RETURN = r"""
"""
-
-class Module(LinodeModuleBase):
- """Module for getting a list of Firewalls"""
-
- def __init__(self) -> None:
- self.module_arg_spec = SPECDOC_META.ansible_spec
- self.results: Dict[str, Any] = {"firewalls": []}
-
- super().__init__(module_arg_spec=self.module_arg_spec)
-
- def exec_module(self, **kwargs: Any) -> Optional[dict]:
- """Entrypoint for firewall list module"""
-
- filter_dict = construct_api_filter(self.module.params)
-
- self.results["firewalls"] = get_all_paginated(
- self.client,
- "/networking/firewalls",
- filter_dict,
- num_results=self.module.params["count"],
- )
- return self.results
-
-
-def main() -> None:
- """Constructs and calls the module"""
- Module()
-
-
if __name__ == "__main__":
- main()
+ module.run()
diff --git a/plugins/modules/lke_version_list.py b/plugins/modules/lke_version_list.py
index c0224400..97dbe869 100644
--- a/plugins/modules/lke_version_list.py
+++ b/plugins/modules/lke_version_list.py
@@ -1,67 +1,28 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
-"""This module allows users to list Linode instances."""
-from __future__ import absolute_import, division, print_function
+"""This module allows users to list Linode LKE Versions."""
-from typing import Any, Dict, Optional
+from __future__ import absolute_import, division, print_function
-import ansible_collections.linode.cloud.plugins.module_utils.doc_fragments.lke_version_list as docs
-from ansible_collections.linode.cloud.plugins.module_utils.linode_common import (
- LinodeModuleBase,
-)
-from ansible_collections.linode.cloud.plugins.module_utils.linode_docs import (
- global_authors,
- global_requirements,
-)
-from ansible_collections.linode.cloud.plugins.module_utils.linode_helper import (
- get_all_paginated,
+from ansible_collections.linode.cloud.plugins.module_utils.doc_fragments import (
+ lke_version_list as docs,
)
-from ansible_specdoc.objects import (
- FieldType,
- SpecDocMeta,
- SpecField,
- SpecReturnValue,
+from ansible_collections.linode.cloud.plugins.module_utils.linode_common_list import (
+ ListModule,
)
-spec = {
- # Disable the default values
- "state": SpecField(type=FieldType.string, required=False, doc_hide=True),
- "label": SpecField(type=FieldType.string, required=False, doc_hide=True),
- "order": SpecField(
- type=FieldType.string,
- description=["The order to list lke versions in."],
- default="asc",
- choices=["desc", "asc"],
- ),
- "count": SpecField(
- type=FieldType.integer,
- description=[
- "The number of results to return.",
- "If undefined, all results will be returned.",
- ],
- ),
-}
-
-SPECDOC_META = SpecDocMeta(
- description=[
- "List Kubernetes versions available for deployment to a Kubernetes cluster."
- ],
- requirements=global_requirements,
- author=global_authors,
- options=spec,
+module = ListModule(
+ result_display_name="LKE Versions",
+ result_field_name="lke_versions",
+ endpoint_template="/lke/versions",
+ result_docs_url="https://techdocs.akamai.com/linode-api/reference/get-lke-versions",
+ result_samples=docs.result_lke_versions_samples,
examples=docs.specdoc_examples,
- return_values={
- "lke_versions": SpecReturnValue(
- description="The returned LKE versions.",
- docs_url="https://techdocs.akamai.com/linode-api/reference/get-lke-versions",
- type=FieldType.list,
- elements=FieldType.dict,
- sample=docs.result_lke_versions_samples,
- )
- },
)
+SPECDOC_META = module.spec
+
DOCUMENTATION = r"""
"""
EXAMPLES = r"""
@@ -69,33 +30,5 @@
RETURN = r"""
"""
-
-class Module(LinodeModuleBase):
- """Module for getting a list of Kubernetes versions"""
-
- def __init__(self) -> None:
- self.module_arg_spec = SPECDOC_META.ansible_spec
- self.results: Dict[str, Any] = {"lke_versions": []}
-
- super().__init__(module_arg_spec=self.module_arg_spec)
-
- def exec_module(self, **kwargs: Any) -> Optional[dict]:
- """Entrypoint for lke version list module"""
-
- self.results["lke_versions"] = get_all_paginated(
- self.client,
- "/lke/versions",
- None,
- num_results=self.module.params["count"],
- )
-
- return self.results
-
-
-def main() -> None:
- """Constructs and calls the module"""
- Module()
-
-
if __name__ == "__main__":
- main()
+ module.run()
diff --git a/plugins/modules/ssh_key_info.py b/plugins/modules/ssh_key_info.py
index 7842e484..6cb4e636 100644
--- a/plugins/modules/ssh_key_info.py
+++ b/plugins/modules/ssh_key_info.py
@@ -5,58 +5,52 @@
from __future__ import absolute_import, division, print_function
-from typing import Any, Optional
-
import ansible_collections.linode.cloud.plugins.module_utils.doc_fragments.ssh_key_info as docs
-from ansible_collections.linode.cloud.plugins.module_utils.linode_common import (
- LinodeModuleBase,
-)
-from ansible_collections.linode.cloud.plugins.module_utils.linode_docs import (
- global_authors,
- global_requirements,
+from ansible_collections.linode.cloud.plugins.module_utils.linode_common_info import (
+ InfoModule,
+ InfoModuleAttr,
+ InfoModuleResult,
)
from ansible_collections.linode.cloud.plugins.module_utils.linode_helper import (
- filter_null_values,
-)
-from ansible_specdoc.objects import (
- FieldType,
- SpecDocMeta,
- SpecField,
- SpecReturnValue,
+ safe_find,
)
+from ansible_specdoc.objects import FieldType
from linode_api4 import SSHKey
-linode_ssh_key_info_spec = {
- # Disable the default values
- "state": SpecField(type=FieldType.string, required=False, doc_hide=True),
- "id": SpecField(
- type=FieldType.integer,
- conflicts_with=["label"],
- description=["The ID of the SSH key."],
+module = InfoModule(
+ primary_result=InfoModuleResult(
+ field_name="ssh_key",
+ field_type=FieldType.dict,
+ display_name="SSH Key",
+ docs_url="https://techdocs.akamai.com/linode-api/reference/get-ssh-key",
+ samples=docs.ssh_key_info_response_sample,
),
- "label": SpecField(
- type=FieldType.string,
- conflicts_with=["id"],
- description=["The label of the SSH key."],
- ),
-}
-
-SPECDOC_META = SpecDocMeta(
- description=["Get info about the Linode SSH public key."],
- requirements=global_requirements,
- author=global_authors,
- options=linode_ssh_key_info_spec,
+ attributes=[
+ InfoModuleAttr(
+ display_name="ID",
+ name="id",
+ type=FieldType.integer,
+ get=lambda client, params: client.load(
+ SSHKey,
+ params.get("id"),
+ )._raw_json,
+ ),
+ InfoModuleAttr(
+ display_name="label",
+ name="label",
+ type=FieldType.string,
+ get=lambda client, params: safe_find(
+ client.profile.ssh_keys,
+ SSHKey.label == params.get("label"),
+ raise_not_found=True,
+ )._raw_json,
+ ),
+ ],
examples=docs.specdoc_examples,
- return_values={
- "ssh_key": SpecReturnValue(
- description="The SSH key in JSON serialized form.",
- docs_url="https://techdocs.akamai.com/linode-api/reference/get-ssh-key",
- type=FieldType.dict,
- sample=docs.ssh_key_info_response_sample,
- )
- },
)
+SPECDOC_META = module.spec
+
DOCUMENTATION = r"""
"""
EXAMPLES = r"""
@@ -64,56 +58,5 @@
RETURN = r"""
"""
-
-class LinodeSSHKeyInfo(LinodeModuleBase):
- """Module for getting Linode SSH public key"""
-
- def __init__(self) -> None:
- self.module_arg_spec = SPECDOC_META.ansible_spec
- self.results = {"ssh_key": None}
-
- super().__init__(
- module_arg_spec=self.module_arg_spec,
- required_one_of=[("id", "label")],
- mutually_exclusive=[("id", "label")],
- )
-
- def _get_ssh_key_by_label(self, label: str) -> Optional[SSHKey]:
- try:
- ssh_keys = self.client.profile.ssh_keys(SSHKey.label == label)
- if not ssh_keys:
- return self.fail(
- msg=f"failed to get ssh key with label {label}: "
- "ssh key does not exist"
- )
- return ssh_keys[0] # maybe return whole list?
- except Exception as exception:
- return self.fail(msg=f"failed to get ssh key {label}: {exception}")
-
- def _get_ssh_key_by_id(self, ssh_key_id: int) -> Optional[SSHKey]:
- return self._get_resource_by_id(SSHKey, ssh_key_id)
-
- def exec_module(self, **kwargs: Any) -> Optional[dict]:
- """Entrypoint for ssh_key_info module"""
-
- 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
-
-
-def main() -> None:
- """Constructs and calls the module"""
- LinodeSSHKeyInfo()
-
-
if __name__ == "__main__":
- main()
+ module.run()
diff --git a/plugins/modules/ssh_key_list.py b/plugins/modules/ssh_key_list.py
index 92a99991..45df7be6 100644
--- a/plugins/modules/ssh_key_list.py
+++ b/plugins/modules/ssh_key_list.py
@@ -5,96 +5,22 @@
from __future__ import absolute_import, division, print_function
-from typing import Any, Dict, Optional
-
import ansible_collections.linode.cloud.plugins.module_utils.doc_fragments.ssh_key_list as docs
-from ansible_collections.linode.cloud.plugins.module_utils.linode_common import (
- LinodeModuleBase,
-)
-from ansible_collections.linode.cloud.plugins.module_utils.linode_docs import (
- global_authors,
- global_requirements,
-)
-from ansible_collections.linode.cloud.plugins.module_utils.linode_helper import (
- construct_api_filter,
- get_all_paginated,
+from ansible_collections.linode.cloud.plugins.module_utils.linode_common_list import (
+ ListModule,
)
-from ansible_specdoc.objects import (
- FieldType,
- SpecDocMeta,
- SpecField,
- SpecReturnValue,
-)
-
-spec_filter = {
- "name": SpecField(
- type=FieldType.string,
- required=True,
- description=[
- "The name of the field to filter on.",
- (
- "Valid filterable attributes can be found here: "
- "https://techdocs.akamai.com/linode-api/reference/get-profile"
- ),
- ],
- ),
- "values": SpecField(
- type=FieldType.list,
- element_type=FieldType.string,
- required=True,
- description=[
- "A list of values to allow for this field.",
- "Fields will pass this filter if at least one of these values matches.",
- ],
- ),
-}
-spec = {
- # Disable the default values
- "state": SpecField(type=FieldType.string, required=False, doc_hide=True),
- "label": SpecField(type=FieldType.string, required=False, doc_hide=True),
- "order": SpecField(
- type=FieldType.string,
- description=["The order to list ssh keys in."],
- default="asc",
- choices=["desc", "asc"],
- ),
- "order_by": SpecField(
- type=FieldType.string,
- description=["The attribute to order ssh keys by."],
- ),
- "filters": SpecField(
- type=FieldType.list,
- element_type=FieldType.dict,
- suboptions=spec_filter,
- description=["A list of filters to apply to the resulting ssh keys."],
- ),
- "count": SpecField(
- type=FieldType.integer,
- description=[
- "The number of results to return.",
- "If undefined, all results will be returned.",
- ],
- ),
-}
-
-SPECDOC_META = SpecDocMeta(
- description=["List and filter on SSH keys in the Linode profile."],
- requirements=global_requirements,
- author=global_authors,
- options=spec,
+module = ListModule(
+ result_display_name="SSH Keys",
+ result_field_name="ssh_keys",
+ endpoint_template="/profile/sshkeys",
+ result_docs_url="https://techdocs.akamai.com/linode-api/reference/get-ssh-keys",
examples=docs.ssh_key_list_specdoc_examples,
- return_values={
- "ssh_keys": SpecReturnValue(
- description="The returned SSH keys.",
- docs_url="https://techdocs.akamai.com/linode-api/reference/get-ssh-keys",
- type=FieldType.list,
- elements=FieldType.dict,
- sample=docs.result_ssh_key_list_samples,
- )
- },
+ result_samples=docs.result_ssh_key_list_samples,
)
+SPECDOC_META = module.spec
+
DOCUMENTATION = r"""
"""
EXAMPLES = r"""
@@ -102,34 +28,5 @@
RETURN = r"""
"""
-
-class SSHKeyListModule(LinodeModuleBase):
- """Module for getting a list of SSH keys in the Linode profile"""
-
- def __init__(self) -> None:
- self.module_arg_spec = SPECDOC_META.ansible_spec
- self.results: Dict[str, Any] = {"ssh_keys": []}
-
- super().__init__(module_arg_spec=self.module_arg_spec)
-
- def exec_module(self, **kwargs: Any) -> Optional[dict]:
- """Entrypoint for SSH key list module"""
-
- filter_dict = construct_api_filter(self.module.params)
-
- self.results["ssh_keys"] = get_all_paginated(
- self.client,
- "/profile/sshkeys",
- filter_dict,
- num_results=self.module.params["count"],
- )
- return self.results
-
-
-def main() -> None:
- """Constructs and calls the module"""
- SSHKeyListModule()
-
-
if __name__ == "__main__":
- main()
+ module.run()
diff --git a/plugins/modules/token_info.py b/plugins/modules/token_info.py
index bf132d25..6d89df9d 100644
--- a/plugins/modules/token_info.py
+++ b/plugins/modules/token_info.py
@@ -5,59 +5,53 @@
from __future__ import absolute_import, division, print_function
-from typing import Any, Optional
-
import ansible_collections.linode.cloud.plugins.module_utils.doc_fragments.token as docs_parent
import ansible_collections.linode.cloud.plugins.module_utils.doc_fragments.token_info as docs
-from ansible_collections.linode.cloud.plugins.module_utils.linode_common import (
- LinodeModuleBase,
-)
-from ansible_collections.linode.cloud.plugins.module_utils.linode_docs import (
- global_authors,
- global_requirements,
+from ansible_collections.linode.cloud.plugins.module_utils.linode_common_info import (
+ InfoModule,
+ InfoModuleAttr,
+ InfoModuleResult,
)
from ansible_collections.linode.cloud.plugins.module_utils.linode_helper import (
- filter_null_values,
-)
-from ansible_specdoc.objects import (
- FieldType,
- SpecDocMeta,
- SpecField,
- SpecReturnValue,
+ safe_find,
)
+from ansible_specdoc.objects import FieldType
from linode_api4 import PersonalAccessToken
-spec = {
- # Disable the default values
- "state": SpecField(type=FieldType.string, required=False, doc_hide=True),
- "id": SpecField(
- type=FieldType.integer,
- description=["The ID of the token."],
- conflicts_with=["label"],
+module = InfoModule(
+ primary_result=InfoModuleResult(
+ field_name="token",
+ field_type=FieldType.dict,
+ display_name="Personal Access Token",
+ docs_url="https://techdocs.akamai.com/linode-api/reference/get-personal-access-tokens",
+ samples=docs_parent.result_token_samples,
),
- "label": SpecField(
- type=FieldType.string,
- description=["The label of the token."],
- conflicts_with=["id"],
- ),
-}
-
-SPECDOC_META = SpecDocMeta(
- description=["Get info about a Linode Personal Access Token."],
- requirements=global_requirements,
- author=global_authors,
- options=spec,
+ attributes=[
+ InfoModuleAttr(
+ display_name="ID",
+ name="id",
+ type=FieldType.integer,
+ get=lambda client, params: client.load(
+ PersonalAccessToken,
+ params.get("id"),
+ )._raw_json,
+ ),
+ InfoModuleAttr(
+ display_name="label",
+ name="label",
+ type=FieldType.string,
+ get=lambda client, params: safe_find(
+ client.profile.tokens,
+ PersonalAccessToken.label == params.get("label"),
+ raise_not_found=True,
+ )._raw_json,
+ ),
+ ],
examples=docs.specdoc_examples,
- return_values={
- "token": SpecReturnValue(
- description="The token in JSON serialized form.",
- docs_url="https://techdocs.akamai.com/linode-api/reference/post-personal-access-token",
- type=FieldType.dict,
- sample=docs_parent.result_token_samples,
- )
- },
)
+SPECDOC_META = module.spec
+
DOCUMENTATION = r"""
"""
EXAMPLES = r"""
@@ -65,60 +59,5 @@
RETURN = r"""
"""
-
-class Module(LinodeModuleBase):
- """Module for getting info about a Linode token"""
-
- def __init__(self) -> None:
- self.module_arg_spec = SPECDOC_META.ansible_spec
- self.results = {"token": None}
-
- super().__init__(
- module_arg_spec=self.module_arg_spec,
- required_one_of=[("id", "label")],
- mutually_exclusive=[("id", "label")],
- )
-
- def _get_token_by_label(self, label: str) -> Optional[PersonalAccessToken]:
- try:
- return self.client.profile.tokens(
- PersonalAccessToken.label == label
- )[0]
- except IndexError:
- return self.fail(
- msg="failed to get token with label {0}: "
- "token does not exist".format(label)
- )
- except Exception as exception:
- return self.fail(
- msg="failed to get token {0}: {1}".format(label, exception)
- )
-
- def _get_token_by_id(self, token_id: int) -> PersonalAccessToken:
- return self._get_resource_by_id(PersonalAccessToken, token_id)
-
- def exec_module(self, **kwargs: Any) -> Optional[dict]:
- """Entrypoint for token info module"""
-
- params = filter_null_values(self.module.params)
-
- if "id" in params:
- self.results["token"] = self._get_token_by_id(
- params.get("id")
- )._raw_json
-
- if "label" in params:
- self.results["token"] = self._get_token_by_label(
- params.get("label")
- )._raw_json
-
- return self.results
-
-
-def main() -> None:
- """Constructs and calls the module"""
- Module()
-
-
if __name__ == "__main__":
- main()
+ module.run()
diff --git a/plugins/modules/token_list.py b/plugins/modules/token_list.py
index 92ce5094..4d4d0068 100644
--- a/plugins/modules/token_list.py
+++ b/plugins/modules/token_list.py
@@ -4,94 +4,22 @@
"""This module allows users to list Linode tokens."""
from __future__ import absolute_import, division, print_function
-from typing import Any, Dict, Optional
-
import ansible_collections.linode.cloud.plugins.module_utils.doc_fragments.token_list as docs
-from ansible_collections.linode.cloud.plugins.module_utils.linode_common import (
- LinodeModuleBase,
-)
-from ansible_collections.linode.cloud.plugins.module_utils.linode_docs import (
- global_authors,
- global_requirements,
-)
-from ansible_collections.linode.cloud.plugins.module_utils.linode_helper import (
- construct_api_filter,
- get_all_paginated,
+from ansible_collections.linode.cloud.plugins.module_utils.linode_common_list import (
+ ListModule,
)
-from ansible_specdoc.objects import (
- FieldType,
- SpecDocMeta,
- SpecField,
- SpecReturnValue,
-)
-
-spec_filter = {
- "name": SpecField(
- type=FieldType.string,
- required=True,
- description=[
- "The name of the field to filter on.",
- "Valid filterable attributes can be found here: "
- "https://techdocs.akamai.com/linode-api/reference/get-profile",
- ],
- ),
- "values": SpecField(
- type=FieldType.list,
- element_type=FieldType.string,
- required=True,
- description=[
- "A list of values to allow for this field.",
- "Fields will pass this filter if at least one of these values matches.",
- ],
- ),
-}
-spec = {
- # Disable the default values
- "state": SpecField(type=FieldType.string, required=False, doc_hide=True),
- "label": SpecField(type=FieldType.string, required=False, doc_hide=True),
- "order": SpecField(
- type=FieldType.string,
- description=["The order to list tokens in."],
- default="asc",
- choices=["desc", "asc"],
- ),
- "order_by": SpecField(
- type=FieldType.string,
- description=["The attribute to order tokens by."],
- ),
- "filters": SpecField(
- type=FieldType.list,
- element_type=FieldType.dict,
- suboptions=spec_filter,
- description=["A list of filters to apply to the resulting tokens."],
- ),
- "count": SpecField(
- type=FieldType.integer,
- description=[
- "The number of results to return.",
- "If undefined, all results will be returned.",
- ],
- ),
-}
-
-SPECDOC_META = SpecDocMeta(
- description=["List and filter on Linode Account tokens."],
- requirements=global_requirements,
- author=global_authors,
- options=spec,
+module = ListModule(
+ result_display_name="Tokens",
+ result_field_name="tokens",
+ endpoint_template="/profile/tokens",
+ result_docs_url="https://techdocs.akamai.com/linode-api/reference/get-personal-access-tokens",
examples=docs.specdoc_examples,
- return_values={
- "tokens": SpecReturnValue(
- description="The returned tokens.",
- docs_url="https://techdocs.akamai.com/linode-api/reference/get-personal-access-tokens",
- type=FieldType.list,
- elements=FieldType.dict,
- sample=docs.result_tokens_samples,
- ),
- },
+ result_samples=docs.result_tokens_samples,
)
+SPECDOC_META = module.spec
+
DOCUMENTATION = r"""
"""
EXAMPLES = r"""
@@ -99,34 +27,5 @@
RETURN = r"""
"""
-
-class Module(LinodeModuleBase):
- """Module for getting a list of Linode Account tokens"""
-
- def __init__(self) -> None:
- self.module_arg_spec = SPECDOC_META.ansible_spec
- self.results: Dict[str, Any] = {"tokens": []}
-
- super().__init__(module_arg_spec=self.module_arg_spec)
-
- def exec_module(self, **kwargs: Any) -> Optional[dict]:
- """Entrypoint for token list module"""
-
- filter_dict = construct_api_filter(self.module.params)
-
- self.results["tokens"] = get_all_paginated(
- self.client,
- "/profile/tokens",
- filter_dict,
- num_results=self.module.params["count"],
- )
- return self.results
-
-
-def main() -> None:
- """Constructs and calls the module"""
- Module()
-
-
if __name__ == "__main__":
- main()
+ module.run()
diff --git a/plugins/modules/user_list.py b/plugins/modules/user_list.py
index b976d5e9..d34964ce 100644
--- a/plugins/modules/user_list.py
+++ b/plugins/modules/user_list.py
@@ -4,64 +4,22 @@
"""This module allows users to list Users."""
from __future__ import absolute_import, division, print_function
-from typing import Any, Dict, Optional
-
import ansible_collections.linode.cloud.plugins.module_utils.doc_fragments.user_list as docs
-from ansible_collections.linode.cloud.plugins.module_utils.linode_common import (
- LinodeModuleBase,
-)
-from ansible_collections.linode.cloud.plugins.module_utils.linode_docs import (
- global_authors,
- global_requirements,
-)
-from ansible_collections.linode.cloud.plugins.module_utils.linode_helper import (
- get_all_paginated,
-)
-from ansible_specdoc.objects import (
- FieldType,
- SpecDocMeta,
- SpecField,
- SpecReturnValue,
+from ansible_collections.linode.cloud.plugins.module_utils.linode_common_list import (
+ ListModule,
)
-spec = {
- # Disable the default values
- "state": SpecField(type=FieldType.string, required=False, doc_hide=True),
- "label": SpecField(type=FieldType.string, required=False, doc_hide=True),
- "order": SpecField(
- type=FieldType.string,
- description=["The order to list users in."],
- default="asc",
- choices=["desc", "asc"],
- ),
- "count": SpecField(
- type=FieldType.integer,
- description=[
- "The number of results to return.",
- "If undefined, all results will be returned.",
- ],
- ),
-}
-
-SPECDOC_META = SpecDocMeta(
- description=["List Users."],
- requirements=global_requirements,
- author=global_authors,
- options=spec,
+module = ListModule(
+ result_display_name="Users",
+ result_field_name="users",
+ endpoint_template="/account/users",
+ result_docs_url="https://techdocs.akamai.com/linode-api/reference/get-users",
examples=docs.specdoc_examples,
- return_values={
- "users": SpecReturnValue(
- description="The returned users.",
- docs_url=(
- "https://techdocs.akamai.com/linode-api/reference/get-account"
- ),
- type=FieldType.list,
- elements=FieldType.dict,
- sample=docs.result_users_samples,
- )
- },
+ result_samples=docs.result_users_samples,
)
+SPECDOC_META = module.spec
+
DOCUMENTATION = r"""
"""
EXAMPLES = r"""
@@ -69,32 +27,5 @@
RETURN = r"""
"""
-
-class Module(LinodeModuleBase):
- """Module for getting a list of Users"""
-
- def __init__(self) -> None:
- self.module_arg_spec = SPECDOC_META.ansible_spec
- self.results: Dict[str, Any] = {"users": []}
-
- super().__init__(module_arg_spec=self.module_arg_spec)
-
- def exec_module(self, **kwargs: Any) -> Optional[dict]:
- """Entrypoint for user module"""
-
- self.results["users"] = get_all_paginated(
- self.client,
- "/account/users",
- None,
- num_results=self.module.params["count"],
- )
- return self.results
-
-
-def main() -> None:
- """Constructs and calls the module"""
- Module()
-
-
if __name__ == "__main__":
- main()
+ module.run()
diff --git a/plugins/modules/vlan_info.py b/plugins/modules/vlan_info.py
index 9f404860..f8274ea7 100644
--- a/plugins/modules/vlan_info.py
+++ b/plugins/modules/vlan_info.py
@@ -5,52 +5,52 @@
from __future__ import absolute_import, division, print_function
-from typing import Any, List, Optional
-
import ansible_collections.linode.cloud.plugins.module_utils.doc_fragments.vlan_info as docs
-from ansible_collections.linode.cloud.plugins.module_utils.linode_common import (
- LinodeModuleBase,
-)
-from ansible_collections.linode.cloud.plugins.module_utils.linode_docs import (
- BETA_DISCLAIMER,
- global_authors,
- global_requirements,
+from ansible_collections.linode.cloud.plugins.module_utils.linode_common_info import (
+ InfoModule,
+ InfoModuleAttr,
+ InfoModuleResult,
)
-from ansible_specdoc.objects import (
- FieldType,
- SpecDocMeta,
- SpecField,
- SpecReturnValue,
+from ansible_collections.linode.cloud.plugins.module_utils.linode_helper import (
+ safe_find,
)
+from ansible_specdoc.objects import FieldType
from linode_api4 import VLAN
-linode_vlan_info_spec = {
- # We need to overwrite attributes to exclude them as requirements
- "state": SpecField(type=FieldType.string, required=False, doc_hide=True),
- "label": SpecField(
- type=FieldType.string, required=True, description=["The VLAN’s label."]
+module = InfoModule(
+ primary_result=InfoModuleResult(
+ field_name="vlan",
+ field_type=FieldType.dict,
+ display_name="VLAN",
+ docs_url="https://techdocs.akamai.com/linode-api/reference/get-vlans",
+ samples=docs.result_vlan_samples,
),
-}
-
-SPECDOC_META = SpecDocMeta(
- description=[
- "Get info about a Linode VLAN.",
- BETA_DISCLAIMER,
+ attributes=[
+ InfoModuleAttr(
+ display_name="ID",
+ name="id",
+ type=FieldType.integer,
+ get=lambda client, params: client.load(
+ VLAN,
+ params.get("id"),
+ )._raw_json,
+ ),
+ InfoModuleAttr(
+ display_name="label",
+ name="label",
+ type=FieldType.string,
+ get=lambda client, params: safe_find(
+ client.networking.vlans,
+ VLAN.label == params.get("label"),
+ raise_not_found=True,
+ )._raw_json,
+ ),
],
- requirements=global_requirements,
- author=global_authors,
- options=linode_vlan_info_spec,
examples=docs.specdoc_examples,
- return_values={
- "vlan": SpecReturnValue(
- description="The VLAN in JSON serialized form.",
- docs_url="https://techdocs.akamai.com/linode-api/reference/get-vlans",
- type=FieldType.dict,
- sample=docs.result_vlan_samples,
- )
- },
)
+SPECDOC_META = module.spec
+
DOCUMENTATION = r"""
"""
EXAMPLES = r"""
@@ -58,46 +58,5 @@
RETURN = r"""
"""
-
-class LinodeVLANInfo(LinodeModuleBase):
- """Module for getting info about a Linode VLAN"""
-
- def __init__(self) -> None:
- self.module_arg_spec = SPECDOC_META.ansible_spec
- self.required_one_of: List[str] = []
- self.results = {"vlan": None}
-
- super().__init__(
- module_arg_spec=self.module_arg_spec,
- required_one_of=self.required_one_of,
- )
-
- def _get_vlan_by_label(self, label: str) -> Optional[VLAN]:
- try:
- return self.client.networking.vlans(VLAN.label == label)[0]
- except IndexError:
- return None
- except Exception as exception:
- return self.fail(msg="failed to get VLAN {0}".format(exception))
-
- def exec_module(self, **kwargs: Any) -> Optional[dict]:
- """Entrypoint for VLAN info module"""
-
- label: str = kwargs.get("label")
- vlan = self._get_vlan_by_label(label)
-
- if vlan is None:
- self.fail("failed to get vlan")
-
- self.results["vlan"] = vlan._raw_json
-
- return self.results
-
-
-def main() -> None:
- """Constructs and calls the Linode VLAN info module"""
- LinodeVLANInfo()
-
-
if __name__ == "__main__":
- main()
+ module.run()
diff --git a/plugins/modules/vlan_list.py b/plugins/modules/vlan_list.py
index efc3c0b4..dcb5d240 100644
--- a/plugins/modules/vlan_list.py
+++ b/plugins/modules/vlan_list.py
@@ -5,97 +5,22 @@
from __future__ import absolute_import, division, print_function
-from typing import Any, Dict, Optional
-
import ansible_collections.linode.cloud.plugins.module_utils.doc_fragments.vlan_list as docs
-from ansible_collections.linode.cloud.plugins.module_utils.linode_common import (
- LinodeModuleBase,
-)
-from ansible_collections.linode.cloud.plugins.module_utils.linode_docs import (
- BETA_DISCLAIMER,
- global_authors,
- global_requirements,
-)
-from ansible_collections.linode.cloud.plugins.module_utils.linode_helper import (
- construct_api_filter,
- get_all_paginated,
+from ansible_collections.linode.cloud.plugins.module_utils.linode_common_list import (
+ ListModule,
)
-from ansible_specdoc.objects import (
- FieldType,
- SpecDocMeta,
- SpecField,
- SpecReturnValue,
-)
-
-spec_filter = {
- "name": SpecField(
- type=FieldType.string,
- required=True,
- description=[
- "The name of the field to filter on.",
- "Valid filterable attributes can be found here: "
- "https://techdocs.akamai.com/linode-api/reference/get-vlans",
- ],
- ),
- "values": SpecField(
- type=FieldType.list,
- element_type=FieldType.string,
- required=True,
- description=[
- "A list of values to allow for this field.",
- "Fields will pass this filter if at least one of these values matches.",
- ],
- ),
-}
-spec = {
- # Disable the default values
- "state": SpecField(type=FieldType.string, required=False, doc_hide=True),
- "label": SpecField(type=FieldType.string, required=False, doc_hide=True),
- "order": SpecField(
- type=FieldType.string,
- description=["The order to list VLANs in."],
- default="asc",
- choices=["desc", "asc"],
- ),
- "order_by": SpecField(
- type=FieldType.string, description=["The attribute to order VLANs by."]
- ),
- "filters": SpecField(
- type=FieldType.list,
- element_type=FieldType.dict,
- suboptions=spec_filter,
- description=["A list of filters to apply to the resulting VLANs."],
- ),
- "count": SpecField(
- type=FieldType.integer,
- description=[
- "The number of results to return.",
- "If undefined, all results will be returned.",
- ],
- ),
-}
-
-SPECDOC_META = SpecDocMeta(
- description=[
- "List and filter on Linode VLANs.",
- BETA_DISCLAIMER,
- ],
- requirements=global_requirements,
- author=global_authors,
- options=spec,
+module = ListModule(
+ result_display_name="VLANs",
+ result_field_name="vlans",
+ endpoint_template="/networking/vlans",
+ result_docs_url="https://techdocs.akamai.com/linode-api/reference/get-vlans",
examples=docs.specdoc_examples,
- return_values={
- "vlans": SpecReturnValue(
- description="The returned VLANs.",
- docs_url="https://techdocs.akamai.com/linode-api/reference/get-vlans",
- type=FieldType.list,
- elements=FieldType.dict,
- sample=docs.result_vlan_samples,
- )
- },
+ result_samples=docs.result_vlan_samples,
)
+SPECDOC_META = module.spec
+
DOCUMENTATION = r"""
"""
EXAMPLES = r"""
@@ -103,34 +28,5 @@
RETURN = r"""
"""
-
-class Module(LinodeModuleBase):
- """Module for getting info about a Linode VLANs"""
-
- def __init__(self) -> None:
- self.module_arg_spec = SPECDOC_META.ansible_spec
- self.results: Dict[str, Any] = {"vlans": []}
-
- super().__init__(module_arg_spec=self.module_arg_spec)
-
- def exec_module(self, **kwargs: Any) -> Optional[dict]:
- """Entrypoint for VLANs list module"""
-
- filter_dict = construct_api_filter(self.module.params)
-
- self.results["vlans"] = get_all_paginated(
- self.client,
- "/networking/vlans",
- filter_dict,
- num_results=self.module.params["count"],
- )
- return self.results
-
-
-def main() -> None:
- """Constructs and calls the module"""
- Module()
-
-
if __name__ == "__main__":
- main()
+ module.run()
diff --git a/template/README.template.md b/template/README.template.md
index 895729ff..1c6ab1eb 100644
--- a/template/README.template.md
+++ b/template/README.template.md
@@ -102,6 +102,31 @@ For more information on Ansible collection usage, see [Ansible's official usage
Use-case examples for this collection can be found [here](./examples/README.md).
+## Development
+
+The following section outlines various information relating to the development of this collection.
+
+### Attaching a Debugger
+
+To quickly and easily attach a debugger to a running module in this collection,
+you can use the [madbg](https://pypi.org/project/madbg/) package:
+
+1. Install `madbg` in your local Python environment:
+
+```shell
+pip install madbg
+```
+
+2. Call `madbg.set_trace(...)` at the location you would like to create a breakpoint at:
+
+```shell
+import madbg; madbg.set_trace()
+```
+
+3. Run the module in either a playbook or a test.
+4. In a separate shell, run `madbg connect`.
+5. You should now be able to remotely debug the module as soon as the breakpoint is triggered.
+
## Licensing
GNU General Public License v3.0.