mirror of
https://github.com/ansible-collections/hetzner.hcloud
synced 2024-11-10 06:34:13 +00:00
chore(deps): update dependency hcloud to v2.2.0 (#544)
[![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 <details> <summary>hetznercloud/hcloud-python (hcloud)</summary> ### [`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](f63ac8b4d0
)) - retry requests when the api returns a conflict error ([#​430](https://togithub.com/hetznercloud/hcloud-python/issues/430)) ([f63ac8b](f63ac8b4d0
)) - retry requests when the network timed outs ([#​430](https://togithub.com/hetznercloud/hcloud-python/issues/430)) ([f63ac8b](f63ac8b4d0
)) - retry requests when the rate limit was reached ([#​430](https://togithub.com/hetznercloud/hcloud-python/issues/430)) ([f63ac8b](f63ac8b4d0
)) ##### Bug Fixes - update network subnet types ([#​431](https://togithub.com/hetznercloud/hcloud-python/issues/431)) ([c32a615](c32a615db7
)) </details> --- ### 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. --- - [ ] <!-- rebase-check -->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). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOC4xOC4xNyIsInVwZGF0ZWRJblZlciI6IjM4LjE4LjE3IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119--> --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: jo <ljonas@riseup.net>
This commit is contained in:
parent
87ad95a0ad
commit
28c2148510
4 changed files with 114 additions and 46 deletions
128
plugins/module_utils/vendor/hcloud/_client.py
vendored
128
plugins/module_utils/vendor/hcloud/_client.py
vendored
|
@ -1,6 +1,7 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
from http import HTTPStatus
|
||||||
from random import uniform
|
from random import uniform
|
||||||
from typing import Protocol
|
from typing import Protocol
|
||||||
|
|
||||||
|
@ -81,7 +82,33 @@ def exponential_backoff_function(
|
||||||
|
|
||||||
|
|
||||||
class Client:
|
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__
|
_version = __version__
|
||||||
__user_agent_prefix = "hcloud-python"
|
__user_agent_prefix = "hcloud-python"
|
||||||
|
@ -259,50 +286,71 @@ class Client:
|
||||||
|
|
||||||
retries = 0
|
retries = 0
|
||||||
while True:
|
while True:
|
||||||
response = self._requests_session.request(
|
|
||||||
method=method,
|
|
||||||
url=url,
|
|
||||||
headers=headers,
|
|
||||||
**kwargs,
|
|
||||||
)
|
|
||||||
|
|
||||||
correlation_id = response.headers.get("X-Correlation-Id")
|
|
||||||
payload = {}
|
|
||||||
try:
|
try:
|
||||||
if len(response.content) > 0:
|
response = self._requests_session.request(
|
||||||
payload = response.json()
|
method=method,
|
||||||
except (TypeError, ValueError) as exc:
|
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(
|
raise APIException(
|
||||||
code=response.status_code,
|
code=response.status_code,
|
||||||
message=response.reason,
|
message=response.reason,
|
||||||
details={"content": response.content},
|
details={"content": response.content},
|
||||||
correlation_id=correlation_id,
|
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
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
__version__ = "2.1.1" # x-release-please-version
|
__version__ = "2.2.0" # x-release-please-version
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import warnings
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -92,12 +93,31 @@ class NetworkSubnet(BaseDomain):
|
||||||
ID of the vSwitch.
|
ID of the vSwitch.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
TYPE_SERVER = "server"
|
@property
|
||||||
"""Subnet Type server, deprecated, use TYPE_CLOUD instead"""
|
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"
|
TYPE_CLOUD = "cloud"
|
||||||
"""Subnet Type cloud"""
|
"""
|
||||||
|
Used to connect cloud servers and load balancers.
|
||||||
|
"""
|
||||||
TYPE_VSWITCH = "vswitch"
|
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")
|
__api_properties__ = ("type", "ip_range", "network_zone", "gateway", "vswitch_id")
|
||||||
__slots__ = __api_properties__
|
__slots__ = __api_properties__
|
||||||
|
|
|
@ -22,7 +22,7 @@ from textwrap import dedent
|
||||||
logger = logging.getLogger("vendor")
|
logger = logging.getLogger("vendor")
|
||||||
|
|
||||||
HCLOUD_SOURCE_URL = "https://github.com/hetznercloud/hcloud-python"
|
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"
|
HCLOUD_VENDOR_PATH = "plugins/module_utils/vendor/hcloud"
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue