From af3e9f4bf22dc88be343c02b391503feecdfec47 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Fri, 19 Dec 2025 19:50:01 +0100
Subject: [PATCH] chore(deps): update dependency hcloud to v2.13.0 (#776)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This PR contains the following updates:
| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [hcloud](https://redirect.github.com/hetznercloud/hcloud-python)
([changelog](https://redirect.github.com/hetznercloud/hcloud-python/blob/main/CHANGELOG.md))
| `2.12.0` -> `2.13.0` |

|

|
---
### Release Notes
hetznercloud/hcloud-python (hcloud)
###
[`v2.13.0`](https://redirect.github.com/hetznercloud/hcloud-python/blob/HEAD/CHANGELOG.md#v2130)
[Compare
Source](https://redirect.github.com/hetznercloud/hcloud-python/compare/v2.12.0...v2.13.0)
##### Features
- add per primary ip actions list operations
([#608](https://redirect.github.com/hetznercloud/hcloud-python/issues/608))
- deprecate datacenter in `primary ips` and `servers`
([#609](https://redirect.github.com/hetznercloud/hcloud-python/issues/609))
---
### Configuration
📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).
🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.
â™» **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.
🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.
---
- [ ] If you want to rebase/retry this PR, check
this box
---
This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/ansible-collections/hetzner.hcloud).
---------
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: jo
---
.../module_utils/vendor/hcloud/__init__.py | 24 ++-
plugins/module_utils/vendor/hcloud/_client.py | 12 +-
.../module_utils/vendor/hcloud/_version.py | 2 +-
.../vendor/hcloud/actions/__init__.py | 16 +-
.../vendor/hcloud/actions/client.py | 164 ++++++++++++------
.../vendor/hcloud/actions/domain.py | 47 +++--
.../vendor/hcloud/certificates/client.py | 127 +++++++-------
.../vendor/hcloud/certificates/domain.py | 19 +-
.../module_utils/vendor/hcloud/core/client.py | 42 +++--
.../module_utils/vendor/hcloud/core/domain.py | 33 +++-
.../vendor/hcloud/datacenters/client.py | 10 +-
.../vendor/hcloud/datacenters/domain.py | 5 +
.../vendor/hcloud/deprecation/__init__.py | 4 +-
.../vendor/hcloud/deprecation/domain.py | 15 +-
.../module_utils/vendor/hcloud/exp/zone.py | 5 +
.../vendor/hcloud/firewalls/client.py | 130 +++++++-------
.../vendor/hcloud/firewalls/domain.py | 17 +-
.../vendor/hcloud/floating_ips/__init__.py | 3 +-
.../vendor/hcloud/floating_ips/client.py | 128 +++++++-------
.../vendor/hcloud/floating_ips/domain.py | 25 ++-
.../vendor/hcloud/helpers/__init__.py | 4 +-
.../vendor/hcloud/helpers/labels.py | 4 +
.../vendor/hcloud/images/__init__.py | 3 +-
.../vendor/hcloud/images/client.py | 129 +++++++-------
.../vendor/hcloud/images/domain.py | 24 ++-
.../module_utils/vendor/hcloud/isos/client.py | 8 +-
.../module_utils/vendor/hcloud/isos/domain.py | 9 +-
.../hcloud/load_balancer_types/client.py | 8 +-
.../hcloud/load_balancer_types/domain.py | 8 +-
.../vendor/hcloud/load_balancers/__init__.py | 4 +
.../vendor/hcloud/load_balancers/client.py | 127 +++++++-------
.../vendor/hcloud/load_balancers/domain.py | 42 +++--
.../vendor/hcloud/locations/client.py | 8 +-
.../vendor/hcloud/locations/domain.py | 4 +
.../vendor/hcloud/metrics/domain.py | 15 +-
.../vendor/hcloud/networks/__init__.py | 2 +
.../vendor/hcloud/networks/client.py | 127 +++++++-------
.../vendor/hcloud/networks/domain.py | 25 ++-
.../vendor/hcloud/placement_groups/client.py | 8 +-
.../vendor/hcloud/placement_groups/domain.py | 12 +-
.../vendor/hcloud/primary_ips/__init__.py | 3 +-
.../vendor/hcloud/primary_ips/client.py | 141 ++++++++++++++-
.../vendor/hcloud/primary_ips/domain.py | 71 ++++++--
.../vendor/hcloud/rdns/__init__.py | 7 +
.../module_utils/vendor/hcloud/rdns/domain.py | 12 ++
.../vendor/hcloud/server_types/client.py | 10 +-
.../vendor/hcloud/server_types/domain.py | 12 +-
.../vendor/hcloud/servers/__init__.py | 6 +
.../vendor/hcloud/servers/client.py | 147 ++++++++--------
.../vendor/hcloud/servers/domain.py | 79 +++++++--
.../vendor/hcloud/ssh_keys/client.py | 8 +-
.../vendor/hcloud/ssh_keys/domain.py | 11 +-
.../vendor/hcloud/storage_box_types/client.py | 8 +-
.../vendor/hcloud/storage_box_types/domain.py | 10 +-
.../vendor/hcloud/storage_boxes/client.py | 108 +++++++-----
.../vendor/hcloud/storage_boxes/domain.py | 31 +++-
.../vendor/hcloud/volumes/__init__.py | 3 +-
.../vendor/hcloud/volumes/client.py | 127 +++++++-------
.../vendor/hcloud/volumes/domain.py | 21 ++-
.../vendor/hcloud/zones/__init__.py | 20 +++
.../vendor/hcloud/zones/client.py | 115 ++++++------
.../vendor/hcloud/zones/domain.py | 31 ++--
scripts/vendor.py | 2 +-
63 files changed, 1487 insertions(+), 895 deletions(-)
create mode 100644 plugins/module_utils/vendor/hcloud/rdns/__init__.py
create mode 100644 plugins/module_utils/vendor/hcloud/rdns/domain.py
diff --git a/plugins/module_utils/vendor/hcloud/__init__.py b/plugins/module_utils/vendor/hcloud/__init__.py
index 95709bb..8a9fa14 100644
--- a/plugins/module_utils/vendor/hcloud/__init__.py
+++ b/plugins/module_utils/vendor/hcloud/__init__.py
@@ -1,12 +1,18 @@
from __future__ import annotations
-from ._client import ( # noqa pylint: disable=C0414
- Client as Client,
- constant_backoff_function as constant_backoff_function,
- exponential_backoff_function as exponential_backoff_function,
+from ._client import (
+ Client,
+ constant_backoff_function,
+ exponential_backoff_function,
)
-from ._exceptions import ( # noqa pylint: disable=C0414
- APIException as APIException,
- HCloudException as HCloudException,
-)
-from ._version import __version__ # noqa
+from ._exceptions import APIException, HCloudException
+from ._version import __version__
+
+__all__ = [
+ "__version__",
+ "Client",
+ "constant_backoff_function",
+ "exponential_backoff_function",
+ "APIException",
+ "HCloudException",
+]
diff --git a/plugins/module_utils/vendor/hcloud/_client.py b/plugins/module_utils/vendor/hcloud/_client.py
index e552433..b6b570a 100644
--- a/plugins/module_utils/vendor/hcloud/_client.py
+++ b/plugins/module_utils/vendor/hcloud/_client.py
@@ -3,7 +3,7 @@ from __future__ import annotations
import time
from http import HTTPStatus
from random import uniform
-from typing import Protocol
+from typing import Any, Protocol
try:
import requests
@@ -75,7 +75,7 @@ def exponential_backoff_function(
"""
def func(retries: int) -> float:
- interval = base * multiplier**retries # Exponential backoff
+ interval: float = base * multiplier**retries # Exponential backoff
interval = min(cap, interval) # Cap backoff
if jitter:
interval = uniform(base, interval) # Add jitter
@@ -295,7 +295,7 @@ class Client:
method: str,
url: str,
**kwargs,
- ) -> dict:
+ ) -> dict[str, Any]:
"""Perform a request to the Hetzner Cloud API.
:param method: Method to perform the request.
@@ -348,7 +348,7 @@ class ClientBase:
method: str,
url: str,
**kwargs,
- ) -> dict:
+ ) -> dict[str, Any]:
"""Perform a request to the provided URL.
:param method: Method to perform the request.
@@ -384,7 +384,7 @@ class ClientBase:
continue
raise
- def _read_response(self, response) -> dict:
+ def _read_response(self, response) -> dict[str, Any]:
correlation_id = response.headers.get("X-Correlation-Id")
payload = {}
try:
@@ -407,7 +407,7 @@ class ClientBase:
correlation_id=correlation_id,
)
- error: dict = payload["error"]
+ error: dict[str, Any] = payload["error"]
raise APIException(
code=error["code"],
message=error["message"],
diff --git a/plugins/module_utils/vendor/hcloud/_version.py b/plugins/module_utils/vendor/hcloud/_version.py
index 77282e5..4e8b02a 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.12.0" # x-releaser-pleaser-version
+__version__ = "2.13.0" # x-releaser-pleaser-version
diff --git a/plugins/module_utils/vendor/hcloud/actions/__init__.py b/plugins/module_utils/vendor/hcloud/actions/__init__.py
index 8a96e5d..ac67793 100644
--- a/plugins/module_utils/vendor/hcloud/actions/__init__.py
+++ b/plugins/module_utils/vendor/hcloud/actions/__init__.py
@@ -2,24 +2,32 @@ from __future__ import annotations
from .client import (
ActionsClient,
+ ActionSort,
ActionsPageResult,
BoundAction,
ResourceActionsClient,
)
from .domain import (
Action,
+ ActionError,
ActionException,
ActionFailedException,
+ ActionResource,
+ ActionStatus,
ActionTimeoutException,
)
__all__ = [
- "Action",
- "ActionException",
- "ActionFailedException",
- "ActionTimeoutException",
"ActionsClient",
"ActionsPageResult",
"BoundAction",
"ResourceActionsClient",
+ "ActionSort",
+ "ActionStatus",
+ "Action",
+ "ActionResource",
+ "ActionError",
+ "ActionException",
+ "ActionFailedException",
+ "ActionTimeoutException",
]
diff --git a/plugins/module_utils/vendor/hcloud/actions/client.py b/plugins/module_utils/vendor/hcloud/actions/client.py
index a0c0cc4..176a6b1 100644
--- a/plugins/module_utils/vendor/hcloud/actions/client.py
+++ b/plugins/module_utils/vendor/hcloud/actions/client.py
@@ -2,16 +2,25 @@ from __future__ import annotations
import time
import warnings
-from typing import TYPE_CHECKING, Any, NamedTuple
+from typing import TYPE_CHECKING, Any, Literal, NamedTuple
from ..core import BoundModelBase, Meta, ResourceClientBase
-from .domain import Action, ActionFailedException, ActionTimeoutException
+from .domain import Action, ActionFailedException, ActionStatus, ActionTimeoutException
if TYPE_CHECKING:
from .._client import Client
-class BoundAction(BoundModelBase, Action):
+__all__ = [
+ "ActionsClient",
+ "ActionsPageResult",
+ "BoundAction",
+ "ResourceActionsClient",
+ "ActionSort",
+]
+
+
+class BoundAction(BoundModelBase[Action], Action):
_client: ActionsClient
model = Action
@@ -45,12 +54,78 @@ class BoundAction(BoundModelBase, Action):
raise ActionFailedException(action=self)
+ActionSort = Literal[
+ "id",
+ "id:asc",
+ "id:desc",
+ "command",
+ "command:asc",
+ "command:desc",
+ "status",
+ "status:asc",
+ "status:desc",
+ "started",
+ "started:asc",
+ "started:desc",
+ "finished",
+ "finished:asc",
+ "finished:desc",
+]
+
+
class ActionsPageResult(NamedTuple):
actions: list[BoundAction]
meta: Meta
-class ResourceActionsClient(ResourceClientBase):
+class ResourceClientBaseActionsMixin(ResourceClientBase):
+ def _get_action_by_id(
+ self,
+ base_url: str,
+ id: int,
+ ) -> BoundAction:
+ response = self._client.request(
+ method="GET",
+ url=f"{base_url}/actions/{id}",
+ )
+ return BoundAction(
+ client=self._parent.actions,
+ data=response["action"],
+ )
+
+ def _get_actions_list(
+ self,
+ base_url: str,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
+ page: int | None = None,
+ per_page: int | None = None,
+ ) -> ActionsPageResult:
+ params: dict[str, Any] = {}
+ if status is not None:
+ params["status"] = status
+ if sort is not None:
+ params["sort"] = sort
+ if page is not None:
+ params["page"] = page
+ if per_page is not None:
+ params["per_page"] = per_page
+
+ response = self._client.request(
+ method="GET",
+ url=f"{base_url}/actions",
+ params=params,
+ )
+ return ActionsPageResult(
+ actions=[BoundAction(self._parent.actions, o) for o in response["actions"]],
+ meta=Meta.parse_meta(response),
+ )
+
+
+class ResourceActionsClient(
+ ResourceClientBaseActionsMixin,
+ ResourceClientBase,
+):
_resource: str
def __init__(self, client: ResourceClientBase | Client, resource: str | None):
@@ -66,69 +141,46 @@ class ResourceActionsClient(ResourceClientBase):
self._resource = resource or ""
def get_by_id(self, id: int) -> BoundAction:
- """Get a specific action by its ID.
-
- :param id: int
- :return: :class:`BoundAction `
"""
- response = self._client.request(
- url=f"{self._resource}/actions/{id}",
- method="GET",
- )
- return BoundAction(self._parent.actions, response["action"])
+ Returns a specific Action by its ID.
+
+ :param id: ID of the Action.
+ """
+ return self._get_action_by_id(self._resource, id)
def get_list(
self,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
page: int | None = None,
per_page: int | None = None,
) -> ActionsPageResult:
- """Get a list of actions.
-
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `command` `status` `progress` `started` `finished` . You can add one of ":asc", ":desc" to modify sort order. ( ":asc" is default)
- :param page: int (optional)
- Specifies the page to fetch
- :param per_page: int (optional)
- Specifies how many results are returned by page
- :return: (List[:class:`BoundAction `], :class:`Meta `)
"""
- params: dict[str, Any] = {}
- if status is not None:
- params["status"] = status
- if sort is not None:
- params["sort"] = sort
- if page is not None:
- params["page"] = page
- if per_page is not None:
- params["per_page"] = per_page
+ Returns a paginated list of Actions.
- response = self._client.request(
- url=f"{self._resource}/actions",
- method="GET",
- params=params,
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
+ :param page: Page number to get.
+ :param per_page: Maximum number of Actions returned per page.
+ """
+ return self._get_actions_list(
+ self._resource,
+ status=status,
+ sort=sort,
+ page=page,
+ per_page=per_page,
)
- actions = [
- BoundAction(self._parent.actions, action_data)
- for action_data in response["actions"]
- ]
- return ActionsPageResult(actions, Meta.parse_meta(response))
def get_all(
self,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
) -> list[BoundAction]:
- """Get all actions.
+ """
+ Returns all Actions.
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `command` `status` `progress` `started` `finished` . You can add one of ":asc", ":desc" to modify sort order. ( ":asc" is default)
- :return: List[:class:`BoundAction `]
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
"""
return self._iter_pages(self.get_list, status=status, sort=sort)
@@ -139,8 +191,8 @@ class ActionsClient(ResourceActionsClient):
def get_list(
self,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
page: int | None = None,
per_page: int | None = None,
) -> ActionsPageResult:
@@ -162,8 +214,8 @@ class ActionsClient(ResourceActionsClient):
def get_all(
self,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
) -> list[BoundAction]:
"""
.. deprecated:: 1.28
diff --git a/plugins/module_utils/vendor/hcloud/actions/domain.py b/plugins/module_utils/vendor/hcloud/actions/domain.py
index 92b40a8..59b7f44 100644
--- a/plugins/module_utils/vendor/hcloud/actions/domain.py
+++ b/plugins/module_utils/vendor/hcloud/actions/domain.py
@@ -1,11 +1,6 @@
from __future__ import annotations
-from typing import TYPE_CHECKING
-
-try:
- from dateutil.parser import isoparse
-except ImportError:
- isoparse = None
+from typing import TYPE_CHECKING, Any, Literal, TypedDict
from .._exceptions import HCloudException
from ..core import BaseDomain
@@ -13,6 +8,22 @@ from ..core import BaseDomain
if TYPE_CHECKING:
from .client import BoundAction
+__all__ = [
+ "ActionStatus",
+ "Action",
+ "ActionResource",
+ "ActionError",
+ "ActionException",
+ "ActionFailedException",
+ "ActionTimeoutException",
+]
+
+ActionStatus = Literal[
+ "running",
+ "success",
+ "error",
+]
+
class Action(BaseDomain):
"""Action Domain
@@ -50,24 +61,35 @@ class Action(BaseDomain):
self,
id: int,
command: str | None = None,
- status: str | None = None,
+ status: ActionStatus | None = None,
progress: int | None = None,
started: str | None = None,
finished: str | None = None,
- resources: list[dict] | None = None,
- error: dict | None = None,
+ resources: list[ActionResource] | None = None,
+ error: ActionError | None = None,
):
self.id = id
self.command = command
self.status = status
self.progress = progress
- self.started = isoparse(started) if started else None
- self.finished = isoparse(finished) if finished else None
+ self.started = self._parse_datetime(started)
+ self.finished = self._parse_datetime(finished)
self.resources = resources
self.error = error
+class ActionResource(TypedDict):
+ id: int
+ type: str
+
+
+class ActionError(TypedDict):
+ code: str
+ message: str
+ details: dict[str, Any]
+
+
class ActionException(HCloudException):
"""A generic action exception"""
@@ -85,7 +107,8 @@ class ActionException(HCloudException):
extras.append(action.error["code"])
else:
- extras.append(action.command)
+ if action.command is not None:
+ extras.append(action.command)
extras.append(str(action.id))
message += f" ({', '.join(extras)})"
diff --git a/plugins/module_utils/vendor/hcloud/certificates/client.py b/plugins/module_utils/vendor/hcloud/certificates/client.py
index 8b2a7ef..46a6a53 100644
--- a/plugins/module_utils/vendor/hcloud/certificates/client.py
+++ b/plugins/module_utils/vendor/hcloud/certificates/client.py
@@ -2,7 +2,14 @@ from __future__ import annotations
from typing import TYPE_CHECKING, Any, NamedTuple
-from ..actions import ActionsPageResult, BoundAction, ResourceActionsClient
+from ..actions import (
+ ActionSort,
+ ActionsPageResult,
+ ActionStatus,
+ BoundAction,
+ ResourceActionsClient,
+)
+from ..actions.client import ResourceClientBaseActionsMixin
from ..core import BoundModelBase, Meta, ResourceClientBase
from .domain import (
Certificate,
@@ -15,12 +22,24 @@ if TYPE_CHECKING:
from .._client import Client
-class BoundCertificate(BoundModelBase, Certificate):
+__all__ = [
+ "BoundCertificate",
+ "CertificatesPageResult",
+ "CertificatesClient",
+]
+
+
+class BoundCertificate(BoundModelBase[Certificate], Certificate):
_client: CertificatesClient
model = Certificate
- def __init__(self, client: CertificatesClient, data: dict, complete: bool = True):
+ def __init__(
+ self,
+ client: CertificatesClient,
+ data: dict[str, Any],
+ complete: bool = True,
+ ):
status = data.get("status")
if status is not None:
error_data = status.get("error")
@@ -36,22 +55,18 @@ class BoundCertificate(BoundModelBase, Certificate):
def get_actions_list(
self,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
page: int | None = None,
per_page: int | None = None,
) -> ActionsPageResult:
- """Returns all action objects for a Certificate.
+ """
+ Returns a paginated list of Actions for a Certificate.
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
- :param page: int (optional)
- Specifies the page to fetch
- :param per_page: int (optional)
- Specifies how many results are returned by page
- :return: (List[:class:`BoundAction `], :class:`Meta `)
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
+ :param page: Page number to get.
+ :param per_page: Maximum number of Actions returned per page.
"""
return self._client.get_actions_list(
self,
@@ -63,16 +78,14 @@ class BoundCertificate(BoundModelBase, Certificate):
def get_actions(
self,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
) -> list[BoundAction]:
- """Returns all action objects for a Certificate.
+ """
+ Returns all Actions for a Certificate.
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
- :return: List[:class:`BoundAction `]
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
"""
return self._client.get_actions(
self,
@@ -117,7 +130,10 @@ class CertificatesPageResult(NamedTuple):
meta: Meta
-class CertificatesClient(ResourceClientBase):
+class CertificatesClient(
+ ResourceClientBaseActionsMixin,
+ ResourceClientBase,
+):
_base_url = "/certificates"
actions: ResourceActionsClient
@@ -306,59 +322,40 @@ class CertificatesClient(ResourceClientBase):
def get_actions_list(
self,
certificate: Certificate | BoundCertificate,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
page: int | None = None,
per_page: int | None = None,
) -> ActionsPageResult:
- """Returns all action objects for a Certificate.
-
- :param certificate: :class:`BoundCertificate ` or :class:`Certificate `
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
- :param page: int (optional)
- Specifies the page to fetch
- :param per_page: int (optional)
- Specifies how many results are returned by page
- :return: (List[:class:`BoundAction `], :class:`Meta `)
"""
- params: dict[str, Any] = {}
- if status is not None:
- params["status"] = status
- if sort is not None:
- params["sort"] = sort
- if page is not None:
- params["page"] = page
- if per_page is not None:
- params["per_page"] = per_page
+ Returns a paginated list of Actions for a Certificate.
- response = self._client.request(
- url=f"{self._base_url}/{certificate.id}/actions",
- method="GET",
- params=params,
+ :param certificate: Certificate to get the Actions for.
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
+ :param page: Page number to get.
+ :param per_page: Maximum number of Actions returned per page.
+ """
+ return self._get_actions_list(
+ f"{self._base_url}/{certificate.id}",
+ status=status,
+ sort=sort,
+ page=page,
+ per_page=per_page,
)
- actions = [
- BoundAction(self._parent.actions, action_data)
- for action_data in response["actions"]
- ]
- return ActionsPageResult(actions, Meta.parse_meta(response))
def get_actions(
self,
certificate: Certificate | BoundCertificate,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
) -> list[BoundAction]:
- """Returns all action objects for a Certificate.
+ """
+ Returns all Actions for a Certificate.
- :param certificate: :class:`BoundCertificate ` or :class:`Certificate `
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
- :return: List[:class:`BoundAction `]
+ :param certificate: Certificate to get the Actions for.
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
"""
return self._iter_pages(
self.get_actions_list,
diff --git a/plugins/module_utils/vendor/hcloud/certificates/domain.py b/plugins/module_utils/vendor/hcloud/certificates/domain.py
index 67daa8e..677ab8f 100644
--- a/plugins/module_utils/vendor/hcloud/certificates/domain.py
+++ b/plugins/module_utils/vendor/hcloud/certificates/domain.py
@@ -2,11 +2,6 @@ from __future__ import annotations
from typing import TYPE_CHECKING
-try:
- from dateutil.parser import isoparse
-except ImportError:
- isoparse = None
-
from ..core import BaseDomain, DomainIdentityMixin
if TYPE_CHECKING:
@@ -14,6 +9,14 @@ if TYPE_CHECKING:
from .client import BoundCertificate
+__all__ = [
+ "Certificate",
+ "ManagedCertificateStatus",
+ "ManagedCertificateError",
+ "CreateManagedCertificateResponse",
+]
+
+
class Certificate(BaseDomain, DomainIdentityMixin):
"""Certificate Domain
@@ -72,9 +75,9 @@ class Certificate(BaseDomain, DomainIdentityMixin):
self.certificate = certificate
self.domain_names = domain_names
self.fingerprint = fingerprint
- self.not_valid_before = isoparse(not_valid_before) if not_valid_before else None
- self.not_valid_after = isoparse(not_valid_after) if not_valid_after else None
- self.created = isoparse(created) if created else None
+ self.not_valid_before = self._parse_datetime(not_valid_before)
+ self.not_valid_after = self._parse_datetime(not_valid_after)
+ self.created = self._parse_datetime(created)
self.labels = labels
self.status = status
diff --git a/plugins/module_utils/vendor/hcloud/core/client.py b/plugins/module_utils/vendor/hcloud/core/client.py
index f0e67a7..4ff7f24 100644
--- a/plugins/module_utils/vendor/hcloud/core/client.py
+++ b/plugins/module_utils/vendor/hcloud/core/client.py
@@ -2,11 +2,22 @@ from __future__ import annotations
import warnings
from collections.abc import Callable
-from typing import TYPE_CHECKING, Any, ClassVar
+from typing import TYPE_CHECKING, Any, ClassVar, Generic, TypeVar
+
+from .domain import BaseDomain
if TYPE_CHECKING:
from .._client import Client, ClientBase
- from .domain import BaseDomain
+ from .domain import Meta
+
+__all__ = [
+ "ResourceClientBase",
+ "ClientEntityBase",
+ "BoundModelBase",
+]
+
+
+T = TypeVar("T")
class ResourceClientBase:
@@ -23,10 +34,10 @@ class ResourceClientBase:
def _iter_pages( # type: ignore[no-untyped-def]
self,
- list_function: Callable,
+ list_function: Callable[..., tuple[list[T], Meta]],
*args,
**kwargs,
- ) -> list:
+ ) -> list[T]:
results = []
page = 1
@@ -46,7 +57,12 @@ class ResourceClientBase:
return results
- def _get_first_by(self, list_function: Callable, *args, **kwargs): # type: ignore[no-untyped-def]
+ def _get_first_by( # type: ignore[no-untyped-def]
+ self,
+ list_function: Callable[..., tuple[list[T], Meta]],
+ *args,
+ **kwargs,
+ ) -> T | None:
entities, _ = list_function(*args, **kwargs)
return entities[0] if entities else None
@@ -69,15 +85,18 @@ class ClientEntityBase(ResourceClientBase):
super().__init__(client)
-class BoundModelBase:
+Domain = TypeVar("Domain", bound=BaseDomain)
+
+
+class BoundModelBase(Generic[Domain]):
"""Bound Model Base"""
- model: type[BaseDomain]
+ model: type[Domain]
def __init__(
self,
client: ResourceClientBase,
- data: dict,
+ data: dict[str, Any],
complete: bool = True,
):
"""
@@ -90,7 +109,7 @@ class BoundModelBase:
"""
self._client = client
self.complete = complete
- self.data_model = self.model.from_dict(data)
+ self.data_model: Domain = self.model.from_dict(data)
def __getattr__(self, name: str): # type: ignore[no-untyped-def]
"""Allow magical access to the properties of the model
@@ -103,9 +122,10 @@ class BoundModelBase:
value = getattr(self.data_model, name)
return value
- def _get_self(self) -> BoundModelBase:
+ def _get_self(self) -> BoundModelBase[Domain]:
assert hasattr(self._client, "get_by_id")
- return self._client.get_by_id(self.data_model.id)
+ assert hasattr(self.data_model, "id")
+ return self._client.get_by_id(self.data_model.id) # type: ignore
def reload(self) -> None:
"""Reloads the model and tries to get all data from the API"""
diff --git a/plugins/module_utils/vendor/hcloud/core/domain.py b/plugins/module_utils/vendor/hcloud/core/domain.py
index b2ac197..a68079b 100644
--- a/plugins/module_utils/vendor/hcloud/core/domain.py
+++ b/plugins/module_utils/vendor/hcloud/core/domain.py
@@ -1,13 +1,26 @@
from __future__ import annotations
-from typing import Any
+from datetime import datetime
+from typing import Any, overload
+
+try:
+ from dateutil.parser import isoparse
+except ImportError:
+ isoparse = None
+
+__all__ = [
+ "BaseDomain",
+ "DomainIdentityMixin",
+ "Pagination",
+ "Meta",
+]
class BaseDomain:
- __api_properties__: tuple
+ __api_properties__: tuple[str, ...]
@classmethod
- def from_dict(cls, data: dict): # type: ignore[no-untyped-def]
+ def from_dict(cls, data: dict[str, Any]): # type: ignore[no-untyped-def]
"""
Build the domain object from the data dict.
"""
@@ -15,7 +28,7 @@ class BaseDomain:
return cls(**supported_data)
def __repr__(self) -> str:
- kwargs = [f"{key}={getattr(self, key)!r}" for key in self.__api_properties__] # type: ignore[var-annotated]
+ kwargs = [f"{key}={getattr(self, key)!r}" for key in self.__api_properties__]
return f"{self.__class__.__qualname__}({', '.join(kwargs)})"
def __eq__(self, other: Any) -> bool:
@@ -27,6 +40,16 @@ class BaseDomain:
return False
return True
+ @overload
+ def _parse_datetime(self, value: str) -> datetime: ...
+ @overload
+ def _parse_datetime(self, value: None) -> None: ...
+
+ def _parse_datetime(self, value: str | None) -> datetime | None:
+ if value is None:
+ return None
+ return isoparse(value)
+
class DomainIdentityMixin:
@@ -106,7 +129,7 @@ class Meta(BaseDomain):
self.pagination = pagination
@classmethod
- def parse_meta(cls, response: dict) -> Meta:
+ def parse_meta(cls, response: dict[str, Any]) -> Meta:
"""
If present, extract the meta details from the response and return a meta object.
"""
diff --git a/plugins/module_utils/vendor/hcloud/datacenters/client.py b/plugins/module_utils/vendor/hcloud/datacenters/client.py
index ae338a5..5d7fe96 100644
--- a/plugins/module_utils/vendor/hcloud/datacenters/client.py
+++ b/plugins/module_utils/vendor/hcloud/datacenters/client.py
@@ -7,13 +7,19 @@ from ..locations import BoundLocation
from ..server_types import BoundServerType
from .domain import Datacenter, DatacenterServerTypes
+__all__ = [
+ "BoundDatacenter",
+ "DatacentersPageResult",
+ "DatacentersClient",
+]
-class BoundDatacenter(BoundModelBase, Datacenter):
+
+class BoundDatacenter(BoundModelBase[Datacenter], Datacenter):
_client: DatacentersClient
model = Datacenter
- def __init__(self, client: DatacentersClient, data: dict):
+ def __init__(self, client: DatacentersClient, data: dict[str, Any]):
location = data.get("location")
if location is not None:
data["location"] = BoundLocation(client._parent.locations, location)
diff --git a/plugins/module_utils/vendor/hcloud/datacenters/domain.py b/plugins/module_utils/vendor/hcloud/datacenters/domain.py
index badd335..4867915 100644
--- a/plugins/module_utils/vendor/hcloud/datacenters/domain.py
+++ b/plugins/module_utils/vendor/hcloud/datacenters/domain.py
@@ -8,6 +8,11 @@ if TYPE_CHECKING:
from ..locations import Location
from ..server_types import BoundServerType
+__all__ = [
+ "Datacenter",
+ "DatacenterServerTypes",
+]
+
class Datacenter(BaseDomain, DomainIdentityMixin):
"""Datacenter Domain
diff --git a/plugins/module_utils/vendor/hcloud/deprecation/__init__.py b/plugins/module_utils/vendor/hcloud/deprecation/__init__.py
index db30b0f..4dd0e91 100644
--- a/plugins/module_utils/vendor/hcloud/deprecation/__init__.py
+++ b/plugins/module_utils/vendor/hcloud/deprecation/__init__.py
@@ -2,4 +2,6 @@ from __future__ import annotations
from .domain import DeprecationInfo
-__all__ = ["DeprecationInfo"]
+__all__ = [
+ "DeprecationInfo",
+]
diff --git a/plugins/module_utils/vendor/hcloud/deprecation/domain.py b/plugins/module_utils/vendor/hcloud/deprecation/domain.py
index 3eb7d50..c78c43e 100644
--- a/plugins/module_utils/vendor/hcloud/deprecation/domain.py
+++ b/plugins/module_utils/vendor/hcloud/deprecation/domain.py
@@ -1,12 +1,11 @@
from __future__ import annotations
-try:
- from dateutil.parser import isoparse
-except ImportError:
- isoparse = None
-
from ..core import BaseDomain
+__all__ = [
+ "DeprecationInfo",
+]
+
class DeprecationInfo(BaseDomain):
"""Describes if, when & how the resources was deprecated. If this field is set to ``None`` the resource is not
@@ -31,7 +30,5 @@ class DeprecationInfo(BaseDomain):
announced: str | None = None,
unavailable_after: str | None = None,
):
- self.announced = isoparse(announced) if announced else None
- self.unavailable_after = (
- isoparse(unavailable_after) if unavailable_after else None
- )
+ self.announced = self._parse_datetime(announced)
+ self.unavailable_after = self._parse_datetime(unavailable_after)
diff --git a/plugins/module_utils/vendor/hcloud/exp/zone.py b/plugins/module_utils/vendor/hcloud/exp/zone.py
index 0860128..c8dd3d0 100644
--- a/plugins/module_utils/vendor/hcloud/exp/zone.py
+++ b/plugins/module_utils/vendor/hcloud/exp/zone.py
@@ -5,6 +5,11 @@ library, breaking changes may occur within minor releases.
from __future__ import annotations
+__all__ = [
+ "is_txt_record_quoted",
+ "format_txt_record",
+]
+
def is_txt_record_quoted(value: str) -> bool:
"""
diff --git a/plugins/module_utils/vendor/hcloud/firewalls/client.py b/plugins/module_utils/vendor/hcloud/firewalls/client.py
index a088947..f314b68 100644
--- a/plugins/module_utils/vendor/hcloud/firewalls/client.py
+++ b/plugins/module_utils/vendor/hcloud/firewalls/client.py
@@ -2,7 +2,14 @@ from __future__ import annotations
from typing import TYPE_CHECKING, Any, NamedTuple
-from ..actions import ActionsPageResult, BoundAction, ResourceActionsClient
+from ..actions import (
+ ActionSort,
+ ActionsPageResult,
+ ActionStatus,
+ BoundAction,
+ ResourceActionsClient,
+)
+from ..actions.client import ResourceClientBaseActionsMixin
from ..core import BoundModelBase, Meta, ResourceClientBase
from .domain import (
CreateFirewallResponse,
@@ -17,12 +24,24 @@ if TYPE_CHECKING:
from .._client import Client
-class BoundFirewall(BoundModelBase, Firewall):
+__all__ = [
+ "BoundFirewall",
+ "FirewallsPageResult",
+ "FirewallsClient",
+]
+
+
+class BoundFirewall(BoundModelBase[Firewall], Firewall):
_client: FirewallsClient
model = Firewall
- def __init__(self, client: FirewallsClient, data: dict, complete: bool = True):
+ def __init__(
+ self,
+ client: FirewallsClient,
+ data: dict[str, Any],
+ complete: bool = True,
+ ):
rules = data.get("rules", [])
if rules:
rules = [
@@ -92,22 +111,18 @@ class BoundFirewall(BoundModelBase, Firewall):
def get_actions_list(
self,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
page: int | None = None,
per_page: int | None = None,
) -> ActionsPageResult:
- """Returns all action objects for a Firewall.
+ """
+ Returns a paginated list of Actions for a Firewall.
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
- :param page: int (optional)
- Specifies the page to fetch
- :param per_page: int (optional)
- Specifies how many results are returned by page
- :return: (List[:class:`BoundAction `], :class:`Meta `)
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
+ :param page: Page number to get.
+ :param per_page: Maximum number of Actions returned per page.
"""
return self._client.get_actions_list(
self,
@@ -119,17 +134,14 @@ class BoundFirewall(BoundModelBase, Firewall):
def get_actions(
self,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
) -> list[BoundAction]:
- """Returns all action objects for a Firewall.
+ """
+ Returns all Actions for a Firewall.
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
-
- :return: List[:class:`BoundAction `]
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
"""
return self._client.get_actions(
self,
@@ -193,7 +205,10 @@ class FirewallsPageResult(NamedTuple):
meta: Meta
-class FirewallsClient(ResourceClientBase):
+class FirewallsClient(
+ ResourceClientBaseActionsMixin,
+ ResourceClientBase,
+):
_base_url = "/firewalls"
actions: ResourceActionsClient
@@ -209,59 +224,40 @@ class FirewallsClient(ResourceClientBase):
def get_actions_list(
self,
firewall: Firewall | BoundFirewall,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
page: int | None = None,
per_page: int | None = None,
) -> ActionsPageResult:
- """Returns all action objects for a Firewall.
-
- :param firewall: :class:`BoundFirewall ` or :class:`Firewall `
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
- :param page: int (optional)
- Specifies the page to fetch
- :param per_page: int (optional)
- Specifies how many results are returned by page
- :return: (List[:class:`BoundAction `], :class:`Meta `)
"""
- params: dict[str, Any] = {}
- if status is not None:
- params["status"] = status
- if sort is not None:
- params["sort"] = sort
- if page is not None:
- params["page"] = page
- if per_page is not None:
- params["per_page"] = per_page
- response = self._client.request(
- url=f"{self._base_url}/{firewall.id}/actions",
- method="GET",
- params=params,
+ Returns a paginated list of Actions for a Firewall.
+
+ :param firewall: Firewall to get the Actions for.
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
+ :param page: Page number to get.
+ :param per_page: Maximum number of Actions returned per page.
+ """
+ return self._get_actions_list(
+ f"{self._base_url}/{firewall.id}",
+ status=status,
+ sort=sort,
+ page=page,
+ per_page=per_page,
)
- actions = [
- BoundAction(self._parent.actions, action_data)
- for action_data in response["actions"]
- ]
- return ActionsPageResult(actions, Meta.parse_meta(response))
def get_actions(
self,
firewall: Firewall | BoundFirewall,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
) -> list[BoundAction]:
- """Returns all action objects for a Firewall.
+ """
+ Returns all Actions for a Firewall.
- :param firewall: :class:`BoundFirewall ` or :class:`Firewall `
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
-
- :return: List[:class:`BoundAction `]
+ :param firewall: Firewall to get the Actions for.
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
"""
return self._iter_pages(
self.get_actions_list,
diff --git a/plugins/module_utils/vendor/hcloud/firewalls/domain.py b/plugins/module_utils/vendor/hcloud/firewalls/domain.py
index a38fb48..76a9b59 100644
--- a/plugins/module_utils/vendor/hcloud/firewalls/domain.py
+++ b/plugins/module_utils/vendor/hcloud/firewalls/domain.py
@@ -2,11 +2,6 @@ from __future__ import annotations
from typing import TYPE_CHECKING, Any
-try:
- from dateutil.parser import isoparse
-except ImportError:
- isoparse = None
-
from ..core import BaseDomain, DomainIdentityMixin
if TYPE_CHECKING:
@@ -15,6 +10,16 @@ if TYPE_CHECKING:
from .client import BoundFirewall
+__all__ = [
+ "Firewall",
+ "FirewallRule",
+ "FirewallResource",
+ "FirewallResourceAppliedToResources",
+ "FirewallResourceLabelSelector",
+ "CreateFirewallResponse",
+]
+
+
class Firewall(BaseDomain, DomainIdentityMixin):
"""Firewall Domain
@@ -49,7 +54,7 @@ class Firewall(BaseDomain, DomainIdentityMixin):
self.rules = rules
self.applied_to = applied_to
self.labels = labels
- self.created = isoparse(created) if created else None
+ self.created = self._parse_datetime(created)
class FirewallRule(BaseDomain):
diff --git a/plugins/module_utils/vendor/hcloud/floating_ips/__init__.py b/plugins/module_utils/vendor/hcloud/floating_ips/__init__.py
index 8c45c77..5ae08fc 100644
--- a/plugins/module_utils/vendor/hcloud/floating_ips/__init__.py
+++ b/plugins/module_utils/vendor/hcloud/floating_ips/__init__.py
@@ -5,12 +5,13 @@ from .client import (
FloatingIPsClient,
FloatingIPsPageResult,
)
-from .domain import CreateFloatingIPResponse, FloatingIP
+from .domain import CreateFloatingIPResponse, FloatingIP, FloatingIPProtection
__all__ = [
"BoundFloatingIP",
"CreateFloatingIPResponse",
"FloatingIP",
+ "FloatingIPProtection",
"FloatingIPsClient",
"FloatingIPsPageResult",
]
diff --git a/plugins/module_utils/vendor/hcloud/floating_ips/client.py b/plugins/module_utils/vendor/hcloud/floating_ips/client.py
index ce28be3..88e7ea4 100644
--- a/plugins/module_utils/vendor/hcloud/floating_ips/client.py
+++ b/plugins/module_utils/vendor/hcloud/floating_ips/client.py
@@ -2,7 +2,14 @@ from __future__ import annotations
from typing import TYPE_CHECKING, Any, NamedTuple
-from ..actions import ActionsPageResult, BoundAction, ResourceActionsClient
+from ..actions import (
+ ActionSort,
+ ActionsPageResult,
+ ActionStatus,
+ BoundAction,
+ ResourceActionsClient,
+)
+from ..actions.client import ResourceClientBaseActionsMixin
from ..core import BoundModelBase, Meta, ResourceClientBase
from ..locations import BoundLocation
from .domain import CreateFloatingIPResponse, FloatingIP
@@ -12,13 +19,24 @@ if TYPE_CHECKING:
from ..locations import Location
from ..servers import BoundServer, Server
+__all__ = [
+ "BoundFloatingIP",
+ "FloatingIPsPageResult",
+ "FloatingIPsClient",
+]
-class BoundFloatingIP(BoundModelBase, FloatingIP):
+
+class BoundFloatingIP(BoundModelBase[FloatingIP], FloatingIP):
_client: FloatingIPsClient
model = FloatingIP
- def __init__(self, client: FloatingIPsClient, data: dict, complete: bool = True):
+ def __init__(
+ self,
+ client: FloatingIPsClient,
+ data: dict[str, Any],
+ complete: bool = True,
+ ):
# pylint: disable=import-outside-toplevel
from ..servers import BoundServer
@@ -38,22 +56,18 @@ class BoundFloatingIP(BoundModelBase, FloatingIP):
def get_actions_list(
self,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
page: int | None = None,
per_page: int | None = None,
) -> ActionsPageResult:
- """Returns all action objects for a Floating IP.
+ """
+ Returns a paginated list of Actions for a Floating IP.
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
- :param page: int (optional)
- Specifies the page to fetch
- :param per_page: int (optional)
- Specifies how many results are returned by page
- :return: (List[:class:`BoundAction `], :class:`Meta `)
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
+ :param page: Page number to get.
+ :param per_page: Maximum number of Actions returned per page.
"""
return self._client.get_actions_list(
self,
@@ -65,16 +79,14 @@ class BoundFloatingIP(BoundModelBase, FloatingIP):
def get_actions(
self,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
) -> list[BoundAction]:
- """Returns all action objects for a Floating IP.
+ """
+ Returns all Actions for a Floating IP.
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
- :return: List[:class:`BoundAction `]
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
"""
return self._client.get_actions(self, status=status, sort=sort)
@@ -147,7 +159,10 @@ class FloatingIPsPageResult(NamedTuple):
meta: Meta
-class FloatingIPsClient(ResourceClientBase):
+class FloatingIPsClient(
+ ResourceClientBaseActionsMixin,
+ ResourceClientBase,
+):
_base_url = "/floating_ips"
actions: ResourceActionsClient
@@ -163,59 +178,40 @@ class FloatingIPsClient(ResourceClientBase):
def get_actions_list(
self,
floating_ip: FloatingIP | BoundFloatingIP,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
page: int | None = None,
per_page: int | None = None,
) -> ActionsPageResult:
- """Returns all action objects for a Floating IP.
-
- :param floating_ip: :class:`BoundFloatingIP ` or :class:`FloatingIP `
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
- :param page: int (optional)
- Specifies the page to fetch
- :param per_page: int (optional)
- Specifies how many results are returned by page
- :return: (List[:class:`BoundAction `], :class:`Meta `)
"""
- params: dict[str, Any] = {}
- if status is not None:
- params["status"] = status
- if sort is not None:
- params["sort"] = sort
- if page is not None:
- params["page"] = page
- if per_page is not None:
- params["per_page"] = per_page
- response = self._client.request(
- url=f"{self._base_url}/{floating_ip.id}/actions",
- method="GET",
- params=params,
+ Returns a paginated list of Actions for a Floating IP.
+
+ :param floating_ip: Floating IP to get the Actions for.
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
+ :param page: Page number to get.
+ :param per_page: Maximum number of Actions returned per page.
+ """
+ return self._get_actions_list(
+ f"{self._base_url}/{floating_ip.id}",
+ status=status,
+ sort=sort,
+ page=page,
+ per_page=per_page,
)
- actions = [
- BoundAction(self._parent.actions, action_data)
- for action_data in response["actions"]
- ]
- return ActionsPageResult(actions, Meta.parse_meta(response))
def get_actions(
self,
floating_ip: FloatingIP | BoundFloatingIP,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
) -> list[BoundAction]:
- """Returns all action objects for a Floating IP.
+ """
+ Returns all Actions for a Floating IP.
- :param floating_ip: :class:`BoundFloatingIP ` or :class:`FloatingIP `
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
-
- :return: List[:class:`BoundAction `]
+ :param floating_ip: Floating IP to get the Actions for.
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
"""
return self._iter_pages(
self.get_actions_list,
diff --git a/plugins/module_utils/vendor/hcloud/floating_ips/domain.py b/plugins/module_utils/vendor/hcloud/floating_ips/domain.py
index e2ef74a..3946da7 100644
--- a/plugins/module_utils/vendor/hcloud/floating_ips/domain.py
+++ b/plugins/module_utils/vendor/hcloud/floating_ips/domain.py
@@ -1,21 +1,24 @@
from __future__ import annotations
-from typing import TYPE_CHECKING
-
-try:
- from dateutil.parser import isoparse
-except ImportError:
- isoparse = None
+from typing import TYPE_CHECKING, TypedDict
from ..core import BaseDomain, DomainIdentityMixin
if TYPE_CHECKING:
from ..actions import BoundAction
from ..locations import BoundLocation
+ from ..rdns import DNSPtr
from ..servers import BoundServer
from .client import BoundFloatingIP
+__all__ = [
+ "FloatingIP",
+ "FloatingIPProtection",
+ "CreateFloatingIPResponse",
+]
+
+
class FloatingIP(BaseDomain, DomainIdentityMixin):
"""Floating IP Domain
@@ -68,10 +71,10 @@ class FloatingIP(BaseDomain, DomainIdentityMixin):
description: str | None = None,
ip: str | None = None,
server: BoundServer | None = None,
- dns_ptr: list[dict] | None = None,
+ dns_ptr: list[DNSPtr] | None = None,
home_location: BoundLocation | None = None,
blocked: bool | None = None,
- protection: dict | None = None,
+ protection: FloatingIPProtection | None = None,
labels: dict[str, str] | None = None,
created: str | None = None,
name: str | None = None,
@@ -86,10 +89,14 @@ class FloatingIP(BaseDomain, DomainIdentityMixin):
self.blocked = blocked
self.protection = protection
self.labels = labels
- self.created = isoparse(created) if created else None
+ self.created = self._parse_datetime(created)
self.name = name
+class FloatingIPProtection(TypedDict):
+ delete: bool
+
+
class CreateFloatingIPResponse(BaseDomain):
"""Create Floating IP Response Domain
diff --git a/plugins/module_utils/vendor/hcloud/helpers/__init__.py b/plugins/module_utils/vendor/hcloud/helpers/__init__.py
index 044703b..e8ec1dc 100644
--- a/plugins/module_utils/vendor/hcloud/helpers/__init__.py
+++ b/plugins/module_utils/vendor/hcloud/helpers/__init__.py
@@ -2,4 +2,6 @@ from __future__ import annotations
from .labels import LabelValidator
-__all__ = ["LabelValidator"]
+__all__ = [
+ "LabelValidator",
+]
diff --git a/plugins/module_utils/vendor/hcloud/helpers/labels.py b/plugins/module_utils/vendor/hcloud/helpers/labels.py
index 3604157..78f4314 100644
--- a/plugins/module_utils/vendor/hcloud/helpers/labels.py
+++ b/plugins/module_utils/vendor/hcloud/helpers/labels.py
@@ -2,6 +2,10 @@ from __future__ import annotations
import re
+__all__ = [
+ "LabelValidator",
+]
+
class LabelValidator:
KEY_REGEX = re.compile(
diff --git a/plugins/module_utils/vendor/hcloud/images/__init__.py b/plugins/module_utils/vendor/hcloud/images/__init__.py
index 071a92b..c299722 100644
--- a/plugins/module_utils/vendor/hcloud/images/__init__.py
+++ b/plugins/module_utils/vendor/hcloud/images/__init__.py
@@ -1,12 +1,13 @@
from __future__ import annotations
from .client import BoundImage, ImagesClient, ImagesPageResult
-from .domain import CreateImageResponse, Image
+from .domain import CreateImageResponse, Image, ImageProtection
__all__ = [
"BoundImage",
"CreateImageResponse",
"Image",
+ "ImageProtection",
"ImagesClient",
"ImagesPageResult",
]
diff --git a/plugins/module_utils/vendor/hcloud/images/client.py b/plugins/module_utils/vendor/hcloud/images/client.py
index b9425b7..2566a96 100644
--- a/plugins/module_utils/vendor/hcloud/images/client.py
+++ b/plugins/module_utils/vendor/hcloud/images/client.py
@@ -3,7 +3,14 @@ from __future__ import annotations
import warnings
from typing import TYPE_CHECKING, Any, NamedTuple
-from ..actions import ActionsPageResult, BoundAction, ResourceActionsClient
+from ..actions import (
+ ActionSort,
+ ActionsPageResult,
+ ActionStatus,
+ BoundAction,
+ ResourceActionsClient,
+)
+from ..actions.client import ResourceClientBaseActionsMixin
from ..core import BoundModelBase, Meta, ResourceClientBase
from .domain import Image
@@ -11,12 +18,23 @@ if TYPE_CHECKING:
from .._client import Client
-class BoundImage(BoundModelBase, Image):
+__all__ = [
+ "BoundImage",
+ "ImagesPageResult",
+ "ImagesClient",
+]
+
+
+class BoundImage(BoundModelBase[Image], Image):
_client: ImagesClient
model = Image
- def __init__(self, client: ImagesClient, data: dict):
+ def __init__(
+ self,
+ client: ImagesClient,
+ data: dict[str, Any],
+ ):
# pylint: disable=import-outside-toplevel
from ..servers import BoundServer
@@ -35,22 +53,18 @@ class BoundImage(BoundModelBase, Image):
def get_actions_list(
self,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
page: int | None = None,
per_page: int | None = None,
- status: list[str] | None = None,
) -> ActionsPageResult:
- """Returns a list of action objects for the image.
+ """
+ Returns a paginated list of Actions for a Image.
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
- :param page: int (optional)
- Specifies the page to fetch
- :param per_page: int (optional)
- Specifies how many results are returned by page
- :return: (List[:class:`BoundAction `], :class:`Meta `)
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
+ :param page: Page number to get.
+ :param per_page: Maximum number of Actions returned per page.
"""
return self._client.get_actions_list(
self,
@@ -62,16 +76,14 @@ class BoundImage(BoundModelBase, Image):
def get_actions(
self,
- sort: list[str] | None = None,
- status: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
) -> list[BoundAction]:
- """Returns all action objects for the image.
+ """
+ Returns all Actions for a Image.
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
- :return: List[:class:`BoundAction `]
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
"""
return self._client.get_actions(
self,
@@ -122,7 +134,10 @@ class ImagesPageResult(NamedTuple):
meta: Meta
-class ImagesClient(ResourceClientBase):
+class ImagesClient(
+ ResourceClientBaseActionsMixin,
+ ResourceClientBase,
+):
_base_url = "/images"
actions: ResourceActionsClient
@@ -138,64 +153,46 @@ class ImagesClient(ResourceClientBase):
def get_actions_list(
self,
image: Image | BoundImage,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
page: int | None = None,
per_page: int | None = None,
- status: list[str] | None = None,
) -> ActionsPageResult:
- """Returns a list of action objects for an image.
-
- :param image: :class:`BoundImage ` or :class:`Image `
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
- :param page: int (optional)
- Specifies the page to fetch
- :param per_page: int (optional)
- Specifies how many results are returned by page
- :return: (List[:class:`BoundAction `], :class:`Meta `)
"""
- params: dict[str, Any] = {}
- if sort is not None:
- params["sort"] = sort
- if status is not None:
- params["status"] = status
- if page is not None:
- params["page"] = page
- if per_page is not None:
- params["per_page"] = per_page
- response = self._client.request(
- url=f"{self._base_url}/{image.id}/actions",
- method="GET",
- params=params,
+ Returns a paginated list of Actions for a Image.
+
+ :param image: Image to get the Actions for.
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
+ :param page: Page number to get.
+ :param per_page: Maximum number of Actions returned per page.
+ """
+ return self._get_actions_list(
+ f"{self._base_url}/{image.id}",
+ status=status,
+ sort=sort,
+ page=page,
+ per_page=per_page,
)
- actions = [
- BoundAction(self._parent.actions, action_data)
- for action_data in response["actions"]
- ]
- return ActionsPageResult(actions, Meta.parse_meta(response))
def get_actions(
self,
image: Image | BoundImage,
- sort: list[str] | None = None,
- status: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
) -> list[BoundAction]:
- """Returns all action objects for an image.
+ """
+ Returns all Actions for a Image.
- :param image: :class:`BoundImage ` or :class:`Image `
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `command` `status` `progress` `started` `finished` . You can add one of ":asc", ":desc" to modify sort order. ( ":asc" is default)
- :return: List[:class:`BoundAction `]
+ :param image: Image to get the Actions for.
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
"""
return self._iter_pages(
self.get_actions_list,
image,
- sort=sort,
status=status,
+ sort=sort,
)
def get_by_id(self, id: int) -> BoundImage:
diff --git a/plugins/module_utils/vendor/hcloud/images/domain.py b/plugins/module_utils/vendor/hcloud/images/domain.py
index 907fa7b..915ace6 100644
--- a/plugins/module_utils/vendor/hcloud/images/domain.py
+++ b/plugins/module_utils/vendor/hcloud/images/domain.py
@@ -1,11 +1,6 @@
from __future__ import annotations
-from typing import TYPE_CHECKING
-
-try:
- from dateutil.parser import isoparse
-except ImportError:
- isoparse = None
+from typing import TYPE_CHECKING, TypedDict
from ..core import BaseDomain, DomainIdentityMixin
@@ -15,6 +10,13 @@ if TYPE_CHECKING:
from .client import BoundImage
+__all__ = [
+ "Image",
+ "ImageProtection",
+ "CreateImageResponse",
+]
+
+
class Image(BaseDomain, DomainIdentityMixin):
"""Image Domain
@@ -92,18 +94,18 @@ class Image(BaseDomain, DomainIdentityMixin):
architecture: str | None = None,
rapid_deploy: bool | None = None,
created_from: Server | BoundServer | None = None,
- protection: dict | None = None,
+ protection: ImageProtection | None = None,
labels: dict[str, str] | None = None,
status: str | None = None,
):
self.id = id
self.name = name
self.type = type
- self.created = isoparse(created) if created else None
+ self.created = self._parse_datetime(created)
self.description = description
self.image_size = image_size
self.disk_size = disk_size
- self.deprecated = isoparse(deprecated) if deprecated else None
+ self.deprecated = self._parse_datetime(deprecated)
self.bound_to = bound_to
self.os_flavor = os_flavor
self.os_version = os_version
@@ -115,6 +117,10 @@ class Image(BaseDomain, DomainIdentityMixin):
self.status = status
+class ImageProtection(TypedDict):
+ delete: bool
+
+
class CreateImageResponse(BaseDomain):
"""Create Image Response Domain
diff --git a/plugins/module_utils/vendor/hcloud/isos/client.py b/plugins/module_utils/vendor/hcloud/isos/client.py
index d5e4496..b9c3a5a 100644
--- a/plugins/module_utils/vendor/hcloud/isos/client.py
+++ b/plugins/module_utils/vendor/hcloud/isos/client.py
@@ -5,8 +5,14 @@ from typing import Any, NamedTuple
from ..core import BoundModelBase, Meta, ResourceClientBase
from .domain import Iso
+__all__ = [
+ "BoundIso",
+ "IsosPageResult",
+ "IsosClient",
+]
-class BoundIso(BoundModelBase, Iso):
+
+class BoundIso(BoundModelBase[Iso], Iso):
_client: IsosClient
model = Iso
diff --git a/plugins/module_utils/vendor/hcloud/isos/domain.py b/plugins/module_utils/vendor/hcloud/isos/domain.py
index 2a5667e..5fd50c6 100644
--- a/plugins/module_utils/vendor/hcloud/isos/domain.py
+++ b/plugins/module_utils/vendor/hcloud/isos/domain.py
@@ -1,11 +1,16 @@
from __future__ import annotations
from datetime import datetime
+from typing import Any
from warnings import warn
from ..core import BaseDomain, DomainIdentityMixin
from ..deprecation import DeprecationInfo
+__all__ = [
+ "Iso",
+]
+
class Iso(BaseDomain, DomainIdentityMixin):
"""Iso Domain
@@ -45,7 +50,7 @@ class Iso(BaseDomain, DomainIdentityMixin):
architecture: str | None = None,
description: str | None = None,
deprecated: str | None = None, # pylint: disable=unused-argument
- deprecation: dict | None = None,
+ deprecation: dict[str, Any] | None = None,
):
self.id = id
self.name = name
@@ -67,4 +72,4 @@ class Iso(BaseDomain, DomainIdentityMixin):
)
if self.deprecation is None:
return None
- return self.deprecation.unavailable_after
+ return self.deprecation.unavailable_after # type: ignore[no-any-return]
diff --git a/plugins/module_utils/vendor/hcloud/load_balancer_types/client.py b/plugins/module_utils/vendor/hcloud/load_balancer_types/client.py
index fbfb08d..87d44e2 100644
--- a/plugins/module_utils/vendor/hcloud/load_balancer_types/client.py
+++ b/plugins/module_utils/vendor/hcloud/load_balancer_types/client.py
@@ -5,8 +5,14 @@ from typing import Any, NamedTuple
from ..core import BoundModelBase, Meta, ResourceClientBase
from .domain import LoadBalancerType
+__all__ = [
+ "BoundLoadBalancerType",
+ "LoadBalancerTypesPageResult",
+ "LoadBalancerTypesClient",
+]
-class BoundLoadBalancerType(BoundModelBase, LoadBalancerType):
+
+class BoundLoadBalancerType(BoundModelBase[LoadBalancerType], LoadBalancerType):
_client: LoadBalancerTypesClient
model = LoadBalancerType
diff --git a/plugins/module_utils/vendor/hcloud/load_balancer_types/domain.py b/plugins/module_utils/vendor/hcloud/load_balancer_types/domain.py
index 9142cb5..1e594e9 100644
--- a/plugins/module_utils/vendor/hcloud/load_balancer_types/domain.py
+++ b/plugins/module_utils/vendor/hcloud/load_balancer_types/domain.py
@@ -1,7 +1,13 @@
from __future__ import annotations
+from typing import Any
+
from ..core import BaseDomain, DomainIdentityMixin
+__all__ = [
+ "LoadBalancerType",
+]
+
class LoadBalancerType(BaseDomain, DomainIdentityMixin):
"""LoadBalancerType Domain
@@ -46,7 +52,7 @@ class LoadBalancerType(BaseDomain, DomainIdentityMixin):
max_services: int | None = None,
max_targets: int | None = None,
max_assigned_certificates: int | None = None,
- prices: list[dict] | None = None,
+ prices: list[dict[str, Any]] | None = None,
):
self.id = id
self.name = name
diff --git a/plugins/module_utils/vendor/hcloud/load_balancers/__init__.py b/plugins/module_utils/vendor/hcloud/load_balancers/__init__.py
index f84c7e2..9b07d02 100644
--- a/plugins/module_utils/vendor/hcloud/load_balancers/__init__.py
+++ b/plugins/module_utils/vendor/hcloud/load_balancers/__init__.py
@@ -15,12 +15,14 @@ from .domain import (
LoadBalancerHealtCheckHttp,
LoadBalancerHealthCheck,
LoadBalancerHealthCheckHttp,
+ LoadBalancerProtection,
LoadBalancerService,
LoadBalancerServiceHttp,
LoadBalancerTarget,
LoadBalancerTargetHealthStatus,
LoadBalancerTargetIP,
LoadBalancerTargetLabelSelector,
+ MetricsType,
PrivateNet,
PublicNetwork,
)
@@ -32,6 +34,7 @@ __all__ = [
"IPv4Address",
"IPv6Network",
"LoadBalancer",
+ "LoadBalancerProtection",
"LoadBalancerAlgorithm",
"LoadBalancerHealtCheckHttp",
"LoadBalancerHealthCheckHttp",
@@ -46,4 +49,5 @@ __all__ = [
"LoadBalancersPageResult",
"PrivateNet",
"PublicNetwork",
+ "MetricsType",
]
diff --git a/plugins/module_utils/vendor/hcloud/load_balancers/client.py b/plugins/module_utils/vendor/hcloud/load_balancers/client.py
index 45c7464..c711fc2 100644
--- a/plugins/module_utils/vendor/hcloud/load_balancers/client.py
+++ b/plugins/module_utils/vendor/hcloud/load_balancers/client.py
@@ -8,7 +8,14 @@ try:
except ImportError:
isoparse = None
-from ..actions import ActionsPageResult, BoundAction, ResourceActionsClient
+from ..actions import (
+ ActionSort,
+ ActionsPageResult,
+ ActionStatus,
+ BoundAction,
+ ResourceActionsClient,
+)
+from ..actions.client import ResourceClientBaseActionsMixin
from ..certificates import BoundCertificate
from ..core import BoundModelBase, Meta, ResourceClientBase
from ..load_balancer_types import BoundLoadBalancerType
@@ -43,13 +50,25 @@ if TYPE_CHECKING:
from ..networks import Network
-class BoundLoadBalancer(BoundModelBase, LoadBalancer):
+__all__ = [
+ "BoundLoadBalancer",
+ "LoadBalancersPageResult",
+ "LoadBalancersClient",
+]
+
+
+class BoundLoadBalancer(BoundModelBase[LoadBalancer], LoadBalancer):
_client: LoadBalancersClient
model = LoadBalancer
# pylint: disable=too-many-branches,too-many-locals
- def __init__(self, client: LoadBalancersClient, data: dict, complete: bool = True):
+ def __init__(
+ self,
+ client: LoadBalancersClient,
+ data: dict[str, Any],
+ complete: bool = True,
+ ):
algorithm = data.get("algorithm")
if algorithm:
data["algorithm"] = LoadBalancerAlgorithm(type=algorithm["type"])
@@ -210,22 +229,18 @@ class BoundLoadBalancer(BoundModelBase, LoadBalancer):
def get_actions_list(
self,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
page: int | None = None,
per_page: int | None = None,
) -> ActionsPageResult:
- """Returns all action objects for a Load Balancer.
+ """
+ Returns a paginated list of Actions for a Load Balancer.
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
- :param page: int (optional)
- Specifies the page to fetch
- :param per_page: int (optional)
- Specifies how many results are returned by page
- :return: (List[:class:`BoundAction `], :class:`Meta `)
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
+ :param page: Page number to get.
+ :param per_page: Maximum number of Actions returned per page.
"""
return self._client.get_actions_list(
self,
@@ -237,16 +252,14 @@ class BoundLoadBalancer(BoundModelBase, LoadBalancer):
def get_actions(
self,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
) -> list[BoundAction]:
- """Returns all action objects for a Load Balancer.
+ """
+ Returns all Actions for a Load Balancer.
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
- :return: List[:class:`BoundAction `]
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
"""
return self._client.get_actions(self, status=status, sort=sort)
@@ -386,7 +399,10 @@ class LoadBalancersPageResult(NamedTuple):
meta: Meta
-class LoadBalancersClient(ResourceClientBase):
+class LoadBalancersClient(
+ ResourceClientBaseActionsMixin,
+ ResourceClientBase,
+):
_base_url = "/load_balancers"
actions: ResourceActionsClient
@@ -619,59 +635,40 @@ class LoadBalancersClient(ResourceClientBase):
def get_actions_list(
self,
load_balancer: LoadBalancer | BoundLoadBalancer,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
page: int | None = None,
per_page: int | None = None,
) -> ActionsPageResult:
- """Returns all action objects for a Load Balancer.
-
- :param load_balancer: :class:`BoundLoadBalancer ` or :class:`LoadBalancer `
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
- :param page: int (optional)
- Specifies the page to fetch
- :param per_page: int (optional)
- Specifies how many results are returned by page
- :return: (List[:class:`BoundAction `], :class:`Meta `)
"""
- params: dict[str, Any] = {}
- if status is not None:
- params["status"] = status
- if sort is not None:
- params["sort"] = sort
- if page is not None:
- params["page"] = page
- if per_page is not None:
- params["per_page"] = per_page
+ Returns a paginated list of Actions for a Load Balancer.
- response = self._client.request(
- url=f"{self._base_url}/{load_balancer.id}/actions",
- method="GET",
- params=params,
+ :param load_balancer: Load Balancer to get the Actions for.
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
+ :param page: Page number to get.
+ :param per_page: Maximum number of Actions returned per page.
+ """
+ return self._get_actions_list(
+ f"{self._base_url}/{load_balancer.id}",
+ status=status,
+ sort=sort,
+ page=page,
+ per_page=per_page,
)
- actions = [
- BoundAction(self._parent.actions, action_data)
- for action_data in response["actions"]
- ]
- return ActionsPageResult(actions, Meta.parse_meta(response))
def get_actions(
self,
load_balancer: LoadBalancer | BoundLoadBalancer,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
) -> list[BoundAction]:
- """Returns all action objects for a Load Balancer.
+ """
+ Returns all Actions for a Load Balancer.
- :param load_balancer: :class:`BoundLoadBalancer ` or :class:`LoadBalancer `
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
- :return: List[:class:`BoundAction `]
+ :param load_balancer: Load Balancer to get the Actions for.
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
"""
return self._iter_pages(
self.get_actions_list,
diff --git a/plugins/module_utils/vendor/hcloud/load_balancers/domain.py b/plugins/module_utils/vendor/hcloud/load_balancers/domain.py
index d2a9adc..c02e110 100644
--- a/plugins/module_utils/vendor/hcloud/load_balancers/domain.py
+++ b/plugins/module_utils/vendor/hcloud/load_balancers/domain.py
@@ -1,12 +1,7 @@
from __future__ import annotations
import warnings
-from typing import TYPE_CHECKING, Any, Literal
-
-try:
- from dateutil.parser import isoparse
-except ImportError:
- isoparse = None
+from typing import TYPE_CHECKING, Any, Literal, TypedDict
from ..core import BaseDomain, DomainIdentityMixin
@@ -21,6 +16,29 @@ if TYPE_CHECKING:
from .client import BoundLoadBalancer
+__all__ = [
+ "LoadBalancer",
+ "LoadBalancerProtection",
+ "LoadBalancerService",
+ "LoadBalancerServiceHttp",
+ "LoadBalancerHealthCheck",
+ "LoadBalancerHealthCheckHttp",
+ "LoadBalancerHealtCheckHttp",
+ "LoadBalancerTarget",
+ "LoadBalancerTargetHealthStatus",
+ "LoadBalancerTargetLabelSelector",
+ "LoadBalancerTargetIP",
+ "LoadBalancerAlgorithm",
+ "PublicNetwork",
+ "IPv4Address",
+ "IPv6Network",
+ "PrivateNet",
+ "CreateLoadBalancerResponse",
+ "GetMetricsResponse",
+ "MetricsType",
+]
+
+
class LoadBalancer(BaseDomain, DomainIdentityMixin):
"""LoadBalancer Domain
@@ -86,7 +104,7 @@ class LoadBalancer(BaseDomain, DomainIdentityMixin):
algorithm: LoadBalancerAlgorithm | None = None,
services: list[LoadBalancerService] | None = None,
load_balancer_type: BoundLoadBalancerType | None = None,
- protection: dict | None = None,
+ protection: LoadBalancerProtection | None = None,
labels: dict[str, str] | None = None,
targets: list[LoadBalancerTarget] | None = None,
created: str | None = None,
@@ -96,7 +114,7 @@ class LoadBalancer(BaseDomain, DomainIdentityMixin):
):
self.id = id
self.name = name
- self.created = isoparse(created) if created else None
+ self.created = self._parse_datetime(created)
self.public_net = public_net
self.private_net = private_net
self.location = location
@@ -121,6 +139,10 @@ class LoadBalancer(BaseDomain, DomainIdentityMixin):
return None
+class LoadBalancerProtection(TypedDict):
+ delete: bool
+
+
class LoadBalancerService(BaseDomain):
"""LoadBalancerService Domain
@@ -339,7 +361,7 @@ class LoadBalancerHealthCheckHttp(BaseDomain):
domain: str | None = None,
path: str | None = None,
response: str | None = None,
- status_codes: list | None = None,
+ status_codes: list[str] | None = None,
tls: bool | None = None,
):
self.domain = domain
@@ -362,7 +384,7 @@ class LoadBalancerHealtCheckHttp(LoadBalancerHealthCheckHttp):
domain: str | None = None,
path: str | None = None,
response: str | None = None,
- status_codes: list | None = None,
+ status_codes: list[str] | None = None,
tls: bool | None = None,
):
warnings.warn(
diff --git a/plugins/module_utils/vendor/hcloud/locations/client.py b/plugins/module_utils/vendor/hcloud/locations/client.py
index e6f685d..5a71c0f 100644
--- a/plugins/module_utils/vendor/hcloud/locations/client.py
+++ b/plugins/module_utils/vendor/hcloud/locations/client.py
@@ -5,8 +5,14 @@ from typing import Any, NamedTuple
from ..core import BoundModelBase, Meta, ResourceClientBase
from .domain import Location
+__all__ = [
+ "BoundLocation",
+ "LocationsPageResult",
+ "LocationsClient",
+]
-class BoundLocation(BoundModelBase, Location):
+
+class BoundLocation(BoundModelBase[Location], Location):
_client: LocationsClient
model = Location
diff --git a/plugins/module_utils/vendor/hcloud/locations/domain.py b/plugins/module_utils/vendor/hcloud/locations/domain.py
index dcdf7a9..b33b157 100644
--- a/plugins/module_utils/vendor/hcloud/locations/domain.py
+++ b/plugins/module_utils/vendor/hcloud/locations/domain.py
@@ -2,6 +2,10 @@ from __future__ import annotations
from ..core import BaseDomain, DomainIdentityMixin
+__all__ = [
+ "Location",
+]
+
class Location(BaseDomain, DomainIdentityMixin):
"""Location Domain
diff --git a/plugins/module_utils/vendor/hcloud/metrics/domain.py b/plugins/module_utils/vendor/hcloud/metrics/domain.py
index 7f29128..3213e27 100644
--- a/plugins/module_utils/vendor/hcloud/metrics/domain.py
+++ b/plugins/module_utils/vendor/hcloud/metrics/domain.py
@@ -3,13 +3,14 @@ from __future__ import annotations
from datetime import datetime
from typing import Literal
-try:
- from dateutil.parser import isoparse
-except ImportError:
- isoparse = None
-
from ..core import BaseDomain
+__all__ = [
+ "TimeSeries",
+ "Metrics",
+]
+
+
TimeSeries = dict[str, dict[Literal["values"], list[tuple[float, str]]]]
@@ -44,7 +45,7 @@ class Metrics(BaseDomain):
step: float,
time_series: TimeSeries,
):
- self.start = isoparse(start)
- self.end = isoparse(end)
+ self.start = self._parse_datetime(start)
+ self.end = self._parse_datetime(end)
self.step = step
self.time_series = time_series
diff --git a/plugins/module_utils/vendor/hcloud/networks/__init__.py b/plugins/module_utils/vendor/hcloud/networks/__init__.py
index fc86564..f49b993 100644
--- a/plugins/module_utils/vendor/hcloud/networks/__init__.py
+++ b/plugins/module_utils/vendor/hcloud/networks/__init__.py
@@ -4,6 +4,7 @@ from .client import BoundNetwork, NetworksClient, NetworksPageResult
from .domain import (
CreateNetworkResponse,
Network,
+ NetworkProtection,
NetworkRoute,
NetworkSubnet,
)
@@ -12,6 +13,7 @@ __all__ = [
"BoundNetwork",
"CreateNetworkResponse",
"Network",
+ "NetworkProtection",
"NetworkRoute",
"NetworkSubnet",
"NetworksClient",
diff --git a/plugins/module_utils/vendor/hcloud/networks/client.py b/plugins/module_utils/vendor/hcloud/networks/client.py
index abef2b6..73b33e5 100644
--- a/plugins/module_utils/vendor/hcloud/networks/client.py
+++ b/plugins/module_utils/vendor/hcloud/networks/client.py
@@ -2,7 +2,14 @@ from __future__ import annotations
from typing import TYPE_CHECKING, Any, NamedTuple
-from ..actions import ActionsPageResult, BoundAction, ResourceActionsClient
+from ..actions import (
+ ActionSort,
+ ActionsPageResult,
+ ActionStatus,
+ BoundAction,
+ ResourceActionsClient,
+)
+from ..actions.client import ResourceClientBaseActionsMixin
from ..core import BoundModelBase, Meta, ResourceClientBase
from .domain import Network, NetworkRoute, NetworkSubnet
@@ -10,12 +17,24 @@ if TYPE_CHECKING:
from .._client import Client
-class BoundNetwork(BoundModelBase, Network):
+__all__ = [
+ "BoundNetwork",
+ "NetworksPageResult",
+ "NetworksClient",
+]
+
+
+class BoundNetwork(BoundModelBase[Network], Network):
_client: NetworksClient
model = Network
- def __init__(self, client: NetworksClient, data: dict, complete: bool = True):
+ def __init__(
+ self,
+ client: NetworksClient,
+ data: dict[str, Any],
+ complete: bool = True,
+ ):
subnets = data.get("subnets", [])
if subnets is not None:
subnets = [NetworkSubnet.from_dict(subnet) for subnet in subnets]
@@ -72,22 +91,18 @@ class BoundNetwork(BoundModelBase, Network):
def get_actions_list(
self,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
page: int | None = None,
per_page: int | None = None,
) -> ActionsPageResult:
- """Returns all action objects for a network.
+ """
+ Returns a paginated list of Actions for a Network.
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
- :param page: int (optional)
- Specifies the page to fetch
- :param per_page: int (optional)
- Specifies how many results are returned by page
- :return: (List[:class:`BoundAction `], :class:`Meta `)
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
+ :param page: Page number to get.
+ :param per_page: Maximum number of Actions returned per page.
"""
return self._client.get_actions_list(
self,
@@ -99,16 +114,14 @@ class BoundNetwork(BoundModelBase, Network):
def get_actions(
self,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
) -> list[BoundAction]:
- """Returns all action objects for a network.
+ """
+ Returns all Actions for a Network.
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
- :return: List[:class:`BoundAction `]
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
"""
return self._client.get_actions(self, status=status, sort=sort)
@@ -172,7 +185,10 @@ class NetworksPageResult(NamedTuple):
meta: Meta
-class NetworksClient(ResourceClientBase):
+class NetworksClient(
+ ResourceClientBaseActionsMixin,
+ ResourceClientBase,
+):
_base_url = "/networks"
actions: ResourceActionsClient
@@ -359,59 +375,40 @@ class NetworksClient(ResourceClientBase):
def get_actions_list(
self,
network: Network | BoundNetwork,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
page: int | None = None,
per_page: int | None = None,
) -> ActionsPageResult:
- """Returns all action objects for a network.
-
- :param network: :class:`BoundNetwork ` or :class:`Network `
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
- :param page: int (optional)
- Specifies the page to fetch
- :param per_page: int (optional)
- Specifies how many results are returned by page
- :return: (List[:class:`BoundAction `], :class:`Meta `)
"""
- params: dict[str, Any] = {}
- if status is not None:
- params["status"] = status
- if sort is not None:
- params["sort"] = sort
- if page is not None:
- params["page"] = page
- if per_page is not None:
- params["per_page"] = per_page
+ Returns a paginated list of Actions for a Network.
- response = self._client.request(
- url=f"{self._base_url}/{network.id}/actions",
- method="GET",
- params=params,
+ :param network: Network to get the Actions for.
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
+ :param page: Page number to get.
+ :param per_page: Maximum number of Actions returned per page.
+ """
+ return self._get_actions_list(
+ f"{self._base_url}/{network.id}",
+ status=status,
+ sort=sort,
+ page=page,
+ per_page=per_page,
)
- actions = [
- BoundAction(self._parent.actions, action_data)
- for action_data in response["actions"]
- ]
- return ActionsPageResult(actions, Meta.parse_meta(response))
def get_actions(
self,
network: Network | BoundNetwork,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
) -> list[BoundAction]:
- """Returns all action objects for a network.
+ """
+ Returns all Actions for a Network.
- :param network: :class:`BoundNetwork ` or :class:`Network `
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
- :return: List[:class:`BoundAction `]
+ :param network: Network to get the Actions for.
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
"""
return self._iter_pages(
self.get_actions_list,
diff --git a/plugins/module_utils/vendor/hcloud/networks/domain.py b/plugins/module_utils/vendor/hcloud/networks/domain.py
index 3c5f02d..80c3bad 100644
--- a/plugins/module_utils/vendor/hcloud/networks/domain.py
+++ b/plugins/module_utils/vendor/hcloud/networks/domain.py
@@ -1,12 +1,7 @@
from __future__ import annotations
import warnings
-from typing import TYPE_CHECKING
-
-try:
- from dateutil.parser import isoparse
-except ImportError:
- isoparse = None
+from typing import TYPE_CHECKING, TypedDict
from ..core import BaseDomain, DomainIdentityMixin
@@ -15,6 +10,14 @@ if TYPE_CHECKING:
from ..servers import BoundServer
from .client import BoundNetwork
+__all__ = [
+ "Network",
+ "NetworkProtection",
+ "NetworkSubnet",
+ "NetworkRoute",
+ "CreateNetworkResponse",
+]
+
class Network(BaseDomain, DomainIdentityMixin):
"""Network Domain
@@ -63,12 +66,12 @@ class Network(BaseDomain, DomainIdentityMixin):
routes: list[NetworkRoute] | None = None,
expose_routes_to_vswitch: bool | None = None,
servers: list[BoundServer] | None = None,
- protection: dict | None = None,
+ protection: NetworkProtection | None = None,
labels: dict[str, str] | None = None,
):
self.id = id
self.name = name
- self.created = isoparse(created) if created else None
+ self.created = self._parse_datetime(created)
self.ip_range = ip_range
self.subnets = subnets
self.routes = routes
@@ -78,6 +81,10 @@ class Network(BaseDomain, DomainIdentityMixin):
self.labels = labels
+class NetworkProtection(TypedDict):
+ delete: bool
+
+
class NetworkSubnet(BaseDomain):
"""Network Subnet Domain
@@ -116,7 +123,7 @@ class NetworkSubnet(BaseDomain):
"""
Used to connect cloud servers and load balancers with dedicated servers.
- See https://docs.hetzner.com/cloud/networks/connect-dedi-vswitch/
+ See https://docs.hetzner.com/networking/networks/connect-dedi-vswitch/
"""
__api_properties__ = ("type", "ip_range", "network_zone", "gateway", "vswitch_id")
diff --git a/plugins/module_utils/vendor/hcloud/placement_groups/client.py b/plugins/module_utils/vendor/hcloud/placement_groups/client.py
index 9493934..041118d 100644
--- a/plugins/module_utils/vendor/hcloud/placement_groups/client.py
+++ b/plugins/module_utils/vendor/hcloud/placement_groups/client.py
@@ -6,8 +6,14 @@ from ..actions import BoundAction
from ..core import BoundModelBase, Meta, ResourceClientBase
from .domain import CreatePlacementGroupResponse, PlacementGroup
+__all__ = [
+ "BoundPlacementGroup",
+ "PlacementGroupsPageResult",
+ "PlacementGroupsClient",
+]
-class BoundPlacementGroup(BoundModelBase, PlacementGroup):
+
+class BoundPlacementGroup(BoundModelBase[PlacementGroup], PlacementGroup):
_client: PlacementGroupsClient
model = PlacementGroup
diff --git a/plugins/module_utils/vendor/hcloud/placement_groups/domain.py b/plugins/module_utils/vendor/hcloud/placement_groups/domain.py
index 950eeba..1dc9b9d 100644
--- a/plugins/module_utils/vendor/hcloud/placement_groups/domain.py
+++ b/plugins/module_utils/vendor/hcloud/placement_groups/domain.py
@@ -2,17 +2,17 @@ from __future__ import annotations
from typing import TYPE_CHECKING
-try:
- from dateutil.parser import isoparse
-except ImportError:
- isoparse = None
-
from ..core import BaseDomain, DomainIdentityMixin
if TYPE_CHECKING:
from ..actions import BoundAction
from .client import BoundPlacementGroup
+__all__ = [
+ "PlacementGroup",
+ "CreatePlacementGroupResponse",
+]
+
class PlacementGroup(BaseDomain, DomainIdentityMixin):
"""Placement Group Domain
@@ -53,7 +53,7 @@ class PlacementGroup(BaseDomain, DomainIdentityMixin):
self.labels = labels
self.servers = servers
self.type = type
- self.created = isoparse(created) if created else None
+ self.created = self._parse_datetime(created)
class CreatePlacementGroupResponse(BaseDomain):
diff --git a/plugins/module_utils/vendor/hcloud/primary_ips/__init__.py b/plugins/module_utils/vendor/hcloud/primary_ips/__init__.py
index 3dc5ed0..9997404 100644
--- a/plugins/module_utils/vendor/hcloud/primary_ips/__init__.py
+++ b/plugins/module_utils/vendor/hcloud/primary_ips/__init__.py
@@ -1,12 +1,13 @@
from __future__ import annotations
from .client import BoundPrimaryIP, PrimaryIPsClient, PrimaryIPsPageResult
-from .domain import CreatePrimaryIPResponse, PrimaryIP
+from .domain import CreatePrimaryIPResponse, PrimaryIP, PrimaryIPProtection
__all__ = [
"BoundPrimaryIP",
"CreatePrimaryIPResponse",
"PrimaryIP",
+ "PrimaryIPProtection",
"PrimaryIPsClient",
"PrimaryIPsPageResult",
]
diff --git a/plugins/module_utils/vendor/hcloud/primary_ips/client.py b/plugins/module_utils/vendor/hcloud/primary_ips/client.py
index eb5d30d..6d6693d 100644
--- a/plugins/module_utils/vendor/hcloud/primary_ips/client.py
+++ b/plugins/module_utils/vendor/hcloud/primary_ips/client.py
@@ -1,31 +1,97 @@
from __future__ import annotations
+import warnings
from typing import TYPE_CHECKING, Any, NamedTuple
-from ..actions import BoundAction, ResourceActionsClient
+from ..actions import (
+ ActionSort,
+ ActionsPageResult,
+ ActionStatus,
+ BoundAction,
+ ResourceActionsClient,
+)
+from ..actions.client import ResourceClientBaseActionsMixin
from ..core import BoundModelBase, Meta, ResourceClientBase
from .domain import CreatePrimaryIPResponse, PrimaryIP
if TYPE_CHECKING:
from .._client import Client
from ..datacenters import BoundDatacenter, Datacenter
+ from ..locations import BoundLocation, Location
-class BoundPrimaryIP(BoundModelBase, PrimaryIP):
+__all__ = [
+ "BoundPrimaryIP",
+ "PrimaryIPsPageResult",
+ "PrimaryIPsClient",
+]
+
+
+class BoundPrimaryIP(BoundModelBase[PrimaryIP], PrimaryIP):
_client: PrimaryIPsClient
model = PrimaryIP
- def __init__(self, client: PrimaryIPsClient, data: dict, complete: bool = True):
+ def __init__(
+ self,
+ client: PrimaryIPsClient,
+ data: dict[str, Any],
+ complete: bool = True,
+ ):
# pylint: disable=import-outside-toplevel
from ..datacenters import BoundDatacenter
+ from ..locations import BoundLocation
- datacenter = data.get("datacenter", {})
- if datacenter:
- data["datacenter"] = BoundDatacenter(client._parent.datacenters, datacenter)
+ raw = data.get("datacenter", {})
+ if raw:
+ data["datacenter"] = BoundDatacenter(client._parent.datacenters, raw)
+
+ raw = data.get("location", {})
+ if raw:
+ data["location"] = BoundLocation(client._parent.locations, raw)
super().__init__(client, data, complete)
+ def get_actions_list(
+ self,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
+ page: int | None = None,
+ per_page: int | None = None,
+ ) -> ActionsPageResult:
+ """
+ Returns a paginated list of Actions for a Primary IP.
+
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
+ :param page: Page number to get.
+ :param per_page: Maximum number of Actions returned per page.
+ """
+ return self._client.get_actions_list(
+ self,
+ status=status,
+ sort=sort,
+ page=page,
+ per_page=per_page,
+ )
+
+ def get_actions(
+ self,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
+ ) -> list[BoundAction]:
+ """
+ Returns all Actions for a Primary IP.
+
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
+ """
+ return self._client.get_actions(
+ self,
+ status=status,
+ sort=sort,
+ )
+
def update(
self,
auto_delete: bool | None = None,
@@ -102,7 +168,10 @@ class PrimaryIPsPageResult(NamedTuple):
meta: Meta
-class PrimaryIPsClient(ResourceClientBase):
+class PrimaryIPsClient(
+ ResourceClientBaseActionsMixin,
+ ResourceClientBase,
+):
_base_url = "/primary_ips"
actions: ResourceActionsClient
@@ -115,6 +184,51 @@ class PrimaryIPsClient(ResourceClientBase):
super().__init__(client)
self.actions = ResourceActionsClient(client, self._base_url)
+ def get_actions_list(
+ self,
+ primary_ip: PrimaryIP | BoundPrimaryIP,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
+ page: int | None = None,
+ per_page: int | None = None,
+ ) -> ActionsPageResult:
+ """
+ Returns a paginated list of Actions for a Primary IP.
+
+ :param primary_ip: Primary IP to get the Actions for.
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
+ :param page: Page number to get.
+ :param per_page: Maximum number of Actions returned per page.
+ """
+ return self._get_actions_list(
+ f"{self._base_url}/{primary_ip.id}",
+ status=status,
+ sort=sort,
+ page=page,
+ per_page=per_page,
+ )
+
+ def get_actions(
+ self,
+ primary_ip: PrimaryIP | BoundPrimaryIP,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
+ ) -> list[BoundAction]:
+ """
+ Returns all Actions for a Primary IP.
+
+ :param primary_ip: Primary IP to get the Actions for.
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
+ """
+ return self._iter_pages(
+ self.get_actions_list,
+ primary_ip,
+ status=status,
+ sort=sort,
+ )
+
def get_by_id(self, id: int) -> BoundPrimaryIP:
"""Returns a specific Primary IP object.
@@ -196,16 +310,18 @@ class PrimaryIPsClient(ResourceClientBase):
type: str,
name: str,
datacenter: Datacenter | BoundDatacenter | None = None,
+ location: Location | BoundLocation | None = None,
assignee_type: str | None = "server",
assignee_id: int | None = None,
auto_delete: bool | None = False,
- labels: dict | None = None,
+ labels: dict[str, str] | None = None,
) -> CreatePrimaryIPResponse:
"""Creates a new Primary IP assigned to a server.
:param type: str Primary IP type Choices: ipv4, ipv6
:param name: str
:param datacenter: Datacenter (optional)
+ :param location: Location (optional)
:param assignee_type: str (optional)
:param assignee_id: int (optional)
:param auto_delete: bool (optional)
@@ -220,7 +336,16 @@ class PrimaryIPsClient(ResourceClientBase):
"auto_delete": auto_delete,
}
if datacenter is not None:
+ warnings.warn(
+ "The 'datacenter' argument is deprecated and will be removed after 1 July 2026. "
+ "Please use the 'location' argument instead. "
+ "See https://docs.hetzner.cloud/changelog#2025-12-16-phasing-out-datacenters",
+ DeprecationWarning,
+ stacklevel=2,
+ )
data["datacenter"] = datacenter.id_or_name
+ if location is not None:
+ data["location"] = location.id_or_name
if assignee_id is not None:
data["assignee_id"] = assignee_id
if labels is not None:
diff --git a/plugins/module_utils/vendor/hcloud/primary_ips/domain.py b/plugins/module_utils/vendor/hcloud/primary_ips/domain.py
index 83e5d7b..96749be 100644
--- a/plugins/module_utils/vendor/hcloud/primary_ips/domain.py
+++ b/plugins/module_utils/vendor/hcloud/primary_ips/domain.py
@@ -1,19 +1,23 @@
from __future__ import annotations
-from typing import TYPE_CHECKING
-
-try:
- from dateutil.parser import isoparse
-except ImportError:
- isoparse = None
+import warnings
+from typing import TYPE_CHECKING, TypedDict
from ..core import BaseDomain, DomainIdentityMixin
if TYPE_CHECKING:
from ..actions import BoundAction
from ..datacenters import BoundDatacenter
+ from ..locations import BoundLocation
+ from ..rdns import DNSPtr
from .client import BoundPrimaryIP
+__all__ = [
+ "PrimaryIP",
+ "PrimaryIPProtection",
+ "CreatePrimaryIPResponse",
+]
+
class PrimaryIP(BaseDomain, DomainIdentityMixin):
"""Primary IP Domain
@@ -27,7 +31,15 @@ class PrimaryIP(BaseDomain, DomainIdentityMixin):
:param dns_ptr: List[Dict]
Array of reverse DNS entries
:param datacenter: :class:`Datacenter `
- Datacenter the Primary IP was created in.
+ Datacenter the Primary IP was created in.
+
+ This property is deprecated and will be removed after 1 July 2026.
+ Please use the ``location`` property instead.
+
+ See https://docs.hetzner.cloud/changelog#2025-12-16-phasing-out-datacenters.
+
+ :param location: :class:`Location `
+ Location the Primary IP was created in.
:param blocked: boolean
Whether the IP is blocked
:param protection: dict
@@ -46,12 +58,12 @@ class PrimaryIP(BaseDomain, DomainIdentityMixin):
Delete the Primary IP when the Assignee it is assigned to is deleted.
"""
- __api_properties__ = (
+ __properties__ = (
"id",
"ip",
"type",
"dns_ptr",
- "datacenter",
+ "location",
"blocked",
"protection",
"labels",
@@ -61,18 +73,26 @@ class PrimaryIP(BaseDomain, DomainIdentityMixin):
"assignee_type",
"auto_delete",
)
- __slots__ = __api_properties__
+ __api_properties__ = (
+ *__properties__,
+ "datacenter",
+ )
+ __slots__ = (
+ *__properties__,
+ "_datacenter",
+ )
def __init__(
self,
id: int | None = None,
type: str | None = None,
ip: str | None = None,
- dns_ptr: list[dict] | None = None,
+ dns_ptr: list[DNSPtr] | None = None,
datacenter: BoundDatacenter | None = None,
+ location: BoundLocation | None = None,
blocked: bool | None = None,
- protection: dict | None = None,
- labels: dict[str, dict] | None = None,
+ protection: PrimaryIPProtection | None = None,
+ labels: dict[str, str] | None = None,
created: str | None = None,
name: str | None = None,
assignee_id: int | None = None,
@@ -84,15 +104,38 @@ class PrimaryIP(BaseDomain, DomainIdentityMixin):
self.ip = ip
self.dns_ptr = dns_ptr
self.datacenter = datacenter
+ self.location = location
self.blocked = blocked
self.protection = protection
self.labels = labels
- self.created = isoparse(created) if created else None
+ self.created = self._parse_datetime(created)
self.name = name
self.assignee_id = assignee_id
self.assignee_type = assignee_type
self.auto_delete = auto_delete
+ @property
+ def datacenter(self) -> BoundDatacenter | None:
+ """
+ :meta private:
+ """
+ warnings.warn(
+ "The 'datacenter' property is deprecated and will be removed after 1 July 2026. "
+ "Please use the 'location' property instead. "
+ "See https://docs.hetzner.cloud/changelog#2025-12-16-phasing-out-datacenters.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self._datacenter
+
+ @datacenter.setter
+ def datacenter(self, value: BoundDatacenter | None) -> None:
+ self._datacenter = value
+
+
+class PrimaryIPProtection(TypedDict):
+ delete: bool
+
class CreatePrimaryIPResponse(BaseDomain):
"""Create Primary IP Response Domain
diff --git a/plugins/module_utils/vendor/hcloud/rdns/__init__.py b/plugins/module_utils/vendor/hcloud/rdns/__init__.py
new file mode 100644
index 0000000..116a632
--- /dev/null
+++ b/plugins/module_utils/vendor/hcloud/rdns/__init__.py
@@ -0,0 +1,7 @@
+from __future__ import annotations
+
+from .domain import DNSPtr
+
+__all__ = [
+ "DNSPtr",
+]
diff --git a/plugins/module_utils/vendor/hcloud/rdns/domain.py b/plugins/module_utils/vendor/hcloud/rdns/domain.py
new file mode 100644
index 0000000..e0e5ac6
--- /dev/null
+++ b/plugins/module_utils/vendor/hcloud/rdns/domain.py
@@ -0,0 +1,12 @@
+from __future__ import annotations
+
+from typing import TypedDict
+
+__all__ = [
+ "DNSPtr",
+]
+
+
+class DNSPtr(TypedDict):
+ ip: str
+ dns_ptr: str
diff --git a/plugins/module_utils/vendor/hcloud/server_types/client.py b/plugins/module_utils/vendor/hcloud/server_types/client.py
index db0ef54..98da70a 100644
--- a/plugins/module_utils/vendor/hcloud/server_types/client.py
+++ b/plugins/module_utils/vendor/hcloud/server_types/client.py
@@ -6,8 +6,14 @@ from ..core import BoundModelBase, Meta, ResourceClientBase
from ..locations import BoundLocation
from .domain import ServerType, ServerTypeLocation
+__all__ = [
+ "BoundServerType",
+ "ServerTypesPageResult",
+ "ServerTypesClient",
+]
-class BoundServerType(BoundModelBase, ServerType):
+
+class BoundServerType(BoundModelBase[ServerType], ServerType):
_client: ServerTypesClient
model = ServerType
@@ -15,7 +21,7 @@ class BoundServerType(BoundModelBase, ServerType):
def __init__(
self,
client: ServerTypesClient,
- data: dict,
+ data: dict[str, Any],
complete: bool = True,
):
raw = data.get("locations")
diff --git a/plugins/module_utils/vendor/hcloud/server_types/domain.py b/plugins/module_utils/vendor/hcloud/server_types/domain.py
index ff9e3fd..279d928 100644
--- a/plugins/module_utils/vendor/hcloud/server_types/domain.py
+++ b/plugins/module_utils/vendor/hcloud/server_types/domain.py
@@ -1,11 +1,17 @@
from __future__ import annotations
import warnings
+from typing import Any
from ..core import BaseDomain, DomainIdentityMixin
from ..deprecation import DeprecationInfo
from ..locations import BoundLocation
+__all__ = [
+ "ServerType",
+ "ServerTypeLocation",
+]
+
class ServerType(BaseDomain, DomainIdentityMixin):
"""ServerType Domain
@@ -79,12 +85,12 @@ class ServerType(BaseDomain, DomainIdentityMixin):
cores: int | None = None,
memory: int | None = None,
disk: int | None = None,
- prices: list[dict] | None = None,
+ prices: list[dict[str, Any]] | None = None,
storage_type: str | None = None,
cpu_type: str | None = None,
architecture: str | None = None,
deprecated: bool | None = None,
- deprecation: dict | None = None,
+ deprecation: dict[str, Any] | None = None,
included_traffic: int | None = None,
locations: list[ServerTypeLocation] | None = None,
):
@@ -191,7 +197,7 @@ class ServerTypeLocation(BaseDomain):
self,
*,
location: BoundLocation,
- deprecation: dict | None,
+ deprecation: dict[str, Any] | None,
):
self.location = location
self.deprecation = (
diff --git a/plugins/module_utils/vendor/hcloud/servers/__init__.py b/plugins/module_utils/vendor/hcloud/servers/__init__.py
index 0b02a11..c71c63e 100644
--- a/plugins/module_utils/vendor/hcloud/servers/__init__.py
+++ b/plugins/module_utils/vendor/hcloud/servers/__init__.py
@@ -7,13 +7,16 @@ from .domain import (
GetMetricsResponse,
IPv4Address,
IPv6Network,
+ MetricsType,
PrivateNet,
PublicNetwork,
PublicNetworkFirewall,
+ RebuildResponse,
RequestConsoleResponse,
ResetPasswordResponse,
Server,
ServerCreatePublicNetwork,
+ ServerProtection,
)
__all__ = [
@@ -29,7 +32,10 @@ __all__ = [
"RequestConsoleResponse",
"ResetPasswordResponse",
"Server",
+ "ServerProtection",
"ServerCreatePublicNetwork",
"ServersClient",
"ServersPageResult",
+ "RebuildResponse",
+ "MetricsType",
]
diff --git a/plugins/module_utils/vendor/hcloud/servers/client.py b/plugins/module_utils/vendor/hcloud/servers/client.py
index 6aefab0..49cc794 100644
--- a/plugins/module_utils/vendor/hcloud/servers/client.py
+++ b/plugins/module_utils/vendor/hcloud/servers/client.py
@@ -1,5 +1,6 @@
from __future__ import annotations
+import warnings
from datetime import datetime
from typing import TYPE_CHECKING, Any, NamedTuple
@@ -8,13 +9,21 @@ try:
except ImportError:
isoparse = None
-from ..actions import ActionsPageResult, BoundAction, ResourceActionsClient
+from ..actions import (
+ ActionSort,
+ ActionsPageResult,
+ ActionStatus,
+ BoundAction,
+ ResourceActionsClient,
+)
+from ..actions.client import ResourceClientBaseActionsMixin
from ..core import BoundModelBase, Meta, ResourceClientBase
from ..datacenters import BoundDatacenter
from ..firewalls import BoundFirewall
from ..floating_ips import BoundFloatingIP
from ..images import BoundImage, CreateImageResponse
from ..isos import BoundIso
+from ..locations import BoundLocation, Location
from ..metrics import Metrics
from ..placement_groups import BoundPlacementGroup
from ..primary_ips import BoundPrimaryIP
@@ -42,7 +51,6 @@ if TYPE_CHECKING:
from ..firewalls import Firewall
from ..images import Image
from ..isos import Iso
- from ..locations import BoundLocation, Location
from ..networks import BoundNetwork, Network
from ..placement_groups import PlacementGroup
from ..server_types import ServerType
@@ -51,16 +59,32 @@ if TYPE_CHECKING:
from .domain import ServerCreatePublicNetwork
-class BoundServer(BoundModelBase, Server):
+__all__ = [
+ "BoundServer",
+ "ServersPageResult",
+ "ServersClient",
+]
+
+
+class BoundServer(BoundModelBase[Server], Server):
_client: ServersClient
model = Server
# pylint: disable=too-many-locals
- def __init__(self, client: ServersClient, data: dict, complete: bool = True):
- datacenter = data.get("datacenter")
- if datacenter is not None:
- data["datacenter"] = BoundDatacenter(client._parent.datacenters, datacenter)
+ def __init__(
+ self,
+ client: ServersClient,
+ data: dict[str, Any],
+ complete: bool = True,
+ ):
+ raw = data.get("datacenter")
+ if raw:
+ data["datacenter"] = BoundDatacenter(client._parent.datacenters, raw)
+
+ raw = data.get("location")
+ if raw:
+ data["location"] = BoundLocation(client._parent.locations, raw)
volumes = data.get("volumes", [])
if volumes:
@@ -169,22 +193,18 @@ class BoundServer(BoundModelBase, Server):
def get_actions_list(
self,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
page: int | None = None,
per_page: int | None = None,
) -> ActionsPageResult:
- """Returns all action objects for a server.
+ """
+ Returns a paginated list of Actions for a Server.
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
- :param page: int (optional)
- Specifies the page to fetch
- :param per_page: int (optional)
- Specifies how many results are returned by page
- :return: (List[:class:`BoundAction `], :class:`Meta `)
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
+ :param page: Page number to get.
+ :param per_page: Maximum number of Actions returned per page.
"""
return self._client.get_actions_list(
self,
@@ -196,16 +216,14 @@ class BoundServer(BoundModelBase, Server):
def get_actions(
self,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
) -> list[BoundAction]:
- """Returns all action objects for a server.
+ """
+ Returns all Actions for a Server.
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
- :return: List[:class:`BoundAction `]
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
"""
return self._client.get_actions(self, status=status, sort=sort)
@@ -506,7 +524,10 @@ class ServersPageResult(NamedTuple):
meta: Meta
-class ServersClient(ResourceClientBase):
+class ServersClient(
+ ResourceClientBaseActionsMixin,
+ ResourceClientBase,
+):
_base_url = "/servers"
actions: ResourceActionsClient
@@ -660,6 +681,13 @@ class ServersClient(ResourceClientBase):
if location is not None:
data["location"] = location.id_or_name
if datacenter is not None:
+ warnings.warn(
+ "The 'datacenter' argument is deprecated and will be removed after 1 July 2026. "
+ "Please use the 'location' argument instead. "
+ "See https://docs.hetzner.cloud/changelog#2025-12-16-phasing-out-datacenters",
+ DeprecationWarning,
+ stacklevel=2,
+ )
data["datacenter"] = datacenter.id_or_name
if ssh_keys is not None:
data["ssh_keys"] = [ssh_key.id_or_name for ssh_key in ssh_keys]
@@ -705,59 +733,40 @@ class ServersClient(ResourceClientBase):
def get_actions_list(
self,
server: Server | BoundServer,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
page: int | None = None,
per_page: int | None = None,
) -> ActionsPageResult:
- """Returns all action objects for a server.
-
- :param server: :class:`BoundServer ` or :class:`Server `
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
- :param page: int (optional)
- Specifies the page to fetch
- :param per_page: int (optional)
- Specifies how many results are returned by page
- :return: (List[:class:`BoundAction `], :class:`Meta `)
"""
- params: dict[str, Any] = {}
- if status is not None:
- params["status"] = status
- if sort is not None:
- params["sort"] = sort
- if page is not None:
- params["page"] = page
- if per_page is not None:
- params["per_page"] = per_page
+ Returns a paginated list of Actions for a Server.
- response = self._client.request(
- url=f"{self._base_url}/{server.id}/actions",
- method="GET",
- params=params,
+ :param server: Server to get the Actions for.
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
+ :param page: Page number to get.
+ :param per_page: Maximum number of Actions returned per page.
+ """
+ return self._get_actions_list(
+ f"{self._base_url}/{server.id}",
+ status=status,
+ sort=sort,
+ page=page,
+ per_page=per_page,
)
- actions = [
- BoundAction(self._parent.actions, action_data)
- for action_data in response["actions"]
- ]
- return ActionsPageResult(actions, Meta.parse_meta(response))
def get_actions(
self,
server: Server | BoundServer,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
) -> list[BoundAction]:
- """Returns all action objects for a server.
+ """
+ Returns all Actions for a Server.
- :param server: :class:`BoundServer ` or :class:`Server `
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
- :return: List[:class:`BoundAction `]
+ :param server: Server to get the Actions for.
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
"""
return self._iter_pages(
self.get_actions_list,
diff --git a/plugins/module_utils/vendor/hcloud/servers/domain.py b/plugins/module_utils/vendor/hcloud/servers/domain.py
index bc8b79a..ec019e4 100644
--- a/plugins/module_utils/vendor/hcloud/servers/domain.py
+++ b/plugins/module_utils/vendor/hcloud/servers/domain.py
@@ -1,11 +1,7 @@
from __future__ import annotations
-from typing import TYPE_CHECKING, Literal
-
-try:
- from dateutil.parser import isoparse
-except ImportError:
- isoparse = None
+import warnings
+from typing import TYPE_CHECKING, Literal, TypedDict
from ..core import BaseDomain, DomainIdentityMixin
@@ -16,15 +12,36 @@ if TYPE_CHECKING:
from ..floating_ips import BoundFloatingIP
from ..images import BoundImage
from ..isos import BoundIso
+ from ..locations import BoundLocation
from ..metrics import Metrics
from ..networks import BoundNetwork, Network
from ..placement_groups import BoundPlacementGroup
from ..primary_ips import BoundPrimaryIP, PrimaryIP
+ from ..rdns import DNSPtr
from ..server_types import BoundServerType
from ..volumes import BoundVolume
from .client import BoundServer
+__all__ = [
+ "Server",
+ "ServerProtection",
+ "CreateServerResponse",
+ "ResetPasswordResponse",
+ "EnableRescueResponse",
+ "RequestConsoleResponse",
+ "RebuildResponse",
+ "PublicNetwork",
+ "PublicNetworkFirewall",
+ "IPv4Address",
+ "IPv6Network",
+ "PrivateNet",
+ "ServerCreatePublicNetwork",
+ "GetMetricsResponse",
+ "MetricsType",
+]
+
+
class Server(BaseDomain, DomainIdentityMixin):
"""Server Domain
@@ -40,6 +57,12 @@ class Server(BaseDomain, DomainIdentityMixin):
Public network information.
:param server_type: :class:`BoundServerType `
:param datacenter: :class:`BoundDatacenter `
+
+ This property is deprecated and will be removed after 1 July 2026.
+ Please use the ``location`` property instead.
+
+ See https://docs.hetzner.cloud/changelog#2025-12-16-phasing-out-datacenters.
+ :param location: :class:`BoundLocation `
:param image: :class:`BoundImage `, None
:param iso: :class:`BoundIso `, None
:param rescue_enabled: bool
@@ -85,13 +108,13 @@ class Server(BaseDomain, DomainIdentityMixin):
STATUS_UNKNOWN = "unknown"
"""Server Status unknown"""
- __api_properties__ = (
+ __properties__ = (
"id",
"name",
"status",
"public_net",
"server_type",
- "datacenter",
+ "location",
"image",
"iso",
"rescue_enabled",
@@ -108,7 +131,14 @@ class Server(BaseDomain, DomainIdentityMixin):
"primary_disk_size",
"placement_group",
)
- __slots__ = __api_properties__
+ __api_properties__ = (
+ *__properties__,
+ "datacenter",
+ )
+ __slots__ = (
+ *__properties__,
+ "_datacenter",
+ )
# pylint: disable=too-many-locals
def __init__(
@@ -120,6 +150,7 @@ class Server(BaseDomain, DomainIdentityMixin):
public_net: PublicNetwork | None = None,
server_type: BoundServerType | None = None,
datacenter: BoundDatacenter | None = None,
+ location: BoundLocation | None = None,
image: BoundImage | None = None,
iso: BoundIso | None = None,
rescue_enabled: bool | None = None,
@@ -128,7 +159,7 @@ class Server(BaseDomain, DomainIdentityMixin):
outgoing_traffic: int | None = None,
ingoing_traffic: int | None = None,
included_traffic: int | None = None,
- protection: dict | None = None,
+ protection: ServerProtection | None = None,
labels: dict[str, str] | None = None,
volumes: list[BoundVolume] | None = None,
private_net: list[PrivateNet] | None = None,
@@ -138,10 +169,11 @@ class Server(BaseDomain, DomainIdentityMixin):
self.id = id
self.name = name
self.status = status
- self.created = isoparse(created) if created else None
+ self.created = self._parse_datetime(created)
self.public_net = public_net
self.server_type = server_type
self.datacenter = datacenter
+ self.location = location
self.image = image
self.iso = iso
self.rescue_enabled = rescue_enabled
@@ -167,6 +199,29 @@ class Server(BaseDomain, DomainIdentityMixin):
return o
return None
+ @property
+ def datacenter(self) -> BoundDatacenter | None:
+ """
+ :meta private:
+ """
+ warnings.warn(
+ "The 'datacenter' property is deprecated and will be removed after 1 July 2026. "
+ "Please use the 'location' property instead. "
+ "See https://docs.hetzner.cloud/changelog#2025-12-16-phasing-out-datacenters.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self._datacenter
+
+ @datacenter.setter
+ def datacenter(self, value: BoundDatacenter | None) -> None:
+ self._datacenter = value
+
+
+class ServerProtection(TypedDict):
+ rebuild: bool
+ delete: bool
+
class CreateServerResponse(BaseDomain):
"""Create Server Response Domain
@@ -392,7 +447,7 @@ class IPv6Network(BaseDomain):
self,
ip: str,
blocked: bool,
- dns_ptr: list,
+ dns_ptr: list[DNSPtr],
):
self.ip = ip
self.blocked = blocked
diff --git a/plugins/module_utils/vendor/hcloud/ssh_keys/client.py b/plugins/module_utils/vendor/hcloud/ssh_keys/client.py
index a565469..d88800a 100644
--- a/plugins/module_utils/vendor/hcloud/ssh_keys/client.py
+++ b/plugins/module_utils/vendor/hcloud/ssh_keys/client.py
@@ -5,8 +5,14 @@ from typing import Any, NamedTuple
from ..core import BoundModelBase, Meta, ResourceClientBase
from .domain import SSHKey
+__all__ = [
+ "BoundSSHKey",
+ "SSHKeysPageResult",
+ "SSHKeysClient",
+]
-class BoundSSHKey(BoundModelBase, SSHKey):
+
+class BoundSSHKey(BoundModelBase[SSHKey], SSHKey):
_client: SSHKeysClient
model = SSHKey
diff --git a/plugins/module_utils/vendor/hcloud/ssh_keys/domain.py b/plugins/module_utils/vendor/hcloud/ssh_keys/domain.py
index 2297b6b..c3fc7c6 100644
--- a/plugins/module_utils/vendor/hcloud/ssh_keys/domain.py
+++ b/plugins/module_utils/vendor/hcloud/ssh_keys/domain.py
@@ -1,12 +1,11 @@
from __future__ import annotations
-try:
- from dateutil.parser import isoparse
-except ImportError:
- isoparse = None
-
from ..core import BaseDomain, DomainIdentityMixin
+__all__ = [
+ "SSHKey",
+]
+
class SSHKey(BaseDomain, DomainIdentityMixin):
"""SSHKey Domain
@@ -49,4 +48,4 @@ class SSHKey(BaseDomain, DomainIdentityMixin):
self.fingerprint = fingerprint
self.public_key = public_key
self.labels = labels
- self.created = isoparse(created) if created else None
+ self.created = self._parse_datetime(created)
diff --git a/plugins/module_utils/vendor/hcloud/storage_box_types/client.py b/plugins/module_utils/vendor/hcloud/storage_box_types/client.py
index 05cb03e..25c1e89 100644
--- a/plugins/module_utils/vendor/hcloud/storage_box_types/client.py
+++ b/plugins/module_utils/vendor/hcloud/storage_box_types/client.py
@@ -8,8 +8,14 @@ from .domain import StorageBoxType
if TYPE_CHECKING:
from .._client import Client
+__all__ = [
+ "BoundStorageBoxType",
+ "StorageBoxTypesPageResult",
+ "StorageBoxTypesClient",
+]
-class BoundStorageBoxType(BoundModelBase, StorageBoxType):
+
+class BoundStorageBoxType(BoundModelBase[StorageBoxType], StorageBoxType):
_client: StorageBoxTypesClient
model = StorageBoxType
diff --git a/plugins/module_utils/vendor/hcloud/storage_box_types/domain.py b/plugins/module_utils/vendor/hcloud/storage_box_types/domain.py
index b807ce2..b393b15 100644
--- a/plugins/module_utils/vendor/hcloud/storage_box_types/domain.py
+++ b/plugins/module_utils/vendor/hcloud/storage_box_types/domain.py
@@ -1,8 +1,14 @@
from __future__ import annotations
+from typing import Any
+
from ..core import BaseDomain, DomainIdentityMixin
from ..deprecation import DeprecationInfo
+__all__ = [
+ "StorageBoxType",
+]
+
class StorageBoxType(BaseDomain, DomainIdentityMixin):
"""
@@ -33,8 +39,8 @@ class StorageBoxType(BaseDomain, DomainIdentityMixin):
automatic_snapshot_limit: int | None = None,
subaccounts_limit: int | None = None,
size: int | None = None,
- prices: list[dict] | None = None,
- deprecation: dict | None = None,
+ prices: list[dict[str, Any]] | None = None,
+ deprecation: dict[str, Any] | None = None,
):
self.id = id
self.name = name
diff --git a/plugins/module_utils/vendor/hcloud/storage_boxes/client.py b/plugins/module_utils/vendor/hcloud/storage_boxes/client.py
index 0cb3c2d..4d258b9 100644
--- a/plugins/module_utils/vendor/hcloud/storage_boxes/client.py
+++ b/plugins/module_utils/vendor/hcloud/storage_boxes/client.py
@@ -2,7 +2,14 @@ from __future__ import annotations
from typing import TYPE_CHECKING, Any, NamedTuple
-from ..actions import ActionsPageResult, BoundAction, ResourceActionsClient
+from ..actions import (
+ ActionSort,
+ ActionsPageResult,
+ ActionStatus,
+ BoundAction,
+ ResourceActionsClient,
+)
+from ..actions.client import ResourceClientBaseActionsMixin
from ..core import BoundModelBase, Meta, ResourceClientBase
from ..locations import BoundLocation, Location
from ..ssh_keys import BoundSSHKey, SSHKey
@@ -28,8 +35,18 @@ from .domain import (
if TYPE_CHECKING:
from .._client import Client
+__all__ = [
+ "BoundStorageBox",
+ "BoundStorageBoxSnapshot",
+ "BoundStorageBoxSubaccount",
+ "StorageBoxesPageResult",
+ "StorageBoxSnapshotsPageResult",
+ "StorageBoxSubaccountsPageResult",
+ "StorageBoxesClient",
+]
-class BoundStorageBox(BoundModelBase, StorageBox):
+
+class BoundStorageBox(BoundModelBase[StorageBox], StorageBox):
_client: StorageBoxesClient
model = StorageBox
@@ -67,20 +84,20 @@ class BoundStorageBox(BoundModelBase, StorageBox):
def get_actions_list(
self,
*,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
page: int | None = None,
per_page: int | None = None,
) -> ActionsPageResult:
"""
- Returns a paginated list of Actions for a Storage Box for a specific page.
+ Returns a paginated list of Actions for a Storage Box.
See https://docs.hetzner.cloud/reference/hetzner#storage-box-actions-list-actions-for-a-storage-box
- :param status: Filter the actions by status. The response will only contain actions matching the specified statuses.
- :param sort: Sort resources by field and direction.
- :param page: Page number to return.
- :param per_page: Maximum number of entries returned per page.
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
+ :param page: Page number to get.
+ :param per_page: Maximum number of Actions returned per page.
Experimental:
Storage Box support is experimental, breaking changes may occur within minor releases.
@@ -96,8 +113,8 @@ class BoundStorageBox(BoundModelBase, StorageBox):
def get_actions(
self,
*,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
) -> list[BoundAction]:
"""
Returns all Actions for a Storage Box.
@@ -322,7 +339,7 @@ class BoundStorageBox(BoundModelBase, StorageBox):
def get_snapshot_by_name(
self,
name: str,
- ) -> BoundStorageBoxSnapshot:
+ ) -> BoundStorageBoxSnapshot | None:
"""
Returns a single Snapshot from a Storage Box.
@@ -438,7 +455,7 @@ class BoundStorageBox(BoundModelBase, StorageBox):
def get_subaccount_by_username(
self,
username: str,
- ) -> BoundStorageBoxSubaccount:
+ ) -> BoundStorageBoxSubaccount | None:
"""
Returns a single Subaccount from a Storage Box.
@@ -537,7 +554,7 @@ class BoundStorageBox(BoundModelBase, StorageBox):
)
-class BoundStorageBoxSnapshot(BoundModelBase, StorageBoxSnapshot):
+class BoundStorageBoxSnapshot(BoundModelBase[StorageBoxSnapshot], StorageBoxSnapshot):
_client: StorageBoxesClient
model = StorageBoxSnapshot
@@ -561,6 +578,8 @@ class BoundStorageBoxSnapshot(BoundModelBase, StorageBoxSnapshot):
super().__init__(client, data, complete)
def _get_self(self) -> BoundStorageBoxSnapshot:
+ assert self.data_model.storage_box is not None
+ assert self.data_model.id is not None
return self._client.get_snapshot_by_id(
self.data_model.storage_box,
self.data_model.id,
@@ -603,7 +622,9 @@ class BoundStorageBoxSnapshot(BoundModelBase, StorageBoxSnapshot):
return self._client.delete_snapshot(self)
-class BoundStorageBoxSubaccount(BoundModelBase, StorageBoxSubaccount):
+class BoundStorageBoxSubaccount(
+ BoundModelBase[StorageBoxSubaccount], StorageBoxSubaccount
+):
_client: StorageBoxesClient
model = StorageBoxSubaccount
@@ -627,6 +648,8 @@ class BoundStorageBoxSubaccount(BoundModelBase, StorageBoxSubaccount):
super().__init__(client, data, complete)
def _get_self(self) -> BoundStorageBoxSubaccount:
+ assert self.data_model.storage_box is not None
+ assert self.data_model.id is not None
return self._client.get_subaccount_by_id(
self.data_model.storage_box,
self.data_model.id,
@@ -737,7 +760,10 @@ class StorageBoxSubaccountsPageResult(NamedTuple):
meta: Meta
-class StorageBoxesClient(ResourceClientBase):
+class StorageBoxesClient(
+ ResourceClientBaseActionsMixin,
+ ResourceClientBase,
+):
"""
A client for the Storage Boxes API.
@@ -1006,58 +1032,46 @@ class StorageBoxesClient(ResourceClientBase):
self,
storage_box: StorageBox | BoundStorageBox,
*,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
page: int | None = None,
per_page: int | None = None,
) -> ActionsPageResult:
"""
- Returns a paginated list of Actions for a Storage Box for a specific page.
+ Returns a paginated list of Actions for a Storage Box.
See https://docs.hetzner.cloud/reference/hetzner#storage-box-actions-list-actions-for-a-storage-box
- :param storage_box: Storage Box to fetch the Actions from.
- :param status: Filter the actions by status. The response will only contain actions matching the specified statuses.
- :param sort: Sort resources by field and direction.
- :param page: Page number to return.
- :param per_page: Maximum number of entries returned per page.
+ :param storage_box: Storage Box to get the Actions for.
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
+ :param page: Page number to get.
+ :param per_page: Maximum number of Actions returned per page.
Experimental:
Storage Box support is experimental, breaking changes may occur within minor releases.
"""
- params: dict[str, Any] = {}
- if status is not None:
- params["status"] = status
- if sort is not None:
- params["sort"] = sort
- if page is not None:
- params["page"] = page
- if per_page is not None:
- params["per_page"] = per_page
-
- response = self._client.request(
- method="GET",
- url=f"/storage_boxes/{storage_box.id}/actions",
- params=params,
- )
- return ActionsPageResult(
- actions=[BoundAction(self._parent.actions, o) for o in response["actions"]],
- meta=Meta.parse_meta(response),
+ return self._get_actions_list(
+ f"{self._base_url}/{storage_box.id}",
+ status=status,
+ sort=sort,
+ page=page,
+ per_page=per_page,
)
def get_actions(
self,
storage_box: StorageBox | BoundStorageBox,
*,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
) -> list[BoundAction]:
"""
Returns all Actions for a Storage Box.
See https://docs.hetzner.cloud/reference/hetzner#storage-box-actions-list-actions-for-a-storage-box
- :param storage_box: Storage Box to fetch the Actions from.
+ :param storage_box: Storage Box to get the Actions for.
:param status: Filter the actions by status. The response will only contain actions matching the specified statuses.
:param sort: Sort resources by field and direction.
@@ -1279,7 +1293,7 @@ class StorageBoxesClient(ResourceClientBase):
self,
storage_box: StorageBox | BoundStorageBox,
name: str,
- ) -> BoundStorageBoxSnapshot:
+ ) -> BoundStorageBoxSnapshot | None:
"""
Returns a single Snapshot from a Storage Box.
@@ -1500,7 +1514,7 @@ class StorageBoxesClient(ResourceClientBase):
self,
storage_box: StorageBox | BoundStorageBox,
username: str,
- ) -> BoundStorageBoxSubaccount:
+ ) -> BoundStorageBoxSubaccount | None:
"""
Returns a single Subaccount from a Storage Box.
diff --git a/plugins/module_utils/vendor/hcloud/storage_boxes/domain.py b/plugins/module_utils/vendor/hcloud/storage_boxes/domain.py
index 040f6e8..03eaab1 100644
--- a/plugins/module_utils/vendor/hcloud/storage_boxes/domain.py
+++ b/plugins/module_utils/vendor/hcloud/storage_boxes/domain.py
@@ -2,11 +2,6 @@ from __future__ import annotations
from typing import TYPE_CHECKING, Any, Literal
-try:
- from dateutil.parser import isoparse
-except ImportError:
- isoparse = None
-
from ..actions import BoundAction
from ..core import BaseDomain, DomainIdentityMixin
from ..locations import BoundLocation, Location
@@ -19,6 +14,26 @@ if TYPE_CHECKING:
BoundStorageBoxSubaccount,
)
+__all__ = [
+ "StorageBox",
+ "StorageBoxAccessSettings",
+ "StorageBoxStats",
+ "StorageBoxSnapshotPlan",
+ "CreateStorageBoxResponse",
+ "DeleteStorageBoxResponse",
+ "StorageBoxFoldersResponse",
+ "StorageBoxSnapshot",
+ "StorageBoxSnapshotStats",
+ "CreateStorageBoxSnapshotResponse",
+ "DeleteStorageBoxSnapshotResponse",
+ "StorageBoxSubaccount",
+ "StorageBoxSubaccountAccessSettings",
+ "CreateStorageBoxSubaccountResponse",
+ "DeleteStorageBoxSubaccountResponse",
+ "StorageBoxStatus",
+]
+
+
StorageBoxStatus = Literal[
"active",
"initializing",
@@ -85,7 +100,7 @@ class StorageBox(BaseDomain, DomainIdentityMixin):
self.access_settings = access_settings
self.stats = stats
self.status = status
- self.created = isoparse(created) if created else None
+ self.created = self._parse_datetime(created)
class StorageBoxAccessSettings(BaseDomain):
@@ -288,7 +303,7 @@ class StorageBoxSnapshot(BaseDomain, DomainIdentityMixin):
self.is_automatic = is_automatic
self.labels = labels
self.storage_box = storage_box
- self.created = isoparse(created) if created else None
+ self.created = self._parse_datetime(created)
self.stats = stats
@@ -389,7 +404,7 @@ class StorageBoxSubaccount(BaseDomain, DomainIdentityMixin):
self.access_settings = access_settings
self.labels = labels
self.storage_box = storage_box
- self.created = isoparse(created) if created else None
+ self.created = self._parse_datetime(created)
class StorageBoxSubaccountAccessSettings(BaseDomain):
diff --git a/plugins/module_utils/vendor/hcloud/volumes/__init__.py b/plugins/module_utils/vendor/hcloud/volumes/__init__.py
index 046df10..1722623 100644
--- a/plugins/module_utils/vendor/hcloud/volumes/__init__.py
+++ b/plugins/module_utils/vendor/hcloud/volumes/__init__.py
@@ -1,12 +1,13 @@
from __future__ import annotations
from .client import BoundVolume, VolumesClient, VolumesPageResult
-from .domain import CreateVolumeResponse, Volume
+from .domain import CreateVolumeResponse, Volume, VolumeProtection
__all__ = [
"BoundVolume",
"CreateVolumeResponse",
"Volume",
+ "VolumeProtection",
"VolumesClient",
"VolumesPageResult",
]
diff --git a/plugins/module_utils/vendor/hcloud/volumes/client.py b/plugins/module_utils/vendor/hcloud/volumes/client.py
index 9d1cded..a4155cf 100644
--- a/plugins/module_utils/vendor/hcloud/volumes/client.py
+++ b/plugins/module_utils/vendor/hcloud/volumes/client.py
@@ -2,7 +2,14 @@ from __future__ import annotations
from typing import TYPE_CHECKING, Any, NamedTuple
-from ..actions import ActionsPageResult, BoundAction, ResourceActionsClient
+from ..actions import (
+ ActionSort,
+ ActionsPageResult,
+ ActionStatus,
+ BoundAction,
+ ResourceActionsClient,
+)
+from ..actions.client import ResourceClientBaseActionsMixin
from ..core import BoundModelBase, Meta, ResourceClientBase
from ..locations import BoundLocation
from .domain import CreateVolumeResponse, Volume
@@ -13,12 +20,24 @@ if TYPE_CHECKING:
from ..servers import BoundServer, Server
-class BoundVolume(BoundModelBase, Volume):
+__all__ = [
+ "BoundVolume",
+ "VolumesPageResult",
+ "VolumesClient",
+]
+
+
+class BoundVolume(BoundModelBase[Volume], Volume):
_client: VolumesClient
model = Volume
- def __init__(self, client: VolumesClient, data: dict, complete: bool = True):
+ def __init__(
+ self,
+ client: VolumesClient,
+ data: dict[str, Any],
+ complete: bool = True,
+ ):
location = data.get("location")
if location is not None:
data["location"] = BoundLocation(client._parent.locations, location)
@@ -35,22 +54,18 @@ class BoundVolume(BoundModelBase, Volume):
def get_actions_list(
self,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
page: int | None = None,
per_page: int | None = None,
) -> ActionsPageResult:
- """Returns all action objects for a volume.
+ """
+ Returns a paginated list of Actions for a Volume.
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
- :param page: int (optional)
- Specifies the page to fetch
- :param per_page: int (optional)
- Specifies how many results are returned by page
- :return: (List[:class:`BoundAction `], :class:`Meta `)
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
+ :param page: Page number to get.
+ :param per_page: Maximum number of Actions returned per page.
"""
return self._client.get_actions_list(
self, status=status, sort=sort, page=page, per_page=per_page
@@ -58,16 +73,14 @@ class BoundVolume(BoundModelBase, Volume):
def get_actions(
self,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
) -> list[BoundAction]:
- """Returns all action objects for a volume.
+ """
+ Returns all Actions for a Volume.
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
- :return: List[:class:`BoundAction `]
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
"""
return self._client.get_actions(self, status=status, sort=sort)
@@ -137,7 +150,10 @@ class VolumesPageResult(NamedTuple):
meta: Meta
-class VolumesClient(ResourceClientBase):
+class VolumesClient(
+ ResourceClientBaseActionsMixin,
+ ResourceClientBase,
+):
_base_url = "/volumes"
actions: ResourceActionsClient
@@ -288,59 +304,40 @@ class VolumesClient(ResourceClientBase):
def get_actions_list(
self,
volume: Volume | BoundVolume,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
page: int | None = None,
per_page: int | None = None,
) -> ActionsPageResult:
- """Returns all action objects for a volume.
-
- :param volume: :class:`BoundVolume ` or :class:`Volume `
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
- :param page: int (optional)
- Specifies the page to fetch
- :param per_page: int (optional)
- Specifies how many results are returned by page
- :return: (List[:class:`BoundAction `], :class:`Meta `)
"""
- params: dict[str, Any] = {}
- if status is not None:
- params["status"] = status
- if sort is not None:
- params["sort"] = sort
- if page is not None:
- params["page"] = page
- if per_page is not None:
- params["per_page"] = per_page
+ Returns a paginated list of Actions for a Volume.
- response = self._client.request(
- url=f"{self._base_url}/{volume.id}/actions",
- method="GET",
- params=params,
+ :param volume: Volume to get the Actions for.
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
+ :param page: Page number to get.
+ :param per_page: Maximum number of Actions returned per page.
+ """
+ return self._get_actions_list(
+ f"{self._base_url}/{volume.id}",
+ status=status,
+ sort=sort,
+ page=page,
+ per_page=per_page,
)
- actions = [
- BoundAction(self._parent.actions, action_data)
- for action_data in response["actions"]
- ]
- return ActionsPageResult(actions, Meta.parse_meta(response))
def get_actions(
self,
volume: Volume | BoundVolume,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
) -> list[BoundAction]:
- """Returns all action objects for a volume.
+ """
+ Returns all Actions for a Volume.
- :param volume: :class:`BoundVolume ` or :class:`Volume `
- :param status: List[str] (optional)
- Response will have only actions with specified statuses. Choices: `running` `success` `error`
- :param sort: List[str] (optional)
- Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
- :return: List[:class:`BoundAction `]
+ :param volume: Volume to get the Actions for.
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
"""
return self._iter_pages(
self.get_actions_list,
diff --git a/plugins/module_utils/vendor/hcloud/volumes/domain.py b/plugins/module_utils/vendor/hcloud/volumes/domain.py
index adfd661..2ed3333 100644
--- a/plugins/module_utils/vendor/hcloud/volumes/domain.py
+++ b/plugins/module_utils/vendor/hcloud/volumes/domain.py
@@ -1,11 +1,6 @@
from __future__ import annotations
-from typing import TYPE_CHECKING
-
-try:
- from dateutil.parser import isoparse
-except ImportError:
- isoparse = None
+from typing import TYPE_CHECKING, TypedDict
from ..core import BaseDomain, DomainIdentityMixin
@@ -15,6 +10,12 @@ if TYPE_CHECKING:
from ..servers import BoundServer, Server
from .client import BoundVolume
+__all__ = [
+ "Volume",
+ "VolumeProtection",
+ "CreateVolumeResponse",
+]
+
class Volume(BaseDomain, DomainIdentityMixin):
"""Volume Domain
@@ -73,14 +74,14 @@ class Volume(BaseDomain, DomainIdentityMixin):
size: int | None = None,
linux_device: str | None = None,
format: str | None = None,
- protection: dict | None = None,
+ protection: VolumeProtection | None = None,
labels: dict[str, str] | None = None,
status: str | None = None,
):
self.id = id
self.name = name
self.server = server
- self.created = isoparse(created) if created else None
+ self.created = self._parse_datetime(created)
self.location = location
self.size = size
self.linux_device = linux_device
@@ -90,6 +91,10 @@ class Volume(BaseDomain, DomainIdentityMixin):
self.status = status
+class VolumeProtection(TypedDict):
+ delete: bool
+
+
class CreateVolumeResponse(BaseDomain):
"""Create Volume Response Domain
diff --git a/plugins/module_utils/vendor/hcloud/zones/__init__.py b/plugins/module_utils/vendor/hcloud/zones/__init__.py
index 7871e10..4cbee7f 100644
--- a/plugins/module_utils/vendor/hcloud/zones/__init__.py
+++ b/plugins/module_utils/vendor/hcloud/zones/__init__.py
@@ -3,16 +3,26 @@ from __future__ import annotations
from .client import (
BoundZone,
BoundZoneRRSet,
+ ZoneRRSetsPageResult,
ZonesClient,
ZonesPageResult,
)
from .domain import (
CreateZoneResponse,
+ CreateZoneRRSetResponse,
+ DeleteZoneResponse,
+ DeleteZoneRRSetResponse,
+ ExportZonefileResponse,
Zone,
ZoneAuthoritativeNameservers,
+ ZoneMode,
ZonePrimaryNameserver,
+ ZoneProtection,
ZoneRecord,
+ ZoneRegistrar,
ZoneRRSet,
+ ZoneRRSetProtection,
+ ZoneStatus,
)
__all__ = [
@@ -26,4 +36,14 @@ __all__ = [
"ZoneRRSet",
"ZonesClient",
"ZonesPageResult",
+ "DeleteZoneRRSetResponse",
+ "ZoneRRSetProtection",
+ "DeleteZoneResponse",
+ "ZoneRegistrar",
+ "ZoneMode",
+ "ZoneRRSetsPageResult",
+ "ZoneProtection",
+ "ExportZonefileResponse",
+ "CreateZoneRRSetResponse",
+ "ZoneStatus",
]
diff --git a/plugins/module_utils/vendor/hcloud/zones/client.py b/plugins/module_utils/vendor/hcloud/zones/client.py
index b334604..2f68028 100644
--- a/plugins/module_utils/vendor/hcloud/zones/client.py
+++ b/plugins/module_utils/vendor/hcloud/zones/client.py
@@ -2,7 +2,14 @@ from __future__ import annotations
from typing import TYPE_CHECKING, Any, NamedTuple
-from ..actions import ActionsPageResult, BoundAction, ResourceActionsClient
+from ..actions import (
+ ActionSort,
+ ActionsPageResult,
+ ActionStatus,
+ BoundAction,
+ ResourceActionsClient,
+)
+from ..actions.client import ResourceClientBaseActionsMixin
from ..core import BoundModelBase, Meta, ResourceClientBase
from .domain import (
CreateZoneResponse,
@@ -22,8 +29,16 @@ from .domain import (
if TYPE_CHECKING:
from .._client import Client
+__all__ = [
+ "BoundZone",
+ "BoundZoneRRSet",
+ "ZonesPageResult",
+ "ZoneRRSetsPageResult",
+ "ZonesClient",
+]
-class BoundZone(BoundModelBase, Zone):
+
+class BoundZone(BoundModelBase[Zone], Zone):
_client: ZonesClient
model = Zone
@@ -81,20 +96,20 @@ class BoundZone(BoundModelBase, Zone):
def get_actions_list(
self,
*,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
page: int | None = None,
per_page: int | None = None,
) -> ActionsPageResult:
"""
- Returns all Actions for the Zone for a specific page.
+ Returns a paginated list of Actions for a Zone.
See https://docs.hetzner.cloud/reference/cloud#zones-list-zones
- :param status: Filter the actions by status. The response will only contain actions matching the specified statuses.
- :param sort: Sort resources by field and direction.
- :param page: Page number to return.
- :param per_page: Maximum number of entries returned per page.
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
+ :param page: Page number to get.
+ :param per_page: Maximum number of Actions returned per page.
"""
return self._client.get_actions_list(
self,
@@ -107,16 +122,16 @@ class BoundZone(BoundModelBase, Zone):
def get_actions(
self,
*,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
) -> list[BoundAction]:
"""
- Returns all Actions for the Zone.
+ Returns all Actions for a Zone.
See https://docs.hetzner.cloud/reference/cloud#zones-list-zones
- :param status: Filter the actions by status. The response will only contain actions matching the specified statuses.
- :param sort: Sort resources by field and direction.
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
"""
return self._client.get_actions(
self,
@@ -367,7 +382,7 @@ class BoundZone(BoundModelBase, Zone):
"""
Updates records in a ZoneRRSet.
- See https://docs.hetzner.cloud/reference/cloud#zone-rrset-actions-update-records-to-an-rrset
+ See https://docs.hetzner.cloud/reference/cloud#zone-rrset-actions-update-records-of-an-rrset
:param rrset: RRSet to update.
:param records: Records to update in the RRSet.
@@ -405,12 +420,17 @@ class BoundZone(BoundModelBase, Zone):
return self._client.set_rrset_records(rrset=rrset, records=records)
-class BoundZoneRRSet(BoundModelBase, ZoneRRSet):
+class BoundZoneRRSet(BoundModelBase[ZoneRRSet], ZoneRRSet):
_client: ZonesClient
model = ZoneRRSet
- def __init__(self, client: ZonesClient, data: dict, complete: bool = True):
+ def __init__(
+ self,
+ client: ZonesClient,
+ data: dict[str, Any],
+ complete: bool = True,
+ ):
raw = data.get("zone")
if raw is not None:
data["zone"] = BoundZone(client, data={"id": raw}, complete=False)
@@ -422,6 +442,8 @@ class BoundZoneRRSet(BoundModelBase, ZoneRRSet):
super().__init__(client, data, complete)
def _get_self(self) -> BoundZoneRRSet:
+ assert self.data_model.zone is not None
+ assert self.data_model.type is not None
return self._client.get_rrset(
self.data_model.zone,
self.data_model.name,
@@ -501,7 +523,7 @@ class BoundZoneRRSet(BoundModelBase, ZoneRRSet):
"""
Updates records in a ZoneRRSet.
- See https://docs.hetzner.cloud/reference/cloud#zone-rrset-actions-update-records-to-an-rrset
+ See https://docs.hetzner.cloud/reference/cloud#zone-rrset-actions-update-records-of-an-rrset
:param records: Records to update in the RRSet.
"""
@@ -544,7 +566,10 @@ class ZoneRRSetsPageResult(NamedTuple):
meta: Meta
-class ZonesClient(ResourceClientBase):
+class ZonesClient(
+ ResourceClientBaseActionsMixin,
+ ResourceClientBase,
+):
"""
ZoneClient is a client for the Zone (DNS) API.
@@ -767,57 +792,45 @@ class ZonesClient(ResourceClientBase):
self,
zone: Zone | BoundZone,
*,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
page: int | None = None,
per_page: int | None = None,
) -> ActionsPageResult:
"""
- Returns all Actions for a Zone for a specific page.
+ Returns a paginated list of Actions for a Zone.
See https://docs.hetzner.cloud/reference/cloud#zones-list-zones
- :param zone: Zone to fetch the Actions from.
- :param status: Filter the actions by status. The response will only contain actions matching the specified statuses.
- :param sort: Sort resources by field and direction.
- :param page: Page number to return.
- :param per_page: Maximum number of entries returned per page.
+ :param zone: Zone to get the Actions for.
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
+ :param page: Page number to get.
+ :param per_page: Maximum number of Actions returned per page.
"""
- params: dict[str, Any] = {}
- if status is not None:
- params["status"] = status
- if sort is not None:
- params["sort"] = sort
- if page is not None:
- params["page"] = page
- if per_page is not None:
- params["per_page"] = per_page
-
- response = self._client.request(
- method="GET",
- url=f"{self._base_url}/{zone.id_or_name}/actions",
- params=params,
- )
- return ActionsPageResult(
- actions=[BoundAction(self._parent.actions, o) for o in response["actions"]],
- meta=Meta.parse_meta(response),
+ return self._get_actions_list(
+ f"{self._base_url}/{zone.id_or_name}",
+ status=status,
+ sort=sort,
+ page=page,
+ per_page=per_page,
)
def get_actions(
self,
zone: Zone | BoundZone,
*,
- status: list[str] | None = None,
- sort: list[str] | None = None,
+ status: list[ActionStatus] | None = None,
+ sort: list[ActionSort] | None = None,
) -> list[BoundAction]:
"""
Returns all Actions for a Zone.
See https://docs.hetzner.cloud/reference/cloud#zones-list-zones
- :param zone: Zone to fetch the Actions from.
- :param status: Filter the actions by status. The response will only contain actions matching the specified statuses.
- :param sort: Sort resources by field and direction.
+ :param zone: Zone to get the Actions for.
+ :param status: Filter the Actions by status.
+ :param sort: Sort Actions by field and direction.
"""
return self._iter_pages(
self.get_actions_list,
@@ -1208,7 +1221,7 @@ class ZonesClient(ResourceClientBase):
"""
Updates records in a ZoneRRSet.
- See https://docs.hetzner.cloud/reference/cloud#zone-rrset-actions-update-records-to-an-rrset
+ See https://docs.hetzner.cloud/reference/cloud#zone-rrset-actions-update-records-of-an-rrset
:param rrset: RRSet to update.
:param records: Records to update in the RRSet.
diff --git a/plugins/module_utils/vendor/hcloud/zones/domain.py b/plugins/module_utils/vendor/hcloud/zones/domain.py
index 726641e..77aee48 100644
--- a/plugins/module_utils/vendor/hcloud/zones/domain.py
+++ b/plugins/module_utils/vendor/hcloud/zones/domain.py
@@ -2,11 +2,6 @@ from __future__ import annotations
from typing import TYPE_CHECKING, Any, Literal, TypedDict
-try:
- from dateutil.parser import isoparse
-except ImportError:
- isoparse = None
-
from ..core import BaseDomain, DomainIdentityMixin
if TYPE_CHECKING:
@@ -14,6 +9,24 @@ if TYPE_CHECKING:
from .client import BoundZone, BoundZoneRRSet
+__all__ = [
+ "ZoneMode",
+ "ZoneStatus",
+ "ZoneRegistrar",
+ "Zone",
+ "ZonePrimaryNameserver",
+ "ZoneAuthoritativeNameservers",
+ "ZoneProtection",
+ "CreateZoneResponse",
+ "DeleteZoneResponse",
+ "ExportZonefileResponse",
+ "ZoneRRSet",
+ "ZoneRRSetProtection",
+ "ZoneRecord",
+ "CreateZoneRRSetResponse",
+ "DeleteZoneRRSetResponse",
+]
+
ZoneMode = Literal["primary", "secondary"]
ZoneStatus = Literal["ok", "updating", "error"]
ZoneRegistrar = Literal["hetzner", "other", "unknown"]
@@ -81,7 +94,7 @@ class Zone(BaseDomain, DomainIdentityMixin):
):
self.id = id
self.name = name
- self.created = isoparse(created) if created else None
+ self.created = self._parse_datetime(created)
self.mode = mode
self.ttl = ttl
self.labels = labels
@@ -188,11 +201,7 @@ class ZoneAuthoritativeNameservers(BaseDomain):
):
self.assigned = assigned
self.delegated = delegated
- self.delegation_last_check = (
- isoparse(delegation_last_check)
- if delegation_last_check is not None
- else None
- )
+ self.delegation_last_check = self._parse_datetime(delegation_last_check)
self.delegation_status = delegation_status
diff --git a/scripts/vendor.py b/scripts/vendor.py
index 8e68e15..e67580d 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.12.0"
+HCLOUD_VERSION = "v2.13.0"
HCLOUD_VENDOR_PATH = "plugins/module_utils/vendor/hcloud"