-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: implement firewall_info module
- Loading branch information
Showing
11 changed files
with
439 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,244 @@ | ||
#!/usr/bin/python | ||
|
||
# Copyright: (c) 2019, Hetzner Cloud GmbH <[email protected]> | ||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) | ||
|
||
|
||
from __future__ import annotations | ||
|
||
DOCUMENTATION = """ | ||
--- | ||
module: firewall_info | ||
short_description: Gather infos about the Hetzner Cloud Firewalls. | ||
description: | ||
- Gather facts about your Hetzner Cloud Firewalls. | ||
author: | ||
- Jonas Lammler (@jooola) | ||
options: | ||
id: | ||
description: | ||
- The ID of the Firewall you want to get. | ||
- The module will fail if the provided ID is invalid. | ||
type: int | ||
name: | ||
description: | ||
- The name for the Firewall you want to get. | ||
type: str | ||
label_selector: | ||
description: | ||
- The label selector for the Firewall you want to get. | ||
type: str | ||
extends_documentation_fragment: | ||
- hetzner.hcloud.hcloud | ||
""" | ||
|
||
EXAMPLES = """ | ||
- name: Gather hcloud Firewall infos | ||
hetzner.hcloud.firewall_info: | ||
register: output | ||
- name: Print the gathered infos | ||
debug: | ||
var: output | ||
""" | ||
|
||
RETURN = """ | ||
hcloud_firewall_info: | ||
description: List of Firewalls. | ||
returned: always | ||
type: list | ||
elements: dict | ||
contains: | ||
id: | ||
description: Numeric identifier of the firewall. | ||
returned: always | ||
type: int | ||
sample: 1937415 | ||
name: | ||
description: Name of the firewall. | ||
returned: always | ||
type: str | ||
sample: my-firewall | ||
labels: | ||
description: User-defined labels (key-value pairs). | ||
returned: always | ||
type: dict | ||
rules: | ||
description: List of rules the firewall contain. | ||
returned: always | ||
type: list | ||
elements: dict | ||
contains: | ||
description: | ||
description: User defined description of this rule. | ||
type: str | ||
returned: always | ||
sample: allow http from anywhere | ||
direction: | ||
description: The direction of the firewall rule. | ||
type: str | ||
returned: always | ||
sample: in | ||
protocol: | ||
description: The protocol of the firewall rule. | ||
type: str | ||
returned: always | ||
sample: tcp | ||
port: | ||
description: The port or port range allowed by this rule. | ||
type: str | ||
returned: if RV(hcloud_firewall_info[].rules[].protocol=tcp) or RV(hcloud_firewall_info[].rules[].protocol=udp) | ||
sample: "80" | ||
source_ips: | ||
description: List of source CIDRs that are allowed within this rule. | ||
type: list | ||
elements: str | ||
returned: always | ||
sample: ["0.0.0.0/0", "::/0"] | ||
destination_ips: | ||
description: List of destination CIDRs that are allowed within this rule. | ||
type: list | ||
elements: str | ||
returned: always | ||
sample: [] | ||
applied_to: | ||
description: List of Resources the Firewall is applied to. | ||
returned: always | ||
type: list | ||
elements: dict | ||
contains: | ||
type: | ||
description: Type of the resource. | ||
type: str | ||
choices: [server, label_selector] | ||
sample: label_selector | ||
server: | ||
description: ID of the server. | ||
type: int | ||
sample: 12345 | ||
label_selector: | ||
description: Label selector value. | ||
type: str | ||
sample: env=prod | ||
applied_to_resources: | ||
description: List of Resources the Firewall label selector is applied to. | ||
returned: if RV(hcloud_firewall_info[].applied_to[].type=label_selector) | ||
type: list | ||
elements: dict | ||
contains: | ||
type: | ||
description: Type of resource referenced. | ||
type: str | ||
choices: [server] | ||
sample: server | ||
server: | ||
description: ID of the Server. | ||
type: int | ||
sample: 12345 | ||
""" | ||
|
||
from ansible.module_utils.basic import AnsibleModule | ||
from ansible.module_utils.common.text.converters import to_native | ||
|
||
from ..module_utils.hcloud import AnsibleHCloud | ||
from ..module_utils.vendor.hcloud import HCloudException | ||
from ..module_utils.vendor.hcloud.firewalls import ( | ||
BoundFirewall, | ||
FirewallResource, | ||
FirewallRule, | ||
) | ||
|
||
|
||
class AnsibleHCloudFirewallInfo(AnsibleHCloud): | ||
represent = "hcloud_firewall_info" | ||
|
||
hcloud_firewall_info: list[BoundFirewall] | None = None | ||
|
||
def _prepare_result(self): | ||
tmp = [] | ||
|
||
for firewall in self.hcloud_firewall_info: | ||
if firewall is None: | ||
continue | ||
|
||
tmp.append( | ||
{ | ||
"id": to_native(firewall.id), | ||
"name": to_native(firewall.name), | ||
"labels": firewall.labels, | ||
"rules": [self._prepare_result_rule(rule) for rule in firewall.rules], | ||
"applied_to": [self._prepare_result_applied_to(resource) for resource in firewall.applied_to], | ||
} | ||
) | ||
|
||
return tmp | ||
|
||
def _prepare_result_rule(self, rule: FirewallRule): | ||
return { | ||
"description": to_native(rule.description) if rule.description is not None else None, | ||
"direction": rule.direction, | ||
"protocol": to_native(rule.protocol), | ||
"port": to_native(rule.port) if rule.port is not None else None, | ||
"source_ips": [to_native(cidr) for cidr in rule.source_ips], | ||
"destination_ips": [to_native(cidr) for cidr in rule.destination_ips], | ||
} | ||
|
||
def _prepare_result_applied_to(self, resource: FirewallResource): | ||
result = { | ||
"type": resource.type, | ||
"server": to_native(resource.server.id) if resource.server is not None else None, | ||
"label_selector": resource.label_selector.selector if resource.label_selector is not None else None, | ||
} | ||
if resource.applied_to_resources is not None: | ||
result["applied_to_resources"] = [ | ||
{ | ||
"type": item.type, | ||
"server": item.server.id if item.server is not None else None, | ||
} | ||
for item in resource.applied_to_resources | ||
] | ||
return result | ||
|
||
def get_firewalls(self): | ||
try: | ||
if self.module.params.get("id") is not None: | ||
self.hcloud_firewall_info = [self.client.firewalls.get_by_id(self.module.params.get("id"))] | ||
elif self.module.params.get("name") is not None: | ||
self.hcloud_firewall_info = [self.client.firewalls.get_by_name(self.module.params.get("name"))] | ||
elif self.module.params.get("label_selector") is not None: | ||
self.hcloud_firewall_info = self.client.firewalls.get_all( | ||
label_selector=self.module.params.get("label_selector") | ||
) | ||
else: | ||
self.hcloud_firewall_info = self.client.firewalls.get_all() | ||
|
||
except HCloudException as exception: | ||
self.fail_json_hcloud(exception) | ||
|
||
@classmethod | ||
def define_module(cls): | ||
return AnsibleModule( | ||
argument_spec=dict( | ||
id={"type": "int"}, | ||
name={"type": "str"}, | ||
label_selector={"type": "str"}, | ||
**super().base_module_arguments(), | ||
), | ||
supports_check_mode=True, | ||
) | ||
|
||
|
||
def main(): | ||
module = AnsibleHCloudFirewallInfo.define_module() | ||
hcloud = AnsibleHCloudFirewallInfo(module) | ||
|
||
hcloud.get_firewalls() | ||
module.exit_json(**hcloud.get_result()) | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
cloud/hcloud | ||
shippable/hcloud/group2 |
12 changes: 12 additions & 0 deletions
12
tests/integration/targets/firewall_info/defaults/main/common.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# | ||
# DO NOT EDIT THIS FILE! Please edit the files in tests/integration/common instead. | ||
# | ||
--- | ||
# Azure Pipelines will configure this value to something similar to | ||
# "azp-84824-1-hetzner-2-13-test-2-13-hcloud-3-9-1-default-i" | ||
hcloud_prefix: "tests" | ||
|
||
# Used to namespace resources created by concurrent test pipelines/targets | ||
hcloud_run_ns: "{{ hcloud_prefix | md5 }}" | ||
hcloud_role_ns: "{{ role_name | split('_') | map('first') | join() }}" | ||
hcloud_ns: "ansible-{{ hcloud_run_ns }}-{{ hcloud_role_ns }}" |
5 changes: 5 additions & 0 deletions
5
tests/integration/targets/firewall_info/defaults/main/main.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Copyright: (c) 2019, Hetzner Cloud GmbH <[email protected]> | ||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) | ||
--- | ||
hcloud_server_name: "{{ hcloud_ns }}" | ||
hcloud_firewall_name: "{{ hcloud_ns }}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
--- | ||
- name: Cleanup test_server | ||
hetzner.hcloud.server: | ||
name: "{{ hcloud_server_name }}" | ||
state: absent | ||
|
||
- name: Cleanup test_firewall | ||
hetzner.hcloud.firewall: | ||
name: "{{ hcloud_firewall_name }}" | ||
state: absent |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# | ||
# DO NOT EDIT THIS FILE! Please edit the files in tests/integration/common instead. | ||
# | ||
--- | ||
- name: Check if cleanup.yml exists | ||
ansible.builtin.stat: | ||
path: "{{ role_path }}/tasks/cleanup.yml" | ||
register: cleanup_file | ||
|
||
- name: Check if prepare.yml exists | ||
ansible.builtin.stat: | ||
path: "{{ role_path }}/tasks/prepare.yml" | ||
register: prepare_file | ||
|
||
- name: Include cleanup tasks | ||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/cleanup.yml" | ||
when: cleanup_file.stat.exists | ||
|
||
- name: Include prepare tasks | ||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/prepare.yml" | ||
when: prepare_file.stat.exists | ||
|
||
- name: Run tests | ||
block: | ||
- name: Include test tasks | ||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/test.yml" | ||
|
||
always: | ||
- name: Include cleanup tasks | ||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/cleanup.yml" | ||
when: cleanup_file.stat.exists |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
--- | ||
- name: Create test_server | ||
hetzner.hcloud.server: | ||
name: "{{ hcloud_server_name }}" | ||
server_type: cx11 | ||
image: ubuntu-22.04 | ||
labels: | ||
firewall: "{{ hcloud_firewall_name }}" | ||
state: stopped | ||
register: test_server | ||
|
||
- name: Create test_firewall | ||
hetzner.hcloud.firewall: | ||
name: "{{ hcloud_firewall_name }}" | ||
labels: | ||
key: value | ||
rules: | ||
- description: allow icmp from anywhere | ||
direction: in | ||
protocol: icmp | ||
source_ips: | ||
- 0.0.0.0/0 | ||
- ::/0 | ||
state: present | ||
register: test_firewall | ||
|
||
- name: Create test_firewall_resource | ||
hetzner.hcloud.firewall_resource: | ||
firewall: "{{ hcloud_firewall_name }}" | ||
servers: | ||
- "{{ hcloud_server_name }}" | ||
label_selectors: | ||
- firewall={{ hcloud_firewall_name }} | ||
state: present | ||
register: test_firewall_resource |
Oops, something went wrong.