From 28c2148510d21a01bc76e6f22ed844ef06324ce2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Aug 2024 17:13:18 +0200 Subject: [PATCH] chore(deps): update dependency hcloud to v2.2.0 (#544) 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)) | `2.1.1` -> `2.2.0` | [![age](https://developer.mend.io/api/mc/badges/age/pypi/hcloud/2.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/pypi/hcloud/2.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/pypi/hcloud/2.1.1/2.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/hcloud/2.1.1/2.2.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes
hetznercloud/hcloud-python (hcloud) ### [`v2.2.0`](https://togithub.com/hetznercloud/hcloud-python/blob/HEAD/CHANGELOG.md#220-2024-08-06) [Compare Source](https://togithub.com/hetznercloud/hcloud-python/compare/v2.1.1...v2.2.0) ##### Features - retry requests when the api gateway errors ([#​430](https://togithub.com/hetznercloud/hcloud-python/issues/430)) ([f63ac8b](https://togithub.com/hetznercloud/hcloud-python/commit/f63ac8b4d08d84804b5431295ba689275c9203f7)) - retry requests when the api returns a conflict error ([#​430](https://togithub.com/hetznercloud/hcloud-python/issues/430)) ([f63ac8b](https://togithub.com/hetznercloud/hcloud-python/commit/f63ac8b4d08d84804b5431295ba689275c9203f7)) - retry requests when the network timed outs ([#​430](https://togithub.com/hetznercloud/hcloud-python/issues/430)) ([f63ac8b](https://togithub.com/hetznercloud/hcloud-python/commit/f63ac8b4d08d84804b5431295ba689275c9203f7)) - retry requests when the rate limit was reached ([#​430](https://togithub.com/hetznercloud/hcloud-python/issues/430)) ([f63ac8b](https://togithub.com/hetznercloud/hcloud-python/commit/f63ac8b4d08d84804b5431295ba689275c9203f7)) ##### Bug Fixes - update network subnet types ([#​431](https://togithub.com/hetznercloud/hcloud-python/issues/431)) ([c32a615](https://togithub.com/hetznercloud/hcloud-python/commit/c32a615db778d57324632d8df99356bb04a91efa))
--- ### 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://www.mend.io/free-developer-tools/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 --- plugins/module_utils/vendor/hcloud/_client.py | 128 ++++++++++++------ .../module_utils/vendor/hcloud/_version.py | 2 +- .../vendor/hcloud/networks/domain.py | 28 +++- scripts/vendor.py | 2 +- 4 files changed, 114 insertions(+), 46 deletions(-) diff --git a/plugins/module_utils/vendor/hcloud/_client.py b/plugins/module_utils/vendor/hcloud/_client.py index 6f1fdad..b208181 100644 --- a/plugins/module_utils/vendor/hcloud/_client.py +++ b/plugins/module_utils/vendor/hcloud/_client.py @@ -1,6 +1,7 @@ from __future__ import annotations import time +from http import HTTPStatus from random import uniform from typing import Protocol @@ -81,7 +82,33 @@ def exponential_backoff_function( class Client: - """Base Client for accessing the Hetzner Cloud API""" + """ + Client for the Hetzner Cloud API. + + The Hetzner Cloud API reference is available at https://docs.hetzner.cloud. + + **Retry mechanism** + + The :attr:`Client.request` method will retry failed requests that match certain criteria. The + default retry interval is defined by an exponential backoff algorithm truncated to 60s + with jitter. The default maximal number of retries is 5. + + The following rules define when a request can be retried: + + - When the client returned a network timeout error. + - When the API returned an HTTP error, with the status code: + + - ``502`` Bad Gateway + - ``504`` Gateway Timeout + + - When the API returned an application error, with the code: + + - ``conflict`` + - ``rate_limit_exceeded`` + + Changes to the retry policy might occur between releases, and will not be considered + breaking changes. + """ _version = __version__ __user_agent_prefix = "hcloud-python" @@ -259,50 +286,71 @@ class Client: retries = 0 while True: - response = self._requests_session.request( - method=method, - url=url, - headers=headers, - **kwargs, - ) - - correlation_id = response.headers.get("X-Correlation-Id") - payload = {} try: - if len(response.content) > 0: - payload = response.json() - except (TypeError, ValueError) as exc: + response = self._requests_session.request( + method=method, + url=url, + headers=headers, + **kwargs, + ) + return self._read_response(response) + except APIException as exception: + if retries < self._retry_max_retries and self._retry_policy(exception): + time.sleep(self._retry_interval(retries)) + retries += 1 + continue + raise + except requests.exceptions.Timeout: + if retries < self._retry_max_retries: + time.sleep(self._retry_interval(retries)) + retries += 1 + continue + raise + + def _read_response(self, response) -> dict: + correlation_id = response.headers.get("X-Correlation-Id") + payload = {} + try: + 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 not payload or "error" not in payload: raise APIException( code=response.status_code, message=response.reason, details={"content": response.content}, correlation_id=correlation_id, - ) from exc - - if not response.ok: - 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, - ) - - error: dict = payload["error"] - - if ( - error["code"] == "rate_limit_exceeded" - and retries < self._retry_max_retries - ): - time.sleep(self._retry_interval(retries)) - retries += 1 - continue - - raise APIException( - code=error["code"], - message=error["message"], - details=error.get("details"), - correlation_id=correlation_id, ) - return payload + error: dict = payload["error"] + raise APIException( + code=error["code"], + message=error["message"], + details=error.get("details"), + correlation_id=correlation_id, + ) + + return payload + + def _retry_policy(self, exception: APIException) -> bool: + if isinstance(exception.code, str): + return exception.code in ( + "rate_limit_exceeded", + "conflict", + ) + + if isinstance(exception.code, int): + return exception.code in ( + HTTPStatus.BAD_GATEWAY, + HTTPStatus.GATEWAY_TIMEOUT, + ) + + return False diff --git a/plugins/module_utils/vendor/hcloud/_version.py b/plugins/module_utils/vendor/hcloud/_version.py index 0dbaa6b..1fc7f59 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.1.1" # x-release-please-version +__version__ = "2.2.0" # x-release-please-version diff --git a/plugins/module_utils/vendor/hcloud/networks/domain.py b/plugins/module_utils/vendor/hcloud/networks/domain.py index 7dac858..3c5f02d 100644 --- a/plugins/module_utils/vendor/hcloud/networks/domain.py +++ b/plugins/module_utils/vendor/hcloud/networks/domain.py @@ -1,5 +1,6 @@ from __future__ import annotations +import warnings from typing import TYPE_CHECKING try: @@ -92,12 +93,31 @@ class NetworkSubnet(BaseDomain): ID of the vSwitch. """ - TYPE_SERVER = "server" - """Subnet Type server, deprecated, use TYPE_CLOUD instead""" + @property + def TYPE_SERVER(self) -> str: # pylint: disable=invalid-name + """ + Used to connect cloud servers and load balancers. + + .. deprecated:: 2.2.0 + Use :attr:`NetworkSubnet.TYPE_CLOUD` instead. + """ + warnings.warn( + "The 'NetworkSubnet.TYPE_SERVER' property is deprecated, please use the `NetworkSubnet.TYPE_CLOUD` property instead.", + DeprecationWarning, + stacklevel=2, + ) + return "server" + TYPE_CLOUD = "cloud" - """Subnet Type cloud""" + """ + Used to connect cloud servers and load balancers. + """ TYPE_VSWITCH = "vswitch" - """Subnet Type vSwitch""" + """ + Used to connect cloud servers and load balancers with dedicated servers. + + See https://docs.hetzner.com/cloud/networks/connect-dedi-vswitch/ + """ __api_properties__ = ("type", "ip_range", "network_zone", "gateway", "vswitch_id") __slots__ = __api_properties__ diff --git a/scripts/vendor.py b/scripts/vendor.py index ee4010a..415d220 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.1.1" +HCLOUD_VERSION = "v2.2.0" HCLOUD_VENDOR_PATH = "plugins/module_utils/vendor/hcloud"