mirror of
https://github.com/ansible-collections/hetzner.hcloud.git
synced 2026-02-04 08:01:49 +00:00
chore(deps): update dependency hcloud to v2.13.0 (#776)
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 <details> <summary>hetznercloud/hcloud-python (hcloud)</summary> ### [`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)) </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://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/ansible-collections/hetzner.hcloud). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi41OS4wIiwidXBkYXRlZEluVmVyIjoiNDIuNTkuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==--> --------- 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
f204b21ee0
commit
af3e9f4bf2
63 changed files with 1487 additions and 895 deletions
24
plugins/module_utils/vendor/hcloud/__init__.py
vendored
24
plugins/module_utils/vendor/hcloud/__init__.py
vendored
|
|
@ -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",
|
||||
]
|
||||
|
|
|
|||
12
plugins/module_utils/vendor/hcloud/_client.py
vendored
12
plugins/module_utils/vendor/hcloud/_client.py
vendored
|
|
@ -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"],
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
from __future__ import annotations
|
||||
|
||||
__version__ = "2.12.0" # x-releaser-pleaser-version
|
||||
__version__ = "2.13.0" # x-releaser-pleaser-version
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
]
|
||||
|
|
|
|||
164
plugins/module_utils/vendor/hcloud/actions/client.py
vendored
164
plugins/module_utils/vendor/hcloud/actions/client.py
vendored
|
|
@ -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 <hcloud.actions.client.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 <hcloud.actions.client.BoundAction>`], :class:`Meta <hcloud.core.domain.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 <hcloud.actions.client.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
|
||||
|
|
|
|||
|
|
@ -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)})"
|
||||
|
|
|
|||
|
|
@ -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 <hcloud.actions.client.BoundAction>`], :class:`Meta <hcloud.core.domain.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 <hcloud.actions.client.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 <hcloud.certificates.client.BoundCertificate>` or :class:`Certificate <hcloud.certificates.domain.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 <hcloud.actions.client.BoundAction>`], :class:`Meta <hcloud.core.domain.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 <hcloud.certificates.client.BoundCertificate>` or :class:`Certificate <hcloud.certificates.domain.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 <hcloud.actions.client.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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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"""
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -2,4 +2,6 @@ from __future__ import annotations
|
|||
|
||||
from .domain import DeprecationInfo
|
||||
|
||||
__all__ = ["DeprecationInfo"]
|
||||
__all__ = [
|
||||
"DeprecationInfo",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -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 <hcloud.actions.client.BoundAction>`], :class:`Meta <hcloud.core.domain.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 <hcloud.actions.client.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 <hcloud.firewalls.client.BoundFirewall>` or :class:`Firewall <hcloud.firewalls.domain.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 <hcloud.actions.client.BoundAction>`], :class:`Meta <hcloud.core.domain.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 <hcloud.firewalls.client.BoundFirewall>` or :class:`Firewall <hcloud.firewalls.domain.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 <hcloud.actions.client.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,
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -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 <hcloud.actions.client.BoundAction>`], :class:`Meta <hcloud.core.domain.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 <hcloud.actions.client.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 <hcloud.floating_ips.client.BoundFloatingIP>` or :class:`FloatingIP <hcloud.floating_ips.domain.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 <hcloud.actions.client.BoundAction>`], :class:`Meta <hcloud.core.domain.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 <hcloud.floating_ips.client.BoundFloatingIP>` or :class:`FloatingIP <hcloud.floating_ips.domain.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 <hcloud.actions.client.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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -2,4 +2,6 @@ from __future__ import annotations
|
|||
|
||||
from .labels import LabelValidator
|
||||
|
||||
__all__ = ["LabelValidator"]
|
||||
__all__ = [
|
||||
"LabelValidator",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@ from __future__ import annotations
|
|||
|
||||
import re
|
||||
|
||||
__all__ = [
|
||||
"LabelValidator",
|
||||
]
|
||||
|
||||
|
||||
class LabelValidator:
|
||||
KEY_REGEX = re.compile(
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
]
|
||||
|
|
|
|||
129
plugins/module_utils/vendor/hcloud/images/client.py
vendored
129
plugins/module_utils/vendor/hcloud/images/client.py
vendored
|
|
@ -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 <hcloud.actions.client.BoundAction>`], :class:`Meta <hcloud.core.domain.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 <hcloud.actions.client.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 <hcloud.images.client.BoundImage>` or :class:`Image <hcloud.images.domain.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 <hcloud.actions.client.BoundAction>`], :class:`Meta <hcloud.core.domain.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 <hcloud.images.client.BoundImage>` or :class:`Image <hcloud.images.domain.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 <hcloud.actions.client.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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -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 <hcloud.actions.client.BoundAction>`], :class:`Meta <hcloud.core.domain.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 <hcloud.actions.client.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 <hcloud.load_balancers.client.BoundLoadBalancer>` or :class:`LoadBalancer <hcloud.load_balancers.domain.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 <hcloud.actions.client.BoundAction>`], :class:`Meta <hcloud.core.domain.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 <hcloud.load_balancers.client.BoundLoadBalancer>` or :class:`LoadBalancer <hcloud.load_balancers.domain.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 <hcloud.actions.client.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,
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@ from __future__ import annotations
|
|||
|
||||
from ..core import BaseDomain, DomainIdentityMixin
|
||||
|
||||
__all__ = [
|
||||
"Location",
|
||||
]
|
||||
|
||||
|
||||
class Location(BaseDomain, DomainIdentityMixin):
|
||||
"""Location Domain
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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 <hcloud.actions.client.BoundAction>`], :class:`Meta <hcloud.core.domain.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 <hcloud.actions.client.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 <hcloud.networks.client.BoundNetwork>` or :class:`Network <hcloud.networks.domain.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 <hcloud.actions.client.BoundAction>`], :class:`Meta <hcloud.core.domain.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 <hcloud.networks.client.BoundNetwork>` or :class:`Network <hcloud.networks.domain.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 <hcloud.actions.client.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,
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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 <hcloud.datacenters.client.BoundDatacenter>`
|
||||
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 <hcloud.locations.client.BoundLocation>`
|
||||
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
|
||||
|
|
|
|||
7
plugins/module_utils/vendor/hcloud/rdns/__init__.py
vendored
Normal file
7
plugins/module_utils/vendor/hcloud/rdns/__init__.py
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from .domain import DNSPtr
|
||||
|
||||
__all__ = [
|
||||
"DNSPtr",
|
||||
]
|
||||
12
plugins/module_utils/vendor/hcloud/rdns/domain.py
vendored
Normal file
12
plugins/module_utils/vendor/hcloud/rdns/domain.py
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TypedDict
|
||||
|
||||
__all__ = [
|
||||
"DNSPtr",
|
||||
]
|
||||
|
||||
|
||||
class DNSPtr(TypedDict):
|
||||
ip: str
|
||||
dns_ptr: str
|
||||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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 = (
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
]
|
||||
|
|
|
|||
147
plugins/module_utils/vendor/hcloud/servers/client.py
vendored
147
plugins/module_utils/vendor/hcloud/servers/client.py
vendored
|
|
@ -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 <hcloud.actions.client.BoundAction>`], :class:`Meta <hcloud.core.domain.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 <hcloud.actions.client.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 <hcloud.servers.client.BoundServer>` or :class:`Server <hcloud.servers.domain.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 <hcloud.actions.client.BoundAction>`], :class:`Meta <hcloud.core.domain.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 <hcloud.servers.client.BoundServer>` or :class:`Server <hcloud.servers.domain.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 <hcloud.actions.client.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,
|
||||
|
|
|
|||
|
|
@ -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 <hcloud.server_types.client.BoundServerType>`
|
||||
:param datacenter: :class:`BoundDatacenter <hcloud.datacenters.client.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 <hcloud.locations.client.BoundLocation>`
|
||||
:param image: :class:`BoundImage <hcloud.images.client.BoundImage>`, None
|
||||
:param iso: :class:`BoundIso <hcloud.isos.client.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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
]
|
||||
|
|
|
|||
127
plugins/module_utils/vendor/hcloud/volumes/client.py
vendored
127
plugins/module_utils/vendor/hcloud/volumes/client.py
vendored
|
|
@ -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 <hcloud.actions.client.BoundAction>`], :class:`Meta <hcloud.core.domain.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 <hcloud.actions.client.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 <hcloud.volumes.client.BoundVolume>` or :class:`Volume <hcloud.volumes.domain.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 <hcloud.actions.client.BoundAction>`], :class:`Meta <hcloud.core.domain.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 <hcloud.volumes.client.BoundVolume>` or :class:`Volume <hcloud.volumes.domain.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 <hcloud.actions.client.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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
]
|
||||
|
|
|
|||
115
plugins/module_utils/vendor/hcloud/zones/client.py
vendored
115
plugins/module_utils/vendor/hcloud/zones/client.py
vendored
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue