
    Vh=                        d dl mZ dZdZdZd dlZd dlmZ ddlm	Z	 dd	l
mZmZ dd
lmZmZmZ  G d de	      Zd Zedk(  r e        yy)    )annotationsa
  
---
module: firewall
short_description: Create and manage firewalls on the Hetzner Cloud.

description:
    - Create, update and manage firewalls on the Hetzner Cloud.

author:
    - Lukas Kaemmerling (@lkaemmerling)

options:
    id:
        description:
            - The ID of the Hetzner Cloud Firewall to manage.
            - Only required if no firewall O(name) is given.
        type: int
    name:
        description:
            - The Name of the Hetzner Cloud Firewall to manage.
            - Only required if no firewall O(id) is given, or the firewall does not exist.
        type: str
    labels:
        description:
            - User-defined labels (key-value pairs).
        type: dict
    rules:
        description:
            - List of rules the firewall contain.
        type: list
        elements: dict
        suboptions:
            description:
                description:
                    - User defined description of this rule.
                type: str
            direction:
                description:
                    - The direction of the firewall rule.
                type: str
                choices: [in, out]
            protocol:
                description:
                    - The protocol of the firewall rule.
                type: str
                choices: [icmp, tcp, udp, esp, gre]
            port:
                description:
                    - The port or port range allowed by this rule.
                    - A port range can be specified by separating two ports with a dash, e.g 1024-5000.
                    - Only used if O(rules[].protocol=tcp) or O(rules[].protocol=udp).
                type: str
            source_ips:
                description:
                    - List of CIDRs that are allowed within this rule.
                    - Use 0.0.0.0/0 to allow all IPv4 addresses and ::/0 to allow all IPv6 addresses.
                    - Only used if O(rules[].direction=in).
                type: list
                elements: str
                default: []
            destination_ips:
                description:
                    - List of CIDRs that are allowed within this rule.
                    - Use 0.0.0.0/0 to allow all IPv4 addresses and ::/0 to allow all IPv6 addresses.
                    - Only used if O(rules[].direction=out).
                type: list
                elements: str
                default: []
    force:
        description:
            - Force the deletion of the Firewall when still in use.
        type: bool
        default: false
    state:
        description:
            - State of the firewall.
        default: present
        choices: [absent, present]
        type: str

extends_documentation_fragment:
    - hetzner.hcloud.hcloud
a  
- name: Create a basic firewall
  hetzner.hcloud.firewall:
    name: my-firewall
    state: present

- name: Create a firewall with rules
  hetzner.hcloud.firewall:
    name: my-firewall
    rules:
      - description: allow icmp from everywhere
        direction: in
        protocol: icmp
        source_ips:
          - 0.0.0.0/0
          - ::/0
    state: present

- name: Create a firewall with labels
  hetzner.hcloud.firewall:
    name: my-firewall
    labels:
      key: value
      mylabel: 123
    state: present

- name: Ensure the firewall is absent (remove if needed)
  hetzner.hcloud.firewall:
    name: my-firewall
    state: absent
a  
hcloud_firewall:
    description: The firewall instance.
    returned: always
    type: 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.rules[].protocol=tcp) or RV(hcloud_firewall.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.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
N)AnsibleModule   )AnsibleHCloud)APIExceptionHCloudException)BoundFirewallFirewallResourceFirewallRulec                  p     e Zd ZU dZdZded<   d ZddZddZd Z	d Z
d	 Zd
 Zd Ze fd       Z xZS )AnsibleHCloudFirewallhcloud_firewallNzBoundFirewall | Nonec           
     t   t        | j                  j                        | j                  j                  | j                  j                  D cg c]  }| j                  |       c}| j                  j                  | j                  j                  D cg c]  }| j                  |       c}dS c c}w c c}w )N)idnameruleslabels
