feat: allow forcing the deletion of firewalls that are still in use (#447)

##### SUMMARY

  - Do not silence 'firewall still in use' deletions errors.
  - Allow forcing the deletion of a firewall that is still in use.

Fixes #380

##### ISSUE TYPE

- Feature Pull Request


##### COMPONENT NAME

firewall
This commit is contained in:
Jonas L 2024-02-02 09:48:56 +01:00 committed by GitHub
parent 2757fe745f
commit 559d31561a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 62 additions and 7 deletions

View file

@ -0,0 +1,3 @@
minor_changes:
- firewall - Do not silence 'firewall still in use' delete failures.
- firewall - Allow forcing the deletion of firewalls that are still in use.

View file

@ -74,6 +74,11 @@ options:
type: list type: list
elements: str elements: str
default: [] default: []
force:
description:
- Force the deletion of the Firewall when still in use.
type: bool
default: false
state: state:
description: description:
- State of the firewall. - State of the firewall.
@ -350,19 +355,32 @@ class AnsibleHCloudFirewall(AnsibleHCloud):
self._get_firewall() self._get_firewall()
if self.hcloud_firewall is not None: if self.hcloud_firewall is not None:
if not self.module.check_mode: if not self.module.check_mode:
if self.hcloud_firewall.applied_to:
if self.module.params.get("force"):
actions = self.hcloud_firewall.remove_from_resources(self.hcloud_firewall.applied_to)
for action in actions:
action.wait_until_finished()
else:
self.module.warn(
f"Firewall {self.hcloud_firewall.name} is currently used by "
"other resources. You need to unassign the resources before "
"deleting the Firewall or use force=true."
)
retry_count = 0 retry_count = 0
while retry_count < 10: while True:
try: try:
self.client.firewalls.delete(self.hcloud_firewall) self.hcloud_firewall.delete()
break break
except APIException as exception: except APIException as exception:
if "is still in use" in exception.message: if "is still in use" in exception.message and retry_count < 10:
retry_count = retry_count + 1 retry_count += 1
time.sleep(0.5 * retry_count) time.sleep(0.5 * retry_count)
else: continue
self.fail_json_hcloud(exception) self.fail_json_hcloud(exception)
except HCloudException as exception: except HCloudException as exception:
self.fail_json_hcloud(exception) self.fail_json_hcloud(exception)
self._mark_as_changed() self._mark_as_changed()
self.hcloud_firewall = None self.hcloud_firewall = None
@ -390,6 +408,7 @@ class AnsibleHCloudFirewall(AnsibleHCloud):
["protocol", "tcp", ["port"]], ["protocol", "tcp", ["port"]],
], ],
), ),
force={"type": "bool", "default": False},
state={ state={
"choices": ["absent", "present"], "choices": ["absent", "present"],
"default": "present", "default": "present",

View file

@ -2,3 +2,4 @@
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
--- ---
hcloud_firewall_name: "{{ hcloud_ns }}" hcloud_firewall_name: "{{ hcloud_ns }}"
hcloud_server_name: "{{ hcloud_ns }}"

View file

@ -1,4 +1,9 @@
--- ---
- name: Cleanup test_server
hetzner.hcloud.server:
name: "{{ hcloud_server_name }}"
state: absent
- name: Cleanup test_firewall - name: Cleanup test_firewall
hetzner.hcloud.firewall: hetzner.hcloud.firewall:
name: "{{ hcloud_firewall_name }}" name: "{{ hcloud_firewall_name }}"

View file

@ -0,0 +1,8 @@
---
- name: Create test_server
hetzner.hcloud.server:
name: "{{ hcloud_server_name }}"
server_type: cx11
image: ubuntu-22.04
state: stopped
register: test_server

View file

@ -69,6 +69,12 @@
that: that:
- result is not changed - result is not changed
- name: Assign firewall to test_server
hetzner.hcloud.firewall_resource:
firewall: "{{ hcloud_firewall_name }}"
servers: ["{{ test_server.hcloud_server.name }}"]
state: present
- name: Test update - name: Test update
hetzner.hcloud.firewall: hetzner.hcloud.firewall:
name: "{{ hcloud_firewall_name }}" name: "{{ hcloud_firewall_name }}"
@ -150,7 +156,7 @@
ansible.builtin.assert: ansible.builtin.assert:
that: that:
- result is changed - result is changed
- result.hcloud_firewall.name == "changed-{{ hcloud_firewall_name }}" - result.hcloud_firewall.name == "changed-" + hcloud_firewall_name
- name: Test update name and labels - name: Test update name and labels
hetzner.hcloud.firewall: hetzner.hcloud.firewall:
@ -171,8 +177,21 @@
hetzner.hcloud.firewall: hetzner.hcloud.firewall:
name: "{{ hcloud_firewall_name }}" name: "{{ hcloud_firewall_name }}"
state: absent state: absent
ignore_errors: true
register: result register: result
- name: Verify delete - name: Verify delete
ansible.builtin.assert:
that:
- result is failed
- '"is still in use" in result.msg'
- name: Test delete with force
hetzner.hcloud.firewall:
name: "{{ hcloud_firewall_name }}"
force: true
state: absent
register: result
- name: Verify delete with force
ansible.builtin.assert: ansible.builtin.assert:
that: that:
- result is changed - result is changed