summaryrefslogtreecommitdiffstats
path: root/ansible_collections/hetzner/hcloud/plugins
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-05 16:18:34 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-05 16:18:34 +0000
commit3667197efb7b18ec842efd504785965911f8ac4b (patch)
tree0b986a4bc6879d080b100666a97cdabbc9ca1f28 /ansible_collections/hetzner/hcloud/plugins
parentAdding upstream version 9.5.1+dfsg. (diff)
downloadansible-3667197efb7b18ec842efd504785965911f8ac4b.tar.xz
ansible-3667197efb7b18ec842efd504785965911f8ac4b.zip
Adding upstream version 10.0.0+dfsg.upstream/10.0.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ansible_collections/hetzner/hcloud/plugins')
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/inventory/hcloud.py145
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/module_utils/hcloud.py27
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/_version.py2
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/core/domain.py18
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/firewalls/domain.py4
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/floating_ips/domain.py4
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/images/client.py22
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/load_balancers/domain.py12
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/networks/domain.py4
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/placement_groups/domain.py4
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/primary_ips/domain.py4
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/servers/domain.py4
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/module_utils/version.py2
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/certificate.py21
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/certificate_info.py33
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/datacenter_info.py9
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/firewall.py29
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/firewall_info.py29
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/firewall_resource.py7
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/floating_ip.py25
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/floating_ip_info.py34
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/image_info.py31
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/iso_info.py9
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/load_balancer.py50
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_info.py79
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_network.py15
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_service.py39
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_target.py17
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_type_info.py27
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/location_info.py23
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/network.py23
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/network_info.py99
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/placement_group.py7
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/primary_ip.py97
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/primary_ip_info.py44
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/rdns.py19
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/route.py11
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/server.py675
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/server_info.py56
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/server_network.py18
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/server_type_info.py49
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/ssh_key.py9
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/ssh_key_info.py27
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/subnetwork.py15
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/volume.py33
-rw-r--r--ansible_collections/hetzner/hcloud/plugins/modules/volume_info.py32
46 files changed, 1052 insertions, 891 deletions
diff --git a/ansible_collections/hetzner/hcloud/plugins/inventory/hcloud.py b/ansible_collections/hetzner/hcloud/plugins/inventory/hcloud.py
index 449342271..d1050c92b 100644
--- a/ansible_collections/hetzner/hcloud/plugins/inventory/hcloud.py
+++ b/ansible_collections/hetzner/hcloud/plugins/inventory/hcloud.py
@@ -32,21 +32,10 @@ options:
description:
- The API Token for the Hetzner Cloud.
type: str
- required: false # TODO: Mark as required once 'api_token_env' is removed.
+ required: true
aliases: [token]
env:
- name: HCLOUD_TOKEN
- api_token_env:
- description:
- - Environment variable name to load the Hetzner Cloud API Token from.
- type: str
- default: HCLOUD_TOKEN
- aliases: [token_env]
- deprecated:
- why: The option is adding too much complexity, while the alternatives are preferred.
- collection_name: hetzner.hcloud
- version: 3.0.0
- alternatives: Use the P(ansible.builtin.env#lookup) lookup plugin instead.
api_endpoint:
description:
- The API Endpoint for the Hetzner Cloud.
@@ -120,6 +109,14 @@ options:
- The suffix for host variables names coming from Hetzner Cloud.
type: str
version_added: 2.5.0
+
+ hostname:
+ description:
+ - A template for the instances hostname, if not provided the Hetzner Cloud server name will be used.
+ - Available variables are the Hetzner Cloud host variables.
+ - The available variables names are provide with the O(hostvars_prefix) or O(hostvars_suffix) modifications.
+ type: str
+ version_added: 3.0.0
"""
EXAMPLES = """
@@ -153,9 +150,43 @@ keyed_groups:
separator: ""
- key: status
prefix: server_status
+
+---
+# Use a custom hostname template.
+plugin: hetzner.hcloud.hcloud
+
+# Available variables are for example:
+## Server
+# id: 42984895
+# name: "my-server"
+# labels:
+# foo: "bar"
+# status: "running"
+## Server Type
+# type: "cx11"
+# server_type: "cx11"
+# architecture: "x86"
+## Image
+# image_id: 114690387
+# image_name: "debian-12"
+# image_os_flavor: "debian"
+## Datacenter
+# datacenter: "hel1-dc2"
+# location: "hel1"
+## Network
+# ipv4: "65.109.140.95" # Value is optional!
+# ipv6: "2a01:4f9:c011:b83f::1" # Value is optional!
+# ipv6_network: 2a01:4f9:c011:b83f::" # Value is optional!
+# ipv6_network_mask: "64" # Value is optional!
+# private_ipv4: "10.0.0.3" # Value is optional!
+# private_networks:
+# - id: 114690387
+# name: "my-private-network"
+# ip: "10.0.0.3"
+#
+hostname: "my-prefix-{{ datacenter }}-{{ name }}-{{ server_type }}"
"""
-import os
import sys
from ipaddress import IPv6Network
@@ -164,6 +195,7 @@ from ansible.inventory.manager import InventoryData
from ansible.module_utils.common.text.converters import to_native
from ansible.plugins.inventory import BaseInventoryPlugin, Cacheable, Constructable
from ansible.utils.display import Display
+from ansible.utils.vars import combine_vars
from ..module_utils.client import (
Client,
@@ -229,7 +261,7 @@ def first_ipv6_address(network: str) -> str:
:param network: IPv6 Network.
"""
- return next(IPv6Network(network).hosts())
+ return str(next(IPv6Network(network).hosts()))
class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
@@ -243,30 +275,9 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
network: Network | None
def _configure_hcloud_client(self):
- # If api_token_env is not the default, print a deprecation warning and load the
- # environment variable.
- api_token_env = self.get_option("api_token_env")
- if api_token_env != "HCLOUD_TOKEN":
- self.display.deprecated(
- "The 'api_token_env' option is deprecated, please use the 'HCLOUD_TOKEN' "
- "environment variable or use the 'ansible.builtin.env' lookup instead.",
- version="3.0.0",
- collection_name="hetzner.hcloud",
- )
- if api_token_env in os.environ:
- self.set_option("api_token", os.environ.get(api_token_env))
-
api_token = self.get_option("api_token")
api_endpoint = self.get_option("api_endpoint")
- if api_token is None: # TODO: Remove once I(api_token_env) is removed.
- raise AnsibleError(
- "No setting was provided for required configuration setting: "
- "plugin_type: inventory "
- "plugin: hetzner.hcloud.hcloud "
- "setting: api_token"
- )
-
# Resolve template string
api_token = self.templar.template(api_token)
@@ -325,43 +336,43 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
def _build_inventory_server(self, server: Server) -> InventoryServer:
server_dict: InventoryServer = {}
server_dict["id"] = server.id
- server_dict["name"] = to_native(server.name)
- server_dict["status"] = to_native(server.status)
+ server_dict["name"] = server.name
+ server_dict["status"] = server.status
# Server Type
- server_dict["type"] = to_native(server.server_type.name)
- server_dict["server_type"] = to_native(server.server_type.name)
- server_dict["architecture"] = to_native(server.server_type.architecture)
+ server_dict["type"] = server.server_type.name
+ server_dict["server_type"] = server.server_type.name
+ server_dict["architecture"] = server.server_type.architecture
# Network
if server.public_net.ipv4:
- server_dict["ipv4"] = to_native(server.public_net.ipv4.ip)
+ server_dict["ipv4"] = server.public_net.ipv4.ip
if server.public_net.ipv6:
- server_dict["ipv6"] = to_native(first_ipv6_address(server.public_net.ipv6.ip))
- server_dict["ipv6_network"] = to_native(server.public_net.ipv6.network)
- server_dict["ipv6_network_mask"] = to_native(server.public_net.ipv6.network_mask)
+ server_dict["ipv6"] = first_ipv6_address(server.public_net.ipv6.ip)
+ server_dict["ipv6_network"] = server.public_net.ipv6.network
+ server_dict["ipv6_network_mask"] = server.public_net.ipv6.network_mask
server_dict["private_networks"] = [
- {"id": v.network.id, "name": to_native(v.network.name), "ip": to_native(v.ip)} for v in server.private_net
+ {"id": v.network.id, "name": v.network.name, "ip": v.ip} for v in server.private_net
]
if self.get_option("network"):
for private_net in server.private_net:
# Set private_ipv4 if user filtered for one network
if private_net.network.id == self.network.id:
- server_dict["private_ipv4"] = to_native(private_net.ip)
+ server_dict["private_ipv4"] = private_net.ip
break
# Datacenter
- server_dict["datacenter"] = to_native(server.datacenter.name)
- server_dict["location"] = to_native(server.datacenter.location.name)
+ server_dict["datacenter"] = server.datacenter.name
+ server_dict["location"] = server.datacenter.location.name
# Image
if server.image is not None:
server_dict["image_id"] = server.image.id
- server_dict["image_os_flavor"] = to_native(server.image.os_flavor)
- server_dict["image_name"] = to_native(server.image.name or server.image.description)
+ server_dict["image_os_flavor"] = server.image.os_flavor
+ server_dict["image_name"] = server.image.name or server.image.description
# Labels
server_dict["labels"] = dict(server.labels)
@@ -380,28 +391,28 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
def _get_server_ansible_host(self, server: Server):
if self.get_option("connect_with") == "public_ipv4":
if server.public_net.ipv4:
- return to_native(server.public_net.ipv4.ip)
+ return server.public_net.ipv4.ip
raise AnsibleError("Server has no public ipv4, but connect_with=public_ipv4 was specified")
if self.get_option("connect_with") == "public_ipv6":
if server.public_net.ipv6:
- return to_native(first_ipv6_address(server.public_net.ipv6.ip))
+ return first_ipv6_address(server.public_net.ipv6.ip)
raise AnsibleError("Server has no public ipv6, but connect_with=public_ipv6 was specified")
if self.get_option("connect_with") == "hostname":
# every server has a name, no need to guard this
- return to_native(server.name)
+ return server.name
if self.get_option("connect_with") == "ipv4_dns_ptr":
if server.public_net.ipv4:
- return to_native(server.public_net.ipv4.dns_ptr)
+ return server.public_net.ipv4.dns_ptr
raise AnsibleError("Server has no public ipv4, but connect_with=ipv4_dns_ptr was specified")
if self.get_option("connect_with") == "private_ipv4":
if self.get_option("network"):
for private_net in server.private_net:
if private_net.network.id == self.network.id:
- return to_native(private_net.ip)
+ return private_net.ip
else:
raise AnsibleError("You can only connect via private IPv4 if you specify a network")
@@ -466,9 +477,10 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
hostvars_prefix = self.get_option("hostvars_prefix")
hostvars_suffix = self.get_option("hostvars_suffix")
+ hostname_template = self.get_option("hostname")
for server in servers:
- self.inventory.add_host(server["name"], group=self.get_option("group"))
+ hostvars = {}
for key, value in server.items():
# Add hostvars prefix and suffix for variables coming from the Hetzner Cloud.
if hostvars_prefix or hostvars_suffix:
@@ -478,7 +490,18 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
if hostvars_suffix:
key = key + hostvars_suffix
- self.inventory.set_variable(server["name"], key, value)
+ hostvars[key] = value
+
+ if hostname_template:
+ templar = self.templar
+ templar.available_variables = combine_vars(hostvars, self._vars)
+ hostname = templar.template(hostname_template)
+ else:
+ hostname = server["name"]
+
+ self.inventory.add_host(hostname, group=self.get_option("group"))
+ for key, value in hostvars.items():
+ self.inventory.set_variable(hostname, key, value)
# Use constructed if applicable
strict = self.get_option("strict")
@@ -486,8 +509,8 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
# Composed variables
self._set_composite_vars(
self.get_option("compose"),
- self.inventory.get_host(server["name"]).get_vars(),
- server["name"],
+ self.inventory.get_host(hostname).get_vars(),
+ hostname,
strict=strict,
)
@@ -495,7 +518,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
self._add_host_to_composed_groups(
self.get_option("groups"),
{},
- server["name"],
+ hostname,
strict=strict,
)
@@ -503,7 +526,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
self._add_host_to_keyed_groups(
self.get_option("keyed_groups"),
{},
- server["name"],
+ hostname,
strict=strict,
)
diff --git a/ansible_collections/hetzner/hcloud/plugins/module_utils/hcloud.py b/ansible_collections/hetzner/hcloud/plugins/module_utils/hcloud.py
index eab0aef59..60391308a 100644
--- a/ansible_collections/hetzner/hcloud/plugins/module_utils/hcloud.py
+++ b/ansible_collections/hetzner/hcloud/plugins/module_utils/hcloud.py
@@ -10,6 +10,10 @@ from typing import Any, NoReturn
from ansible.module_utils.basic import AnsibleModule as AnsibleModuleBase, env_fallback
from ansible.module_utils.common.text.converters import to_native
+from ansible.module_utils.common.validation import (
+ check_missing_parameters,
+ check_required_one_of,
+)
from .client import ClientException, client_check_required_lib, client_get_by_name_or_id
from .vendor.hcloud import APIException, Client, HCloudException
@@ -94,6 +98,29 @@ class AnsibleHCloud:
def _mark_as_changed(self) -> None:
self.result["changed"] = True
+ def fail_on_invalid_params(
+ self,
+ *,
+ required: list[str] | None = None,
+ required_one_of: list[list[str]] | None = None,
+ ) -> None:
+ """
+ Run additional validation that cannot be done in the argument spec validation.
+
+ :param required_params: Check that terms exists in the module params.
+ :param required_one_of: Check each list of terms to ensure at least one exists in the module parameters.
+ """
+ try:
+ if required:
+ check_missing_parameters(self.module.params, required)
+
+ if required_one_of:
+ params_without_nones = {k: v for k, v in self.module.params.items() if v is not None}
+ check_required_one_of(required_one_of, params_without_nones)
+
+ except TypeError as e:
+ self.module.fail_json(msg=to_native(e))
+
@classmethod
def base_module_arguments(cls):
return {
diff --git a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/_version.py b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/_version.py
index e03c1b434..d350d7138 100644
--- a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/_version.py
+++ b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/_version.py
@@ -1,3 +1,3 @@
from __future__ import annotations
-VERSION = "1.33.2" # x-release-please-version
+VERSION = "1.35.0" # x-release-please-version
diff --git a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/core/domain.py b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/core/domain.py
index 692f7488b..bba954fe2 100644
--- a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/core/domain.py
+++ b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/core/domain.py
@@ -34,6 +34,24 @@ class DomainIdentityMixin:
return self.name
raise ValueError("id or name must be set")
+ def has_id_or_name(self, id_or_name: int | str) -> bool:
+ """
+ Return whether this domain has the same id or same name as the other.
+
+ The domain calling this method MUST be a bound domain or be populated, otherwise
+ the comparison will not work as expected (e.g. the domains are the same but
+ cannot be equal, if one provides an id and the other the name).
+ """
+ values: list[int | str] = []
+ if self.id is not None:
+ values.append(self.id)
+ if self.name is not None:
+ values.append(self.name)
+ if not values:
+ raise ValueError("id or name must be set")
+
+ return id_or_name in values
+
class Pagination(BaseDomain):
__slots__ = (
diff --git a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/firewalls/domain.py b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/firewalls/domain.py
index 5ce9281d9..d637231d6 100644
--- a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/firewalls/domain.py
+++ b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/firewalls/domain.py
@@ -7,7 +7,7 @@ try:
except ImportError:
isoparse = None
-from ..core import BaseDomain
+from ..core import BaseDomain, DomainIdentityMixin
if TYPE_CHECKING:
from ..actions import BoundAction
@@ -15,7 +15,7 @@ if TYPE_CHECKING:
from .client import BoundFirewall
-class Firewall(BaseDomain):
+class Firewall(BaseDomain, DomainIdentityMixin):
"""Firewall Domain
:param id: int
diff --git a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/floating_ips/domain.py b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/floating_ips/domain.py
index e1f295bd6..abd2c13cc 100644
--- a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/floating_ips/domain.py
+++ b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/floating_ips/domain.py
@@ -7,7 +7,7 @@ try:
except ImportError:
isoparse = None
-from ..core import BaseDomain
+from ..core import BaseDomain, DomainIdentityMixin
if TYPE_CHECKING:
from ..actions import BoundAction
@@ -16,7 +16,7 @@ if TYPE_CHECKING:
from .client import BoundFloatingIP
-class FloatingIP(BaseDomain):
+class FloatingIP(BaseDomain, DomainIdentityMixin):
"""Floating IP Domain
:param id: int
diff --git a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/images/client.py b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/images/client.py
index 65b7546a8..a7d41e01b 100644
--- a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/images/client.py
+++ b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/images/client.py
@@ -1,5 +1,6 @@
from __future__ import annotations
+import warnings
from typing import TYPE_CHECKING, Any, NamedTuple
from ..actions import ActionsPageResult, BoundAction, ResourceActionsClient
@@ -305,18 +306,27 @@ class ImagesClient(ClientEntityBase):
def get_by_name(self, name: str) -> BoundImage | None:
"""Get image by name
- Deprecated: Use get_by_name_and_architecture instead.
-
:param name: str
Used to get image by name.
:return: :class:`BoundImage <hcloud.images.client.BoundImage>`
+
+ .. deprecated:: 1.19
+ Use :func:`hcloud.images.client.ImagesClient.get_by_name_and_architecture` instead.
"""
+ warnings.warn(
+ "The 'hcloud.images.client.ImagesClient.get_by_name' method is deprecated, please use the "
+ "'hcloud.images.client.ImagesClient.get_by_name_and_architecture' method instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
return self._get_first_by(name=name)
def get_by_name_and_architecture(
self,
name: str,
architecture: str,
+ *,
+ include_deprecated: bool | None = None,
) -> BoundImage | None:
"""Get image by name
@@ -324,9 +334,15 @@ class ImagesClient(ClientEntityBase):
Used to identify the image.
:param architecture: str
Used to identify the image.
+ :param include_deprecated: bool (optional)
+ Include deprecated images. Default: False
:return: :class:`BoundImage <hcloud.images.client.BoundImage>`
"""
- return self._get_first_by(name=name, architecture=[architecture])
+ return self._get_first_by(
+ name=name,
+ architecture=[architecture],
+ include_deprecated=include_deprecated,
+ )
def update(
self,
diff --git a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/load_balancers/domain.py b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/load_balancers/domain.py
index 6d6f0700a..76e8db3f7 100644
--- a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/load_balancers/domain.py
+++ b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/load_balancers/domain.py
@@ -7,7 +7,7 @@ try:
except ImportError:
isoparse = None
-from ..core import BaseDomain
+from ..core import BaseDomain, DomainIdentityMixin
if TYPE_CHECKING:
from ..actions import BoundAction
@@ -20,7 +20,7 @@ if TYPE_CHECKING:
from .client import BoundLoadBalancer
-class LoadBalancer(BaseDomain):
+class LoadBalancer(BaseDomain, DomainIdentityMixin):
"""LoadBalancer Domain
:param id: int
@@ -79,7 +79,7 @@ class LoadBalancer(BaseDomain):
id: int,
name: str | None = None,
public_net: PublicNetwork | None = None,
- private_net: PrivateNet | None = None,
+ private_net: list[PrivateNet] | None = None,
location: BoundLocation | None = None,
algorithm: LoadBalancerAlgorithm | None = None,
services: list[LoadBalancerService] | None = None,
@@ -203,9 +203,9 @@ class LoadBalancerService(BaseDomain):
if self.health_check.http.response is not None:
health_check_http["response"] = self.health_check.http.response
if self.health_check.http.status_codes is not None:
- health_check_http[
- "status_codes"
- ] = self.health_check.http.status_codes
+ health_check_http["status_codes"] = (
+ self.health_check.http.status_codes
+ )
if self.health_check.http.tls is not None:
health_check_http["tls"] = self.health_check.http.tls
diff --git a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/networks/domain.py b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/networks/domain.py
index c307bf989..e04de2775 100644
--- a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/networks/domain.py
+++ b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/networks/domain.py
@@ -7,7 +7,7 @@ try:
except ImportError:
isoparse = None
-from ..core import BaseDomain
+from ..core import BaseDomain, DomainIdentityMixin
if TYPE_CHECKING:
from ..actions import BoundAction
@@ -15,7 +15,7 @@ if TYPE_CHECKING:
from .client import BoundNetwork
-class Network(BaseDomain):
+class Network(BaseDomain, DomainIdentityMixin):
"""Network Domain
:param id: int
diff --git a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/placement_groups/domain.py b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/placement_groups/domain.py
index 16b2a390d..1c6fc04cd 100644
--- a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/placement_groups/domain.py
+++ b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/placement_groups/domain.py
@@ -7,14 +7,14 @@ try:
except ImportError:
isoparse = None
-from ..core import BaseDomain
+from ..core import BaseDomain, DomainIdentityMixin
if TYPE_CHECKING:
from ..actions import BoundAction
from .client import BoundPlacementGroup
-class PlacementGroup(BaseDomain):
+class PlacementGroup(BaseDomain, DomainIdentityMixin):
"""Placement Group Domain
:param id: int
diff --git a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/primary_ips/domain.py b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/primary_ips/domain.py
index aeb943f0a..2eebacef4 100644
--- a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/primary_ips/domain.py
+++ b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/primary_ips/domain.py
@@ -7,7 +7,7 @@ try:
except ImportError:
isoparse = None
-from ..core import BaseDomain
+from ..core import BaseDomain, DomainIdentityMixin
if TYPE_CHECKING:
from ..actions import BoundAction
@@ -15,7 +15,7 @@ if TYPE_CHECKING:
from .client import BoundPrimaryIP
-class PrimaryIP(BaseDomain):
+class PrimaryIP(BaseDomain, DomainIdentityMixin):
"""Primary IP Domain
:param id: int
diff --git a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/servers/domain.py b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/servers/domain.py
index 0a0d34688..d5e769e5e 100644
--- a/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/servers/domain.py
+++ b/ansible_collections/hetzner/hcloud/plugins/module_utils/vendor/hcloud/servers/domain.py
@@ -7,7 +7,7 @@ try:
except ImportError:
isoparse = None
-from ..core import BaseDomain
+from ..core import BaseDomain, DomainIdentityMixin
if TYPE_CHECKING:
from ..actions import BoundAction
@@ -25,7 +25,7 @@ if TYPE_CHECKING:
from .client import BoundServer
-class Server(BaseDomain):
+class Server(BaseDomain, DomainIdentityMixin):
"""Server Domain
:param id: int
diff --git a/ansible_collections/hetzner/hcloud/plugins/module_utils/version.py b/ansible_collections/hetzner/hcloud/plugins/module_utils/version.py
index e78c320a2..0bf903564 100644
--- a/ansible_collections/hetzner/hcloud/plugins/module_utils/version.py
+++ b/ansible_collections/hetzner/hcloud/plugins/module_utils/version.py
@@ -1,3 +1,3 @@
from __future__ import annotations
-version = "2.5.0" # x-release-please-version
+version = "3.1.1" # x-release-please-version
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/certificate.py b/ansible_collections/hetzner/hcloud/plugins/modules/certificate.py
index ea39be6ca..53466e48f 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/certificate.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/certificate.py
@@ -146,7 +146,6 @@ hcloud_certificate:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import HCloudException
@@ -160,14 +159,14 @@ class AnsibleHCloudCertificate(AnsibleHCloud):
def _prepare_result(self):
return {
- "id": to_native(self.hcloud_certificate.id),
- "name": to_native(self.hcloud_certificate.name),
- "type": to_native(self.hcloud_certificate.type),
- "fingerprint": to_native(self.hcloud_certificate.fingerprint),
- "certificate": to_native(self.hcloud_certificate.certificate),
- "not_valid_before": to_native(self.hcloud_certificate.not_valid_before),
- "not_valid_after": to_native(self.hcloud_certificate.not_valid_after),
- "domain_names": [to_native(domain) for domain in self.hcloud_certificate.domain_names],
+ "id": str(self.hcloud_certificate.id),
+ "name": self.hcloud_certificate.name,
+ "type": self.hcloud_certificate.type,
+ "fingerprint": self.hcloud_certificate.fingerprint,
+ "certificate": self.hcloud_certificate.certificate,
+ "not_valid_before": self.hcloud_certificate.not_valid_before.isoformat(),
+ "not_valid_after": self.hcloud_certificate.not_valid_after.isoformat(),
+ "domain_names": self.hcloud_certificate.domain_names,
"labels": self.hcloud_certificate.labels,
}
@@ -203,7 +202,9 @@ class AnsibleHCloudCertificate(AnsibleHCloud):
if not self.module.check_mode:
try:
resp = self.client.certificates.create_managed(**params)
- resp.action.wait_until_finished(max_retries=1000)
+ # Action should take 60 to 90 seconds on average, wait for 5m to
+ # allow DNS or Let's Encrypt slowdowns.
+ resp.action.wait_until_finished(max_retries=300)
except HCloudException as exception:
self.fail_json_hcloud(exception)
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/certificate_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/certificate_info.py
index e074046fd..37b944341 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/certificate_info.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/certificate_info.py
@@ -87,7 +87,6 @@ hcloud_certificate_info:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import HCloudException
@@ -100,23 +99,25 @@ class AnsibleHCloudCertificateInfo(AnsibleHCloud):
hcloud_certificate_info: list[BoundCertificate] | None = None
def _prepare_result(self):
- certificates = []
+ tmp = []
for certificate in self.hcloud_certificate_info:
- if certificate:
- certificates.append(
- {
- "id": to_native(certificate.id),
- "name": to_native(certificate.name),
- "fingerprint": to_native(certificate.fingerprint),
- "certificate": to_native(certificate.certificate),
- "not_valid_before": to_native(certificate.not_valid_before),
- "not_valid_after": to_native(certificate.not_valid_after),
- "domain_names": [to_native(domain) for domain in certificate.domain_names],
- "labels": certificate.labels,
- }
- )
- return certificates
+ if certificate is None:
+ continue
+
+ tmp.append(
+ {
+ "id": str(certificate.id),
+ "name": certificate.name,
+ "fingerprint": certificate.fingerprint,
+ "certificate": certificate.certificate,
+ "not_valid_before": certificate.not_valid_before.isoformat(),
+ "not_valid_after": certificate.not_valid_after.isoformat(),
+ "domain_names": certificate.domain_names,
+ "labels": certificate.labels,
+ }
+ )
+ return tmp
def get_certificates(self):
try:
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/datacenter_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/datacenter_info.py
index f6665a6fb..85475dd44 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/datacenter_info.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/datacenter_info.py
@@ -118,7 +118,6 @@ hcloud_datacenter_info:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import HCloudException
@@ -139,10 +138,10 @@ class AnsibleHCloudDatacenterInfo(AnsibleHCloud):
tmp.append(
{
- "id": to_native(datacenter.id),
- "name": to_native(datacenter.name),
- "description": to_native(datacenter.description),
- "location": to_native(datacenter.location.name),
+ "id": str(datacenter.id),
+ "name": datacenter.name,
+ "description": datacenter.description,
+ "location": datacenter.location.name,
"server_types": {
"available": [o.id for o in datacenter.server_types.available],
"available_for_migration": [o.id for o in datacenter.server_types.available_for_migration],
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/firewall.py b/ansible_collections/hetzner/hcloud/plugins/modules/firewall.py
index 3c51b5c0a..30f17eb9b 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/firewall.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/firewall.py
@@ -219,7 +219,6 @@ hcloud_firewall:
import time
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import APIException, HCloudException
@@ -237,8 +236,8 @@ class AnsibleHCloudFirewall(AnsibleHCloud):
def _prepare_result(self):
return {
- "id": to_native(self.hcloud_firewall.id),
- "name": to_native(self.hcloud_firewall.name),
+ "id": str(self.hcloud_firewall.id),
+ "name": self.hcloud_firewall.name,
"rules": [self._prepare_result_rule(rule) for rule in self.hcloud_firewall.rules],
"labels": self.hcloud_firewall.labels,
"applied_to": [self._prepare_result_applied_to(resource) for resource in self.hcloud_firewall.applied_to],
@@ -246,27 +245,25 @@ class AnsibleHCloudFirewall(AnsibleHCloud):
def _prepare_result_rule(self, rule: FirewallRule):
return {
- "direction": to_native(rule.direction),
- "protocol": to_native(rule.protocol),
- "port": to_native(rule.port) if rule.port is not None else None,
- "source_ips": [to_native(cidr) for cidr in rule.source_ips],
- "destination_ips": [to_native(cidr) for cidr in rule.destination_ips],
- "description": to_native(rule.description) if rule.description is not None else None,
+ "direction": rule.direction,
+ "protocol": rule.protocol,
+ "port": rule.port,
+ "source_ips": rule.source_ips,
+ "destination_ips": rule.destination_ips,
+ "description": rule.description,
}
def _prepare_result_applied_to(self, resource: FirewallResource):
result = {
- "type": to_native(resource.type),
- "server": to_native(resource.server.id) if resource.server is not None else None,
- "label_selector": (
- to_native(resource.label_selector.selector) if resource.label_selector is not None else None
- ),
+ "type": resource.type,
+ "server": str(resource.server.id) if resource.server is not None else None,
+ "label_selector": resource.label_selector.selector if resource.label_selector is not None else None,
}
if resource.applied_to_resources is not None:
result["applied_to_resources"] = [
{
- "type": to_native(item.type),
- "server": to_native(item.server.id) if item.server is not None else None,
+ "type": item.type,
+ "server": str(item.server.id) if item.server is not None else None,
}
for item in resource.applied_to_resources
]
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/firewall_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/firewall_info.py
index 7e7a623d0..a07d9ec54 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/firewall_info.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/firewall_info.py
@@ -142,7 +142,6 @@ hcloud_firewall_info:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import HCloudException
@@ -167,8 +166,8 @@ class AnsibleHCloudFirewallInfo(AnsibleHCloud):
tmp.append(
{
- "id": to_native(firewall.id),
- "name": to_native(firewall.name),
+ "id": str(firewall.id),
+ "name": firewall.name,
"labels": firewall.labels,
"rules": [self._prepare_result_rule(rule) for rule in firewall.rules],
"applied_to": [self._prepare_result_applied_to(resource) for resource in firewall.applied_to],
@@ -179,27 +178,25 @@ class AnsibleHCloudFirewallInfo(AnsibleHCloud):
def _prepare_result_rule(self, rule: FirewallRule):
return {
- "description": to_native(rule.description) if rule.description is not None else None,
- "direction": to_native(rule.direction),
- "protocol": to_native(rule.protocol),
- "port": to_native(rule.port) if rule.port is not None else None,
- "source_ips": [to_native(cidr) for cidr in rule.source_ips],
- "destination_ips": [to_native(cidr) for cidr in rule.destination_ips],
+ "description": rule.description,
+ "direction": rule.direction,
+ "protocol": rule.protocol,
+ "port": rule.port,
+ "source_ips": rule.source_ips,
+ "destination_ips": rule.destination_ips,
}
def _prepare_result_applied_to(self, resource: FirewallResource):
result = {
- "type": to_native(resource.type),
- "server": to_native(resource.server.id) if resource.server is not None else None,
- "label_selector": (
- to_native(resource.label_selector.selector) if resource.label_selector is not None else None
- ),
+ "type": resource.type,
+ "server": str(resource.server.id) if resource.server is not None else None,
+ "label_selector": resource.label_selector.selector if resource.label_selector is not None else None,
}
if resource.applied_to_resources is not None:
result["applied_to_resources"] = [
{
- "type": to_native(item.type),
- "server": to_native(item.server.id) if item.server is not None else None,
+ "type": item.type,
+ "server": str(item.server.id) if item.server is not None else None,
}
for item in resource.applied_to_resources
]
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/firewall_resource.py b/ansible_collections/hetzner/hcloud/plugins/modules/firewall_resource.py
index 207f27092..7c0271ba3 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/firewall_resource.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/firewall_resource.py
@@ -103,7 +103,6 @@ hcloud_firewall_resource:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import HCloudException
@@ -125,12 +124,12 @@ class AnsibleHCloudFirewallResource(AnsibleHCloud):
label_selectors = []
for resource in self.hcloud_firewall_resource.applied_to:
if resource.type == FirewallResource.TYPE_SERVER:
- servers.append(to_native(resource.server.name))
+ servers.append(resource.server.name)
elif resource.type == FirewallResource.TYPE_LABEL_SELECTOR:
- label_selectors.append(to_native(resource.label_selector.selector))
+ label_selectors.append(resource.label_selector.selector)
return {
- "firewall": to_native(self.hcloud_firewall_resource.name),
+ "firewall": self.hcloud_firewall_resource.name,
"servers": servers,
"label_selectors": label_selectors,
}
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/floating_ip.py b/ansible_collections/hetzner/hcloud/plugins/modules/floating_ip.py
index e037dd7a1..022036124 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/floating_ip.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/floating_ip.py
@@ -160,7 +160,6 @@ hcloud_floating_ip:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import HCloudException
@@ -173,19 +172,15 @@ class AnsibleHCloudFloatingIP(AnsibleHCloud):
hcloud_floating_ip: BoundFloatingIP | None = None
def _prepare_result(self):
- server = None
-
- if self.hcloud_floating_ip.server is not None:
- server = to_native(self.hcloud_floating_ip.server.name)
return {
- "id": to_native(self.hcloud_floating_ip.id),
- "name": to_native(self.hcloud_floating_ip.name),
- "description": to_native(self.hcloud_floating_ip.description),
- "ip": to_native(self.hcloud_floating_ip.ip),
- "type": to_native(self.hcloud_floating_ip.type),
- "home_location": to_native(self.hcloud_floating_ip.home_location.name),
+ "id": str(self.hcloud_floating_ip.id),
+ "name": self.hcloud_floating_ip.name,
+ "description": self.hcloud_floating_ip.description,
+ "ip": self.hcloud_floating_ip.ip,
+ "type": self.hcloud_floating_ip.type,
+ "home_location": self.hcloud_floating_ip.home_location.name,
"labels": self.hcloud_floating_ip.labels,
- "server": server,
+ "server": self.hcloud_floating_ip.server.name if self.hcloud_floating_ip.server is not None else None,
"delete_protection": self.hcloud_floating_ip.protection["delete"],
}
@@ -221,7 +216,8 @@ class AnsibleHCloudFloatingIP(AnsibleHCloud):
delete_protection = self.module.params.get("delete_protection")
if delete_protection is not None:
- self.hcloud_floating_ip.change_protection(delete=delete_protection).wait_until_finished()
+ action = self.hcloud_floating_ip.change_protection(delete=delete_protection)
+ action.wait_until_finished()
except HCloudException as exception:
self.fail_json_hcloud(exception)
self._mark_as_changed()
@@ -266,7 +262,8 @@ class AnsibleHCloudFloatingIP(AnsibleHCloud):
delete_protection = self.module.params.get("delete_protection")
if delete_protection is not None and delete_protection != self.hcloud_floating_ip.protection["delete"]:
if not self.module.check_mode:
- self.hcloud_floating_ip.change_protection(delete=delete_protection).wait_until_finished()
+ action = self.hcloud_floating_ip.change_protection(delete=delete_protection)
+ action.wait_until_finished()
self._mark_as_changed()
self._get_floating_ip()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/floating_ip_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/floating_ip_info.py
index 663d29622..6595799ba 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/floating_ip_info.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/floating_ip_info.py
@@ -100,7 +100,6 @@ hcloud_floating_ip_info:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import HCloudException
@@ -116,23 +115,22 @@ class AnsibleHCloudFloatingIPInfo(AnsibleHCloud):
tmp = []
for floating_ip in self.hcloud_floating_ip_info:
- if floating_ip is not None:
- server_name = None
- if floating_ip.server is not None:
- server_name = floating_ip.server.name
- tmp.append(
- {
- "id": to_native(floating_ip.id),
- "name": to_native(floating_ip.name),
- "description": to_native(floating_ip.description),
- "ip": to_native(floating_ip.ip),
- "type": to_native(floating_ip.type),
- "server": to_native(server_name),
- "home_location": to_native(floating_ip.home_location.name),
- "labels": floating_ip.labels,
- "delete_protection": floating_ip.protection["delete"],
- }
- )
+ if floating_ip is None:
+ continue
+
+ tmp.append(
+ {
+ "id": str(floating_ip.id),
+ "name": floating_ip.name,
+ "description": floating_ip.description,
+ "ip": floating_ip.ip,
+ "type": floating_ip.type,
+ "server": floating_ip.server.name if floating_ip.server is not None else None,
+ "home_location": floating_ip.home_location.name,
+ "labels": floating_ip.labels,
+ "delete_protection": floating_ip.protection["delete"],
+ }
+ )
return tmp
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/image_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/image_info.py
index b0d7fc482..a3a1331c5 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/image_info.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/image_info.py
@@ -112,7 +112,6 @@ hcloud_image_info:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import HCloudException
@@ -128,20 +127,22 @@ class AnsibleHCloudImageInfo(AnsibleHCloud):
tmp = []
for image in self.hcloud_image_info:
- if image is not None:
- tmp.append(
- {
- "id": to_native(image.id),
- "status": to_native(image.status),
- "type": to_native(image.type),
- "name": to_native(image.name),
- "description": to_native(image.description),
- "os_flavor": to_native(image.os_flavor),
- "os_version": to_native(image.os_version),
- "architecture": to_native(image.architecture),
- "labels": image.labels,
- }
- )
+ if image is None:
+ continue
+
+ tmp.append(
+ {
+ "id": str(image.id),
+ "status": image.status,
+ "type": image.type,
+ "name": image.name,
+ "description": image.description,
+ "os_flavor": image.os_flavor,
+ "os_version": image.os_version,
+ "architecture": image.architecture,
+ "labels": image.labels,
+ }
+ )
return tmp
def get_images(self):
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/iso_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/iso_info.py
index e623d1714..aab33cab2 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/iso_info.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/iso_info.py
@@ -122,7 +122,6 @@ hcloud_iso_info:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import HCloudException
@@ -143,13 +142,13 @@ class AnsibleHCloudIsoInfo(AnsibleHCloud):
tmp.append(
{
- "id": to_native(iso_info.id),
- "name": to_native(iso_info.name),
- "description": to_native(iso_info.description),
+ "id": str(iso_info.id),
+ "name": iso_info.name,
+ "description": iso_info.description,
"type": iso_info.type,
"architecture": iso_info.architecture,
"deprecated": (
- iso_info.deprecation.unavailable_after if iso_info.deprecation is not None else None
+ iso_info.deprecation.unavailable_after.isoformat() if iso_info.deprecation is not None else None
),
"deprecation": (
{
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer.py b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer.py
index 1a0d8712a..11dbf96fb 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer.py
@@ -152,7 +152,6 @@ hcloud_load_balancer:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import HCloudException
@@ -168,23 +167,20 @@ class AnsibleHCloudLoadBalancer(AnsibleHCloud):
hcloud_load_balancer: BoundLoadBalancer | None = None
def _prepare_result(self):
- private_ipv4_address = (
- None
- if len(self.hcloud_load_balancer.private_net) == 0
- else to_native(self.hcloud_load_balancer.private_net[0].ip)
- )
return {
- "id": to_native(self.hcloud_load_balancer.id),
- "name": to_native(self.hcloud_load_balancer.name),
- "ipv4_address": to_native(self.hcloud_load_balancer.public_net.ipv4.ip),
- "ipv6_address": to_native(self.hcloud_load_balancer.public_net.ipv6.ip),
- "private_ipv4_address": private_ipv4_address,
- "load_balancer_type": to_native(self.hcloud_load_balancer.load_balancer_type.name),
- "algorithm": to_native(self.hcloud_load_balancer.algorithm.type),
- "location": to_native(self.hcloud_load_balancer.location.name),
+ "id": str(self.hcloud_load_balancer.id),
+ "name": self.hcloud_load_balancer.name,
+ "ipv4_address": self.hcloud_load_balancer.public_net.ipv4.ip,
+ "ipv6_address": self.hcloud_load_balancer.public_net.ipv6.ip,
+ "private_ipv4_address": (
+ self.hcloud_load_balancer.private_net[0].ip if len(self.hcloud_load_balancer.private_net) else None
+ ),
+ "load_balancer_type": self.hcloud_load_balancer.load_balancer_type.name,
+ "algorithm": self.hcloud_load_balancer.algorithm.type,
+ "location": self.hcloud_load_balancer.location.name,
"labels": self.hcloud_load_balancer.labels,
"delete_protection": self.hcloud_load_balancer.protection["delete"],
- "disable_public_interface": False if self.hcloud_load_balancer.public_net.enabled else True,
+ "disable_public_interface": not self.hcloud_load_balancer.public_net.enabled,
}
def _get_load_balancer(self):
@@ -217,12 +213,13 @@ class AnsibleHCloudLoadBalancer(AnsibleHCloud):
if not self.module.check_mode:
resp = self.client.load_balancers.create(**params)
- resp.action.wait_until_finished(max_retries=1000)
+ resp.action.wait_until_finished()
delete_protection = self.module.params.get("delete_protection")
if delete_protection is not None:
self._get_load_balancer()
- self.hcloud_load_balancer.change_protection(delete=delete_protection).wait_until_finished()
+ action = self.hcloud_load_balancer.change_protection(delete=delete_protection)
+ action.wait_until_finished()
except HCloudException as exception:
self.fail_json_hcloud(exception)
self._mark_as_changed()
@@ -239,7 +236,8 @@ class AnsibleHCloudLoadBalancer(AnsibleHCloud):
delete_protection = self.module.params.get("delete_protection")
if delete_protection is not None and delete_protection != self.hcloud_load_balancer.protection["delete"]:
if not self.module.check_mode:
- self.hcloud_load_balancer.change_protection(delete=delete_protection).wait_until_finished()
+ action = self.hcloud_load_balancer.change_protection(delete=delete_protection)
+ action.wait_until_finished()
self._mark_as_changed()
self._get_load_balancer()
@@ -249,9 +247,11 @@ class AnsibleHCloudLoadBalancer(AnsibleHCloud):
):
if not self.module.check_mode:
if disable_public_interface is True:
- self.hcloud_load_balancer.disable_public_interface().wait_until_finished()
+ action = self.hcloud_load_balancer.disable_public_interface()
+ action.wait_until_finished()
else:
- self.hcloud_load_balancer.enable_public_interface().wait_until_finished()
+ action = self.hcloud_load_balancer.enable_public_interface()
+ action.wait_until_finished()
self._mark_as_changed()
load_balancer_type = self.module.params.get("load_balancer_type")
@@ -263,17 +263,17 @@ class AnsibleHCloudLoadBalancer(AnsibleHCloud):
if not new_load_balancer_type:
self.module.fail_json(msg="unknown load balancer type")
if not self.module.check_mode:
- self.hcloud_load_balancer.change_type(
+ action = self.hcloud_load_balancer.change_type(
load_balancer_type=new_load_balancer_type,
- ).wait_until_finished(max_retries=1000)
+ )
+ action.wait_until_finished()
self._mark_as_changed()
algorithm = self.module.params.get("algorithm")
if algorithm is not None and self.hcloud_load_balancer.algorithm.type != algorithm:
- self.hcloud_load_balancer.change_algorithm(
- algorithm=LoadBalancerAlgorithm(type=algorithm)
- ).wait_until_finished()
+ action = self.hcloud_load_balancer.change_algorithm(algorithm=LoadBalancerAlgorithm(type=algorithm))
+ action.wait_until_finished()
self._mark_as_changed()
self._get_load_balancer()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_info.py
index 19ead98c2..4ed5f134b 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_info.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_info.py
@@ -277,11 +277,14 @@ hcloud_load_balancer_info:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import HCloudException
-from ..module_utils.vendor.hcloud.load_balancers import BoundLoadBalancer
+from ..module_utils.vendor.hcloud.load_balancers import (
+ BoundLoadBalancer,
+ LoadBalancerService,
+ LoadBalancerTarget,
+)
class AnsibleHCloudLoadBalancerInfo(AnsibleHCloud):
@@ -293,44 +296,40 @@ class AnsibleHCloudLoadBalancerInfo(AnsibleHCloud):
tmp = []
for load_balancer in self.hcloud_load_balancer_info:
- if load_balancer is not None:
- services = [self._prepare_service_result(service) for service in load_balancer.services]
- targets = [self._prepare_target_result(target) for target in load_balancer.targets]
-
- private_ipv4_address = (
- None if len(load_balancer.private_net) == 0 else to_native(load_balancer.private_net[0].ip)
- )
- tmp.append(
- {
- "id": to_native(load_balancer.id),
- "name": to_native(load_balancer.name),
- "ipv4_address": to_native(load_balancer.public_net.ipv4.ip),
- "ipv6_address": to_native(load_balancer.public_net.ipv6.ip),
- "private_ipv4_address": private_ipv4_address,
- "load_balancer_type": to_native(load_balancer.load_balancer_type.name),
- "location": to_native(load_balancer.location.name),
- "labels": load_balancer.labels,
- "delete_protection": load_balancer.protection["delete"],
- "disable_public_interface": False if load_balancer.public_net.enabled else True,
- "targets": targets,
- "services": services,
- }
- )
+ if load_balancer is None:
+ continue
+
+ tmp.append(
+ {
+ "id": str(load_balancer.id),
+ "name": load_balancer.name,
+ "ipv4_address": load_balancer.public_net.ipv4.ip,
+ "ipv6_address": load_balancer.public_net.ipv6.ip,
+ "private_ipv4_address": load_balancer.private_net[0].ip if len(load_balancer.private_net) else None,
+ "load_balancer_type": load_balancer.load_balancer_type.name,
+ "location": load_balancer.location.name,
+ "labels": load_balancer.labels,
+ "delete_protection": load_balancer.protection["delete"],
+ "disable_public_interface": False if load_balancer.public_net.enabled else True,
+ "targets": [self._prepare_target_result(target) for target in load_balancer.targets],
+ "services": [self._prepare_service_result(service) for service in load_balancer.services],
+ }
+ )
return tmp
@staticmethod
- def _prepare_service_result(service):
+ def _prepare_service_result(service: LoadBalancerService):
http = None
if service.protocol != "tcp":
http = {
- "cookie_name": to_native(service.http.cookie_name),
- "cookie_lifetime": service.http.cookie_name,
+ "cookie_name": service.http.cookie_name,
+ "cookie_lifetime": service.http.cookie_lifetime,
"redirect_http": service.http.redirect_http,
"sticky_sessions": service.http.sticky_sessions,
- "certificates": [to_native(certificate.name) for certificate in service.http.certificates],
+ "certificates": [certificate.name for certificate in service.http.certificates],
}
health_check = {
- "protocol": to_native(service.health_check.protocol),
+ "protocol": service.health_check.protocol,
"port": service.health_check.port,
"interval": service.health_check.interval,
"timeout": service.health_check.timeout,
@@ -338,14 +337,14 @@ class AnsibleHCloudLoadBalancerInfo(AnsibleHCloud):
}
if service.health_check.protocol != "tcp":
health_check["http"] = {
- "domain": to_native(service.health_check.http.domain),
- "path": to_native(service.health_check.http.path),
- "response": to_native(service.health_check.http.response),
- "certificates": [to_native(status_code) for status_code in service.health_check.http.status_codes],
+ "domain": service.health_check.http.domain,
+ "path": service.health_check.http.path,
+ "response": service.health_check.http.response,
+ "certificates": service.health_check.http.status_codes,
"tls": service.health_check.http.tls,
}
return {
- "protocol": to_native(service.protocol),
+ "protocol": service.protocol,
"listen_port": service.listen_port,
"destination_port": service.destination_port,
"proxyprotocol": service.proxyprotocol,
@@ -354,17 +353,17 @@ class AnsibleHCloudLoadBalancerInfo(AnsibleHCloud):
}
@staticmethod
- def _prepare_target_result(target):
+ def _prepare_target_result(target: LoadBalancerTarget):
result = {
- "type": to_native(target.type),
+ "type": target.type,
"use_private_ip": target.use_private_ip,
}
if target.type == "server":
- result["server"] = to_native(target.server.name)
+ result["server"] = target.server.name
elif target.type == "label_selector":
- result["label_selector"] = to_native(target.label_selector.selector)
+ result["label_selector"] = target.label_selector.selector
elif target.type == "ip":
- result["ip"] = to_native(target.ip.ip)
+ result["ip"] = target.ip.ip
if target.health_status is not None:
result["health_status"] = [
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_network.py b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_network.py
index 4560f8735..b6ec486ed 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_network.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_network.py
@@ -90,7 +90,6 @@ hcloud_load_balancer_network:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import HCloudException
@@ -107,9 +106,9 @@ class AnsibleHCloudLoadBalancerNetwork(AnsibleHCloud):
def _prepare_result(self):
return {
- "network": to_native(self.hcloud_network.name),
- "load_balancer": to_native(self.hcloud_load_balancer.name),
- "ip": to_native(self.hcloud_load_balancer_network.ip),
+ "network": self.hcloud_network.name,
+ "load_balancer": self.hcloud_load_balancer.name,
+ "ip": self.hcloud_load_balancer_network.ip,
}
def _get_load_balancer_and_network(self):
@@ -140,7 +139,8 @@ class AnsibleHCloudLoadBalancerNetwork(AnsibleHCloud):
if not self.module.check_mode:
try:
- self.hcloud_load_balancer.attach_to_network(**params).wait_until_finished()
+ action = self.hcloud_load_balancer.attach_to_network(**params)
+ action.wait_until_finished()
except HCloudException as exception:
self.fail_json_hcloud(exception)
@@ -160,9 +160,8 @@ class AnsibleHCloudLoadBalancerNetwork(AnsibleHCloud):
if self.hcloud_load_balancer_network is not None and self.hcloud_load_balancer is not None:
if not self.module.check_mode:
try:
- self.hcloud_load_balancer.detach_from_network(
- self.hcloud_load_balancer_network.network
- ).wait_until_finished()
+ action = self.hcloud_load_balancer.detach_from_network(self.hcloud_load_balancer_network.network)
+ action.wait_until_finished()
self._mark_as_changed()
except HCloudException as exception:
self.fail_json_hcloud(exception)
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_service.py b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_service.py
index 1fc18deef..29e37083c 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_service.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_service.py
@@ -279,7 +279,6 @@ hcloud_load_balancer_service:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import APIException, HCloudException
@@ -302,16 +301,16 @@ class AnsibleHCloudLoadBalancerService(AnsibleHCloud):
http = None
if self.hcloud_load_balancer_service.protocol != "tcp":
http = {
- "cookie_name": to_native(self.hcloud_load_balancer_service.http.cookie_name),
- "cookie_lifetime": self.hcloud_load_balancer_service.http.cookie_name,
+ "cookie_name": self.hcloud_load_balancer_service.http.cookie_name,
+ "cookie_lifetime": self.hcloud_load_balancer_service.http.cookie_lifetime,
"redirect_http": self.hcloud_load_balancer_service.http.redirect_http,
"sticky_sessions": self.hcloud_load_balancer_service.http.sticky_sessions,
"certificates": [
- to_native(certificate.name) for certificate in self.hcloud_load_balancer_service.http.certificates
+ certificate.name for certificate in self.hcloud_load_balancer_service.http.certificates
],
}
health_check = {
- "protocol": to_native(self.hcloud_load_balancer_service.health_check.protocol),
+ "protocol": self.hcloud_load_balancer_service.health_check.protocol,
"port": self.hcloud_load_balancer_service.health_check.port,
"interval": self.hcloud_load_balancer_service.health_check.interval,
"timeout": self.hcloud_load_balancer_service.health_check.timeout,
@@ -319,18 +318,15 @@ class AnsibleHCloudLoadBalancerService(AnsibleHCloud):
}
if self.hcloud_load_balancer_service.health_check.protocol != "tcp":
health_check["http"] = {
- "domain": to_native(self.hcloud_load_balancer_service.health_check.http.domain),
- "path": to_native(self.hcloud_load_balancer_service.health_check.http.path),
- "response": to_native(self.hcloud_load_balancer_service.health_check.http.response),
- "status_codes": [
- to_native(status_code)
- for status_code in self.hcloud_load_balancer_service.health_check.http.status_codes
- ],
+ "domain": self.hcloud_load_balancer_service.health_check.http.domain,
+ "path": self.hcloud_load_balancer_service.health_check.http.path,
+ "response": self.hcloud_load_balancer_service.health_check.http.response,
+ "status_codes": self.hcloud_load_balancer_service.health_check.http.status_codes,
"tls": self.hcloud_load_balancer_service.health_check.http.tls,
}
return {
- "load_balancer": to_native(self.hcloud_load_balancer.name),
- "protocol": to_native(self.hcloud_load_balancer_service.protocol),
+ "load_balancer": self.hcloud_load_balancer.name,
+ "protocol": self.hcloud_load_balancer_service.protocol,
"listen_port": self.hcloud_load_balancer_service.listen_port,
"destination_port": self.hcloud_load_balancer_service.destination_port,
"proxyprotocol": self.hcloud_load_balancer_service.proxyprotocol,
@@ -372,9 +368,8 @@ class AnsibleHCloudLoadBalancerService(AnsibleHCloud):
if not self.module.check_mode:
try:
- self.hcloud_load_balancer.add_service(LoadBalancerService(**params)).wait_until_finished(
- max_retries=1000
- )
+ action = self.hcloud_load_balancer.add_service(LoadBalancerService(**params))
+ action.wait_until_finished()
except HCloudException as exception:
self.fail_json_hcloud(exception)
self._mark_as_changed()
@@ -468,9 +463,8 @@ class AnsibleHCloudLoadBalancerService(AnsibleHCloud):
changed = True
if not self.module.check_mode:
- self.hcloud_load_balancer.update_service(LoadBalancerService(**params)).wait_until_finished(
- max_retries=1000
- )
+ action = self.hcloud_load_balancer.update_service(LoadBalancerService(**params))
+ action.wait_until_finished()
except HCloudException as exception:
self.fail_json_hcloud(exception)
self._get_load_balancer()
@@ -496,9 +490,8 @@ class AnsibleHCloudLoadBalancerService(AnsibleHCloud):
if self.hcloud_load_balancer_service is not None:
if not self.module.check_mode:
try:
- self.hcloud_load_balancer.delete_service(self.hcloud_load_balancer_service).wait_until_finished(
- max_retries=1000
- )
+ action = self.hcloud_load_balancer.delete_service(self.hcloud_load_balancer_service)
+ action.wait_until_finished()
except HCloudException as exception:
self.fail_json_hcloud(exception)
self._mark_as_changed()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_target.py b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_target.py
index 36e7f608f..c392ae712 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_target.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_target.py
@@ -134,7 +134,6 @@ hcloud_load_balancer_target:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import APIException, HCloudException
@@ -156,17 +155,17 @@ class AnsibleHCloudLoadBalancerTarget(AnsibleHCloud):
def _prepare_result(self):
result = {
- "type": to_native(self.hcloud_load_balancer_target.type),
- "load_balancer": to_native(self.hcloud_load_balancer.name),
+ "type": self.hcloud_load_balancer_target.type,
+ "load_balancer": self.hcloud_load_balancer.name,
"use_private_ip": self.hcloud_load_balancer_target.use_private_ip,
}
if self.hcloud_load_balancer_target.type == "server":
- result["server"] = to_native(self.hcloud_load_balancer_target.server.name)
+ result["server"] = self.hcloud_load_balancer_target.server.name
elif self.hcloud_load_balancer_target.type == "label_selector":
- result["label_selector"] = to_native(self.hcloud_load_balancer_target.label_selector.selector)
+ result["label_selector"] = self.hcloud_load_balancer_target.label_selector.selector
elif self.hcloud_load_balancer_target.type == "ip":
- result["ip"] = to_native(self.hcloud_load_balancer_target.ip.ip)
+ result["ip"] = self.hcloud_load_balancer_target.ip.ip
return result
def _get_load_balancer_and_target(self):
@@ -225,7 +224,8 @@ class AnsibleHCloudLoadBalancerTarget(AnsibleHCloud):
if not self.module.check_mode:
try:
- self.hcloud_load_balancer.add_target(**params).wait_until_finished()
+ action = self.hcloud_load_balancer.add_target(**params)
+ action.wait_until_finished()
except APIException as exception:
if exception.code == "locked" or exception.code == "conflict":
self._create_load_balancer_target()
@@ -270,7 +270,8 @@ class AnsibleHCloudLoadBalancerTarget(AnsibleHCloud):
use_private_ip=False,
)
try:
- self.hcloud_load_balancer.remove_target(target).wait_until_finished()
+ action = self.hcloud_load_balancer.remove_target(target)
+ action.wait_until_finished()
except HCloudException as exception:
self.fail_json_hcloud(exception)
self._mark_as_changed()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_type_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_type_info.py
index 67feafd59..90505651c 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_type_info.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/load_balancer_type_info.py
@@ -88,7 +88,6 @@ hcloud_load_balancer_type_info:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import HCloudException
@@ -104,18 +103,20 @@ class AnsibleHCloudLoadBalancerTypeInfo(AnsibleHCloud):
tmp = []
for load_balancer_type in self.hcloud_load_balancer_type_info:
- if load_balancer_type is not None:
- tmp.append(
- {
- "id": to_native(load_balancer_type.id),
- "name": to_native(load_balancer_type.name),
- "description": to_native(load_balancer_type.description),
- "max_connections": load_balancer_type.max_connections,
- "max_services": load_balancer_type.max_services,
- "max_targets": load_balancer_type.max_targets,
- "max_assigned_certificates": load_balancer_type.max_assigned_certificates,
- }
- )
+ if load_balancer_type is None:
+ continue
+
+ tmp.append(
+ {
+ "id": str(load_balancer_type.id),
+ "name": load_balancer_type.name,
+ "description": load_balancer_type.description,
+ "max_connections": load_balancer_type.max_connections,
+ "max_services": load_balancer_type.max_services,
+ "max_targets": load_balancer_type.max_targets,
+ "max_assigned_certificates": load_balancer_type.max_assigned_certificates,
+ }
+ )
return tmp
def get_load_balancer_types(self):
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/location_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/location_info.py
index ac495c6c8..676917bfc 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/location_info.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/location_info.py
@@ -78,7 +78,6 @@ hcloud_location_info:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import HCloudException
@@ -94,16 +93,18 @@ class AnsibleHCloudLocationInfo(AnsibleHCloud):
tmp = []
for location in self.hcloud_location_info:
- if location is not None:
- tmp.append(
- {
- "id": to_native(location.id),
- "name": to_native(location.name),
- "description": to_native(location.description),
- "city": to_native(location.city),
- "country": to_native(location.country),
- }
- )
+ if location is None:
+ continue
+
+ tmp.append(
+ {
+ "id": str(location.id),
+ "name": location.name,
+ "description": location.description,
+ "city": location.city,
+ "country": location.country,
+ }
+ )
return tmp
def get_locations(self):
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/network.py b/ansible_collections/hetzner/hcloud/plugins/modules/network.py
index 24e45a48d..92fe9461e 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/network.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/network.py
@@ -115,7 +115,6 @@ hcloud_network:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import HCloudException
@@ -129,9 +128,9 @@ class AnsibleHCloudNetwork(AnsibleHCloud):
def _prepare_result(self):
return {
- "id": to_native(self.hcloud_network.id),
- "name": to_native(self.hcloud_network.name),
- "ip_range": to_native(self.hcloud_network.ip_range),
+ "id": str(self.hcloud_network.id),
+ "name": self.hcloud_network.name,
+ "ip_range": self.hcloud_network.ip_range,
"expose_routes_to_vswitch": self.hcloud_network.expose_routes_to_vswitch,
"delete_protection": self.hcloud_network.protection["delete"],
"labels": self.hcloud_network.labels,
@@ -165,7 +164,8 @@ class AnsibleHCloudNetwork(AnsibleHCloud):
delete_protection = self.module.params.get("delete_protection")
if delete_protection is not None:
self._get_network()
- self.hcloud_network.change_protection(delete=delete_protection).wait_until_finished()
+ action = self.hcloud_network.change_protection(delete=delete_protection)
+ action.wait_until_finished()
except HCloudException as exception:
self.fail_json_hcloud(exception)
self._mark_as_changed()
@@ -173,6 +173,13 @@ class AnsibleHCloudNetwork(AnsibleHCloud):
def _update_network(self):
try:
+ name = self.module.params.get("name")
+ if name is not None and self.hcloud_network.name != name:
+ self.module.fail_on_missing_params(required_params=["id"])
+ if not self.module.check_mode:
+ self.hcloud_network.update(name=name)
+ 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:
@@ -182,7 +189,8 @@ class AnsibleHCloudNetwork(AnsibleHCloud):
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()
+ action = self.hcloud_network.change_ip_range(ip_range=ip_range)
+ action.wait_until_finished()
self._mark_as_changed()
expose_routes_to_vswitch = self.module.params.get("expose_routes_to_vswitch")
@@ -197,7 +205,8 @@ class AnsibleHCloudNetwork(AnsibleHCloud):
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()
+ action = self.hcloud_network.change_protection(delete=delete_protection)
+ action.wait_until_finished()
self._mark_as_changed()
except HCloudException as exception:
self.fail_json_hcloud(exception)
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/network_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/network_info.py
index 4008352b4..8f1e5fbf7 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/network_info.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/network_info.py
@@ -185,7 +185,6 @@ hcloud_network_info:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import HCloudException
@@ -201,55 +200,55 @@ class AnsibleHCloudNetworkInfo(AnsibleHCloud):
tmp = []
for network in self.hcloud_network_info:
- if network is not None:
- subnets = []
- for subnet in network.subnets:
- prepared_subnet = {
- "type": subnet.type,
- "ip_range": subnet.ip_range,
- "network_zone": subnet.network_zone,
- "gateway": subnet.gateway,
- }
- subnets.append(prepared_subnet)
- routes = []
- for route in network.routes:
- prepared_route = {"destination": route.destination, "gateway": route.gateway}
- routes.append(prepared_route)
-
- servers = []
- for server in network.servers:
- image = None if server.image is None else to_native(server.image.name)
- ipv4_address = None if server.public_net.ipv4 is None else to_native(server.public_net.ipv4.ip)
- ipv6 = None if server.public_net.ipv6 is None else to_native(server.public_net.ipv6.ip)
- prepared_server = {
- "id": to_native(server.id),
- "name": to_native(server.name),
- "ipv4_address": ipv4_address,
- "ipv6": ipv6,
- "image": image,
- "server_type": to_native(server.server_type.name),
- "datacenter": to_native(server.datacenter.name),
- "location": to_native(server.datacenter.location.name),
- "rescue_enabled": server.rescue_enabled,
- "backup_window": to_native(server.backup_window),
- "labels": server.labels,
- "status": to_native(server.status),
- }
- servers.append(prepared_server)
-
- tmp.append(
- {
- "id": to_native(network.id),
- "name": to_native(network.name),
- "ip_range": to_native(network.ip_range),
- "subnetworks": subnets,
- "routes": routes,
- "expose_routes_to_vswitch": network.expose_routes_to_vswitch,
- "servers": servers,
- "labels": network.labels,
- "delete_protection": network.protection["delete"],
- }
- )
+ if network is None:
+ continue
+
+ subnets = []
+ for subnet in network.subnets:
+ prepared_subnet = {
+ "type": subnet.type,
+ "ip_range": subnet.ip_range,
+ "network_zone": subnet.network_zone,
+ "gateway": subnet.gateway,
+ }
+ subnets.append(prepared_subnet)
+
+ routes = []
+ for route in network.routes:
+ prepared_route = {"destination": route.destination, "gateway": route.gateway}
+ routes.append(prepared_route)
+
+ servers = []
+ for server in network.servers:
+ prepared_server = {
+ "id": str(server.id),
+ "name": server.name,
+ "ipv4_address": server.public_net.ipv4.ip if server.public_net.ipv4 is not None else None,
+ "ipv6": server.public_net.ipv6.ip if server.public_net.ipv6 is not None else None,
+ "image": server.image.name if server.image is not None else None,
+ "server_type": server.server_type.name,
+ "datacenter": server.datacenter.name,
+ "location": server.datacenter.location.name,
+ "rescue_enabled": server.rescue_enabled,
+ "backup_window": server.backup_window,
+ "labels": server.labels,
+ "status": server.status,
+ }
+ servers.append(prepared_server)
+
+ tmp.append(
+ {
+ "id": str(network.id),
+ "name": network.name,
+ "ip_range": network.ip_range,
+ "subnetworks": subnets,
+ "routes": routes,
+ "expose_routes_to_vswitch": network.expose_routes_to_vswitch,
+ "servers": servers,
+ "labels": network.labels,
+ "delete_protection": network.protection["delete"],
+ }
+ )
return tmp
def get_networks(self):
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/placement_group.py b/ansible_collections/hetzner/hcloud/plugins/modules/placement_group.py
index ba26fad22..45a0cd76b 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/placement_group.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/placement_group.py
@@ -107,7 +107,6 @@ hcloud_placement_group:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import HCloudException
@@ -121,10 +120,10 @@ class AnsibleHCloudPlacementGroup(AnsibleHCloud):
def _prepare_result(self):
return {
- "id": to_native(self.hcloud_placement_group.id),
- "name": to_native(self.hcloud_placement_group.name),
+ "id": str(self.hcloud_placement_group.id),
+ "name": self.hcloud_placement_group.name,
"labels": self.hcloud_placement_group.labels,
- "type": to_native(self.hcloud_placement_group.type),
+ "type": self.hcloud_placement_group.type,
"servers": self.hcloud_placement_group.servers,
}
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/primary_ip.py b/ansible_collections/hetzner/hcloud/plugins/modules/primary_ip.py
index 607f6c7e1..08bcea493 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/primary_ip.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/primary_ip.py
@@ -35,6 +35,12 @@ options:
- Home Location of the Hetzner Cloud Primary IP.
- Required if no I(server) is given and Primary IP does not exist.
type: str
+ server:
+ description:
+ - Name or ID of the Hetzner Cloud Server the Primary IP should be assigned to.
+ - The Primary IP cannot be assigned to a running server.
+ - Required if no O(datacenter) is given and the Primary IP does not exist.
+ type: str
type:
description:
- Type of the Primary IP.
@@ -43,9 +49,9 @@ options:
type: str
auto_delete:
description:
- - Delete this Primary IP when the resource it is assigned to is deleted
+ - Delete the Primary IP when the resource it is assigned to is deleted.
type: bool
- default: no
+ default: false
delete_protection:
description:
- Protect the Primary IP for deletion.
@@ -66,22 +72,39 @@ extends_documentation_fragment:
"""
EXAMPLES = """
-- name: Create a basic IPv4 Primary IP
+- name: Create a IPv4 Primary IP
hetzner.hcloud.primary_ip:
name: my-primary-ip
datacenter: fsn1-dc14
type: ipv4
state: present
-- name: Create a basic IPv6 Primary IP
+
+- name: Create a IPv6 Primary IP
hetzner.hcloud.primary_ip:
name: my-primary-ip
datacenter: fsn1-dc14
type: ipv6
state: present
-- name: Primary IP should be absent
+
+- name: Delete a Primary IP
hetzner.hcloud.primary_ip:
name: my-primary-ip
state: absent
+
+- name: Ensure the server is stopped
+ hetzner.hcloud.server:
+ name: my-server
+ state: stopped
+- name: Create a Primary IP attached to a Server
+ hetzner.hcloud.primary_ip:
+ name: my-primary-ip
+ server: my-server
+ type: ipv4
+ state: present
+- name: Ensure the server is started
+ hetzner.hcloud.server:
+ name: my-server
+ state: started
"""
RETURN = """
@@ -127,10 +150,24 @@ hcloud_primary_ip:
sample:
key: value
mylabel: 123
+ assignee_id:
+ description: ID of the resource the Primary IP is assigned to, null if it is not assigned.
+ type: int
+ returned: always
+ sample: 1937415
+ assignee_type:
+ description: Resource type the Primary IP can be assigned to.
+ type: str
+ returned: always
+ sample: server
+ auto_delete:
+ description: Delete the Primary IP when the resource it is assigned to is deleted.
+ type: bool
+ returned: always
+ sample: false
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import HCloudException
@@ -144,13 +181,18 @@ class AnsibleHCloudPrimaryIP(AnsibleHCloud):
def _prepare_result(self):
return {
- "id": to_native(self.hcloud_primary_ip.id),
- "name": to_native(self.hcloud_primary_ip.name),
- "ip": to_native(self.hcloud_primary_ip.ip),
- "type": to_native(self.hcloud_primary_ip.type),
- "datacenter": to_native(self.hcloud_primary_ip.datacenter.name),
+ "id": str(self.hcloud_primary_ip.id),
+ "name": self.hcloud_primary_ip.name,
+ "ip": self.hcloud_primary_ip.ip,
+ "type": self.hcloud_primary_ip.type,
+ "datacenter": self.hcloud_primary_ip.datacenter.name,
"labels": self.hcloud_primary_ip.labels,
"delete_protection": self.hcloud_primary_ip.protection["delete"],
+ "assignee_id": (
+ str(self.hcloud_primary_ip.assignee_id) if self.hcloud_primary_ip.assignee_id is not None else None
+ ),
+ "assignee_type": self.hcloud_primary_ip.assignee_type,
+ "auto_delete": self.hcloud_primary_ip.auto_delete,
}
def _get_primary_ip(self):
@@ -163,23 +205,35 @@ class AnsibleHCloudPrimaryIP(AnsibleHCloud):
self.fail_json_hcloud(exception)
def _create_primary_ip(self):
- self.module.fail_on_missing_params(required_params=["type", "datacenter"])
+ self.fail_on_invalid_params(
+ required=["type", "name"],
+ required_one_of=[["server", "datacenter"]],
+ )
try:
params = {
"type": self.module.params.get("type"),
"name": self.module.params.get("name"),
- "datacenter": self.client.datacenters.get_by_name(self.module.params.get("datacenter")),
+ "auto_delete": self.module.params.get("auto_delete"),
+ "datacenter": None, # TODO: https://github.com/hetznercloud/hcloud-python/pull/363
}
+ if self.module.params.get("datacenter") is not None:
+ params["datacenter"] = self.client.datacenters.get_by_name(self.module.params.get("datacenter"))
+ elif self.module.params.get("server") is not None:
+ params["assignee_id"] = self._client_get_by_name_or_id("servers", self.module.params.get("server")).id
+
if self.module.params.get("labels") is not None:
params["labels"] = self.module.params.get("labels")
if not self.module.check_mode:
resp = self.client.primary_ips.create(**params)
+ if resp.action is not None:
+ resp.action.wait_until_finished()
self.hcloud_primary_ip = resp.primary_ip
delete_protection = self.module.params.get("delete_protection")
if delete_protection is not None:
- self.hcloud_primary_ip.change_protection(delete=delete_protection).wait_until_finished()
+ action = self.hcloud_primary_ip.change_protection(delete=delete_protection)
+ action.wait_until_finished()
except HCloudException as exception:
self.fail_json_hcloud(exception)
self._mark_as_changed()
@@ -187,16 +241,26 @@ class AnsibleHCloudPrimaryIP(AnsibleHCloud):
def _update_primary_ip(self):
try:
+ changes = {}
+
+ auto_delete = self.module.params.get("auto_delete")
+ if auto_delete is not None and auto_delete != self.hcloud_primary_ip.auto_delete:
+ changes["auto_delete"] = auto_delete
+
labels = self.module.params.get("labels")
if labels is not None and labels != self.hcloud_primary_ip.labels:
+ changes["labels"] = labels
+
+ if changes:
if not self.module.check_mode:
- self.hcloud_primary_ip.update(labels=labels)
+ self.hcloud_primary_ip.update(**changes)
self._mark_as_changed()
delete_protection = self.module.params.get("delete_protection")
if delete_protection is not None and delete_protection != self.hcloud_primary_ip.protection["delete"]:
if not self.module.check_mode:
- self.hcloud_primary_ip.change_protection(delete=delete_protection).wait_until_finished()
+ action = self.hcloud_primary_ip.change_protection(delete=delete_protection)
+ action.wait_until_finished()
self._mark_as_changed()
self._get_primary_ip()
@@ -228,6 +292,7 @@ class AnsibleHCloudPrimaryIP(AnsibleHCloud):
id={"type": "int"},
name={"type": "str"},
datacenter={"type": "str"},
+ server={"type": "str"},
auto_delete={"type": "bool", "default": False},
type={"choices": ["ipv4", "ipv6"]},
labels={"type": "dict"},
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/primary_ip_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/primary_ip_info.py
index c0bfdbb35..72e359ae2 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/primary_ip_info.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/primary_ip_info.py
@@ -117,10 +117,14 @@ hcloud_primary_ip_info:
description: True if the Primary IP is protected for deletion
returned: always
type: bool
+ auto_delete:
+ description: Delete the Primary IP when the resource it is assigned to is deleted.
+ type: bool
+ returned: always
+ sample: false
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import HCloudException
@@ -136,26 +140,24 @@ class AnsibleHCloudPrimaryIPInfo(AnsibleHCloud):
tmp = []
for primary_ip in self.hcloud_primary_ip_info:
- if primary_ip is not None:
- dns_ptr = None
- if len(primary_ip.dns_ptr) > 0:
- dns_ptr = primary_ip.dns_ptr[0]["dns_ptr"]
- tmp.append(
- {
- "id": to_native(primary_ip.id),
- "name": to_native(primary_ip.name),
- "ip": to_native(primary_ip.ip),
- "type": to_native(primary_ip.type),
- "assignee_id": (
- to_native(primary_ip.assignee_id) if primary_ip.assignee_id is not None else None
- ),
- "assignee_type": to_native(primary_ip.assignee_type),
- "home_location": to_native(primary_ip.datacenter.name),
- "dns_ptr": to_native(dns_ptr) if dns_ptr is not None else None,
- "labels": primary_ip.labels,
- "delete_protection": primary_ip.protection["delete"],
- }
- )
+ if primary_ip is None:
+ continue
+
+ tmp.append(
+ {
+ "id": str(primary_ip.id),
+ "name": primary_ip.name,
+ "ip": primary_ip.ip,
+ "type": primary_ip.type,
+ "assignee_id": str(primary_ip.assignee_id) if primary_ip.assignee_id is not None else None,
+ "assignee_type": primary_ip.assignee_type,
+ "auto_delete": primary_ip.auto_delete,
+ "home_location": primary_ip.datacenter.name,
+ "dns_ptr": primary_ip.dns_ptr[0]["dns_ptr"] if len(primary_ip.dns_ptr) else None,
+ "labels": primary_ip.labels,
+ "delete_protection": primary_ip.protection["delete"],
+ }
+ )
return tmp
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/rdns.py b/ansible_collections/hetzner/hcloud/plugins/modules/rdns.py
index b2decdec8..4e21f3e92 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/rdns.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/rdns.py
@@ -136,7 +136,6 @@ import ipaddress
from typing import Any
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import HCloudException
@@ -157,18 +156,18 @@ class AnsibleHCloudReverseDNS(AnsibleHCloud):
"server": None,
"floating_ip": None,
"load_balancer": None,
- "ip_address": to_native(self.hcloud_rdns["ip_address"]),
- "dns_ptr": to_native(self.hcloud_rdns["dns_ptr"]),
+ "ip_address": self.hcloud_rdns["ip_address"],
+ "dns_ptr": self.hcloud_rdns["dns_ptr"],
}
if self.module.params.get("server"):
- result["server"] = to_native(self.hcloud_resource.name)
+ result["server"] = self.hcloud_resource.name
elif self.module.params.get("floating_ip"):
- result["floating_ip"] = to_native(self.hcloud_resource.name)
+ result["floating_ip"] = self.hcloud_resource.name
elif self.module.params.get("load_balancer"):
- result["load_balancer"] = to_native(self.hcloud_resource.name)
+ result["load_balancer"] = self.hcloud_resource.name
elif self.module.params.get("primary_ip"):
- result["primary_ip"] = to_native(self.hcloud_resource.name)
+ result["primary_ip"] = self.hcloud_resource.name
return result
def _get_resource(self):
@@ -277,7 +276,8 @@ class AnsibleHCloudReverseDNS(AnsibleHCloud):
if not self.module.check_mode:
try:
- self.hcloud_resource.change_dns_ptr(**params).wait_until_finished()
+ action = self.hcloud_resource.change_dns_ptr(**params)
+ action.wait_until_finished()
except HCloudException as exception:
self.fail_json_hcloud(exception)
self._mark_as_changed()
@@ -294,7 +294,8 @@ class AnsibleHCloudReverseDNS(AnsibleHCloud):
if not self.module.check_mode:
try:
- self.hcloud_resource.change_dns_ptr(**params).wait_until_finished()
+ action = self.hcloud_resource.change_dns_ptr(**params)
+ action.wait_until_finished()
except HCloudException as exception:
self.fail_json_hcloud(exception)
self._mark_as_changed()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/route.py b/ansible_collections/hetzner/hcloud/plugins/modules/route.py
index 3c96a7382..37ff50b07 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/route.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/route.py
@@ -86,7 +86,6 @@ hcloud_route:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import HCloudException
@@ -101,8 +100,8 @@ class AnsibleHCloudRoute(AnsibleHCloud):
def _prepare_result(self):
return {
- "network": to_native(self.hcloud_network.name),
- "destination": to_native(self.hcloud_route.destination),
+ "network": self.hcloud_network.name,
+ "destination": self.hcloud_route.destination,
"gateway": self.hcloud_route.gateway,
}
@@ -130,7 +129,8 @@ class AnsibleHCloudRoute(AnsibleHCloud):
if not self.module.check_mode:
try:
- self.hcloud_network.add_route(route=route).wait_until_finished()
+ action = self.hcloud_network.add_route(route=route)
+ action.wait_until_finished()
except HCloudException as exception:
self.fail_json_hcloud(exception)
@@ -150,7 +150,8 @@ class AnsibleHCloudRoute(AnsibleHCloud):
if self.hcloud_route is not None and self.hcloud_network is not None:
if not self.module.check_mode:
try:
- self.hcloud_network.delete_route(self.hcloud_route).wait_until_finished()
+ action = self.hcloud_network.delete_route(self.hcloud_route)
+ action.wait_until_finished()
except HCloudException as exception:
self.fail_json_hcloud(exception)
self._mark_as_changed()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/server.py b/ansible_collections/hetzner/hcloud/plugins/modules/server.py
index f5cadb807..d7bae3fc1 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/server.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/server.py
@@ -22,50 +22,58 @@ author:
options:
id:
description:
- - The ID of the Hetzner Cloud server to manage.
- - Only required if no server I(name) is given
+ - ID of the Hetzner Cloud Server to manage.
+ - Only required if no server O(name) is given
type: int
name:
description:
- - The Name of the Hetzner Cloud server to manage.
- - Only required if no server I(id) is given or a server does not exist.
+ - Name of the Hetzner Cloud Server to manage.
+ - Only required if no server O(id) is given or a server does not exist.
type: str
server_type:
description:
- - The Server Type of the Hetzner Cloud server to manage.
+ - Hetzner Cloud Server Type (name or ID) of the server.
- Required if server does not exist.
type: str
ssh_keys:
description:
- - List of SSH key names
- - The key names correspond to the SSH keys configured for your
- Hetzner Cloud account access.
+ - List of Hetzner Cloud SSH Keys (name or ID) to create the server with.
+ - Only used during the server creation.
type: list
elements: str
volumes:
description:
- - List of Volumes IDs that should be attached to the server on server creation.
+ - List of Hetzner Cloud Volumes (name or ID) that should be attached to the server.
+ - Only used during the server creation.
type: list
elements: str
firewalls:
description:
- - List of Firewall IDs that should be attached to the server on server creation.
+ - List of Hetzner Cloud Firewalls (name or ID) that should be attached to the server.
type: list
elements: str
image:
description:
- - Image the server should be created from.
- - Required if server does not exist.
+ - Hetzner Cloud Image (name or ID) to create the server from.
+ - Required if server does not exist or when O(state=rebuild).
type: str
+ image_allow_deprecated:
+ description:
+ - Allows the creation of servers with deprecated images.
+ type: bool
+ default: false
+ aliases: [allow_deprecated_image]
location:
description:
- - Location of Server.
- - Required if no I(datacenter) is given and server does not exist.
+ - Hetzner Cloud Location (name or ID) to create the server in.
+ - Required if no O(datacenter) is given and server does not exist.
+ - Only used during the server creation.
type: str
datacenter:
description:
- - Datacenter of Server.
- - Required if no I(location) is given and server does not exist.
+ - Hetzner Cloud Datacenter (name or ID) to create the server in.
+ - Required if no O(location) is given and server does not exist.
+ - Only used during the server creation.
type: str
backups:
description:
@@ -79,50 +87,42 @@ options:
default: false
enable_ipv4:
description:
- - Enables the public ipv4 address
+ - Enables the public ipv4 address.
type: bool
default: true
enable_ipv6:
description:
- - Enables the public ipv6 address
+ - Enables the public ipv6 address.
type: bool
default: true
ipv4:
description:
- - ID of the ipv4 Primary IP to use. If omitted and enable_ipv4 is true, a new ipv4 Primary IP will automatically be created
+ - Hetzner Cloud Primary IPv4 (name or ID) to use.
+ - If omitted and O(enable_ipv4=true), a new ipv4 Primary IP will automatically be created.
type: str
ipv6:
description:
- - ID of the ipv6 Primary IP to use. If omitted and enable_ipv6 is true, a new ipv6 Primary IP will automatically be created.
+ - Hetzner Cloud Primary IPv6 (name or ID) to use.
+ - If omitted and O(enable_ipv6=true), a new ipv6 Primary IP will automatically be created.
type: str
private_networks:
description:
- - List of private networks the server is attached to (name or ID)
+ - List of Hetzner Cloud Networks (name or ID) the server should be attached to.
- If None, private networks are left as they are (e.g. if previously added by hcloud_server_network),
if it has any other value (including []), only those networks are attached to the server.
type: list
elements: str
- force_upgrade:
- description:
- - Deprecated
- - Force the upgrade of the server.
- - Power off the server if it is running on upgrade.
- type: bool
force:
description:
- Force the update of the server.
- - May power off the server if update.
- type: bool
- default: false
- allow_deprecated_image:
- description:
- - Allows the creation of servers with deprecated images.
+ - May power off the server if update is applied.
type: bool
default: false
+ aliases: [force_upgrade]
user_data:
description:
- User Data to be passed to the server on creation.
- - Only used if server does not exist.
+ - Only used during the server creation.
type: str
rescue_mode:
description:
@@ -135,16 +135,16 @@ options:
delete_protection:
description:
- Protect the Server for deletion.
- - Needs to be the same as I(rebuild_protection).
+ - Needs to be the same as O(rebuild_protection).
type: bool
rebuild_protection:
description:
- Protect the Server for rebuild.
- - Needs to be the same as I(delete_protection).
+ - Needs to be the same as O(delete_protection).
type: bool
placement_group:
description:
- - Placement Group of the server.
+ - Hetzner Cloud Placement Group (name or ID) to create the server in.
type: str
state:
description:
@@ -336,9 +336,9 @@ hcloud_server:
"""
from datetime import datetime, timedelta, timezone
+from typing import TYPE_CHECKING, Literal
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import HCloudException
@@ -348,8 +348,14 @@ from ..module_utils.vendor.hcloud.servers import (
Server,
ServerCreatePublicNetwork,
)
-from ..module_utils.vendor.hcloud.ssh_keys import SSHKey
-from ..module_utils.vendor.hcloud.volumes import Volume
+
+if TYPE_CHECKING:
+ from ..module_utils.vendor.hcloud.actions import BoundAction
+ from ..module_utils.vendor.hcloud.firewalls import BoundFirewall
+ from ..module_utils.vendor.hcloud.networks import BoundNetwork
+ from ..module_utils.vendor.hcloud.placement_groups import BoundPlacementGroup
+ from ..module_utils.vendor.hcloud.primary_ips import PrimaryIP
+ from ..module_utils.vendor.hcloud.server_types import ServerType
class AnsibleHCloudServer(AnsibleHCloud):
@@ -358,38 +364,31 @@ class AnsibleHCloudServer(AnsibleHCloud):
hcloud_server: BoundServer | None = None
def _prepare_result(self):
- image = None if self.hcloud_server.image is None else to_native(self.hcloud_server.image.name)
- placement_group = (
- None if self.hcloud_server.placement_group is None else to_native(self.hcloud_server.placement_group.name)
- )
- ipv4_address = (
- None if self.hcloud_server.public_net.ipv4 is None else to_native(self.hcloud_server.public_net.ipv4.ip)
- )
- ipv6 = None if self.hcloud_server.public_net.ipv6 is None else to_native(self.hcloud_server.public_net.ipv6.ip)
- backup_window = (
- None if self.hcloud_server.backup_window is None else to_native(self.hcloud_server.backup_window)
- )
return {
- "id": to_native(self.hcloud_server.id),
- "name": to_native(self.hcloud_server.name),
- "created": to_native(self.hcloud_server.created.isoformat()),
- "ipv4_address": ipv4_address,
- "ipv6": ipv6,
- "private_networks": [to_native(net.network.name) for net in self.hcloud_server.private_net],
+ "id": str(self.hcloud_server.id),
+ "name": self.hcloud_server.name,
+ "created": self.hcloud_server.created.isoformat(),
+ "ipv4_address": (
+ self.hcloud_server.public_net.ipv4.ip if self.hcloud_server.public_net.ipv4 is not None else None
+ ),
+ "ipv6": self.hcloud_server.public_net.ipv6.ip if self.hcloud_server.public_net.ipv6 is not None else None,
+ "private_networks": [net.network.name for net in self.hcloud_server.private_net],
"private_networks_info": [
- {"name": to_native(net.network.name), "ip": net.ip} for net in self.hcloud_server.private_net
+ {"name": net.network.name, "ip": net.ip} for net in self.hcloud_server.private_net
],
- "image": image,
- "server_type": to_native(self.hcloud_server.server_type.name),
- "datacenter": to_native(self.hcloud_server.datacenter.name),
- "location": to_native(self.hcloud_server.datacenter.location.name),
- "placement_group": placement_group,
+ "image": self.hcloud_server.image.name if self.hcloud_server.image is not None else None,
+ "server_type": self.hcloud_server.server_type.name,
+ "datacenter": self.hcloud_server.datacenter.name,
+ "location": self.hcloud_server.datacenter.location.name,
+ "placement_group": (
+ self.hcloud_server.placement_group.name if self.hcloud_server.placement_group is not None else None
+ ),
"rescue_enabled": self.hcloud_server.rescue_enabled,
- "backup_window": backup_window,
+ "backup_window": self.hcloud_server.backup_window,
"labels": self.hcloud_server.labels,
"delete_protection": self.hcloud_server.protection["delete"],
"rebuild_protection": self.hcloud_server.protection["rebuild"],
- "status": to_native(self.hcloud_server.status),
+ "status": self.hcloud_server.status,
}
def _get_server(self):
@@ -405,73 +404,76 @@ class AnsibleHCloudServer(AnsibleHCloud):
self.module.fail_on_missing_params(required_params=["name", "server_type", "image"])
server_type = self._get_server_type()
+ image = self._get_image(server_type)
params = {
"name": self.module.params.get("name"),
+ "labels": self.module.params.get("labels"),
"server_type": server_type,
+ "image": image,
"user_data": self.module.params.get("user_data"),
- "labels": self.module.params.get("labels"),
- "image": self._get_image(server_type),
- "placement_group": self._get_placement_group(),
"public_net": ServerCreatePublicNetwork(
enable_ipv4=self.module.params.get("enable_ipv4"),
enable_ipv6=self.module.params.get("enable_ipv6"),
),
}
+ if self.module.params.get("placement_group") is not None:
+ params["placement_group"] = self._client_get_by_name_or_id(
+ "placement_groups", self.module.params.get("placement_group")
+ )
+
if self.module.params.get("ipv4") is not None:
- primary_ip = self.client.primary_ips.get_by_name(self.module.params.get("ipv4"))
- if not primary_ip:
- primary_ip = self.client.primary_ips.get_by_id(self.module.params.get("ipv4"))
- params["public_net"].ipv4 = primary_ip
+ params["public_net"].ipv4 = self._client_get_by_name_or_id("primary_ips", self.module.params.get("ipv4"))
if self.module.params.get("ipv6") is not None:
- primary_ip = self.client.primary_ips.get_by_name(self.module.params.get("ipv6"))
- if not primary_ip:
- primary_ip = self.client.primary_ips.get_by_id(self.module.params.get("ipv6"))
- params["public_net"].ipv6 = primary_ip
+ params["public_net"].ipv6 = self._client_get_by_name_or_id("primary_ips", self.module.params.get("ipv6"))
if self.module.params.get("private_networks") is not None:
- _networks = []
- for network_name_or_id in self.module.params.get("private_networks"):
- _networks.append(
- self.client.networks.get_by_name(network_name_or_id)
- or self.client.networks.get_by_id(network_name_or_id)
- )
- params["networks"] = _networks
+ params["networks"] = [
+ self._client_get_by_name_or_id("networks", name_or_id)
+ for name_or_id in self.module.params.get("private_networks")
+ ]
if self.module.params.get("ssh_keys") is not None:
- params["ssh_keys"] = [SSHKey(name=ssh_key_name) for ssh_key_name in self.module.params.get("ssh_keys")]
+ params["ssh_keys"] = [
+ self._client_get_by_name_or_id("ssh_keys", name_or_id)
+ for name_or_id in self.module.params.get("ssh_keys")
+ ]
if self.module.params.get("volumes") is not None:
- params["volumes"] = [Volume(id=volume_id) for volume_id in self.module.params.get("volumes")]
+ params["volumes"] = [
+ self._client_get_by_name_or_id("volumes", name_or_id)
+ for name_or_id in self.module.params.get("volumes")
+ ]
+
if self.module.params.get("firewalls") is not None:
- params["firewalls"] = []
- for firewall_param in self.module.params.get("firewalls"):
- firewall = self.client.firewalls.get_by_name(firewall_param)
- if firewall is not None:
- # When firewall name is not available look for id instead
- params["firewalls"].append(firewall)
- else:
- params["firewalls"].append(self.client.firewalls.get_by_id(firewall_param))
+ params["firewalls"] = [
+ self._client_get_by_name_or_id("firewalls", name_or_id)
+ for name_or_id in self.module.params.get("firewalls")
+ ]
if self.module.params.get("location") is None and self.module.params.get("datacenter") is None:
# When not given, the API will choose the location.
params["location"] = None
params["datacenter"] = None
elif self.module.params.get("location") is not None and self.module.params.get("datacenter") is None:
- params["location"] = self.client.locations.get_by_name(self.module.params.get("location"))
+ params["location"] = self._client_get_by_name_or_id("locations", self.module.params.get("location"))
elif self.module.params.get("location") is None and self.module.params.get("datacenter") is not None:
- params["datacenter"] = self.client.datacenters.get_by_name(self.module.params.get("datacenter"))
+ params["datacenter"] = self._client_get_by_name_or_id("datacenters", self.module.params.get("datacenter"))
if self.module.params.get("state") == "stopped":
params["start_after_create"] = False
+
if not self.module.check_mode:
try:
resp = self.client.servers.create(**params)
self.result["root_password"] = resp.root_password
- resp.action.wait_until_finished(max_retries=1000)
- [action.wait_until_finished() for action in resp.next_actions]
+ # Action should take 60 to 90 seconds on average, but can be >10m when creating a
+ # server from a custom images
+ resp.action.wait_until_finished(max_retries=1800)
+ for action in resp.next_actions:
+ action.wait_until_finished()
rescue_mode = self.module.params.get("rescue_mode")
if rescue_mode:
@@ -481,40 +483,35 @@ class AnsibleHCloudServer(AnsibleHCloud):
backups = self.module.params.get("backups")
if backups:
self._get_server()
- self.hcloud_server.enable_backup().wait_until_finished()
+ action = self.hcloud_server.enable_backup()
+ action.wait_until_finished()
delete_protection = self.module.params.get("delete_protection")
rebuild_protection = self.module.params.get("rebuild_protection")
if delete_protection is not None and rebuild_protection is not None:
self._get_server()
- self.hcloud_server.change_protection(
+ action = self.hcloud_server.change_protection(
delete=delete_protection,
rebuild=rebuild_protection,
- ).wait_until_finished()
+ )
+ action.wait_until_finished()
except HCloudException as exception:
self.fail_json_hcloud(exception)
self._mark_as_changed()
self._get_server()
- def _get_image(self, server_type):
- image_resp = self.client.images.get_list(
+ def _get_image(self, server_type: ServerType):
+ image = self.client.images.get_by_name_and_architecture(
name=self.module.params.get("image"),
architecture=server_type.architecture,
include_deprecated=True,
)
- images = getattr(image_resp, "images")
- image = None
- if images is not None and len(images) > 0:
- # If image name is not available look for id instead
- image = images[0]
- else:
- try:
- image = self.client.images.get_by_id(self.module.params.get("image"))
- except HCloudException as exception:
- self.fail_json_hcloud(exception, msg=f"Image {self.module.params.get('image')} was not found")
+ if image is None:
+ image = self.client.images.get_by_id(self.module.params.get("image"))
+
if image.deprecated is not None:
available_until = image.deprecated + timedelta(days=90)
- if self.module.params.get("allow_deprecated_image"):
+ if self.module.params.get("image_allow_deprecated"):
self.module.warn(
f"You try to use a deprecated image. The image {image.name} will "
f"continue to be available until {available_until.strftime('%Y-%m-%d')}."
@@ -524,27 +521,18 @@ class AnsibleHCloudServer(AnsibleHCloud):
msg=(
f"You try to use a deprecated image. The image {image.name} will "
f"continue to be available until {available_until.strftime('%Y-%m-%d')}. "
- "If you want to use this image use allow_deprecated_image=true."
+ "If you want to use this image use image_allow_deprecated=true."
)
)
return image
- def _get_server_type(self):
- server_type = self.client.server_types.get_by_name(self.module.params.get("server_type"))
- if server_type is None:
- try:
- server_type = self.client.server_types.get_by_id(self.module.params.get("server_type"))
- except HCloudException as exception:
- self.fail_json_hcloud(
- exception,
- msg=f"server_type {self.module.params.get('server_type')} was not found",
- )
+ def _get_server_type(self) -> ServerType:
+ server_type = self._client_get_by_name_or_id("server_types", self.module.params.get("server_type"))
self._check_and_warn_deprecated_server(server_type)
-
return server_type
- def _check_and_warn_deprecated_server(self, server_type):
+ def _check_and_warn_deprecated_server(self, server_type: ServerType) -> None:
if server_type.deprecation is None:
return
@@ -567,42 +555,16 @@ class AnsibleHCloudServer(AnsibleHCloud):
"the server_type parameter on the hetzner.hcloud.server module."
)
- def _get_placement_group(self):
- if self.module.params.get("placement_group") is None:
- return None
-
- placement_group = self.client.placement_groups.get_by_name(self.module.params.get("placement_group"))
- if placement_group is None:
- try:
- placement_group = self.client.placement_groups.get_by_id(self.module.params.get("placement_group"))
- except HCloudException as exception:
- self.fail_json_hcloud(
- exception,
- msg=f"placement_group {self.module.params.get('placement_group')} was not found",
- )
-
- return placement_group
-
- def _get_primary_ip(self, field):
- if self.module.params.get(field) is None:
- return None
-
- primary_ip = self.client.primary_ips.get_by_name(self.module.params.get(field))
- if primary_ip is None:
- try:
- primary_ip = self.client.primary_ips.get_by_id(self.module.params.get(field))
- except HCloudException as exception:
- self.fail_json_hcloud(exception, msg=f"primary_ip {self.module.params.get(field)} was not found")
-
- return primary_ip
-
- def _update_server(self):
- if "force_upgrade" in self.module.params and self.module.params.get("force_upgrade") is not None:
- self.module.warn("force_upgrade is deprecated, use force instead")
-
+ def _update_server(self) -> None:
try:
previous_server_status = self.hcloud_server.status
+ labels = self.module.params.get("labels")
+ if labels is not None and labels != self.hcloud_server.labels:
+ if not self.module.check_mode:
+ self.hcloud_server.update(labels=labels)
+ self._mark_as_changed()
+
rescue_mode = self.module.params.get("rescue_mode")
if rescue_mode and self.hcloud_server.rescue_enabled is False:
if not self.module.check_mode:
@@ -610,167 +572,39 @@ class AnsibleHCloudServer(AnsibleHCloud):
self._mark_as_changed()
elif not rescue_mode and self.hcloud_server.rescue_enabled is True:
if not self.module.check_mode:
- self.hcloud_server.disable_rescue().wait_until_finished()
+ action = self.hcloud_server.disable_rescue()
+ action.wait_until_finished()
self._mark_as_changed()
backups = self.module.params.get("backups")
if backups and self.hcloud_server.backup_window is None:
if not self.module.check_mode:
- self.hcloud_server.enable_backup().wait_until_finished()
+ action = self.hcloud_server.enable_backup()
+ action.wait_until_finished()
self._mark_as_changed()
elif backups is not None and not backups and self.hcloud_server.backup_window is not None:
if not self.module.check_mode:
- self.hcloud_server.disable_backup().wait_until_finished()
+ action = self.hcloud_server.disable_backup()
+ action.wait_until_finished()
self._mark_as_changed()
- labels = self.module.params.get("labels")
- if labels is not None and labels != self.hcloud_server.labels:
- if not self.module.check_mode:
- self.hcloud_server.update(labels=labels)
- self._mark_as_changed()
+ if self.module.params.get("firewalls") is not None:
+ self._update_server_firewalls()
- wanted_firewalls = self.module.params.get("firewalls")
- if wanted_firewalls is not None:
- # Removing existing but not wanted firewalls
- for current_firewall in self.hcloud_server.public_net.firewalls:
- if current_firewall.firewall.name not in wanted_firewalls:
- self._mark_as_changed()
- if self.module.check_mode:
- continue
-
- firewall_resource = FirewallResource(type="server", server=self.hcloud_server)
- actions = self.client.firewalls.remove_from_resources(
- current_firewall.firewall,
- [firewall_resource],
- )
- for action in actions:
- action.wait_until_finished()
-
- # Adding wanted firewalls that doesn't exist yet
- for firewall_name in wanted_firewalls:
- found = False
- for firewall in self.hcloud_server.public_net.firewalls:
- if firewall.firewall.name == firewall_name:
- found = True
- break
-
- if not found:
- self._mark_as_changed()
- if not self.module.check_mode:
- firewall = self.client.firewalls.get_by_name(firewall_name)
- if firewall is None:
- self.module.fail_json(msg=f"firewall {firewall_name} was not found")
- firewall_resource = FirewallResource(type="server", server=self.hcloud_server)
- actions = self.client.firewalls.apply_to_resources(firewall, [firewall_resource])
- for action in actions:
- action.wait_until_finished()
-
- if "placement_group" in self.module.params:
- if self.module.params["placement_group"] is None and self.hcloud_server.placement_group is not None:
- if not self.module.check_mode:
- self.hcloud_server.remove_from_placement_group().wait_until_finished()
- self._mark_as_changed()
- else:
- placement_group = self._get_placement_group()
- if placement_group is not None and (
- self.hcloud_server.placement_group is None
- or self.hcloud_server.placement_group.id != placement_group.id
- ):
- self.stop_server_if_forced()
- if not self.module.check_mode:
- self.hcloud_server.add_to_placement_group(placement_group).wait_until_finished()
- self._mark_as_changed()
-
- if "ipv4" in self.module.params:
- if (
- self.module.params["ipv4"] is None
- and self.hcloud_server.public_net.primary_ipv4 is not None
- and not self.module.params.get("enable_ipv4")
- ):
- self.stop_server_if_forced()
- if not self.module.check_mode:
- self.hcloud_server.public_net.primary_ipv4.unassign().wait_until_finished()
- self._mark_as_changed()
- else:
- primary_ip = self._get_primary_ip("ipv4")
- if primary_ip is not None and (
- self.hcloud_server.public_net.primary_ipv4 is None
- or self.hcloud_server.public_net.primary_ipv4.id != primary_ip.id
- ):
- self.stop_server_if_forced()
- if not self.module.check_mode:
- if self.hcloud_server.public_net.primary_ipv4:
- self.hcloud_server.public_net.primary_ipv4.unassign().wait_until_finished()
- primary_ip.assign(self.hcloud_server.id, "server").wait_until_finished()
- self._mark_as_changed()
- if "ipv6" in self.module.params:
- if (
- (self.module.params["ipv6"] is None or self.module.params["ipv6"] == "")
- and self.hcloud_server.public_net.primary_ipv6 is not None
- and not self.module.params.get("enable_ipv6")
- ):
- self.stop_server_if_forced()
- if not self.module.check_mode:
- self.hcloud_server.public_net.primary_ipv6.unassign().wait_until_finished()
- self._mark_as_changed()
- else:
- primary_ip = self._get_primary_ip("ipv6")
- if primary_ip is not None and (
- self.hcloud_server.public_net.primary_ipv6 is None
- or self.hcloud_server.public_net.primary_ipv6.id != primary_ip.id
- ):
- self.stop_server_if_forced()
- if not self.module.check_mode:
- if self.hcloud_server.public_net.primary_ipv6 is not None:
- self.hcloud_server.public_net.primary_ipv6.unassign().wait_until_finished()
- primary_ip.assign(self.hcloud_server.id, "server").wait_until_finished()
- self._mark_as_changed()
- if "private_networks" in self.module.params and self.module.params["private_networks"] is not None:
- if not bool(self.module.params["private_networks"]):
- # This handles None, "" and []
- networks_target = {}
- else:
- _networks = {}
- for network_name_or_id in self.module.params.get("private_networks"):
- _found_network = self.client.networks.get_by_name(
- network_name_or_id
- ) or self.client.networks.get_by_id(network_name_or_id)
- _networks.update({_found_network.id: _found_network})
- networks_target = _networks
- networks_is = dict()
- for p_network in self.hcloud_server.private_net:
- networks_is.update({p_network.network.id: p_network.network})
- for network_id in set(list(networks_is) + list(networks_target)):
- if network_id in networks_is and network_id not in networks_target:
- self.stop_server_if_forced()
- if not self.module.check_mode:
- self.hcloud_server.detach_from_network(networks_is[network_id]).wait_until_finished()
- self._mark_as_changed()
- elif network_id in networks_target and network_id not in networks_is:
- self.stop_server_if_forced()
- if not self.module.check_mode:
- self.hcloud_server.attach_to_network(networks_target[network_id]).wait_until_finished()
- self._mark_as_changed()
-
- server_type = self.module.params.get("server_type")
- if server_type is not None:
- if self.hcloud_server.server_type.name == server_type:
- # Check if we should warn for using an deprecated server type
- self._check_and_warn_deprecated_server(self.hcloud_server.server_type)
-
- else:
- # Server type should be changed
- self.stop_server_if_forced()
-
- timeout = 100
- if self.module.params.get("upgrade_disk"):
- timeout = 1000 # When we upgrade the disk to the resize progress takes some more time.
- if not self.module.check_mode:
- self.hcloud_server.change_type(
- server_type=self._get_server_type(),
- upgrade_disk=self.module.params.get("upgrade_disk"),
- ).wait_until_finished(timeout)
- self._mark_as_changed()
+ if self.module.params.get("placement_group") is not None:
+ self._update_server_placement_group()
+
+ if self.module.params.get("ipv4") is not None:
+ self._update_server_ip("ipv4")
+
+ if self.module.params.get("ipv6") is not None:
+ self._update_server_ip("ipv6")
+
+ if self.module.params.get("private_networks") is not None:
+ self._update_server_networks()
+
+ if self.module.params.get("server_type") is not None:
+ self._update_server_server_type()
if not self.module.check_mode and (
(self.module.params.get("state") == "present" and previous_server_status == Server.STATUS_RUNNING)
@@ -785,15 +619,197 @@ class AnsibleHCloudServer(AnsibleHCloud):
or rebuild_protection != self.hcloud_server.protection["rebuild"]
):
if not self.module.check_mode:
- self.hcloud_server.change_protection(
+ action = self.hcloud_server.change_protection(
delete=delete_protection,
rebuild=rebuild_protection,
- ).wait_until_finished()
+ )
+ action.wait_until_finished()
self._mark_as_changed()
self._get_server()
except HCloudException as exception:
self.fail_json_hcloud(exception)
+ def _update_server_placement_group(self) -> None:
+ current: BoundPlacementGroup | None = self.hcloud_server.placement_group
+ wanted = self.module.params.get("placement_group")
+
+ # Return if nothing changed
+ if current is not None and current.has_id_or_name(wanted):
+ return
+
+ # Fetch resource if parameter is truthy
+ if wanted:
+ placement_group = self._client_get_by_name_or_id("placement_groups", wanted)
+
+ # Remove if current is defined
+ if current is not None:
+ if not self.module.check_mode:
+ action = self.hcloud_server.remove_from_placement_group()
+ action.wait_until_finished()
+ self._mark_as_changed()
+
+ # Return if parameter is falsy
+ if not wanted:
+ return
+
+ # Assign new
+ self.stop_server_if_forced()
+ if not self.module.check_mode:
+ action = self.hcloud_server.add_to_placement_group(placement_group)
+ action.wait_until_finished()
+ self._mark_as_changed()
+
+ def _update_server_server_type(self) -> None:
+ current: ServerType = self.hcloud_server.server_type
+ wanted = self.module.params.get("server_type")
+
+ # Return if nothing changed
+ if current.has_id_or_name(wanted):
+ # Check if we should warn for using an deprecated server type
+ self._check_and_warn_deprecated_server(self.hcloud_server.server_type)
+ return
+
+ self.stop_server_if_forced()
+
+ upgrade_disk = self.module.params.get("upgrade_disk")
+ # Upgrading a server takes 160 seconds on average, upgrading the disk should
+ # take more time
+ upgrade_timeout = 600 if upgrade_disk else 180
+
+ if not self.module.check_mode:
+ action = self.hcloud_server.change_type(
+ server_type=self._get_server_type(),
+ upgrade_disk=upgrade_disk,
+ )
+ action.wait_until_finished(max_retries=upgrade_timeout)
+ self._mark_as_changed()
+
+ def _update_server_ip(self, kind: Literal["ipv4", "ipv6"]) -> None:
+ current: PrimaryIP | None = getattr(self.hcloud_server.public_net, f"primary_{kind}")
+ wanted = self.module.params.get(kind)
+ enable = self.module.params.get(f"enable_{kind}")
+
+ # Return if nothing changed
+ if current is not None and current.has_id_or_name(wanted) and enable:
+ return
+
+ # Fetch resource if parameter is truthy
+ if wanted:
+ primary_ip = self._client_get_by_name_or_id("primary_ips", wanted)
+
+ # Remove if current is defined
+ if current is not None:
+ self.stop_server_if_forced()
+ if not self.module.check_mode:
+ action = self.client.primary_ips.unassign(current)
+ action.wait_until_finished()
+ self._mark_as_changed()
+
+ # Return if parameter is falsy or resource is disabled
+ if not wanted or not enable:
+ return
+
+ # Assign new
+ self.stop_server_if_forced()
+ if not self.module.check_mode:
+ action = self.client.primary_ips.assign(
+ primary_ip,
+ assignee_id=self.hcloud_server.id,
+ assignee_type="server",
+ )
+ action.wait_until_finished()
+ self._mark_as_changed()
+
+ def _update_server_networks(self) -> None:
+ current: list[BoundNetwork] = [item.network for item in self.hcloud_server.private_net]
+ wanted: list[BoundNetwork] = [
+ self._client_get_by_name_or_id("networks", name_or_id)
+ for name_or_id in self.module.params.get("private_networks")
+ ]
+
+ current_ids = {item.id for item in current}
+ wanted_ids = {item.id for item in wanted}
+
+ # Removing existing but not wanted networks
+ actions: list[BoundAction] = []
+ for current_network in current:
+ if current_network.id in wanted_ids:
+ continue
+
+ self._mark_as_changed()
+ if self.module.check_mode:
+ continue
+
+ actions.append(self.hcloud_server.detach_from_network(current_network))
+
+ for action in actions:
+ action.wait_until_finished()
+
+ # Adding wanted networks that doesn't exist yet
+ actions: list[BoundAction] = []
+ for wanted_network in wanted:
+ if wanted_network.id in current_ids:
+ continue
+
+ self._mark_as_changed()
+ if self.module.check_mode:
+ continue
+
+ actions.append(self.hcloud_server.attach_to_network(wanted_network))
+
+ for action in actions:
+ action.wait_until_finished()
+
+ def _update_server_firewalls(self) -> None:
+ current: list[BoundFirewall] = [item.firewall for item in self.hcloud_server.public_net.firewalls]
+ wanted: list[BoundFirewall] = [
+ self._client_get_by_name_or_id("firewalls", name_or_id)
+ for name_or_id in self.module.params.get("firewalls")
+ ]
+
+ current_ids = {item.id for item in current}
+ wanted_ids = {item.id for item in wanted}
+
+ # Removing existing but not wanted firewalls
+ actions: list[BoundAction] = []
+ for current_firewall in current:
+ if current_firewall.id in wanted_ids:
+ continue
+
+ self._mark_as_changed()
+ if self.module.check_mode:
+ continue
+
+ actions.extend(
+ self.client.firewalls.remove_from_resources(
+ current_firewall,
+ [FirewallResource(type="server", server=self.hcloud_server)],
+ )
+ )
+
+ for action in actions:
+ action.wait_until_finished()
+
+ # Adding wanted firewalls that doesn't exist yet
+ actions: list[BoundAction] = []
+ for wanted_firewall in wanted:
+ if wanted_firewall.id in current_ids:
+ continue
+
+ self._mark_as_changed()
+ if self.module.check_mode:
+ continue
+
+ actions.extend(
+ self.client.firewalls.apply_to_resources(
+ wanted_firewall,
+ [FirewallResource(type="server", server=self.hcloud_server)],
+ )
+ )
+
+ for action in actions:
+ action.wait_until_finished()
+
def _set_rescue_mode(self, rescue_mode):
if self.module.params.get("ssh_keys"):
resp = self.hcloud_server.enable_rescue(
@@ -813,7 +829,8 @@ class AnsibleHCloudServer(AnsibleHCloud):
if self.hcloud_server:
if self.hcloud_server.status != Server.STATUS_RUNNING:
if not self.module.check_mode:
- self.client.servers.power_on(self.hcloud_server).wait_until_finished()
+ action = self.client.servers.power_on(self.hcloud_server)
+ action.wait_until_finished()
self._mark_as_changed()
self._get_server()
except HCloudException as exception:
@@ -824,7 +841,8 @@ class AnsibleHCloudServer(AnsibleHCloud):
if self.hcloud_server:
if self.hcloud_server.status != Server.STATUS_OFF:
if not self.module.check_mode:
- self.client.servers.power_off(self.hcloud_server).wait_until_finished()
+ action = self.client.servers.power_off(self.hcloud_server)
+ action.wait_until_finished()
self._mark_as_changed()
self._get_server()
except HCloudException as exception:
@@ -833,18 +851,14 @@ class AnsibleHCloudServer(AnsibleHCloud):
def stop_server_if_forced(self):
previous_server_status = self.hcloud_server.status
if previous_server_status == Server.STATUS_RUNNING and not self.module.check_mode:
- if (
- self.module.params.get("force_upgrade")
- or self.module.params.get("force")
- or self.module.params.get("state") == "stopped"
- ):
+ if self.module.params.get("force") or self.module.params.get("state") == "stopped":
self.stop_server() # Only stopped server can be upgraded
return previous_server_status
- else:
- self.module.warn(
- f"You can not upgrade a running instance {self.hcloud_server.name}. "
- "You need to stop the instance or use force=true."
- )
+
+ self.module.warn(
+ f"You can not upgrade a running instance {self.hcloud_server.name}. "
+ "You need to stop the instance or use force=true."
+ )
return None
@@ -874,7 +888,8 @@ class AnsibleHCloudServer(AnsibleHCloud):
self._get_server()
if self.hcloud_server is not None:
if not self.module.check_mode:
- self.client.servers.delete(self.hcloud_server).wait_until_finished()
+ action = self.client.servers.delete(self.hcloud_server)
+ action.wait_until_finished()
self._mark_as_changed()
self.hcloud_server = None
except HCloudException as exception:
@@ -887,6 +902,7 @@ class AnsibleHCloudServer(AnsibleHCloud):
id={"type": "int"},
name={"type": "str"},
image={"type": "str"},
+ image_allow_deprecated={"type": "bool", "default": False, "aliases": ["allow_deprecated_image"]},
server_type={"type": "str"},
location={"type": "str"},
datacenter={"type": "str"},
@@ -902,9 +918,14 @@ class AnsibleHCloudServer(AnsibleHCloud):
ipv4={"type": "str"},
ipv6={"type": "str"},
private_networks={"type": "list", "elements": "str", "default": None},
- force={"type": "bool", "default": False},
- force_upgrade={"type": "bool"},
- allow_deprecated_image={"type": "bool", "default": False},
+ force={
+ "type": "bool",
+ "default": False,
+ "aliases": ["force_upgrade"],
+ "deprecated_aliases": [
+ {"collection_name": "hetzner.hcloud", "name": "force_upgrade", "version": "4.0.0"}
+ ],
+ },
rescue_mode={"type": "str"},
delete_protection={"type": "bool"},
rebuild_protection={"type": "bool"},
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/server_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/server_info.py
index cee1634cb..3417e58af 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/server_info.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/server_info.py
@@ -146,7 +146,6 @@ hcloud_server_info:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import HCloudException
@@ -162,36 +161,31 @@ class AnsibleHCloudServerInfo(AnsibleHCloud):
tmp = []
for server in self.hcloud_server_info:
- if server is not None:
- image = None if server.image is None else to_native(server.image.name)
- placement_group = None if server.placement_group is None else to_native(server.placement_group.name)
- ipv4_address = None if server.public_net.ipv4 is None else to_native(server.public_net.ipv4.ip)
- ipv6 = None if server.public_net.ipv6 is None else to_native(server.public_net.ipv6.ip)
- backup_window = None if server.backup_window is None else to_native(server.backup_window)
- tmp.append(
- {
- "id": to_native(server.id),
- "name": to_native(server.name),
- "created": to_native(server.created.isoformat()),
- "ipv4_address": ipv4_address,
- "ipv6": ipv6,
- "private_networks": [to_native(net.network.name) for net in server.private_net],
- "private_networks_info": [
- {"name": to_native(net.network.name), "ip": net.ip} for net in server.private_net
- ],
- "image": image,
- "server_type": to_native(server.server_type.name),
- "datacenter": to_native(server.datacenter.name),
- "location": to_native(server.datacenter.location.name),
- "placement_group": placement_group,
- "rescue_enabled": server.rescue_enabled,
- "backup_window": backup_window,
- "labels": server.labels,
- "status": to_native(server.status),
- "delete_protection": server.protection["delete"],
- "rebuild_protection": server.protection["rebuild"],
- }
- )
+ if server is None:
+ continue
+
+ tmp.append(
+ {
+ "id": str(server.id),
+ "name": server.name,
+ "created": server.created.isoformat(),
+ "ipv4_address": server.public_net.ipv4.ip if server.public_net.ipv4 is not None else None,
+ "ipv6": server.public_net.ipv6.ip if server.public_net.ipv6 is not None else None,
+ "private_networks": [net.network.name for net in server.private_net],
+ "private_networks_info": [{"name": net.network.name, "ip": net.ip} for net in server.private_net],
+ "image": server.image.name if server.image is not None else None,
+ "server_type": server.server_type.name,
+ "datacenter": server.datacenter.name,
+ "location": server.datacenter.location.name,
+ "placement_group": server.placement_group.name if server.placement_group is not None else None,
+ "rescue_enabled": server.rescue_enabled,
+ "backup_window": server.backup_window,
+ "labels": server.labels,
+ "status": server.status,
+ "delete_protection": server.protection["delete"],
+ "rebuild_protection": server.protection["rebuild"],
+ }
+ )
return tmp
def get_servers(self):
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/server_network.py b/ansible_collections/hetzner/hcloud/plugins/modules/server_network.py
index ca80a8a76..bc6dec428 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/server_network.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/server_network.py
@@ -111,7 +111,6 @@ hcloud_server_network:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import APIException, HCloudException
@@ -128,10 +127,10 @@ class AnsibleHCloudServerNetwork(AnsibleHCloud):
def _prepare_result(self):
return {
- "network": to_native(self.hcloud_network.name),
- "server": to_native(self.hcloud_server.name),
- "ip": to_native(self.hcloud_server_network.ip),
- "alias_ips": self.hcloud_server_network.alias_ips,
+ "network": self.hcloud_network.name,
+ "server": self.hcloud_server.name,
+ "ip": self.hcloud_server_network.ip,
+ "alias_ips": list(sorted(self.hcloud_server_network.alias_ips)),
}
def _get_server_and_network(self):
@@ -165,7 +164,8 @@ class AnsibleHCloudServerNetwork(AnsibleHCloud):
if not self.module.check_mode:
try:
- self.hcloud_server.attach_to_network(**params).wait_until_finished()
+ action = self.hcloud_server.attach_to_network(**params)
+ action.wait_until_finished()
except HCloudException as exception:
self.fail_json_hcloud(exception)
@@ -183,7 +183,8 @@ class AnsibleHCloudServerNetwork(AnsibleHCloud):
if not self.module.check_mode:
try:
- self.hcloud_server.change_alias_ips(**params).wait_until_finished()
+ action = self.hcloud_server.change_alias_ips(**params)
+ action.wait_until_finished()
except APIException as exception:
self.fail_json_hcloud(exception)
@@ -205,7 +206,8 @@ class AnsibleHCloudServerNetwork(AnsibleHCloud):
if self.hcloud_server_network is not None and self.hcloud_server is not None:
if not self.module.check_mode:
try:
- self.hcloud_server.detach_from_network(self.hcloud_server_network.network).wait_until_finished()
+ action = self.hcloud_server.detach_from_network(self.hcloud_server_network.network)
+ action.wait_until_finished()
except HCloudException as exception:
self.fail_json_hcloud(exception)
self._mark_as_changed()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/server_type_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/server_type_info.py
index 61f1f5011..4f16b52fe 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/server_type_info.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/server_type_info.py
@@ -124,7 +124,6 @@ hcloud_server_type_info:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import HCloudException
@@ -140,29 +139,31 @@ class AnsibleHCloudServerTypeInfo(AnsibleHCloud):
tmp = []
for server_type in self.hcloud_server_type_info:
- if server_type is not None:
- tmp.append(
- {
- "id": to_native(server_type.id),
- "name": to_native(server_type.name),
- "description": to_native(server_type.description),
- "cores": server_type.cores,
- "memory": server_type.memory,
- "disk": server_type.disk,
- "storage_type": to_native(server_type.storage_type),
- "cpu_type": to_native(server_type.cpu_type),
- "architecture": to_native(server_type.architecture),
- "included_traffic": server_type.included_traffic,
- "deprecation": (
- {
- "announced": server_type.deprecation.announced.isoformat(),
- "unavailable_after": server_type.deprecation.unavailable_after.isoformat(),
- }
- if server_type.deprecation is not None
- else None
- ),
- }
- )
+ if server_type is None:
+ continue
+
+ tmp.append(
+ {
+ "id": str(server_type.id),
+ "name": server_type.name,
+ "description": server_type.description,
+ "cores": server_type.cores,
+ "memory": server_type.memory,
+ "disk": server_type.disk,
+ "storage_type": server_type.storage_type,
+ "cpu_type": server_type.cpu_type,
+ "architecture": server_type.architecture,
+ "included_traffic": server_type.included_traffic,
+ "deprecation": (
+ {
+ "announced": server_type.deprecation.announced.isoformat(),
+ "unavailable_after": server_type.deprecation.unavailable_after.isoformat(),
+ }
+ if server_type.deprecation is not None
+ else None
+ ),
+ }
+ )
return tmp
def get_server_types(self):
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/ssh_key.py b/ansible_collections/hetzner/hcloud/plugins/modules/ssh_key.py
index 349c52c68..e33987c44 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/ssh_key.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/ssh_key.py
@@ -113,7 +113,6 @@ hcloud_ssh_key:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import HCloudException
@@ -127,10 +126,10 @@ class AnsibleHCloudSSHKey(AnsibleHCloud):
def _prepare_result(self):
return {
- "id": to_native(self.hcloud_ssh_key.id),
- "name": to_native(self.hcloud_ssh_key.name),
- "fingerprint": to_native(self.hcloud_ssh_key.fingerprint),
- "public_key": to_native(self.hcloud_ssh_key.public_key),
+ "id": str(self.hcloud_ssh_key.id),
+ "name": self.hcloud_ssh_key.name,
+ "fingerprint": self.hcloud_ssh_key.fingerprint,
+ "public_key": self.hcloud_ssh_key.public_key,
"labels": self.hcloud_ssh_key.labels,
}
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/ssh_key_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/ssh_key_info.py
index 7a4ab5928..b6b22ff35 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/ssh_key_info.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/ssh_key_info.py
@@ -79,7 +79,6 @@ hcloud_ssh_key_info:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import HCloudException
@@ -92,20 +91,22 @@ class AnsibleHCloudSSHKeyInfo(AnsibleHCloud):
hcloud_ssh_key_info: list[BoundSSHKey] | None = None
def _prepare_result(self):
- ssh_keys = []
+ tmp = []
for ssh_key in self.hcloud_ssh_key_info:
- if ssh_key:
- ssh_keys.append(
- {
- "id": to_native(ssh_key.id),
- "name": to_native(ssh_key.name),
- "fingerprint": to_native(ssh_key.fingerprint),
- "public_key": to_native(ssh_key.public_key),
- "labels": ssh_key.labels,
- }
- )
- return ssh_keys
+ if ssh_key is None:
+ continue
+
+ tmp.append(
+ {
+ "id": str(ssh_key.id),
+ "name": ssh_key.name,
+ "fingerprint": ssh_key.fingerprint,
+ "public_key": ssh_key.public_key,
+ "labels": ssh_key.labels,
+ }
+ )
+ return tmp
def get_ssh_keys(self):
try:
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/subnetwork.py b/ansible_collections/hetzner/hcloud/plugins/modules/subnetwork.py
index aea40bb13..6f7feeaad 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/subnetwork.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/subnetwork.py
@@ -123,7 +123,6 @@ hcloud_subnetwork:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import HCloudException
@@ -138,10 +137,10 @@ class AnsibleHCloudSubnetwork(AnsibleHCloud):
def _prepare_result(self):
return {
- "network": to_native(self.hcloud_network.name),
- "ip_range": to_native(self.hcloud_subnetwork.ip_range),
- "type": to_native(self.hcloud_subnetwork.type),
- "network_zone": to_native(self.hcloud_subnetwork.network_zone),
+ "network": self.hcloud_network.name,
+ "ip_range": self.hcloud_subnetwork.ip_range,
+ "type": self.hcloud_subnetwork.type,
+ "network_zone": self.hcloud_subnetwork.network_zone,
"gateway": self.hcloud_subnetwork.gateway,
"vswitch_id": self.hcloud_subnetwork.vswitch_id,
}
@@ -174,7 +173,8 @@ class AnsibleHCloudSubnetwork(AnsibleHCloud):
if not self.module.check_mode:
try:
- self.hcloud_network.add_subnet(subnet=NetworkSubnet(**params)).wait_until_finished()
+ action = self.hcloud_network.add_subnet(subnet=NetworkSubnet(**params))
+ action.wait_until_finished()
except HCloudException as exception:
self.fail_json_hcloud(exception)
@@ -194,7 +194,8 @@ class AnsibleHCloudSubnetwork(AnsibleHCloud):
if self.hcloud_subnetwork is not None and self.hcloud_network is not None:
if not self.module.check_mode:
try:
- self.hcloud_network.delete_subnet(self.hcloud_subnetwork).wait_until_finished()
+ action = self.hcloud_network.delete_subnet(self.hcloud_subnetwork)
+ action.wait_until_finished()
except HCloudException as exception:
self.fail_json_hcloud(exception)
self._mark_as_changed()
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/volume.py b/ansible_collections/hetzner/hcloud/plugins/modules/volume.py
index 8442ed90b..1bcb44253 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/volume.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/volume.py
@@ -160,7 +160,6 @@ hcloud_volume:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import HCloudException
@@ -173,18 +172,14 @@ class AnsibleHCloudVolume(AnsibleHCloud):
hcloud_volume: BoundVolume | None = None
def _prepare_result(self):
- server_name = None
- if self.hcloud_volume.server is not None:
- server_name = to_native(self.hcloud_volume.server.name)
-
return {
- "id": to_native(self.hcloud_volume.id),
- "name": to_native(self.hcloud_volume.name),
+ "id": str(self.hcloud_volume.id),
+ "name": self.hcloud_volume.name,
"size": self.hcloud_volume.size,
- "location": to_native(self.hcloud_volume.location.name),
+ "location": self.hcloud_volume.location.name,
"labels": self.hcloud_volume.labels,
- "server": server_name,
- "linux_device": to_native(self.hcloud_volume.linux_device),
+ "server": self.hcloud_volume.server.name if self.hcloud_volume.server is not None else None,
+ "linux_device": self.hcloud_volume.linux_device,
"delete_protection": self.hcloud_volume.protection["delete"],
}
@@ -221,7 +216,8 @@ class AnsibleHCloudVolume(AnsibleHCloud):
delete_protection = self.module.params.get("delete_protection")
if delete_protection is not None:
self._get_volume()
- self.hcloud_volume.change_protection(delete=delete_protection).wait_until_finished()
+ action = self.hcloud_volume.change_protection(delete=delete_protection)
+ action.wait_until_finished()
except HCloudException as exception:
self.fail_json_hcloud(exception)
self._mark_as_changed()
@@ -233,7 +229,8 @@ class AnsibleHCloudVolume(AnsibleHCloud):
if size:
if self.hcloud_volume.size < size:
if not self.module.check_mode:
- self.hcloud_volume.resize(size).wait_until_finished()
+ action = self.hcloud_volume.resize(size)
+ action.wait_until_finished()
self._mark_as_changed()
elif self.hcloud_volume.size > size:
self.module.warn("Shrinking of volumes is not supported")
@@ -244,12 +241,14 @@ class AnsibleHCloudVolume(AnsibleHCloud):
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()
+ action = self.hcloud_volume.attach(server, automount=automount)
+ action.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()
+ action = self.hcloud_volume.detach()
+ action.wait_until_finished()
self._mark_as_changed()
labels = self.module.params.get("labels")
@@ -261,7 +260,8 @@ class AnsibleHCloudVolume(AnsibleHCloud):
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.change_protection(delete=delete_protection).wait_until_finished()
+ action = self.hcloud_volume.change_protection(delete=delete_protection)
+ action.wait_until_finished()
self._mark_as_changed()
self._get_volume()
@@ -281,7 +281,8 @@ class AnsibleHCloudVolume(AnsibleHCloud):
if self.hcloud_volume is not None:
if not self.module.check_mode:
if self.hcloud_volume.server is not None:
- self.hcloud_volume.detach().wait_until_finished()
+ action = self.hcloud_volume.detach()
+ action.wait_until_finished()
self.client.volumes.delete(self.hcloud_volume)
self._mark_as_changed()
self.hcloud_volume = None
diff --git a/ansible_collections/hetzner/hcloud/plugins/modules/volume_info.py b/ansible_collections/hetzner/hcloud/plugins/modules/volume_info.py
index 1e507690e..b30956d74 100644
--- a/ansible_collections/hetzner/hcloud/plugins/modules/volume_info.py
+++ b/ansible_collections/hetzner/hcloud/plugins/modules/volume_info.py
@@ -95,7 +95,6 @@ hcloud_volume_info:
"""
from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.common.text.converters import to_native
from ..module_utils.hcloud import AnsibleHCloud
from ..module_utils.vendor.hcloud import HCloudException
@@ -111,22 +110,21 @@ class AnsibleHCloudVolumeInfo(AnsibleHCloud):
tmp = []
for volume in self.hcloud_volume_info:
- if volume is not None:
- server_name = None
- if volume.server is not None:
- server_name = to_native(volume.server.name)
- tmp.append(
- {
- "id": to_native(volume.id),
- "name": to_native(volume.name),
- "size": volume.size,
- "location": to_native(volume.location.name),
- "labels": volume.labels,
- "server": server_name,
- "linux_device": to_native(volume.linux_device),
- "delete_protection": volume.protection["delete"],
- }
- )
+ if volume is None:
+ continue
+
+ tmp.append(
+ {
+ "id": str(volume.id),
+ "name": volume.name,
+ "size": volume.size,
+ "location": volume.location.name,
+ "labels": volume.labels,
+ "server": volume.server.name if volume.server is not None else None,
+ "linux_device": volume.linux_device,
+ "delete_protection": volume.protection["delete"],
+ }
+ )
return tmp