From 9adb8b398191ba2442ea1886ca7187f92cd6b16c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 3 Jul 2024 15:05:12 +0200 Subject: [PATCH] chore(deps): update dependency hcloud to v2 (#523) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [hcloud](https://togithub.com/hetznercloud/hcloud-python) ([changelog](https://togithub.com/hetznercloud/hcloud-python/blob/main/CHANGELOG.md)) | `1.35.0` -> `2.0.1` | [![age](https://developer.mend.io/api/mc/badges/age/pypi/hcloud/2.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/hcloud/2.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/hcloud/1.35.0/2.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/hcloud/1.35.0/2.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
hetznercloud/hcloud-python (hcloud) ### [`v2.0.1`](https://togithub.com/hetznercloud/hcloud-python/blob/HEAD/CHANGELOG.md#201-2024-07-03) [Compare Source](https://togithub.com/hetznercloud/hcloud-python/compare/v2.0.0...v2.0.1) ##### Bug Fixes - `assignee_type` is required when creating a primary ip ([#​409](https://togithub.com/hetznercloud/hcloud-python/issues/409)) ([bce5e94](https://togithub.com/hetznercloud/hcloud-python/commit/bce5e940e27f2c6d9d50016b5828c79aadfc4401)) - clean unused arguments in the `Client.servers.rebuild` method ([#​407](https://togithub.com/hetznercloud/hcloud-python/issues/407)) ([6d33c3c](https://togithub.com/hetznercloud/hcloud-python/commit/6d33c3cff5443686c7ed37eb8635e0461bb3b928)) - details are optional in API errors ([#​411](https://togithub.com/hetznercloud/hcloud-python/issues/411)) ([f1c6594](https://togithub.com/hetznercloud/hcloud-python/commit/f1c6594dee7088872f2375359ee259e4e93b31d2)) - rename `trace_id` variable to `correlation_id` ([#​408](https://togithub.com/hetznercloud/hcloud-python/issues/408)) ([66a0f54](https://togithub.com/hetznercloud/hcloud-python/commit/66a0f546998193f9078f70a4a2fb1fc11937c086)) ### [`v2.0.0`](https://togithub.com/hetznercloud/hcloud-python/blob/HEAD/CHANGELOG.md#200-2024-07-03) [Compare Source](https://togithub.com/hetznercloud/hcloud-python/compare/v1.35.0...v2.0.0) ##### ⚠ BREAKING CHANGES - return full rebuild response in `Client.servers.rebuild` ([#​406](https://togithub.com/hetznercloud/hcloud-python/issues/406)) - make `datacenter` argument optional when creating a primary ip ([#​363](https://togithub.com/hetznercloud/hcloud-python/issues/363)) - remove deprecated `include_wildcard_architecture` argument in `IsosClient.get_list` and `IsosClient.get_all` ([#​402](https://togithub.com/hetznercloud/hcloud-python/issues/402)) - make `Client.request` `tries` a private argument ([#​399](https://togithub.com/hetznercloud/hcloud-python/issues/399)) - make `Client.poll_interval` a private property ([#​398](https://togithub.com/hetznercloud/hcloud-python/issues/398)) - return empty dict on empty responses in `Client.request` ([#​400](https://togithub.com/hetznercloud/hcloud-python/issues/400)) - remove deprecated `hcloud.hcloud` module ([#​401](https://togithub.com/hetznercloud/hcloud-python/issues/401)) - move `hcloud.__version__.VERSION` to `hcloud.__version__` ([#​397](https://togithub.com/hetznercloud/hcloud-python/issues/397)) ##### Features - add `trace_id` to API exceptions ([#​404](https://togithub.com/hetznercloud/hcloud-python/issues/404)) ([8375261](https://togithub.com/hetznercloud/hcloud-python/commit/8375261da3b84d6fece97263c7bea40ad2a6cfcf)) - allow using a custom poll_interval function ([#​403](https://togithub.com/hetznercloud/hcloud-python/issues/403)) ([93eb56b](https://togithub.com/hetznercloud/hcloud-python/commit/93eb56ba4d1a69e175398bca42e723a7e8e46371)) - make `Client.poll_interval` a private property ([#​398](https://togithub.com/hetznercloud/hcloud-python/issues/398)) ([d5f24db](https://togithub.com/hetznercloud/hcloud-python/commit/d5f24db2816a0d00b8c7936e2a0290d2c4bb1e92)) - make `Client.request` `tries` a private argument ([#​399](https://togithub.com/hetznercloud/hcloud-python/issues/399)) ([428ea7e](https://togithub.com/hetznercloud/hcloud-python/commit/428ea7e3be03a16114f875146971db59aabaac2c)) - move `hcloud.__version__.VERSION` to `hcloud.__version__` ([#​397](https://togithub.com/hetznercloud/hcloud-python/issues/397)) ([4e3f638](https://togithub.com/hetznercloud/hcloud-python/commit/4e3f638862c9d260df98182c3f7858282049c26c)), closes [#​234](https://togithub.com/hetznercloud/hcloud-python/issues/234) - remove deprecated `hcloud.hcloud` module ([#​401](https://togithub.com/hetznercloud/hcloud-python/issues/401)) ([db37e63](https://togithub.com/hetznercloud/hcloud-python/commit/db37e633ebbf73354d3b2f4858cf3eebf173bfbc)) - remove deprecated `include_wildcard_architecture` argument in `IsosClient.get_list` and `IsosClient.get_all` ([#​402](https://togithub.com/hetznercloud/hcloud-python/issues/402)) ([6b977e2](https://togithub.com/hetznercloud/hcloud-python/commit/6b977e2da5cec30110c32a91d572003e5b5c400a)) - return empty dict on empty responses in `Client.request` ([#​400](https://togithub.com/hetznercloud/hcloud-python/issues/400)) ([9f46adb](https://togithub.com/hetznercloud/hcloud-python/commit/9f46adb946eb2770ee4f3a4e87cfc1c8b9b33c28)) - return full rebuild response in `Client.servers.rebuild` ([#​406](https://togithub.com/hetznercloud/hcloud-python/issues/406)) ([1970d84](https://togithub.com/hetznercloud/hcloud-python/commit/1970d84bec2106c8c53d8e611b74d41eb5286e9b)) ##### Bug Fixes - make `datacenter` argument optional when creating a primary ip ([#​363](https://togithub.com/hetznercloud/hcloud-python/issues/363)) ([ebef774](https://togithub.com/hetznercloud/hcloud-python/commit/ebef77464c4c3b0ce33460cad2747e89d35047c7)) ##### Dependencies - update dependency coverage to >=7.5,<7.6 ([#​386](https://togithub.com/hetznercloud/hcloud-python/issues/386)) ([5660691](https://togithub.com/hetznercloud/hcloud-python/commit/5660691ebd6122fa7ebec56a24bce9fce0577573)) - update dependency mypy to >=1.10,<1.11 ([#​387](https://togithub.com/hetznercloud/hcloud-python/issues/387)) ([35c933b](https://togithub.com/hetznercloud/hcloud-python/commit/35c933bd2108d42e74b74b01d6db74e159ec9142)) - update dependency myst-parser to v3 ([#​385](https://togithub.com/hetznercloud/hcloud-python/issues/385)) ([9f18270](https://togithub.com/hetznercloud/hcloud-python/commit/9f182704898cb96f1ea162511605906f87cff50c)) - update dependency pylint to >=3,<3.3 ([#​391](https://togithub.com/hetznercloud/hcloud-python/issues/391)) ([4a6f005](https://togithub.com/hetznercloud/hcloud-python/commit/4a6f005cb0488291ae91390a612bab6afc6d80b6)) - update dependency pytest to >=8,<8.3 ([#​390](https://togithub.com/hetznercloud/hcloud-python/issues/390)) ([584a36b](https://togithub.com/hetznercloud/hcloud-python/commit/584a36b658670297ffffa9afa70835d29d27fbca)) - update dependency sphinx to >=7.3.4,<7.4 ([#​383](https://togithub.com/hetznercloud/hcloud-python/issues/383)) ([69c2e16](https://togithub.com/hetznercloud/hcloud-python/commit/69c2e16073df9ef8520e3a635b3866403eba030e)) - update pre-commit hook asottile/pyupgrade to v3.16.0 ([0ce5fbc](https://togithub.com/hetznercloud/hcloud-python/commit/0ce5fbccba4a4255e08a37abf1f21ab9cc85f287)) - update pre-commit hook pre-commit/pre-commit-hooks to v4.6.0 ([5ef25ab](https://togithub.com/hetznercloud/hcloud-python/commit/5ef25ab3966d731c4c36ea3e785c2b5f20c69489)) - update pre-commit hook psf/black-pre-commit-mirror to v24.4.0 ([0941fbf](https://togithub.com/hetznercloud/hcloud-python/commit/0941fbfab20ca8a59e768c4a5e6fc101393c97f0)) - update pre-commit hook psf/black-pre-commit-mirror to v24.4.1 ([fec08c5](https://togithub.com/hetznercloud/hcloud-python/commit/fec08c5323359d0a4f0771123f483ff975aa68b0)) - update pre-commit hook psf/black-pre-commit-mirror to v24.4.2 ([#​389](https://togithub.com/hetznercloud/hcloud-python/issues/389)) ([2b2e21f](https://togithub.com/hetznercloud/hcloud-python/commit/2b2e21f61366b5ec0f2ff5558f652d2bfed9d138)) - update pre-commit hook pycqa/flake8 to v7.1.0 ([3bc651d](https://togithub.com/hetznercloud/hcloud-python/commit/3bc651d50d85aa92ba76dbfeef1d604cabaa4628)) ##### Documentation - add v2 upgrade notes ([#​405](https://togithub.com/hetznercloud/hcloud-python/issues/405)) ([c77f771](https://togithub.com/hetznercloud/hcloud-python/commit/c77f771e2bed176acd6aa5011be006c800181809)) - cx11 is name, not an id ([#​381](https://togithub.com/hetznercloud/hcloud-python/issues/381)) ([b745d40](https://togithub.com/hetznercloud/hcloud-python/commit/b745d4049f720b93d840a9204a99d246ecb499e5))
--- ### 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 has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](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 | 1 + plugins/module_utils/vendor/hcloud/_client.py | 97 +++++++++++-------- .../module_utils/vendor/hcloud/_exceptions.py | 18 +++- .../module_utils/vendor/hcloud/_version.py | 2 +- .../vendor/hcloud/actions/client.py | 22 +++-- plugins/module_utils/vendor/hcloud/hcloud.py | 12 --- .../module_utils/vendor/hcloud/isos/client.py | 23 ----- .../vendor/hcloud/primary_ips/client.py | 17 ++-- .../vendor/hcloud/servers/client.py | 30 ++---- plugins/modules/iso_info.py | 2 +- plugins/modules/primary_ip.py | 1 - plugins/modules/server.py | 2 +- scripts/vendor.py | 13 +-- .../targets/floating_ip/tasks/test.yml | 6 +- .../targets/load_balancer/tasks/test.yml | 2 +- .../targets/network/tasks/test.yml | 2 +- .../targets/primary_ip/tasks/test.yml | 2 +- .../targets/server/tasks/test_basic.yml | 6 +- .../targets/server/tasks/test_firewalls.yml | 2 +- .../targets/server/tasks/test_validation.yml | 4 +- .../targets/ssh_key/tasks/test.yml | 2 +- .../integration/targets/volume/tasks/test.yml | 4 +- tests/unit/module_utils/test_hcloud.py | 2 +- 23 files changed, 124 insertions(+), 148 deletions(-) delete mode 100644 plugins/module_utils/vendor/hcloud/hcloud.py diff --git a/plugins/module_utils/vendor/hcloud/__init__.py b/plugins/module_utils/vendor/hcloud/__init__.py index 6b69b16..2cf9921 100644 --- a/plugins/module_utils/vendor/hcloud/__init__.py +++ b/plugins/module_utils/vendor/hcloud/__init__.py @@ -5,3 +5,4 @@ from ._exceptions import ( # noqa pylint: disable=C0414 APIException as APIException, HCloudException as HCloudException, ) +from ._version import __version__ # noqa diff --git a/plugins/module_utils/vendor/hcloud/_client.py b/plugins/module_utils/vendor/hcloud/_client.py index 257d361..842c5d0 100644 --- a/plugins/module_utils/vendor/hcloud/_client.py +++ b/plugins/module_utils/vendor/hcloud/_client.py @@ -1,15 +1,15 @@ from __future__ import annotations import time -from typing import NoReturn +from typing import Protocol try: import requests except ImportError: requests = None -from ._version import VERSION from ._exceptions import APIException +from ._version import __version__ from .actions import ActionsClient from .certificates import CertificatesClient from .datacenters import DatacentersClient @@ -29,10 +29,19 @@ from .ssh_keys import SSHKeysClient from .volumes import VolumesClient +class PollIntervalFunction(Protocol): + def __call__(self, retries: int) -> float: + """ + Return a interval in seconds to wait between each API call. + + :param retries: Number of calls already made. + """ + + class Client: """Base Client for accessing the Hetzner Cloud API""" - _version = VERSION + _version = __version__ _retry_wait_time = 0.5 __user_agent_prefix = "hcloud-python" @@ -42,7 +51,8 @@ class Client: api_endpoint: str = "https://api.hetzner.cloud/v1", application_name: str | None = None, application_version: str | None = None, - poll_interval: int = 1, + poll_interval: int | float | PollIntervalFunction = 1.0, + poll_max_retries: int = 120, timeout: float | tuple[float, float] | None = None, ): """Create a new Client instance @@ -51,7 +61,11 @@ class Client: :param api_endpoint: Hetzner Cloud API endpoint :param application_name: Your application name :param application_version: Your application _version - :param poll_interval: Interval for polling information from Hetzner Cloud API in seconds + :param poll_interval: + Interval in seconds to use when polling actions from the API. + You may pass a function to compute a custom poll interval. + :param poll_max_retries: + Max retries before timeout when polling actions from the API. :param timeout: Requests timeout in seconds """ self.token = token @@ -60,7 +74,12 @@ class Client: self._application_version = application_version self._requests_session = requests.Session() self._requests_timeout = timeout - self.poll_interval = poll_interval + + if isinstance(poll_interval, (int, float)): + self._poll_interval_func = lambda _: poll_interval # Constant poll interval + else: + self._poll_interval_func = poll_interval + self._poll_max_retries = poll_max_retries self.datacenters = DatacentersClient(self) """DatacentersClient Instance @@ -174,32 +193,18 @@ class Client: } return headers - def _raise_exception_from_response(self, response) -> NoReturn: - raise APIException( - code=response.status_code, - message=response.reason, - details={"content": response.content}, - ) - - def _raise_exception_from_content(self, content: dict) -> NoReturn: - raise APIException( - code=content["error"]["code"], - message=content["error"]["message"], - details=content["error"]["details"], - ) - def request( # type: ignore[no-untyped-def] self, method: str, url: str, - tries: int = 1, + *, + _tries: int = 1, **kwargs, ) -> dict: """Perform a request to the Hetzner Cloud API, wrapper around requests.request :param method: HTTP Method to perform the Request :param url: URL of the Endpoint - :param tries: Tries of the request (used internally, should not be set by the user) :param timeout: Requests timeout in seconds :return: Response """ @@ -213,24 +218,40 @@ class Client: **kwargs, ) - content = response.content + correlation_id = response.headers.get("X-Correlation-Id") + payload = {} try: - if len(content) > 0: - content = response.json() - except (TypeError, ValueError): - self._raise_exception_from_response(response) + if len(response.content) > 0: + payload = response.json() + except (TypeError, ValueError) as exc: + raise APIException( + code=response.status_code, + message=response.reason, + details={"content": response.content}, + correlation_id=correlation_id, + ) from exc if not response.ok: - if content: - assert isinstance(content, dict) - if content["error"]["code"] == "rate_limit_exceeded" and tries < 5: - time.sleep(tries * self._retry_wait_time) - tries = tries + 1 - return self.request(method, url, tries, **kwargs) + if not payload or "error" not in payload: + raise APIException( + code=response.status_code, + message=response.reason, + details={"content": response.content}, + correlation_id=correlation_id, + ) - self._raise_exception_from_content(content) - else: - self._raise_exception_from_response(response) + error: dict = payload["error"] - # TODO: return an empty dict instead of an empty string when content == "". - return content # type: ignore[return-value] + if error["code"] == "rate_limit_exceeded" and _tries < 5: + time.sleep(_tries * self._retry_wait_time) + _tries = _tries + 1 + return self.request(method, url, _tries=_tries, **kwargs) + + raise APIException( + code=error["code"], + message=error["message"], + details=error.get("details"), + correlation_id=correlation_id, + ) + + return payload diff --git a/plugins/module_utils/vendor/hcloud/_exceptions.py b/plugins/module_utils/vendor/hcloud/_exceptions.py index 877083f..c884a9a 100644 --- a/plugins/module_utils/vendor/hcloud/_exceptions.py +++ b/plugins/module_utils/vendor/hcloud/_exceptions.py @@ -10,8 +10,22 @@ class HCloudException(Exception): class APIException(HCloudException): """There was an error while performing an API Request""" - def __init__(self, code: int | str, message: str | None, details: Any): - super().__init__(code if message is None and isinstance(code, str) else message) + def __init__( + self, + code: int | str, + message: str, + details: Any, + *, + correlation_id: str | None = None, + ): + extras = [str(code)] + if correlation_id is not None: + extras.append(correlation_id) + + error = f"{message} ({', '.join(extras)})" + + super().__init__(error) self.code = code self.message = message self.details = details + self.correlation_id = correlation_id diff --git a/plugins/module_utils/vendor/hcloud/_version.py b/plugins/module_utils/vendor/hcloud/_version.py index d350d71..bf6f151 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 = "1.35.0" # x-release-please-version +__version__ = "2.0.1" # x-release-please-version diff --git a/plugins/module_utils/vendor/hcloud/actions/client.py b/plugins/module_utils/vendor/hcloud/actions/client.py index a188f62..85fc007 100644 --- a/plugins/module_utils/vendor/hcloud/actions/client.py +++ b/plugins/module_utils/vendor/hcloud/actions/client.py @@ -16,20 +16,24 @@ class BoundAction(BoundModelBase, Action): model = Action - def wait_until_finished(self, max_retries: int = 100) -> None: - """Wait until the specific action has status="finished" (set Client.poll_interval to specify a delay between checks) + def wait_until_finished(self, max_retries: int | None = None) -> None: + """Wait until the specific action has status=finished. - :param max_retries: int - Specify how many retries will be performed before an ActionTimeoutException will be raised - :raises: ActionFailedException when action is finished with status=="error" - :raises: ActionTimeoutException when Action is still in "running" state after max_retries reloads. + :param max_retries: int Specify how many retries will be performed before an ActionTimeoutException will be raised. + :raises: ActionFailedException when action is finished with status==error + :raises: ActionTimeoutException when Action is still in status==running after max_retries is reached. """ + if max_retries is None: + # pylint: disable=protected-access + max_retries = self._client._client._poll_max_retries + + retries = 0 while self.status == Action.STATUS_RUNNING: - if max_retries > 0: + if retries < max_retries: self.reload() + retries += 1 # pylint: disable=protected-access - time.sleep(self._client._client.poll_interval) - max_retries = max_retries - 1 + time.sleep(self._client._client._poll_interval_func(retries)) else: raise ActionTimeoutException(action=self) diff --git a/plugins/module_utils/vendor/hcloud/hcloud.py b/plugins/module_utils/vendor/hcloud/hcloud.py deleted file mode 100644 index 9de1cfe..0000000 --- a/plugins/module_utils/vendor/hcloud/hcloud.py +++ /dev/null @@ -1,12 +0,0 @@ -from __future__ import annotations - -import warnings - -warnings.warn( - "The 'hcloud.hcloud' module is deprecated, please import from the 'hcloud' module instead (e.g. 'from hcloud import Client').", - DeprecationWarning, - stacklevel=2, -) - -# pylint: disable=wildcard-import,wrong-import-position,unused-wildcard-import -from ._client import * # noqa diff --git a/plugins/module_utils/vendor/hcloud/isos/client.py b/plugins/module_utils/vendor/hcloud/isos/client.py index cc46af7..fa7b1a8 100644 --- a/plugins/module_utils/vendor/hcloud/isos/client.py +++ b/plugins/module_utils/vendor/hcloud/isos/client.py @@ -1,7 +1,6 @@ from __future__ import annotations from typing import TYPE_CHECKING, Any, NamedTuple -from warnings import warn from ..core import BoundModelBase, ClientEntityBase, Meta from .domain import Iso @@ -37,7 +36,6 @@ class IsosClient(ClientEntityBase): self, name: str | None = None, architecture: list[str] | None = None, - include_wildcard_architecture: bool | None = None, include_architecture_wildcard: bool | None = None, page: int | None = None, per_page: int | None = None, @@ -48,8 +46,6 @@ class IsosClient(ClientEntityBase): Can be used to filter ISOs by their name. :param architecture: List[str] (optional) Can be used to filter ISOs by their architecture. Choices: x86 arm - :param include_wildcard_architecture: bool (optional) - Deprecated, please use `include_architecture_wildcard` instead. :param include_architecture_wildcard: bool (optional) Custom ISOs do not have an architecture set. You must also set this flag to True if you are filtering by architecture and also want custom ISOs. @@ -59,14 +55,6 @@ class IsosClient(ClientEntityBase): Specifies how many results are returned by page :return: (List[:class:`BoundIso `], :class:`Meta `) """ - - if include_wildcard_architecture is not None: - warn( - "The `include_wildcard_architecture` argument is deprecated, please use the `include_architecture_wildcard` argument instead.", - DeprecationWarning, - ) - include_architecture_wildcard = include_wildcard_architecture - params: dict[str, Any] = {} if name is not None: params["name"] = name @@ -87,7 +75,6 @@ class IsosClient(ClientEntityBase): self, name: str | None = None, architecture: list[str] | None = None, - include_wildcard_architecture: bool | None = None, include_architecture_wildcard: bool | None = None, ) -> list[BoundIso]: """Get all ISOs @@ -96,21 +83,11 @@ class IsosClient(ClientEntityBase): Can be used to filter ISOs by their name. :param architecture: List[str] (optional) Can be used to filter ISOs by their architecture. Choices: x86 arm - :param include_wildcard_architecture: bool (optional) - Deprecated, please use `include_architecture_wildcard` instead. :param include_architecture_wildcard: bool (optional) Custom ISOs do not have an architecture set. You must also set this flag to True if you are filtering by architecture and also want custom ISOs. :return: List[:class:`BoundIso `] """ - - if include_wildcard_architecture is not None: - warn( - "The `include_wildcard_architecture` argument is deprecated, please use the `include_architecture_wildcard` argument instead.", - DeprecationWarning, - ) - include_architecture_wildcard = include_wildcard_architecture - return self._iter_pages( self.get_list, name=name, diff --git a/plugins/module_utils/vendor/hcloud/primary_ips/client.py b/plugins/module_utils/vendor/hcloud/primary_ips/client.py index ece8d88..41ef3bf 100644 --- a/plugins/module_utils/vendor/hcloud/primary_ips/client.py +++ b/plugins/module_utils/vendor/hcloud/primary_ips/client.py @@ -189,9 +189,8 @@ class PrimaryIPsClient(ClientEntityBase): def create( self, type: str, - # TODO: Make the datacenter argument optional - datacenter: Datacenter | BoundDatacenter | None, name: str, + datacenter: Datacenter | BoundDatacenter | None = None, assignee_type: str | None = "server", assignee_id: int | None = None, auto_delete: bool | None = False, @@ -199,23 +198,21 @@ class PrimaryIPsClient(ClientEntityBase): ) -> CreatePrimaryIPResponse: """Creates a new Primary IP assigned to a server. - :param type: str - Primary IP type Choices: ipv4, ipv6 - :param assignee_type: str - :param assignee_id: int (optional) - :param datacenter: Datacenter - :param labels: Dict[str, str] (optional) - User-defined labels (key-value pairs) + :param type: str Primary IP type Choices: ipv4, ipv6 :param name: str + :param datacenter: Datacenter (optional) + :param assignee_type: str (optional) + :param assignee_id: int (optional) :param auto_delete: bool (optional) + :param labels: Dict[str, str] (optional) User-defined labels (key-value pairs) :return: :class:`CreatePrimaryIPResponse ` """ data: dict[str, Any] = { + "name": name, "type": type, "assignee_type": assignee_type, "auto_delete": auto_delete, - "name": name, } if datacenter is not None: data["datacenter"] = datacenter.id_or_name diff --git a/plugins/module_utils/vendor/hcloud/servers/client.py b/plugins/module_utils/vendor/hcloud/servers/client.py index b959b9d..0d65e79 100644 --- a/plugins/module_utils/vendor/hcloud/servers/client.py +++ b/plugins/module_utils/vendor/hcloud/servers/client.py @@ -1,6 +1,5 @@ from __future__ import annotations -import warnings from datetime import datetime from typing import TYPE_CHECKING, Any, NamedTuple @@ -336,15 +335,14 @@ class BoundServer(BoundModelBase, Server): def rebuild( self, image: Image | BoundImage, - *, - return_response: bool = False, - ) -> RebuildResponse | BoundAction: + # pylint: disable=unused-argument + **kwargs: Any, + ) -> RebuildResponse: """Rebuilds a server overwriting its disk with the content of an image, thereby destroying all data on the target server. :param image: Image to use for the rebuilt server - :param return_response: Whether to return the full response or only the action. """ - return self._client.rebuild(self, image, return_response=return_response) + return self._client.rebuild(self, image) def change_type( self, @@ -1009,14 +1007,13 @@ class ServersClient(ClientEntityBase): self, server: Server | BoundServer, image: Image | BoundImage, - *, - return_response: bool = False, - ) -> RebuildResponse | BoundAction: + # pylint: disable=unused-argument + **kwargs: Any, + ) -> RebuildResponse: """Rebuilds a server overwriting its disk with the content of an image, thereby destroying all data on the target server. :param server: Server to rebuild :param image: Image to use for the rebuilt server - :param return_response: Whether to return the full response or only the action. """ data: dict[str, Any] = {"image": image.id_or_name} response = self._client.request( @@ -1025,22 +1022,11 @@ class ServersClient(ClientEntityBase): json=data, ) - rebuild_response = RebuildResponse( + return RebuildResponse( action=BoundAction(self._client.actions, response["action"]), root_password=response.get("root_password"), ) - if not return_response: - warnings.warn( - "Returning only the 'action' is deprecated, please set the " - "'return_response' keyword argument to 'True' to return the full " - "rebuild response and update your code accordingly.", - DeprecationWarning, - stacklevel=2, - ) - return rebuild_response.action - return rebuild_response - def enable_backup(self, server: Server | BoundServer) -> BoundAction: """Enables and configures the automatic daily backup option for the server. Enabling automatic backups will increase the price of the server by 20%. diff --git a/plugins/modules/iso_info.py b/plugins/modules/iso_info.py index aab33ca..1ba5193 100644 --- a/plugins/modules/iso_info.py +++ b/plugins/modules/iso_info.py @@ -172,7 +172,7 @@ class AnsibleHCloudIsoInfo(AnsibleHCloud): else: self.hcloud_iso_info = self.client.isos.get_all( architecture=self.module.params.get("architecture"), - include_wildcard_architecture=self.module.params.get("include_wildcard_architecture"), + include_architecture_wildcard=self.module.params.get("include_wildcard_architecture"), ) except HCloudException as exception: diff --git a/plugins/modules/primary_ip.py b/plugins/modules/primary_ip.py index 08bcea4..a257325 100644 --- a/plugins/modules/primary_ip.py +++ b/plugins/modules/primary_ip.py @@ -214,7 +214,6 @@ class AnsibleHCloudPrimaryIP(AnsibleHCloud): "type": self.module.params.get("type"), "name": self.module.params.get("name"), "auto_delete": self.module.params.get("auto_delete"), - "datacenter": None, # TODO: https://github.com/hetznercloud/hcloud-python/pull/363 } if self.module.params.get("datacenter") is not None: diff --git a/plugins/modules/server.py b/plugins/modules/server.py index 350415b..765b358 100644 --- a/plugins/modules/server.py +++ b/plugins/modules/server.py @@ -868,7 +868,7 @@ class AnsibleHCloudServer(AnsibleHCloud): if not self.module.check_mode: image = self._get_image(self.hcloud_server.server_type) # When we rebuild the server progress takes some more time. - resp = self.client.servers.rebuild(self.hcloud_server, image, return_response=True) + resp = self.client.servers.rebuild(self.hcloud_server, image) resp.action.wait_until_finished(1000) self._mark_as_changed() diff --git a/scripts/vendor.py b/scripts/vendor.py index 4fa881d..6ff12ad 100755 --- a/scripts/vendor.py +++ b/scripts/vendor.py @@ -22,26 +22,15 @@ from textwrap import dedent logger = logging.getLogger("vendor") HCLOUD_SOURCE_URL = "https://github.com/hetznercloud/hcloud-python" -HCLOUD_VERSION = "v1.35.0" +HCLOUD_VERSION = "v2.0.1" HCLOUD_VENDOR_PATH = "plugins/module_utils/vendor/hcloud" def apply_code_modifications(source_path: Path): - # The ansible galaxy-importer consider __version___.py to be an invalid filename in module_utils/ - # Move the __version__.py file to _version.py - move(source_path / "__version__.py", source_path / "_version.py") - for file in source_path.rglob("*.py"): content = file.read_text() content_orig = content - # Move the __version__.py file to _version.py - content = re.sub( - r"from .__version__ import VERSION", - r"from ._version import VERSION", - content, - ) - # Wrap requests imports content = re.sub( r"import requests", diff --git a/tests/integration/targets/floating_ip/tasks/test.yml b/tests/integration/targets/floating_ip/tasks/test.yml index 8f27e4f..6b4b58d 100644 --- a/tests/integration/targets/floating_ip/tasks/test.yml +++ b/tests/integration/targets/floating_ip/tasks/test.yml @@ -102,7 +102,7 @@ that: - result is failed - result.failure.code == "invalid_input" - - result.msg == "invalid input in fields 'server', 'home_location'" + - result.failure.message == "invalid input in fields 'server', 'home_location'" - name: test create Floating IP with check mode hetzner.hcloud.floating_ip: @@ -373,7 +373,7 @@ that: - result is failed - result.failure.code == "protected" - - result.msg == "Floating IP deletion is protected" + - result.failure.message == "Floating IP deletion is protected" - name: test update Floating IP delete protection hetzner.hcloud.floating_ip: @@ -462,7 +462,7 @@ that: - result is failed - result.failure.code == "protected" - - result.msg == "Floating IP deletion is protected" + - result.failure.message == "Floating IP deletion is protected" - name: test update Floating IP delete protection hetzner.hcloud.floating_ip: diff --git a/tests/integration/targets/load_balancer/tasks/test.yml b/tests/integration/targets/load_balancer/tasks/test.yml index 3b7de5b..4593f93 100644 --- a/tests/integration/targets/load_balancer/tasks/test.yml +++ b/tests/integration/targets/load_balancer/tasks/test.yml @@ -121,7 +121,7 @@ that: - result is failed - result.failure.code == "protected" - - result.msg == "load balancer deletion is protected" + - result.failure.message == "load balancer deletion is protected" - name: Test update delete_protection hetzner.hcloud.load_balancer: diff --git a/tests/integration/targets/network/tasks/test.yml b/tests/integration/targets/network/tasks/test.yml index b814ceb..7651b5e 100644 --- a/tests/integration/targets/network/tasks/test.yml +++ b/tests/integration/targets/network/tasks/test.yml @@ -100,7 +100,7 @@ that: - result is failed - result.failure.code == "protected" - - result.msg == "network deletion is protected" + - result.failure.message == "network deletion is protected" - name: Test update delete protection hetzner.hcloud.network: diff --git a/tests/integration/targets/primary_ip/tasks/test.yml b/tests/integration/targets/primary_ip/tasks/test.yml index 1c43846..970631d 100644 --- a/tests/integration/targets/primary_ip/tasks/test.yml +++ b/tests/integration/targets/primary_ip/tasks/test.yml @@ -121,7 +121,7 @@ that: - result is failed - result.failure.code == "protected" - - result.msg == "Primary IP deletion is protected" + - result.failure.message == "Primary IP deletion is protected" - name: Test update delete protection hetzner.hcloud.primary_ip: diff --git a/tests/integration/targets/server/tasks/test_basic.yml b/tests/integration/targets/server/tasks/test_basic.yml index b80a0d2..571a75c 100644 --- a/tests/integration/targets/server/tasks/test_basic.yml +++ b/tests/integration/targets/server/tasks/test_basic.yml @@ -316,7 +316,7 @@ that: - result is failed - result.failure.code == "protected" - - result.msg == "server deletion is protected" + - result.failure.message == "server deletion is protected" - name: test rebuild server fails if it is protected hetzner.hcloud.server: @@ -330,7 +330,7 @@ that: - result is failed - result.failure.code == "protected" - - result.msg == "server rebuild is protected" + - result.failure.message == "server rebuild is protected" - name: test remove server protection hetzner.hcloud.server: @@ -588,7 +588,7 @@ that: - result is failed - result.failure.code == "protected" - - result.msg == "server deletion is protected" + - result.failure.message == "server deletion is protected" - name: remove protection from server hetzner.hcloud.server: diff --git a/tests/integration/targets/server/tasks/test_firewalls.yml b/tests/integration/targets/server/tasks/test_firewalls.yml index 661012c..efcba3f 100644 --- a/tests/integration/targets/server/tasks/test_firewalls.yml +++ b/tests/integration/targets/server/tasks/test_firewalls.yml @@ -14,7 +14,7 @@ that: - result is failed - result.failure.code == "not_found" - - result.msg == "firewall not-existing was not found" + - result.failure.message == "firewall not-existing was not found" - name: setup create firewalls hetzner.hcloud.firewall: diff --git a/tests/integration/targets/server/tasks/test_validation.yml b/tests/integration/targets/server/tasks/test_validation.yml index 545117b..9d9a7e0 100644 --- a/tests/integration/targets/server/tasks/test_validation.yml +++ b/tests/integration/targets/server/tasks/test_validation.yml @@ -35,7 +35,7 @@ that: - result is failed - result.failure.code == "not_found" - - result.msg == "server_type not-existing-server-type was not found" + - result.failure.message == "server_type not-existing-server-type was not found" - name: test create server with not existing image hetzner.hcloud.server: @@ -50,4 +50,4 @@ that: - result is failed - result.failure.code == "not_found" - - result.msg == "Image my-not-existing-image-20.04 was not found" + - result.failure.message == "Image my-not-existing-image-20.04 was not found" diff --git a/tests/integration/targets/ssh_key/tasks/test.yml b/tests/integration/targets/ssh_key/tasks/test.yml index 3403080..29a797d 100644 --- a/tests/integration/targets/ssh_key/tasks/test.yml +++ b/tests/integration/targets/ssh_key/tasks/test.yml @@ -134,7 +134,7 @@ that: - result is failed - result.failure.code == "uniqueness_error" - - result.msg == "SSH key with the same fingerprint already exists" + - result.failure.message == "SSH key with the same fingerprint already exists" - name: test delete ssh key hetzner.hcloud.ssh_key: diff --git a/tests/integration/targets/volume/tasks/test.yml b/tests/integration/targets/volume/tasks/test.yml index 55ed807..e116886 100644 --- a/tests/integration/targets/volume/tasks/test.yml +++ b/tests/integration/targets/volume/tasks/test.yml @@ -209,7 +209,7 @@ that: - result is failed - result.failure.code == "protected" - - result.msg == "volume deletion is protected" + - result.failure.message == "volume deletion is protected" - name: test update Volume delete protection hetzner.hcloud.volume: @@ -256,7 +256,7 @@ that: - result is failed - result.failure.code == "protected" - - result.msg == "volume deletion is protected" + - result.failure.message == "volume deletion is protected" - name: test update Volume delete protection hetzner.hcloud.volume: diff --git a/tests/unit/module_utils/test_hcloud.py b/tests/unit/module_utils/test_hcloud.py index 2f5e750..196ca87 100644 --- a/tests/unit/module_utils/test_hcloud.py +++ b/tests/unit/module_utils/test_hcloud.py @@ -35,7 +35,7 @@ def test_hcloud_fail_json_hcloud(module): hcloud.fail_json_hcloud(exception) module.fail_json.assert_called_with( - msg="invalid input in fields 'server', 'home_location'", + msg="invalid input in fields 'server', 'home_location' (invalid_input)", exception=traceback.format_exc(), failure={ "message": "invalid input in fields 'server', 'home_location'",