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 __future__ import annotations
|
||||||
|
|
||||||
from ._client import ( # noqa pylint: disable=C0414
|
from ._client import (
|
||||||
Client as Client,
|
Client,
|
||||||
constant_backoff_function as constant_backoff_function,
|
constant_backoff_function,
|
||||||
exponential_backoff_function as exponential_backoff_function,
|
exponential_backoff_function,
|
||||||
)
|
)
|
||||||
from ._exceptions import ( # noqa pylint: disable=C0414
|
from ._exceptions import APIException, HCloudException
|
||||||
APIException as APIException,
|
from ._version import __version__
|
||||||
HCloudException as HCloudException,
|
|
||||||
)
|
__all__ = [
|
||||||
from ._version import __version__ # noqa
|
"__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
|
import time
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
from random import uniform
|
from random import uniform
|
||||||
from typing import Protocol
|
from typing import Any, Protocol
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import requests
|
import requests
|
||||||
|
|
@ -75,7 +75,7 @@ def exponential_backoff_function(
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def func(retries: int) -> float:
|
def func(retries: int) -> float:
|
||||||
interval = base * multiplier**retries # Exponential backoff
|
interval: float = base * multiplier**retries # Exponential backoff
|
||||||
interval = min(cap, interval) # Cap backoff
|
interval = min(cap, interval) # Cap backoff
|
||||||
if jitter:
|
if jitter:
|
||||||
interval = uniform(base, interval) # Add jitter
|
interval = uniform(base, interval) # Add jitter
|
||||||
|
|
@ -295,7 +295,7 @@ class Client:
|
||||||
method: str,
|
method: str,
|
||||||
url: str,
|
url: str,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
) -> dict:
|
) -> dict[str, Any]:
|
||||||
"""Perform a request to the Hetzner Cloud API.
|
"""Perform a request to the Hetzner Cloud API.
|
||||||
|
|
||||||
:param method: Method to perform the request.
|
:param method: Method to perform the request.
|
||||||
|
|
@ -348,7 +348,7 @@ class ClientBase:
|
||||||
method: str,
|
method: str,
|
||||||
url: str,
|
url: str,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
) -> dict:
|
) -> dict[str, Any]:
|
||||||
"""Perform a request to the provided URL.
|
"""Perform a request to the provided URL.
|
||||||
|
|
||||||
:param method: Method to perform the request.
|
:param method: Method to perform the request.
|
||||||
|
|
@ -384,7 +384,7 @@ class ClientBase:
|
||||||
continue
|
continue
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def _read_response(self, response) -> dict:
|
def _read_response(self, response) -> dict[str, Any]:
|
||||||
correlation_id = response.headers.get("X-Correlation-Id")
|
correlation_id = response.headers.get("X-Correlation-Id")
|
||||||
payload = {}
|
payload = {}
|
||||||
try:
|
try:
|
||||||
|
|
@ -407,7 +407,7 @@ class ClientBase:
|
||||||
correlation_id=correlation_id,
|
correlation_id=correlation_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
error: dict = payload["error"]
|
error: dict[str, Any] = payload["error"]
|
||||||
raise APIException(
|
raise APIException(
|
||||||
code=error["code"],
|
code=error["code"],
|
||||||
message=error["message"],
|
message=error["message"],
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
from __future__ import annotations
|
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 (
|
from .client import (
|
||||||
ActionsClient,
|
ActionsClient,
|
||||||
|
ActionSort,
|
||||||
ActionsPageResult,
|
ActionsPageResult,
|
||||||
BoundAction,
|
BoundAction,
|
||||||
ResourceActionsClient,
|
ResourceActionsClient,
|
||||||
)
|
)
|
||||||
from .domain import (
|
from .domain import (
|
||||||
Action,
|
Action,
|
||||||
|
ActionError,
|
||||||
ActionException,
|
ActionException,
|
||||||
ActionFailedException,
|
ActionFailedException,
|
||||||
|
ActionResource,
|
||||||
|
ActionStatus,
|
||||||
ActionTimeoutException,
|
ActionTimeoutException,
|
||||||
)
|
)
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"Action",
|
|
||||||
"ActionException",
|
|
||||||
"ActionFailedException",
|
|
||||||
"ActionTimeoutException",
|
|
||||||
"ActionsClient",
|
"ActionsClient",
|
||||||
"ActionsPageResult",
|
"ActionsPageResult",
|
||||||
"BoundAction",
|
"BoundAction",
|
||||||
"ResourceActionsClient",
|
"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 time
|
||||||
import warnings
|
import warnings
|
||||||
from typing import TYPE_CHECKING, Any, NamedTuple
|
from typing import TYPE_CHECKING, Any, Literal, NamedTuple
|
||||||
|
|
||||||
from ..core import BoundModelBase, Meta, ResourceClientBase
|
from ..core import BoundModelBase, Meta, ResourceClientBase
|
||||||
from .domain import Action, ActionFailedException, ActionTimeoutException
|
from .domain import Action, ActionFailedException, ActionStatus, ActionTimeoutException
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .._client import Client
|
from .._client import Client
|
||||||
|
|
||||||
|
|
||||||
class BoundAction(BoundModelBase, Action):
|
__all__ = [
|
||||||
|
"ActionsClient",
|
||||||
|
"ActionsPageResult",
|
||||||
|
"BoundAction",
|
||||||
|
"ResourceActionsClient",
|
||||||
|
"ActionSort",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class BoundAction(BoundModelBase[Action], Action):
|
||||||
_client: ActionsClient
|
_client: ActionsClient
|
||||||
|
|
||||||
model = Action
|
model = Action
|
||||||
|
|
@ -45,12 +54,78 @@ class BoundAction(BoundModelBase, Action):
|
||||||
raise ActionFailedException(action=self)
|
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):
|
class ActionsPageResult(NamedTuple):
|
||||||
actions: list[BoundAction]
|
actions: list[BoundAction]
|
||||||
meta: Meta
|
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
|
_resource: str
|
||||||
|
|
||||||
def __init__(self, client: ResourceClientBase | Client, resource: str | None):
|
def __init__(self, client: ResourceClientBase | Client, resource: str | None):
|
||||||
|
|
@ -66,69 +141,46 @@ class ResourceActionsClient(ResourceClientBase):
|
||||||
self._resource = resource or ""
|
self._resource = resource or ""
|
||||||
|
|
||||||
def get_by_id(self, id: int) -> BoundAction:
|
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(
|
Returns a specific Action by its ID.
|
||||||
url=f"{self._resource}/actions/{id}",
|
|
||||||
method="GET",
|
:param id: ID of the Action.
|
||||||
)
|
"""
|
||||||
return BoundAction(self._parent.actions, response["action"])
|
return self._get_action_by_id(self._resource, id)
|
||||||
|
|
||||||
def get_list(
|
def get_list(
|
||||||
self,
|
self,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
page: int | None = None,
|
page: int | None = None,
|
||||||
per_page: int | None = None,
|
per_page: int | None = None,
|
||||||
) -> ActionsPageResult:
|
) -> 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] = {}
|
Returns a paginated list of Actions.
|
||||||
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(
|
:param status: Filter the Actions by status.
|
||||||
url=f"{self._resource}/actions",
|
:param sort: Sort Actions by field and direction.
|
||||||
method="GET",
|
:param page: Page number to get.
|
||||||
params=params,
|
: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(
|
def get_all(
|
||||||
self,
|
self,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
) -> list[BoundAction]:
|
) -> list[BoundAction]:
|
||||||
"""Get all actions.
|
"""
|
||||||
|
Returns all Actions.
|
||||||
|
|
||||||
:param status: List[str] (optional)
|
:param status: Filter the Actions by status.
|
||||||
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
:param sort: Sort Actions by field and direction.
|
||||||
: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>`]
|
|
||||||
"""
|
"""
|
||||||
return self._iter_pages(self.get_list, status=status, sort=sort)
|
return self._iter_pages(self.get_list, status=status, sort=sort)
|
||||||
|
|
||||||
|
|
@ -139,8 +191,8 @@ class ActionsClient(ResourceActionsClient):
|
||||||
|
|
||||||
def get_list(
|
def get_list(
|
||||||
self,
|
self,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
page: int | None = None,
|
page: int | None = None,
|
||||||
per_page: int | None = None,
|
per_page: int | None = None,
|
||||||
) -> ActionsPageResult:
|
) -> ActionsPageResult:
|
||||||
|
|
@ -162,8 +214,8 @@ class ActionsClient(ResourceActionsClient):
|
||||||
|
|
||||||
def get_all(
|
def get_all(
|
||||||
self,
|
self,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
) -> list[BoundAction]:
|
) -> list[BoundAction]:
|
||||||
"""
|
"""
|
||||||
.. deprecated:: 1.28
|
.. deprecated:: 1.28
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,6 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING, Any, Literal, TypedDict
|
||||||
|
|
||||||
try:
|
|
||||||
from dateutil.parser import isoparse
|
|
||||||
except ImportError:
|
|
||||||
isoparse = None
|
|
||||||
|
|
||||||
from .._exceptions import HCloudException
|
from .._exceptions import HCloudException
|
||||||
from ..core import BaseDomain
|
from ..core import BaseDomain
|
||||||
|
|
@ -13,6 +8,22 @@ from ..core import BaseDomain
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .client import BoundAction
|
from .client import BoundAction
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"ActionStatus",
|
||||||
|
"Action",
|
||||||
|
"ActionResource",
|
||||||
|
"ActionError",
|
||||||
|
"ActionException",
|
||||||
|
"ActionFailedException",
|
||||||
|
"ActionTimeoutException",
|
||||||
|
]
|
||||||
|
|
||||||
|
ActionStatus = Literal[
|
||||||
|
"running",
|
||||||
|
"success",
|
||||||
|
"error",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class Action(BaseDomain):
|
class Action(BaseDomain):
|
||||||
"""Action Domain
|
"""Action Domain
|
||||||
|
|
@ -50,24 +61,35 @@ class Action(BaseDomain):
|
||||||
self,
|
self,
|
||||||
id: int,
|
id: int,
|
||||||
command: str | None = None,
|
command: str | None = None,
|
||||||
status: str | None = None,
|
status: ActionStatus | None = None,
|
||||||
progress: int | None = None,
|
progress: int | None = None,
|
||||||
started: str | None = None,
|
started: str | None = None,
|
||||||
finished: str | None = None,
|
finished: str | None = None,
|
||||||
resources: list[dict] | None = None,
|
resources: list[ActionResource] | None = None,
|
||||||
error: dict | None = None,
|
error: ActionError | None = None,
|
||||||
):
|
):
|
||||||
self.id = id
|
self.id = id
|
||||||
self.command = command
|
self.command = command
|
||||||
|
|
||||||
self.status = status
|
self.status = status
|
||||||
self.progress = progress
|
self.progress = progress
|
||||||
self.started = isoparse(started) if started else None
|
self.started = self._parse_datetime(started)
|
||||||
self.finished = isoparse(finished) if finished else None
|
self.finished = self._parse_datetime(finished)
|
||||||
self.resources = resources
|
self.resources = resources
|
||||||
self.error = error
|
self.error = error
|
||||||
|
|
||||||
|
|
||||||
|
class ActionResource(TypedDict):
|
||||||
|
id: int
|
||||||
|
type: str
|
||||||
|
|
||||||
|
|
||||||
|
class ActionError(TypedDict):
|
||||||
|
code: str
|
||||||
|
message: str
|
||||||
|
details: dict[str, Any]
|
||||||
|
|
||||||
|
|
||||||
class ActionException(HCloudException):
|
class ActionException(HCloudException):
|
||||||
"""A generic action exception"""
|
"""A generic action exception"""
|
||||||
|
|
||||||
|
|
@ -85,7 +107,8 @@ class ActionException(HCloudException):
|
||||||
|
|
||||||
extras.append(action.error["code"])
|
extras.append(action.error["code"])
|
||||||
else:
|
else:
|
||||||
extras.append(action.command)
|
if action.command is not None:
|
||||||
|
extras.append(action.command)
|
||||||
|
|
||||||
extras.append(str(action.id))
|
extras.append(str(action.id))
|
||||||
message += f" ({', '.join(extras)})"
|
message += f" ({', '.join(extras)})"
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,14 @@ from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, Any, NamedTuple
|
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 ..core import BoundModelBase, Meta, ResourceClientBase
|
||||||
from .domain import (
|
from .domain import (
|
||||||
Certificate,
|
Certificate,
|
||||||
|
|
@ -15,12 +22,24 @@ if TYPE_CHECKING:
|
||||||
from .._client import Client
|
from .._client import Client
|
||||||
|
|
||||||
|
|
||||||
class BoundCertificate(BoundModelBase, Certificate):
|
__all__ = [
|
||||||
|
"BoundCertificate",
|
||||||
|
"CertificatesPageResult",
|
||||||
|
"CertificatesClient",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class BoundCertificate(BoundModelBase[Certificate], Certificate):
|
||||||
_client: CertificatesClient
|
_client: CertificatesClient
|
||||||
|
|
||||||
model = Certificate
|
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")
|
status = data.get("status")
|
||||||
if status is not None:
|
if status is not None:
|
||||||
error_data = status.get("error")
|
error_data = status.get("error")
|
||||||
|
|
@ -36,22 +55,18 @@ class BoundCertificate(BoundModelBase, Certificate):
|
||||||
|
|
||||||
def get_actions_list(
|
def get_actions_list(
|
||||||
self,
|
self,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
page: int | None = None,
|
page: int | None = None,
|
||||||
per_page: int | None = None,
|
per_page: int | None = None,
|
||||||
) -> ActionsPageResult:
|
) -> ActionsPageResult:
|
||||||
"""Returns all action objects for a Certificate.
|
"""
|
||||||
|
Returns a paginated list of Actions for a Certificate.
|
||||||
|
|
||||||
:param status: List[str] (optional)
|
:param status: Filter the Actions by status.
|
||||||
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
:param sort: Sort Actions by field and direction.
|
||||||
:param sort: List[str] (optional)
|
:param page: Page number to get.
|
||||||
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 per_page: Maximum number of Actions returned per page.
|
||||||
: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>`)
|
|
||||||
"""
|
"""
|
||||||
return self._client.get_actions_list(
|
return self._client.get_actions_list(
|
||||||
self,
|
self,
|
||||||
|
|
@ -63,16 +78,14 @@ class BoundCertificate(BoundModelBase, Certificate):
|
||||||
|
|
||||||
def get_actions(
|
def get_actions(
|
||||||
self,
|
self,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
) -> list[BoundAction]:
|
) -> list[BoundAction]:
|
||||||
"""Returns all action objects for a Certificate.
|
"""
|
||||||
|
Returns all Actions for a Certificate.
|
||||||
|
|
||||||
:param status: List[str] (optional)
|
:param status: Filter the Actions by status.
|
||||||
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
:param sort: Sort Actions by field and direction.
|
||||||
: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>`]
|
|
||||||
"""
|
"""
|
||||||
return self._client.get_actions(
|
return self._client.get_actions(
|
||||||
self,
|
self,
|
||||||
|
|
@ -117,7 +130,10 @@ class CertificatesPageResult(NamedTuple):
|
||||||
meta: Meta
|
meta: Meta
|
||||||
|
|
||||||
|
|
||||||
class CertificatesClient(ResourceClientBase):
|
class CertificatesClient(
|
||||||
|
ResourceClientBaseActionsMixin,
|
||||||
|
ResourceClientBase,
|
||||||
|
):
|
||||||
_base_url = "/certificates"
|
_base_url = "/certificates"
|
||||||
|
|
||||||
actions: ResourceActionsClient
|
actions: ResourceActionsClient
|
||||||
|
|
@ -306,59 +322,40 @@ class CertificatesClient(ResourceClientBase):
|
||||||
def get_actions_list(
|
def get_actions_list(
|
||||||
self,
|
self,
|
||||||
certificate: Certificate | BoundCertificate,
|
certificate: Certificate | BoundCertificate,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
page: int | None = None,
|
page: int | None = None,
|
||||||
per_page: int | None = None,
|
per_page: int | None = None,
|
||||||
) -> ActionsPageResult:
|
) -> 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] = {}
|
Returns a paginated list of Actions for a Certificate.
|
||||||
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(
|
:param certificate: Certificate to get the Actions for.
|
||||||
url=f"{self._base_url}/{certificate.id}/actions",
|
:param status: Filter the Actions by status.
|
||||||
method="GET",
|
:param sort: Sort Actions by field and direction.
|
||||||
params=params,
|
: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(
|
def get_actions(
|
||||||
self,
|
self,
|
||||||
certificate: Certificate | BoundCertificate,
|
certificate: Certificate | BoundCertificate,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
) -> list[BoundAction]:
|
) -> 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 certificate: Certificate to get the Actions for.
|
||||||
:param status: List[str] (optional)
|
:param status: Filter the Actions by status.
|
||||||
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
:param sort: Sort Actions by field and direction.
|
||||||
: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>`]
|
|
||||||
"""
|
"""
|
||||||
return self._iter_pages(
|
return self._iter_pages(
|
||||||
self.get_actions_list,
|
self.get_actions_list,
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
try:
|
|
||||||
from dateutil.parser import isoparse
|
|
||||||
except ImportError:
|
|
||||||
isoparse = None
|
|
||||||
|
|
||||||
from ..core import BaseDomain, DomainIdentityMixin
|
from ..core import BaseDomain, DomainIdentityMixin
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
|
@ -14,6 +9,14 @@ if TYPE_CHECKING:
|
||||||
from .client import BoundCertificate
|
from .client import BoundCertificate
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"Certificate",
|
||||||
|
"ManagedCertificateStatus",
|
||||||
|
"ManagedCertificateError",
|
||||||
|
"CreateManagedCertificateResponse",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class Certificate(BaseDomain, DomainIdentityMixin):
|
class Certificate(BaseDomain, DomainIdentityMixin):
|
||||||
"""Certificate Domain
|
"""Certificate Domain
|
||||||
|
|
||||||
|
|
@ -72,9 +75,9 @@ class Certificate(BaseDomain, DomainIdentityMixin):
|
||||||
self.certificate = certificate
|
self.certificate = certificate
|
||||||
self.domain_names = domain_names
|
self.domain_names = domain_names
|
||||||
self.fingerprint = fingerprint
|
self.fingerprint = fingerprint
|
||||||
self.not_valid_before = isoparse(not_valid_before) if not_valid_before else None
|
self.not_valid_before = self._parse_datetime(not_valid_before)
|
||||||
self.not_valid_after = isoparse(not_valid_after) if not_valid_after else None
|
self.not_valid_after = self._parse_datetime(not_valid_after)
|
||||||
self.created = isoparse(created) if created else None
|
self.created = self._parse_datetime(created)
|
||||||
self.labels = labels
|
self.labels = labels
|
||||||
self.status = status
|
self.status = status
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,22 @@ from __future__ import annotations
|
||||||
|
|
||||||
import warnings
|
import warnings
|
||||||
from collections.abc import Callable
|
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:
|
if TYPE_CHECKING:
|
||||||
from .._client import Client, ClientBase
|
from .._client import Client, ClientBase
|
||||||
from .domain import BaseDomain
|
from .domain import Meta
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"ResourceClientBase",
|
||||||
|
"ClientEntityBase",
|
||||||
|
"BoundModelBase",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
T = TypeVar("T")
|
||||||
|
|
||||||
|
|
||||||
class ResourceClientBase:
|
class ResourceClientBase:
|
||||||
|
|
@ -23,10 +34,10 @@ class ResourceClientBase:
|
||||||
|
|
||||||
def _iter_pages( # type: ignore[no-untyped-def]
|
def _iter_pages( # type: ignore[no-untyped-def]
|
||||||
self,
|
self,
|
||||||
list_function: Callable,
|
list_function: Callable[..., tuple[list[T], Meta]],
|
||||||
*args,
|
*args,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
) -> list:
|
) -> list[T]:
|
||||||
results = []
|
results = []
|
||||||
|
|
||||||
page = 1
|
page = 1
|
||||||
|
|
@ -46,7 +57,12 @@ class ResourceClientBase:
|
||||||
|
|
||||||
return results
|
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)
|
entities, _ = list_function(*args, **kwargs)
|
||||||
return entities[0] if entities else None
|
return entities[0] if entities else None
|
||||||
|
|
||||||
|
|
@ -69,15 +85,18 @@ class ClientEntityBase(ResourceClientBase):
|
||||||
super().__init__(client)
|
super().__init__(client)
|
||||||
|
|
||||||
|
|
||||||
class BoundModelBase:
|
Domain = TypeVar("Domain", bound=BaseDomain)
|
||||||
|
|
||||||
|
|
||||||
|
class BoundModelBase(Generic[Domain]):
|
||||||
"""Bound Model Base"""
|
"""Bound Model Base"""
|
||||||
|
|
||||||
model: type[BaseDomain]
|
model: type[Domain]
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
client: ResourceClientBase,
|
client: ResourceClientBase,
|
||||||
data: dict,
|
data: dict[str, Any],
|
||||||
complete: bool = True,
|
complete: bool = True,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
|
|
@ -90,7 +109,7 @@ class BoundModelBase:
|
||||||
"""
|
"""
|
||||||
self._client = client
|
self._client = client
|
||||||
self.complete = complete
|
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]
|
def __getattr__(self, name: str): # type: ignore[no-untyped-def]
|
||||||
"""Allow magical access to the properties of the model
|
"""Allow magical access to the properties of the model
|
||||||
|
|
@ -103,9 +122,10 @@ class BoundModelBase:
|
||||||
value = getattr(self.data_model, name)
|
value = getattr(self.data_model, name)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def _get_self(self) -> BoundModelBase:
|
def _get_self(self) -> BoundModelBase[Domain]:
|
||||||
assert hasattr(self._client, "get_by_id")
|
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:
|
def reload(self) -> None:
|
||||||
"""Reloads the model and tries to get all data from the API"""
|
"""Reloads the model and tries to get all data from the API"""
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,26 @@
|
||||||
from __future__ import annotations
|
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:
|
class BaseDomain:
|
||||||
__api_properties__: tuple
|
__api_properties__: tuple[str, ...]
|
||||||
|
|
||||||
@classmethod
|
@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.
|
Build the domain object from the data dict.
|
||||||
"""
|
"""
|
||||||
|
|
@ -15,7 +28,7 @@ class BaseDomain:
|
||||||
return cls(**supported_data)
|
return cls(**supported_data)
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
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)})"
|
return f"{self.__class__.__qualname__}({', '.join(kwargs)})"
|
||||||
|
|
||||||
def __eq__(self, other: Any) -> bool:
|
def __eq__(self, other: Any) -> bool:
|
||||||
|
|
@ -27,6 +40,16 @@ class BaseDomain:
|
||||||
return False
|
return False
|
||||||
return True
|
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:
|
class DomainIdentityMixin:
|
||||||
|
|
||||||
|
|
@ -106,7 +129,7 @@ class Meta(BaseDomain):
|
||||||
self.pagination = pagination
|
self.pagination = pagination
|
||||||
|
|
||||||
@classmethod
|
@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.
|
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 ..server_types import BoundServerType
|
||||||
from .domain import Datacenter, DatacenterServerTypes
|
from .domain import Datacenter, DatacenterServerTypes
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"BoundDatacenter",
|
||||||
|
"DatacentersPageResult",
|
||||||
|
"DatacentersClient",
|
||||||
|
]
|
||||||
|
|
||||||
class BoundDatacenter(BoundModelBase, Datacenter):
|
|
||||||
|
class BoundDatacenter(BoundModelBase[Datacenter], Datacenter):
|
||||||
_client: DatacentersClient
|
_client: DatacentersClient
|
||||||
|
|
||||||
model = Datacenter
|
model = Datacenter
|
||||||
|
|
||||||
def __init__(self, client: DatacentersClient, data: dict):
|
def __init__(self, client: DatacentersClient, data: dict[str, Any]):
|
||||||
location = data.get("location")
|
location = data.get("location")
|
||||||
if location is not None:
|
if location is not None:
|
||||||
data["location"] = BoundLocation(client._parent.locations, location)
|
data["location"] = BoundLocation(client._parent.locations, location)
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,11 @@ if TYPE_CHECKING:
|
||||||
from ..locations import Location
|
from ..locations import Location
|
||||||
from ..server_types import BoundServerType
|
from ..server_types import BoundServerType
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"Datacenter",
|
||||||
|
"DatacenterServerTypes",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class Datacenter(BaseDomain, DomainIdentityMixin):
|
class Datacenter(BaseDomain, DomainIdentityMixin):
|
||||||
"""Datacenter Domain
|
"""Datacenter Domain
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
from .domain import DeprecationInfo
|
from .domain import DeprecationInfo
|
||||||
|
|
||||||
__all__ = ["DeprecationInfo"]
|
__all__ = [
|
||||||
|
"DeprecationInfo",
|
||||||
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
try:
|
|
||||||
from dateutil.parser import isoparse
|
|
||||||
except ImportError:
|
|
||||||
isoparse = None
|
|
||||||
|
|
||||||
from ..core import BaseDomain
|
from ..core import BaseDomain
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"DeprecationInfo",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class DeprecationInfo(BaseDomain):
|
class DeprecationInfo(BaseDomain):
|
||||||
"""Describes if, when & how the resources was deprecated. If this field is set to ``None`` the resource is not
|
"""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,
|
announced: str | None = None,
|
||||||
unavailable_after: str | None = None,
|
unavailable_after: str | None = None,
|
||||||
):
|
):
|
||||||
self.announced = isoparse(announced) if announced else None
|
self.announced = self._parse_datetime(announced)
|
||||||
self.unavailable_after = (
|
self.unavailable_after = self._parse_datetime(unavailable_after)
|
||||||
isoparse(unavailable_after) if unavailable_after else None
|
|
||||||
)
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,11 @@ library, breaking changes may occur within minor releases.
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"is_txt_record_quoted",
|
||||||
|
"format_txt_record",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def is_txt_record_quoted(value: str) -> bool:
|
def is_txt_record_quoted(value: str) -> bool:
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,14 @@ from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, Any, NamedTuple
|
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 ..core import BoundModelBase, Meta, ResourceClientBase
|
||||||
from .domain import (
|
from .domain import (
|
||||||
CreateFirewallResponse,
|
CreateFirewallResponse,
|
||||||
|
|
@ -17,12 +24,24 @@ if TYPE_CHECKING:
|
||||||
from .._client import Client
|
from .._client import Client
|
||||||
|
|
||||||
|
|
||||||
class BoundFirewall(BoundModelBase, Firewall):
|
__all__ = [
|
||||||
|
"BoundFirewall",
|
||||||
|
"FirewallsPageResult",
|
||||||
|
"FirewallsClient",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class BoundFirewall(BoundModelBase[Firewall], Firewall):
|
||||||
_client: FirewallsClient
|
_client: FirewallsClient
|
||||||
|
|
||||||
model = Firewall
|
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", [])
|
rules = data.get("rules", [])
|
||||||
if rules:
|
if rules:
|
||||||
rules = [
|
rules = [
|
||||||
|
|
@ -92,22 +111,18 @@ class BoundFirewall(BoundModelBase, Firewall):
|
||||||
|
|
||||||
def get_actions_list(
|
def get_actions_list(
|
||||||
self,
|
self,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
page: int | None = None,
|
page: int | None = None,
|
||||||
per_page: int | None = None,
|
per_page: int | None = None,
|
||||||
) -> ActionsPageResult:
|
) -> ActionsPageResult:
|
||||||
"""Returns all action objects for a Firewall.
|
"""
|
||||||
|
Returns a paginated list of Actions for a Firewall.
|
||||||
|
|
||||||
:param status: List[str] (optional)
|
:param status: Filter the Actions by status.
|
||||||
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
:param sort: Sort Actions by field and direction.
|
||||||
:param sort: List[str] (optional)
|
:param page: Page number to get.
|
||||||
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 per_page: Maximum number of Actions returned per page.
|
||||||
: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>`)
|
|
||||||
"""
|
"""
|
||||||
return self._client.get_actions_list(
|
return self._client.get_actions_list(
|
||||||
self,
|
self,
|
||||||
|
|
@ -119,17 +134,14 @@ class BoundFirewall(BoundModelBase, Firewall):
|
||||||
|
|
||||||
def get_actions(
|
def get_actions(
|
||||||
self,
|
self,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
) -> list[BoundAction]:
|
) -> list[BoundAction]:
|
||||||
"""Returns all action objects for a Firewall.
|
"""
|
||||||
|
Returns all Actions for a Firewall.
|
||||||
|
|
||||||
:param status: List[str] (optional)
|
:param status: Filter the Actions by status.
|
||||||
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
:param sort: Sort Actions by field and direction.
|
||||||
: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>`]
|
|
||||||
"""
|
"""
|
||||||
return self._client.get_actions(
|
return self._client.get_actions(
|
||||||
self,
|
self,
|
||||||
|
|
@ -193,7 +205,10 @@ class FirewallsPageResult(NamedTuple):
|
||||||
meta: Meta
|
meta: Meta
|
||||||
|
|
||||||
|
|
||||||
class FirewallsClient(ResourceClientBase):
|
class FirewallsClient(
|
||||||
|
ResourceClientBaseActionsMixin,
|
||||||
|
ResourceClientBase,
|
||||||
|
):
|
||||||
_base_url = "/firewalls"
|
_base_url = "/firewalls"
|
||||||
|
|
||||||
actions: ResourceActionsClient
|
actions: ResourceActionsClient
|
||||||
|
|
@ -209,59 +224,40 @@ class FirewallsClient(ResourceClientBase):
|
||||||
def get_actions_list(
|
def get_actions_list(
|
||||||
self,
|
self,
|
||||||
firewall: Firewall | BoundFirewall,
|
firewall: Firewall | BoundFirewall,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
page: int | None = None,
|
page: int | None = None,
|
||||||
per_page: int | None = None,
|
per_page: int | None = None,
|
||||||
) -> ActionsPageResult:
|
) -> 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] = {}
|
Returns a paginated list of Actions for a Firewall.
|
||||||
if status is not None:
|
|
||||||
params["status"] = status
|
:param firewall: Firewall to get the Actions for.
|
||||||
if sort is not None:
|
:param status: Filter the Actions by status.
|
||||||
params["sort"] = sort
|
:param sort: Sort Actions by field and direction.
|
||||||
if page is not None:
|
:param page: Page number to get.
|
||||||
params["page"] = page
|
:param per_page: Maximum number of Actions returned per page.
|
||||||
if per_page is not None:
|
"""
|
||||||
params["per_page"] = per_page
|
return self._get_actions_list(
|
||||||
response = self._client.request(
|
f"{self._base_url}/{firewall.id}",
|
||||||
url=f"{self._base_url}/{firewall.id}/actions",
|
status=status,
|
||||||
method="GET",
|
sort=sort,
|
||||||
params=params,
|
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(
|
def get_actions(
|
||||||
self,
|
self,
|
||||||
firewall: Firewall | BoundFirewall,
|
firewall: Firewall | BoundFirewall,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
) -> list[BoundAction]:
|
) -> 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 firewall: Firewall to get the Actions for.
|
||||||
:param status: List[str] (optional)
|
:param status: Filter the Actions by status.
|
||||||
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
:param sort: Sort Actions by field and direction.
|
||||||
: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>`]
|
|
||||||
"""
|
"""
|
||||||
return self._iter_pages(
|
return self._iter_pages(
|
||||||
self.get_actions_list,
|
self.get_actions_list,
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, Any
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
try:
|
|
||||||
from dateutil.parser import isoparse
|
|
||||||
except ImportError:
|
|
||||||
isoparse = None
|
|
||||||
|
|
||||||
from ..core import BaseDomain, DomainIdentityMixin
|
from ..core import BaseDomain, DomainIdentityMixin
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
|
@ -15,6 +10,16 @@ if TYPE_CHECKING:
|
||||||
from .client import BoundFirewall
|
from .client import BoundFirewall
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"Firewall",
|
||||||
|
"FirewallRule",
|
||||||
|
"FirewallResource",
|
||||||
|
"FirewallResourceAppliedToResources",
|
||||||
|
"FirewallResourceLabelSelector",
|
||||||
|
"CreateFirewallResponse",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class Firewall(BaseDomain, DomainIdentityMixin):
|
class Firewall(BaseDomain, DomainIdentityMixin):
|
||||||
"""Firewall Domain
|
"""Firewall Domain
|
||||||
|
|
||||||
|
|
@ -49,7 +54,7 @@ class Firewall(BaseDomain, DomainIdentityMixin):
|
||||||
self.rules = rules
|
self.rules = rules
|
||||||
self.applied_to = applied_to
|
self.applied_to = applied_to
|
||||||
self.labels = labels
|
self.labels = labels
|
||||||
self.created = isoparse(created) if created else None
|
self.created = self._parse_datetime(created)
|
||||||
|
|
||||||
|
|
||||||
class FirewallRule(BaseDomain):
|
class FirewallRule(BaseDomain):
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,13 @@ from .client import (
|
||||||
FloatingIPsClient,
|
FloatingIPsClient,
|
||||||
FloatingIPsPageResult,
|
FloatingIPsPageResult,
|
||||||
)
|
)
|
||||||
from .domain import CreateFloatingIPResponse, FloatingIP
|
from .domain import CreateFloatingIPResponse, FloatingIP, FloatingIPProtection
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"BoundFloatingIP",
|
"BoundFloatingIP",
|
||||||
"CreateFloatingIPResponse",
|
"CreateFloatingIPResponse",
|
||||||
"FloatingIP",
|
"FloatingIP",
|
||||||
|
"FloatingIPProtection",
|
||||||
"FloatingIPsClient",
|
"FloatingIPsClient",
|
||||||
"FloatingIPsPageResult",
|
"FloatingIPsPageResult",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,14 @@ from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, Any, NamedTuple
|
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 ..core import BoundModelBase, Meta, ResourceClientBase
|
||||||
from ..locations import BoundLocation
|
from ..locations import BoundLocation
|
||||||
from .domain import CreateFloatingIPResponse, FloatingIP
|
from .domain import CreateFloatingIPResponse, FloatingIP
|
||||||
|
|
@ -12,13 +19,24 @@ if TYPE_CHECKING:
|
||||||
from ..locations import Location
|
from ..locations import Location
|
||||||
from ..servers import BoundServer, Server
|
from ..servers import BoundServer, Server
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"BoundFloatingIP",
|
||||||
|
"FloatingIPsPageResult",
|
||||||
|
"FloatingIPsClient",
|
||||||
|
]
|
||||||
|
|
||||||
class BoundFloatingIP(BoundModelBase, FloatingIP):
|
|
||||||
|
class BoundFloatingIP(BoundModelBase[FloatingIP], FloatingIP):
|
||||||
_client: FloatingIPsClient
|
_client: FloatingIPsClient
|
||||||
|
|
||||||
model = FloatingIP
|
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
|
# pylint: disable=import-outside-toplevel
|
||||||
from ..servers import BoundServer
|
from ..servers import BoundServer
|
||||||
|
|
||||||
|
|
@ -38,22 +56,18 @@ class BoundFloatingIP(BoundModelBase, FloatingIP):
|
||||||
|
|
||||||
def get_actions_list(
|
def get_actions_list(
|
||||||
self,
|
self,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
page: int | None = None,
|
page: int | None = None,
|
||||||
per_page: int | None = None,
|
per_page: int | None = None,
|
||||||
) -> ActionsPageResult:
|
) -> ActionsPageResult:
|
||||||
"""Returns all action objects for a Floating IP.
|
"""
|
||||||
|
Returns a paginated list of Actions for a Floating IP.
|
||||||
|
|
||||||
:param status: List[str] (optional)
|
:param status: Filter the Actions by status.
|
||||||
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
:param sort: Sort Actions by field and direction.
|
||||||
:param sort: List[str] (optional)
|
:param page: Page number to get.
|
||||||
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 per_page: Maximum number of Actions returned per page.
|
||||||
: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>`)
|
|
||||||
"""
|
"""
|
||||||
return self._client.get_actions_list(
|
return self._client.get_actions_list(
|
||||||
self,
|
self,
|
||||||
|
|
@ -65,16 +79,14 @@ class BoundFloatingIP(BoundModelBase, FloatingIP):
|
||||||
|
|
||||||
def get_actions(
|
def get_actions(
|
||||||
self,
|
self,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
) -> list[BoundAction]:
|
) -> list[BoundAction]:
|
||||||
"""Returns all action objects for a Floating IP.
|
"""
|
||||||
|
Returns all Actions for a Floating IP.
|
||||||
|
|
||||||
:param status: List[str] (optional)
|
:param status: Filter the Actions by status.
|
||||||
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
:param sort: Sort Actions by field and direction.
|
||||||
: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>`]
|
|
||||||
"""
|
"""
|
||||||
return self._client.get_actions(self, status=status, sort=sort)
|
return self._client.get_actions(self, status=status, sort=sort)
|
||||||
|
|
||||||
|
|
@ -147,7 +159,10 @@ class FloatingIPsPageResult(NamedTuple):
|
||||||
meta: Meta
|
meta: Meta
|
||||||
|
|
||||||
|
|
||||||
class FloatingIPsClient(ResourceClientBase):
|
class FloatingIPsClient(
|
||||||
|
ResourceClientBaseActionsMixin,
|
||||||
|
ResourceClientBase,
|
||||||
|
):
|
||||||
_base_url = "/floating_ips"
|
_base_url = "/floating_ips"
|
||||||
|
|
||||||
actions: ResourceActionsClient
|
actions: ResourceActionsClient
|
||||||
|
|
@ -163,59 +178,40 @@ class FloatingIPsClient(ResourceClientBase):
|
||||||
def get_actions_list(
|
def get_actions_list(
|
||||||
self,
|
self,
|
||||||
floating_ip: FloatingIP | BoundFloatingIP,
|
floating_ip: FloatingIP | BoundFloatingIP,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
page: int | None = None,
|
page: int | None = None,
|
||||||
per_page: int | None = None,
|
per_page: int | None = None,
|
||||||
) -> ActionsPageResult:
|
) -> 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] = {}
|
Returns a paginated list of Actions for a Floating IP.
|
||||||
if status is not None:
|
|
||||||
params["status"] = status
|
:param floating_ip: Floating IP to get the Actions for.
|
||||||
if sort is not None:
|
:param status: Filter the Actions by status.
|
||||||
params["sort"] = sort
|
:param sort: Sort Actions by field and direction.
|
||||||
if page is not None:
|
:param page: Page number to get.
|
||||||
params["page"] = page
|
:param per_page: Maximum number of Actions returned per page.
|
||||||
if per_page is not None:
|
"""
|
||||||
params["per_page"] = per_page
|
return self._get_actions_list(
|
||||||
response = self._client.request(
|
f"{self._base_url}/{floating_ip.id}",
|
||||||
url=f"{self._base_url}/{floating_ip.id}/actions",
|
status=status,
|
||||||
method="GET",
|
sort=sort,
|
||||||
params=params,
|
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(
|
def get_actions(
|
||||||
self,
|
self,
|
||||||
floating_ip: FloatingIP | BoundFloatingIP,
|
floating_ip: FloatingIP | BoundFloatingIP,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
) -> list[BoundAction]:
|
) -> 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 floating_ip: Floating IP to get the Actions for.
|
||||||
:param status: List[str] (optional)
|
:param status: Filter the Actions by status.
|
||||||
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
:param sort: Sort Actions by field and direction.
|
||||||
: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>`]
|
|
||||||
"""
|
"""
|
||||||
return self._iter_pages(
|
return self._iter_pages(
|
||||||
self.get_actions_list,
|
self.get_actions_list,
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,24 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING, TypedDict
|
||||||
|
|
||||||
try:
|
|
||||||
from dateutil.parser import isoparse
|
|
||||||
except ImportError:
|
|
||||||
isoparse = None
|
|
||||||
|
|
||||||
from ..core import BaseDomain, DomainIdentityMixin
|
from ..core import BaseDomain, DomainIdentityMixin
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from ..actions import BoundAction
|
from ..actions import BoundAction
|
||||||
from ..locations import BoundLocation
|
from ..locations import BoundLocation
|
||||||
|
from ..rdns import DNSPtr
|
||||||
from ..servers import BoundServer
|
from ..servers import BoundServer
|
||||||
from .client import BoundFloatingIP
|
from .client import BoundFloatingIP
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"FloatingIP",
|
||||||
|
"FloatingIPProtection",
|
||||||
|
"CreateFloatingIPResponse",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class FloatingIP(BaseDomain, DomainIdentityMixin):
|
class FloatingIP(BaseDomain, DomainIdentityMixin):
|
||||||
"""Floating IP Domain
|
"""Floating IP Domain
|
||||||
|
|
||||||
|
|
@ -68,10 +71,10 @@ class FloatingIP(BaseDomain, DomainIdentityMixin):
|
||||||
description: str | None = None,
|
description: str | None = None,
|
||||||
ip: str | None = None,
|
ip: str | None = None,
|
||||||
server: BoundServer | None = None,
|
server: BoundServer | None = None,
|
||||||
dns_ptr: list[dict] | None = None,
|
dns_ptr: list[DNSPtr] | None = None,
|
||||||
home_location: BoundLocation | None = None,
|
home_location: BoundLocation | None = None,
|
||||||
blocked: bool | None = None,
|
blocked: bool | None = None,
|
||||||
protection: dict | None = None,
|
protection: FloatingIPProtection | None = None,
|
||||||
labels: dict[str, str] | None = None,
|
labels: dict[str, str] | None = None,
|
||||||
created: str | None = None,
|
created: str | None = None,
|
||||||
name: str | None = None,
|
name: str | None = None,
|
||||||
|
|
@ -86,10 +89,14 @@ class FloatingIP(BaseDomain, DomainIdentityMixin):
|
||||||
self.blocked = blocked
|
self.blocked = blocked
|
||||||
self.protection = protection
|
self.protection = protection
|
||||||
self.labels = labels
|
self.labels = labels
|
||||||
self.created = isoparse(created) if created else None
|
self.created = self._parse_datetime(created)
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
|
|
||||||
|
class FloatingIPProtection(TypedDict):
|
||||||
|
delete: bool
|
||||||
|
|
||||||
|
|
||||||
class CreateFloatingIPResponse(BaseDomain):
|
class CreateFloatingIPResponse(BaseDomain):
|
||||||
"""Create Floating IP Response Domain
|
"""Create Floating IP Response Domain
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
from .labels import LabelValidator
|
from .labels import LabelValidator
|
||||||
|
|
||||||
__all__ = ["LabelValidator"]
|
__all__ = [
|
||||||
|
"LabelValidator",
|
||||||
|
]
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,10 @@ from __future__ import annotations
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"LabelValidator",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class LabelValidator:
|
class LabelValidator:
|
||||||
KEY_REGEX = re.compile(
|
KEY_REGEX = re.compile(
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from .client import BoundImage, ImagesClient, ImagesPageResult
|
from .client import BoundImage, ImagesClient, ImagesPageResult
|
||||||
from .domain import CreateImageResponse, Image
|
from .domain import CreateImageResponse, Image, ImageProtection
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"BoundImage",
|
"BoundImage",
|
||||||
"CreateImageResponse",
|
"CreateImageResponse",
|
||||||
"Image",
|
"Image",
|
||||||
|
"ImageProtection",
|
||||||
"ImagesClient",
|
"ImagesClient",
|
||||||
"ImagesPageResult",
|
"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
|
import warnings
|
||||||
from typing import TYPE_CHECKING, Any, NamedTuple
|
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 ..core import BoundModelBase, Meta, ResourceClientBase
|
||||||
from .domain import Image
|
from .domain import Image
|
||||||
|
|
||||||
|
|
@ -11,12 +18,23 @@ if TYPE_CHECKING:
|
||||||
from .._client import Client
|
from .._client import Client
|
||||||
|
|
||||||
|
|
||||||
class BoundImage(BoundModelBase, Image):
|
__all__ = [
|
||||||
|
"BoundImage",
|
||||||
|
"ImagesPageResult",
|
||||||
|
"ImagesClient",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class BoundImage(BoundModelBase[Image], Image):
|
||||||
_client: ImagesClient
|
_client: ImagesClient
|
||||||
|
|
||||||
model = Image
|
model = Image
|
||||||
|
|
||||||
def __init__(self, client: ImagesClient, data: dict):
|
def __init__(
|
||||||
|
self,
|
||||||
|
client: ImagesClient,
|
||||||
|
data: dict[str, Any],
|
||||||
|
):
|
||||||
# pylint: disable=import-outside-toplevel
|
# pylint: disable=import-outside-toplevel
|
||||||
from ..servers import BoundServer
|
from ..servers import BoundServer
|
||||||
|
|
||||||
|
|
@ -35,22 +53,18 @@ class BoundImage(BoundModelBase, Image):
|
||||||
|
|
||||||
def get_actions_list(
|
def get_actions_list(
|
||||||
self,
|
self,
|
||||||
sort: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
|
sort: list[ActionSort] | None = None,
|
||||||
page: int | None = None,
|
page: int | None = None,
|
||||||
per_page: int | None = None,
|
per_page: int | None = None,
|
||||||
status: list[str] | None = None,
|
|
||||||
) -> ActionsPageResult:
|
) -> ActionsPageResult:
|
||||||
"""Returns a list of action objects for the image.
|
"""
|
||||||
|
Returns a paginated list of Actions for a Image.
|
||||||
|
|
||||||
:param status: List[str] (optional)
|
:param status: Filter the Actions by status.
|
||||||
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
:param sort: Sort Actions by field and direction.
|
||||||
:param sort: List[str] (optional)
|
:param page: Page number to get.
|
||||||
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 per_page: Maximum number of Actions returned per page.
|
||||||
: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>`)
|
|
||||||
"""
|
"""
|
||||||
return self._client.get_actions_list(
|
return self._client.get_actions_list(
|
||||||
self,
|
self,
|
||||||
|
|
@ -62,16 +76,14 @@ class BoundImage(BoundModelBase, Image):
|
||||||
|
|
||||||
def get_actions(
|
def get_actions(
|
||||||
self,
|
self,
|
||||||
sort: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
status: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
) -> list[BoundAction]:
|
) -> list[BoundAction]:
|
||||||
"""Returns all action objects for the image.
|
"""
|
||||||
|
Returns all Actions for a Image.
|
||||||
|
|
||||||
:param status: List[str] (optional)
|
:param status: Filter the Actions by status.
|
||||||
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
:param sort: Sort Actions by field and direction.
|
||||||
: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>`]
|
|
||||||
"""
|
"""
|
||||||
return self._client.get_actions(
|
return self._client.get_actions(
|
||||||
self,
|
self,
|
||||||
|
|
@ -122,7 +134,10 @@ class ImagesPageResult(NamedTuple):
|
||||||
meta: Meta
|
meta: Meta
|
||||||
|
|
||||||
|
|
||||||
class ImagesClient(ResourceClientBase):
|
class ImagesClient(
|
||||||
|
ResourceClientBaseActionsMixin,
|
||||||
|
ResourceClientBase,
|
||||||
|
):
|
||||||
_base_url = "/images"
|
_base_url = "/images"
|
||||||
|
|
||||||
actions: ResourceActionsClient
|
actions: ResourceActionsClient
|
||||||
|
|
@ -138,64 +153,46 @@ class ImagesClient(ResourceClientBase):
|
||||||
def get_actions_list(
|
def get_actions_list(
|
||||||
self,
|
self,
|
||||||
image: Image | BoundImage,
|
image: Image | BoundImage,
|
||||||
sort: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
|
sort: list[ActionSort] | None = None,
|
||||||
page: int | None = None,
|
page: int | None = None,
|
||||||
per_page: int | None = None,
|
per_page: int | None = None,
|
||||||
status: list[str] | None = None,
|
|
||||||
) -> ActionsPageResult:
|
) -> 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] = {}
|
Returns a paginated list of Actions for a Image.
|
||||||
if sort is not None:
|
|
||||||
params["sort"] = sort
|
:param image: Image to get the Actions for.
|
||||||
if status is not None:
|
:param status: Filter the Actions by status.
|
||||||
params["status"] = status
|
:param sort: Sort Actions by field and direction.
|
||||||
if page is not None:
|
:param page: Page number to get.
|
||||||
params["page"] = page
|
:param per_page: Maximum number of Actions returned per page.
|
||||||
if per_page is not None:
|
"""
|
||||||
params["per_page"] = per_page
|
return self._get_actions_list(
|
||||||
response = self._client.request(
|
f"{self._base_url}/{image.id}",
|
||||||
url=f"{self._base_url}/{image.id}/actions",
|
status=status,
|
||||||
method="GET",
|
sort=sort,
|
||||||
params=params,
|
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(
|
def get_actions(
|
||||||
self,
|
self,
|
||||||
image: Image | BoundImage,
|
image: Image | BoundImage,
|
||||||
sort: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
status: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
) -> list[BoundAction]:
|
) -> 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 image: Image to get the Actions for.
|
||||||
:param status: List[str] (optional)
|
:param status: Filter the Actions by status.
|
||||||
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
:param sort: Sort Actions by field and direction.
|
||||||
: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>`]
|
|
||||||
"""
|
"""
|
||||||
return self._iter_pages(
|
return self._iter_pages(
|
||||||
self.get_actions_list,
|
self.get_actions_list,
|
||||||
image,
|
image,
|
||||||
sort=sort,
|
|
||||||
status=status,
|
status=status,
|
||||||
|
sort=sort,
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_by_id(self, id: int) -> BoundImage:
|
def get_by_id(self, id: int) -> BoundImage:
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,6 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING, TypedDict
|
||||||
|
|
||||||
try:
|
|
||||||
from dateutil.parser import isoparse
|
|
||||||
except ImportError:
|
|
||||||
isoparse = None
|
|
||||||
|
|
||||||
from ..core import BaseDomain, DomainIdentityMixin
|
from ..core import BaseDomain, DomainIdentityMixin
|
||||||
|
|
||||||
|
|
@ -15,6 +10,13 @@ if TYPE_CHECKING:
|
||||||
from .client import BoundImage
|
from .client import BoundImage
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"Image",
|
||||||
|
"ImageProtection",
|
||||||
|
"CreateImageResponse",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class Image(BaseDomain, DomainIdentityMixin):
|
class Image(BaseDomain, DomainIdentityMixin):
|
||||||
"""Image Domain
|
"""Image Domain
|
||||||
|
|
||||||
|
|
@ -92,18 +94,18 @@ class Image(BaseDomain, DomainIdentityMixin):
|
||||||
architecture: str | None = None,
|
architecture: str | None = None,
|
||||||
rapid_deploy: bool | None = None,
|
rapid_deploy: bool | None = None,
|
||||||
created_from: Server | BoundServer | None = None,
|
created_from: Server | BoundServer | None = None,
|
||||||
protection: dict | None = None,
|
protection: ImageProtection | None = None,
|
||||||
labels: dict[str, str] | None = None,
|
labels: dict[str, str] | None = None,
|
||||||
status: str | None = None,
|
status: str | None = None,
|
||||||
):
|
):
|
||||||
self.id = id
|
self.id = id
|
||||||
self.name = name
|
self.name = name
|
||||||
self.type = type
|
self.type = type
|
||||||
self.created = isoparse(created) if created else None
|
self.created = self._parse_datetime(created)
|
||||||
self.description = description
|
self.description = description
|
||||||
self.image_size = image_size
|
self.image_size = image_size
|
||||||
self.disk_size = disk_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.bound_to = bound_to
|
||||||
self.os_flavor = os_flavor
|
self.os_flavor = os_flavor
|
||||||
self.os_version = os_version
|
self.os_version = os_version
|
||||||
|
|
@ -115,6 +117,10 @@ class Image(BaseDomain, DomainIdentityMixin):
|
||||||
self.status = status
|
self.status = status
|
||||||
|
|
||||||
|
|
||||||
|
class ImageProtection(TypedDict):
|
||||||
|
delete: bool
|
||||||
|
|
||||||
|
|
||||||
class CreateImageResponse(BaseDomain):
|
class CreateImageResponse(BaseDomain):
|
||||||
"""Create Image Response Domain
|
"""Create Image Response Domain
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,14 @@ from typing import Any, NamedTuple
|
||||||
from ..core import BoundModelBase, Meta, ResourceClientBase
|
from ..core import BoundModelBase, Meta, ResourceClientBase
|
||||||
from .domain import Iso
|
from .domain import Iso
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"BoundIso",
|
||||||
|
"IsosPageResult",
|
||||||
|
"IsosClient",
|
||||||
|
]
|
||||||
|
|
||||||
class BoundIso(BoundModelBase, Iso):
|
|
||||||
|
class BoundIso(BoundModelBase[Iso], Iso):
|
||||||
_client: IsosClient
|
_client: IsosClient
|
||||||
|
|
||||||
model = Iso
|
model = Iso
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,16 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from typing import Any
|
||||||
from warnings import warn
|
from warnings import warn
|
||||||
|
|
||||||
from ..core import BaseDomain, DomainIdentityMixin
|
from ..core import BaseDomain, DomainIdentityMixin
|
||||||
from ..deprecation import DeprecationInfo
|
from ..deprecation import DeprecationInfo
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"Iso",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class Iso(BaseDomain, DomainIdentityMixin):
|
class Iso(BaseDomain, DomainIdentityMixin):
|
||||||
"""Iso Domain
|
"""Iso Domain
|
||||||
|
|
@ -45,7 +50,7 @@ class Iso(BaseDomain, DomainIdentityMixin):
|
||||||
architecture: str | None = None,
|
architecture: str | None = None,
|
||||||
description: str | None = None,
|
description: str | None = None,
|
||||||
deprecated: str | None = None, # pylint: disable=unused-argument
|
deprecated: str | None = None, # pylint: disable=unused-argument
|
||||||
deprecation: dict | None = None,
|
deprecation: dict[str, Any] | None = None,
|
||||||
):
|
):
|
||||||
self.id = id
|
self.id = id
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
@ -67,4 +72,4 @@ class Iso(BaseDomain, DomainIdentityMixin):
|
||||||
)
|
)
|
||||||
if self.deprecation is None:
|
if self.deprecation is None:
|
||||||
return 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 ..core import BoundModelBase, Meta, ResourceClientBase
|
||||||
from .domain import LoadBalancerType
|
from .domain import LoadBalancerType
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"BoundLoadBalancerType",
|
||||||
|
"LoadBalancerTypesPageResult",
|
||||||
|
"LoadBalancerTypesClient",
|
||||||
|
]
|
||||||
|
|
||||||
class BoundLoadBalancerType(BoundModelBase, LoadBalancerType):
|
|
||||||
|
class BoundLoadBalancerType(BoundModelBase[LoadBalancerType], LoadBalancerType):
|
||||||
_client: LoadBalancerTypesClient
|
_client: LoadBalancerTypesClient
|
||||||
|
|
||||||
model = LoadBalancerType
|
model = LoadBalancerType
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,13 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from ..core import BaseDomain, DomainIdentityMixin
|
from ..core import BaseDomain, DomainIdentityMixin
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"LoadBalancerType",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class LoadBalancerType(BaseDomain, DomainIdentityMixin):
|
class LoadBalancerType(BaseDomain, DomainIdentityMixin):
|
||||||
"""LoadBalancerType Domain
|
"""LoadBalancerType Domain
|
||||||
|
|
@ -46,7 +52,7 @@ class LoadBalancerType(BaseDomain, DomainIdentityMixin):
|
||||||
max_services: int | None = None,
|
max_services: int | None = None,
|
||||||
max_targets: int | None = None,
|
max_targets: int | None = None,
|
||||||
max_assigned_certificates: 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.id = id
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,14 @@ from .domain import (
|
||||||
LoadBalancerHealtCheckHttp,
|
LoadBalancerHealtCheckHttp,
|
||||||
LoadBalancerHealthCheck,
|
LoadBalancerHealthCheck,
|
||||||
LoadBalancerHealthCheckHttp,
|
LoadBalancerHealthCheckHttp,
|
||||||
|
LoadBalancerProtection,
|
||||||
LoadBalancerService,
|
LoadBalancerService,
|
||||||
LoadBalancerServiceHttp,
|
LoadBalancerServiceHttp,
|
||||||
LoadBalancerTarget,
|
LoadBalancerTarget,
|
||||||
LoadBalancerTargetHealthStatus,
|
LoadBalancerTargetHealthStatus,
|
||||||
LoadBalancerTargetIP,
|
LoadBalancerTargetIP,
|
||||||
LoadBalancerTargetLabelSelector,
|
LoadBalancerTargetLabelSelector,
|
||||||
|
MetricsType,
|
||||||
PrivateNet,
|
PrivateNet,
|
||||||
PublicNetwork,
|
PublicNetwork,
|
||||||
)
|
)
|
||||||
|
|
@ -32,6 +34,7 @@ __all__ = [
|
||||||
"IPv4Address",
|
"IPv4Address",
|
||||||
"IPv6Network",
|
"IPv6Network",
|
||||||
"LoadBalancer",
|
"LoadBalancer",
|
||||||
|
"LoadBalancerProtection",
|
||||||
"LoadBalancerAlgorithm",
|
"LoadBalancerAlgorithm",
|
||||||
"LoadBalancerHealtCheckHttp",
|
"LoadBalancerHealtCheckHttp",
|
||||||
"LoadBalancerHealthCheckHttp",
|
"LoadBalancerHealthCheckHttp",
|
||||||
|
|
@ -46,4 +49,5 @@ __all__ = [
|
||||||
"LoadBalancersPageResult",
|
"LoadBalancersPageResult",
|
||||||
"PrivateNet",
|
"PrivateNet",
|
||||||
"PublicNetwork",
|
"PublicNetwork",
|
||||||
|
"MetricsType",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,14 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
isoparse = None
|
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 ..certificates import BoundCertificate
|
||||||
from ..core import BoundModelBase, Meta, ResourceClientBase
|
from ..core import BoundModelBase, Meta, ResourceClientBase
|
||||||
from ..load_balancer_types import BoundLoadBalancerType
|
from ..load_balancer_types import BoundLoadBalancerType
|
||||||
|
|
@ -43,13 +50,25 @@ if TYPE_CHECKING:
|
||||||
from ..networks import Network
|
from ..networks import Network
|
||||||
|
|
||||||
|
|
||||||
class BoundLoadBalancer(BoundModelBase, LoadBalancer):
|
__all__ = [
|
||||||
|
"BoundLoadBalancer",
|
||||||
|
"LoadBalancersPageResult",
|
||||||
|
"LoadBalancersClient",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class BoundLoadBalancer(BoundModelBase[LoadBalancer], LoadBalancer):
|
||||||
_client: LoadBalancersClient
|
_client: LoadBalancersClient
|
||||||
|
|
||||||
model = LoadBalancer
|
model = LoadBalancer
|
||||||
|
|
||||||
# pylint: disable=too-many-branches,too-many-locals
|
# 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")
|
algorithm = data.get("algorithm")
|
||||||
if algorithm:
|
if algorithm:
|
||||||
data["algorithm"] = LoadBalancerAlgorithm(type=algorithm["type"])
|
data["algorithm"] = LoadBalancerAlgorithm(type=algorithm["type"])
|
||||||
|
|
@ -210,22 +229,18 @@ class BoundLoadBalancer(BoundModelBase, LoadBalancer):
|
||||||
|
|
||||||
def get_actions_list(
|
def get_actions_list(
|
||||||
self,
|
self,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
page: int | None = None,
|
page: int | None = None,
|
||||||
per_page: int | None = None,
|
per_page: int | None = None,
|
||||||
) -> ActionsPageResult:
|
) -> ActionsPageResult:
|
||||||
"""Returns all action objects for a Load Balancer.
|
"""
|
||||||
|
Returns a paginated list of Actions for a Load Balancer.
|
||||||
|
|
||||||
:param status: List[str] (optional)
|
:param status: Filter the Actions by status.
|
||||||
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
:param sort: Sort Actions by field and direction.
|
||||||
:param sort: List[str] (optional)
|
:param page: Page number to get.
|
||||||
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 per_page: Maximum number of Actions returned per page.
|
||||||
: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>`)
|
|
||||||
"""
|
"""
|
||||||
return self._client.get_actions_list(
|
return self._client.get_actions_list(
|
||||||
self,
|
self,
|
||||||
|
|
@ -237,16 +252,14 @@ class BoundLoadBalancer(BoundModelBase, LoadBalancer):
|
||||||
|
|
||||||
def get_actions(
|
def get_actions(
|
||||||
self,
|
self,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
) -> list[BoundAction]:
|
) -> list[BoundAction]:
|
||||||
"""Returns all action objects for a Load Balancer.
|
"""
|
||||||
|
Returns all Actions for a Load Balancer.
|
||||||
|
|
||||||
:param status: List[str] (optional)
|
:param status: Filter the Actions by status.
|
||||||
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
:param sort: Sort Actions by field and direction.
|
||||||
: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>`]
|
|
||||||
"""
|
"""
|
||||||
return self._client.get_actions(self, status=status, sort=sort)
|
return self._client.get_actions(self, status=status, sort=sort)
|
||||||
|
|
||||||
|
|
@ -386,7 +399,10 @@ class LoadBalancersPageResult(NamedTuple):
|
||||||
meta: Meta
|
meta: Meta
|
||||||
|
|
||||||
|
|
||||||
class LoadBalancersClient(ResourceClientBase):
|
class LoadBalancersClient(
|
||||||
|
ResourceClientBaseActionsMixin,
|
||||||
|
ResourceClientBase,
|
||||||
|
):
|
||||||
_base_url = "/load_balancers"
|
_base_url = "/load_balancers"
|
||||||
|
|
||||||
actions: ResourceActionsClient
|
actions: ResourceActionsClient
|
||||||
|
|
@ -619,59 +635,40 @@ class LoadBalancersClient(ResourceClientBase):
|
||||||
def get_actions_list(
|
def get_actions_list(
|
||||||
self,
|
self,
|
||||||
load_balancer: LoadBalancer | BoundLoadBalancer,
|
load_balancer: LoadBalancer | BoundLoadBalancer,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
page: int | None = None,
|
page: int | None = None,
|
||||||
per_page: int | None = None,
|
per_page: int | None = None,
|
||||||
) -> ActionsPageResult:
|
) -> 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] = {}
|
Returns a paginated list of Actions for a Load Balancer.
|
||||||
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(
|
:param load_balancer: Load Balancer to get the Actions for.
|
||||||
url=f"{self._base_url}/{load_balancer.id}/actions",
|
:param status: Filter the Actions by status.
|
||||||
method="GET",
|
:param sort: Sort Actions by field and direction.
|
||||||
params=params,
|
: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(
|
def get_actions(
|
||||||
self,
|
self,
|
||||||
load_balancer: LoadBalancer | BoundLoadBalancer,
|
load_balancer: LoadBalancer | BoundLoadBalancer,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
) -> list[BoundAction]:
|
) -> 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 load_balancer: Load Balancer to get the Actions for.
|
||||||
:param status: List[str] (optional)
|
:param status: Filter the Actions by status.
|
||||||
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
:param sort: Sort Actions by field and direction.
|
||||||
: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>`]
|
|
||||||
"""
|
"""
|
||||||
return self._iter_pages(
|
return self._iter_pages(
|
||||||
self.get_actions_list,
|
self.get_actions_list,
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,7 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import warnings
|
import warnings
|
||||||
from typing import TYPE_CHECKING, Any, Literal
|
from typing import TYPE_CHECKING, Any, Literal, TypedDict
|
||||||
|
|
||||||
try:
|
|
||||||
from dateutil.parser import isoparse
|
|
||||||
except ImportError:
|
|
||||||
isoparse = None
|
|
||||||
|
|
||||||
from ..core import BaseDomain, DomainIdentityMixin
|
from ..core import BaseDomain, DomainIdentityMixin
|
||||||
|
|
||||||
|
|
@ -21,6 +16,29 @@ if TYPE_CHECKING:
|
||||||
from .client import BoundLoadBalancer
|
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):
|
class LoadBalancer(BaseDomain, DomainIdentityMixin):
|
||||||
"""LoadBalancer Domain
|
"""LoadBalancer Domain
|
||||||
|
|
||||||
|
|
@ -86,7 +104,7 @@ class LoadBalancer(BaseDomain, DomainIdentityMixin):
|
||||||
algorithm: LoadBalancerAlgorithm | None = None,
|
algorithm: LoadBalancerAlgorithm | None = None,
|
||||||
services: list[LoadBalancerService] | None = None,
|
services: list[LoadBalancerService] | None = None,
|
||||||
load_balancer_type: BoundLoadBalancerType | None = None,
|
load_balancer_type: BoundLoadBalancerType | None = None,
|
||||||
protection: dict | None = None,
|
protection: LoadBalancerProtection | None = None,
|
||||||
labels: dict[str, str] | None = None,
|
labels: dict[str, str] | None = None,
|
||||||
targets: list[LoadBalancerTarget] | None = None,
|
targets: list[LoadBalancerTarget] | None = None,
|
||||||
created: str | None = None,
|
created: str | None = None,
|
||||||
|
|
@ -96,7 +114,7 @@ class LoadBalancer(BaseDomain, DomainIdentityMixin):
|
||||||
):
|
):
|
||||||
self.id = id
|
self.id = id
|
||||||
self.name = name
|
self.name = name
|
||||||
self.created = isoparse(created) if created else None
|
self.created = self._parse_datetime(created)
|
||||||
self.public_net = public_net
|
self.public_net = public_net
|
||||||
self.private_net = private_net
|
self.private_net = private_net
|
||||||
self.location = location
|
self.location = location
|
||||||
|
|
@ -121,6 +139,10 @@ class LoadBalancer(BaseDomain, DomainIdentityMixin):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class LoadBalancerProtection(TypedDict):
|
||||||
|
delete: bool
|
||||||
|
|
||||||
|
|
||||||
class LoadBalancerService(BaseDomain):
|
class LoadBalancerService(BaseDomain):
|
||||||
"""LoadBalancerService Domain
|
"""LoadBalancerService Domain
|
||||||
|
|
||||||
|
|
@ -339,7 +361,7 @@ class LoadBalancerHealthCheckHttp(BaseDomain):
|
||||||
domain: str | None = None,
|
domain: str | None = None,
|
||||||
path: str | None = None,
|
path: str | None = None,
|
||||||
response: str | None = None,
|
response: str | None = None,
|
||||||
status_codes: list | None = None,
|
status_codes: list[str] | None = None,
|
||||||
tls: bool | None = None,
|
tls: bool | None = None,
|
||||||
):
|
):
|
||||||
self.domain = domain
|
self.domain = domain
|
||||||
|
|
@ -362,7 +384,7 @@ class LoadBalancerHealtCheckHttp(LoadBalancerHealthCheckHttp):
|
||||||
domain: str | None = None,
|
domain: str | None = None,
|
||||||
path: str | None = None,
|
path: str | None = None,
|
||||||
response: str | None = None,
|
response: str | None = None,
|
||||||
status_codes: list | None = None,
|
status_codes: list[str] | None = None,
|
||||||
tls: bool | None = None,
|
tls: bool | None = None,
|
||||||
):
|
):
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,14 @@ from typing import Any, NamedTuple
|
||||||
from ..core import BoundModelBase, Meta, ResourceClientBase
|
from ..core import BoundModelBase, Meta, ResourceClientBase
|
||||||
from .domain import Location
|
from .domain import Location
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"BoundLocation",
|
||||||
|
"LocationsPageResult",
|
||||||
|
"LocationsClient",
|
||||||
|
]
|
||||||
|
|
||||||
class BoundLocation(BoundModelBase, Location):
|
|
||||||
|
class BoundLocation(BoundModelBase[Location], Location):
|
||||||
_client: LocationsClient
|
_client: LocationsClient
|
||||||
|
|
||||||
model = Location
|
model = Location
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,10 @@ from __future__ import annotations
|
||||||
|
|
||||||
from ..core import BaseDomain, DomainIdentityMixin
|
from ..core import BaseDomain, DomainIdentityMixin
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"Location",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class Location(BaseDomain, DomainIdentityMixin):
|
class Location(BaseDomain, DomainIdentityMixin):
|
||||||
"""Location Domain
|
"""Location Domain
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,14 @@ from __future__ import annotations
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Literal
|
from typing import Literal
|
||||||
|
|
||||||
try:
|
|
||||||
from dateutil.parser import isoparse
|
|
||||||
except ImportError:
|
|
||||||
isoparse = None
|
|
||||||
|
|
||||||
from ..core import BaseDomain
|
from ..core import BaseDomain
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"TimeSeries",
|
||||||
|
"Metrics",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
TimeSeries = dict[str, dict[Literal["values"], list[tuple[float, str]]]]
|
TimeSeries = dict[str, dict[Literal["values"], list[tuple[float, str]]]]
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -44,7 +45,7 @@ class Metrics(BaseDomain):
|
||||||
step: float,
|
step: float,
|
||||||
time_series: TimeSeries,
|
time_series: TimeSeries,
|
||||||
):
|
):
|
||||||
self.start = isoparse(start)
|
self.start = self._parse_datetime(start)
|
||||||
self.end = isoparse(end)
|
self.end = self._parse_datetime(end)
|
||||||
self.step = step
|
self.step = step
|
||||||
self.time_series = time_series
|
self.time_series = time_series
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ from .client import BoundNetwork, NetworksClient, NetworksPageResult
|
||||||
from .domain import (
|
from .domain import (
|
||||||
CreateNetworkResponse,
|
CreateNetworkResponse,
|
||||||
Network,
|
Network,
|
||||||
|
NetworkProtection,
|
||||||
NetworkRoute,
|
NetworkRoute,
|
||||||
NetworkSubnet,
|
NetworkSubnet,
|
||||||
)
|
)
|
||||||
|
|
@ -12,6 +13,7 @@ __all__ = [
|
||||||
"BoundNetwork",
|
"BoundNetwork",
|
||||||
"CreateNetworkResponse",
|
"CreateNetworkResponse",
|
||||||
"Network",
|
"Network",
|
||||||
|
"NetworkProtection",
|
||||||
"NetworkRoute",
|
"NetworkRoute",
|
||||||
"NetworkSubnet",
|
"NetworkSubnet",
|
||||||
"NetworksClient",
|
"NetworksClient",
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,14 @@ from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, Any, NamedTuple
|
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 ..core import BoundModelBase, Meta, ResourceClientBase
|
||||||
from .domain import Network, NetworkRoute, NetworkSubnet
|
from .domain import Network, NetworkRoute, NetworkSubnet
|
||||||
|
|
||||||
|
|
@ -10,12 +17,24 @@ if TYPE_CHECKING:
|
||||||
from .._client import Client
|
from .._client import Client
|
||||||
|
|
||||||
|
|
||||||
class BoundNetwork(BoundModelBase, Network):
|
__all__ = [
|
||||||
|
"BoundNetwork",
|
||||||
|
"NetworksPageResult",
|
||||||
|
"NetworksClient",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class BoundNetwork(BoundModelBase[Network], Network):
|
||||||
_client: NetworksClient
|
_client: NetworksClient
|
||||||
|
|
||||||
model = Network
|
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", [])
|
subnets = data.get("subnets", [])
|
||||||
if subnets is not None:
|
if subnets is not None:
|
||||||
subnets = [NetworkSubnet.from_dict(subnet) for subnet in subnets]
|
subnets = [NetworkSubnet.from_dict(subnet) for subnet in subnets]
|
||||||
|
|
@ -72,22 +91,18 @@ class BoundNetwork(BoundModelBase, Network):
|
||||||
|
|
||||||
def get_actions_list(
|
def get_actions_list(
|
||||||
self,
|
self,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
page: int | None = None,
|
page: int | None = None,
|
||||||
per_page: int | None = None,
|
per_page: int | None = None,
|
||||||
) -> ActionsPageResult:
|
) -> ActionsPageResult:
|
||||||
"""Returns all action objects for a network.
|
"""
|
||||||
|
Returns a paginated list of Actions for a Network.
|
||||||
|
|
||||||
:param status: List[str] (optional)
|
:param status: Filter the Actions by status.
|
||||||
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
:param sort: Sort Actions by field and direction.
|
||||||
:param sort: List[str] (optional)
|
:param page: Page number to get.
|
||||||
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 per_page: Maximum number of Actions returned per page.
|
||||||
: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>`)
|
|
||||||
"""
|
"""
|
||||||
return self._client.get_actions_list(
|
return self._client.get_actions_list(
|
||||||
self,
|
self,
|
||||||
|
|
@ -99,16 +114,14 @@ class BoundNetwork(BoundModelBase, Network):
|
||||||
|
|
||||||
def get_actions(
|
def get_actions(
|
||||||
self,
|
self,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
) -> list[BoundAction]:
|
) -> list[BoundAction]:
|
||||||
"""Returns all action objects for a network.
|
"""
|
||||||
|
Returns all Actions for a Network.
|
||||||
|
|
||||||
:param status: List[str] (optional)
|
:param status: Filter the Actions by status.
|
||||||
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
:param sort: Sort Actions by field and direction.
|
||||||
: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>`]
|
|
||||||
"""
|
"""
|
||||||
return self._client.get_actions(self, status=status, sort=sort)
|
return self._client.get_actions(self, status=status, sort=sort)
|
||||||
|
|
||||||
|
|
@ -172,7 +185,10 @@ class NetworksPageResult(NamedTuple):
|
||||||
meta: Meta
|
meta: Meta
|
||||||
|
|
||||||
|
|
||||||
class NetworksClient(ResourceClientBase):
|
class NetworksClient(
|
||||||
|
ResourceClientBaseActionsMixin,
|
||||||
|
ResourceClientBase,
|
||||||
|
):
|
||||||
_base_url = "/networks"
|
_base_url = "/networks"
|
||||||
|
|
||||||
actions: ResourceActionsClient
|
actions: ResourceActionsClient
|
||||||
|
|
@ -359,59 +375,40 @@ class NetworksClient(ResourceClientBase):
|
||||||
def get_actions_list(
|
def get_actions_list(
|
||||||
self,
|
self,
|
||||||
network: Network | BoundNetwork,
|
network: Network | BoundNetwork,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
page: int | None = None,
|
page: int | None = None,
|
||||||
per_page: int | None = None,
|
per_page: int | None = None,
|
||||||
) -> ActionsPageResult:
|
) -> 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] = {}
|
Returns a paginated list of Actions for a Network.
|
||||||
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(
|
:param network: Network to get the Actions for.
|
||||||
url=f"{self._base_url}/{network.id}/actions",
|
:param status: Filter the Actions by status.
|
||||||
method="GET",
|
:param sort: Sort Actions by field and direction.
|
||||||
params=params,
|
: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(
|
def get_actions(
|
||||||
self,
|
self,
|
||||||
network: Network | BoundNetwork,
|
network: Network | BoundNetwork,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
) -> list[BoundAction]:
|
) -> 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 network: Network to get the Actions for.
|
||||||
:param status: List[str] (optional)
|
:param status: Filter the Actions by status.
|
||||||
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
:param sort: Sort Actions by field and direction.
|
||||||
: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>`]
|
|
||||||
"""
|
"""
|
||||||
return self._iter_pages(
|
return self._iter_pages(
|
||||||
self.get_actions_list,
|
self.get_actions_list,
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,7 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import warnings
|
import warnings
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING, TypedDict
|
||||||
|
|
||||||
try:
|
|
||||||
from dateutil.parser import isoparse
|
|
||||||
except ImportError:
|
|
||||||
isoparse = None
|
|
||||||
|
|
||||||
from ..core import BaseDomain, DomainIdentityMixin
|
from ..core import BaseDomain, DomainIdentityMixin
|
||||||
|
|
||||||
|
|
@ -15,6 +10,14 @@ if TYPE_CHECKING:
|
||||||
from ..servers import BoundServer
|
from ..servers import BoundServer
|
||||||
from .client import BoundNetwork
|
from .client import BoundNetwork
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"Network",
|
||||||
|
"NetworkProtection",
|
||||||
|
"NetworkSubnet",
|
||||||
|
"NetworkRoute",
|
||||||
|
"CreateNetworkResponse",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class Network(BaseDomain, DomainIdentityMixin):
|
class Network(BaseDomain, DomainIdentityMixin):
|
||||||
"""Network Domain
|
"""Network Domain
|
||||||
|
|
@ -63,12 +66,12 @@ class Network(BaseDomain, DomainIdentityMixin):
|
||||||
routes: list[NetworkRoute] | None = None,
|
routes: list[NetworkRoute] | None = None,
|
||||||
expose_routes_to_vswitch: bool | None = None,
|
expose_routes_to_vswitch: bool | None = None,
|
||||||
servers: list[BoundServer] | None = None,
|
servers: list[BoundServer] | None = None,
|
||||||
protection: dict | None = None,
|
protection: NetworkProtection | None = None,
|
||||||
labels: dict[str, str] | None = None,
|
labels: dict[str, str] | None = None,
|
||||||
):
|
):
|
||||||
self.id = id
|
self.id = id
|
||||||
self.name = name
|
self.name = name
|
||||||
self.created = isoparse(created) if created else None
|
self.created = self._parse_datetime(created)
|
||||||
self.ip_range = ip_range
|
self.ip_range = ip_range
|
||||||
self.subnets = subnets
|
self.subnets = subnets
|
||||||
self.routes = routes
|
self.routes = routes
|
||||||
|
|
@ -78,6 +81,10 @@ class Network(BaseDomain, DomainIdentityMixin):
|
||||||
self.labels = labels
|
self.labels = labels
|
||||||
|
|
||||||
|
|
||||||
|
class NetworkProtection(TypedDict):
|
||||||
|
delete: bool
|
||||||
|
|
||||||
|
|
||||||
class NetworkSubnet(BaseDomain):
|
class NetworkSubnet(BaseDomain):
|
||||||
"""Network Subnet Domain
|
"""Network Subnet Domain
|
||||||
|
|
||||||
|
|
@ -116,7 +123,7 @@ class NetworkSubnet(BaseDomain):
|
||||||
"""
|
"""
|
||||||
Used to connect cloud servers and load balancers with dedicated servers.
|
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")
|
__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 ..core import BoundModelBase, Meta, ResourceClientBase
|
||||||
from .domain import CreatePlacementGroupResponse, PlacementGroup
|
from .domain import CreatePlacementGroupResponse, PlacementGroup
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"BoundPlacementGroup",
|
||||||
|
"PlacementGroupsPageResult",
|
||||||
|
"PlacementGroupsClient",
|
||||||
|
]
|
||||||
|
|
||||||
class BoundPlacementGroup(BoundModelBase, PlacementGroup):
|
|
||||||
|
class BoundPlacementGroup(BoundModelBase[PlacementGroup], PlacementGroup):
|
||||||
_client: PlacementGroupsClient
|
_client: PlacementGroupsClient
|
||||||
|
|
||||||
model = PlacementGroup
|
model = PlacementGroup
|
||||||
|
|
|
||||||
|
|
@ -2,17 +2,17 @@ from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
try:
|
|
||||||
from dateutil.parser import isoparse
|
|
||||||
except ImportError:
|
|
||||||
isoparse = None
|
|
||||||
|
|
||||||
from ..core import BaseDomain, DomainIdentityMixin
|
from ..core import BaseDomain, DomainIdentityMixin
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from ..actions import BoundAction
|
from ..actions import BoundAction
|
||||||
from .client import BoundPlacementGroup
|
from .client import BoundPlacementGroup
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"PlacementGroup",
|
||||||
|
"CreatePlacementGroupResponse",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class PlacementGroup(BaseDomain, DomainIdentityMixin):
|
class PlacementGroup(BaseDomain, DomainIdentityMixin):
|
||||||
"""Placement Group Domain
|
"""Placement Group Domain
|
||||||
|
|
@ -53,7 +53,7 @@ class PlacementGroup(BaseDomain, DomainIdentityMixin):
|
||||||
self.labels = labels
|
self.labels = labels
|
||||||
self.servers = servers
|
self.servers = servers
|
||||||
self.type = type
|
self.type = type
|
||||||
self.created = isoparse(created) if created else None
|
self.created = self._parse_datetime(created)
|
||||||
|
|
||||||
|
|
||||||
class CreatePlacementGroupResponse(BaseDomain):
|
class CreatePlacementGroupResponse(BaseDomain):
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from .client import BoundPrimaryIP, PrimaryIPsClient, PrimaryIPsPageResult
|
from .client import BoundPrimaryIP, PrimaryIPsClient, PrimaryIPsPageResult
|
||||||
from .domain import CreatePrimaryIPResponse, PrimaryIP
|
from .domain import CreatePrimaryIPResponse, PrimaryIP, PrimaryIPProtection
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"BoundPrimaryIP",
|
"BoundPrimaryIP",
|
||||||
"CreatePrimaryIPResponse",
|
"CreatePrimaryIPResponse",
|
||||||
"PrimaryIP",
|
"PrimaryIP",
|
||||||
|
"PrimaryIPProtection",
|
||||||
"PrimaryIPsClient",
|
"PrimaryIPsClient",
|
||||||
"PrimaryIPsPageResult",
|
"PrimaryIPsPageResult",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,31 +1,97 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import warnings
|
||||||
from typing import TYPE_CHECKING, Any, NamedTuple
|
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 ..core import BoundModelBase, Meta, ResourceClientBase
|
||||||
from .domain import CreatePrimaryIPResponse, PrimaryIP
|
from .domain import CreatePrimaryIPResponse, PrimaryIP
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .._client import Client
|
from .._client import Client
|
||||||
from ..datacenters import BoundDatacenter, Datacenter
|
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
|
_client: PrimaryIPsClient
|
||||||
|
|
||||||
model = PrimaryIP
|
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
|
# pylint: disable=import-outside-toplevel
|
||||||
from ..datacenters import BoundDatacenter
|
from ..datacenters import BoundDatacenter
|
||||||
|
from ..locations import BoundLocation
|
||||||
|
|
||||||
datacenter = data.get("datacenter", {})
|
raw = data.get("datacenter", {})
|
||||||
if datacenter:
|
if raw:
|
||||||
data["datacenter"] = BoundDatacenter(client._parent.datacenters, datacenter)
|
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)
|
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(
|
def update(
|
||||||
self,
|
self,
|
||||||
auto_delete: bool | None = None,
|
auto_delete: bool | None = None,
|
||||||
|
|
@ -102,7 +168,10 @@ class PrimaryIPsPageResult(NamedTuple):
|
||||||
meta: Meta
|
meta: Meta
|
||||||
|
|
||||||
|
|
||||||
class PrimaryIPsClient(ResourceClientBase):
|
class PrimaryIPsClient(
|
||||||
|
ResourceClientBaseActionsMixin,
|
||||||
|
ResourceClientBase,
|
||||||
|
):
|
||||||
_base_url = "/primary_ips"
|
_base_url = "/primary_ips"
|
||||||
|
|
||||||
actions: ResourceActionsClient
|
actions: ResourceActionsClient
|
||||||
|
|
@ -115,6 +184,51 @@ class PrimaryIPsClient(ResourceClientBase):
|
||||||
super().__init__(client)
|
super().__init__(client)
|
||||||
self.actions = ResourceActionsClient(client, self._base_url)
|
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:
|
def get_by_id(self, id: int) -> BoundPrimaryIP:
|
||||||
"""Returns a specific Primary IP object.
|
"""Returns a specific Primary IP object.
|
||||||
|
|
||||||
|
|
@ -196,16 +310,18 @@ class PrimaryIPsClient(ResourceClientBase):
|
||||||
type: str,
|
type: str,
|
||||||
name: str,
|
name: str,
|
||||||
datacenter: Datacenter | BoundDatacenter | None = None,
|
datacenter: Datacenter | BoundDatacenter | None = None,
|
||||||
|
location: Location | BoundLocation | None = None,
|
||||||
assignee_type: str | None = "server",
|
assignee_type: str | None = "server",
|
||||||
assignee_id: int | None = None,
|
assignee_id: int | None = None,
|
||||||
auto_delete: bool | None = False,
|
auto_delete: bool | None = False,
|
||||||
labels: dict | None = None,
|
labels: dict[str, str] | None = None,
|
||||||
) -> CreatePrimaryIPResponse:
|
) -> CreatePrimaryIPResponse:
|
||||||
"""Creates a new Primary IP assigned to a server.
|
"""Creates a new Primary IP assigned to a server.
|
||||||
|
|
||||||
:param type: str Primary IP type Choices: ipv4, ipv6
|
:param type: str Primary IP type Choices: ipv4, ipv6
|
||||||
:param name: str
|
:param name: str
|
||||||
:param datacenter: Datacenter (optional)
|
:param datacenter: Datacenter (optional)
|
||||||
|
:param location: Location (optional)
|
||||||
:param assignee_type: str (optional)
|
:param assignee_type: str (optional)
|
||||||
:param assignee_id: int (optional)
|
:param assignee_id: int (optional)
|
||||||
:param auto_delete: bool (optional)
|
:param auto_delete: bool (optional)
|
||||||
|
|
@ -220,7 +336,16 @@ class PrimaryIPsClient(ResourceClientBase):
|
||||||
"auto_delete": auto_delete,
|
"auto_delete": auto_delete,
|
||||||
}
|
}
|
||||||
if datacenter is not None:
|
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
|
data["datacenter"] = datacenter.id_or_name
|
||||||
|
if location is not None:
|
||||||
|
data["location"] = location.id_or_name
|
||||||
if assignee_id is not None:
|
if assignee_id is not None:
|
||||||
data["assignee_id"] = assignee_id
|
data["assignee_id"] = assignee_id
|
||||||
if labels is not None:
|
if labels is not None:
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,23 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
import warnings
|
||||||
|
from typing import TYPE_CHECKING, TypedDict
|
||||||
try:
|
|
||||||
from dateutil.parser import isoparse
|
|
||||||
except ImportError:
|
|
||||||
isoparse = None
|
|
||||||
|
|
||||||
from ..core import BaseDomain, DomainIdentityMixin
|
from ..core import BaseDomain, DomainIdentityMixin
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from ..actions import BoundAction
|
from ..actions import BoundAction
|
||||||
from ..datacenters import BoundDatacenter
|
from ..datacenters import BoundDatacenter
|
||||||
|
from ..locations import BoundLocation
|
||||||
|
from ..rdns import DNSPtr
|
||||||
from .client import BoundPrimaryIP
|
from .client import BoundPrimaryIP
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"PrimaryIP",
|
||||||
|
"PrimaryIPProtection",
|
||||||
|
"CreatePrimaryIPResponse",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class PrimaryIP(BaseDomain, DomainIdentityMixin):
|
class PrimaryIP(BaseDomain, DomainIdentityMixin):
|
||||||
"""Primary IP Domain
|
"""Primary IP Domain
|
||||||
|
|
@ -27,7 +31,15 @@ class PrimaryIP(BaseDomain, DomainIdentityMixin):
|
||||||
:param dns_ptr: List[Dict]
|
:param dns_ptr: List[Dict]
|
||||||
Array of reverse DNS entries
|
Array of reverse DNS entries
|
||||||
:param datacenter: :class:`Datacenter <hcloud.datacenters.client.BoundDatacenter>`
|
: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
|
:param blocked: boolean
|
||||||
Whether the IP is blocked
|
Whether the IP is blocked
|
||||||
:param protection: dict
|
:param protection: dict
|
||||||
|
|
@ -46,12 +58,12 @@ class PrimaryIP(BaseDomain, DomainIdentityMixin):
|
||||||
Delete the Primary IP when the Assignee it is assigned to is deleted.
|
Delete the Primary IP when the Assignee it is assigned to is deleted.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__api_properties__ = (
|
__properties__ = (
|
||||||
"id",
|
"id",
|
||||||
"ip",
|
"ip",
|
||||||
"type",
|
"type",
|
||||||
"dns_ptr",
|
"dns_ptr",
|
||||||
"datacenter",
|
"location",
|
||||||
"blocked",
|
"blocked",
|
||||||
"protection",
|
"protection",
|
||||||
"labels",
|
"labels",
|
||||||
|
|
@ -61,18 +73,26 @@ class PrimaryIP(BaseDomain, DomainIdentityMixin):
|
||||||
"assignee_type",
|
"assignee_type",
|
||||||
"auto_delete",
|
"auto_delete",
|
||||||
)
|
)
|
||||||
__slots__ = __api_properties__
|
__api_properties__ = (
|
||||||
|
*__properties__,
|
||||||
|
"datacenter",
|
||||||
|
)
|
||||||
|
__slots__ = (
|
||||||
|
*__properties__,
|
||||||
|
"_datacenter",
|
||||||
|
)
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
id: int | None = None,
|
id: int | None = None,
|
||||||
type: str | None = None,
|
type: str | None = None,
|
||||||
ip: str | None = None,
|
ip: str | None = None,
|
||||||
dns_ptr: list[dict] | None = None,
|
dns_ptr: list[DNSPtr] | None = None,
|
||||||
datacenter: BoundDatacenter | None = None,
|
datacenter: BoundDatacenter | None = None,
|
||||||
|
location: BoundLocation | None = None,
|
||||||
blocked: bool | None = None,
|
blocked: bool | None = None,
|
||||||
protection: dict | None = None,
|
protection: PrimaryIPProtection | None = None,
|
||||||
labels: dict[str, dict] | None = None,
|
labels: dict[str, str] | None = None,
|
||||||
created: str | None = None,
|
created: str | None = None,
|
||||||
name: str | None = None,
|
name: str | None = None,
|
||||||
assignee_id: int | None = None,
|
assignee_id: int | None = None,
|
||||||
|
|
@ -84,15 +104,38 @@ class PrimaryIP(BaseDomain, DomainIdentityMixin):
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
self.dns_ptr = dns_ptr
|
self.dns_ptr = dns_ptr
|
||||||
self.datacenter = datacenter
|
self.datacenter = datacenter
|
||||||
|
self.location = location
|
||||||
self.blocked = blocked
|
self.blocked = blocked
|
||||||
self.protection = protection
|
self.protection = protection
|
||||||
self.labels = labels
|
self.labels = labels
|
||||||
self.created = isoparse(created) if created else None
|
self.created = self._parse_datetime(created)
|
||||||
self.name = name
|
self.name = name
|
||||||
self.assignee_id = assignee_id
|
self.assignee_id = assignee_id
|
||||||
self.assignee_type = assignee_type
|
self.assignee_type = assignee_type
|
||||||
self.auto_delete = auto_delete
|
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):
|
class CreatePrimaryIPResponse(BaseDomain):
|
||||||
"""Create Primary IP Response Domain
|
"""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 ..locations import BoundLocation
|
||||||
from .domain import ServerType, ServerTypeLocation
|
from .domain import ServerType, ServerTypeLocation
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"BoundServerType",
|
||||||
|
"ServerTypesPageResult",
|
||||||
|
"ServerTypesClient",
|
||||||
|
]
|
||||||
|
|
||||||
class BoundServerType(BoundModelBase, ServerType):
|
|
||||||
|
class BoundServerType(BoundModelBase[ServerType], ServerType):
|
||||||
_client: ServerTypesClient
|
_client: ServerTypesClient
|
||||||
|
|
||||||
model = ServerType
|
model = ServerType
|
||||||
|
|
@ -15,7 +21,7 @@ class BoundServerType(BoundModelBase, ServerType):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
client: ServerTypesClient,
|
client: ServerTypesClient,
|
||||||
data: dict,
|
data: dict[str, Any],
|
||||||
complete: bool = True,
|
complete: bool = True,
|
||||||
):
|
):
|
||||||
raw = data.get("locations")
|
raw = data.get("locations")
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,17 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import warnings
|
import warnings
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from ..core import BaseDomain, DomainIdentityMixin
|
from ..core import BaseDomain, DomainIdentityMixin
|
||||||
from ..deprecation import DeprecationInfo
|
from ..deprecation import DeprecationInfo
|
||||||
from ..locations import BoundLocation
|
from ..locations import BoundLocation
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"ServerType",
|
||||||
|
"ServerTypeLocation",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class ServerType(BaseDomain, DomainIdentityMixin):
|
class ServerType(BaseDomain, DomainIdentityMixin):
|
||||||
"""ServerType Domain
|
"""ServerType Domain
|
||||||
|
|
@ -79,12 +85,12 @@ class ServerType(BaseDomain, DomainIdentityMixin):
|
||||||
cores: int | None = None,
|
cores: int | None = None,
|
||||||
memory: int | None = None,
|
memory: int | None = None,
|
||||||
disk: int | None = None,
|
disk: int | None = None,
|
||||||
prices: list[dict] | None = None,
|
prices: list[dict[str, Any]] | None = None,
|
||||||
storage_type: str | None = None,
|
storage_type: str | None = None,
|
||||||
cpu_type: str | None = None,
|
cpu_type: str | None = None,
|
||||||
architecture: str | None = None,
|
architecture: str | None = None,
|
||||||
deprecated: bool | None = None,
|
deprecated: bool | None = None,
|
||||||
deprecation: dict | None = None,
|
deprecation: dict[str, Any] | None = None,
|
||||||
included_traffic: int | None = None,
|
included_traffic: int | None = None,
|
||||||
locations: list[ServerTypeLocation] | None = None,
|
locations: list[ServerTypeLocation] | None = None,
|
||||||
):
|
):
|
||||||
|
|
@ -191,7 +197,7 @@ class ServerTypeLocation(BaseDomain):
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
location: BoundLocation,
|
location: BoundLocation,
|
||||||
deprecation: dict | None,
|
deprecation: dict[str, Any] | None,
|
||||||
):
|
):
|
||||||
self.location = location
|
self.location = location
|
||||||
self.deprecation = (
|
self.deprecation = (
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,16 @@ from .domain import (
|
||||||
GetMetricsResponse,
|
GetMetricsResponse,
|
||||||
IPv4Address,
|
IPv4Address,
|
||||||
IPv6Network,
|
IPv6Network,
|
||||||
|
MetricsType,
|
||||||
PrivateNet,
|
PrivateNet,
|
||||||
PublicNetwork,
|
PublicNetwork,
|
||||||
PublicNetworkFirewall,
|
PublicNetworkFirewall,
|
||||||
|
RebuildResponse,
|
||||||
RequestConsoleResponse,
|
RequestConsoleResponse,
|
||||||
ResetPasswordResponse,
|
ResetPasswordResponse,
|
||||||
Server,
|
Server,
|
||||||
ServerCreatePublicNetwork,
|
ServerCreatePublicNetwork,
|
||||||
|
ServerProtection,
|
||||||
)
|
)
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
|
|
@ -29,7 +32,10 @@ __all__ = [
|
||||||
"RequestConsoleResponse",
|
"RequestConsoleResponse",
|
||||||
"ResetPasswordResponse",
|
"ResetPasswordResponse",
|
||||||
"Server",
|
"Server",
|
||||||
|
"ServerProtection",
|
||||||
"ServerCreatePublicNetwork",
|
"ServerCreatePublicNetwork",
|
||||||
"ServersClient",
|
"ServersClient",
|
||||||
"ServersPageResult",
|
"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
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import warnings
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import TYPE_CHECKING, Any, NamedTuple
|
from typing import TYPE_CHECKING, Any, NamedTuple
|
||||||
|
|
||||||
|
|
@ -8,13 +9,21 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
isoparse = None
|
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 ..core import BoundModelBase, Meta, ResourceClientBase
|
||||||
from ..datacenters import BoundDatacenter
|
from ..datacenters import BoundDatacenter
|
||||||
from ..firewalls import BoundFirewall
|
from ..firewalls import BoundFirewall
|
||||||
from ..floating_ips import BoundFloatingIP
|
from ..floating_ips import BoundFloatingIP
|
||||||
from ..images import BoundImage, CreateImageResponse
|
from ..images import BoundImage, CreateImageResponse
|
||||||
from ..isos import BoundIso
|
from ..isos import BoundIso
|
||||||
|
from ..locations import BoundLocation, Location
|
||||||
from ..metrics import Metrics
|
from ..metrics import Metrics
|
||||||
from ..placement_groups import BoundPlacementGroup
|
from ..placement_groups import BoundPlacementGroup
|
||||||
from ..primary_ips import BoundPrimaryIP
|
from ..primary_ips import BoundPrimaryIP
|
||||||
|
|
@ -42,7 +51,6 @@ if TYPE_CHECKING:
|
||||||
from ..firewalls import Firewall
|
from ..firewalls import Firewall
|
||||||
from ..images import Image
|
from ..images import Image
|
||||||
from ..isos import Iso
|
from ..isos import Iso
|
||||||
from ..locations import BoundLocation, Location
|
|
||||||
from ..networks import BoundNetwork, Network
|
from ..networks import BoundNetwork, Network
|
||||||
from ..placement_groups import PlacementGroup
|
from ..placement_groups import PlacementGroup
|
||||||
from ..server_types import ServerType
|
from ..server_types import ServerType
|
||||||
|
|
@ -51,16 +59,32 @@ if TYPE_CHECKING:
|
||||||
from .domain import ServerCreatePublicNetwork
|
from .domain import ServerCreatePublicNetwork
|
||||||
|
|
||||||
|
|
||||||
class BoundServer(BoundModelBase, Server):
|
__all__ = [
|
||||||
|
"BoundServer",
|
||||||
|
"ServersPageResult",
|
||||||
|
"ServersClient",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class BoundServer(BoundModelBase[Server], Server):
|
||||||
_client: ServersClient
|
_client: ServersClient
|
||||||
|
|
||||||
model = Server
|
model = Server
|
||||||
|
|
||||||
# pylint: disable=too-many-locals
|
# pylint: disable=too-many-locals
|
||||||
def __init__(self, client: ServersClient, data: dict, complete: bool = True):
|
def __init__(
|
||||||
datacenter = data.get("datacenter")
|
self,
|
||||||
if datacenter is not None:
|
client: ServersClient,
|
||||||
data["datacenter"] = BoundDatacenter(client._parent.datacenters, datacenter)
|
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", [])
|
volumes = data.get("volumes", [])
|
||||||
if volumes:
|
if volumes:
|
||||||
|
|
@ -169,22 +193,18 @@ class BoundServer(BoundModelBase, Server):
|
||||||
|
|
||||||
def get_actions_list(
|
def get_actions_list(
|
||||||
self,
|
self,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
page: int | None = None,
|
page: int | None = None,
|
||||||
per_page: int | None = None,
|
per_page: int | None = None,
|
||||||
) -> ActionsPageResult:
|
) -> ActionsPageResult:
|
||||||
"""Returns all action objects for a server.
|
"""
|
||||||
|
Returns a paginated list of Actions for a Server.
|
||||||
|
|
||||||
:param status: List[str] (optional)
|
:param status: Filter the Actions by status.
|
||||||
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
:param sort: Sort Actions by field and direction.
|
||||||
:param sort: List[str] (optional)
|
:param page: Page number to get.
|
||||||
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 per_page: Maximum number of Actions returned per page.
|
||||||
: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>`)
|
|
||||||
"""
|
"""
|
||||||
return self._client.get_actions_list(
|
return self._client.get_actions_list(
|
||||||
self,
|
self,
|
||||||
|
|
@ -196,16 +216,14 @@ class BoundServer(BoundModelBase, Server):
|
||||||
|
|
||||||
def get_actions(
|
def get_actions(
|
||||||
self,
|
self,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
) -> list[BoundAction]:
|
) -> list[BoundAction]:
|
||||||
"""Returns all action objects for a server.
|
"""
|
||||||
|
Returns all Actions for a Server.
|
||||||
|
|
||||||
:param status: List[str] (optional)
|
:param status: Filter the Actions by status.
|
||||||
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
:param sort: Sort Actions by field and direction.
|
||||||
: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>`]
|
|
||||||
"""
|
"""
|
||||||
return self._client.get_actions(self, status=status, sort=sort)
|
return self._client.get_actions(self, status=status, sort=sort)
|
||||||
|
|
||||||
|
|
@ -506,7 +524,10 @@ class ServersPageResult(NamedTuple):
|
||||||
meta: Meta
|
meta: Meta
|
||||||
|
|
||||||
|
|
||||||
class ServersClient(ResourceClientBase):
|
class ServersClient(
|
||||||
|
ResourceClientBaseActionsMixin,
|
||||||
|
ResourceClientBase,
|
||||||
|
):
|
||||||
_base_url = "/servers"
|
_base_url = "/servers"
|
||||||
|
|
||||||
actions: ResourceActionsClient
|
actions: ResourceActionsClient
|
||||||
|
|
@ -660,6 +681,13 @@ class ServersClient(ResourceClientBase):
|
||||||
if location is not None:
|
if location is not None:
|
||||||
data["location"] = location.id_or_name
|
data["location"] = location.id_or_name
|
||||||
if datacenter is not None:
|
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
|
data["datacenter"] = datacenter.id_or_name
|
||||||
if ssh_keys is not None:
|
if ssh_keys is not None:
|
||||||
data["ssh_keys"] = [ssh_key.id_or_name for ssh_key in ssh_keys]
|
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(
|
def get_actions_list(
|
||||||
self,
|
self,
|
||||||
server: Server | BoundServer,
|
server: Server | BoundServer,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
page: int | None = None,
|
page: int | None = None,
|
||||||
per_page: int | None = None,
|
per_page: int | None = None,
|
||||||
) -> ActionsPageResult:
|
) -> 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] = {}
|
Returns a paginated list of Actions for a Server.
|
||||||
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(
|
:param server: Server to get the Actions for.
|
||||||
url=f"{self._base_url}/{server.id}/actions",
|
:param status: Filter the Actions by status.
|
||||||
method="GET",
|
:param sort: Sort Actions by field and direction.
|
||||||
params=params,
|
: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(
|
def get_actions(
|
||||||
self,
|
self,
|
||||||
server: Server | BoundServer,
|
server: Server | BoundServer,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
) -> list[BoundAction]:
|
) -> 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 server: Server to get the Actions for.
|
||||||
:param status: List[str] (optional)
|
:param status: Filter the Actions by status.
|
||||||
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
:param sort: Sort Actions by field and direction.
|
||||||
: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>`]
|
|
||||||
"""
|
"""
|
||||||
return self._iter_pages(
|
return self._iter_pages(
|
||||||
self.get_actions_list,
|
self.get_actions_list,
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,7 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, Literal
|
import warnings
|
||||||
|
from typing import TYPE_CHECKING, Literal, TypedDict
|
||||||
try:
|
|
||||||
from dateutil.parser import isoparse
|
|
||||||
except ImportError:
|
|
||||||
isoparse = None
|
|
||||||
|
|
||||||
from ..core import BaseDomain, DomainIdentityMixin
|
from ..core import BaseDomain, DomainIdentityMixin
|
||||||
|
|
||||||
|
|
@ -16,15 +12,36 @@ if TYPE_CHECKING:
|
||||||
from ..floating_ips import BoundFloatingIP
|
from ..floating_ips import BoundFloatingIP
|
||||||
from ..images import BoundImage
|
from ..images import BoundImage
|
||||||
from ..isos import BoundIso
|
from ..isos import BoundIso
|
||||||
|
from ..locations import BoundLocation
|
||||||
from ..metrics import Metrics
|
from ..metrics import Metrics
|
||||||
from ..networks import BoundNetwork, Network
|
from ..networks import BoundNetwork, Network
|
||||||
from ..placement_groups import BoundPlacementGroup
|
from ..placement_groups import BoundPlacementGroup
|
||||||
from ..primary_ips import BoundPrimaryIP, PrimaryIP
|
from ..primary_ips import BoundPrimaryIP, PrimaryIP
|
||||||
|
from ..rdns import DNSPtr
|
||||||
from ..server_types import BoundServerType
|
from ..server_types import BoundServerType
|
||||||
from ..volumes import BoundVolume
|
from ..volumes import BoundVolume
|
||||||
from .client import BoundServer
|
from .client import BoundServer
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"Server",
|
||||||
|
"ServerProtection",
|
||||||
|
"CreateServerResponse",
|
||||||
|
"ResetPasswordResponse",
|
||||||
|
"EnableRescueResponse",
|
||||||
|
"RequestConsoleResponse",
|
||||||
|
"RebuildResponse",
|
||||||
|
"PublicNetwork",
|
||||||
|
"PublicNetworkFirewall",
|
||||||
|
"IPv4Address",
|
||||||
|
"IPv6Network",
|
||||||
|
"PrivateNet",
|
||||||
|
"ServerCreatePublicNetwork",
|
||||||
|
"GetMetricsResponse",
|
||||||
|
"MetricsType",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class Server(BaseDomain, DomainIdentityMixin):
|
class Server(BaseDomain, DomainIdentityMixin):
|
||||||
"""Server Domain
|
"""Server Domain
|
||||||
|
|
||||||
|
|
@ -40,6 +57,12 @@ class Server(BaseDomain, DomainIdentityMixin):
|
||||||
Public network information.
|
Public network information.
|
||||||
:param server_type: :class:`BoundServerType <hcloud.server_types.client.BoundServerType>`
|
:param server_type: :class:`BoundServerType <hcloud.server_types.client.BoundServerType>`
|
||||||
:param datacenter: :class:`BoundDatacenter <hcloud.datacenters.client.BoundDatacenter>`
|
: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 image: :class:`BoundImage <hcloud.images.client.BoundImage>`, None
|
||||||
:param iso: :class:`BoundIso <hcloud.isos.client.BoundIso>`, None
|
:param iso: :class:`BoundIso <hcloud.isos.client.BoundIso>`, None
|
||||||
:param rescue_enabled: bool
|
:param rescue_enabled: bool
|
||||||
|
|
@ -85,13 +108,13 @@ class Server(BaseDomain, DomainIdentityMixin):
|
||||||
STATUS_UNKNOWN = "unknown"
|
STATUS_UNKNOWN = "unknown"
|
||||||
"""Server Status unknown"""
|
"""Server Status unknown"""
|
||||||
|
|
||||||
__api_properties__ = (
|
__properties__ = (
|
||||||
"id",
|
"id",
|
||||||
"name",
|
"name",
|
||||||
"status",
|
"status",
|
||||||
"public_net",
|
"public_net",
|
||||||
"server_type",
|
"server_type",
|
||||||
"datacenter",
|
"location",
|
||||||
"image",
|
"image",
|
||||||
"iso",
|
"iso",
|
||||||
"rescue_enabled",
|
"rescue_enabled",
|
||||||
|
|
@ -108,7 +131,14 @@ class Server(BaseDomain, DomainIdentityMixin):
|
||||||
"primary_disk_size",
|
"primary_disk_size",
|
||||||
"placement_group",
|
"placement_group",
|
||||||
)
|
)
|
||||||
__slots__ = __api_properties__
|
__api_properties__ = (
|
||||||
|
*__properties__,
|
||||||
|
"datacenter",
|
||||||
|
)
|
||||||
|
__slots__ = (
|
||||||
|
*__properties__,
|
||||||
|
"_datacenter",
|
||||||
|
)
|
||||||
|
|
||||||
# pylint: disable=too-many-locals
|
# pylint: disable=too-many-locals
|
||||||
def __init__(
|
def __init__(
|
||||||
|
|
@ -120,6 +150,7 @@ class Server(BaseDomain, DomainIdentityMixin):
|
||||||
public_net: PublicNetwork | None = None,
|
public_net: PublicNetwork | None = None,
|
||||||
server_type: BoundServerType | None = None,
|
server_type: BoundServerType | None = None,
|
||||||
datacenter: BoundDatacenter | None = None,
|
datacenter: BoundDatacenter | None = None,
|
||||||
|
location: BoundLocation | None = None,
|
||||||
image: BoundImage | None = None,
|
image: BoundImage | None = None,
|
||||||
iso: BoundIso | None = None,
|
iso: BoundIso | None = None,
|
||||||
rescue_enabled: bool | None = None,
|
rescue_enabled: bool | None = None,
|
||||||
|
|
@ -128,7 +159,7 @@ class Server(BaseDomain, DomainIdentityMixin):
|
||||||
outgoing_traffic: int | None = None,
|
outgoing_traffic: int | None = None,
|
||||||
ingoing_traffic: int | None = None,
|
ingoing_traffic: int | None = None,
|
||||||
included_traffic: int | None = None,
|
included_traffic: int | None = None,
|
||||||
protection: dict | None = None,
|
protection: ServerProtection | None = None,
|
||||||
labels: dict[str, str] | None = None,
|
labels: dict[str, str] | None = None,
|
||||||
volumes: list[BoundVolume] | None = None,
|
volumes: list[BoundVolume] | None = None,
|
||||||
private_net: list[PrivateNet] | None = None,
|
private_net: list[PrivateNet] | None = None,
|
||||||
|
|
@ -138,10 +169,11 @@ class Server(BaseDomain, DomainIdentityMixin):
|
||||||
self.id = id
|
self.id = id
|
||||||
self.name = name
|
self.name = name
|
||||||
self.status = status
|
self.status = status
|
||||||
self.created = isoparse(created) if created else None
|
self.created = self._parse_datetime(created)
|
||||||
self.public_net = public_net
|
self.public_net = public_net
|
||||||
self.server_type = server_type
|
self.server_type = server_type
|
||||||
self.datacenter = datacenter
|
self.datacenter = datacenter
|
||||||
|
self.location = location
|
||||||
self.image = image
|
self.image = image
|
||||||
self.iso = iso
|
self.iso = iso
|
||||||
self.rescue_enabled = rescue_enabled
|
self.rescue_enabled = rescue_enabled
|
||||||
|
|
@ -167,6 +199,29 @@ class Server(BaseDomain, DomainIdentityMixin):
|
||||||
return o
|
return o
|
||||||
return None
|
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):
|
class CreateServerResponse(BaseDomain):
|
||||||
"""Create Server Response Domain
|
"""Create Server Response Domain
|
||||||
|
|
@ -392,7 +447,7 @@ class IPv6Network(BaseDomain):
|
||||||
self,
|
self,
|
||||||
ip: str,
|
ip: str,
|
||||||
blocked: bool,
|
blocked: bool,
|
||||||
dns_ptr: list,
|
dns_ptr: list[DNSPtr],
|
||||||
):
|
):
|
||||||
self.ip = ip
|
self.ip = ip
|
||||||
self.blocked = blocked
|
self.blocked = blocked
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,14 @@ from typing import Any, NamedTuple
|
||||||
from ..core import BoundModelBase, Meta, ResourceClientBase
|
from ..core import BoundModelBase, Meta, ResourceClientBase
|
||||||
from .domain import SSHKey
|
from .domain import SSHKey
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"BoundSSHKey",
|
||||||
|
"SSHKeysPageResult",
|
||||||
|
"SSHKeysClient",
|
||||||
|
]
|
||||||
|
|
||||||
class BoundSSHKey(BoundModelBase, SSHKey):
|
|
||||||
|
class BoundSSHKey(BoundModelBase[SSHKey], SSHKey):
|
||||||
_client: SSHKeysClient
|
_client: SSHKeysClient
|
||||||
|
|
||||||
model = SSHKey
|
model = SSHKey
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
try:
|
|
||||||
from dateutil.parser import isoparse
|
|
||||||
except ImportError:
|
|
||||||
isoparse = None
|
|
||||||
|
|
||||||
from ..core import BaseDomain, DomainIdentityMixin
|
from ..core import BaseDomain, DomainIdentityMixin
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"SSHKey",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class SSHKey(BaseDomain, DomainIdentityMixin):
|
class SSHKey(BaseDomain, DomainIdentityMixin):
|
||||||
"""SSHKey Domain
|
"""SSHKey Domain
|
||||||
|
|
@ -49,4 +48,4 @@ class SSHKey(BaseDomain, DomainIdentityMixin):
|
||||||
self.fingerprint = fingerprint
|
self.fingerprint = fingerprint
|
||||||
self.public_key = public_key
|
self.public_key = public_key
|
||||||
self.labels = labels
|
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:
|
if TYPE_CHECKING:
|
||||||
from .._client import Client
|
from .._client import Client
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"BoundStorageBoxType",
|
||||||
|
"StorageBoxTypesPageResult",
|
||||||
|
"StorageBoxTypesClient",
|
||||||
|
]
|
||||||
|
|
||||||
class BoundStorageBoxType(BoundModelBase, StorageBoxType):
|
|
||||||
|
class BoundStorageBoxType(BoundModelBase[StorageBoxType], StorageBoxType):
|
||||||
_client: StorageBoxTypesClient
|
_client: StorageBoxTypesClient
|
||||||
|
|
||||||
model = StorageBoxType
|
model = StorageBoxType
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,14 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from ..core import BaseDomain, DomainIdentityMixin
|
from ..core import BaseDomain, DomainIdentityMixin
|
||||||
from ..deprecation import DeprecationInfo
|
from ..deprecation import DeprecationInfo
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"StorageBoxType",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class StorageBoxType(BaseDomain, DomainIdentityMixin):
|
class StorageBoxType(BaseDomain, DomainIdentityMixin):
|
||||||
"""
|
"""
|
||||||
|
|
@ -33,8 +39,8 @@ class StorageBoxType(BaseDomain, DomainIdentityMixin):
|
||||||
automatic_snapshot_limit: int | None = None,
|
automatic_snapshot_limit: int | None = None,
|
||||||
subaccounts_limit: int | None = None,
|
subaccounts_limit: int | None = None,
|
||||||
size: int | None = None,
|
size: int | None = None,
|
||||||
prices: list[dict] | None = None,
|
prices: list[dict[str, Any]] | None = None,
|
||||||
deprecation: dict | None = None,
|
deprecation: dict[str, Any] | None = None,
|
||||||
):
|
):
|
||||||
self.id = id
|
self.id = id
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,14 @@ from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, Any, NamedTuple
|
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 ..core import BoundModelBase, Meta, ResourceClientBase
|
||||||
from ..locations import BoundLocation, Location
|
from ..locations import BoundLocation, Location
|
||||||
from ..ssh_keys import BoundSSHKey, SSHKey
|
from ..ssh_keys import BoundSSHKey, SSHKey
|
||||||
|
|
@ -28,8 +35,18 @@ from .domain import (
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .._client import Client
|
from .._client import Client
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"BoundStorageBox",
|
||||||
|
"BoundStorageBoxSnapshot",
|
||||||
|
"BoundStorageBoxSubaccount",
|
||||||
|
"StorageBoxesPageResult",
|
||||||
|
"StorageBoxSnapshotsPageResult",
|
||||||
|
"StorageBoxSubaccountsPageResult",
|
||||||
|
"StorageBoxesClient",
|
||||||
|
]
|
||||||
|
|
||||||
class BoundStorageBox(BoundModelBase, StorageBox):
|
|
||||||
|
class BoundStorageBox(BoundModelBase[StorageBox], StorageBox):
|
||||||
_client: StorageBoxesClient
|
_client: StorageBoxesClient
|
||||||
|
|
||||||
model = StorageBox
|
model = StorageBox
|
||||||
|
|
@ -67,20 +84,20 @@ class BoundStorageBox(BoundModelBase, StorageBox):
|
||||||
def get_actions_list(
|
def get_actions_list(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
page: int | None = None,
|
page: int | None = None,
|
||||||
per_page: int | None = None,
|
per_page: int | None = None,
|
||||||
) -> ActionsPageResult:
|
) -> 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
|
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 status: Filter the Actions by status.
|
||||||
:param sort: Sort resources by field and direction.
|
:param sort: Sort Actions by field and direction.
|
||||||
:param page: Page number to return.
|
:param page: Page number to get.
|
||||||
:param per_page: Maximum number of entries returned per page.
|
:param per_page: Maximum number of Actions returned per page.
|
||||||
|
|
||||||
Experimental:
|
Experimental:
|
||||||
Storage Box support is experimental, breaking changes may occur within minor releases.
|
Storage Box support is experimental, breaking changes may occur within minor releases.
|
||||||
|
|
@ -96,8 +113,8 @@ class BoundStorageBox(BoundModelBase, StorageBox):
|
||||||
def get_actions(
|
def get_actions(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
) -> list[BoundAction]:
|
) -> list[BoundAction]:
|
||||||
"""
|
"""
|
||||||
Returns all Actions for a Storage Box.
|
Returns all Actions for a Storage Box.
|
||||||
|
|
@ -322,7 +339,7 @@ class BoundStorageBox(BoundModelBase, StorageBox):
|
||||||
def get_snapshot_by_name(
|
def get_snapshot_by_name(
|
||||||
self,
|
self,
|
||||||
name: str,
|
name: str,
|
||||||
) -> BoundStorageBoxSnapshot:
|
) -> BoundStorageBoxSnapshot | None:
|
||||||
"""
|
"""
|
||||||
Returns a single Snapshot from a Storage Box.
|
Returns a single Snapshot from a Storage Box.
|
||||||
|
|
||||||
|
|
@ -438,7 +455,7 @@ class BoundStorageBox(BoundModelBase, StorageBox):
|
||||||
def get_subaccount_by_username(
|
def get_subaccount_by_username(
|
||||||
self,
|
self,
|
||||||
username: str,
|
username: str,
|
||||||
) -> BoundStorageBoxSubaccount:
|
) -> BoundStorageBoxSubaccount | None:
|
||||||
"""
|
"""
|
||||||
Returns a single Subaccount from a Storage Box.
|
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
|
_client: StorageBoxesClient
|
||||||
|
|
||||||
model = StorageBoxSnapshot
|
model = StorageBoxSnapshot
|
||||||
|
|
@ -561,6 +578,8 @@ class BoundStorageBoxSnapshot(BoundModelBase, StorageBoxSnapshot):
|
||||||
super().__init__(client, data, complete)
|
super().__init__(client, data, complete)
|
||||||
|
|
||||||
def _get_self(self) -> BoundStorageBoxSnapshot:
|
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(
|
return self._client.get_snapshot_by_id(
|
||||||
self.data_model.storage_box,
|
self.data_model.storage_box,
|
||||||
self.data_model.id,
|
self.data_model.id,
|
||||||
|
|
@ -603,7 +622,9 @@ class BoundStorageBoxSnapshot(BoundModelBase, StorageBoxSnapshot):
|
||||||
return self._client.delete_snapshot(self)
|
return self._client.delete_snapshot(self)
|
||||||
|
|
||||||
|
|
||||||
class BoundStorageBoxSubaccount(BoundModelBase, StorageBoxSubaccount):
|
class BoundStorageBoxSubaccount(
|
||||||
|
BoundModelBase[StorageBoxSubaccount], StorageBoxSubaccount
|
||||||
|
):
|
||||||
_client: StorageBoxesClient
|
_client: StorageBoxesClient
|
||||||
|
|
||||||
model = StorageBoxSubaccount
|
model = StorageBoxSubaccount
|
||||||
|
|
@ -627,6 +648,8 @@ class BoundStorageBoxSubaccount(BoundModelBase, StorageBoxSubaccount):
|
||||||
super().__init__(client, data, complete)
|
super().__init__(client, data, complete)
|
||||||
|
|
||||||
def _get_self(self) -> BoundStorageBoxSubaccount:
|
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(
|
return self._client.get_subaccount_by_id(
|
||||||
self.data_model.storage_box,
|
self.data_model.storage_box,
|
||||||
self.data_model.id,
|
self.data_model.id,
|
||||||
|
|
@ -737,7 +760,10 @@ class StorageBoxSubaccountsPageResult(NamedTuple):
|
||||||
meta: Meta
|
meta: Meta
|
||||||
|
|
||||||
|
|
||||||
class StorageBoxesClient(ResourceClientBase):
|
class StorageBoxesClient(
|
||||||
|
ResourceClientBaseActionsMixin,
|
||||||
|
ResourceClientBase,
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
A client for the Storage Boxes API.
|
A client for the Storage Boxes API.
|
||||||
|
|
||||||
|
|
@ -1006,58 +1032,46 @@ class StorageBoxesClient(ResourceClientBase):
|
||||||
self,
|
self,
|
||||||
storage_box: StorageBox | BoundStorageBox,
|
storage_box: StorageBox | BoundStorageBox,
|
||||||
*,
|
*,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
page: int | None = None,
|
page: int | None = None,
|
||||||
per_page: int | None = None,
|
per_page: int | None = None,
|
||||||
) -> ActionsPageResult:
|
) -> 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
|
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 status: Filter the Actions by status.
|
||||||
:param sort: Sort resources by field and direction.
|
:param sort: Sort Actions by field and direction.
|
||||||
:param page: Page number to return.
|
:param page: Page number to get.
|
||||||
:param per_page: Maximum number of entries returned per page.
|
:param per_page: Maximum number of Actions returned per page.
|
||||||
|
|
||||||
Experimental:
|
Experimental:
|
||||||
Storage Box support is experimental, breaking changes may occur within minor releases.
|
Storage Box support is experimental, breaking changes may occur within minor releases.
|
||||||
"""
|
"""
|
||||||
params: dict[str, Any] = {}
|
return self._get_actions_list(
|
||||||
if status is not None:
|
f"{self._base_url}/{storage_box.id}",
|
||||||
params["status"] = status
|
status=status,
|
||||||
if sort is not None:
|
sort=sort,
|
||||||
params["sort"] = sort
|
page=page,
|
||||||
if page is not None:
|
per_page=per_page,
|
||||||
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),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_actions(
|
def get_actions(
|
||||||
self,
|
self,
|
||||||
storage_box: StorageBox | BoundStorageBox,
|
storage_box: StorageBox | BoundStorageBox,
|
||||||
*,
|
*,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
) -> list[BoundAction]:
|
) -> list[BoundAction]:
|
||||||
"""
|
"""
|
||||||
Returns all Actions for a Storage Box.
|
Returns all Actions for a Storage Box.
|
||||||
|
|
||||||
See https://docs.hetzner.cloud/reference/hetzner#storage-box-actions-list-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 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 sort: Sort resources by field and direction.
|
||||||
|
|
||||||
|
|
@ -1279,7 +1293,7 @@ class StorageBoxesClient(ResourceClientBase):
|
||||||
self,
|
self,
|
||||||
storage_box: StorageBox | BoundStorageBox,
|
storage_box: StorageBox | BoundStorageBox,
|
||||||
name: str,
|
name: str,
|
||||||
) -> BoundStorageBoxSnapshot:
|
) -> BoundStorageBoxSnapshot | None:
|
||||||
"""
|
"""
|
||||||
Returns a single Snapshot from a Storage Box.
|
Returns a single Snapshot from a Storage Box.
|
||||||
|
|
||||||
|
|
@ -1500,7 +1514,7 @@ class StorageBoxesClient(ResourceClientBase):
|
||||||
self,
|
self,
|
||||||
storage_box: StorageBox | BoundStorageBox,
|
storage_box: StorageBox | BoundStorageBox,
|
||||||
username: str,
|
username: str,
|
||||||
) -> BoundStorageBoxSubaccount:
|
) -> BoundStorageBoxSubaccount | None:
|
||||||
"""
|
"""
|
||||||
Returns a single Subaccount from a Storage Box.
|
Returns a single Subaccount from a Storage Box.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, Any, Literal
|
from typing import TYPE_CHECKING, Any, Literal
|
||||||
|
|
||||||
try:
|
|
||||||
from dateutil.parser import isoparse
|
|
||||||
except ImportError:
|
|
||||||
isoparse = None
|
|
||||||
|
|
||||||
from ..actions import BoundAction
|
from ..actions import BoundAction
|
||||||
from ..core import BaseDomain, DomainIdentityMixin
|
from ..core import BaseDomain, DomainIdentityMixin
|
||||||
from ..locations import BoundLocation, Location
|
from ..locations import BoundLocation, Location
|
||||||
|
|
@ -19,6 +14,26 @@ if TYPE_CHECKING:
|
||||||
BoundStorageBoxSubaccount,
|
BoundStorageBoxSubaccount,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"StorageBox",
|
||||||
|
"StorageBoxAccessSettings",
|
||||||
|
"StorageBoxStats",
|
||||||
|
"StorageBoxSnapshotPlan",
|
||||||
|
"CreateStorageBoxResponse",
|
||||||
|
"DeleteStorageBoxResponse",
|
||||||
|
"StorageBoxFoldersResponse",
|
||||||
|
"StorageBoxSnapshot",
|
||||||
|
"StorageBoxSnapshotStats",
|
||||||
|
"CreateStorageBoxSnapshotResponse",
|
||||||
|
"DeleteStorageBoxSnapshotResponse",
|
||||||
|
"StorageBoxSubaccount",
|
||||||
|
"StorageBoxSubaccountAccessSettings",
|
||||||
|
"CreateStorageBoxSubaccountResponse",
|
||||||
|
"DeleteStorageBoxSubaccountResponse",
|
||||||
|
"StorageBoxStatus",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
StorageBoxStatus = Literal[
|
StorageBoxStatus = Literal[
|
||||||
"active",
|
"active",
|
||||||
"initializing",
|
"initializing",
|
||||||
|
|
@ -85,7 +100,7 @@ class StorageBox(BaseDomain, DomainIdentityMixin):
|
||||||
self.access_settings = access_settings
|
self.access_settings = access_settings
|
||||||
self.stats = stats
|
self.stats = stats
|
||||||
self.status = status
|
self.status = status
|
||||||
self.created = isoparse(created) if created else None
|
self.created = self._parse_datetime(created)
|
||||||
|
|
||||||
|
|
||||||
class StorageBoxAccessSettings(BaseDomain):
|
class StorageBoxAccessSettings(BaseDomain):
|
||||||
|
|
@ -288,7 +303,7 @@ class StorageBoxSnapshot(BaseDomain, DomainIdentityMixin):
|
||||||
self.is_automatic = is_automatic
|
self.is_automatic = is_automatic
|
||||||
self.labels = labels
|
self.labels = labels
|
||||||
self.storage_box = storage_box
|
self.storage_box = storage_box
|
||||||
self.created = isoparse(created) if created else None
|
self.created = self._parse_datetime(created)
|
||||||
self.stats = stats
|
self.stats = stats
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -389,7 +404,7 @@ class StorageBoxSubaccount(BaseDomain, DomainIdentityMixin):
|
||||||
self.access_settings = access_settings
|
self.access_settings = access_settings
|
||||||
self.labels = labels
|
self.labels = labels
|
||||||
self.storage_box = storage_box
|
self.storage_box = storage_box
|
||||||
self.created = isoparse(created) if created else None
|
self.created = self._parse_datetime(created)
|
||||||
|
|
||||||
|
|
||||||
class StorageBoxSubaccountAccessSettings(BaseDomain):
|
class StorageBoxSubaccountAccessSettings(BaseDomain):
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from .client import BoundVolume, VolumesClient, VolumesPageResult
|
from .client import BoundVolume, VolumesClient, VolumesPageResult
|
||||||
from .domain import CreateVolumeResponse, Volume
|
from .domain import CreateVolumeResponse, Volume, VolumeProtection
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"BoundVolume",
|
"BoundVolume",
|
||||||
"CreateVolumeResponse",
|
"CreateVolumeResponse",
|
||||||
"Volume",
|
"Volume",
|
||||||
|
"VolumeProtection",
|
||||||
"VolumesClient",
|
"VolumesClient",
|
||||||
"VolumesPageResult",
|
"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 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 ..core import BoundModelBase, Meta, ResourceClientBase
|
||||||
from ..locations import BoundLocation
|
from ..locations import BoundLocation
|
||||||
from .domain import CreateVolumeResponse, Volume
|
from .domain import CreateVolumeResponse, Volume
|
||||||
|
|
@ -13,12 +20,24 @@ if TYPE_CHECKING:
|
||||||
from ..servers import BoundServer, Server
|
from ..servers import BoundServer, Server
|
||||||
|
|
||||||
|
|
||||||
class BoundVolume(BoundModelBase, Volume):
|
__all__ = [
|
||||||
|
"BoundVolume",
|
||||||
|
"VolumesPageResult",
|
||||||
|
"VolumesClient",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class BoundVolume(BoundModelBase[Volume], Volume):
|
||||||
_client: VolumesClient
|
_client: VolumesClient
|
||||||
|
|
||||||
model = Volume
|
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")
|
location = data.get("location")
|
||||||
if location is not None:
|
if location is not None:
|
||||||
data["location"] = BoundLocation(client._parent.locations, location)
|
data["location"] = BoundLocation(client._parent.locations, location)
|
||||||
|
|
@ -35,22 +54,18 @@ class BoundVolume(BoundModelBase, Volume):
|
||||||
|
|
||||||
def get_actions_list(
|
def get_actions_list(
|
||||||
self,
|
self,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
page: int | None = None,
|
page: int | None = None,
|
||||||
per_page: int | None = None,
|
per_page: int | None = None,
|
||||||
) -> ActionsPageResult:
|
) -> ActionsPageResult:
|
||||||
"""Returns all action objects for a volume.
|
"""
|
||||||
|
Returns a paginated list of Actions for a Volume.
|
||||||
|
|
||||||
:param status: List[str] (optional)
|
:param status: Filter the Actions by status.
|
||||||
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
:param sort: Sort Actions by field and direction.
|
||||||
:param sort: List[str] (optional)
|
:param page: Page number to get.
|
||||||
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 per_page: Maximum number of Actions returned per page.
|
||||||
: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>`)
|
|
||||||
"""
|
"""
|
||||||
return self._client.get_actions_list(
|
return self._client.get_actions_list(
|
||||||
self, status=status, sort=sort, page=page, per_page=per_page
|
self, status=status, sort=sort, page=page, per_page=per_page
|
||||||
|
|
@ -58,16 +73,14 @@ class BoundVolume(BoundModelBase, Volume):
|
||||||
|
|
||||||
def get_actions(
|
def get_actions(
|
||||||
self,
|
self,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
) -> list[BoundAction]:
|
) -> list[BoundAction]:
|
||||||
"""Returns all action objects for a volume.
|
"""
|
||||||
|
Returns all Actions for a Volume.
|
||||||
|
|
||||||
:param status: List[str] (optional)
|
:param status: Filter the Actions by status.
|
||||||
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
:param sort: Sort Actions by field and direction.
|
||||||
: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>`]
|
|
||||||
"""
|
"""
|
||||||
return self._client.get_actions(self, status=status, sort=sort)
|
return self._client.get_actions(self, status=status, sort=sort)
|
||||||
|
|
||||||
|
|
@ -137,7 +150,10 @@ class VolumesPageResult(NamedTuple):
|
||||||
meta: Meta
|
meta: Meta
|
||||||
|
|
||||||
|
|
||||||
class VolumesClient(ResourceClientBase):
|
class VolumesClient(
|
||||||
|
ResourceClientBaseActionsMixin,
|
||||||
|
ResourceClientBase,
|
||||||
|
):
|
||||||
_base_url = "/volumes"
|
_base_url = "/volumes"
|
||||||
|
|
||||||
actions: ResourceActionsClient
|
actions: ResourceActionsClient
|
||||||
|
|
@ -288,59 +304,40 @@ class VolumesClient(ResourceClientBase):
|
||||||
def get_actions_list(
|
def get_actions_list(
|
||||||
self,
|
self,
|
||||||
volume: Volume | BoundVolume,
|
volume: Volume | BoundVolume,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
page: int | None = None,
|
page: int | None = None,
|
||||||
per_page: int | None = None,
|
per_page: int | None = None,
|
||||||
) -> ActionsPageResult:
|
) -> 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] = {}
|
Returns a paginated list of Actions for a Volume.
|
||||||
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(
|
:param volume: Volume to get the Actions for.
|
||||||
url=f"{self._base_url}/{volume.id}/actions",
|
:param status: Filter the Actions by status.
|
||||||
method="GET",
|
:param sort: Sort Actions by field and direction.
|
||||||
params=params,
|
: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(
|
def get_actions(
|
||||||
self,
|
self,
|
||||||
volume: Volume | BoundVolume,
|
volume: Volume | BoundVolume,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
) -> list[BoundAction]:
|
) -> 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 volume: Volume to get the Actions for.
|
||||||
:param status: List[str] (optional)
|
:param status: Filter the Actions by status.
|
||||||
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
:param sort: Sort Actions by field and direction.
|
||||||
: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>`]
|
|
||||||
"""
|
"""
|
||||||
return self._iter_pages(
|
return self._iter_pages(
|
||||||
self.get_actions_list,
|
self.get_actions_list,
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,6 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING, TypedDict
|
||||||
|
|
||||||
try:
|
|
||||||
from dateutil.parser import isoparse
|
|
||||||
except ImportError:
|
|
||||||
isoparse = None
|
|
||||||
|
|
||||||
from ..core import BaseDomain, DomainIdentityMixin
|
from ..core import BaseDomain, DomainIdentityMixin
|
||||||
|
|
||||||
|
|
@ -15,6 +10,12 @@ if TYPE_CHECKING:
|
||||||
from ..servers import BoundServer, Server
|
from ..servers import BoundServer, Server
|
||||||
from .client import BoundVolume
|
from .client import BoundVolume
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"Volume",
|
||||||
|
"VolumeProtection",
|
||||||
|
"CreateVolumeResponse",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class Volume(BaseDomain, DomainIdentityMixin):
|
class Volume(BaseDomain, DomainIdentityMixin):
|
||||||
"""Volume Domain
|
"""Volume Domain
|
||||||
|
|
@ -73,14 +74,14 @@ class Volume(BaseDomain, DomainIdentityMixin):
|
||||||
size: int | None = None,
|
size: int | None = None,
|
||||||
linux_device: str | None = None,
|
linux_device: str | None = None,
|
||||||
format: str | None = None,
|
format: str | None = None,
|
||||||
protection: dict | None = None,
|
protection: VolumeProtection | None = None,
|
||||||
labels: dict[str, str] | None = None,
|
labels: dict[str, str] | None = None,
|
||||||
status: str | None = None,
|
status: str | None = None,
|
||||||
):
|
):
|
||||||
self.id = id
|
self.id = id
|
||||||
self.name = name
|
self.name = name
|
||||||
self.server = server
|
self.server = server
|
||||||
self.created = isoparse(created) if created else None
|
self.created = self._parse_datetime(created)
|
||||||
self.location = location
|
self.location = location
|
||||||
self.size = size
|
self.size = size
|
||||||
self.linux_device = linux_device
|
self.linux_device = linux_device
|
||||||
|
|
@ -90,6 +91,10 @@ class Volume(BaseDomain, DomainIdentityMixin):
|
||||||
self.status = status
|
self.status = status
|
||||||
|
|
||||||
|
|
||||||
|
class VolumeProtection(TypedDict):
|
||||||
|
delete: bool
|
||||||
|
|
||||||
|
|
||||||
class CreateVolumeResponse(BaseDomain):
|
class CreateVolumeResponse(BaseDomain):
|
||||||
"""Create Volume Response Domain
|
"""Create Volume Response Domain
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,16 +3,26 @@ from __future__ import annotations
|
||||||
from .client import (
|
from .client import (
|
||||||
BoundZone,
|
BoundZone,
|
||||||
BoundZoneRRSet,
|
BoundZoneRRSet,
|
||||||
|
ZoneRRSetsPageResult,
|
||||||
ZonesClient,
|
ZonesClient,
|
||||||
ZonesPageResult,
|
ZonesPageResult,
|
||||||
)
|
)
|
||||||
from .domain import (
|
from .domain import (
|
||||||
CreateZoneResponse,
|
CreateZoneResponse,
|
||||||
|
CreateZoneRRSetResponse,
|
||||||
|
DeleteZoneResponse,
|
||||||
|
DeleteZoneRRSetResponse,
|
||||||
|
ExportZonefileResponse,
|
||||||
Zone,
|
Zone,
|
||||||
ZoneAuthoritativeNameservers,
|
ZoneAuthoritativeNameservers,
|
||||||
|
ZoneMode,
|
||||||
ZonePrimaryNameserver,
|
ZonePrimaryNameserver,
|
||||||
|
ZoneProtection,
|
||||||
ZoneRecord,
|
ZoneRecord,
|
||||||
|
ZoneRegistrar,
|
||||||
ZoneRRSet,
|
ZoneRRSet,
|
||||||
|
ZoneRRSetProtection,
|
||||||
|
ZoneStatus,
|
||||||
)
|
)
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
|
|
@ -26,4 +36,14 @@ __all__ = [
|
||||||
"ZoneRRSet",
|
"ZoneRRSet",
|
||||||
"ZonesClient",
|
"ZonesClient",
|
||||||
"ZonesPageResult",
|
"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 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 ..core import BoundModelBase, Meta, ResourceClientBase
|
||||||
from .domain import (
|
from .domain import (
|
||||||
CreateZoneResponse,
|
CreateZoneResponse,
|
||||||
|
|
@ -22,8 +29,16 @@ from .domain import (
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .._client import Client
|
from .._client import Client
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"BoundZone",
|
||||||
|
"BoundZoneRRSet",
|
||||||
|
"ZonesPageResult",
|
||||||
|
"ZoneRRSetsPageResult",
|
||||||
|
"ZonesClient",
|
||||||
|
]
|
||||||
|
|
||||||
class BoundZone(BoundModelBase, Zone):
|
|
||||||
|
class BoundZone(BoundModelBase[Zone], Zone):
|
||||||
_client: ZonesClient
|
_client: ZonesClient
|
||||||
|
|
||||||
model = Zone
|
model = Zone
|
||||||
|
|
@ -81,20 +96,20 @@ class BoundZone(BoundModelBase, Zone):
|
||||||
def get_actions_list(
|
def get_actions_list(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
page: int | None = None,
|
page: int | None = None,
|
||||||
per_page: int | None = None,
|
per_page: int | None = None,
|
||||||
) -> ActionsPageResult:
|
) -> 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
|
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 status: Filter the Actions by status.
|
||||||
:param sort: Sort resources by field and direction.
|
:param sort: Sort Actions by field and direction.
|
||||||
:param page: Page number to return.
|
:param page: Page number to get.
|
||||||
:param per_page: Maximum number of entries returned per page.
|
:param per_page: Maximum number of Actions returned per page.
|
||||||
"""
|
"""
|
||||||
return self._client.get_actions_list(
|
return self._client.get_actions_list(
|
||||||
self,
|
self,
|
||||||
|
|
@ -107,16 +122,16 @@ class BoundZone(BoundModelBase, Zone):
|
||||||
def get_actions(
|
def get_actions(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
) -> list[BoundAction]:
|
) -> list[BoundAction]:
|
||||||
"""
|
"""
|
||||||
Returns all Actions for the Zone.
|
Returns all Actions for a Zone.
|
||||||
|
|
||||||
See https://docs.hetzner.cloud/reference/cloud#zones-list-zones
|
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 status: Filter the Actions by status.
|
||||||
:param sort: Sort resources by field and direction.
|
:param sort: Sort Actions by field and direction.
|
||||||
"""
|
"""
|
||||||
return self._client.get_actions(
|
return self._client.get_actions(
|
||||||
self,
|
self,
|
||||||
|
|
@ -367,7 +382,7 @@ class BoundZone(BoundModelBase, Zone):
|
||||||
"""
|
"""
|
||||||
Updates records in a 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 rrset: RRSet to update.
|
:param rrset: RRSet to update.
|
||||||
:param records: Records to update in the RRSet.
|
: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)
|
return self._client.set_rrset_records(rrset=rrset, records=records)
|
||||||
|
|
||||||
|
|
||||||
class BoundZoneRRSet(BoundModelBase, ZoneRRSet):
|
class BoundZoneRRSet(BoundModelBase[ZoneRRSet], ZoneRRSet):
|
||||||
_client: ZonesClient
|
_client: ZonesClient
|
||||||
|
|
||||||
model = ZoneRRSet
|
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")
|
raw = data.get("zone")
|
||||||
if raw is not None:
|
if raw is not None:
|
||||||
data["zone"] = BoundZone(client, data={"id": raw}, complete=False)
|
data["zone"] = BoundZone(client, data={"id": raw}, complete=False)
|
||||||
|
|
@ -422,6 +442,8 @@ class BoundZoneRRSet(BoundModelBase, ZoneRRSet):
|
||||||
super().__init__(client, data, complete)
|
super().__init__(client, data, complete)
|
||||||
|
|
||||||
def _get_self(self) -> BoundZoneRRSet:
|
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(
|
return self._client.get_rrset(
|
||||||
self.data_model.zone,
|
self.data_model.zone,
|
||||||
self.data_model.name,
|
self.data_model.name,
|
||||||
|
|
@ -501,7 +523,7 @@ class BoundZoneRRSet(BoundModelBase, ZoneRRSet):
|
||||||
"""
|
"""
|
||||||
Updates records in a 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.
|
:param records: Records to update in the RRSet.
|
||||||
"""
|
"""
|
||||||
|
|
@ -544,7 +566,10 @@ class ZoneRRSetsPageResult(NamedTuple):
|
||||||
meta: Meta
|
meta: Meta
|
||||||
|
|
||||||
|
|
||||||
class ZonesClient(ResourceClientBase):
|
class ZonesClient(
|
||||||
|
ResourceClientBaseActionsMixin,
|
||||||
|
ResourceClientBase,
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
ZoneClient is a client for the Zone (DNS) API.
|
ZoneClient is a client for the Zone (DNS) API.
|
||||||
|
|
||||||
|
|
@ -767,57 +792,45 @@ class ZonesClient(ResourceClientBase):
|
||||||
self,
|
self,
|
||||||
zone: Zone | BoundZone,
|
zone: Zone | BoundZone,
|
||||||
*,
|
*,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
page: int | None = None,
|
page: int | None = None,
|
||||||
per_page: int | None = None,
|
per_page: int | None = None,
|
||||||
) -> ActionsPageResult:
|
) -> 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
|
See https://docs.hetzner.cloud/reference/cloud#zones-list-zones
|
||||||
|
|
||||||
:param zone: Zone to fetch the Actions from.
|
:param zone: Zone to get the Actions for.
|
||||||
:param status: Filter the actions by status. The response will only contain actions matching the specified statuses.
|
:param status: Filter the Actions by status.
|
||||||
:param sort: Sort resources by field and direction.
|
:param sort: Sort Actions by field and direction.
|
||||||
:param page: Page number to return.
|
:param page: Page number to get.
|
||||||
:param per_page: Maximum number of entries returned per page.
|
:param per_page: Maximum number of Actions returned per page.
|
||||||
"""
|
"""
|
||||||
params: dict[str, Any] = {}
|
return self._get_actions_list(
|
||||||
if status is not None:
|
f"{self._base_url}/{zone.id_or_name}",
|
||||||
params["status"] = status
|
status=status,
|
||||||
if sort is not None:
|
sort=sort,
|
||||||
params["sort"] = sort
|
page=page,
|
||||||
if page is not None:
|
per_page=per_page,
|
||||||
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),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_actions(
|
def get_actions(
|
||||||
self,
|
self,
|
||||||
zone: Zone | BoundZone,
|
zone: Zone | BoundZone,
|
||||||
*,
|
*,
|
||||||
status: list[str] | None = None,
|
status: list[ActionStatus] | None = None,
|
||||||
sort: list[str] | None = None,
|
sort: list[ActionSort] | None = None,
|
||||||
) -> list[BoundAction]:
|
) -> list[BoundAction]:
|
||||||
"""
|
"""
|
||||||
Returns all Actions for a Zone.
|
Returns all Actions for a Zone.
|
||||||
|
|
||||||
See https://docs.hetzner.cloud/reference/cloud#zones-list-zones
|
See https://docs.hetzner.cloud/reference/cloud#zones-list-zones
|
||||||
|
|
||||||
:param zone: Zone to fetch the Actions from.
|
:param zone: Zone to get the Actions for.
|
||||||
:param status: Filter the actions by status. The response will only contain actions matching the specified statuses.
|
:param status: Filter the Actions by status.
|
||||||
:param sort: Sort resources by field and direction.
|
:param sort: Sort Actions by field and direction.
|
||||||
"""
|
"""
|
||||||
return self._iter_pages(
|
return self._iter_pages(
|
||||||
self.get_actions_list,
|
self.get_actions_list,
|
||||||
|
|
@ -1208,7 +1221,7 @@ class ZonesClient(ResourceClientBase):
|
||||||
"""
|
"""
|
||||||
Updates records in a 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 rrset: RRSet to update.
|
:param rrset: RRSet to update.
|
||||||
:param records: Records to update in the RRSet.
|
:param records: Records to update in the RRSet.
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,6 @@ from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, Any, Literal, TypedDict
|
from typing import TYPE_CHECKING, Any, Literal, TypedDict
|
||||||
|
|
||||||
try:
|
|
||||||
from dateutil.parser import isoparse
|
|
||||||
except ImportError:
|
|
||||||
isoparse = None
|
|
||||||
|
|
||||||
from ..core import BaseDomain, DomainIdentityMixin
|
from ..core import BaseDomain, DomainIdentityMixin
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
|
@ -14,6 +9,24 @@ if TYPE_CHECKING:
|
||||||
from .client import BoundZone, BoundZoneRRSet
|
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"]
|
ZoneMode = Literal["primary", "secondary"]
|
||||||
ZoneStatus = Literal["ok", "updating", "error"]
|
ZoneStatus = Literal["ok", "updating", "error"]
|
||||||
ZoneRegistrar = Literal["hetzner", "other", "unknown"]
|
ZoneRegistrar = Literal["hetzner", "other", "unknown"]
|
||||||
|
|
@ -81,7 +94,7 @@ class Zone(BaseDomain, DomainIdentityMixin):
|
||||||
):
|
):
|
||||||
self.id = id
|
self.id = id
|
||||||
self.name = name
|
self.name = name
|
||||||
self.created = isoparse(created) if created else None
|
self.created = self._parse_datetime(created)
|
||||||
self.mode = mode
|
self.mode = mode
|
||||||
self.ttl = ttl
|
self.ttl = ttl
|
||||||
self.labels = labels
|
self.labels = labels
|
||||||
|
|
@ -188,11 +201,7 @@ class ZoneAuthoritativeNameservers(BaseDomain):
|
||||||
):
|
):
|
||||||
self.assigned = assigned
|
self.assigned = assigned
|
||||||
self.delegated = delegated
|
self.delegated = delegated
|
||||||
self.delegation_last_check = (
|
self.delegation_last_check = self._parse_datetime(delegation_last_check)
|
||||||
isoparse(delegation_last_check)
|
|
||||||
if delegation_last_check is not None
|
|
||||||
else None
|
|
||||||
)
|
|
||||||
self.delegation_status = delegation_status
|
self.delegation_status = delegation_status
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ from textwrap import dedent
|
||||||
logger = logging.getLogger("vendor")
|
logger = logging.getLogger("vendor")
|
||||||
|
|
||||||
HCLOUD_SOURCE_URL = "https://github.com/hetznercloud/hcloud-python"
|
HCLOUD_SOURCE_URL = "https://github.com/hetznercloud/hcloud-python"
|
||||||
HCLOUD_VERSION = "v2.12.0"
|
HCLOUD_VERSION = "v2.13.0"
|
||||||
HCLOUD_VENDOR_PATH = "plugins/module_utils/vendor/hcloud"
|
HCLOUD_VENDOR_PATH = "plugins/module_utils/vendor/hcloud"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue