From f1c6a3331f16769df0be16a9891c0bd3766d2a17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20K=C3=A4mmerling?= <4281581+LKaemmerling@users.noreply.github.com> Date: Fri, 18 Oct 2019 10:54:01 +0200 Subject: [PATCH] hcloud: Add delete_protection to hcloud_network and hcloud_network_info (#63656) --- .../modules/cloud/hcloud/hcloud_network.py | 55 ++++++++++++----- .../cloud/hcloud/hcloud_network_info.py | 8 ++- .../targets/hcloud_network/tasks/main.yml | 59 +++++++++++++++++++ .../hcloud_network_info/tasks/main.yml | 2 +- 4 files changed, 106 insertions(+), 18 deletions(-) diff --git a/lib/ansible/modules/cloud/hcloud/hcloud_network.py b/lib/ansible/modules/cloud/hcloud/hcloud_network.py index 239ee75dba..4597af434c 100644 --- a/lib/ansible/modules/cloud/hcloud/hcloud_network.py +++ b/lib/ansible/modules/cloud/hcloud/hcloud_network.py @@ -49,6 +49,11 @@ options: description: - User-defined labels (key-value pairs). type: dict + delete_protection: + description: + - Protect the Network for deletion. + type: bool + version_added: "2.10" state: description: - State of the Network. @@ -96,6 +101,12 @@ hcloud_network: type: str returned: always sample: 10.0.0.0/8 + delete_protection: + description: True if Network is protected for deletion + type: bool + returned: always + sample: false + version_added: "2.10" labels: description: User-defined labels (key-value pairs) type: dict @@ -125,6 +136,7 @@ class AnsibleHcloudNetwork(Hcloud): "id": to_native(self.hcloud_network.id), "name": to_native(self.hcloud_network.name), "ip_range": to_native(self.hcloud_network.ip_range), + "delete_protection": self.hcloud_network.protection["delete"], "labels": self.hcloud_network.labels, } @@ -159,19 +171,26 @@ class AnsibleHcloudNetwork(Hcloud): self._get_network() def _update_network(self): + try: + labels = self.module.params.get("labels") + if labels is not None and labels != self.hcloud_network.labels: + if not self.module.check_mode: + self.hcloud_network.update(labels=labels) + self._mark_as_changed() - labels = self.module.params.get("labels") - if labels is not None and labels != self.hcloud_network.labels: - if not self.module.check_mode: - self.hcloud_network.update(labels=labels) - self._mark_as_changed() - - ip_range = self.module.params.get("ip_range") - if ip_range is not None and ip_range != self.hcloud_network.ip_range: - if not self.module.check_mode: - self.hcloud_network.change_ip_range(ip_range=ip_range).wait_until_finished() - self._mark_as_changed() + ip_range = self.module.params.get("ip_range") + if ip_range is not None and ip_range != self.hcloud_network.ip_range: + if not self.module.check_mode: + self.hcloud_network.change_ip_range(ip_range=ip_range).wait_until_finished() + self._mark_as_changed() + delete_protection = self.module.params.get("delete_protection") + if delete_protection is not None and delete_protection != self.hcloud_network.protection["delete"]: + if not self.module.check_mode: + self.hcloud_network.change_protection(delete=delete_protection).wait_until_finished() + self._mark_as_changed() + except APIException as e: + self.module.fail_json(msg=e.message) self._get_network() def present_network(self): @@ -182,11 +201,14 @@ class AnsibleHcloudNetwork(Hcloud): self._update_network() def delete_network(self): - self._get_network() - if self.hcloud_network is not None: - if not self.module.check_mode: - self.client.networks.delete(self.hcloud_network) - self._mark_as_changed() + try: + self._get_network() + if self.hcloud_network is not None: + if not self.module.check_mode: + self.client.networks.delete(self.hcloud_network) + self._mark_as_changed() + except APIException as e: + self.module.fail_json(msg=e.message) self.hcloud_network = None @staticmethod @@ -197,6 +219,7 @@ class AnsibleHcloudNetwork(Hcloud): name={"type": "str"}, ip_range={"type": "str"}, labels={"type": "dict"}, + delete_protection={"type": "bool"}, state={ "choices": ["absent", "present"], "default": "present", diff --git a/lib/ansible/modules/cloud/hcloud/hcloud_network_info.py b/lib/ansible/modules/cloud/hcloud/hcloud_network_info.py index fc1a3862d9..dae960ef92 100644 --- a/lib/ansible/modules/cloud/hcloud/hcloud_network_info.py +++ b/lib/ansible/modules/cloud/hcloud/hcloud_network_info.py @@ -69,7 +69,7 @@ hcloud_network_info: description: Name of the network returned: always type: str - sample: awsome-network + sample: awesome-network ip_range: description: IP range of the network returned: always @@ -87,6 +87,11 @@ hcloud_network_info: description: Servers attached to the network returned: always type: complex + delete_protection: + description: True if the network is protected for deletion + returned: always + type: bool + version_added: "2.10" labels: description: Labels of the network returned: always @@ -156,6 +161,7 @@ class AnsibleHcloudNetworkInfo(Hcloud): "routes": routes, "servers": servers, "labels": network.labels, + "delete_protection": network.protection["delete"], }) return tmp diff --git a/test/integration/targets/hcloud_network/tasks/main.yml b/test/integration/targets/hcloud_network/tasks/main.yml index 726f9055af..32bd579fad 100644 --- a/test/integration/targets/hcloud_network/tasks/main.yml +++ b/test/integration/targets/hcloud_network/tasks/main.yml @@ -99,6 +99,65 @@ that: - network is not changed +- name: test update Network delete protection + hcloud_network: + name: "{{hcloud_network_name}}" + ip_range: "10.0.0.0/8" + delete_protection: true + register: network +- name: verify test update Network delete protection + assert: + that: + - network is changed + - network.hcloud_network.delete_protection is sameas true + +- name: test update Network delete protection idempotency + hcloud_network: + name: "{{hcloud_network_name}}" + ip_range: "10.0.0.0/8" + delete_protection: true + register: network +- name: verify test update Network delete protection idempotency + assert: + that: + - network is not changed + - network.hcloud_network.delete_protection is sameas true + +- name: test Network without delete protection set to be idempotent + hcloud_network: + name: "{{hcloud_network_name}}" + ip_range: "10.0.0.0/8" + register: network +- name: verify test Network without delete protection set to be idempotent + assert: + that: + - network is not changed + - network.hcloud_network.delete_protection is sameas true + +- name: test delete Network fails if it is protected + hcloud_network: + name: "{{hcloud_network_name}}" + state: absent + ignore_errors: yes + register: result +- name: verify delete Network + assert: + that: + - result is failed + - 'result.msg == "network deletion is protected"' + +- name: test update Network delete protection + hcloud_network: + name: "{{hcloud_network_name}}" + ip_range: "10.0.0.0/8" + delete_protection: false + register: network +- name: verify test update Network delete protection + assert: + that: + - network is changed + - network.hcloud_network.delete_protection is sameas false + - name: test delete Network hcloud_network: name: "{{hcloud_network_name}}" diff --git a/test/integration/targets/hcloud_network_info/tasks/main.yml b/test/integration/targets/hcloud_network_info/tasks/main.yml index 3bd7508d10..e7924a8d0d 100644 --- a/test/integration/targets/hcloud_network_info/tasks/main.yml +++ b/test/integration/targets/hcloud_network_info/tasks/main.yml @@ -62,7 +62,7 @@ - name: verify test gather hcloud network with correct label selector assert: that: - - hcloud_network.hcloud_network_info | selectattr('name','equalto','{{ hcloud_network_name }}') | list | count == 1 + - hcloud_network.hcloud_network_info | selectattr('name','equalto','{{ hcloud_network_name }}') | list | count >= 1 - name: test gather hcloud network info with wrong label selector hcloud_network_info: