#!/usr/bin/python # Copyright: (c) 2019, Hetzner Cloud GmbH # 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 Firewalls 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": to_native(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": to_native(resource.type), "server": to_native(resource.server.id) if resource.server is not None else None, "label_selector": ( to_native(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": to_native(item.type), "server": to_native(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()