hcloud: Add Delete Protection to hcloud_volume and hcloud_volume_info (#63665)

pull/61912/head
Lukas Kämmerling 5 years ago committed by René Moser
parent e9e4b02b92
commit 8eb46acbb1

@ -18,12 +18,12 @@ DOCUMENTATION = """
---
module: hcloud_volume
short_description: Create and manage block volumes on the Hetzner Cloud.
short_description: Create and manage block Volume on the Hetzner Cloud.
version_added: "2.8"
description:
- Create, update and attach/detach block volumes on the Hetzner Cloud.
- Create, update and attach/detach block Volume on the Hetzner Cloud.
author:
- Christopher Schmitt (@cschmitt-hcloud)
@ -64,13 +64,18 @@ options:
- Server Name the Volume should be assigned to.
- Required if no I(location) is given and Volume does not exists.
type: str
delete_protection:
description:
- Protect the Volume for deletion.
type: bool
version_added: "2.10"
labels:
description:
- User-defined key-value pairs.
type: dict
state:
description:
- State of the volume.
- State of the Volume.
default: present
choices: [absent, present]
type: str
@ -78,32 +83,32 @@ extends_documentation_fragment: hcloud
"""
EXAMPLES = """
- name: Create a volume
- name: Create a Volume
hcloud_volume:
name: my-volume
location: fsn1
size: 100
state: present
- name: Create a volume and format it with ext4
- name: Create a Volume and format it with ext4
hcloud_volume:
name: my-volume
location: fsn
format: ext4
size: 100
state: present
- name: Mount a existing volume and automount
- name: Mount a existing Volume and automount
hcloud_volume:
name: my-volume
server: my-server
automount: yes
state: present
- name: Mount a existing volume and automount
- name: Mount a existing Volume and automount
hcloud_volume:
name: my-volume
server: my-server
automount: yes
state: present
- name: Ensure the volume is absent (remove if needed)
- name: Ensure the Volume is absent (remove if needed)
hcloud_volume:
name: my-volume
state: absent
@ -111,33 +116,33 @@ EXAMPLES = """
RETURN = """
hcloud_volume:
description: The block volume
description: The block Volume
returned: Always
type: complex
contains:
id:
description: ID of the volume
description: ID of the Volume
type: int
returned: Always
sample: 12345
name:
description: Name of the volume
description: Name of the Volume
type: str
returned: Always
sample: my-volume
size:
description: Size in GB of the volume
description: Size in GB of the Volume
type: int
returned: Always
sample: 1337
linux_device:
description: Path to the device that contains the volume.
description: Path to the device that contains the Volume.
returned: always
type: str
sample: /dev/disk/by-id/scsi-0HC_Volume_12345
version_added: "2.10"
location:
description: Location name where the volume is located at
description: Location name where the Volume is located at
type: str
returned: Always
sample: "fsn1"
@ -149,10 +154,16 @@ hcloud_volume:
key: value
mylabel: 123
server:
description: Server name where the volume is attached to
description: Server name where the Volume is attached to
type: str
returned: Always
sample: "my-server"
delete_protection:
description: True if Volume is protected for deletion
type: bool
returned: always
sample: false
version_added: "2.10"
"""
from ansible.module_utils.basic import AnsibleModule
@ -185,6 +196,7 @@ class AnsibleHcloudVolume(Hcloud):
"labels": self.hcloud_volume.labels,
"server": to_native(server_name),
"linux_device": to_native(self.hcloud_volume.linux_device),
"delete_protection": self.hcloud_volume.protection["delete"],
}
def _get_volume(self):
@ -227,36 +239,45 @@ class AnsibleHcloudVolume(Hcloud):
self._get_volume()
def _update_volume(self):
size = self.module.params.get("size")
if size:
if self.hcloud_volume.size < size:
if not self.module.check_mode:
self.hcloud_volume.resize(size).wait_until_finished()
self._mark_as_changed()
elif self.hcloud_volume.size > size:
self.module.warn("Shrinking of volumes is not supported")
try:
size = self.module.params.get("size")
if size:
if self.hcloud_volume.size < size:
if not self.module.check_mode:
self.hcloud_volume.resize(size).wait_until_finished()
self._mark_as_changed()
elif self.hcloud_volume.size > size:
self.module.warn("Shrinking of volumes is not supported")
server_name = self.module.params.get("server")
if server_name:
server = self.client.servers.get_by_name(server_name)
if self.hcloud_volume.server is None or self.hcloud_volume.server.name != server.name:
if not self.module.check_mode:
automount = self.module.params.get("automount", False)
self.hcloud_volume.attach(server, automount=automount).wait_until_finished()
self._mark_as_changed()
else:
if self.hcloud_volume.server is not None:
if not self.module.check_mode:
self.hcloud_volume.detach().wait_until_finished()
self._mark_as_changed()
server_name = self.module.params.get("server")
if server_name:
server = self.client.servers.get_by_name(server_name)
if self.hcloud_volume.server is None or self.hcloud_volume.server.name != server.name:
labels = self.module.params.get("labels")
if labels is not None and labels != self.hcloud_volume.labels:
if not self.module.check_mode:
automount = self.module.params.get("automount", False)
self.hcloud_volume.attach(server, automount=automount).wait_until_finished()
self.hcloud_volume.update(labels=labels)
self._mark_as_changed()
else:
if self.hcloud_volume.server is not None:
delete_protection = self.module.params.get("delete_protection")
if delete_protection is not None and delete_protection != self.hcloud_volume.protection["delete"]:
if not self.module.check_mode:
self.hcloud_volume.detach().wait_until_finished()
self.hcloud_volume.change_protection(delete=delete_protection).wait_until_finished()
self._mark_as_changed()
labels = self.module.params.get("labels")
if labels is not None and labels != self.hcloud_volume.labels:
if not self.module.check_mode:
self.hcloud_volume.update(labels=labels)
self._mark_as_changed()
self._get_volume()
self._get_volume()
except hcloud.APIException as e:
self.module.fail_json(msg=e.message)
def present_volume(self):
self._get_volume()
@ -266,12 +287,15 @@ class AnsibleHcloudVolume(Hcloud):
self._update_volume()
def delete_volume(self):
self._get_volume()
if self.hcloud_volume is not None:
if not self.module.check_mode:
self.client.volumes.delete(self.hcloud_volume)
self._mark_as_changed()
self.hcloud_volume = None
try:
self._get_volume()
if self.hcloud_volume is not None:
if not self.module.check_mode:
self.client.volumes.delete(self.hcloud_volume)
self._mark_as_changed()
self.hcloud_volume = None
except hcloud.APIException as e:
self.module.fail_json(msg=e.message)
@staticmethod
def define_module():
@ -287,6 +311,7 @@ class AnsibleHcloudVolume(Hcloud):
format={"type": "str",
"choices": ['xfs', 'ext4'],
},
delete_protection={"type": "bool"},
state={
"choices": ["absent", "present"],
"default": "present",

@ -18,11 +18,11 @@ DOCUMENTATION = """
---
module: hcloud_volume_info
short_description: Gather infos about your Hetzner Cloud volumes.
short_description: Gather infos about your Hetzner Cloud Volumes.
version_added: "2.8"
description:
- Gather infos about your Hetzner Cloud volumes.
- Gather infos about your Hetzner Cloud Volumes.
author:
- Lukas Kaemmerling (@LKaemmerling)
@ -30,21 +30,21 @@ author:
options:
id:
description:
- The ID of the volume you want to get.
- The ID of the Volume you want to get.
type: int
name:
description:
- The name of the volume you want to get.
- The name of the Volume you want to get.
type: str
label_selector:
description:
- The label selector for the volume you want to get.
- The label selector for the Volume you want to get.
type: str
extends_documentation_fragment: hcloud
"""
EXAMPLES = """
- name: Gather hcloud volume infos
- name: Gather hcloud Volume infos
hcloud_volume_info:
register: output
- name: Print the gathered infos
@ -54,41 +54,46 @@ EXAMPLES = """
RETURN = """
hcloud_volume_info:
description: The volume infos as list
description: The Volume infos as list
returned: always
type: complex
contains:
id:
description: Numeric identifier of the volume
description: Numeric identifier of the Volume
returned: always
type: int
sample: 1937415
name:
description: Name of the volume
description: Name of the Volume
returned: always
type: str
sample: my-volume
size:
description: Size of the volume
description: Size of the Volume
returned: always
type: str
sample: 10
linux_device:
description: Path to the device that contains the volume.
description: Path to the device that contains the Volume.
returned: always
type: str
sample: /dev/disk/by-id/scsi-0HC_Volume_12345
version_added: "2.10"
location:
description: Name of the location where the volume resides in
description: Name of the location where the Volume resides in
returned: always
type: str
sample: fsn1
server:
description: Name of the server where the volume is attached to
description: Name of the server where the Volume is attached to
returned: always
type: str
sample: my-server
delete_protection:
description: True if the Volume is protected for deletion
returned: always
type: bool
version_added: "2.10"
labels:
description: User-defined labels (key-value pairs)
returned: always
@ -126,6 +131,7 @@ class AnsibleHcloudVolumeInfo(Hcloud):
"labels": volume.labels,
"server": to_native(server_name),
"linux_device": to_native(volume.linux_device),
"delete_protection": volume.protection["delete"],
})
return tmp

@ -26,25 +26,25 @@
- result is failed
- 'result.msg == "missing required arguments: size"'
- name: test create volume with check mode
- name: test create Volume with check mode
hcloud_volume:
name: "{{hcloud_volume_name}}"
size: 10
location: "fsn1"
register: result
check_mode: yes
- name: verify create volume with check mode result
- name: verify create Volume with check mode result
assert:
that:
- result is changed
- name: test create volume
- name: test create Volume
hcloud_volume:
name: "{{hcloud_volume_name}}"
size: 10
location: "fsn1"
register: volume
- name: verify test create volume
- name: verify test create Volume
assert:
that:
- volume is changed
@ -54,30 +54,30 @@
- volume.hcloud_volume.server != "{{hcloud_server_name}}"
- volume.hcloud_volume.linux_device is defined
- name: test create volume idempotence
- name: test create Volume idempotence
hcloud_volume:
name: "{{hcloud_volume_name}}"
size: 10
location: "fsn1"
register: volume
- name: verify test create volume
- name: verify test create Volume
assert:
that:
- volume is not changed
- name: test attach volume with checkmode
- name: test attach Volume with checkmode
hcloud_volume:
name: "{{hcloud_volume_name}}"
server: "{{hcloud_server_name}}"
check_mode: yes
register: volume
- name: verify test attach volume with checkmode
- name: verify test attach Volume with checkmode
assert:
that:
- volume is changed
- volume.hcloud_volume.server != "{{hcloud_server_name}}"
- name: test attach volume
- name: test attach Volume
hcloud_volume:
name: "{{hcloud_volume_name}}"
server: "{{hcloud_server_name}}"
@ -88,29 +88,29 @@
- volume is changed
- volume.hcloud_volume.server == "{{hcloud_server_name}}"
- name: test attach volume idempotence
- name: test attach Volume idempotence
hcloud_volume:
name: "{{hcloud_volume_name}}"
server: "{{hcloud_server_name}}"
register: volume
- name: verify attach volume idempotence
- name: verify attach Volume idempotence
assert:
that:
- volume is not changed
- volume.hcloud_volume.server == "{{hcloud_server_name}}"
- name: test detach volume with checkmode
- name: test detach Volume with checkmode
hcloud_volume:
name: "{{hcloud_volume_name}}"
check_mode: yes
register: volume
- name: verify detach volume with checkmode
- name: verify detach Volume with checkmode
assert:
that:
- volume is changed
- volume.hcloud_volume.server == "{{hcloud_server_name}}"
- name: test detach volume
- name: test detach Volume
hcloud_volume:
name: "{{hcloud_volume_name}}"
register: volume
@ -121,57 +121,112 @@
- volume.hcloud_volume.location == "fsn1"
- volume.hcloud_volume.server != "{{hcloud_server_name}}"
- name: test update volume label
- name: test update Volume label
hcloud_volume:
name: "{{hcloud_volume_name}}"
labels:
key: value
register: volume
- name: verify test update volume lable
- name: verify test update Volume label
assert:
that:
- volume is changed
- volume.hcloud_volume.labels.key == "value"
- name: test update volume label with the same label
- name: test update Volume label with the same label
hcloud_volume:
name: "{{hcloud_volume_name}}"
labels:
key: value
register: volume
- name: verify test update volume lable with the same label
- name: verify test update Volume lable with the same label
assert:
that:
- volume is not changed
- name: test increase volume size
- name: test increase Volume size
hcloud_volume:
name: "{{hcloud_volume_name}}"
size: 11
register: volume
- name: verify test increase volume size
- name: verify test increase Volume size
assert:
that:
- volume is changed
- volume.hcloud_volume.size == 11
- name: test decreace volume size
- name: test decreace Volume size
hcloud_volume:
name: "{{hcloud_volume_name}}"
size: 10
register: volume
- name: verify test decreace volume size
- name: verify test decreace Volume size
assert:
that:
- volume is not changed
- volume.hcloud_volume.size == 11
- name: test delete volume
- name: test update Volume delete protection
hcloud_volume:
name: "{{hcloud_volume_name}}"
delete_protection: true
register: volume
- name: verify test update Volume delete protection
assert:
that:
- volume is changed
- volume.hcloud_volume.delete_protection is sameas true
- name: test update Volume delete protection idempotency
hcloud_volume:
name: "{{hcloud_volume_name}}"
delete_protection: true
register: volume
- name: verify test update Volume delete protection idempotency
assert:
that:
- volume is not changed
- volume.hcloud_volume.delete_protection is sameas true
- name: test Volume without delete protection set to be idempotent
hcloud_volume:
name: "{{hcloud_volume_name}}"
register: volume
- name: verify test Volume without delete protection set to be idempotent
assert:
that:
- volume is not changed
- volume.hcloud_volume.delete_protection is sameas true
- name: test delete Volume fails if it is protected
hcloud_volume:
name: "{{hcloud_volume_name}}"
state: absent
ignore_errors: yes
register: result
- name: verify delete Volume fails if it is protected
assert:
that:
- result is failed
- 'result.msg == "volume deletion is protected"'
- name: test update Volume delete protection
hcloud_volume:
name: "{{hcloud_volume_name}}"
delete_protection: false
register: volume
- name: verify test update Volume delete protection
assert:
that:
- volume is changed
- volume.hcloud_volume.delete_protection is sameas false
- name: test delete Volume
hcloud_volume:
name: "{{hcloud_volume_name}}"
state: absent
register: result
- name: verify delete volume
- name: verify delete Volume
assert:
that:
- result is success

Loading…
Cancel
Save