1
0
Fork 0
mirror of https://github.com/ansible-collections/hetzner.hcloud.git synced 2026-02-04 08:01:49 +00:00

do not require server when detaching volume and rename module result property

This commit is contained in:
jo 2025-04-28 12:08:34 +02:00
parent fb439e7b50
commit 9f802d5faf
No known key found for this signature in database
GPG key ID: B2FEC9B22722B984
4 changed files with 139 additions and 154 deletions

View file

@ -55,7 +55,6 @@ EXAMPLES = """
- name: Detach my-volume from my-server
hetzner.hcloud.volume_attachment:
volume: my-volume
server: my-server
state: absent
- name: Attach my-volume using id to my-server with automount enabled
@ -92,25 +91,33 @@ from ..module_utils.vendor.hcloud.servers import BoundServer
from ..module_utils.vendor.hcloud.volumes import BoundVolume
class AnsibleHcloudVolumeAttachment(AnsibleHCloud):
class AnsibleHCloudVolumeAttachment(AnsibleHCloud):
represent = "hcloud_volume_attachment"
hcloud_volume: BoundVolume | None = None
# We must the hcloud_volume_attachment name instead of hcloud_volume, because
# AnsibleHCloud.get_result does funny things.
hcloud_volume_attachment: BoundVolume | None = None
hcloud_server: BoundServer | None = None
def _prepare_result(self):
return {
"volume": self.hcloud_volume.name,
"server": self.hcloud_volume.server.name if self.hcloud_volume.server is not None else None,
"volume": self.hcloud_volume_attachment.name,
"server": (
self.hcloud_volume_attachment.server.name if self.hcloud_volume_attachment.server is not None else None
),
}
def _get_server_and_volume(self):
def _get_volume(self):
try:
self.hcloud_volume = self._client_get_by_name_or_id(
self.hcloud_volume_attachment = self._client_get_by_name_or_id(
"volumes",
self.module.params.get("volume"),
)
except HCloudException as exception:
self.fail_json_hcloud(exception)
def _get_server(self):
try:
self.hcloud_server = self._client_get_by_name_or_id(
"servers",
self.module.params.get("server"),
@ -119,41 +126,46 @@ class AnsibleHcloudVolumeAttachment(AnsibleHCloud):
self.fail_json_hcloud(exception)
def attach_volume(self):
try:
self._get_server_and_volume()
self.module.fail_on_missing_params(required_params=["server"])
if self.hcloud_volume.server is not None:
if self.hcloud_volume.server.id == self.hcloud_server.id:
try:
self._get_volume()
self._get_server()
if self.hcloud_volume_attachment.server is not None:
if self.hcloud_volume_attachment.server.id == self.hcloud_server.id:
return
if not self.module.check_mode:
action = self.hcloud_volume.detach()
action = self.hcloud_volume_attachment.detach()
action.wait_until_finished()
self.hcloud_volume.server = None
self.hcloud_volume_attachment.server = None
self._mark_as_changed()
else:
if not self.module.check_mode:
action = self.hcloud_volume.attach(
server=self.hcloud_server,
automount=self.module.params.get("automount"),
)
action.wait_until_finished()
if not self.module.check_mode:
action = self.hcloud_volume_attachment.attach(
server=self.hcloud_server,
automount=self.module.params.get("automount"),
)
action.wait_until_finished()
self.hcloud_volume.server = self.hcloud_server
self._mark_as_changed()
self.hcloud_volume_attachment.server = self.hcloud_server
self._mark_as_changed()
except HCloudException as exception:
self.fail_json_hcloud(exception)
def detach_volume(self):
try:
self._get_server_and_volume()
if self.hcloud_volume.server is not None:
self._get_volume()
if self.hcloud_volume_attachment.server is not None:
if not self.module.check_mode:
action = self.hcloud_volume.detach()
action = self.hcloud_volume_attachment.detach()
action.wait_until_finished()
self.hcloud_volume_attachment.server = None
self._mark_as_changed()
except HCloudException as exception:
self.fail_json_hcloud(exception)
@ -163,8 +175,8 @@ class AnsibleHcloudVolumeAttachment(AnsibleHCloud):
return AnsibleModule(
argument_spec=dict(
volume={"type": "str", "required": True},
server={"type": "str", "required": True},
automount={"type": "bool", "default": False},
server={"type": "str"},
automount={"type": "bool"},
state={
"choices": ["present", "absent"],
"default": "present",
@ -176,9 +188,9 @@ class AnsibleHcloudVolumeAttachment(AnsibleHCloud):
def main():
module = AnsibleHcloudVolumeAttachment.define_module()
module = AnsibleHCloudVolumeAttachment.define_module()
hcloud = AnsibleHcloudVolumeAttachment(module)
hcloud = AnsibleHCloudVolumeAttachment(module)
state = module.params["state"]
if state == "present":
hcloud.attach_volume()

View file

@ -4,6 +4,12 @@
name: "{{ hcloud_server_name }}"
state: absent
- name: Cleanup test_server2
hetzner.hcloud.server:
name: "{{ hcloud_server_name }}2"
state: absent
register: test_server2
- name: Cleanup test_volume
hetzner.hcloud.volume:
name: "{{ hcloud_volume_name }}"

View file

@ -0,0 +1,25 @@
---
- name: Create test_server
hetzner.hcloud.server:
name: "{{ hcloud_server_name }}"
server_type: "{{ hcloud_server_type_name }}"
image: "{{ hcloud_image_name }}"
location: "{{ hcloud_location_name }}"
state: created
register: test_server
- name: Create test_server2
hetzner.hcloud.server:
name: "{{ hcloud_server_name }}2"
server_type: "{{ hcloud_server_type_name }}"
image: "{{ hcloud_image_name }}"
location: "{{ hcloud_location_name }}"
state: created
register: test_server2
- name: Create test_volume
hetzner.hcloud.volume:
name: "{{ hcloud_volume_name }}"
size: 10
location: "{{ hcloud_location_name }}"
register: test_volume

View file

@ -1,186 +1,128 @@
# Copyright: (c) 2025, Hetzner Cloud GmbH <info@hetzner-cloud.de>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
---
- name: Setup server
hetzner.hcloud.server:
name: "{{ hcloud_server_name }}"
server_type: "{{ hcloud_server_type_name }}"
image: "{{ hcloud_image_name }}"
state: created
location: "{{ hcloud_location_name }}"
register: vol_server
- name: Verify setup server
ansible.builtin.assert:
that:
- vol_server is changed
- name: Setup volume
hetzner.hcloud.volume:
name: "{{ hcloud_volume_name }}"
size: 10
location: "{{ hcloud_location_name }}"
register: vol_volume
- name: Verify setup volume
ansible.builtin.assert:
that:
- vol_volume is changed
- name: Test missing volume name # noqa: args[module]
- name: Test missing required parameters # noqa: args[module]
hetzner.hcloud.volume_attachment:
server: "{{ hcloud_server_name }}"
register: result
ignore_errors: true
- name: Verify fail test volume name or id
- name: Verify missing required parameters
ansible.builtin.assert:
that:
- result is failed
- 'result.msg == "missing required arguments: volume"'
- name: Test missing server name # noqa: args[module]
- name: Test missing required parameters # noqa: args[module]
hetzner.hcloud.volume_attachment:
volume: "{{ hcloud_volume_name }}"
register: result
ignore_errors: true
- name: Verify fail test server name
- name: Verify missing required parameters
ansible.builtin.assert:
that:
- result is failed
- 'result.msg == "missing required arguments: server"'
- name: Test attach Volume with check mode (Volume)
- name: Test attach with check mode
hetzner.hcloud.volume_attachment:
volume: "{{ hcloud_volume_name }}"
server: "{{ hcloud_server_name }}"
register: result
check_mode: true
- name: Verify attach Volume with check mode result (Volume)
- name: Verify attach with check mode
ansible.builtin.assert:
that:
- result is changed
- name: Test attach Volume (Volume)
- name: Test attach volume not found
hetzner.hcloud.volume_attachment:
volume: "{{ hcloud_volume_name }}"
server: "{{ hcloud_server_name }}"
register: volume
- name: Verify test attach Volume (Volume)
ansible.builtin.assert:
that:
- volume is changed
- volume.hcloud_volume_attachment.volume == hcloud_volume_name
- volume.hcloud_volume_attachment.server == hcloud_server_name
- name: Test attach Volume idempotence (Volume)
hetzner.hcloud.volume_attachment:
volume: "{{ hcloud_volume_name }}"
server: "{{ hcloud_server_name }}"
register: volume
- name: Verify test create Volume (Volume)
ansible.builtin.assert:
that:
- volume is not changed
- name: Test detach Volume with checkmode (Volume)
hetzner.hcloud.volume_attachment:
volume: "{{ hcloud_volume_name }}"
server: "{{ hcloud_server_name }}"
state: "absent"
check_mode: true
register: volume
- name: Verify detach Volume with checkmode (Volume)
ansible.builtin.assert:
that:
- volume is changed
- volume.hcloud_volume_attachment.server == hcloud_server_name
- name: Test detach Volume (Volume)
hetzner.hcloud.volume_attachment:
volume: "{{ hcloud_volume_name }}"
server: "{{ hcloud_server_name }}"
state: "absent"
register: volume
- name: Verify detach volume (Volume)
ansible.builtin.assert:
that:
- volume is changed
- volume.hcloud_volume_attachment.server == hcloud_server_name
- name: Test detach Volume idempotency (Volume)
hetzner.hcloud.volume_attachment:
volume: "{{ hcloud_volume_name }}"
server: "{{ hcloud_server_name }}"
state: "absent"
register: volume
- name: Verify detach volume idempotency (Volume)
ansible.builtin.assert:
that:
- volume is not changed
- name: Test attach Volume with check mode (ID)
hetzner.hcloud.volume_attachment:
volume: "{{ vol_volume.hcloud_volume.id }}"
volume: "invalid"
server: "{{ hcloud_server_name }}"
register: result
check_mode: true
- name: Verify attach Volume with check mode result (ID)
ignore_errors: true
- name: Verify attach volume not found
ansible.builtin.assert:
that:
- result is failed
- 'result.msg == "resource (volume) does not exist: invalid"'
- name: Test attach server not found
hetzner.hcloud.volume_attachment:
volume: "{{ hcloud_volume_name }}"
server: "invalid"
register: result
ignore_errors: true
- name: Verify attach server not found
ansible.builtin.assert:
that:
- result is failed
- 'result.msg == "resource (server) does not exist: invalid"'
- name: Test attach
hetzner.hcloud.volume_attachment:
volume: "{{ hcloud_volume_name }}"
server: "{{ hcloud_server_name }}"
register: result
- name: Verify attach
ansible.builtin.assert:
that:
- result is changed
- result.hcloud_volume_attachment.volume == hcloud_volume_name
- result.hcloud_volume_attachment.server == hcloud_server_name
- name: Test attach Volume (ID)
- name: Test attach idempotency
hetzner.hcloud.volume_attachment:
volume: "{{ vol_volume.hcloud_volume.id }}"
volume: "{{ hcloud_volume_name }}"
server: "{{ hcloud_server_name }}"
register: volume
- name: Verify test attach Volume (ID)
register: result
- name: Verify attach idempotency
ansible.builtin.assert:
that:
- volume is changed
- volume.hcloud_volume_attachment.volume == hcloud_volume_name
- volume.hcloud_volume_attachment.server == hcloud_server_name
- result is not changed
- name: Test attach Volume idempotence (ID)
- name: Test attach to another server
hetzner.hcloud.volume_attachment:
volume: "{{ vol_volume.hcloud_volume.id }}"
server: "{{ hcloud_server_name }}"
register: volume
- name: Verify test create Volume (ID)
volume: "{{ hcloud_volume_name }}"
server: "{{ hcloud_server_name }}2"
register: result
- name: Verify attach
ansible.builtin.assert:
that:
- volume is not changed
- result is changed
- result.hcloud_volume_attachment.volume == hcloud_volume_name
- result.hcloud_volume_attachment.server == hcloud_server_name + '2'
- name: Test detach Volume with checkmode (ID)
- name: Test detach with check mode
hetzner.hcloud.volume_attachment:
volume: "{{ vol_volume.hcloud_volume.id }}"
server: "{{ hcloud_server_name }}"
volume: "{{ hcloud_volume_name }}"
state: "absent"
check_mode: true
register: volume
- name: Verify detach Volume with checkmode (ID)
register: result
- name: Verify detach with check mode
ansible.builtin.assert:
that:
- volume is changed
- volume.hcloud_volume_attachment.server == hcloud_server_name
- result is changed
- result.hcloud_volume_attachment.volume == hcloud_volume_name
- result.hcloud_volume_attachment.server is none
- name: Test detach Volume (ID)
- name: Test detach
hetzner.hcloud.volume_attachment:
volume: "{{ vol_volume.hcloud_volume.id }}"
server: "{{ hcloud_server_name }}"
volume: "{{ hcloud_volume_name }}"
state: "absent"
register: volume
- name: Verify detach volume (ID)
register: result
- name: Verify detach
ansible.builtin.assert:
that:
- volume is changed
- volume.hcloud_volume_attachment.server == hcloud_server_name
- result is changed
- result.hcloud_volume_attachment.volume == hcloud_volume_name
- result.hcloud_volume_attachment.server is none
- name: Test detach Volume idempotency (ID)
- name: Test detach idempotency
hetzner.hcloud.volume_attachment:
volume: "{{ vol_volume.hcloud_volume.id }}"
server: "{{ hcloud_server_name }}"
volume: "{{ hcloud_volume_name }}"
state: "absent"
register: volume
- name: Verify detach volume idempotency (ID)
register: result
- name: Verify detach idempotency
ansible.builtin.assert:
that:
- volume is not changed
- result is not changed