From 871bc897bffb93bb11b18d02b81097a8001e15c9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 10 Nov 2025 10:23:01 +0100 Subject: [PATCH] chore(deps): update dependency hcloud to v2.10.0 (#728) --- plugins/filter/__init__.py | 0 plugins/filter/all.py | 15 +++----- .../module_utils/vendor/hcloud/_version.py | 2 +- .../vendor/hcloud/exp/__init__.py | 4 +++ .../module_utils/vendor/hcloud/exp/zone.py | 35 +++++++++++++++++++ .../vendor/hcloud/load_balancers/domain.py | 12 ++++++- .../vendor/hcloud/servers/domain.py | 12 ++++++- plugins/modules/load_balancer_network.py | 17 +++------ plugins/modules/server_network.py | 14 ++------ scripts/vendor.py | 2 +- 10 files changed, 75 insertions(+), 38 deletions(-) create mode 100644 plugins/filter/__init__.py create mode 100644 plugins/module_utils/vendor/hcloud/exp/__init__.py create mode 100644 plugins/module_utils/vendor/hcloud/exp/zone.py diff --git a/plugins/filter/__init__.py b/plugins/filter/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/plugins/filter/all.py b/plugins/filter/all.py index 6dea3f8..d76ea2e 100644 --- a/plugins/filter/all.py +++ b/plugins/filter/all.py @@ -5,6 +5,8 @@ from typing import Literal from ansible.errors import AnsibleFilterError from ansible.module_utils.common.text.converters import to_native +from ..module_utils.vendor.hcloud.exp.zone import format_txt_record + # pylint: disable=unused-argument def load_balancer_status(load_balancer: dict, *args, **kwargs) -> Literal["unknown", "unhealthy", "healthy"]: @@ -50,18 +52,11 @@ def load_balancer_status(load_balancer: dict, *args, **kwargs) -> Literal["unkno # pylint: disable=unused-argument def txt_record(record: str, *args, **kwargs) -> str: """ - Return the status of a Load Balancer based on its targets. + Format a TXT record by splitting it in quoted strings of 255 characters. + Existing quotes will be escaped. """ try: - record = record.replace('"', '\\"') - - parts = [] - for start in range(0, len(record), 255): - end = min(start + 255, len(record)) - parts.append('"' + record[start:end] + '"') - record = " ".join(parts) - - return record + return format_txt_record(record) except Exception as exc: raise AnsibleFilterError(f"txt_record - {to_native(exc)}", orig_exc=exc) from exc diff --git a/plugins/module_utils/vendor/hcloud/_version.py b/plugins/module_utils/vendor/hcloud/_version.py index b320f7b..fc2e418 100644 --- a/plugins/module_utils/vendor/hcloud/_version.py +++ b/plugins/module_utils/vendor/hcloud/_version.py @@ -1,3 +1,3 @@ from __future__ import annotations -__version__ = "2.9.0" # x-releaser-pleaser-version +__version__ = "2.10.0" # x-releaser-pleaser-version diff --git a/plugins/module_utils/vendor/hcloud/exp/__init__.py b/plugins/module_utils/vendor/hcloud/exp/__init__.py new file mode 100644 index 0000000..1f47055 --- /dev/null +++ b/plugins/module_utils/vendor/hcloud/exp/__init__.py @@ -0,0 +1,4 @@ +""" +The `exp` module is a namespace that holds experimental features for the `hcloud-python` +library, breaking changes may occur within minor releases. +""" diff --git a/plugins/module_utils/vendor/hcloud/exp/zone.py b/plugins/module_utils/vendor/hcloud/exp/zone.py new file mode 100644 index 0000000..0860128 --- /dev/null +++ b/plugins/module_utils/vendor/hcloud/exp/zone.py @@ -0,0 +1,35 @@ +""" +The `exp.zone` module is a namespace that holds experimental features for the `hcloud-python` +library, breaking changes may occur within minor releases. +""" + +from __future__ import annotations + + +def is_txt_record_quoted(value: str) -> bool: + """ + Check whether a TXT record is already quoted. + + - hello world => false + - "hello world" => true + """ + return value.startswith('"') and value.endswith('"') + + +def format_txt_record(value: str) -> str: + """ + Format a TXT record by splitting it in quoted strings of 255 characters. + Existing quotes will be escaped. + + - hello world => "hello world" + - hello "world" => "hello \"world\"" + """ + value = value.replace('"', '\\"') + + parts = [] + for start in range(0, len(value), 255): + end = min(start + 255, len(value)) + parts.append('"' + value[start:end] + '"') + value = " ".join(parts) + + return value diff --git a/plugins/module_utils/vendor/hcloud/load_balancers/domain.py b/plugins/module_utils/vendor/hcloud/load_balancers/domain.py index 4a34812..d2a9adc 100644 --- a/plugins/module_utils/vendor/hcloud/load_balancers/domain.py +++ b/plugins/module_utils/vendor/hcloud/load_balancers/domain.py @@ -16,7 +16,7 @@ if TYPE_CHECKING: from ..load_balancer_types import BoundLoadBalancerType from ..locations import BoundLocation from ..metrics import Metrics - from ..networks import BoundNetwork + from ..networks import BoundNetwork, Network from ..servers import BoundServer from .client import BoundLoadBalancer @@ -110,6 +110,16 @@ class LoadBalancer(BaseDomain, DomainIdentityMixin): self.ingoing_traffic = ingoing_traffic self.included_traffic = included_traffic + def private_net_for(self, network: BoundNetwork | Network) -> PrivateNet | None: + """ + Returns the load balancer's network attachment information in the given Network, + and None if no attachment was found. + """ + for o in self.private_net or []: + if o.network.id == network.id: + return o + return None + class LoadBalancerService(BaseDomain): """LoadBalancerService Domain diff --git a/plugins/module_utils/vendor/hcloud/servers/domain.py b/plugins/module_utils/vendor/hcloud/servers/domain.py index 77c6d66..bc8b79a 100644 --- a/plugins/module_utils/vendor/hcloud/servers/domain.py +++ b/plugins/module_utils/vendor/hcloud/servers/domain.py @@ -17,7 +17,7 @@ if TYPE_CHECKING: from ..images import BoundImage from ..isos import BoundIso from ..metrics import Metrics - from ..networks import BoundNetwork + from ..networks import BoundNetwork, Network from ..placement_groups import BoundPlacementGroup from ..primary_ips import BoundPrimaryIP, PrimaryIP from ..server_types import BoundServerType @@ -157,6 +157,16 @@ class Server(BaseDomain, DomainIdentityMixin): self.primary_disk_size = primary_disk_size self.placement_group = placement_group + def private_net_for(self, network: BoundNetwork | Network) -> PrivateNet | None: + """ + Returns the server's network attachment information in the given Network, + and None if no attachment was found. + """ + for o in self.private_net or []: + if o.network.id == network.id: + return o + return None + class CreateServerResponse(BaseDomain): """Create Server Response Domain diff --git a/plugins/modules/load_balancer_network.py b/plugins/modules/load_balancer_network.py index a5304bb..7450e1e 100644 --- a/plugins/modules/load_balancer_network.py +++ b/plugins/modules/load_balancer_network.py @@ -127,6 +127,8 @@ class AnsibleHCloudLoadBalancerNetwork(AnsibleHCloud): def _get_load_balancer_and_network(self): try: + self.hcloud_load_balancer_network = None + self.hcloud_network = self._client_get_by_name_or_id( "networks", self.module.params.get("network"), @@ -135,17 +137,10 @@ class AnsibleHCloudLoadBalancerNetwork(AnsibleHCloud): "load_balancers", self.module.params.get("load_balancer"), ) - - self.hcloud_load_balancer_network = None + self.hcloud_load_balancer_network = self.hcloud_load_balancer.private_net_for(self.hcloud_network) except HCloudException as exception: self.fail_json_hcloud(exception) - def _get_load_balancer_network(self): - self.hcloud_load_balancer_network = None - for private_net in self.hcloud_load_balancer.private_net: - if private_net.network.id == self.hcloud_network.id: - self.hcloud_load_balancer_network = private_net - def _attach(self): params = { "network": self.hcloud_network, @@ -185,7 +180,6 @@ class AnsibleHCloudLoadBalancerNetwork(AnsibleHCloud): self._attach() self._get_load_balancer_and_network() - self._get_load_balancer_network() def _update_load_balancer_network(self): ip_range = self.module.params.get("ip_range") @@ -202,12 +196,10 @@ class AnsibleHCloudLoadBalancerNetwork(AnsibleHCloud): # No further updates needed, exit self._get_load_balancer_and_network() - self._get_load_balancer_network() return def present_load_balancer_network(self): self._get_load_balancer_and_network() - self._get_load_balancer_network() if self.hcloud_load_balancer_network is None: self._create_load_balancer_network() else: @@ -215,7 +207,6 @@ class AnsibleHCloudLoadBalancerNetwork(AnsibleHCloud): def delete_load_balancer_network(self): self._get_load_balancer_and_network() - self._get_load_balancer_network() if self.hcloud_load_balancer_network is not None and self.hcloud_load_balancer is not None: self._detach() self.hcloud_load_balancer_network = None @@ -230,7 +221,7 @@ class AnsibleHCloudLoadBalancerNetwork(AnsibleHCloud): # pylint: disable=disallowed-name for _ in range(10): self.hcloud_load_balancer.reload() - self._get_load_balancer_network() + self.hcloud_load_balancer_network = self.hcloud_load_balancer.private_net_for(self.hcloud_network) if done(self.hcloud_load_balancer_network): break diff --git a/plugins/modules/server_network.py b/plugins/modules/server_network.py index 58cf7e5..0f58ae9 100644 --- a/plugins/modules/server_network.py +++ b/plugins/modules/server_network.py @@ -148,6 +148,8 @@ class AnsibleHCloudServerNetwork(AnsibleHCloud): def _get_server_and_network(self): try: + self.hcloud_server_network = None + self.hcloud_network = self._client_get_by_name_or_id( "networks", self.module.params.get("network"), @@ -156,15 +158,10 @@ class AnsibleHCloudServerNetwork(AnsibleHCloud): "servers", self.module.params.get("server"), ) - self.hcloud_server_network = None + self.hcloud_server_network = self.hcloud_server.private_net_for(self.hcloud_network) except HCloudException as exception: self.fail_json_hcloud(exception) - def _get_server_network(self): - for private_net in self.hcloud_server.private_net: - if private_net.network.id == self.hcloud_network.id: - self.hcloud_server_network = private_net - def _attach(self): params = { "network": self.hcloud_network, @@ -199,7 +196,6 @@ class AnsibleHCloudServerNetwork(AnsibleHCloud): def _create_server_network(self): self._attach() self._get_server_and_network() - self._get_server_network() def _update_server_network(self): ip_range = self.module.params.get("ip_range") @@ -216,7 +212,6 @@ class AnsibleHCloudServerNetwork(AnsibleHCloud): # No further updates needed, exit self._get_server_and_network() - self._get_server_network() return params = { @@ -236,11 +231,9 @@ class AnsibleHCloudServerNetwork(AnsibleHCloud): self._mark_as_changed() self._get_server_and_network() - self._get_server_network() def present_server_network(self): self._get_server_and_network() - self._get_server_network() if self.hcloud_server_network is None: self._create_server_network() else: @@ -248,7 +241,6 @@ class AnsibleHCloudServerNetwork(AnsibleHCloud): def delete_server_network(self): self._get_server_and_network() - self._get_server_network() if self.hcloud_server_network is not None and self.hcloud_server is not None: self._detach() self.hcloud_server_network = None diff --git a/scripts/vendor.py b/scripts/vendor.py index 5f3f35e..70c1d33 100755 --- a/scripts/vendor.py +++ b/scripts/vendor.py @@ -22,7 +22,7 @@ from textwrap import dedent logger = logging.getLogger("vendor") HCLOUD_SOURCE_URL = "https://github.com/hetznercloud/hcloud-python" -HCLOUD_VERSION = "v2.9.0" +HCLOUD_VERSION = "v2.10.0" HCLOUD_VENDOR_PATH = "plugins/module_utils/vendor/hcloud"