diff --git a/README.md b/README.md index bc2bcfe4..05ab2e06 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ Name | Description | [linode.cloud.lke_node_pool](./docs/modules/lke_node_pool.md)|Manage Linode LKE cluster node pools.| [linode.cloud.nodebalancer](./docs/modules/nodebalancer.md)|Manage a Linode NodeBalancer.| [linode.cloud.nodebalancer_node](./docs/modules/nodebalancer_node.md)|Manage Linode NodeBalancer Nodes.| -[linode.cloud.nodebalancer_stats](./docs/modules/nodebalancer_stats.md)|View a Linode NodeBalancers Stats.| +[linode.cloud.nodebalancer_stats](./docs/modules/nodebalancer_stats.md)|Get info about a Linode Node Balancer Stats.| [linode.cloud.object_keys](./docs/modules/object_keys.md)|Manage Linode Object Storage Keys.| [linode.cloud.placement_group](./docs/modules/placement_group.md)|Manage a Linode Placement Group.| [linode.cloud.placement_group_assign](./docs/modules/placement_group_assign.md)|Manages a single assignment between a Linode and a Placement Group.| @@ -69,7 +69,7 @@ Name | Description | [linode.cloud.ip_info](./docs/modules/ip_info.md)|Get info about a Linode IP.| [linode.cloud.ipv6_range_info](./docs/modules/ipv6_range_info.md)|Get info about a Linode IPv6 range.| [linode.cloud.lke_cluster_info](./docs/modules/lke_cluster_info.md)|Get info about a Linode LKE cluster.| -[linode.cloud.nodebalancer_info](./docs/modules/nodebalancer_info.md)|Get info about a Linode NodeBalancer.| +[linode.cloud.nodebalancer_info](./docs/modules/nodebalancer_info.md)|Get info about a Linode Node Balancer.| [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.| @@ -101,7 +101,7 @@ Name | Description | [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.nodebalancer_list](./docs/modules/nodebalancer_list.md)|List and filter on Nodebalancers.| +[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 Linode Regions.| diff --git a/docs/modules/nodebalancer_info.md b/docs/modules/nodebalancer_info.md index 1060595b..ba0e4e2a 100644 --- a/docs/modules/nodebalancer_info.md +++ b/docs/modules/nodebalancer_info.md @@ -1,6 +1,6 @@ # nodebalancer_info -Get info about a Linode NodeBalancer. +Get info about a Linode Node Balancer. - [Minimum Required Fields](#minimum-required-fields) - [Examples](#examples) @@ -31,12 +31,12 @@ Get info about a Linode NodeBalancer. | Field | Type | Required | Description | |-----------|------|----------|------------------------------------------------------------------------------| -| `id` |
`int`
|
Optional
| The ID of this NodeBalancer. Optional if `label` is defined. **(Conflicts With: `label`)** | -| `label` |
`str`
|
Optional
| The label of this NodeBalancer. Optional if `id` is defined. **(Conflicts With: `id`)** | +| `label` |
`str`
|
Optional
| The label of the Node Balancer to resolve. **(Conflicts With: `id`)** | +| `id` |
`int`
|
Optional
| The ID of the Node Balancer to resolve. **(Conflicts With: `label`)** | ## Return Values -- `node_balancer` - The NodeBalancer in JSON serialized form. +- `node_balancer` - The returned Node Balancer. - Sample Response: ```json @@ -64,7 +64,7 @@ Get info about a Linode NodeBalancer. - See the [Linode API response documentation](https://techdocs.akamai.com/linode-api/reference/get-node-balancer) for a list of returned fields -- `configs` - A list of configs applied to the NodeBalancer. +- `configs` - The returned configs. - Sample Response: ```json @@ -96,10 +96,10 @@ Get info about a Linode NodeBalancer. } ] ``` - - See the [Linode API response documentation](https://techdocs.akamai.com/linode-api/reference/get-node-balancer-config) for a list of returned fields + - See the [Linode API response documentation](https://techdocs.akamai.com/linode-api/reference/get-node-balancer-configs) for a list of returned fields -- `nodes` - A list of configs applied to the NodeBalancer. +- `nodes` - The returned nodes. - Sample Response: ```json @@ -116,10 +116,10 @@ Get info about a Linode NodeBalancer. } ] ``` - - See the [Linode API response documentation](https://techdocs.akamai.com/linode-api/reference/get-node-balancer-node) for a list of returned fields + - See the [Linode API response documentation](https://techdocs.akamai.com/linode-api/reference/get-node-balancer-config-nodes) for a list of returned fields -- `firewalls` - A list IDs for firewalls attached to this NodeBalancer. +- `firewalls` - The returned firewalls. - Sample Response: ```json @@ -131,3 +131,37 @@ Get info about a Linode NodeBalancer. - See the [Linode API response documentation](https://techdocs.akamai.com/linode-api/reference/get-node-balancer-firewalls) for a list of returned fields +- `firewalls_data` - The returned firewalls_data. + + - Sample Response: + ```json + [ + { + "created": "2020-04-10T13:34:00", + "entities": [ + { + "id": 1234, + "label": "example-label", + "type": "nodebalancer", + "url": "/v4/nodebalancers/1234" + } + ], + "id": 45678, + "label": "very-cool-label", + "rules": { + "fingerprint": "abcdefg", + "inbound": [], + "inbound_policy": "DROP", + "outbound": [], + "outbound_policy": "DROP", + "version": 1 + }, + "status": "enabled", + "tags": [], + "updated": "2020-04-10T13:34:01" + } + ] + ``` + - See the [Linode API response documentation](https://techdocs.akamai.com/linode-api/reference/get-node-balancer-firewalls) for a list of returned fields + + diff --git a/docs/modules/nodebalancer_list.md b/docs/modules/nodebalancer_list.md index 60853355..67cb2a28 100644 --- a/docs/modules/nodebalancer_list.md +++ b/docs/modules/nodebalancer_list.md @@ -1,6 +1,6 @@ # nodebalancer_list -List and filter on Nodebalancers. +List and filter on Node Balancers. - [Minimum Required Fields](#minimum-required-fields) - [Examples](#examples) @@ -32,21 +32,21 @@ List and filter on Nodebalancers. | Field | Type | Required | Description | |-----------|------|----------|------------------------------------------------------------------------------| -| `order` |
`str`
|
Optional
| The order to list nodebalancers in. **(Choices: `desc`, `asc`; Default: `asc`)** | -| `order_by` |
`str`
|
Optional
| The attribute to order nodebalancers by. | -| [`filters` (sub-options)](#filters) |
`list`
|
Optional
| A list of filters to apply to the resulting nodebalancers. | -| `count` |
`int`
|
Optional
| The number of results to return. If undefined, all results will be returned. | +| `order` |
`str`
|
Optional
| The order to list Node Balancers in. **(Choices: `desc`, `asc`; Default: `asc`)** | +| `order_by` |
`str`
|
Optional
| The attribute to order Node Balancers by. | +| [`filters` (sub-options)](#filters) |
`list`
|
Optional
| A list of filters to apply to the resulting Node Balancers. | +| `count` |
`int`
|
Optional
| The number of Node Balancers 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-node-balancers | +| `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-node-balancers). | | `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 -- `nodebalancers` - The returned nodebalancers. +- `nodebalancers` - The returned Node Balancers. - Sample Response: ```json diff --git a/docs/modules/nodebalancer_stats.md b/docs/modules/nodebalancer_stats.md index 7a1ae565..fcd344da 100644 --- a/docs/modules/nodebalancer_stats.md +++ b/docs/modules/nodebalancer_stats.md @@ -1,6 +1,6 @@ # nodebalancer_stats -View a Linode NodeBalancers Stats. +Get info about a Linode Node Balancer Stats. - [Minimum Required Fields](#minimum-required-fields) - [Examples](#examples) @@ -28,12 +28,12 @@ View a Linode NodeBalancers Stats. | Field | Type | Required | Description | |-----------|------|----------|------------------------------------------------------------------------------| -| `id` |
`int`
|
Optional
| The id of the nodebalancer for which the statistics apply to. **(Conflicts With: `label`)** | -| `label` |
`str`
|
Optional
| The label of the nodebalancer for which the statistics apply to. **(Conflicts With: `id`)** | +| `label` |
`str`
|
Optional
| The label of the Node Balancer Stats to resolve. **(Conflicts With: `id`)** | +| `id` |
`int`
|
Optional
| The ID of the Node Balancer Stats to resolve. **(Conflicts With: `label`)** | ## Return Values -- `node_balancer_stats` - The NodeBalancer Stats in JSON serialized form. +- `node_balancer_stats` - The returned Node Balancer Stats. - Sample Response: ```json diff --git a/plugins/module_utils/doc_fragments/nodebalancer.py b/plugins/module_utils/doc_fragments/nodebalancer.py index e0bf2dcc..aa6350e5 100644 --- a/plugins/module_utils/doc_fragments/nodebalancer.py +++ b/plugins/module_utils/doc_fragments/nodebalancer.py @@ -86,3 +86,30 @@ 1234, 5678 ]'''] + +result_firewalls_data_samples = ['''[ + { + "created": "2020-04-10T13:34:00", + "entities": [ + { + "id": 1234, + "label": "example-label", + "type": "nodebalancer", + "url": "/v4/nodebalancers/1234" + } + ], + "id": 45678, + "label": "very-cool-label", + "rules": { + "fingerprint": "abcdefg", + "inbound": [], + "inbound_policy": "DROP", + "outbound": [], + "outbound_policy": "DROP", + "version": 1 + }, + "status": "enabled", + "tags": [], + "updated": "2020-04-10T13:34:01" + } +]'''] diff --git a/plugins/modules/nodebalancer_info.py b/plugins/modules/nodebalancer_info.py index b5cc230d..4f3aed8d 100644 --- a/plugins/modules/nodebalancer_info.py +++ b/plugins/modules/nodebalancer_info.py @@ -1,11 +1,11 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -"""This module contains all of the functionality for Linode NodeBalancers.""" +"""This module allows users to retrieve information about a Linode NodeBalancer.""" from __future__ import absolute_import, division, print_function -from typing import Any, List, Optional +from typing import Any, Dict, List from ansible_collections.linode.cloud.plugins.module_utils.doc_fragments import ( nodebalancer as docs_parent, @@ -13,83 +13,118 @@ from ansible_collections.linode.cloud.plugins.module_utils.doc_fragments import ( nodebalancer_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, -) -from ansible_specdoc.objects import ( - FieldType, - SpecDocMeta, - SpecField, - SpecReturnValue, + paginated_list_to_json, + safe_find, ) -from linode_api4 import NodeBalancer, NodeBalancerConfig, NodeBalancerNode - -linode_nodebalancer_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 ID of this NodeBalancer.", - "Optional if `label` is defined.", - ], +from ansible_specdoc.objects import FieldType +from linode_api4 import LinodeClient, NodeBalancer + + +def _get_firewalls_data( + client: LinodeClient, nodebalancer: NodeBalancer, params: Dict[str, Any] +) -> List[Any]: + firewalls = NodeBalancer(client, nodebalancer["id"]).firewalls() + firewalls_json = [] + for firewall in firewalls: + firewall._api_get() + firewalls_json.append(firewall._raw_json) + return firewalls_json + + +def _get_nodes( + client: LinodeClient, nodebalancer: NodeBalancer, params: Dict[str, Any] +) -> List[Any]: + configs = NodeBalancer(client, nodebalancer["id"]).configs + nodes_json = [] + for config in configs: + for node in config.nodes: + node._api_get() + nodes_json.append(node._raw_json) + return nodes_json + + +module = InfoModule( + primary_result=InfoModuleResult( + field_name="node_balancer", + field_type=FieldType.dict, + display_name="Node Balancer", + docs_url="https://techdocs.akamai.com/linode-api/reference/get-node-balancer", + samples=docs_parent.result_node_balancer_samples, ), - "label": SpecField( - type=FieldType.string, - required=False, - conflicts_with=["id"], - description=[ - "The label of this NodeBalancer.", - "Optional if `id` is defined.", - ], - ), -} - -SPECDOC_META = SpecDocMeta( - description=["Get info about a Linode NodeBalancer."], - requirements=global_requirements, - author=global_authors, - options=linode_nodebalancer_info_spec, - examples=docs.specdoc_examples, - return_values={ - "node_balancer": SpecReturnValue( - description="The NodeBalancer in JSON serialized form.", - docs_url="https://techdocs.akamai.com/linode-api/reference/get-node-balancer", - type="dict", - sample=docs_parent.result_node_balancer_samples, + secondary_results=[ + InfoModuleResult( + field_name="configs", + field_type=FieldType.list, + display_name="configs", + docs_url="https://techdocs.akamai.com/linode-api/reference/get-node-balancer-configs", + samples=docs_parent.result_configs_samples, + get=lambda client, nodebalancer, params: paginated_list_to_json( + NodeBalancer(client, nodebalancer["id"]).configs + ), ), - "configs": SpecReturnValue( - description="A list of configs applied to the NodeBalancer.", - docs_url="https://techdocs.akamai.com/linode-api/reference/get-node-balancer-config", - type=FieldType.list, - sample=docs_parent.result_configs_samples, + InfoModuleResult( + field_name="nodes", + field_type=FieldType.list, + display_name="nodes", + docs_url="https://techdocs.akamai.com/linode-api/" + + "reference/get-node-balancer-config-nodes", + samples=docs_parent.result_nodes_samples, + get=_get_nodes, ), - "nodes": SpecReturnValue( - description="A list of configs applied to the NodeBalancer.", - docs_url="https://techdocs.akamai.com/linode-api/reference/get-node-balancer-node", - type=FieldType.list, - sample=docs_parent.result_nodes_samples, + InfoModuleResult( + field_name="firewalls", + field_type=FieldType.list, + display_name="firewalls", + docs_url="https://techdocs.akamai.com/linode-api/reference/get-node-balancer-firewalls", + samples=docs_parent.result_firewalls_samples, + get=lambda client, nodebalancer, params: [ + firewall.id + for firewall in NodeBalancer( + client, nodebalancer["id"] + ).firewalls() + ], ), - "firewalls": SpecReturnValue( - description="A list IDs for firewalls attached to this NodeBalancer.", + InfoModuleResult( + field_name="firewalls_data", + field_type=FieldType.list, + display_name="firewalls_data", docs_url="https://techdocs.akamai.com/linode-api/reference/get-node-balancer-firewalls", - type=FieldType.list, - elements=FieldType.integer, - sample=docs_parent.result_firewalls_samples, + samples=docs_parent.result_firewalls_data_samples, + get=_get_firewalls_data, + ), + ], + attributes=[ + InfoModuleAttr( + display_name="ID", + name="id", + type=FieldType.integer, + get=lambda client, params: client.load( + NodeBalancer, + params.get("id"), + )._raw_json, + ), + InfoModuleAttr( + display_name="label", + name="label", + type=FieldType.string, + get=lambda client, params: safe_find( + client.nodebalancers, + NodeBalancer.label == params.get("label"), + raise_not_found=True, + )._raw_json, ), - }, + ], + examples=docs.specdoc_examples, ) -linode_nodebalancer_valid_filters = ["id", "label"] + +SPECDOC_META = module.spec DOCUMENTATION = r""" """ @@ -98,94 +133,5 @@ RETURN = r""" """ - -class LinodeNodeBalancerInfo(LinodeModuleBase): - """Module for getting info about a Linode NodeBalancer""" - - def __init__(self) -> None: - self.module_arg_spec = SPECDOC_META.ansible_spec - self.required_one_of: List[str] = [] - self.results: dict = { - "node_balancer": None, - "configs": [], - "nodes": [], - "firewalls": [], - } - - super().__init__( - module_arg_spec=self.module_arg_spec, - required_one_of=self.required_one_of, - ) - - def _get_matching_nodebalancer(self) -> Optional[NodeBalancer]: - filter_items = { - k: v - for k, v in self.module.params.items() - if k in linode_nodebalancer_valid_filters and v is not None - } - - filter_statement = create_filter_and(NodeBalancer, filter_items) - - try: - # Special case because ID is not filterable - if "id" in filter_items.keys(): - result = NodeBalancer(self.client, self.module.params.get("id")) - result._api_get() # Force lazy-loading - - return result - - return self.client.nodebalancers(filter_statement)[0] - except IndexError: - return None - except Exception as exception: - return self.fail( - msg="failed to get nodebalancer {0}".format(exception) - ) - - def _get_node_by_label( - self, config: NodeBalancerConfig, label: str - ) -> Optional[NodeBalancerNode]: - try: - return config.nodes(NodeBalancerNode.label == label)[0] - except IndexError: - return None - except Exception as exception: - return self.fail( - msg="failed to get nodebalancer node {0}, {1}".format( - label, exception - ) - ) - - def exec_module(self, **kwargs: Any) -> Optional[dict]: - """Entrypoint for NodeBalancer Info module""" - - node_balancer = self._get_matching_nodebalancer() - - if node_balancer is None: - return self.fail("failed to get nodebalancer") - - self.results["node_balancer"] = node_balancer._raw_json - - for config in node_balancer.configs: - self.results["configs"].append(config._raw_json) - - for node in config.nodes: - node._api_get() - - self.results["nodes"].append(node._raw_json) - - # NOTE: Only the Firewall IDs are used here to reduce the - # number of API requests made by this module and to simplify - # the module result. - self.results["firewalls"] = [v.id for v in node_balancer.firewalls()] - - return self.results - - -def main() -> None: - """Constructs and calls the Linode NodeBalancer Info module""" - LinodeNodeBalancerInfo() - - if __name__ == "__main__": - main() + module.run() diff --git a/plugins/modules/nodebalancer_list.py b/plugins/modules/nodebalancer_list.py index 8e9f30fb..8417f3c3 100644 --- a/plugins/modules/nodebalancer_list.py +++ b/plugins/modules/nodebalancer_list.py @@ -1,99 +1,26 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -"""This module allows users to list Nodebalancers.""" -from __future__ import absolute_import, division, print_function +"""This module contains all of the functionality for listing Linode Node Balancers.""" -from typing import Any, Dict, Optional +from __future__ import absolute_import, division, print_function import ansible_collections.linode.cloud.plugins.module_utils.doc_fragments.nodebalancer_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-node-balancers", - ], - ), - "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 nodebalancers in."], - default="asc", - choices=["desc", "asc"], - ), - "order_by": SpecField( - type=FieldType.string, - description=["The attribute to order nodebalancers by."], - ), - "filters": SpecField( - type=FieldType.list, - element_type=FieldType.dict, - suboptions=spec_filter, - description=[ - "A list of filters to apply to the resulting nodebalancers." - ], - ), - "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 Nodebalancers."], - requirements=global_requirements, - author=global_authors, - options=spec, +module = ListModule( + result_display_name="Node Balancers", + result_field_name="nodebalancers", + endpoint_template="/nodebalancers", + result_docs_url="https://techdocs.akamai.com/linode-api/reference/get-node-balancers", examples=docs.specdoc_examples, - return_values={ - "nodebalancers": SpecReturnValue( - description="The returned nodebalancers.", - docs_url="https://techdocs.akamai.com/linode-api/reference/get-node-balancers", - type=FieldType.list, - elements=FieldType.dict, - sample=docs.result_nodebalancers_samples, - ) - }, + result_samples=docs.result_nodebalancers_samples, ) +SPECDOC_META = module.spec + DOCUMENTATION = r""" """ EXAMPLES = r""" @@ -101,34 +28,5 @@ RETURN = r""" """ - -class Module(LinodeModuleBase): - """Module for getting a list of Linode Nodebalancers""" - - def __init__(self) -> None: - self.module_arg_spec = SPECDOC_META.ansible_spec - self.results: Dict[str, Any] = {"nodebalancers": []} - - super().__init__(module_arg_spec=self.module_arg_spec) - - def exec_module(self, **kwargs: Any) -> Optional[dict]: - """Entrypoint for nodebalancers list module""" - - filter_dict = construct_api_filter(self.module.params) - - self.results["nodebalancers"] = get_all_paginated( - self.client, - "/nodebalancers", - 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/nodebalancer_stats.py b/plugins/modules/nodebalancer_stats.py index ecad435c..c7b6d778 100644 --- a/plugins/modules/nodebalancer_stats.py +++ b/plugins/modules/nodebalancer_stats.py @@ -5,60 +5,54 @@ from __future__ import absolute_import, division, print_function -from typing import Any, Dict, List, Optional - from ansible_collections.linode.cloud.plugins.module_utils.doc_fragments import ( nodebalancer_stats 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_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 NodeBalancer -linode_nodebalancer_stats_spec = { - "state": SpecField(type=FieldType.string, required=False, doc_hide=True), - "id": SpecField( - type=FieldType.integer, - description=[ - "The id of the nodebalancer for which the statistics apply to." - ], - conflicts_with=["label"], - ), - "label": SpecField( - type=FieldType.string, - description=[ - "The label of the nodebalancer for which the statistics apply to." - ], - conflicts_with=["id"], +module = InfoModule( + primary_result=InfoModuleResult( + field_name="node_balancer_stats", + field_type=FieldType.dict, + display_name="Node Balancer Stats", + docs_url="https://techdocs.akamai.com/linode-api/reference/get-node-balancer-stats", + samples=docs.result_nodebalancer_stats_samples, ), -} - -SPECDOC_META = SpecDocMeta( - description=["View a Linode NodeBalancers Stats."], - requirements=global_requirements, - author=global_authors, - options=linode_nodebalancer_stats_spec, - examples=docs.specdoc_examples, - return_values={ - "node_balancer_stats": SpecReturnValue( - description="The NodeBalancer Stats in JSON serialized form.", - docs_url="https://techdocs.akamai.com/linode-api/reference/get-node-balancer-stats", - type=FieldType.dict, - sample=docs.result_nodebalancer_stats_samples, + attributes=[ + InfoModuleAttr( + display_name="ID", + name="id", + type=FieldType.integer, + get=lambda client, params: client.load( + NodeBalancer, + params.get("id"), + )._raw_json, + ), + InfoModuleAttr( + display_name="label", + name="label", + type=FieldType.string, + get=lambda client, params: safe_find( + client.nodebalancers, + NodeBalancer.label == params.get("label"), + raise_not_found=True, + )._raw_json, ), - }, + ], + examples=docs.specdoc_examples, ) +SPECDOC_META = module.spec + DOCUMENTATION = r""" """ EXAMPLES = r""" @@ -66,69 +60,5 @@ RETURN = r""" """ - -class Module(LinodeModuleBase): - """Module for getting info about a NodeBalancer's Statistics""" - - def __init__(self) -> None: - self.required_one_of: List[str] = [] - self.results: Dict[str, Any] = {"node_balancer_stats": {}} - - self.module_arg_spec = SPECDOC_META.ansible_spec - - super().__init__( - module_arg_spec=self.module_arg_spec, - required_one_of=self.required_one_of, - ) - - def _get_stats_by_label(self, label: str) -> Optional[dict]: - try: - nodebalancer = self.client.nodebalancers( - NodeBalancer.label == label - )[0] - return self.client.get( - "/nodebalancers/{}/stats".format(nodebalancer.id) - ) - except IndexError: - return self.fail( - msg="failed to find nodebalancer with label {0}: " - "nodebalancer does not exist".format(label) - ) - except Exception as exception: - return self.fail( - msg="failed to get nodebalancer {0}: {1}".format( - label, exception - ) - ) - - def exec_module(self, **kwargs: Any) -> Optional[dict]: - """Entrypoint for NodeBalancer Statistics module""" - - if (kwargs["id"] is None and kwargs["label"] is None) or ( - kwargs["id"] is not None and kwargs["label"] is not None - ): - return self.fail( - msg="Label and ID are mutually exclusive and one " - + "must be used to resolve Nodebalancer statistics." - ) - - if kwargs["id"] is not None: - self.results["node_balancer_stats"] = self.client.get( - "/nodebalancers/{}/stats".format(kwargs["id"]) - ) - - if kwargs["label"] is not None: - self.results["node_balancer_stats"] = self._get_stats_by_label( - kwargs["label"] - ) - - return self.results - - -def main() -> None: - """Constructs and calls the nodebalancer_stats module""" - Module() - - if __name__ == "__main__": - main() + module.run() diff --git a/tests/integration/targets/nodebalancer_populated/tasks/main.yaml b/tests/integration/targets/nodebalancer_populated/tasks/main.yaml index 19958f1f..12b41757 100644 --- a/tests/integration/targets/nodebalancer_populated/tasks/main.yaml +++ b/tests/integration/targets/nodebalancer_populated/tasks/main.yaml @@ -248,26 +248,34 @@ - rm_config.configs|length == 1 - rm_config.nodes|length == 1 - - name: Get info about the NodeBalancer + - name: Get info about the NodeBalancer by label linode.cloud.nodebalancer_info: label: '{{ create_populated_nodebalancer.node_balancer.label }}' + register: nb_info_label + + - name: Get info about the NodeBalancer by id + linode.cloud.nodebalancer_info: id: '{{ create_populated_nodebalancer.node_balancer.id }}' - register: nb_info + register: nb_info_id - name: Assert that info is valid assert: that: - - nb_info.node_balancer.label == rm_config.node_balancer.label - - nb_info.configs|length == 1 - - nb_info.nodes|length == 1 - - nb_info.nodes[0] != None + - nb_info_label.node_balancer.label == rm_config.node_balancer.label + - nb_info_label.configs|length == 1 + - nb_info_label.nodes|length == 1 + - nb_info_label.nodes[0] != None + - nb_info_id.node_balancer.id == rm_config.node_balancer.id + - nb_info_id.configs|length == 1 + - nb_info_id.nodes|length == 1 + - nb_info_id.nodes[0] != None - name: Get info about a NodeBalancer that doesn't exist linode.cloud.nodebalancer_info: label: 'fake_nodebalancer-{{ r }}' register: fake_nb_info failed_when: - - "'failed' not in fake_nb_info.msg" + - "'Failed' not in fake_nb_info.msg" always: - ignore_errors: yes diff --git a/tests/integration/targets/nodebalancer_stats/tasks/main.yaml b/tests/integration/targets/nodebalancer_stats/tasks/main.yaml index b51b77cd..0d002d69 100644 --- a/tests/integration/targets/nodebalancer_stats/tasks/main.yaml +++ b/tests/integration/targets/nodebalancer_stats/tasks/main.yaml @@ -76,13 +76,11 @@ linode.cloud.nodebalancer_stats: id: '{{ create_populated_nodebalancer.node_balancer.id }}' register: nodebalancer_stats_id - failed_when: '"Stats are unavailable at this time" not in nodebalancer_stats_id.msg' - name: Get stats about the Nodebalancer by label linode.cloud.nodebalancer_stats: label: '{{ create_populated_nodebalancer.node_balancer.label }}' register: nodebalancer_stats_label - failed_when: '"Stats are unavailable at this time" not in nodebalancer_stats_label.msg' always: - ignore_errors: yes