applied_to)	strr   r   r   r   _prepare_result_ruler   r   _prepare_result_applied_to)selfruleresources      k/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/hetzner/hcloud/plugins/modules/firewall.py_prepare_resultz%AnsibleHCloudFirewall._prepare_result   s    d**--.((--BFBVBVB\B\]$d//5]**11UYUiUiUtUtu4::8Du
 	
 ^us   B0B5c                    |j                   |j                  |j                  |j                  |j                  |j
                  dS )N	directionprotocolport
source_ipsdestination_ipsdescriptionr   )r   r   s     r   r   z*AnsibleHCloudFirewall._prepare_result_rule   s:    II//#33++
 	
    c                   |j                   |j                  t        |j                  j                        nd |j                  |j                  j
                  nd d}|j                  U|j                  D cg c]<  }|j                   |j                  t        |j                  j                        nd d> c}|d<   |S c c}w )N)typeserverlabel_selector)r'   r(   applied_to_resources)r'   r(   r   r   r)   selectorr*   )r   r   resultitems       r   r   z0AnsibleHCloudFirewall._prepare_result_applied_to   s    MM191Lc(//,,-RVBJBYBYBeh55>>ko

 ((4 %99.
  !II59[[5Lc$++..1RV.F)* .s   8ACc                    	 | j                   j                  j                  d      N| j                  j                  j                  | j                   j                  j                  d            | _        y | j                   j                  j                  d      N| j                  j                  j                  | j                   j                  j                  d            | _        y y # t        $ r}| j                  |       Y d }~y d }~ww xY w)Nr   r   )
moduleparamsgetclient	firewalls	get_by_idr   get_by_namer   fail_json_hcloud)r   	exceptions     r   _get_firewallz#AnsibleHCloudFirewall._get_firewall  s    	-{{!!%%d+7'+{{'<'<'F'Ft{{GYGYG]G]^bGc'd$##''/;'+{{'<'<'H'HI[I[I_I_`fIg'h$ <  	-!!),,	-s   A2C) 5A2C) )	D2DDc                   | j                   j                  dg       | j                   j                  j                  d      | j                   j                  j                  d      d}| j                   j                  j                  d      }|B|D cg c]3  }t	        |d   |d   |d   |d   ng |d	   |d	   ng |d
   |d         5 c}|d<   | j                   j
                  s'	  | j                  j                  j                  di | | j                          | j                          y c c}w # t        $ r}| j                  ||       Y d }~Gd }~ww xY w)Nr   required_paramsr   )r   r   r   r   r    r"   r#   r!   r$   r   r    r"   r#   r!   r$   )r0    )r/   fail_on_missing_paramsr0   r1   r   
check_moder2   r3   creater   r6   _mark_as_changedr8   )r   r0   r   r   r7   s        r   _create_firewallz&AnsibleHCloudFirewall._create_firewall  s]   **F8*DKK&&**62kk((,,X6
 ""&&w/ "
  ";/!*-59,5G5StL1Y[?CDU?V?bD):$;hjf $] 3
F7O {{%%@,%%,,6v6 	'
 # @%%i%??@s   8D0)&D5 5	E>EEc                2   | j                   j                  j                  d      }|x| j                  j                  |k7  r_| j                   j                  dg       | j                   j                  s| j                  j                  |       | j                          | j                   j                  j                  d      }|[| j                  j                  |k7  rB| j                   j                  s| j                  j                  |       | j                          | j                   j                  j                  d      }||| j                  j                  D cg c]  }| j                  |       c}k7  r| j                   j                  sY|D cg c]3  }t        |d   |d	   |d
   |d
   ng |d   |d   ng |d   |d         5 }}| j                  j                  |       | j                          | j                          y c c}w c c}w )Nr   r   r:   )r   r   )r   r   r   r    r"   r#   r!   r$   r<   )r/   r0   r1   r   r   r>   r?   updaterA   r   r   r   r   	set_rulesr8   )r   r   r   r   r   	new_ruless         r   _update_firewallz&AnsibleHCloudFirewall._update_firewall7  s   {{!!%%f- 4 4 9 9T AKK..v.F;;))$$+++6!!###''1$"6"6"="="G;;))$$++6+:!!#""&&w/W[WkWkWqWq*rt4+D+DT+J*r!r;;)) !&
  !"&{"3!%j!19=l9K9W4#5]_CGHYCZCf->(?ln!&\$($7
	 
 $$..y9!!#! +s
