From d8cab1f818f0c17b18206036aa96dbc6756e9c1d Mon Sep 17 00:00:00 2001 From: ezilber-akamai Date: Thu, 22 Aug 2024 16:41:28 -0400 Subject: [PATCH 1/2] Migrated token info and list modules --- README.md | 2 +- docs/modules/token_info.md | 8 +- docs/modules/token_list.md | 14 ++-- plugins/modules/token_info.py | 135 ++++++++++------------------------ plugins/modules/token_list.py | 123 +++---------------------------- 5 files changed, 60 insertions(+), 222 deletions(-) diff --git a/README.md b/README.md index 718887a2..53d6d71a 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,7 @@ Name | Description | [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.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.| 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/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() From 28950a9ef41d002b7eb7f324383f134e49a88249 Mon Sep 17 00:00:00 2001 From: ezilber-akamai Date: Mon, 26 Aug 2024 13:59:23 -0400 Subject: [PATCH 2/2] Fixed docs --- docs/inventory/instance.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/inventory/instance.rst b/docs/inventory/instance.rst index 195d8afa..18445b50 100644 --- a/docs/inventory/instance.rst +++ b/docs/inventory/instance.rst @@ -58,7 +58,7 @@ Parameters **strict (type=bool):** - \• If \ :literal:`yes`\ make invalid entries a fatal error, otherwise skip and continue. + \• If :literal:`yes` make invalid entries a fatal error, otherwise skip and continue. \• Since it is possible to use facts in the expressions they might not always be available and we ignore those errors by default. @@ -94,13 +94,13 @@ Parameters **default_value (type=str):** \• The default value when the host variable's value is an empty string. - \• This option is mutually exclusive with \ :literal:`keyed\_groups[].trailing\_separator`\ . + \• This option is mutually exclusive with :literal:`keyed\_groups[].trailing\_separator`. **trailing_separator (type=bool, default=True):** - \• Set this option to \ :literal:`False`\ to omit the \ :literal:`keyed\_groups[].separator`\ after the host variable when the value is an empty string. + \• Set this option to :literal:`False` to omit the :literal:`keyed\_groups[].separator` after the host variable when the value is an empty string. - \• This option is mutually exclusive with \ :literal:`keyed\_groups[].default\_value`\ . + \• This option is mutually exclusive with :literal:`keyed\_groups[].default\_value`.