Skip to content

Commit

Permalink
Migrated Firewall-related info and list modules to new framework (#568)
Browse files Browse the repository at this point in the history
* Migrated firewall info and list modules

* Fixed docs
  • Loading branch information
ezilber-akamai committed Sep 3, 2024
1 parent ce05f8a commit 73cbd64
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 237 deletions.
10 changes: 5 additions & 5 deletions docs/modules/firewall_info.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ Get info about a Linode Firewall.
| Field | Type | Required | Description |
|-----------|------|----------|------------------------------------------------------------------------------|
| `id` | <center>`int`</center> | <center>Optional</center> | The unique id of the Firewall. Optional if `label` is defined. **(Conflicts With: `label`)** |
| `label` | <center>`str`</center> | <center>Optional</center> | The Firewall’s label. Optional if `id` is defined. **(Conflicts With: `id`)** |
| `label` | <center>`str`</center> | <center>Optional</center> | The label of the Firewall to resolve. **(Conflicts With: `id`)** |
| `id` | <center>`int`</center> | <center>Optional</center> | 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
Expand Down Expand Up @@ -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
Expand All @@ -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


12 changes: 6 additions & 6 deletions docs/modules/firewall_list.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,21 @@ List and filter on Firewalls.
| Field | Type | Required | Description |
|-----------|------|----------|------------------------------------------------------------------------------|
| `order` | <center>`str`</center> | <center>Optional</center> | The order to list firewalls in. **(Choices: `desc`, `asc`; Default: `asc`)** |
| `order_by` | <center>`str`</center> | <center>Optional</center> | The attribute to order firewalls by. |
| [`filters` (sub-options)](#filters) | <center>`list`</center> | <center>Optional</center> | A list of filters to apply to the resulting firewalls. |
| `count` | <center>`int`</center> | <center>Optional</center> | The number of results to return. If undefined, all results will be returned. |
| `order` | <center>`str`</center> | <center>Optional</center> | The order to list Firewalls in. **(Choices: `desc`, `asc`; Default: `asc`)** |
| `order_by` | <center>`str`</center> | <center>Optional</center> | The attribute to order Firewalls by. |
| [`filters` (sub-options)](#filters) | <center>`list`</center> | <center>Optional</center> | A list of filters to apply to the resulting Firewalls. |
| `count` | <center>`int`</center> | <center>Optional</center> | The number of Firewalls to return. If undefined, all results will be returned. |

### filters

| Field | Type | Required | Description |
|-----------|------|----------|------------------------------------------------------------------------------|
| `name` | <center>`str`</center> | <center>**Required**</center> | 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` | <center>`str`</center> | <center>**Required**</center> | 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` | <center>`list`</center> | <center>**Required**</center> | 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
Expand Down
161 changes: 48 additions & 113 deletions plugins/modules/firewall_info.py
Original file line number Diff line number Diff line change
@@ -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"""
"""
Expand All @@ -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()
126 changes: 13 additions & 113 deletions plugins/modules/firewall_list.py
Original file line number Diff line number Diff line change
@@ -1,132 +1,32 @@
#!/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"""
"""
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()

0 comments on commit 73cbd64

Please sign in to comment.