s   "H8Hc                ~    | j                          | j                  | j                          y | j                          y )N)r8   r   rB   rG   )r   s    r   present_firewallz&AnsibleHCloudFirewall.present_firewallX  s2    '!!#!!#r%   c                <   | j                          | j                  | j                  j                  s| j                  j                  r| j                  j
                  j                  d      rG| j                  j                  | j                  j                        }|D ]  }|j                           n3| j                  j                  d| j                  j                   d       d}	 	 | j                  j                          	 | j%                          d | _        y # t        $ rP}d|j                  v r'|dk  r"|dz  }t        j                  d|z         Y d }~s| j!                  |       Y d }~n*d }~wt"        $ r}| j!                  |       Y d }~nd }~ww xY w)	Nforcez	Firewall zy is currently used by other resources. You need to unassign the resources before deleting the Firewall or use force=true.r   zis still in use
      g      ?)r8   r   r/   r?   r   r0   r1   remove_from_resourceswait_until_finishedwarnr   deleter   messagetimesleepr6   r   rA   )r   actionsactionretry_countr7   s        r   delete_firewallz%AnsibleHCloudFirewall.delete_firewall_  sp   +;;))''22{{))--g6"&"6"6"L"LTMaMaMlMl"m&- 9F"6689 (('(<(<(A(A'B CG G  
9,,335 !!## ( 9,	0A0AAkTVFV'1,K JJs['89$--i88* 9--i889 s*   ,D 	F(0E3E33F?FFc                   t        t        dddiddiddit        ddt        ddidddgddg d	dddiddg d
ddg d
      ddggdddggdddggg      dddddgdddt        |          ddggdddgggd      S )Nr'   intr   dictlistinout)r'   choices)icmpudptcpespgre)r'   elementsdefault)r$   r   r    r!   r"   r#   r   r    ra   r!   rb   )r'   re   optionsrequired_togetherrequired_ifboolF)r'   rf   absentpresent)r_   rf   )r   r   r   r   rK   stater   r   rm   T)argument_specrequired_one_ofri   supports_check_moder=   )r   r[   superbase_module_arguments)cls	__class__s    r   define_modulez#AnsibleHCloudFirewall.define_module  s     E?e_'# %+UO+0dE]"K*/<`!a$e_,2RT#U17UWY(Z )4Z'@&A#UVH5#UVH5!"  &%8 ()4(-4 '/158 #F^,!9vh78 $? 
  	
r%   )r   r   )r   r
   )__name__
__module____qualname__	representr   __annotations__r   r   r   r8   rB   rG   rI   rX   classmethodru   __classcell__)rt   s   @r   r   r      sQ    !I,0O)0

 -:B$$B !
 !
r%   r   c                    t         j                         } t        |       }| j                  j                  d      }|dk(  r|j	                          n|dk(  r|j                           | j                  di |j                          y )Nrm   rk   rl   r=   )r   ru   r0   r1   rX   rI   	exit_json
get_result)r/   hcloudrm   s      r   mainr     sr    "002F"6*FMMg&E 	)	!F+v((*+r%   __main__)
__future__r   DOCUMENTATIONEXAMPLESRETURNrS   ansible.module_utils.basicr   module_utils.hcloudr   module_utils.vendor.hcloudr   r   $module_utils.vendor.hcloud.firewallsr	   r
   r   r   r   rv   r=   r%   r   <module>r      sd    #Rh@\
|  4 / F z
M z
z
, zF r%   