mirror of
https://github.com/ansible-collections/hetzner.hcloud
synced 2024-12-04 17:49:16 +00:00
feat: vendor hcloud python dependency (#244)
* chore: ignore venv directories * chore: ignore integration test generated inventory * feat: vendor hcloud package * import https://github.com/hetznercloud/hcloud-python * use vendored hcloud in modules * update integration test requirements * make vendor script self contained * chore: add check-hcloud-vendor pre-commit hook * pin hcloud version to v.1.24.0 * move vendored __version__.py file to _version.py * update comment about galaxy-importer filename lint
This commit is contained in:
parent
5190535323
commit
8a6157e8b2
84 changed files with 8433 additions and 79 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1,3 +1,5 @@
|
||||||
|
.venv
|
||||||
|
venv
|
||||||
|
|
||||||
# Created by https://www.gitignore.io/api/git,linux,pydev,python,windows,pycharm+all,jupyternotebook,vim,webstorm,emacs,dotenv
|
# Created by https://www.gitignore.io/api/git,linux,pydev,python,windows,pycharm+all,jupyternotebook,vim,webstorm,emacs,dotenv
|
||||||
# Edit at https://www.gitignore.io/?templates=git,linux,pydev,python,windows,pycharm+all,jupyternotebook,vim,webstorm,emacs,dotenv
|
# Edit at https://www.gitignore.io/?templates=git,linux,pydev,python,windows,pycharm+all,jupyternotebook,vim,webstorm,emacs,dotenv
|
||||||
|
@ -55,7 +57,6 @@ flycheck_*.el
|
||||||
# network security
|
# network security
|
||||||
/network-security.data
|
/network-security.data
|
||||||
|
|
||||||
|
|
||||||
### Git ###
|
### Git ###
|
||||||
# Created by git for backups. To disable backups in Git:
|
# Created by git for backups. To disable backups in Git:
|
||||||
# $ git config --global mergetool.keepBackup false
|
# $ git config --global mergetool.keepBackup false
|
||||||
|
@ -387,3 +388,4 @@ $RECYCLE.BIN/
|
||||||
# End of https://www.gitignore.io/api/git,linux,pydev,python,windows,pycharm+all,jupyternotebook,vim,webstorm,emacs,dotenv
|
# End of https://www.gitignore.io/api/git,linux,pydev,python,windows,pycharm+all,jupyternotebook,vim,webstorm,emacs,dotenv
|
||||||
|
|
||||||
cloud-config-hcloud.ini
|
cloud-config-hcloud.ini
|
||||||
|
tests/integration/inventory
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
---
|
---
|
||||||
# See https://pre-commit.com for more information
|
# See https://pre-commit.com for more information
|
||||||
# See https://pre-commit.com/hooks.html for more hooks
|
# See https://pre-commit.com/hooks.html for more hooks
|
||||||
|
exclude: ^plugins/module_utils/vendor/hcloud/.*$
|
||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
rev: v4.4.0
|
rev: v4.4.0
|
||||||
|
@ -52,3 +53,11 @@ repos:
|
||||||
entry: antsibull-changelog lint
|
entry: antsibull-changelog lint
|
||||||
pass_filenames: false
|
pass_filenames: false
|
||||||
files: ^changelogs/.*$
|
files: ^changelogs/.*$
|
||||||
|
|
||||||
|
- id: check-hcloud-vendor
|
||||||
|
name: check hcloud vendor
|
||||||
|
description: Ensure the hcloud vendored files are in sync
|
||||||
|
language: python
|
||||||
|
entry: python3 scripts/vendor.py
|
||||||
|
pass_filenames: false
|
||||||
|
files: ^scripts/vendor.py$
|
||||||
|
|
9
Makefile
Normal file
9
Makefile
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
SHELL := bash
|
||||||
|
.PHONY: vendor clean
|
||||||
|
|
||||||
|
vendor:
|
||||||
|
python3 scripts/vendor.py
|
||||||
|
|
||||||
|
clean:
|
||||||
|
git clean -xdf \
|
||||||
|
-e tests/integration/cloud-config-hcloud.ini
|
12
changelogs/fragments/vendor-hcloud-python-dependency.yml
Normal file
12
changelogs/fragments/vendor-hcloud-python-dependency.yml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
release_summary: |
|
||||||
|
This release bundles the hcloud dependency in the collection, this allows us to ship
|
||||||
|
new features or bug fixes without having to release new major versions and require the
|
||||||
|
users to upgrade their version of the hcloud dependency.
|
||||||
|
minor_changes:
|
||||||
|
- Bundle hcloud python dependency inside the collection.
|
||||||
|
- >
|
||||||
|
python-dateutil >= 2.7.5 is now required by the collection. If you already have the
|
||||||
|
hcloud package installed, this dependency should also be installed.
|
||||||
|
- >
|
||||||
|
requests >= 2.20 is now required by the collection. If you already have the hcloud
|
||||||
|
package installed, this dependency should also be installed.
|
|
@ -17,7 +17,8 @@ options:
|
||||||
default: https://api.hetzner.cloud/v1
|
default: https://api.hetzner.cloud/v1
|
||||||
type: str
|
type: str
|
||||||
requirements:
|
requirements:
|
||||||
- hcloud-python >= 1.20.0
|
- python-dateutil >= 2.7.5
|
||||||
|
- requests >=2.20
|
||||||
seealso:
|
seealso:
|
||||||
- name: Documentation for Hetzner Cloud API
|
- name: Documentation for Hetzner Cloud API
|
||||||
description: Complete reference for the Hetzner Cloud API.
|
description: Complete reference for the Hetzner Cloud API.
|
||||||
|
|
|
@ -121,13 +121,11 @@ from ansible.errors import AnsibleError
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
from ansible.module_utils.common.text.converters import to_native
|
||||||
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
|
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
|
||||||
from ansible.release import __version__
|
from ansible.release import __version__
|
||||||
|
from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import (
|
||||||
try:
|
HAS_DATEUTIL,
|
||||||
from hcloud import APIException, hcloud
|
HAS_REQUESTS,
|
||||||
|
)
|
||||||
HAS_HCLOUD = True
|
from ansible_collections.hetzner.hcloud.plugins.module_utils.vendor import hcloud
|
||||||
except ImportError:
|
|
||||||
HAS_HCLOUD = False
|
|
||||||
|
|
||||||
|
|
||||||
class InventoryModule(BaseInventoryPlugin, Constructable):
|
class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||||
|
@ -159,7 +157,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||||
# We test the API Token against the location API, because this is the API with the smallest result
|
# We test the API Token against the location API, because this is the API with the smallest result
|
||||||
# and not controllable from the customer.
|
# and not controllable from the customer.
|
||||||
self.client.locations.get_all()
|
self.client.locations.get_all()
|
||||||
except APIException:
|
except hcloud.APIException:
|
||||||
raise AnsibleError("Invalid Hetzner Cloud API Token.")
|
raise AnsibleError("Invalid Hetzner Cloud API Token.")
|
||||||
|
|
||||||
def _get_servers(self):
|
def _get_servers(self):
|
||||||
|
@ -177,7 +175,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||||
self.network = self.client.networks.get_by_name(network)
|
self.network = self.client.networks.get_by_name(network)
|
||||||
if self.network is None:
|
if self.network is None:
|
||||||
self.network = self.client.networks.get_by_id(network)
|
self.network = self.client.networks.get_by_id(network)
|
||||||
except APIException:
|
except hcloud.APIException:
|
||||||
raise AnsibleError("The given network is not found.")
|
raise AnsibleError("The given network is not found.")
|
||||||
|
|
||||||
tmp = []
|
tmp = []
|
||||||
|
@ -322,8 +320,10 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||||
def parse(self, inventory, loader, path, cache=True):
|
def parse(self, inventory, loader, path, cache=True):
|
||||||
super().parse(inventory, loader, path, cache)
|
super().parse(inventory, loader, path, cache)
|
||||||
|
|
||||||
if not HAS_HCLOUD:
|
if not HAS_REQUESTS:
|
||||||
raise AnsibleError("The Hetzner Cloud dynamic inventory plugin requires hcloud-python.")
|
raise AnsibleError("The Hetzner Cloud dynamic inventory plugin requires requests.")
|
||||||
|
if not HAS_DATEUTIL:
|
||||||
|
raise AnsibleError("The Hetzner Cloud dynamic inventory plugin requires python-dateutil.")
|
||||||
|
|
||||||
self._read_config_data(path)
|
self._read_config_data(path)
|
||||||
self._configure_hcloud_client()
|
self._configure_hcloud_client()
|
||||||
|
|
|
@ -5,13 +5,20 @@
|
||||||
|
|
||||||
from ansible.module_utils.ansible_release import __version__
|
from ansible.module_utils.ansible_release import __version__
|
||||||
from ansible.module_utils.basic import env_fallback, missing_required_lib
|
from ansible.module_utils.basic import env_fallback, missing_required_lib
|
||||||
|
from ansible_collections.hetzner.hcloud.plugins.module_utils.vendor import hcloud
|
||||||
|
|
||||||
|
HAS_REQUESTS = True
|
||||||
|
HAS_DATEUTIL = True
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import hcloud
|
import requests # pylint: disable=unused-import
|
||||||
|
|
||||||
HAS_HCLOUD = True
|
|
||||||
except ImportError:
|
except ImportError:
|
||||||
HAS_HCLOUD = False
|
HAS_REQUESTS = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
import dateutil # pylint: disable=unused-import
|
||||||
|
except ImportError:
|
||||||
|
HAS_DATEUTIL = False
|
||||||
|
|
||||||
|
|
||||||
class Hcloud:
|
class Hcloud:
|
||||||
|
@ -19,8 +26,10 @@ class Hcloud:
|
||||||
self.module = module
|
self.module = module
|
||||||
self.represent = represent
|
self.represent = represent
|
||||||
self.result = {"changed": False, self.represent: None}
|
self.result = {"changed": False, self.represent: None}
|
||||||
if not HAS_HCLOUD:
|
if not HAS_REQUESTS:
|
||||||
module.fail_json(msg=missing_required_lib("hcloud-python"))
|
module.fail_json(msg=missing_required_lib("requests"))
|
||||||
|
if not HAS_DATEUTIL:
|
||||||
|
module.fail_json(msg=missing_required_lib("python-dateutil"))
|
||||||
self._build_client()
|
self._build_client()
|
||||||
|
|
||||||
def _build_client(self):
|
def _build_client(self):
|
||||||
|
|
0
plugins/module_utils/vendor/__init__.py
vendored
Normal file
0
plugins/module_utils/vendor/__init__.py
vendored
Normal file
2
plugins/module_utils/vendor/hcloud/__init__.py
vendored
Normal file
2
plugins/module_utils/vendor/hcloud/__init__.py
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
from ._exceptions import APIException, HCloudException # noqa
|
||||||
|
from .hcloud import Client # noqa
|
14
plugins/module_utils/vendor/hcloud/_exceptions.py
vendored
Normal file
14
plugins/module_utils/vendor/hcloud/_exceptions.py
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
class HCloudException(Exception):
|
||||||
|
"""There was an error while using the hcloud library"""
|
||||||
|
|
||||||
|
|
||||||
|
class APIException(HCloudException):
|
||||||
|
"""There was an error while performing an API Request"""
|
||||||
|
|
||||||
|
def __init__(self, code, message, details):
|
||||||
|
self.code = code
|
||||||
|
self.message = message
|
||||||
|
self.details = details
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.message
|
1
plugins/module_utils/vendor/hcloud/_version.py
vendored
Normal file
1
plugins/module_utils/vendor/hcloud/_version.py
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
VERSION = "1.24.0" # x-release-please-version
|
0
plugins/module_utils/vendor/hcloud/actions/__init__.py
vendored
Normal file
0
plugins/module_utils/vendor/hcloud/actions/__init__.py
vendored
Normal file
90
plugins/module_utils/vendor/hcloud/actions/client.py
vendored
Normal file
90
plugins/module_utils/vendor/hcloud/actions/client.py
vendored
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
import time
|
||||||
|
|
||||||
|
from ..core.client import BoundModelBase, ClientEntityBase
|
||||||
|
from .domain import Action, ActionFailedException, ActionTimeoutException
|
||||||
|
|
||||||
|
|
||||||
|
class BoundAction(BoundModelBase):
|
||||||
|
model = Action
|
||||||
|
|
||||||
|
def wait_until_finished(self, max_retries=100):
|
||||||
|
"""Wait until the specific action has status="finished" (set Client.poll_interval to specify a delay between checks)
|
||||||
|
|
||||||
|
:param max_retries: int
|
||||||
|
Specify how many retries will be performed before an ActionTimeoutException will be raised
|
||||||
|
:raises: ActionFailedException when action is finished with status=="error"
|
||||||
|
:raises: ActionTimeoutException when Action is still in "running" state after max_retries reloads.
|
||||||
|
"""
|
||||||
|
while self.status == Action.STATUS_RUNNING:
|
||||||
|
if max_retries > 0:
|
||||||
|
self.reload()
|
||||||
|
time.sleep(self._client._client.poll_interval)
|
||||||
|
max_retries = max_retries - 1
|
||||||
|
else:
|
||||||
|
raise ActionTimeoutException(action=self)
|
||||||
|
|
||||||
|
if self.status == Action.STATUS_ERROR:
|
||||||
|
raise ActionFailedException(action=self)
|
||||||
|
|
||||||
|
|
||||||
|
class ActionsClient(ClientEntityBase):
|
||||||
|
results_list_attribute_name = "actions"
|
||||||
|
|
||||||
|
def get_by_id(self, id):
|
||||||
|
# type: (int) -> BoundAction
|
||||||
|
"""Get a specific action by its ID.
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
|
||||||
|
response = self._client.request(url=f"/actions/{id}", method="GET")
|
||||||
|
return BoundAction(self, response["action"])
|
||||||
|
|
||||||
|
def get_list(
|
||||||
|
self,
|
||||||
|
status=None, # type: Optional[List[str]]
|
||||||
|
sort=None, # type: Optional[List[str]]
|
||||||
|
page=None, # type: Optional[int]
|
||||||
|
per_page=None, # type: Optional[int]
|
||||||
|
):
|
||||||
|
# type: (...) -> PageResults[List[BoundAction]]
|
||||||
|
"""Get a list of actions from this account
|
||||||
|
|
||||||
|
: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 = {}
|
||||||
|
if status is not None:
|
||||||
|
params["status"] = status
|
||||||
|
if sort is not None:
|
||||||
|
params["sort"] = sort
|
||||||
|
if page is not None:
|
||||||
|
params["page"] = page
|
||||||
|
if per_page is not None:
|
||||||
|
params["per_page"] = per_page
|
||||||
|
|
||||||
|
response = self._client.request(url="/actions", method="GET", params=params)
|
||||||
|
actions = [
|
||||||
|
BoundAction(self, action_data) for action_data in response["actions"]
|
||||||
|
]
|
||||||
|
return self._add_meta_to_result(actions, response)
|
||||||
|
|
||||||
|
def get_all(self, status=None, sort=None):
|
||||||
|
# type: (Optional[List[str]], Optional[List[str]]) -> List[BoundAction]
|
||||||
|
"""Get all actions of the account
|
||||||
|
|
||||||
|
:param status: List[str] (optional)
|
||||||
|
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
||||||
|
:param sort: List[str] (optional)
|
||||||
|
Specify how the results are sorted. Choices: `id` `command` `status` `progress` `started` `finished` . You can add one of ":asc", ":desc" to modify sort order. ( ":asc" is default)
|
||||||
|
:return: List[:class:`BoundAction <hcloud.actions.client.BoundAction>`]
|
||||||
|
"""
|
||||||
|
return super().get_all(status=status, sort=sort)
|
75
plugins/module_utils/vendor/hcloud/actions/domain.py
vendored
Normal file
75
plugins/module_utils/vendor/hcloud/actions/domain.py
vendored
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
try:
|
||||||
|
from dateutil.parser import isoparse
|
||||||
|
except ImportError:
|
||||||
|
isoparse = None
|
||||||
|
|
||||||
|
from .._exceptions import HCloudException
|
||||||
|
from ..core.domain import BaseDomain
|
||||||
|
|
||||||
|
|
||||||
|
class Action(BaseDomain):
|
||||||
|
"""Action Domain
|
||||||
|
|
||||||
|
:param id: int ID of an action
|
||||||
|
:param command: Command executed in the action
|
||||||
|
:param status: Status of the action
|
||||||
|
:param progress: Progress of action in percent
|
||||||
|
:param started: Point in time when the action was started
|
||||||
|
:param datetime,None finished: Point in time when the action was finished. Only set if the action is finished otherwise None
|
||||||
|
:param resources: Resources the action relates to
|
||||||
|
:param error: Error message for the action if error occurred, otherwise None.
|
||||||
|
"""
|
||||||
|
|
||||||
|
STATUS_RUNNING = "running"
|
||||||
|
"""Action Status running"""
|
||||||
|
STATUS_SUCCESS = "success"
|
||||||
|
"""Action Status success"""
|
||||||
|
STATUS_ERROR = "error"
|
||||||
|
"""Action Status error"""
|
||||||
|
|
||||||
|
__slots__ = (
|
||||||
|
"id",
|
||||||
|
"command",
|
||||||
|
"status",
|
||||||
|
"progress",
|
||||||
|
"resources",
|
||||||
|
"error",
|
||||||
|
"started",
|
||||||
|
"finished",
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
id,
|
||||||
|
command=None,
|
||||||
|
status=None,
|
||||||
|
progress=None,
|
||||||
|
started=None,
|
||||||
|
finished=None,
|
||||||
|
resources=None,
|
||||||
|
error=None,
|
||||||
|
):
|
||||||
|
self.id = id
|
||||||
|
self.command = command
|
||||||
|
|
||||||
|
self.status = status
|
||||||
|
self.progress = progress
|
||||||
|
self.started = isoparse(started) if started else None
|
||||||
|
self.finished = isoparse(finished) if finished else None
|
||||||
|
self.resources = resources
|
||||||
|
self.error = error
|
||||||
|
|
||||||
|
|
||||||
|
class ActionException(HCloudException):
|
||||||
|
"""A generic action exception"""
|
||||||
|
|
||||||
|
def __init__(self, action):
|
||||||
|
self.action = action
|
||||||
|
|
||||||
|
|
||||||
|
class ActionFailedException(ActionException):
|
||||||
|
"""The Action you were waiting for failed"""
|
||||||
|
|
||||||
|
|
||||||
|
class ActionTimeoutException(ActionException):
|
||||||
|
"""The Action you were waiting for timed out"""
|
0
plugins/module_utils/vendor/hcloud/certificates/__init__.py
vendored
Normal file
0
plugins/module_utils/vendor/hcloud/certificates/__init__.py
vendored
Normal file
316
plugins/module_utils/vendor/hcloud/certificates/client.py
vendored
Normal file
316
plugins/module_utils/vendor/hcloud/certificates/client.py
vendored
Normal file
|
@ -0,0 +1,316 @@
|
||||||
|
from ..actions.client import BoundAction
|
||||||
|
from ..core.client import BoundModelBase, ClientEntityBase, GetEntityByNameMixin
|
||||||
|
from ..core.domain import add_meta_to_result
|
||||||
|
from .domain import (
|
||||||
|
Certificate,
|
||||||
|
CreateManagedCertificateResponse,
|
||||||
|
ManagedCertificateError,
|
||||||
|
ManagedCertificateStatus,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class BoundCertificate(BoundModelBase):
|
||||||
|
model = Certificate
|
||||||
|
|
||||||
|
def __init__(self, client, data, complete=True):
|
||||||
|
status = data.get("status")
|
||||||
|
if status is not None:
|
||||||
|
error_data = status.get("error")
|
||||||
|
error = None
|
||||||
|
if error_data:
|
||||||
|
error = ManagedCertificateError(
|
||||||
|
code=error_data["code"], message=error_data["message"]
|
||||||
|
)
|
||||||
|
data["status"] = ManagedCertificateStatus(
|
||||||
|
issuance=status["issuance"], renewal=status["renewal"], error=error
|
||||||
|
)
|
||||||
|
super().__init__(client, data, complete)
|
||||||
|
|
||||||
|
def get_actions_list(self, status=None, sort=None, page=None, per_page=None):
|
||||||
|
# type: (Optional[List[str]], Optional[List[str]], Optional[int], Optional[int]) -> PageResults[List[BoundAction, Meta]]
|
||||||
|
"""Returns all action objects for a Certificate.
|
||||||
|
|
||||||
|
:param status: List[str] (optional)
|
||||||
|
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
||||||
|
:param sort: List[str] (optional)
|
||||||
|
Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
|
||||||
|
:param page: int (optional)
|
||||||
|
Specifies the page to fetch
|
||||||
|
:param per_page: int (optional)
|
||||||
|
Specifies how many results are returned by page
|
||||||
|
:return: (List[:class:`BoundAction <hcloud.actions.client.BoundAction>`], :class:`Meta <hcloud.core.domain.Meta>`)
|
||||||
|
"""
|
||||||
|
return self._client.get_actions_list(self, status, sort, page, per_page)
|
||||||
|
|
||||||
|
def get_actions(self, status=None, sort=None):
|
||||||
|
# type: (Optional[List[str]], Optional[List[str]]) -> List[BoundAction]
|
||||||
|
"""Returns all action objects for a Certificate.
|
||||||
|
|
||||||
|
:param status: List[str] (optional)
|
||||||
|
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
||||||
|
:param sort: List[str] (optional)
|
||||||
|
Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
|
||||||
|
:return: List[:class:`BoundAction <hcloud.actions.client.BoundAction>`]
|
||||||
|
"""
|
||||||
|
return self._client.get_actions(self, status, sort)
|
||||||
|
|
||||||
|
def update(self, name=None, labels=None):
|
||||||
|
# type: (Optional[str], Optional[Dict[str, str]]) -> BoundCertificate
|
||||||
|
"""Updates an certificate. You can update an certificate name and the certificate labels.
|
||||||
|
|
||||||
|
:param name: str (optional)
|
||||||
|
New name to set
|
||||||
|
:param labels: Dict[str, str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:return: :class:`BoundCertificate <hcloud.certificates.client.BoundCertificate>
|
||||||
|
"""
|
||||||
|
return self._client.update(self, name, labels)
|
||||||
|
|
||||||
|
def delete(self):
|
||||||
|
# type: () -> bool
|
||||||
|
"""Deletes a certificate.
|
||||||
|
:return: boolean
|
||||||
|
"""
|
||||||
|
return self._client.delete(self)
|
||||||
|
|
||||||
|
def retry_issuance(self):
|
||||||
|
# type: () -> BoundAction
|
||||||
|
"""Retry a failed Certificate issuance or renewal.
|
||||||
|
:return: BoundAction
|
||||||
|
"""
|
||||||
|
return self._client.retry_issuance(self)
|
||||||
|
|
||||||
|
|
||||||
|
class CertificatesClient(ClientEntityBase, GetEntityByNameMixin):
|
||||||
|
results_list_attribute_name = "certificates"
|
||||||
|
|
||||||
|
def get_by_id(self, id):
|
||||||
|
# type: (int) -> BoundCertificate
|
||||||
|
"""Get a specific certificate by its ID.
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
:return: :class:`BoundCertificate <hcloud.certificates.client.BoundCertificate>`
|
||||||
|
"""
|
||||||
|
response = self._client.request(url=f"/certificates/{id}", method="GET")
|
||||||
|
return BoundCertificate(self, response["certificate"])
|
||||||
|
|
||||||
|
def get_list(
|
||||||
|
self,
|
||||||
|
name=None, # type: Optional[str]
|
||||||
|
label_selector=None, # type: Optional[str]
|
||||||
|
page=None, # type: Optional[int]
|
||||||
|
per_page=None, # type: Optional[int]
|
||||||
|
):
|
||||||
|
# type: (...) -> PageResults[List[BoundCertificate], Meta]
|
||||||
|
"""Get a list of certificates
|
||||||
|
|
||||||
|
:param name: str (optional)
|
||||||
|
Can be used to filter certificates by their name.
|
||||||
|
:param label_selector: str (optional)
|
||||||
|
Can be used to filter certificates by labels. The response will only contain certificates matching the label selector.
|
||||||
|
: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:`BoundCertificate <hcloud.certificates.client.BoundCertificate>`], :class:`Meta <hcloud.core.domain.Meta>`)
|
||||||
|
"""
|
||||||
|
params = {}
|
||||||
|
if name is not None:
|
||||||
|
params["name"] = name
|
||||||
|
|
||||||
|
if label_selector is not None:
|
||||||
|
params["label_selector"] = label_selector
|
||||||
|
|
||||||
|
if page is not None:
|
||||||
|
params["page"] = page
|
||||||
|
|
||||||
|
if per_page is not None:
|
||||||
|
params["per_page"] = per_page
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url="/certificates", method="GET", params=params
|
||||||
|
)
|
||||||
|
|
||||||
|
certificates = [
|
||||||
|
BoundCertificate(self, certificate_data)
|
||||||
|
for certificate_data in response["certificates"]
|
||||||
|
]
|
||||||
|
|
||||||
|
return self._add_meta_to_result(certificates, response)
|
||||||
|
|
||||||
|
def get_all(self, name=None, label_selector=None):
|
||||||
|
# type: (Optional[str], Optional[str]) -> List[BoundCertificate]
|
||||||
|
"""Get all certificates
|
||||||
|
|
||||||
|
:param name: str (optional)
|
||||||
|
Can be used to filter certificates by their name.
|
||||||
|
:param label_selector: str (optional)
|
||||||
|
Can be used to filter certificates by labels. The response will only contain certificates matching the label selector.
|
||||||
|
:return: List[:class:`BoundCertificate <hcloud.certificates.client.BoundCertificate>`]
|
||||||
|
"""
|
||||||
|
return super().get_all(name=name, label_selector=label_selector)
|
||||||
|
|
||||||
|
def get_by_name(self, name):
|
||||||
|
# type: (str) -> BoundCertificate
|
||||||
|
"""Get certificate by name
|
||||||
|
|
||||||
|
:param name: str
|
||||||
|
Used to get certificate by name.
|
||||||
|
:return: :class:`BoundCertificate <hcloud.certificates.client.BoundCertificate>`
|
||||||
|
"""
|
||||||
|
return super().get_by_name(name)
|
||||||
|
|
||||||
|
def create(self, name, certificate, private_key, labels=None):
|
||||||
|
# type: (str, str, str, Optional[Dict[str, str]]) -> BoundCertificate
|
||||||
|
"""Creates a new Certificate with the given name, certificate and private_key. This methods allows only creating
|
||||||
|
custom uploaded certificates. If you want to create a managed certificate use :func:`~hcloud.certificates.client.CertificatesClient.create_managed`
|
||||||
|
|
||||||
|
:param name: str
|
||||||
|
:param certificate: str
|
||||||
|
Certificate and chain in PEM format, in order so that each record directly certifies the one preceding
|
||||||
|
:param private_key: str
|
||||||
|
Certificate key in PEM format
|
||||||
|
:param labels: Dict[str, str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:return: :class:`BoundCertificate <hcloud.certificates.client.BoundCertificate>`
|
||||||
|
"""
|
||||||
|
data = {
|
||||||
|
"name": name,
|
||||||
|
"certificate": certificate,
|
||||||
|
"private_key": private_key,
|
||||||
|
"type": Certificate.TYPE_UPLOADED,
|
||||||
|
}
|
||||||
|
if labels is not None:
|
||||||
|
data["labels"] = labels
|
||||||
|
response = self._client.request(url="/certificates", method="POST", json=data)
|
||||||
|
return BoundCertificate(self, response["certificate"])
|
||||||
|
|
||||||
|
def create_managed(self, name, domain_names, labels=None):
|
||||||
|
# type: (str, List[str], Optional[Dict[str, str]]) -> CreateManagedCertificateResponse
|
||||||
|
"""Creates a new managed Certificate with the given name and domain names. This methods allows only creating
|
||||||
|
managed certificates for domains that are using the Hetzner DNS service. If you want to create a custom uploaded certificate use :func:`~hcloud.certificates.client.CertificatesClient.create`
|
||||||
|
|
||||||
|
:param name: str
|
||||||
|
:param domain_names: List[str]
|
||||||
|
Domains and subdomains that should be contained in the Certificate
|
||||||
|
:param labels: Dict[str, str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:return: :class:`BoundCertificate <hcloud.certificates.client.BoundCertificate>`
|
||||||
|
"""
|
||||||
|
data = {
|
||||||
|
"name": name,
|
||||||
|
"type": Certificate.TYPE_MANAGED,
|
||||||
|
"domain_names": domain_names,
|
||||||
|
}
|
||||||
|
if labels is not None:
|
||||||
|
data["labels"] = labels
|
||||||
|
response = self._client.request(url="/certificates", method="POST", json=data)
|
||||||
|
return CreateManagedCertificateResponse(
|
||||||
|
certificate=BoundCertificate(self, response["certificate"]),
|
||||||
|
action=BoundAction(self._client.actions, response["action"]),
|
||||||
|
)
|
||||||
|
|
||||||
|
def update(self, certificate, name=None, labels=None):
|
||||||
|
# type: (Certificate, Optional[str], Optional[Dict[str, str]]) -> BoundCertificate
|
||||||
|
"""Updates a Certificate. You can update a certificate name and labels.
|
||||||
|
|
||||||
|
:param certificate: :class:`BoundCertificate <hcloud.certificates.client.BoundCertificate>` or :class:`Certificate <hcloud.certificates.domain.Certificate>`
|
||||||
|
:param name: str (optional)
|
||||||
|
New name to set
|
||||||
|
:param labels: Dict[str, str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:return: :class:`BoundCertificate <hcloud.certificates.client.BoundCertificate>`
|
||||||
|
"""
|
||||||
|
data = {}
|
||||||
|
if name is not None:
|
||||||
|
data["name"] = name
|
||||||
|
if labels is not None:
|
||||||
|
data["labels"] = labels
|
||||||
|
response = self._client.request(
|
||||||
|
url=f"/certificates/{certificate.id}",
|
||||||
|
method="PUT",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return BoundCertificate(self, response["certificate"])
|
||||||
|
|
||||||
|
def delete(self, certificate):
|
||||||
|
# type: (Certificate) -> bool
|
||||||
|
self._client.request(
|
||||||
|
url=f"/certificates/{certificate.id}",
|
||||||
|
method="DELETE",
|
||||||
|
)
|
||||||
|
"""Deletes a certificate.
|
||||||
|
|
||||||
|
:param certificate: :class:`BoundCertificate <hcloud.certificates.client.BoundCertificate>` or :class:`Certificate <hcloud.certificates.domain.Certificate>`
|
||||||
|
:return: True
|
||||||
|
"""
|
||||||
|
# Return always true, because the API does not return an action for it. When an error occurs a HcloudAPIException will be raised
|
||||||
|
return True
|
||||||
|
|
||||||
|
def get_actions_list(
|
||||||
|
self, certificate, status=None, sort=None, page=None, per_page=None
|
||||||
|
):
|
||||||
|
# type: (Certificate, Optional[List[str]], Optional[List[str]], Optional[int], Optional[int]) -> PageResults[List[BoundAction], Meta]
|
||||||
|
"""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 = {}
|
||||||
|
if status is not None:
|
||||||
|
params["status"] = status
|
||||||
|
if sort is not None:
|
||||||
|
params["sort"] = sort
|
||||||
|
if page is not None:
|
||||||
|
params["page"] = page
|
||||||
|
if per_page is not None:
|
||||||
|
params["per_page"] = per_page
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url="/certificates/{certificate_id}/actions".format(
|
||||||
|
certificate_id=certificate.id
|
||||||
|
),
|
||||||
|
method="GET",
|
||||||
|
params=params,
|
||||||
|
)
|
||||||
|
actions = [
|
||||||
|
BoundAction(self._client.actions, action_data)
|
||||||
|
for action_data in response["actions"]
|
||||||
|
]
|
||||||
|
return add_meta_to_result(actions, response, "actions")
|
||||||
|
|
||||||
|
def get_actions(self, certificate, status=None, sort=None):
|
||||||
|
# type: (Certificate, Optional[List[str]], Optional[List[str]]) -> List[BoundAction]
|
||||||
|
"""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`
|
||||||
|
:return: List[:class:`BoundAction <hcloud.actions.client.BoundAction>`]
|
||||||
|
"""
|
||||||
|
return super().get_actions(certificate, status=status, sort=sort)
|
||||||
|
|
||||||
|
def retry_issuance(self, certificate):
|
||||||
|
# type: (Certificate) -> BoundAction
|
||||||
|
"""Returns all action objects for a Certificate.
|
||||||
|
|
||||||
|
:param certificate: :class:`BoundCertificate <hcloud.certificates.client.BoundCertificate>` or :class:`Certificate <hcloud.certificates.domain.Certificate>`
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
response = self._client.request(
|
||||||
|
url="/certificates/{certificate_id}/actions/retry".format(
|
||||||
|
certificate_id=certificate.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
120
plugins/module_utils/vendor/hcloud/certificates/domain.py
vendored
Normal file
120
plugins/module_utils/vendor/hcloud/certificates/domain.py
vendored
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
try:
|
||||||
|
from dateutil.parser import isoparse
|
||||||
|
except ImportError:
|
||||||
|
isoparse = None
|
||||||
|
|
||||||
|
from ..core.domain import BaseDomain, DomainIdentityMixin
|
||||||
|
|
||||||
|
|
||||||
|
class Certificate(BaseDomain, DomainIdentityMixin):
|
||||||
|
"""Certificate Domain
|
||||||
|
|
||||||
|
:param id: int ID of Certificate
|
||||||
|
:param name: str Name of Certificate
|
||||||
|
:param certificate: str Certificate and chain in PEM format, in order so that each record directly certifies the one preceding
|
||||||
|
:param not_valid_before: datetime
|
||||||
|
Point in time when the Certificate becomes valid
|
||||||
|
:param not_valid_after: datetime
|
||||||
|
Point in time when the Certificate becomes invalid
|
||||||
|
:param domain_names: List[str] List of domains and subdomains covered by this certificate
|
||||||
|
:param fingerprint: str Fingerprint of the Certificate
|
||||||
|
:param labels: dict
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:param created: datetime
|
||||||
|
Point in time when the certificate was created
|
||||||
|
:param type: str Type of Certificate
|
||||||
|
:param status: ManagedCertificateStatus Current status of a type managed Certificate, always none for type uploaded Certificates
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = (
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"certificate",
|
||||||
|
"not_valid_before",
|
||||||
|
"not_valid_after",
|
||||||
|
"domain_names",
|
||||||
|
"fingerprint",
|
||||||
|
"created",
|
||||||
|
"labels",
|
||||||
|
"type",
|
||||||
|
"status",
|
||||||
|
)
|
||||||
|
TYPE_UPLOADED = "uploaded"
|
||||||
|
TYPE_MANAGED = "managed"
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
id=None,
|
||||||
|
name=None,
|
||||||
|
certificate=None,
|
||||||
|
not_valid_before=None,
|
||||||
|
not_valid_after=None,
|
||||||
|
domain_names=None,
|
||||||
|
fingerprint=None,
|
||||||
|
created=None,
|
||||||
|
labels=None,
|
||||||
|
type=None,
|
||||||
|
status=None,
|
||||||
|
):
|
||||||
|
self.id = id
|
||||||
|
self.name = name
|
||||||
|
self.type = type
|
||||||
|
self.certificate = certificate
|
||||||
|
self.domain_names = domain_names
|
||||||
|
self.fingerprint = fingerprint
|
||||||
|
self.not_valid_before = isoparse(not_valid_before) if not_valid_before else None
|
||||||
|
self.not_valid_after = isoparse(not_valid_after) if not_valid_after else None
|
||||||
|
self.created = isoparse(created) if created else None
|
||||||
|
self.labels = labels
|
||||||
|
self.status = status
|
||||||
|
|
||||||
|
|
||||||
|
class ManagedCertificateStatus(BaseDomain):
|
||||||
|
"""ManagedCertificateStatus Domain
|
||||||
|
|
||||||
|
:param issuance: str
|
||||||
|
Status of the issuance process of the Certificate
|
||||||
|
:param renewal: str
|
||||||
|
Status of the renewal process of the Certificate
|
||||||
|
:param error: ManagedCertificateError
|
||||||
|
If issuance or renewal reports failure, this property contains information about what happened
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, issuance=None, renewal=None, error=None):
|
||||||
|
self.issuance = issuance
|
||||||
|
self.renewal = renewal
|
||||||
|
self.error = error
|
||||||
|
|
||||||
|
|
||||||
|
class ManagedCertificateError(BaseDomain):
|
||||||
|
"""ManagedCertificateError Domain
|
||||||
|
|
||||||
|
:param code: str
|
||||||
|
Error code identifying the error
|
||||||
|
:param message:
|
||||||
|
Message detailing the error
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, code=None, message=None):
|
||||||
|
self.code = code
|
||||||
|
self.message = message
|
||||||
|
|
||||||
|
|
||||||
|
class CreateManagedCertificateResponse(BaseDomain):
|
||||||
|
"""Create Managed Certificate Response Domain
|
||||||
|
|
||||||
|
:param certificate: :class:`BoundCertificate <hcloud.certificate.client.BoundCertificate>`
|
||||||
|
The created server
|
||||||
|
:param action: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
Shows the progress of the certificate creation
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("certificate", "action")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
certificate, # type: BoundCertificate
|
||||||
|
action, # type: BoundAction
|
||||||
|
):
|
||||||
|
self.certificate = certificate
|
||||||
|
self.action = action
|
0
plugins/module_utils/vendor/hcloud/core/__init__.py
vendored
Normal file
0
plugins/module_utils/vendor/hcloud/core/__init__.py
vendored
Normal file
127
plugins/module_utils/vendor/hcloud/core/client.py
vendored
Normal file
127
plugins/module_utils/vendor/hcloud/core/client.py
vendored
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
from .domain import add_meta_to_result
|
||||||
|
|
||||||
|
|
||||||
|
class ClientEntityBase:
|
||||||
|
max_per_page = 50
|
||||||
|
results_list_attribute_name = None
|
||||||
|
|
||||||
|
def __init__(self, client):
|
||||||
|
"""
|
||||||
|
:param client: Client
|
||||||
|
:return self
|
||||||
|
"""
|
||||||
|
self._client = client
|
||||||
|
|
||||||
|
def _is_list_attribute_implemented(self):
|
||||||
|
if self.results_list_attribute_name is None:
|
||||||
|
raise NotImplementedError(
|
||||||
|
"in order to get results list, 'results_list_attribute_name' attribute of {} has to be specified".format(
|
||||||
|
self.__class__.__name__
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def _add_meta_to_result(
|
||||||
|
self,
|
||||||
|
results, # type: List[BoundModelBase]
|
||||||
|
response, # type: json
|
||||||
|
):
|
||||||
|
# type: (...) -> PageResult
|
||||||
|
self._is_list_attribute_implemented()
|
||||||
|
return add_meta_to_result(results, response, self.results_list_attribute_name)
|
||||||
|
|
||||||
|
def _get_all(
|
||||||
|
self,
|
||||||
|
list_function, # type: function
|
||||||
|
results_list_attribute_name, # type: str
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
|
):
|
||||||
|
# type (...) -> List[BoundModelBase]
|
||||||
|
|
||||||
|
page = 1
|
||||||
|
|
||||||
|
results = []
|
||||||
|
|
||||||
|
while page:
|
||||||
|
page_result = list_function(
|
||||||
|
page=page, per_page=self.max_per_page, *args, **kwargs
|
||||||
|
)
|
||||||
|
result = getattr(page_result, results_list_attribute_name)
|
||||||
|
if result:
|
||||||
|
results.extend(result)
|
||||||
|
meta = page_result.meta
|
||||||
|
if (
|
||||||
|
meta
|
||||||
|
and meta.pagination
|
||||||
|
and meta.pagination.next_page
|
||||||
|
and meta.pagination.next_page
|
||||||
|
):
|
||||||
|
page = meta.pagination.next_page
|
||||||
|
else:
|
||||||
|
page = None
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
|
def get_all(self, *args, **kwargs):
|
||||||
|
# type: (...) -> List[BoundModelBase]
|
||||||
|
self._is_list_attribute_implemented()
|
||||||
|
return self._get_all(
|
||||||
|
self.get_list, self.results_list_attribute_name, *args, **kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_actions(self, *args, **kwargs):
|
||||||
|
# type: (...) -> List[BoundModelBase]
|
||||||
|
if not hasattr(self, "get_actions_list"):
|
||||||
|
raise ValueError("this endpoint does not support get_actions method")
|
||||||
|
|
||||||
|
return self._get_all(self.get_actions_list, "actions", *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class GetEntityByNameMixin:
|
||||||
|
"""
|
||||||
|
Use as a mixin for ClientEntityBase classes
|
||||||
|
"""
|
||||||
|
|
||||||
|
def get_by_name(self, name):
|
||||||
|
# type: (str) -> BoundModelBase
|
||||||
|
self._is_list_attribute_implemented()
|
||||||
|
response = self.get_list(name=name)
|
||||||
|
entities = getattr(response, self.results_list_attribute_name)
|
||||||
|
entity = entities[0] if entities else None
|
||||||
|
return entity
|
||||||
|
|
||||||
|
|
||||||
|
class BoundModelBase:
|
||||||
|
"""Bound Model Base"""
|
||||||
|
|
||||||
|
model = None
|
||||||
|
|
||||||
|
def __init__(self, client, data={}, complete=True):
|
||||||
|
"""
|
||||||
|
:param client:
|
||||||
|
The client for the specific model to use
|
||||||
|
:param data:
|
||||||
|
The data of the model
|
||||||
|
:param complete: bool
|
||||||
|
False if not all attributes of the model fetched
|
||||||
|
"""
|
||||||
|
self._client = client
|
||||||
|
self.complete = complete
|
||||||
|
self.data_model = self.model.from_dict(data)
|
||||||
|
|
||||||
|
def __getattr__(self, name):
|
||||||
|
"""Allow magical access to the properties of the model
|
||||||
|
:param name: str
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
value = getattr(self.data_model, name)
|
||||||
|
if not value and not self.complete:
|
||||||
|
self.reload()
|
||||||
|
value = getattr(self.data_model, name)
|
||||||
|
return value
|
||||||
|
|
||||||
|
def reload(self):
|
||||||
|
"""Reloads the model and tries to get all data from the APIx"""
|
||||||
|
bound_model = self._client.get_by_id(self.data_model.id)
|
||||||
|
self.data_model = bound_model.data_model
|
||||||
|
self.complete = True
|
75
plugins/module_utils/vendor/hcloud/core/domain.py
vendored
Normal file
75
plugins/module_utils/vendor/hcloud/core/domain.py
vendored
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
from collections import namedtuple
|
||||||
|
|
||||||
|
|
||||||
|
class BaseDomain:
|
||||||
|
__slots__ = ()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls, data):
|
||||||
|
supported_data = {k: v for k, v in data.items() if k in cls.__slots__}
|
||||||
|
return cls(**supported_data)
|
||||||
|
|
||||||
|
|
||||||
|
class DomainIdentityMixin:
|
||||||
|
__slots__ = ()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def id_or_name(self):
|
||||||
|
if self.id is not None:
|
||||||
|
return self.id
|
||||||
|
elif self.name is not None:
|
||||||
|
return self.name
|
||||||
|
else:
|
||||||
|
raise ValueError("id or name must be set")
|
||||||
|
|
||||||
|
|
||||||
|
class Pagination(BaseDomain):
|
||||||
|
__slots__ = (
|
||||||
|
"page",
|
||||||
|
"per_page",
|
||||||
|
"previous_page",
|
||||||
|
"next_page",
|
||||||
|
"last_page",
|
||||||
|
"total_entries",
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
page,
|
||||||
|
per_page,
|
||||||
|
previous_page=None,
|
||||||
|
next_page=None,
|
||||||
|
last_page=None,
|
||||||
|
total_entries=None,
|
||||||
|
):
|
||||||
|
self.page = page
|
||||||
|
self.per_page = per_page
|
||||||
|
self.previous_page = previous_page
|
||||||
|
self.next_page = next_page
|
||||||
|
self.last_page = last_page
|
||||||
|
self.total_entries = total_entries
|
||||||
|
|
||||||
|
|
||||||
|
class Meta(BaseDomain):
|
||||||
|
__slots__ = ("pagination",)
|
||||||
|
|
||||||
|
def __init__(self, pagination=None):
|
||||||
|
self.pagination = pagination
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def parse_meta(cls, json_content):
|
||||||
|
meta = None
|
||||||
|
if json_content and "meta" in json_content:
|
||||||
|
meta = cls()
|
||||||
|
pagination_json = json_content["meta"].get("pagination")
|
||||||
|
if pagination_json:
|
||||||
|
pagination = Pagination(**pagination_json)
|
||||||
|
meta.pagination = pagination
|
||||||
|
return meta
|
||||||
|
|
||||||
|
|
||||||
|
def add_meta_to_result(result, json_content, attr_name):
|
||||||
|
# type: (List[BoundModelBase], json, string) -> PageResult
|
||||||
|
class_name = f"PageResults{attr_name.capitalize()}"
|
||||||
|
PageResults = namedtuple(class_name, [attr_name, "meta"])
|
||||||
|
return PageResults(**{attr_name: result, "meta": Meta.parse_meta(json_content)})
|
0
plugins/module_utils/vendor/hcloud/datacenters/__init__.py
vendored
Normal file
0
plugins/module_utils/vendor/hcloud/datacenters/__init__.py
vendored
Normal file
111
plugins/module_utils/vendor/hcloud/datacenters/client.py
vendored
Normal file
111
plugins/module_utils/vendor/hcloud/datacenters/client.py
vendored
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
from ..core.client import BoundModelBase, ClientEntityBase, GetEntityByNameMixin
|
||||||
|
from ..locations.client import BoundLocation
|
||||||
|
from ..server_types.client import BoundServerType
|
||||||
|
from .domain import Datacenter, DatacenterServerTypes
|
||||||
|
|
||||||
|
|
||||||
|
class BoundDatacenter(BoundModelBase):
|
||||||
|
model = Datacenter
|
||||||
|
|
||||||
|
def __init__(self, client, data):
|
||||||
|
location = data.get("location")
|
||||||
|
if location is not None:
|
||||||
|
data["location"] = BoundLocation(client._client.locations, location)
|
||||||
|
|
||||||
|
server_types = data.get("server_types")
|
||||||
|
if server_types is not None:
|
||||||
|
available = [
|
||||||
|
BoundServerType(
|
||||||
|
client._client.server_types, {"id": server_type}, complete=False
|
||||||
|
)
|
||||||
|
for server_type in server_types["available"]
|
||||||
|
]
|
||||||
|
supported = [
|
||||||
|
BoundServerType(
|
||||||
|
client._client.server_types, {"id": server_type}, complete=False
|
||||||
|
)
|
||||||
|
for server_type in server_types["supported"]
|
||||||
|
]
|
||||||
|
available_for_migration = [
|
||||||
|
BoundServerType(
|
||||||
|
client._client.server_types, {"id": server_type}, complete=False
|
||||||
|
)
|
||||||
|
for server_type in server_types["available_for_migration"]
|
||||||
|
]
|
||||||
|
data["server_types"] = DatacenterServerTypes(
|
||||||
|
available=available,
|
||||||
|
supported=supported,
|
||||||
|
available_for_migration=available_for_migration,
|
||||||
|
)
|
||||||
|
|
||||||
|
super().__init__(client, data)
|
||||||
|
|
||||||
|
|
||||||
|
class DatacentersClient(ClientEntityBase, GetEntityByNameMixin):
|
||||||
|
results_list_attribute_name = "datacenters"
|
||||||
|
|
||||||
|
def get_by_id(self, id):
|
||||||
|
# type: (int) -> BoundDatacenter
|
||||||
|
"""Get a specific datacenter by its ID.
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
:return: :class:`BoundDatacenter <hcloud.datacenters.client.BoundDatacenter>`
|
||||||
|
"""
|
||||||
|
response = self._client.request(url=f"/datacenters/{id}", method="GET")
|
||||||
|
return BoundDatacenter(self, response["datacenter"])
|
||||||
|
|
||||||
|
def get_list(
|
||||||
|
self,
|
||||||
|
name=None, # type: Optional[str]
|
||||||
|
page=None, # type: Optional[int]
|
||||||
|
per_page=None, # type: Optional[int]
|
||||||
|
):
|
||||||
|
# type: (...) -> PageResults[List[BoundDatacenter], Meta]
|
||||||
|
"""Get a list of datacenters
|
||||||
|
|
||||||
|
:param name: str (optional)
|
||||||
|
Can be used to filter datacenters by their name.
|
||||||
|
: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:`BoundDatacenter <hcloud.datacenters.client.BoundDatacenter>`], :class:`Meta <hcloud.core.domain.Meta>`)
|
||||||
|
"""
|
||||||
|
params = {}
|
||||||
|
if name is not None:
|
||||||
|
params["name"] = name
|
||||||
|
|
||||||
|
if page is not None:
|
||||||
|
params["page"] = page
|
||||||
|
|
||||||
|
if per_page is not None:
|
||||||
|
params["per_page"] = per_page
|
||||||
|
|
||||||
|
response = self._client.request(url="/datacenters", method="GET", params=params)
|
||||||
|
|
||||||
|
datacenters = [
|
||||||
|
BoundDatacenter(self, datacenter_data)
|
||||||
|
for datacenter_data in response["datacenters"]
|
||||||
|
]
|
||||||
|
|
||||||
|
return self._add_meta_to_result(datacenters, response)
|
||||||
|
|
||||||
|
def get_all(self, name=None):
|
||||||
|
# type: (Optional[str]) -> List[BoundDatacenter]
|
||||||
|
"""Get all datacenters
|
||||||
|
|
||||||
|
:param name: str (optional)
|
||||||
|
Can be used to filter datacenters by their name.
|
||||||
|
:return: List[:class:`BoundDatacenter <hcloud.datacenters.client.BoundDatacenter>`]
|
||||||
|
"""
|
||||||
|
return super().get_all(name=name)
|
||||||
|
|
||||||
|
def get_by_name(self, name):
|
||||||
|
# type: (str) -> BoundDatacenter
|
||||||
|
"""Get datacenter by name
|
||||||
|
|
||||||
|
:param name: str
|
||||||
|
Used to get datacenter by name.
|
||||||
|
:return: :class:`BoundDatacenter <hcloud.datacenters.client.BoundDatacenter>`
|
||||||
|
"""
|
||||||
|
return super().get_by_name(name)
|
42
plugins/module_utils/vendor/hcloud/datacenters/domain.py
vendored
Normal file
42
plugins/module_utils/vendor/hcloud/datacenters/domain.py
vendored
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
from ..core.domain import BaseDomain, DomainIdentityMixin
|
||||||
|
|
||||||
|
|
||||||
|
class Datacenter(BaseDomain, DomainIdentityMixin):
|
||||||
|
"""Datacenter Domain
|
||||||
|
|
||||||
|
:param id: int ID of Datacenter
|
||||||
|
:param name: str Name of Datacenter
|
||||||
|
:param description: str Description of Datacenter
|
||||||
|
:param location: :class:`BoundLocation <hcloud.locations.client.BoundLocation>`
|
||||||
|
:param server_types: :class:`DatacenterServerTypes <hcloud.datacenters.domain.DatacenterServerTypes>`
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("id", "name", "description", "location", "server_types")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self, id=None, name=None, description=None, location=None, server_types=None
|
||||||
|
):
|
||||||
|
self.id = id
|
||||||
|
self.name = name
|
||||||
|
self.description = description
|
||||||
|
self.location = location
|
||||||
|
self.server_types = server_types
|
||||||
|
|
||||||
|
|
||||||
|
class DatacenterServerTypes:
|
||||||
|
"""DatacenterServerTypes Domain
|
||||||
|
|
||||||
|
:param available: List[:class:`BoundServerTypes <hcloud.server_types.client.BoundServerTypes>`]
|
||||||
|
All available server types for this datacenter
|
||||||
|
:param supported: List[:class:`BoundServerTypes <hcloud.server_types.client.BoundServerTypes>`]
|
||||||
|
All supported server types for this datacenter
|
||||||
|
:param available_for_migration: List[:class:`BoundServerTypes <hcloud.server_types.client.BoundServerTypes>`]
|
||||||
|
All available for migration (change type) server types for this datacenter
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("available", "supported", "available_for_migration")
|
||||||
|
|
||||||
|
def __init__(self, available, supported, available_for_migration):
|
||||||
|
self.available = available
|
||||||
|
self.supported = supported
|
||||||
|
self.available_for_migration = available_for_migration
|
0
plugins/module_utils/vendor/hcloud/deprecation/__init__.py
vendored
Normal file
0
plugins/module_utils/vendor/hcloud/deprecation/__init__.py
vendored
Normal file
34
plugins/module_utils/vendor/hcloud/deprecation/domain.py
vendored
Normal file
34
plugins/module_utils/vendor/hcloud/deprecation/domain.py
vendored
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
try:
|
||||||
|
from dateutil.parser import isoparse
|
||||||
|
except ImportError:
|
||||||
|
isoparse = None
|
||||||
|
|
||||||
|
from ..core.domain import BaseDomain
|
||||||
|
|
||||||
|
|
||||||
|
class DeprecationInfo(BaseDomain):
|
||||||
|
"""Describes if, when & how the resources was deprecated. If this field is set to ``None`` the resource is not
|
||||||
|
deprecated. If it has a value, it is considered deprecated.
|
||||||
|
|
||||||
|
:param announced: datetime
|
||||||
|
Date of when the deprecation was announced.
|
||||||
|
:param unavailable_after: datetime
|
||||||
|
After the time in this field, the resource will not be available from the general listing endpoint of the
|
||||||
|
resource type, and it can not be used in new resources. For example, if this is an image, you can not create
|
||||||
|
new servers with this image after the mentioned date.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = (
|
||||||
|
"announced",
|
||||||
|
"unavailable_after",
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
announced=None,
|
||||||
|
unavailable_after=None,
|
||||||
|
):
|
||||||
|
self.announced = isoparse(announced) if announced else None
|
||||||
|
self.unavailable_after = (
|
||||||
|
isoparse(unavailable_after) if unavailable_after else None
|
||||||
|
)
|
0
plugins/module_utils/vendor/hcloud/firewalls/__init__.py
vendored
Normal file
0
plugins/module_utils/vendor/hcloud/firewalls/__init__.py
vendored
Normal file
416
plugins/module_utils/vendor/hcloud/firewalls/client.py
vendored
Normal file
416
plugins/module_utils/vendor/hcloud/firewalls/client.py
vendored
Normal file
|
@ -0,0 +1,416 @@
|
||||||
|
from ..actions.client import BoundAction
|
||||||
|
from ..core.client import BoundModelBase, ClientEntityBase, GetEntityByNameMixin
|
||||||
|
from ..core.domain import add_meta_to_result
|
||||||
|
from .domain import (
|
||||||
|
CreateFirewallResponse,
|
||||||
|
Firewall,
|
||||||
|
FirewallResource,
|
||||||
|
FirewallResourceLabelSelector,
|
||||||
|
FirewallRule,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class BoundFirewall(BoundModelBase):
|
||||||
|
model = Firewall
|
||||||
|
|
||||||
|
def __init__(self, client, data, complete=True):
|
||||||
|
rules = data.get("rules", [])
|
||||||
|
if rules:
|
||||||
|
rules = [
|
||||||
|
FirewallRule(
|
||||||
|
direction=rule["direction"],
|
||||||
|
source_ips=rule["source_ips"],
|
||||||
|
destination_ips=rule["destination_ips"],
|
||||||
|
protocol=rule["protocol"],
|
||||||
|
port=rule["port"],
|
||||||
|
description=rule["description"],
|
||||||
|
)
|
||||||
|
for rule in rules
|
||||||
|
]
|
||||||
|
data["rules"] = rules
|
||||||
|
|
||||||
|
applied_to = data.get("applied_to", [])
|
||||||
|
if applied_to:
|
||||||
|
from ..servers.client import BoundServer
|
||||||
|
|
||||||
|
ats = []
|
||||||
|
for a in applied_to:
|
||||||
|
if a["type"] == FirewallResource.TYPE_SERVER:
|
||||||
|
ats.append(
|
||||||
|
FirewallResource(
|
||||||
|
type=a["type"],
|
||||||
|
server=BoundServer(
|
||||||
|
client._client.servers, a["server"], complete=False
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
elif a["type"] == FirewallResource.TYPE_LABEL_SELECTOR:
|
||||||
|
ats.append(
|
||||||
|
FirewallResource(
|
||||||
|
type=a["type"],
|
||||||
|
label_selector=FirewallResourceLabelSelector(
|
||||||
|
selector=a["label_selector"]["selector"]
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
data["applied_to"] = ats
|
||||||
|
|
||||||
|
super().__init__(client, data, complete)
|
||||||
|
|
||||||
|
def get_actions_list(self, status=None, sort=None, page=None, per_page=None):
|
||||||
|
# type: (Optional[List[str]], Optional[List[str]], Optional[int], Optional[int]) -> PageResult[BoundAction, Meta]
|
||||||
|
"""Returns all action objects for a Firewall.
|
||||||
|
|
||||||
|
:param status: List[str] (optional)
|
||||||
|
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
||||||
|
:param sort: List[str] (optional)
|
||||||
|
Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
|
||||||
|
:param page: int (optional)
|
||||||
|
Specifies the page to fetch
|
||||||
|
:param per_page: int (optional)
|
||||||
|
Specifies how many results are returned by page
|
||||||
|
:return: (List[:class:`BoundAction <hcloud.actions.client.BoundAction>`], :class:`Meta <hcloud.core.domain.Meta>`)
|
||||||
|
"""
|
||||||
|
return self._client.get_actions_list(self, status, sort, page, per_page)
|
||||||
|
|
||||||
|
def get_actions(self, status=None, sort=None):
|
||||||
|
# type: (Optional[List[str]], Optional[List[str]]) -> List[BoundAction]
|
||||||
|
"""Returns all action objects for a Firewall.
|
||||||
|
|
||||||
|
:param status: List[str] (optional)
|
||||||
|
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
||||||
|
:param sort: List[str] (optional)
|
||||||
|
Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
|
||||||
|
|
||||||
|
:return: List[:class:`BoundAction <hcloud.actions.client.BoundAction>`]
|
||||||
|
"""
|
||||||
|
return self._client.get_actions(self, status, sort)
|
||||||
|
|
||||||
|
def update(self, name=None, labels=None):
|
||||||
|
# type: (Optional[str], Optional[Dict[str, str]], Optional[str]) -> BoundFirewall
|
||||||
|
"""Updates the name or labels of a Firewall.
|
||||||
|
|
||||||
|
:param labels: Dict[str, str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:param name: str (optional)
|
||||||
|
New Name to set
|
||||||
|
:return: :class:`BoundFirewall <hcloud.firewalls.client.BoundFirewall>`
|
||||||
|
"""
|
||||||
|
return self._client.update(self, labels, name)
|
||||||
|
|
||||||
|
def delete(self):
|
||||||
|
# type: () -> bool
|
||||||
|
"""Deletes a Firewall.
|
||||||
|
|
||||||
|
:return: boolean
|
||||||
|
"""
|
||||||
|
return self._client.delete(self)
|
||||||
|
|
||||||
|
def set_rules(self, rules):
|
||||||
|
# type: (List[FirewallRule]) -> List[BoundAction]
|
||||||
|
"""Sets the rules of a Firewall. All existing rules will be overwritten. Pass an empty rules array to remove all rules.
|
||||||
|
:param rules: List[:class:`FirewallRule <hcloud.firewalls.domain.FirewallRule>`]
|
||||||
|
:return: List[:class:`BoundAction <hcloud.actions.client.BoundAction>`]
|
||||||
|
"""
|
||||||
|
|
||||||
|
return self._client.set_rules(self, rules)
|
||||||
|
|
||||||
|
def apply_to_resources(self, resources):
|
||||||
|
# type: (List[FirewallResource]) -> List[BoundAction]
|
||||||
|
"""Applies one Firewall to multiple resources.
|
||||||
|
:param resources: List[:class:`FirewallResource <hcloud.firewalls.domain.FirewallResource>`]
|
||||||
|
:return: List[:class:`BoundAction <hcloud.actions.client.BoundAction>`]
|
||||||
|
"""
|
||||||
|
return self._client.apply_to_resources(self, resources)
|
||||||
|
|
||||||
|
def remove_from_resources(self, resources):
|
||||||
|
# type: (List[FirewallResource]) -> List[BoundAction]
|
||||||
|
"""Removes one Firewall from multiple resources.
|
||||||
|
:param resources: List[:class:`FirewallResource <hcloud.firewalls.domain.FirewallResource>`]
|
||||||
|
:return: List[:class:`BoundAction <hcloud.actions.client.BoundAction>`]
|
||||||
|
"""
|
||||||
|
return self._client.remove_from_resources(self, resources)
|
||||||
|
|
||||||
|
|
||||||
|
class FirewallsClient(ClientEntityBase, GetEntityByNameMixin):
|
||||||
|
results_list_attribute_name = "firewalls"
|
||||||
|
|
||||||
|
def get_actions_list(
|
||||||
|
self,
|
||||||
|
firewall, # type: Firewall
|
||||||
|
status=None, # type: Optional[List[str]]
|
||||||
|
sort=None, # type: Optional[List[str]]
|
||||||
|
page=None, # type: Optional[int]
|
||||||
|
per_page=None, # type: Optional[int]
|
||||||
|
):
|
||||||
|
# type: (...) -> PageResults[List[BoundAction], Meta]
|
||||||
|
"""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 = {}
|
||||||
|
if status is not None:
|
||||||
|
params["status"] = status
|
||||||
|
if sort is not None:
|
||||||
|
params["sort"] = sort
|
||||||
|
if page is not None:
|
||||||
|
params["page"] = page
|
||||||
|
if per_page is not None:
|
||||||
|
params["per_page"] = per_page
|
||||||
|
response = self._client.request(
|
||||||
|
url=f"/firewalls/{firewall.id}/actions",
|
||||||
|
method="GET",
|
||||||
|
params=params,
|
||||||
|
)
|
||||||
|
actions = [
|
||||||
|
BoundAction(self._client.actions, action_data)
|
||||||
|
for action_data in response["actions"]
|
||||||
|
]
|
||||||
|
return add_meta_to_result(actions, response, "actions")
|
||||||
|
|
||||||
|
def get_actions(
|
||||||
|
self,
|
||||||
|
firewall, # type: Firewall
|
||||||
|
status=None, # type: Optional[List[str]]
|
||||||
|
sort=None, # type: Optional[List[str]]
|
||||||
|
):
|
||||||
|
# type: (...) -> List[BoundAction]
|
||||||
|
"""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`
|
||||||
|
|
||||||
|
:return: List[:class:`BoundAction <hcloud.actions.client.BoundAction>`]
|
||||||
|
"""
|
||||||
|
return super().get_actions(firewall, status=status, sort=sort)
|
||||||
|
|
||||||
|
def get_by_id(self, id):
|
||||||
|
# type: (int) -> BoundFirewall
|
||||||
|
"""Returns a specific Firewall object.
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
:return: :class:`BoundFirewall <hcloud.firewalls.client.BoundFirewall>`
|
||||||
|
"""
|
||||||
|
response = self._client.request(url=f"/firewalls/{id}", method="GET")
|
||||||
|
return BoundFirewall(self, response["firewall"])
|
||||||
|
|
||||||
|
def get_list(
|
||||||
|
self,
|
||||||
|
label_selector=None, # type: Optional[str]
|
||||||
|
page=None, # type: Optional[int]
|
||||||
|
per_page=None, # type: Optional[int]
|
||||||
|
name=None, # type: Optional[str]
|
||||||
|
sort=None, # type: Optional[List[str]]
|
||||||
|
):
|
||||||
|
# type: (...) -> PageResults[List[BoundFirewall]]
|
||||||
|
"""Get a list of floating ips from this account
|
||||||
|
|
||||||
|
:param label_selector: str (optional)
|
||||||
|
Can be used to filter Firewalls by labels. The response will only contain Firewalls matching the label selector values.
|
||||||
|
:param page: int (optional)
|
||||||
|
Specifies the page to fetch
|
||||||
|
:param per_page: int (optional)
|
||||||
|
Specifies how many results are returned by page
|
||||||
|
:param name: str (optional)
|
||||||
|
Can be used to filter networks by their name.
|
||||||
|
:param sort: List[str] (optional)
|
||||||
|
Choices: id name created (You can add one of ":asc", ":desc" to modify sort order. ( ":asc" is default))
|
||||||
|
:return: (List[:class:`BoundFirewall <hcloud.firewalls.client.BoundFirewall>`], :class:`Meta <hcloud.core.domain.Meta>`)
|
||||||
|
"""
|
||||||
|
params = {}
|
||||||
|
|
||||||
|
if label_selector is not None:
|
||||||
|
params["label_selector"] = label_selector
|
||||||
|
if page is not None:
|
||||||
|
params["page"] = page
|
||||||
|
if per_page is not None:
|
||||||
|
params["per_page"] = per_page
|
||||||
|
if name is not None:
|
||||||
|
params["name"] = name
|
||||||
|
if sort is not None:
|
||||||
|
params["sort"] = sort
|
||||||
|
response = self._client.request(url="/firewalls", method="GET", params=params)
|
||||||
|
firewalls = [
|
||||||
|
BoundFirewall(self, firewall_data)
|
||||||
|
for firewall_data in response["firewalls"]
|
||||||
|
]
|
||||||
|
|
||||||
|
return self._add_meta_to_result(firewalls, response)
|
||||||
|
|
||||||
|
def get_all(self, label_selector=None, name=None, sort=None):
|
||||||
|
# type: (Optional[str], Optional[str], Optional[List[str]]) -> List[BoundFirewall]
|
||||||
|
"""Get all floating ips from this account
|
||||||
|
|
||||||
|
:param label_selector: str (optional)
|
||||||
|
Can be used to filter Firewalls by labels. The response will only contain Firewalls matching the label selector values.
|
||||||
|
:param name: str (optional)
|
||||||
|
Can be used to filter networks by their name.
|
||||||
|
:param sort: List[str] (optional)
|
||||||
|
Choices: id name created (You can add one of ":asc", ":desc" to modify sort order. ( ":asc" is default))
|
||||||
|
:return: List[:class:`BoundFirewall <hcloud.firewalls.client.BoundFirewall>`]
|
||||||
|
"""
|
||||||
|
return super().get_all(label_selector=label_selector, name=name, sort=sort)
|
||||||
|
|
||||||
|
def get_by_name(self, name):
|
||||||
|
# type: (str) -> BoundFirewall
|
||||||
|
"""Get Firewall by name
|
||||||
|
|
||||||
|
:param name: str
|
||||||
|
Used to get Firewall by name.
|
||||||
|
:return: :class:`BoundFirewall <hcloud.firewalls.client.BoundFirewall>`
|
||||||
|
"""
|
||||||
|
return super().get_by_name(name)
|
||||||
|
|
||||||
|
def create(
|
||||||
|
self,
|
||||||
|
name, # type: str
|
||||||
|
rules=None, # type: Optional[List[FirewallRule]]
|
||||||
|
labels=None, # type: Optional[str]
|
||||||
|
resources=None, # type: Optional[List[FirewallResource]]
|
||||||
|
):
|
||||||
|
# type: (...) -> CreateFirewallResponse
|
||||||
|
"""Creates a new Firewall.
|
||||||
|
|
||||||
|
:param name: str
|
||||||
|
Firewall Name
|
||||||
|
:param rules: List[:class:`FirewallRule <hcloud.firewalls.domain.FirewallRule>`] (optional)
|
||||||
|
:param labels: Dict[str, str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:param resources: List[:class:`FirewallResource <hcloud.firewalls.domain.FirewallResource>`] (optional)
|
||||||
|
:return: :class:`CreateFirewallResponse <hcloud.firewalls.domain.CreateFirewallResponse>`
|
||||||
|
"""
|
||||||
|
|
||||||
|
data = {"name": name}
|
||||||
|
if labels is not None:
|
||||||
|
data["labels"] = labels
|
||||||
|
|
||||||
|
if rules is not None:
|
||||||
|
data.update({"rules": []})
|
||||||
|
for rule in rules:
|
||||||
|
data["rules"].append(rule.to_payload())
|
||||||
|
if resources is not None:
|
||||||
|
data.update({"apply_to": []})
|
||||||
|
for resource in resources:
|
||||||
|
data["apply_to"].append(resource.to_payload())
|
||||||
|
response = self._client.request(url="/firewalls", json=data, method="POST")
|
||||||
|
|
||||||
|
actions = []
|
||||||
|
if response.get("actions") is not None:
|
||||||
|
actions = [
|
||||||
|
BoundAction(self._client.actions, _) for _ in response["actions"]
|
||||||
|
]
|
||||||
|
|
||||||
|
result = CreateFirewallResponse(
|
||||||
|
firewall=BoundFirewall(self, response["firewall"]), actions=actions
|
||||||
|
)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def update(self, firewall, labels=None, name=None):
|
||||||
|
# type: (Firewall, Optional[Dict[str, str]], Optional[str]) -> BoundFirewall
|
||||||
|
"""Updates the description or labels of a Firewall.
|
||||||
|
|
||||||
|
:param firewall: :class:`BoundFirewall <hcloud.firewalls.client.BoundFirewall>` or :class:`Firewall <hcloud.firewalls.domain.Firewall>`
|
||||||
|
:param labels: Dict[str, str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:param name: str (optional)
|
||||||
|
New name to set
|
||||||
|
:return: :class:`BoundFirewall <hcloud.firewalls.client.BoundFirewall>`
|
||||||
|
"""
|
||||||
|
data = {}
|
||||||
|
if labels is not None:
|
||||||
|
data["labels"] = labels
|
||||||
|
if name is not None:
|
||||||
|
data["name"] = name
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url=f"/firewalls/{firewall.id}",
|
||||||
|
method="PUT",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return BoundFirewall(self, response["firewall"])
|
||||||
|
|
||||||
|
def delete(self, firewall):
|
||||||
|
# type: (Firewall) -> bool
|
||||||
|
"""Deletes a Firewall.
|
||||||
|
|
||||||
|
:param firewall: :class:`BoundFirewall <hcloud.firewalls.client.BoundFirewall>` or :class:`Firewall <hcloud.firewalls.domain.Firewall>`
|
||||||
|
:return: boolean
|
||||||
|
"""
|
||||||
|
self._client.request(
|
||||||
|
url=f"/firewalls/{firewall.id}",
|
||||||
|
method="DELETE",
|
||||||
|
)
|
||||||
|
# Return always true, because the API does not return an action for it. When an error occurs a HcloudAPIException will be raised
|
||||||
|
return True
|
||||||
|
|
||||||
|
def set_rules(self, firewall, rules):
|
||||||
|
# type: (Firewall, List[FirewallRule]) -> List[BoundAction]
|
||||||
|
"""Sets the rules of a Firewall. All existing rules will be overwritten. Pass an empty rules array to remove all rules.
|
||||||
|
|
||||||
|
:param firewall: :class:`BoundFirewall <hcloud.firewalls.client.BoundFirewall>` or :class:`Firewall <hcloud.firewalls.domain.Firewall>`
|
||||||
|
:param rules: List[:class:`FirewallRule <hcloud.firewalls.domain.FirewallRule>`]
|
||||||
|
:return: List[:class:`BoundAction <hcloud.actions.client.BoundAction>`]
|
||||||
|
"""
|
||||||
|
data = {"rules": []}
|
||||||
|
for rule in rules:
|
||||||
|
data["rules"].append(rule.to_payload())
|
||||||
|
response = self._client.request(
|
||||||
|
url="/firewalls/{firewall_id}/actions/set_rules".format(
|
||||||
|
firewall_id=firewall.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return [BoundAction(self._client.actions, _) for _ in response["actions"]]
|
||||||
|
|
||||||
|
def apply_to_resources(self, firewall, resources):
|
||||||
|
# type: (Firewall, List[FirewallResource]) -> List[BoundAction]
|
||||||
|
"""Applies one Firewall to multiple resources.
|
||||||
|
|
||||||
|
:param firewall: :class:`BoundFirewall <hcloud.firewalls.client.BoundFirewall>` or :class:`Firewall <hcloud.firewalls.domain.Firewall>`
|
||||||
|
:param resources: List[:class:`FirewallResource <hcloud.firewalls.domain.FirewallResource>`]
|
||||||
|
:return: List[:class:`BoundAction <hcloud.actions.client.BoundAction>`]
|
||||||
|
"""
|
||||||
|
data = {"apply_to": []}
|
||||||
|
for resource in resources:
|
||||||
|
data["apply_to"].append(resource.to_payload())
|
||||||
|
response = self._client.request(
|
||||||
|
url="/firewalls/{firewall_id}/actions/apply_to_resources".format(
|
||||||
|
firewall_id=firewall.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return [BoundAction(self._client.actions, _) for _ in response["actions"]]
|
||||||
|
|
||||||
|
def remove_from_resources(self, firewall, resources):
|
||||||
|
# type: (Firewall, List[FirewallResource]) -> List[BoundAction]
|
||||||
|
"""Removes one Firewall from multiple resources.
|
||||||
|
|
||||||
|
:param firewall: :class:`BoundFirewall <hcloud.firewalls.client.BoundFirewall>` or :class:`Firewall <hcloud.firewalls.domain.Firewall>`
|
||||||
|
:param resources: List[:class:`FirewallResource <hcloud.firewalls.domain.FirewallResource>`]
|
||||||
|
:return: List[:class:`BoundAction <hcloud.actions.client.BoundAction>`]
|
||||||
|
"""
|
||||||
|
data = {"remove_from": []}
|
||||||
|
for resource in resources:
|
||||||
|
data["remove_from"].append(resource.to_payload())
|
||||||
|
response = self._client.request(
|
||||||
|
url="/firewalls/{firewall_id}/actions/remove_from_resources".format(
|
||||||
|
firewall_id=firewall.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return [BoundAction(self._client.actions, _) for _ in response["actions"]]
|
180
plugins/module_utils/vendor/hcloud/firewalls/domain.py
vendored
Normal file
180
plugins/module_utils/vendor/hcloud/firewalls/domain.py
vendored
Normal file
|
@ -0,0 +1,180 @@
|
||||||
|
try:
|
||||||
|
from dateutil.parser import isoparse
|
||||||
|
except ImportError:
|
||||||
|
isoparse = None
|
||||||
|
|
||||||
|
from ..core.domain import BaseDomain
|
||||||
|
|
||||||
|
|
||||||
|
class Firewall(BaseDomain):
|
||||||
|
"""Firewall Domain
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
ID of the Firewall
|
||||||
|
:param name: str
|
||||||
|
Name of the Firewall
|
||||||
|
:param labels: dict
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:param rules: List[:class:`FirewallRule <hcloud.firewalls.domain.FirewallRule>`]
|
||||||
|
Rules of the Firewall
|
||||||
|
:param applied_to: List[:class:`FirewallResource <hcloud.firewalls.domain.FirewallResource>`]
|
||||||
|
Resources currently using the Firewall
|
||||||
|
:param created: datetime
|
||||||
|
Point in time when the image was created
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("id", "name", "labels", "rules", "applied_to", "created")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self, id=None, name=None, labels=None, rules=None, applied_to=None, created=None
|
||||||
|
):
|
||||||
|
self.id = id
|
||||||
|
self.name = name
|
||||||
|
self.rules = rules
|
||||||
|
self.applied_to = applied_to
|
||||||
|
self.labels = labels
|
||||||
|
self.created = isoparse(created) if created else None
|
||||||
|
|
||||||
|
|
||||||
|
class FirewallRule:
|
||||||
|
"""Firewall Rule Domain
|
||||||
|
|
||||||
|
:param direction: str
|
||||||
|
The Firewall which was created
|
||||||
|
:param port: str
|
||||||
|
Port to which traffic will be allowed, only applicable for protocols TCP and UDP, specify port ranges by using
|
||||||
|
- as a indicator, Sample: 80-85 means all ports between 80 & 85 (80, 82, 83, 84, 85)
|
||||||
|
:param protocol: str
|
||||||
|
Select traffic direction on which rule should be applied. Use source_ips for direction in and destination_ips for direction out.
|
||||||
|
:param source_ips: List[str]
|
||||||
|
List of permitted IPv4/IPv6 addresses in CIDR notation. Use 0.0.0.0/0 to allow all IPv4 addresses and ::/0 to allow all IPv6 addresses. You can specify 100 CIDRs at most.
|
||||||
|
:param destination_ips: List[str]
|
||||||
|
List of permitted IPv4/IPv6 addresses in CIDR notation. Use 0.0.0.0/0 to allow all IPv4 addresses and ::/0 to allow all IPv6 addresses. You can specify 100 CIDRs at most.
|
||||||
|
:param description: str
|
||||||
|
Short description of the firewall rule
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = (
|
||||||
|
"direction",
|
||||||
|
"port",
|
||||||
|
"protocol",
|
||||||
|
"source_ips",
|
||||||
|
"destination_ips",
|
||||||
|
"description",
|
||||||
|
)
|
||||||
|
|
||||||
|
DIRECTION_IN = "in"
|
||||||
|
"""Firewall Rule Direction In"""
|
||||||
|
DIRECTION_OUT = "out"
|
||||||
|
"""Firewall Rule Direction Out"""
|
||||||
|
|
||||||
|
PROTOCOL_UDP = "udp"
|
||||||
|
"""Firewall Rule Protocol UDP"""
|
||||||
|
PROTOCOL_ICMP = "icmp"
|
||||||
|
"""Firewall Rule Protocol ICMP"""
|
||||||
|
PROTOCOL_TCP = "tcp"
|
||||||
|
"""Firewall Rule Protocol TCP"""
|
||||||
|
PROTOCOL_ESP = "esp"
|
||||||
|
"""Firewall Rule Protocol ESP"""
|
||||||
|
PROTOCOL_GRE = "gre"
|
||||||
|
"""Firewall Rule Protocol GRE"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
direction, # type: str
|
||||||
|
protocol, # type: str
|
||||||
|
source_ips, # type: List[str]
|
||||||
|
port=None, # type: Optional[str]
|
||||||
|
destination_ips=None, # type: Optional[List[str]]
|
||||||
|
description=None, # type: Optional[str]
|
||||||
|
):
|
||||||
|
self.direction = direction
|
||||||
|
self.port = port
|
||||||
|
self.protocol = protocol
|
||||||
|
self.source_ips = source_ips
|
||||||
|
self.destination_ips = destination_ips or []
|
||||||
|
self.description = description
|
||||||
|
|
||||||
|
def to_payload(self):
|
||||||
|
payload = {
|
||||||
|
"direction": self.direction,
|
||||||
|
"protocol": self.protocol,
|
||||||
|
"source_ips": self.source_ips,
|
||||||
|
}
|
||||||
|
if len(self.destination_ips) > 0:
|
||||||
|
payload.update({"destination_ips": self.destination_ips})
|
||||||
|
if self.port is not None:
|
||||||
|
payload.update({"port": self.port})
|
||||||
|
if self.description is not None:
|
||||||
|
payload.update({"description": self.description})
|
||||||
|
return payload
|
||||||
|
|
||||||
|
|
||||||
|
class FirewallResource:
|
||||||
|
"""Firewall Used By Domain
|
||||||
|
|
||||||
|
:param type: str
|
||||||
|
Type of resource referenced
|
||||||
|
:param server: Optional[Server]
|
||||||
|
Server the Firewall is applied to
|
||||||
|
:param label_selector: Optional[FirewallResourceLabelSelector]
|
||||||
|
Label Selector for Servers the Firewall should be applied to
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("type", "server", "label_selector")
|
||||||
|
|
||||||
|
TYPE_SERVER = "server"
|
||||||
|
"""Firewall Used By Type Server"""
|
||||||
|
TYPE_LABEL_SELECTOR = "label_selector"
|
||||||
|
"""Firewall Used By Type label_selector"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
type, # type: str
|
||||||
|
server=None, # type: Optional[Server]
|
||||||
|
label_selector=None, # type: Optional[FirewallResourceLabelSelector]
|
||||||
|
):
|
||||||
|
self.type = type
|
||||||
|
self.server = server
|
||||||
|
self.label_selector = label_selector
|
||||||
|
|
||||||
|
def to_payload(self):
|
||||||
|
payload = {"type": self.type}
|
||||||
|
if self.server is not None:
|
||||||
|
payload.update({"server": {"id": self.server.id}})
|
||||||
|
|
||||||
|
if self.label_selector is not None:
|
||||||
|
payload.update(
|
||||||
|
{"label_selector": {"selector": self.label_selector.selector}}
|
||||||
|
)
|
||||||
|
return payload
|
||||||
|
|
||||||
|
|
||||||
|
class FirewallResourceLabelSelector(BaseDomain):
|
||||||
|
"""FirewallResourceLabelSelector Domain
|
||||||
|
|
||||||
|
:param selector: str Target label selector
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, selector=None):
|
||||||
|
self.selector = selector
|
||||||
|
|
||||||
|
|
||||||
|
class CreateFirewallResponse(BaseDomain):
|
||||||
|
"""Create Firewall Response Domain
|
||||||
|
|
||||||
|
:param firewall: :class:`BoundFirewall <hcloud.firewalls.client.BoundFirewall>`
|
||||||
|
The Firewall which was created
|
||||||
|
:param actions: List[:class:`BoundAction <hcloud.actions.client.BoundAction>`]
|
||||||
|
The Action which shows the progress of the Firewall Creation
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("firewall", "actions")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
firewall, # type: BoundFirewall
|
||||||
|
actions, # type: BoundAction
|
||||||
|
):
|
||||||
|
self.firewall = firewall
|
||||||
|
self.actions = actions
|
0
plugins/module_utils/vendor/hcloud/floating_ips/__init__.py
vendored
Normal file
0
plugins/module_utils/vendor/hcloud/floating_ips/__init__.py
vendored
Normal file
422
plugins/module_utils/vendor/hcloud/floating_ips/client.py
vendored
Normal file
422
plugins/module_utils/vendor/hcloud/floating_ips/client.py
vendored
Normal file
|
@ -0,0 +1,422 @@
|
||||||
|
from ..actions.client import BoundAction
|
||||||
|
from ..core.client import BoundModelBase, ClientEntityBase, GetEntityByNameMixin
|
||||||
|
from ..core.domain import add_meta_to_result
|
||||||
|
from ..locations.client import BoundLocation
|
||||||
|
from .domain import CreateFloatingIPResponse, FloatingIP
|
||||||
|
|
||||||
|
|
||||||
|
class BoundFloatingIP(BoundModelBase):
|
||||||
|
model = FloatingIP
|
||||||
|
|
||||||
|
def __init__(self, client, data, complete=True):
|
||||||
|
from ..servers.client import BoundServer
|
||||||
|
|
||||||
|
server = data.get("server")
|
||||||
|
if server is not None:
|
||||||
|
data["server"] = BoundServer(
|
||||||
|
client._client.servers, {"id": server}, complete=False
|
||||||
|
)
|
||||||
|
|
||||||
|
home_location = data.get("home_location")
|
||||||
|
if home_location is not None:
|
||||||
|
data["home_location"] = BoundLocation(
|
||||||
|
client._client.locations, home_location
|
||||||
|
)
|
||||||
|
|
||||||
|
super().__init__(client, data, complete)
|
||||||
|
|
||||||
|
def get_actions_list(self, status=None, sort=None, page=None, per_page=None):
|
||||||
|
# type: (Optional[List[str]], Optional[List[str]], Optional[int], Optional[int]) -> PageResult[BoundAction, Meta]
|
||||||
|
"""Returns all action objects for a Floating IP.
|
||||||
|
|
||||||
|
:param status: List[str] (optional)
|
||||||
|
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
||||||
|
:param sort: List[str] (optional)
|
||||||
|
Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
|
||||||
|
:param page: int (optional)
|
||||||
|
Specifies the page to fetch
|
||||||
|
:param per_page: int (optional)
|
||||||
|
Specifies how many results are returned by page
|
||||||
|
:return: (List[:class:`BoundAction <hcloud.actions.client.BoundAction>`], :class:`Meta <hcloud.core.domain.Meta>`)
|
||||||
|
"""
|
||||||
|
return self._client.get_actions_list(self, status, sort, page, per_page)
|
||||||
|
|
||||||
|
def get_actions(self, status=None, sort=None):
|
||||||
|
# type: (Optional[List[str]], Optional[List[str]]) -> List[BoundAction]
|
||||||
|
"""Returns all action objects for a Floating IP.
|
||||||
|
|
||||||
|
:param status: List[str] (optional)
|
||||||
|
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
||||||
|
:param sort: List[str] (optional)
|
||||||
|
Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
|
||||||
|
|
||||||
|
:return: List[:class:`BoundAction <hcloud.actions.client.BoundAction>`]
|
||||||
|
"""
|
||||||
|
return self._client.get_actions(self, status, sort)
|
||||||
|
|
||||||
|
def update(self, description=None, labels=None, name=None):
|
||||||
|
# type: (Optional[str], Optional[Dict[str, str]], Optional[str]) -> BoundFloatingIP
|
||||||
|
"""Updates the description or labels of a Floating IP.
|
||||||
|
|
||||||
|
:param description: str (optional)
|
||||||
|
New Description to set
|
||||||
|
:param labels: Dict[str, str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:param name: str (optional)
|
||||||
|
New Name to set
|
||||||
|
:return: :class:`BoundFloatingIP <hcloud.floating_ips.client.BoundFloatingIP>`
|
||||||
|
"""
|
||||||
|
return self._client.update(self, description, labels, name)
|
||||||
|
|
||||||
|
def delete(self):
|
||||||
|
# type: () -> bool
|
||||||
|
"""Deletes a Floating IP. If it is currently assigned to a server it will automatically get unassigned.
|
||||||
|
|
||||||
|
:return: boolean
|
||||||
|
"""
|
||||||
|
return self._client.delete(self)
|
||||||
|
|
||||||
|
def change_protection(self, delete=None):
|
||||||
|
# type: (Optional[bool]) -> BoundAction
|
||||||
|
"""Changes the protection configuration of the Floating IP.
|
||||||
|
|
||||||
|
:param delete: boolean
|
||||||
|
If true, prevents the Floating IP from being deleted
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.change_protection(self, delete)
|
||||||
|
|
||||||
|
def assign(self, server):
|
||||||
|
# type: (Server) -> BoundAction
|
||||||
|
"""Assigns a Floating IP to a server.
|
||||||
|
|
||||||
|
:param server: :class:`BoundServer <hcloud.servers.client.BoundServer>` or :class:`Server <hcloud.servers.domain.Server>`
|
||||||
|
Server the Floating IP shall be assigned to
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.assign(self, server)
|
||||||
|
|
||||||
|
def unassign(self):
|
||||||
|
# type: () -> BoundAction
|
||||||
|
"""Unassigns a Floating IP, resulting in it being unreachable. You may assign it to a server again at a later time.
|
||||||
|
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.unassign(self)
|
||||||
|
|
||||||
|
def change_dns_ptr(self, ip, dns_ptr):
|
||||||
|
# type: (str, str) -> BoundAction
|
||||||
|
"""Changes the hostname that will appear when getting the hostname belonging to this Floating IP.
|
||||||
|
|
||||||
|
:param ip: str
|
||||||
|
The IP address for which to set the reverse DNS entry
|
||||||
|
:param dns_ptr: str
|
||||||
|
Hostname to set as a reverse DNS PTR entry, will reset to original default value if `None`
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.change_dns_ptr(self, ip, dns_ptr)
|
||||||
|
|
||||||
|
|
||||||
|
class FloatingIPsClient(ClientEntityBase, GetEntityByNameMixin):
|
||||||
|
results_list_attribute_name = "floating_ips"
|
||||||
|
|
||||||
|
def get_actions_list(
|
||||||
|
self,
|
||||||
|
floating_ip, # type: FloatingIP
|
||||||
|
status=None, # type: Optional[List[str]]
|
||||||
|
sort=None, # type: Optional[List[str]]
|
||||||
|
page=None, # type: Optional[int]
|
||||||
|
per_page=None, # type: Optional[int]
|
||||||
|
):
|
||||||
|
# type: (...) -> PageResults[List[BoundAction], Meta]
|
||||||
|
"""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 = {}
|
||||||
|
if status is not None:
|
||||||
|
params["status"] = status
|
||||||
|
if sort is not None:
|
||||||
|
params["sort"] = sort
|
||||||
|
if page is not None:
|
||||||
|
params["page"] = page
|
||||||
|
if per_page is not None:
|
||||||
|
params["per_page"] = per_page
|
||||||
|
response = self._client.request(
|
||||||
|
url="/floating_ips/{floating_ip_id}/actions".format(
|
||||||
|
floating_ip_id=floating_ip.id
|
||||||
|
),
|
||||||
|
method="GET",
|
||||||
|
params=params,
|
||||||
|
)
|
||||||
|
actions = [
|
||||||
|
BoundAction(self._client.actions, action_data)
|
||||||
|
for action_data in response["actions"]
|
||||||
|
]
|
||||||
|
return add_meta_to_result(actions, response, "actions")
|
||||||
|
|
||||||
|
def get_actions(
|
||||||
|
self,
|
||||||
|
floating_ip, # type: FloatingIP
|
||||||
|
status=None, # type: Optional[List[str]]
|
||||||
|
sort=None, # type: Optional[List[str]]
|
||||||
|
):
|
||||||
|
# type: (...) -> List[BoundAction]
|
||||||
|
"""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`
|
||||||
|
|
||||||
|
:return: List[:class:`BoundAction <hcloud.actions.client.BoundAction>`]
|
||||||
|
"""
|
||||||
|
return super().get_actions(floating_ip, status=status, sort=sort)
|
||||||
|
|
||||||
|
def get_by_id(self, id):
|
||||||
|
# type: (int) -> BoundFloatingIP
|
||||||
|
"""Returns a specific Floating IP object.
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
:return: :class:`BoundFloatingIP <hcloud.floating_ips.client.BoundFloatingIP>`
|
||||||
|
"""
|
||||||
|
response = self._client.request(url=f"/floating_ips/{id}", method="GET")
|
||||||
|
return BoundFloatingIP(self, response["floating_ip"])
|
||||||
|
|
||||||
|
def get_list(
|
||||||
|
self,
|
||||||
|
label_selector=None, # type: Optional[str]
|
||||||
|
page=None, # type: Optional[int]
|
||||||
|
per_page=None, # type: Optional[int]
|
||||||
|
name=None, # type: Optional[str]
|
||||||
|
):
|
||||||
|
# type: (...) -> PageResults[List[BoundFloatingIP]]
|
||||||
|
"""Get a list of floating ips from this account
|
||||||
|
|
||||||
|
:param label_selector: str (optional)
|
||||||
|
Can be used to filter Floating IPs by labels. The response will only contain Floating IPs matching the label selector.able values.
|
||||||
|
:param page: int (optional)
|
||||||
|
Specifies the page to fetch
|
||||||
|
:param per_page: int (optional)
|
||||||
|
Specifies how many results are returned by page
|
||||||
|
:param name: str (optional)
|
||||||
|
Can be used to filter networks by their name.
|
||||||
|
:return: (List[:class:`BoundFloatingIP <hcloud.floating_ips.client.BoundFloatingIP>`], :class:`Meta <hcloud.core.domain.Meta>`)
|
||||||
|
"""
|
||||||
|
params = {}
|
||||||
|
|
||||||
|
if label_selector is not None:
|
||||||
|
params["label_selector"] = label_selector
|
||||||
|
if page is not None:
|
||||||
|
params["page"] = page
|
||||||
|
if per_page is not None:
|
||||||
|
params["per_page"] = per_page
|
||||||
|
if name is not None:
|
||||||
|
params["name"] = name
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url="/floating_ips", method="GET", params=params
|
||||||
|
)
|
||||||
|
floating_ips = [
|
||||||
|
BoundFloatingIP(self, floating_ip_data)
|
||||||
|
for floating_ip_data in response["floating_ips"]
|
||||||
|
]
|
||||||
|
|
||||||
|
return self._add_meta_to_result(floating_ips, response)
|
||||||
|
|
||||||
|
def get_all(self, label_selector=None, name=None):
|
||||||
|
# type: (Optional[str], Optional[str]) -> List[BoundFloatingIP]
|
||||||
|
"""Get all floating ips from this account
|
||||||
|
|
||||||
|
:param label_selector: str (optional)
|
||||||
|
Can be used to filter Floating IPs by labels. The response will only contain Floating IPs matching the label selector.able values.
|
||||||
|
:param name: str (optional)
|
||||||
|
Can be used to filter networks by their name.
|
||||||
|
:return: List[:class:`BoundFloatingIP <hcloud.floating_ips.client.BoundFloatingIP>`]
|
||||||
|
"""
|
||||||
|
return super().get_all(label_selector=label_selector, name=name)
|
||||||
|
|
||||||
|
def get_by_name(self, name):
|
||||||
|
# type: (str) -> BoundFloatingIP
|
||||||
|
"""Get Floating IP by name
|
||||||
|
|
||||||
|
:param name: str
|
||||||
|
Used to get Floating IP by name.
|
||||||
|
:return: :class:`BoundFloatingIP <hcloud.floating_ips.client.BoundFloatingIP>`
|
||||||
|
"""
|
||||||
|
return super().get_by_name(name)
|
||||||
|
|
||||||
|
def create(
|
||||||
|
self,
|
||||||
|
type, # type: str
|
||||||
|
description=None, # type: Optional[str]
|
||||||
|
labels=None, # type: Optional[str]
|
||||||
|
home_location=None, # type: Optional[Location]
|
||||||
|
server=None, # type: Optional[Server]
|
||||||
|
name=None, # type: Optional[str]
|
||||||
|
):
|
||||||
|
# type: (...) -> CreateFloatingIPResponse
|
||||||
|
"""Creates a new Floating IP assigned to a server.
|
||||||
|
|
||||||
|
:param type: str
|
||||||
|
Floating IP type Choices: ipv4, ipv6
|
||||||
|
:param description: str (optional)
|
||||||
|
:param labels: Dict[str, str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:param home_location: :class:`BoundLocation <hcloud.locations.client.BoundLocation>` or :class:`Location <hcloud.locations.domain.Location>` (
|
||||||
|
Home location (routing is optimized for that location). Only optional if server argument is passed.
|
||||||
|
:param server: :class:`BoundServer <hcloud.servers.client.BoundServer>` or :class:`Server <hcloud.servers.domain.Server>`
|
||||||
|
Server to assign the Floating IP to
|
||||||
|
:param name: str (optional)
|
||||||
|
:return: :class:`CreateFloatingIPResponse <hcloud.floating_ips.domain.CreateFloatingIPResponse>`
|
||||||
|
"""
|
||||||
|
|
||||||
|
data = {"type": type}
|
||||||
|
if description is not None:
|
||||||
|
data["description"] = description
|
||||||
|
if labels is not None:
|
||||||
|
data["labels"] = labels
|
||||||
|
if home_location is not None:
|
||||||
|
data["home_location"] = home_location.id_or_name
|
||||||
|
if server is not None:
|
||||||
|
data["server"] = server.id
|
||||||
|
if name is not None:
|
||||||
|
data["name"] = name
|
||||||
|
|
||||||
|
response = self._client.request(url="/floating_ips", json=data, method="POST")
|
||||||
|
|
||||||
|
action = None
|
||||||
|
if response.get("action") is not None:
|
||||||
|
action = BoundAction(self._client.actions, response["action"])
|
||||||
|
|
||||||
|
result = CreateFloatingIPResponse(
|
||||||
|
floating_ip=BoundFloatingIP(self, response["floating_ip"]), action=action
|
||||||
|
)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def update(self, floating_ip, description=None, labels=None, name=None):
|
||||||
|
# type: (FloatingIP, Optional[str], Optional[Dict[str, str]], Optional[str]) -> BoundFloatingIP
|
||||||
|
"""Updates the description or labels of a Floating IP.
|
||||||
|
|
||||||
|
:param floating_ip: :class:`BoundFloatingIP <hcloud.floating_ips.client.BoundFloatingIP>` or :class:`FloatingIP <hcloud.floating_ips.domain.FloatingIP>`
|
||||||
|
:param description: str (optional)
|
||||||
|
New Description to set
|
||||||
|
:param labels: Dict[str, str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:param name: str (optional)
|
||||||
|
New name to set
|
||||||
|
:return: :class:`BoundFloatingIP <hcloud.floating_ips.client.BoundFloatingIP>`
|
||||||
|
"""
|
||||||
|
data = {}
|
||||||
|
if description is not None:
|
||||||
|
data["description"] = description
|
||||||
|
if labels is not None:
|
||||||
|
data["labels"] = labels
|
||||||
|
if name is not None:
|
||||||
|
data["name"] = name
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url=f"/floating_ips/{floating_ip.id}",
|
||||||
|
method="PUT",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return BoundFloatingIP(self, response["floating_ip"])
|
||||||
|
|
||||||
|
def delete(self, floating_ip):
|
||||||
|
# type: (FloatingIP) -> bool
|
||||||
|
"""Deletes a Floating IP. If it is currently assigned to a server it will automatically get unassigned.
|
||||||
|
|
||||||
|
:param floating_ip: :class:`BoundFloatingIP <hcloud.floating_ips.client.BoundFloatingIP>` or :class:`FloatingIP <hcloud.floating_ips.domain.FloatingIP>`
|
||||||
|
:return: boolean
|
||||||
|
"""
|
||||||
|
self._client.request(
|
||||||
|
url=f"/floating_ips/{floating_ip.id}",
|
||||||
|
method="DELETE",
|
||||||
|
)
|
||||||
|
# Return always true, because the API does not return an action for it. When an error occurs a HcloudAPIException will be raised
|
||||||
|
return True
|
||||||
|
|
||||||
|
def change_protection(self, floating_ip, delete=None):
|
||||||
|
# type: (FloatingIP, Optional[bool]) -> BoundAction
|
||||||
|
"""Changes the protection configuration of the Floating IP.
|
||||||
|
|
||||||
|
:param floating_ip: :class:`BoundFloatingIP <hcloud.floating_ips.client.BoundFloatingIP>` or :class:`FloatingIP <hcloud.floating_ips.domain.FloatingIP>`
|
||||||
|
:param delete: boolean
|
||||||
|
If true, prevents the Floating IP from being deleted
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
data = {}
|
||||||
|
if delete is not None:
|
||||||
|
data.update({"delete": delete})
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url="/floating_ips/{floating_ip_id}/actions/change_protection".format(
|
||||||
|
floating_ip_id=floating_ip.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
||||||
|
|
||||||
|
def assign(self, floating_ip, server):
|
||||||
|
# type: (FloatingIP, Server) -> BoundAction
|
||||||
|
"""Assigns a Floating IP to a server.
|
||||||
|
|
||||||
|
:param floating_ip: :class:`BoundFloatingIP <hcloud.floating_ips.client.BoundFloatingIP>` or :class:`FloatingIP <hcloud.floating_ips.domain.FloatingIP>`
|
||||||
|
:param server: :class:`BoundServer <hcloud.servers.client.BoundServer>` or :class:`Server <hcloud.servers.domain.Server>`
|
||||||
|
Server the Floating IP shall be assigned to
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
response = self._client.request(
|
||||||
|
url="/floating_ips/{floating_ip_id}/actions/assign".format(
|
||||||
|
floating_ip_id=floating_ip.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
json={"server": server.id},
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
||||||
|
|
||||||
|
def unassign(self, floating_ip):
|
||||||
|
# type: (FloatingIP) -> BoundAction
|
||||||
|
"""Unassigns a Floating IP, resulting in it being unreachable. You may assign it to a server again at a later time.
|
||||||
|
|
||||||
|
:param floating_ip: :class:`BoundFloatingIP <hcloud.floating_ips.client.BoundFloatingIP>` or :class:`FloatingIP <hcloud.floating_ips.domain.FloatingIP>`
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
response = self._client.request(
|
||||||
|
url="/floating_ips/{floating_ip_id}/actions/unassign".format(
|
||||||
|
floating_ip_id=floating_ip.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
||||||
|
|
||||||
|
def change_dns_ptr(self, floating_ip, ip, dns_ptr):
|
||||||
|
# type: (FloatingIP, str, str) -> BoundAction
|
||||||
|
"""Changes the hostname that will appear when getting the hostname belonging to this Floating IP.
|
||||||
|
|
||||||
|
:param floating_ip: :class:`BoundFloatingIP <hcloud.floating_ips.client.BoundFloatingIP>` or :class:`FloatingIP <hcloud.floating_ips.domain.FloatingIP>`
|
||||||
|
:param ip: str
|
||||||
|
The IP address for which to set the reverse DNS entry
|
||||||
|
:param dns_ptr: str
|
||||||
|
Hostname to set as a reverse DNS PTR entry, will reset to original default value if `None`
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
response = self._client.request(
|
||||||
|
url="/floating_ips/{floating_ip_id}/actions/change_dns_ptr".format(
|
||||||
|
floating_ip_id=floating_ip.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
json={"ip": ip, "dns_ptr": dns_ptr},
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
99
plugins/module_utils/vendor/hcloud/floating_ips/domain.py
vendored
Normal file
99
plugins/module_utils/vendor/hcloud/floating_ips/domain.py
vendored
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
try:
|
||||||
|
from dateutil.parser import isoparse
|
||||||
|
except ImportError:
|
||||||
|
isoparse = None
|
||||||
|
|
||||||
|
from ..core.domain import BaseDomain
|
||||||
|
|
||||||
|
|
||||||
|
class FloatingIP(BaseDomain):
|
||||||
|
"""Floating IP Domain
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
ID of the Floating IP
|
||||||
|
:param description: str, None
|
||||||
|
Description of the Floating IP
|
||||||
|
:param ip: str
|
||||||
|
IP address of the Floating IP
|
||||||
|
:param type: str
|
||||||
|
Type of Floating IP. Choices: `ipv4`, `ipv6`
|
||||||
|
:param server: :class:`BoundServer <hcloud.servers.client.BoundServer>`, None
|
||||||
|
Server the Floating IP is assigned to, None if it is not assigned at all
|
||||||
|
:param dns_ptr: List[Dict]
|
||||||
|
Array of reverse DNS entries
|
||||||
|
:param home_location: :class:`BoundLocation <hcloud.locations.client.BoundLocation>`
|
||||||
|
Location the Floating IP was created in. Routing is optimized for this location.
|
||||||
|
:param blocked: boolean
|
||||||
|
Whether the IP is blocked
|
||||||
|
:param protection: dict
|
||||||
|
Protection configuration for the Floating IP
|
||||||
|
:param labels: dict
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:param created: datetime
|
||||||
|
Point in time when the Floating IP was created
|
||||||
|
:param name: str
|
||||||
|
Name of the Floating IP
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = (
|
||||||
|
"id",
|
||||||
|
"type",
|
||||||
|
"description",
|
||||||
|
"ip",
|
||||||
|
"server",
|
||||||
|
"dns_ptr",
|
||||||
|
"home_location",
|
||||||
|
"blocked",
|
||||||
|
"protection",
|
||||||
|
"labels",
|
||||||
|
"name",
|
||||||
|
"created",
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
id=None,
|
||||||
|
type=None,
|
||||||
|
description=None,
|
||||||
|
ip=None,
|
||||||
|
server=None,
|
||||||
|
dns_ptr=None,
|
||||||
|
home_location=None,
|
||||||
|
blocked=None,
|
||||||
|
protection=None,
|
||||||
|
labels=None,
|
||||||
|
created=None,
|
||||||
|
name=None,
|
||||||
|
):
|
||||||
|
self.id = id
|
||||||
|
self.type = type
|
||||||
|
self.description = description
|
||||||
|
self.ip = ip
|
||||||
|
self.server = server
|
||||||
|
self.dns_ptr = dns_ptr
|
||||||
|
self.home_location = home_location
|
||||||
|
self.blocked = blocked
|
||||||
|
self.protection = protection
|
||||||
|
self.labels = labels
|
||||||
|
self.created = isoparse(created) if created else None
|
||||||
|
self.name = name
|
||||||
|
|
||||||
|
|
||||||
|
class CreateFloatingIPResponse(BaseDomain):
|
||||||
|
"""Create Floating IP Response Domain
|
||||||
|
|
||||||
|
:param floating_ip: :class:`BoundFloatingIP <hcloud.floating_ips.client.BoundFloatingIP>`
|
||||||
|
The Floating IP which was created
|
||||||
|
:param action: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
The Action which shows the progress of the Floating IP Creation
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("floating_ip", "action")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
floating_ip, # type: BoundFloatingIP
|
||||||
|
action, # type: BoundAction
|
||||||
|
):
|
||||||
|
self.floating_ip = floating_ip
|
||||||
|
self.action = action
|
225
plugins/module_utils/vendor/hcloud/hcloud.py
vendored
Normal file
225
plugins/module_utils/vendor/hcloud/hcloud.py
vendored
Normal file
|
@ -0,0 +1,225 @@
|
||||||
|
import time
|
||||||
|
from typing import Optional, Union
|
||||||
|
|
||||||
|
try:
|
||||||
|
import requests
|
||||||
|
except ImportError:
|
||||||
|
requests = None
|
||||||
|
|
||||||
|
from ._version import VERSION
|
||||||
|
from ._exceptions import APIException
|
||||||
|
from .actions.client import ActionsClient
|
||||||
|
from .certificates.client import CertificatesClient
|
||||||
|
from .datacenters.client import DatacentersClient
|
||||||
|
from .firewalls.client import FirewallsClient
|
||||||
|
from .floating_ips.client import FloatingIPsClient
|
||||||
|
from .images.client import ImagesClient
|
||||||
|
from .isos.client import IsosClient
|
||||||
|
from .load_balancer_types.client import LoadBalancerTypesClient
|
||||||
|
from .load_balancers.client import LoadBalancersClient
|
||||||
|
from .locations.client import LocationsClient
|
||||||
|
from .networks.client import NetworksClient
|
||||||
|
from .placement_groups.client import PlacementGroupsClient
|
||||||
|
from .primary_ips.client import PrimaryIPsClient
|
||||||
|
from .server_types.client import ServerTypesClient
|
||||||
|
from .servers.client import ServersClient
|
||||||
|
from .ssh_keys.client import SSHKeysClient
|
||||||
|
from .volumes.client import VolumesClient
|
||||||
|
|
||||||
|
|
||||||
|
class Client:
|
||||||
|
"""Base Client for accessing the Hetzner Cloud API"""
|
||||||
|
|
||||||
|
_version = VERSION
|
||||||
|
_retry_wait_time = 0.5
|
||||||
|
__user_agent_prefix = "hcloud-python"
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
token: str,
|
||||||
|
api_endpoint: str = "https://api.hetzner.cloud/v1",
|
||||||
|
application_name: Optional[str] = None,
|
||||||
|
application_version: Optional[str] = None,
|
||||||
|
poll_interval: int = 1,
|
||||||
|
):
|
||||||
|
"""Create an new Client instance
|
||||||
|
|
||||||
|
:param token: Hetzner Cloud API token
|
||||||
|
:param api_endpoint: Hetzner Cloud API endpoint
|
||||||
|
:param application_name: Your application name
|
||||||
|
:param application_version: Your application _version
|
||||||
|
:param poll_interval: Interval for polling information from Hetzner Cloud API in seconds
|
||||||
|
"""
|
||||||
|
self.token = token
|
||||||
|
self._api_endpoint = api_endpoint
|
||||||
|
self._application_name = application_name
|
||||||
|
self._application_version = application_version
|
||||||
|
self._requests_session = requests.Session()
|
||||||
|
self.poll_interval = poll_interval
|
||||||
|
|
||||||
|
self.datacenters = DatacentersClient(self)
|
||||||
|
"""DatacentersClient Instance
|
||||||
|
|
||||||
|
:type: :class:`DatacentersClient <hcloud.datacenters.client.DatacentersClient>`
|
||||||
|
"""
|
||||||
|
self.locations = LocationsClient(self)
|
||||||
|
"""LocationsClient Instance
|
||||||
|
|
||||||
|
:type: :class:`LocationsClient <hcloud.locations.client.LocationsClient>`
|
||||||
|
"""
|
||||||
|
self.servers = ServersClient(self)
|
||||||
|
"""ServersClient Instance
|
||||||
|
|
||||||
|
:type: :class:`ServersClient <hcloud.servers.client.ServersClient>`
|
||||||
|
"""
|
||||||
|
self.server_types = ServerTypesClient(self)
|
||||||
|
"""ServerTypesClient Instance
|
||||||
|
|
||||||
|
:type: :class:`ServerTypesClient <hcloud.server_types.client.ServerTypesClient>`
|
||||||
|
"""
|
||||||
|
self.volumes = VolumesClient(self)
|
||||||
|
"""VolumesClient Instance
|
||||||
|
|
||||||
|
:type: :class:`VolumesClient <hcloud.volumes.client.VolumesClient>`
|
||||||
|
"""
|
||||||
|
self.actions = ActionsClient(self)
|
||||||
|
"""ActionsClient Instance
|
||||||
|
|
||||||
|
:type: :class:`ActionsClient <hcloud.actions.client.ActionsClient>`
|
||||||
|
"""
|
||||||
|
self.images = ImagesClient(self)
|
||||||
|
"""ImagesClient Instance
|
||||||
|
|
||||||
|
:type: :class:`ImagesClient <hcloud.images.client.ImagesClient>`
|
||||||
|
"""
|
||||||
|
self.isos = IsosClient(self)
|
||||||
|
"""ImagesClient Instance
|
||||||
|
|
||||||
|
:type: :class:`IsosClient <hcloud.isos.client.IsosClient>`
|
||||||
|
"""
|
||||||
|
self.ssh_keys = SSHKeysClient(self)
|
||||||
|
"""SSHKeysClient Instance
|
||||||
|
|
||||||
|
:type: :class:`SSHKeysClient <hcloud.ssh_keys.client.SSHKeysClient>`
|
||||||
|
"""
|
||||||
|
self.floating_ips = FloatingIPsClient(self)
|
||||||
|
"""FloatingIPsClient Instance
|
||||||
|
|
||||||
|
:type: :class:`FloatingIPsClient <hcloud.floating_ips.client.FloatingIPsClient>`
|
||||||
|
"""
|
||||||
|
self.primary_ips = PrimaryIPsClient(self)
|
||||||
|
"""PrimaryIPsClient Instance
|
||||||
|
|
||||||
|
:type: :class:`PrimaryIPsClient <hcloud.primary_ips.client.PrimaryIPsClient>`
|
||||||
|
"""
|
||||||
|
self.networks = NetworksClient(self)
|
||||||
|
"""NetworksClient Instance
|
||||||
|
|
||||||
|
:type: :class:`NetworksClient <hcloud.networks.client.NetworksClient>`
|
||||||
|
"""
|
||||||
|
self.certificates = CertificatesClient(self)
|
||||||
|
"""CertificatesClient Instance
|
||||||
|
|
||||||
|
:type: :class:`CertificatesClient <hcloud.certificates.client.CertificatesClient>`
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.load_balancers = LoadBalancersClient(self)
|
||||||
|
"""LoadBalancersClient Instance
|
||||||
|
|
||||||
|
:type: :class:`LoadBalancersClient <hcloud.load_balancers.client.LoadBalancersClient>`
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.load_balancer_types = LoadBalancerTypesClient(self)
|
||||||
|
"""LoadBalancerTypesClient Instance
|
||||||
|
|
||||||
|
:type: :class:`LoadBalancerTypesClient <hcloud.load_balancer_types.client.LoadBalancerTypesClient>`
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.firewalls = FirewallsClient(self)
|
||||||
|
"""FirewallsClient Instance
|
||||||
|
|
||||||
|
:type: :class:`FirewallsClient <hcloud.firewalls.client.FirewallsClient>`
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.placement_groups = PlacementGroupsClient(self)
|
||||||
|
"""PlacementGroupsClient Instance
|
||||||
|
|
||||||
|
:type: :class:`PlacementGroupsClient <hcloud.placement_groups.client.PlacementGroupsClient>`
|
||||||
|
"""
|
||||||
|
|
||||||
|
def _get_user_agent(self) -> str:
|
||||||
|
"""Get the user agent of the hcloud-python instance with the user application name (if specified)
|
||||||
|
|
||||||
|
:return: The user agent of this hcloud-python instance
|
||||||
|
"""
|
||||||
|
user_agents = []
|
||||||
|
for name, version in [
|
||||||
|
(self._application_name, self._application_version),
|
||||||
|
(self.__user_agent_prefix, self._version),
|
||||||
|
]:
|
||||||
|
if name is not None:
|
||||||
|
user_agents.append(name if version is None else f"{name}/{version}")
|
||||||
|
|
||||||
|
return " ".join(user_agents)
|
||||||
|
|
||||||
|
def _get_headers(self) -> dict:
|
||||||
|
headers = {
|
||||||
|
"User-Agent": self._get_user_agent(),
|
||||||
|
"Authorization": f"Bearer {self.token}",
|
||||||
|
}
|
||||||
|
return headers
|
||||||
|
|
||||||
|
def _raise_exception_from_response(self, response):
|
||||||
|
raise APIException(
|
||||||
|
code=response.status_code,
|
||||||
|
message=response.reason,
|
||||||
|
details={"content": response.content},
|
||||||
|
)
|
||||||
|
|
||||||
|
def _raise_exception_from_content(self, content: dict):
|
||||||
|
raise APIException(
|
||||||
|
code=content["error"]["code"],
|
||||||
|
message=content["error"]["message"],
|
||||||
|
details=content["error"]["details"],
|
||||||
|
)
|
||||||
|
|
||||||
|
def request(
|
||||||
|
self,
|
||||||
|
method: str,
|
||||||
|
url: str,
|
||||||
|
tries: int = 1,
|
||||||
|
**kwargs,
|
||||||
|
) -> Union[bytes, dict]:
|
||||||
|
"""Perform a request to the Hetzner Cloud API, wrapper around requests.request
|
||||||
|
|
||||||
|
:param method: HTTP Method to perform the Request
|
||||||
|
:param url: URL of the Endpoint
|
||||||
|
:param tries: Tries of the request (used internally, should not be set by the user)
|
||||||
|
:return: Response
|
||||||
|
"""
|
||||||
|
response = self._requests_session.request(
|
||||||
|
method=method,
|
||||||
|
url=self._api_endpoint + url,
|
||||||
|
headers=self._get_headers(),
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
content = response.content
|
||||||
|
try:
|
||||||
|
if len(content) > 0:
|
||||||
|
content = response.json()
|
||||||
|
except (TypeError, ValueError):
|
||||||
|
self._raise_exception_from_response(response)
|
||||||
|
|
||||||
|
if not response.ok:
|
||||||
|
if content:
|
||||||
|
if content["error"]["code"] == "rate_limit_exceeded" and tries < 5:
|
||||||
|
time.sleep(tries * self._retry_wait_time)
|
||||||
|
tries = tries + 1
|
||||||
|
return self.request(method, url, tries, **kwargs)
|
||||||
|
else:
|
||||||
|
self._raise_exception_from_content(content)
|
||||||
|
else:
|
||||||
|
self._raise_exception_from_response(response)
|
||||||
|
|
||||||
|
return content
|
0
plugins/module_utils/vendor/hcloud/helpers/__init__.py
vendored
Normal file
0
plugins/module_utils/vendor/hcloud/helpers/__init__.py
vendored
Normal file
39
plugins/module_utils/vendor/hcloud/helpers/labels.py
vendored
Normal file
39
plugins/module_utils/vendor/hcloud/helpers/labels.py
vendored
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import re
|
||||||
|
from typing import Dict
|
||||||
|
|
||||||
|
|
||||||
|
class LabelValidator:
|
||||||
|
KEY_REGEX = re.compile(
|
||||||
|
r"^([a-z0-9A-Z]((?:[\-_.]|[a-z0-9A-Z]){0,253}[a-z0-9A-Z])?/)?[a-z0-9A-Z]((?:[\-_.]|[a-z0-9A-Z]|){0,61}[a-z0-9A-Z])?$"
|
||||||
|
)
|
||||||
|
VALUE_REGEX = re.compile(
|
||||||
|
r"^(([a-z0-9A-Z](?:[\-_.]|[a-z0-9A-Z]){0,61})?[a-z0-9A-Z]$|$)"
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def validate(labels: Dict[str, str]) -> bool:
|
||||||
|
"""Validates Labels. If you want to know which key/value pair of the dict is not correctly formatted
|
||||||
|
use :func:`~hcloud.helpers.labels.validate_verbose`.
|
||||||
|
|
||||||
|
:return: bool
|
||||||
|
"""
|
||||||
|
for k, v in labels.items():
|
||||||
|
if LabelValidator.KEY_REGEX.match(k) is None:
|
||||||
|
return False
|
||||||
|
if LabelValidator.VALUE_REGEX.match(v) is None:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def validate_verbose(labels: Dict[str, str]) -> (bool, str):
|
||||||
|
"""Validates Labels and returns the corresponding error message if something is wrong. Returns True, <empty string>
|
||||||
|
if everything is fine.
|
||||||
|
|
||||||
|
:return: bool, str
|
||||||
|
"""
|
||||||
|
for k, v in labels.items():
|
||||||
|
if LabelValidator.KEY_REGEX.match(k) is None:
|
||||||
|
return False, f"label key {k} is not correctly formatted"
|
||||||
|
if LabelValidator.VALUE_REGEX.match(v) is None:
|
||||||
|
return False, f"label value {v} (key: {k}) is not correctly formatted"
|
||||||
|
return True, ""
|
0
plugins/module_utils/vendor/hcloud/images/__init__.py
vendored
Normal file
0
plugins/module_utils/vendor/hcloud/images/__init__.py
vendored
Normal file
354
plugins/module_utils/vendor/hcloud/images/client.py
vendored
Normal file
354
plugins/module_utils/vendor/hcloud/images/client.py
vendored
Normal file
|
@ -0,0 +1,354 @@
|
||||||
|
from ..actions.client import BoundAction
|
||||||
|
from ..core.client import BoundModelBase, ClientEntityBase, GetEntityByNameMixin
|
||||||
|
from ..core.domain import add_meta_to_result
|
||||||
|
from .domain import Image
|
||||||
|
|
||||||
|
|
||||||
|
class BoundImage(BoundModelBase):
|
||||||
|
model = Image
|
||||||
|
|
||||||
|
def __init__(self, client, data):
|
||||||
|
from ..servers.client import BoundServer
|
||||||
|
|
||||||
|
created_from = data.get("created_from")
|
||||||
|
if created_from is not None:
|
||||||
|
data["created_from"] = BoundServer(
|
||||||
|
client._client.servers, created_from, complete=False
|
||||||
|
)
|
||||||
|
bound_to = data.get("bound_to")
|
||||||
|
if bound_to is not None:
|
||||||
|
data["bound_to"] = BoundServer(
|
||||||
|
client._client.servers, {"id": bound_to}, complete=False
|
||||||
|
)
|
||||||
|
|
||||||
|
super().__init__(client, data)
|
||||||
|
|
||||||
|
def get_actions_list(self, sort=None, page=None, per_page=None, status=None):
|
||||||
|
# type: (Optional[List[str]], Optional[int], Optional[int], Optional[List[str]]) -> PageResult[BoundAction, Meta]
|
||||||
|
"""Returns a list of action objects for the 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>`)
|
||||||
|
"""
|
||||||
|
return self._client.get_actions_list(
|
||||||
|
self, sort=sort, page=page, per_page=per_page, status=status
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_actions(self, sort=None, status=None):
|
||||||
|
# type: (Optional[List[str]], Optional[List[str]]) -> List[BoundAction]
|
||||||
|
"""Returns all action objects for the image.
|
||||||
|
|
||||||
|
:param status: List[str] (optional)
|
||||||
|
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
||||||
|
:param sort: List[str] (optional)
|
||||||
|
Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
|
||||||
|
:return: List[:class:`BoundAction <hcloud.actions.client.BoundAction>`]
|
||||||
|
"""
|
||||||
|
return self._client.get_actions(self, status=status, sort=sort)
|
||||||
|
|
||||||
|
def update(self, description=None, type=None, labels=None):
|
||||||
|
# type: (Optional[str], Optional[str], Optional[Dict[str, str]]) -> BoundImage
|
||||||
|
"""Updates the Image. You may change the description, convert a Backup image to a Snapshot Image or change the image labels.
|
||||||
|
|
||||||
|
:param description: str (optional)
|
||||||
|
New description of Image
|
||||||
|
:param type: str (optional)
|
||||||
|
Destination image type to convert to
|
||||||
|
Choices: snapshot
|
||||||
|
:param labels: Dict[str, str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:return: :class:`BoundImage <hcloud.images.client.BoundImage>`
|
||||||
|
"""
|
||||||
|
return self._client.update(self, description, type, labels)
|
||||||
|
|
||||||
|
def delete(self):
|
||||||
|
# type: () -> bool
|
||||||
|
"""Deletes an Image. Only images of type snapshot and backup can be deleted.
|
||||||
|
|
||||||
|
:return: bool
|
||||||
|
"""
|
||||||
|
return self._client.delete(self)
|
||||||
|
|
||||||
|
def change_protection(self, delete=None):
|
||||||
|
# type: (Optional[bool]) -> BoundAction
|
||||||
|
"""Changes the protection configuration of the image. Can only be used on snapshots.
|
||||||
|
|
||||||
|
:param delete: bool
|
||||||
|
If true, prevents the snapshot from being deleted
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.change_protection(self, delete)
|
||||||
|
|
||||||
|
|
||||||
|
class ImagesClient(ClientEntityBase, GetEntityByNameMixin):
|
||||||
|
results_list_attribute_name = "images"
|
||||||
|
|
||||||
|
def get_actions_list(
|
||||||
|
self,
|
||||||
|
image, # type: Image
|
||||||
|
sort=None, # type: Optional[List[str]]
|
||||||
|
page=None, # type: Optional[int]
|
||||||
|
per_page=None, # type: Optional[int]
|
||||||
|
status=None, # type: Optional[List[str]]
|
||||||
|
):
|
||||||
|
# type: (...) -> PageResults[List[BoundAction], Meta]
|
||||||
|
"""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 = {}
|
||||||
|
if sort is not None:
|
||||||
|
params["sort"] = sort
|
||||||
|
if status is not None:
|
||||||
|
params["status"] = status
|
||||||
|
if page is not None:
|
||||||
|
params["page"] = page
|
||||||
|
if per_page is not None:
|
||||||
|
params["per_page"] = per_page
|
||||||
|
response = self._client.request(
|
||||||
|
url=f"/images/{image.id}/actions",
|
||||||
|
method="GET",
|
||||||
|
params=params,
|
||||||
|
)
|
||||||
|
actions = [
|
||||||
|
BoundAction(self._client.actions, action_data)
|
||||||
|
for action_data in response["actions"]
|
||||||
|
]
|
||||||
|
return add_meta_to_result(actions, response, "actions")
|
||||||
|
|
||||||
|
def get_actions(
|
||||||
|
self,
|
||||||
|
image, # type: Image
|
||||||
|
sort=None, # type: Optional[List[str]]
|
||||||
|
status=None, # type: Optional[List[str]]
|
||||||
|
):
|
||||||
|
# type: (...) -> List[BoundAction]
|
||||||
|
"""Returns all 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` `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 super().get_actions(image, sort=sort, status=status)
|
||||||
|
|
||||||
|
def get_by_id(self, id):
|
||||||
|
# type: (int) -> BoundImage
|
||||||
|
"""Get a specific Image
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
:return: :class:`BoundImage <hcloud.images.client.BoundImage
|
||||||
|
"""
|
||||||
|
response = self._client.request(url=f"/images/{id}", method="GET")
|
||||||
|
return BoundImage(self, response["image"])
|
||||||
|
|
||||||
|
def get_list(
|
||||||
|
self,
|
||||||
|
name=None, # type: Optional[str]
|
||||||
|
label_selector=None, # type: Optional[str]
|
||||||
|
bound_to=None, # type: Optional[List[str]]
|
||||||
|
type=None, # type: Optional[List[str]]
|
||||||
|
architecture=None, # type: Optional[List[str]]
|
||||||
|
sort=None, # type: Optional[List[str]]
|
||||||
|
page=None, # type: Optional[int]
|
||||||
|
per_page=None, # type: Optional[int]
|
||||||
|
status=None, # type: Optional[List[str]]
|
||||||
|
include_deprecated=None, # type: Optional[bool]
|
||||||
|
):
|
||||||
|
# type: (...) -> PageResults[List[BoundImage]]
|
||||||
|
"""Get all images
|
||||||
|
|
||||||
|
:param name: str (optional)
|
||||||
|
Can be used to filter images by their name.
|
||||||
|
:param label_selector: str (optional)
|
||||||
|
Can be used to filter servers by labels. The response will only contain servers matching the label selector.
|
||||||
|
:param bound_to: List[str] (optional)
|
||||||
|
Server Id linked to the image. Only available for images of type backup
|
||||||
|
:param type: List[str] (optional)
|
||||||
|
Choices: system snapshot backup
|
||||||
|
:param architecture: List[str] (optional)
|
||||||
|
Choices: x86 arm
|
||||||
|
:param status: List[str] (optional)
|
||||||
|
Can be used to filter images by their status. The response will only contain images matching the status.
|
||||||
|
:param sort: List[str] (optional)
|
||||||
|
Choices: id id:asc id:desc name name:asc name:desc created created:asc created:desc
|
||||||
|
:param include_deprecated: bool (optional)
|
||||||
|
Include deprecated images in the response. Default: False
|
||||||
|
: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:`BoundImage <hcloud.images.client.BoundImage>`], :class:`Meta <hcloud.core.domain.Meta>`)
|
||||||
|
"""
|
||||||
|
params = {}
|
||||||
|
if name is not None:
|
||||||
|
params["name"] = name
|
||||||
|
if label_selector is not None:
|
||||||
|
params["label_selector"] = label_selector
|
||||||
|
if bound_to is not None:
|
||||||
|
params["bound_to"] = bound_to
|
||||||
|
if type is not None:
|
||||||
|
params["type"] = type
|
||||||
|
if architecture is not None:
|
||||||
|
params["architecture"] = architecture
|
||||||
|
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
|
||||||
|
if status is not None:
|
||||||
|
params["status"] = per_page
|
||||||
|
if include_deprecated is not None:
|
||||||
|
params["include_deprecated"] = include_deprecated
|
||||||
|
response = self._client.request(url="/images", method="GET", params=params)
|
||||||
|
images = [BoundImage(self, image_data) for image_data in response["images"]]
|
||||||
|
|
||||||
|
return self._add_meta_to_result(images, response)
|
||||||
|
|
||||||
|
def get_all(
|
||||||
|
self,
|
||||||
|
name=None, # type: Optional[str]
|
||||||
|
label_selector=None, # type: Optional[str]
|
||||||
|
bound_to=None, # type: Optional[List[str]]
|
||||||
|
type=None, # type: Optional[List[str]]
|
||||||
|
architecture=None, # type: Optional[List[str]]
|
||||||
|
sort=None, # type: Optional[List[str]]
|
||||||
|
status=None, # type: Optional[List[str]]
|
||||||
|
include_deprecated=None, # type: Optional[bool]
|
||||||
|
):
|
||||||
|
# type: (...) -> List[BoundImage]
|
||||||
|
"""Get all images
|
||||||
|
|
||||||
|
:param name: str (optional)
|
||||||
|
Can be used to filter images by their name.
|
||||||
|
:param label_selector: str (optional)
|
||||||
|
Can be used to filter servers by labels. The response will only contain servers matching the label selector.
|
||||||
|
:param bound_to: List[str] (optional)
|
||||||
|
Server Id linked to the image. Only available for images of type backup
|
||||||
|
:param type: List[str] (optional)
|
||||||
|
Choices: system snapshot backup
|
||||||
|
:param architecture: List[str] (optional)
|
||||||
|
Choices: x86 arm
|
||||||
|
:param status: List[str] (optional)
|
||||||
|
Can be used to filter images by their status. The response will only contain images matching the status.
|
||||||
|
:param sort: List[str] (optional)
|
||||||
|
Choices: id name created (You can add one of ":asc", ":desc" to modify sort order. ( ":asc" is default))
|
||||||
|
:param include_deprecated: bool (optional)
|
||||||
|
Include deprecated images in the response. Default: False
|
||||||
|
:return: List[:class:`BoundImage <hcloud.images.client.BoundImage>`]
|
||||||
|
"""
|
||||||
|
return super().get_all(
|
||||||
|
name=name,
|
||||||
|
label_selector=label_selector,
|
||||||
|
bound_to=bound_to,
|
||||||
|
type=type,
|
||||||
|
architecture=architecture,
|
||||||
|
sort=sort,
|
||||||
|
status=status,
|
||||||
|
include_deprecated=include_deprecated,
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_by_name(self, name):
|
||||||
|
# type: (str) -> BoundImage
|
||||||
|
"""Get image by name
|
||||||
|
|
||||||
|
Deprecated: Use get_by_name_and_architecture instead.
|
||||||
|
|
||||||
|
:param name: str
|
||||||
|
Used to get image by name.
|
||||||
|
:return: :class:`BoundImage <hcloud.images.client.BoundImage>`
|
||||||
|
"""
|
||||||
|
return super().get_by_name(name)
|
||||||
|
|
||||||
|
def get_by_name_and_architecture(self, name, architecture):
|
||||||
|
# type: (str, str) -> BoundImage
|
||||||
|
"""Get image by name
|
||||||
|
|
||||||
|
:param name: str
|
||||||
|
Used to identify the image.
|
||||||
|
:param architecture: str
|
||||||
|
Used to identify the image.
|
||||||
|
:return: :class:`BoundImage <hcloud.images.client.BoundImage>`
|
||||||
|
"""
|
||||||
|
response = self.get_list(name=name, architecture=[architecture])
|
||||||
|
entities = getattr(response, self.results_list_attribute_name)
|
||||||
|
entity = entities[0] if entities else None
|
||||||
|
return entity
|
||||||
|
|
||||||
|
def update(self, image, description=None, type=None, labels=None):
|
||||||
|
# type:(Image, Optional[str], Optional[str], Optional[Dict[str, str]]) -> BoundImage
|
||||||
|
"""Updates the Image. You may change the description, convert a Backup image to a Snapshot Image or change the image labels.
|
||||||
|
|
||||||
|
:param image: :class:`BoundImage <hcloud.images.client.BoundImage>` or :class:`Image <hcloud.images.domain.Image>`
|
||||||
|
:param description: str (optional)
|
||||||
|
New description of Image
|
||||||
|
:param type: str (optional)
|
||||||
|
Destination image type to convert to
|
||||||
|
Choices: snapshot
|
||||||
|
:param labels: Dict[str, str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:return: :class:`BoundImage <hcloud.images.client.BoundImage>`
|
||||||
|
"""
|
||||||
|
data = {}
|
||||||
|
if description is not None:
|
||||||
|
data.update({"description": description})
|
||||||
|
if type is not None:
|
||||||
|
data.update({"type": type})
|
||||||
|
if labels is not None:
|
||||||
|
data.update({"labels": labels})
|
||||||
|
response = self._client.request(
|
||||||
|
url=f"/images/{image.id}", method="PUT", json=data
|
||||||
|
)
|
||||||
|
return BoundImage(self, response["image"])
|
||||||
|
|
||||||
|
def delete(self, image):
|
||||||
|
# type: (Image) -> bool
|
||||||
|
"""Deletes an Image. Only images of type snapshot and backup can be deleted.
|
||||||
|
|
||||||
|
:param :class:`BoundImage <hcloud.images.client.BoundImage>` or :class:`Image <hcloud.images.domain.Image>`
|
||||||
|
:return: bool
|
||||||
|
"""
|
||||||
|
self._client.request(url=f"/images/{image.id}", method="DELETE")
|
||||||
|
# Return allays true, because the API does not return an action for it. When an error occurs a APIException will be raised
|
||||||
|
return True
|
||||||
|
|
||||||
|
def change_protection(self, image, delete=None):
|
||||||
|
# type: (Image, Optional[bool]) -> BoundAction
|
||||||
|
"""Changes the protection configuration of the image. Can only be used on snapshots.
|
||||||
|
|
||||||
|
:param image: :class:`BoundImage <hcloud.images.client.BoundImage>` or :class:`Image <hcloud.images.domain.Image>`
|
||||||
|
:param delete: bool
|
||||||
|
If true, prevents the snapshot from being deleted
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
data = {}
|
||||||
|
if delete is not None:
|
||||||
|
data.update({"delete": delete})
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url="/images/{image_id}/actions/change_protection".format(
|
||||||
|
image_id=image.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
124
plugins/module_utils/vendor/hcloud/images/domain.py
vendored
Normal file
124
plugins/module_utils/vendor/hcloud/images/domain.py
vendored
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
try:
|
||||||
|
from dateutil.parser import isoparse
|
||||||
|
except ImportError:
|
||||||
|
isoparse = None
|
||||||
|
|
||||||
|
from ..core.domain import BaseDomain, DomainIdentityMixin
|
||||||
|
|
||||||
|
|
||||||
|
class Image(BaseDomain, DomainIdentityMixin):
|
||||||
|
"""Image Domain
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
ID of the image
|
||||||
|
:param type: str
|
||||||
|
Type of the image Choices: `system`, `snapshot`, `backup`, `app`
|
||||||
|
:param status: str
|
||||||
|
Whether the image can be used or if it’s still being created Choices: `available`, `creating`
|
||||||
|
:param name: str, None
|
||||||
|
Unique identifier of the image. This value is only set for system images.
|
||||||
|
:param description: str
|
||||||
|
Description of the image
|
||||||
|
:param image_size: number, None
|
||||||
|
Size of the image file in our storage in GB. For snapshot images this is the value relevant for calculating costs for the image.
|
||||||
|
:param disk_size: number
|
||||||
|
Size of the disk contained in the image in GB.
|
||||||
|
:param created: datetime
|
||||||
|
Point in time when the image was created
|
||||||
|
:param created_from: :class:`BoundServer <hcloud.servers.client.BoundServer>`, None
|
||||||
|
Information about the server the image was created from
|
||||||
|
:param bound_to: :class:`BoundServer <hcloud.servers.client.BoundServer>`, None
|
||||||
|
ID of server the image is bound to. Only set for images of type `backup`.
|
||||||
|
:param os_flavor: str
|
||||||
|
Flavor of operating system contained in the image Choices: `ubuntu`, `centos`, `debian`, `fedora`, `unknown`
|
||||||
|
:param os_version: str, None
|
||||||
|
Operating system version
|
||||||
|
:param architecture: str
|
||||||
|
CPU Architecture that the image is compatible with. Choices: `x86`, `arm`
|
||||||
|
:param rapid_deploy: bool
|
||||||
|
Indicates that rapid deploy of the image is available
|
||||||
|
:param protection: dict
|
||||||
|
Protection configuration for the image
|
||||||
|
:param deprecated: datetime, None
|
||||||
|
Point in time when the image is considered to be deprecated (in ISO-8601 format)
|
||||||
|
:param labels: Dict
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = (
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"type",
|
||||||
|
"description",
|
||||||
|
"image_size",
|
||||||
|
"disk_size",
|
||||||
|
"bound_to",
|
||||||
|
"os_flavor",
|
||||||
|
"os_version",
|
||||||
|
"architecture",
|
||||||
|
"rapid_deploy",
|
||||||
|
"created_from",
|
||||||
|
"status",
|
||||||
|
"protection",
|
||||||
|
"labels",
|
||||||
|
"created",
|
||||||
|
"deprecated",
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
id=None,
|
||||||
|
name=None,
|
||||||
|
type=None,
|
||||||
|
created=None,
|
||||||
|
description=None,
|
||||||
|
image_size=None,
|
||||||
|
disk_size=None,
|
||||||
|
deprecated=None,
|
||||||
|
bound_to=None,
|
||||||
|
os_flavor=None,
|
||||||
|
os_version=None,
|
||||||
|
architecture=None,
|
||||||
|
rapid_deploy=None,
|
||||||
|
created_from=None,
|
||||||
|
protection=None,
|
||||||
|
labels=None,
|
||||||
|
status=None,
|
||||||
|
):
|
||||||
|
self.id = id
|
||||||
|
self.name = name
|
||||||
|
self.type = type
|
||||||
|
self.created = isoparse(created) if created else None
|
||||||
|
self.description = description
|
||||||
|
self.image_size = image_size
|
||||||
|
self.disk_size = disk_size
|
||||||
|
self.deprecated = isoparse(deprecated) if deprecated else None
|
||||||
|
self.bound_to = bound_to
|
||||||
|
self.os_flavor = os_flavor
|
||||||
|
self.os_version = os_version
|
||||||
|
self.architecture = architecture
|
||||||
|
self.rapid_deploy = rapid_deploy
|
||||||
|
self.created_from = created_from
|
||||||
|
self.protection = protection
|
||||||
|
self.labels = labels
|
||||||
|
self.status = status
|
||||||
|
|
||||||
|
|
||||||
|
class CreateImageResponse(BaseDomain):
|
||||||
|
"""Create Image Response Domain
|
||||||
|
|
||||||
|
:param image: :class:`BoundImage <hcloud.images.client.BoundImage>`
|
||||||
|
The Image which was created
|
||||||
|
:param action: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
The Action which shows the progress of the Floating IP Creation
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("action", "image")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
action, # type: BoundAction
|
||||||
|
image, # type: BoundImage
|
||||||
|
):
|
||||||
|
self.action = action
|
||||||
|
self.image = image
|
0
plugins/module_utils/vendor/hcloud/isos/__init__.py
vendored
Normal file
0
plugins/module_utils/vendor/hcloud/isos/__init__.py
vendored
Normal file
118
plugins/module_utils/vendor/hcloud/isos/client.py
vendored
Normal file
118
plugins/module_utils/vendor/hcloud/isos/client.py
vendored
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
from warnings import warn
|
||||||
|
|
||||||
|
from ..core.client import BoundModelBase, ClientEntityBase, GetEntityByNameMixin
|
||||||
|
from .domain import Iso
|
||||||
|
|
||||||
|
|
||||||
|
class BoundIso(BoundModelBase):
|
||||||
|
model = Iso
|
||||||
|
|
||||||
|
|
||||||
|
class IsosClient(ClientEntityBase, GetEntityByNameMixin):
|
||||||
|
results_list_attribute_name = "isos"
|
||||||
|
|
||||||
|
def get_by_id(self, id):
|
||||||
|
# type: (int) -> BoundIso
|
||||||
|
"""Get a specific ISO by its id
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
:return: :class:`BoundIso <hcloud.isos.client.BoundIso>`
|
||||||
|
"""
|
||||||
|
response = self._client.request(url=f"/isos/{id}", method="GET")
|
||||||
|
return BoundIso(self, response["iso"])
|
||||||
|
|
||||||
|
def get_list(
|
||||||
|
self,
|
||||||
|
name=None, # type: Optional[str]
|
||||||
|
architecture=None, # type: Optional[List[str]]
|
||||||
|
include_wildcard_architecture=None, # type: Optional[bool]
|
||||||
|
include_architecture_wildcard=None, # type: Optional[bool]
|
||||||
|
page=None, # type: Optional[int]
|
||||||
|
per_page=None, # type: Optional[int]
|
||||||
|
):
|
||||||
|
# type: (...) -> PageResults[List[BoundIso], Meta]
|
||||||
|
"""Get a list of ISOs
|
||||||
|
|
||||||
|
:param name: str (optional)
|
||||||
|
Can be used to filter ISOs by their name.
|
||||||
|
:param architecture: List[str] (optional)
|
||||||
|
Can be used to filter ISOs by their architecture. Choices: x86 arm
|
||||||
|
:param include_wildcard_architecture: bool (optional)
|
||||||
|
Deprecated, please use `include_architecture_wildcard` instead.
|
||||||
|
:param include_architecture_wildcard: bool (optional)
|
||||||
|
Custom ISOs do not have an architecture set. You must also set this flag to True if you are filtering by
|
||||||
|
architecture and also want custom ISOs.
|
||||||
|
: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:`BoundIso <hcloud.isos.client.BoundIso>`], :class:`Meta <hcloud.core.domain.Meta>`)
|
||||||
|
"""
|
||||||
|
|
||||||
|
if include_wildcard_architecture is not None:
|
||||||
|
warn(
|
||||||
|
"The `include_wildcard_architecture` argument is deprecated, please use the `include_architecture_wildcard` argument instead.",
|
||||||
|
DeprecationWarning,
|
||||||
|
)
|
||||||
|
include_architecture_wildcard = include_wildcard_architecture
|
||||||
|
|
||||||
|
params = {}
|
||||||
|
if name is not None:
|
||||||
|
params["name"] = name
|
||||||
|
if architecture is not None:
|
||||||
|
params["architecture"] = architecture
|
||||||
|
if include_architecture_wildcard is not None:
|
||||||
|
params["include_architecture_wildcard"] = include_architecture_wildcard
|
||||||
|
if page is not None:
|
||||||
|
params["page"] = page
|
||||||
|
if per_page is not None:
|
||||||
|
params["per_page"] = per_page
|
||||||
|
|
||||||
|
response = self._client.request(url="/isos", method="GET", params=params)
|
||||||
|
isos = [BoundIso(self, iso_data) for iso_data in response["isos"]]
|
||||||
|
return self._add_meta_to_result(isos, response)
|
||||||
|
|
||||||
|
def get_all(
|
||||||
|
self,
|
||||||
|
name=None, # type: Optional[str]
|
||||||
|
architecture=None, # type: Optional[List[str]]
|
||||||
|
include_wildcard_architecture=None, # type: Optional[bool]
|
||||||
|
include_architecture_wildcard=None, # type: Optional[bool]
|
||||||
|
):
|
||||||
|
# type: (...) -> List[BoundIso]
|
||||||
|
"""Get all ISOs
|
||||||
|
|
||||||
|
:param name: str (optional)
|
||||||
|
Can be used to filter ISOs by their name.
|
||||||
|
:param architecture: List[str] (optional)
|
||||||
|
Can be used to filter ISOs by their architecture. Choices: x86 arm
|
||||||
|
:param include_wildcard_architecture: bool (optional)
|
||||||
|
Deprecated, please use `include_architecture_wildcard` instead.
|
||||||
|
:param include_architecture_wildcard: bool (optional)
|
||||||
|
Custom ISOs do not have an architecture set. You must also set this flag to True if you are filtering by
|
||||||
|
architecture and also want custom ISOs.
|
||||||
|
:return: List[:class:`BoundIso <hcloud.isos.client.BoundIso>`]
|
||||||
|
"""
|
||||||
|
|
||||||
|
if include_wildcard_architecture is not None:
|
||||||
|
warn(
|
||||||
|
"The `include_wildcard_architecture` argument is deprecated, please use the `include_architecture_wildcard` argument instead.",
|
||||||
|
DeprecationWarning,
|
||||||
|
)
|
||||||
|
include_architecture_wildcard = include_wildcard_architecture
|
||||||
|
|
||||||
|
return super().get_all(
|
||||||
|
name=name,
|
||||||
|
architecture=architecture,
|
||||||
|
include_architecture_wildcard=include_architecture_wildcard,
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_by_name(self, name):
|
||||||
|
# type: (str) -> BoundIso
|
||||||
|
"""Get iso by name
|
||||||
|
|
||||||
|
:param name: str
|
||||||
|
Used to get iso by name.
|
||||||
|
:return: :class:`BoundIso <hcloud.isos.client.BoundIso>`
|
||||||
|
"""
|
||||||
|
return super().get_by_name(name)
|
42
plugins/module_utils/vendor/hcloud/isos/domain.py
vendored
Normal file
42
plugins/module_utils/vendor/hcloud/isos/domain.py
vendored
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
try:
|
||||||
|
from dateutil.parser import isoparse
|
||||||
|
except ImportError:
|
||||||
|
isoparse = None
|
||||||
|
|
||||||
|
from ..core.domain import BaseDomain, DomainIdentityMixin
|
||||||
|
|
||||||
|
|
||||||
|
class Iso(BaseDomain, DomainIdentityMixin):
|
||||||
|
"""Iso Domain
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
ID of the ISO
|
||||||
|
:param name: str, None
|
||||||
|
Unique identifier of the ISO. Only set for public ISOs
|
||||||
|
:param description: str
|
||||||
|
Description of the ISO
|
||||||
|
:param type: str
|
||||||
|
Type of the ISO. Choices: `public`, `private`
|
||||||
|
:param architecture: str, None
|
||||||
|
CPU Architecture that the ISO is compatible with. None means that the compatibility is unknown. Choices: `x86`, `arm`
|
||||||
|
:param deprecated: datetime, None
|
||||||
|
ISO 8601 timestamp of deprecation, None if ISO is still available. After the deprecation time it will no longer be possible to attach the ISO to servers.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("id", "name", "type", "architecture", "description", "deprecated")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
id=None,
|
||||||
|
name=None,
|
||||||
|
type=None,
|
||||||
|
architecture=None,
|
||||||
|
description=None,
|
||||||
|
deprecated=None,
|
||||||
|
):
|
||||||
|
self.id = id
|
||||||
|
self.name = name
|
||||||
|
self.type = type
|
||||||
|
self.architecture = architecture
|
||||||
|
self.description = description
|
||||||
|
self.deprecated = isoparse(deprecated) if deprecated else None
|
0
plugins/module_utils/vendor/hcloud/load_balancer_types/__init__.py
vendored
Normal file
0
plugins/module_utils/vendor/hcloud/load_balancer_types/__init__.py
vendored
Normal file
74
plugins/module_utils/vendor/hcloud/load_balancer_types/client.py
vendored
Normal file
74
plugins/module_utils/vendor/hcloud/load_balancer_types/client.py
vendored
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
from ..core.client import BoundModelBase, ClientEntityBase, GetEntityByNameMixin
|
||||||
|
from .domain import LoadBalancerType
|
||||||
|
|
||||||
|
|
||||||
|
class BoundLoadBalancerType(BoundModelBase):
|
||||||
|
model = LoadBalancerType
|
||||||
|
|
||||||
|
|
||||||
|
class LoadBalancerTypesClient(ClientEntityBase, GetEntityByNameMixin):
|
||||||
|
results_list_attribute_name = "load_balancer_types"
|
||||||
|
|
||||||
|
def get_by_id(self, id):
|
||||||
|
# type: (int) -> load_balancer_types.client.BoundLoadBalancerType
|
||||||
|
"""Returns a specific Load Balancer Type.
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
:return: :class:`BoundLoadBalancerType <hcloud.load_balancer_type.client.BoundLoadBalancerType>`
|
||||||
|
"""
|
||||||
|
response = self._client.request(
|
||||||
|
url="/load_balancer_types/{load_balancer_type_id}".format(
|
||||||
|
load_balancer_type_id=id
|
||||||
|
),
|
||||||
|
method="GET",
|
||||||
|
)
|
||||||
|
return BoundLoadBalancerType(self, response["load_balancer_type"])
|
||||||
|
|
||||||
|
def get_list(self, name=None, page=None, per_page=None):
|
||||||
|
# type: (Optional[str], Optional[int], Optional[int]) -> PageResults[List[BoundLoadBalancerType], Meta]
|
||||||
|
"""Get a list of Load Balancer types
|
||||||
|
|
||||||
|
:param name: str (optional)
|
||||||
|
Can be used to filter Load Balancer type by their name.
|
||||||
|
: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:`BoundLoadBalancerType <hcloud.load_balancer_types.client.BoundLoadBalancerType>`], :class:`Meta <hcloud.core.domain.Meta>`)
|
||||||
|
"""
|
||||||
|
params = {}
|
||||||
|
if name is not None:
|
||||||
|
params["name"] = name
|
||||||
|
if page is not None:
|
||||||
|
params["page"] = page
|
||||||
|
if per_page is not None:
|
||||||
|
params["per_page"] = per_page
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url="/load_balancer_types", method="GET", params=params
|
||||||
|
)
|
||||||
|
load_balancer_types = [
|
||||||
|
BoundLoadBalancerType(self, load_balancer_type_data)
|
||||||
|
for load_balancer_type_data in response["load_balancer_types"]
|
||||||
|
]
|
||||||
|
return self._add_meta_to_result(load_balancer_types, response)
|
||||||
|
|
||||||
|
def get_all(self, name=None):
|
||||||
|
# type: (Optional[str]) -> List[BoundLoadBalancerType]
|
||||||
|
"""Get all Load Balancer types
|
||||||
|
|
||||||
|
:param name: str (optional)
|
||||||
|
Can be used to filter Load Balancer type by their name.
|
||||||
|
:return: List[:class:`BoundLoadBalancerType <hcloud.load_balancer_types.client.BoundLoadBalancerType>`]
|
||||||
|
"""
|
||||||
|
return super().get_all(name=name)
|
||||||
|
|
||||||
|
def get_by_name(self, name):
|
||||||
|
# type: (str) -> BoundLoadBalancerType
|
||||||
|
"""Get Load Balancer type by name
|
||||||
|
|
||||||
|
:param name: str
|
||||||
|
Used to get Load Balancer type by name.
|
||||||
|
:return: :class:`BoundLoadBalancerType <hcloud.load_balancer_types.client.BoundLoadBalancerType>`
|
||||||
|
"""
|
||||||
|
return super().get_by_name(name)
|
55
plugins/module_utils/vendor/hcloud/load_balancer_types/domain.py
vendored
Normal file
55
plugins/module_utils/vendor/hcloud/load_balancer_types/domain.py
vendored
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
from ..core.domain import BaseDomain, DomainIdentityMixin
|
||||||
|
|
||||||
|
|
||||||
|
class LoadBalancerType(BaseDomain, DomainIdentityMixin):
|
||||||
|
"""LoadBalancerType Domain
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
ID of the Load Balancer type
|
||||||
|
:param name: str
|
||||||
|
Name of the Load Balancer type
|
||||||
|
:param description: str
|
||||||
|
Description of the Load Balancer type
|
||||||
|
:param max_connections: int
|
||||||
|
Max amount of connections the Load Balancer can handle
|
||||||
|
:param max_services: int
|
||||||
|
Max amount of services the Load Balancer can handle
|
||||||
|
:param max_targets: int
|
||||||
|
Max amount of targets the Load Balancer can handle
|
||||||
|
:param max_assigned_certificates: int
|
||||||
|
Max amount of certificates the Load Balancer can serve
|
||||||
|
:param prices: Dict
|
||||||
|
Prices in different locations
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = (
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"description",
|
||||||
|
"max_connections",
|
||||||
|
"max_services",
|
||||||
|
"max_targets",
|
||||||
|
"max_assigned_certificates",
|
||||||
|
"prices",
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
id=None,
|
||||||
|
name=None,
|
||||||
|
description=None,
|
||||||
|
max_connections=None,
|
||||||
|
max_services=None,
|
||||||
|
max_targets=None,
|
||||||
|
max_assigned_certificates=None,
|
||||||
|
prices=None,
|
||||||
|
):
|
||||||
|
self.id = id
|
||||||
|
self.name = name
|
||||||
|
self.description = description
|
||||||
|
self.max_connections = max_connections
|
||||||
|
self.max_services = max_services
|
||||||
|
self.max_targets = max_targets
|
||||||
|
self.max_assigned_certificates = max_assigned_certificates
|
||||||
|
self.prices = prices
|
0
plugins/module_utils/vendor/hcloud/load_balancers/__init__.py
vendored
Normal file
0
plugins/module_utils/vendor/hcloud/load_balancers/__init__.py
vendored
Normal file
900
plugins/module_utils/vendor/hcloud/load_balancers/client.py
vendored
Normal file
900
plugins/module_utils/vendor/hcloud/load_balancers/client.py
vendored
Normal file
|
@ -0,0 +1,900 @@
|
||||||
|
from ..actions.client import BoundAction
|
||||||
|
from ..certificates.client import BoundCertificate
|
||||||
|
from ..core.client import BoundModelBase, ClientEntityBase, GetEntityByNameMixin
|
||||||
|
from ..core.domain import add_meta_to_result
|
||||||
|
from ..load_balancer_types.client import BoundLoadBalancerType
|
||||||
|
from ..locations.client import BoundLocation
|
||||||
|
from ..networks.client import BoundNetwork
|
||||||
|
from ..servers.client import BoundServer
|
||||||
|
from .domain import (
|
||||||
|
CreateLoadBalancerResponse,
|
||||||
|
IPv4Address,
|
||||||
|
IPv6Network,
|
||||||
|
LoadBalancer,
|
||||||
|
LoadBalancerAlgorithm,
|
||||||
|
LoadBalancerHealtCheckHttp,
|
||||||
|
LoadBalancerHealthCheck,
|
||||||
|
LoadBalancerService,
|
||||||
|
LoadBalancerServiceHttp,
|
||||||
|
LoadBalancerTarget,
|
||||||
|
LoadBalancerTargetIP,
|
||||||
|
LoadBalancerTargetLabelSelector,
|
||||||
|
PrivateNet,
|
||||||
|
PublicNetwork,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class BoundLoadBalancer(BoundModelBase):
|
||||||
|
model = LoadBalancer
|
||||||
|
|
||||||
|
def __init__(self, client, data, complete=True):
|
||||||
|
algorithm = data.get("algorithm")
|
||||||
|
if algorithm:
|
||||||
|
data["algorithm"] = LoadBalancerAlgorithm(type=algorithm["type"])
|
||||||
|
|
||||||
|
public_net = data.get("public_net")
|
||||||
|
if public_net:
|
||||||
|
ipv4_address = IPv4Address.from_dict(public_net["ipv4"])
|
||||||
|
ipv6_network = IPv6Network.from_dict(public_net["ipv6"])
|
||||||
|
data["public_net"] = PublicNetwork(
|
||||||
|
ipv4=ipv4_address, ipv6=ipv6_network, enabled=public_net["enabled"]
|
||||||
|
)
|
||||||
|
|
||||||
|
private_nets = data.get("private_net")
|
||||||
|
if private_nets:
|
||||||
|
private_nets = [
|
||||||
|
PrivateNet(
|
||||||
|
network=BoundNetwork(
|
||||||
|
client._client.networks,
|
||||||
|
{"id": private_net["network"]},
|
||||||
|
complete=False,
|
||||||
|
),
|
||||||
|
ip=private_net["ip"],
|
||||||
|
)
|
||||||
|
for private_net in private_nets
|
||||||
|
]
|
||||||
|
data["private_net"] = private_nets
|
||||||
|
|
||||||
|
targets = data.get("targets")
|
||||||
|
if targets:
|
||||||
|
tmp_targets = []
|
||||||
|
for target in targets:
|
||||||
|
tmp_target = LoadBalancerTarget(type=target["type"])
|
||||||
|
if target["type"] == "server":
|
||||||
|
tmp_target.server = BoundServer(
|
||||||
|
client._client.servers, data=target["server"], complete=False
|
||||||
|
)
|
||||||
|
tmp_target.use_private_ip = target["use_private_ip"]
|
||||||
|
elif target["type"] == "label_selector":
|
||||||
|
tmp_target.label_selector = LoadBalancerTargetLabelSelector(
|
||||||
|
selector=target["label_selector"]["selector"]
|
||||||
|
)
|
||||||
|
tmp_target.use_private_ip = target["use_private_ip"]
|
||||||
|
elif target["type"] == "ip":
|
||||||
|
tmp_target.ip = LoadBalancerTargetIP(ip=target["ip"]["ip"])
|
||||||
|
tmp_targets.append(tmp_target)
|
||||||
|
data["targets"] = tmp_targets
|
||||||
|
|
||||||
|
services = data.get("services")
|
||||||
|
if services:
|
||||||
|
tmp_services = []
|
||||||
|
for service in services:
|
||||||
|
tmp_service = LoadBalancerService(
|
||||||
|
protocol=service["protocol"],
|
||||||
|
listen_port=service["listen_port"],
|
||||||
|
destination_port=service["destination_port"],
|
||||||
|
proxyprotocol=service["proxyprotocol"],
|
||||||
|
)
|
||||||
|
if service["protocol"] != "tcp":
|
||||||
|
tmp_service.http = LoadBalancerServiceHttp(
|
||||||
|
sticky_sessions=service["http"]["sticky_sessions"],
|
||||||
|
redirect_http=service["http"]["redirect_http"],
|
||||||
|
cookie_name=service["http"]["cookie_name"],
|
||||||
|
cookie_lifetime=service["http"]["cookie_lifetime"],
|
||||||
|
)
|
||||||
|
tmp_service.http.certificates = [
|
||||||
|
BoundCertificate(
|
||||||
|
client._client.certificates,
|
||||||
|
{"id": certificate},
|
||||||
|
complete=False,
|
||||||
|
)
|
||||||
|
for certificate in service["http"]["certificates"]
|
||||||
|
]
|
||||||
|
|
||||||
|
tmp_service.health_check = LoadBalancerHealthCheck(
|
||||||
|
protocol=service["health_check"]["protocol"],
|
||||||
|
port=service["health_check"]["port"],
|
||||||
|
interval=service["health_check"]["interval"],
|
||||||
|
retries=service["health_check"]["retries"],
|
||||||
|
timeout=service["health_check"]["timeout"],
|
||||||
|
)
|
||||||
|
if tmp_service.health_check.protocol != "tcp":
|
||||||
|
tmp_service.health_check.http = LoadBalancerHealtCheckHttp(
|
||||||
|
domain=service["health_check"]["http"]["domain"],
|
||||||
|
path=service["health_check"]["http"]["path"],
|
||||||
|
response=service["health_check"]["http"]["response"],
|
||||||
|
tls=service["health_check"]["http"]["tls"],
|
||||||
|
status_codes=service["health_check"]["http"]["status_codes"],
|
||||||
|
)
|
||||||
|
tmp_services.append(tmp_service)
|
||||||
|
data["services"] = tmp_services
|
||||||
|
|
||||||
|
load_balancer_type = data.get("load_balancer_type")
|
||||||
|
if load_balancer_type is not None:
|
||||||
|
data["load_balancer_type"] = BoundLoadBalancerType(
|
||||||
|
client._client.load_balancer_types, load_balancer_type
|
||||||
|
)
|
||||||
|
|
||||||
|
location = data.get("location")
|
||||||
|
if location is not None:
|
||||||
|
data["location"] = BoundLocation(client._client.locations, location)
|
||||||
|
|
||||||
|
super().__init__(client, data, complete)
|
||||||
|
|
||||||
|
def update(self, name=None, labels=None):
|
||||||
|
# type: (Optional[str], Optional[Dict[str, str]]) -> BoundLoadBalancer
|
||||||
|
"""Updates a Load Balancer. You can update a Load Balancers name and a Load Balancers labels.
|
||||||
|
|
||||||
|
:param name: str (optional)
|
||||||
|
New name to set
|
||||||
|
:param labels: Dict[str, str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:return: :class:`BoundLoadBalancer <hcloud.load_balancers.client.BoundLoadBalancer>`
|
||||||
|
"""
|
||||||
|
return self._client.update(self, name, labels)
|
||||||
|
|
||||||
|
def delete(self):
|
||||||
|
# type: () -> BoundAction
|
||||||
|
"""Deletes a Load Balancer.
|
||||||
|
|
||||||
|
:return: boolean
|
||||||
|
"""
|
||||||
|
return self._client.delete(self)
|
||||||
|
|
||||||
|
def get_actions_list(self, status=None, sort=None, page=None, per_page=None):
|
||||||
|
# type: (Optional[List[str]], Optional[List[str]], Optional[int], Optional[int]) -> PageResults[List[BoundAction, Meta]]
|
||||||
|
"""Returns all action objects for a Load Balancer.
|
||||||
|
|
||||||
|
:param status: List[str] (optional)
|
||||||
|
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
||||||
|
:param sort: List[str] (optional)
|
||||||
|
Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
|
||||||
|
:param page: int (optional)
|
||||||
|
Specifies the page to fetch
|
||||||
|
:param per_page: int (optional)
|
||||||
|
Specifies how many results are returned by page
|
||||||
|
:return: (List[:class:`BoundAction <hcloud.actions.client.BoundAction>`], :class:`Meta <hcloud.core.domain.Meta>`)
|
||||||
|
"""
|
||||||
|
return self._client.get_actions_list(self, status, sort, page, per_page)
|
||||||
|
|
||||||
|
def get_actions(self, status=None, sort=None):
|
||||||
|
# type: (Optional[List[str]], Optional[List[str]]) -> List[BoundAction]
|
||||||
|
"""Returns all action objects for a Load Balancer.
|
||||||
|
|
||||||
|
:param status: List[str] (optional)
|
||||||
|
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
||||||
|
:param sort: List[str] (optional)
|
||||||
|
Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
|
||||||
|
:return: List[:class:`BoundAction <hcloud.actions.client.BoundAction>`]
|
||||||
|
"""
|
||||||
|
return self._client.get_actions(self, status, sort)
|
||||||
|
|
||||||
|
def add_service(self, service):
|
||||||
|
# type: (LoadBalancerService) -> List[BoundAction]
|
||||||
|
"""Adds a service to a Load Balancer.
|
||||||
|
|
||||||
|
:param service: :class:`LoadBalancerService <hcloud.load_balancers.domain.LoadBalancerService>`
|
||||||
|
The LoadBalancerService you want to add to the Load Balancer
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.add_service(self, service=service)
|
||||||
|
|
||||||
|
def update_service(self, service):
|
||||||
|
# type: (LoadBalancerService) -> List[BoundAction]
|
||||||
|
"""Updates a service of an Load Balancer.
|
||||||
|
|
||||||
|
:param service: :class:`LoadBalancerService <hcloud.load_balancers.domain.LoadBalancerService>`
|
||||||
|
The LoadBalancerService you want to update
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.update_service(self, service=service)
|
||||||
|
|
||||||
|
def delete_service(self, service):
|
||||||
|
# type: (LoadBalancerService) -> List[BoundAction]
|
||||||
|
"""Deletes a service from a Load Balancer.
|
||||||
|
|
||||||
|
:param service: :class:`LoadBalancerService <hcloud.load_balancers.domain.LoadBalancerService>`
|
||||||
|
The LoadBalancerService you want to delete from the Load Balancer
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.delete_service(self, service)
|
||||||
|
|
||||||
|
def add_target(self, target):
|
||||||
|
# type: (LoadBalancerTarget) -> List[BoundAction]
|
||||||
|
"""Adds a target to a Load Balancer.
|
||||||
|
|
||||||
|
:param target: :class:`LoadBalancerTarget <hcloud.load_balancers.domain.LoadBalancerTarget>`
|
||||||
|
The LoadBalancerTarget you want to add to the Load Balancer
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.add_target(self, target)
|
||||||
|
|
||||||
|
def remove_target(self, target):
|
||||||
|
# type: (LoadBalancerTarget) -> List[BoundAction]
|
||||||
|
"""Removes a target from a Load Balancer.
|
||||||
|
|
||||||
|
:param target: :class:`LoadBalancerTarget <hcloud.load_balancers.domain.LoadBalancerTarget>`
|
||||||
|
The LoadBalancerTarget you want to remove from the Load Balancer
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.remove_target(self, target)
|
||||||
|
|
||||||
|
def change_algorithm(self, algorithm):
|
||||||
|
# type: (LoadBalancerAlgorithm) -> List[BoundAction]
|
||||||
|
"""Changes the algorithm used by the Load Balancer
|
||||||
|
|
||||||
|
:param algorithm: :class:`LoadBalancerAlgorithm <hcloud.load_balancers.domain.LoadBalancerAlgorithm>`
|
||||||
|
The LoadBalancerAlgorithm you want to use
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.change_algorithm(self, algorithm)
|
||||||
|
|
||||||
|
def change_dns_ptr(self, ip, dns_ptr):
|
||||||
|
# type: (str, str) -> BoundAction
|
||||||
|
"""Changes the hostname that will appear when getting the hostname belonging to the public IPs (IPv4 and IPv6) of this Load Balancer.
|
||||||
|
|
||||||
|
:param ip: str
|
||||||
|
The IP address for which to set the reverse DNS entry
|
||||||
|
:param dns_ptr: str
|
||||||
|
Hostname to set as a reverse DNS PTR entry, will reset to original default value if `None`
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.change_dns_ptr(self, ip, dns_ptr)
|
||||||
|
|
||||||
|
def change_protection(self, delete):
|
||||||
|
# type: (LoadBalancerService) -> List[BoundAction]
|
||||||
|
"""Changes the protection configuration of a Load Balancer.
|
||||||
|
|
||||||
|
:param delete: boolean
|
||||||
|
If True, prevents the Load Balancer from being deleted
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.change_protection(self, delete)
|
||||||
|
|
||||||
|
def attach_to_network(self, network, ip=None):
|
||||||
|
# type: (Union[Network,BoundNetwork],Optional[str]) -> BoundAction
|
||||||
|
"""Attaches a Load Balancer to a Network
|
||||||
|
|
||||||
|
:param network: :class:`BoundNetwork <hcloud.networks.client.BoundNetwork>` or :class:`Network <hcloud.networks.domain.Network>`
|
||||||
|
:param ip: str
|
||||||
|
IP to request to be assigned to this Load Balancer
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.attach_to_network(self, network, ip)
|
||||||
|
|
||||||
|
def detach_from_network(self, network):
|
||||||
|
# type: ( Union[Network,BoundNetwork]) -> BoundAction
|
||||||
|
"""Detaches a Load Balancer from a Network.
|
||||||
|
|
||||||
|
:param network: :class:`BoundNetwork <hcloud.networks.client.BoundNetwork>` or :class:`Network <hcloud.networks.domain.Network>`
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.detach_from_network(self, network)
|
||||||
|
|
||||||
|
def enable_public_interface(self):
|
||||||
|
# type: () -> BoundAction
|
||||||
|
"""Enables the public interface of a Load Balancer.
|
||||||
|
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.enable_public_interface(self)
|
||||||
|
|
||||||
|
def disable_public_interface(self):
|
||||||
|
# type: () -> BoundAction
|
||||||
|
"""Disables the public interface of a Load Balancer.
|
||||||
|
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.disable_public_interface(self)
|
||||||
|
|
||||||
|
def change_type(self, load_balancer_type):
|
||||||
|
# type: (Union[LoadBalancerType,BoundLoadBalancerType]) -> BoundAction
|
||||||
|
"""Changes the type of a Load Balancer.
|
||||||
|
|
||||||
|
:param load_balancer_type: :class:`BoundLoadBalancerType <hcloud.load_balancer_types.client.BoundLoadBalancerType>` or :class:`LoadBalancerType <hcloud.load_balancer_types.domain.LoadBalancerType>`
|
||||||
|
Load Balancer type the Load Balancer should migrate to
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.change_type(self, load_balancer_type)
|
||||||
|
|
||||||
|
|
||||||
|
class LoadBalancersClient(ClientEntityBase, GetEntityByNameMixin):
|
||||||
|
results_list_attribute_name = "load_balancers"
|
||||||
|
|
||||||
|
def get_by_id(self, id):
|
||||||
|
# type: (int) -> BoundLoadBalancer
|
||||||
|
"""Get a specific Load Balancer
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
:return: :class:`BoundLoadBalancer <hcloud.load_balancers.client.BoundLoadBalancer>`
|
||||||
|
"""
|
||||||
|
response = self._client.request(
|
||||||
|
url=f"/load_balancers/{id}",
|
||||||
|
method="GET",
|
||||||
|
)
|
||||||
|
return BoundLoadBalancer(self, response["load_balancer"])
|
||||||
|
|
||||||
|
def get_list(
|
||||||
|
self,
|
||||||
|
name=None, # type: Optional[str]
|
||||||
|
label_selector=None, # type: Optional[str]
|
||||||
|
page=None, # type: Optional[int]
|
||||||
|
per_page=None, # type: Optional[int]
|
||||||
|
):
|
||||||
|
# type: (...) -> PageResults[List[BoundLoadBalancer], Meta]
|
||||||
|
"""Get a list of Load Balancers from this account
|
||||||
|
|
||||||
|
:param name: str (optional)
|
||||||
|
Can be used to filter Load Balancers by their name.
|
||||||
|
:param label_selector: str (optional)
|
||||||
|
Can be used to filter Load Balancers by labels. The response will only contain Load Balancers matching the label selector.
|
||||||
|
: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:`BoundLoadBalancer <hcloud.load_balancers.client.BoundLoadBalancer>`], :class:`Meta <hcloud.core.domain.Meta>`)
|
||||||
|
"""
|
||||||
|
params = {}
|
||||||
|
if name is not None:
|
||||||
|
params["name"] = name
|
||||||
|
if label_selector is not None:
|
||||||
|
params["label_selector"] = label_selector
|
||||||
|
if page is not None:
|
||||||
|
params["page"] = page
|
||||||
|
if per_page is not None:
|
||||||
|
params["per_page"] = per_page
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url="/load_balancers", method="GET", params=params
|
||||||
|
)
|
||||||
|
|
||||||
|
ass_load_balancers = [
|
||||||
|
BoundLoadBalancer(self, load_balancer_data)
|
||||||
|
for load_balancer_data in response["load_balancers"]
|
||||||
|
]
|
||||||
|
return self._add_meta_to_result(ass_load_balancers, response)
|
||||||
|
|
||||||
|
def get_all(self, name=None, label_selector=None):
|
||||||
|
# type: (Optional[str], Optional[str]) -> List[BoundLoadBalancer]
|
||||||
|
"""Get all Load Balancers from this account
|
||||||
|
|
||||||
|
:param name: str (optional)
|
||||||
|
Can be used to filter Load Balancers by their name.
|
||||||
|
:param label_selector: str (optional)
|
||||||
|
Can be used to filter Load Balancers by labels. The response will only contain Load Balancers matching the label selector.
|
||||||
|
:return: List[:class:`BoundLoadBalancer <hcloud.load_balancers.client.BoundLoadBalancer>`]
|
||||||
|
"""
|
||||||
|
return super().get_all(name=name, label_selector=label_selector)
|
||||||
|
|
||||||
|
def get_by_name(self, name):
|
||||||
|
# type: (str) -> BoundLoadBalancer
|
||||||
|
"""Get Load Balancer by name
|
||||||
|
|
||||||
|
:param name: str
|
||||||
|
Used to get Load Balancer by name.
|
||||||
|
:return: :class:`BoundLoadBalancer <hcloud.load_balancers.client.BoundLoadBalancer>`
|
||||||
|
"""
|
||||||
|
return super().get_by_name(name)
|
||||||
|
|
||||||
|
def create(
|
||||||
|
self,
|
||||||
|
name, # type: str
|
||||||
|
load_balancer_type, # type: LoadBalancerType
|
||||||
|
algorithm=None, # type: Optional[LoadBalancerAlgorithm]
|
||||||
|
services=None, # type: Optional[List[LoadBalancerService]]
|
||||||
|
targets=None, # type: Optional[List[LoadBalancerTarget]]
|
||||||
|
labels=None, # type: Optional[Dict[str, str]]
|
||||||
|
location=None, # type: Optional[Location]
|
||||||
|
network_zone=None, # type: Optional[str]
|
||||||
|
public_interface=None, # type: Optional[bool]
|
||||||
|
network=None, # type: Optional[Union[Network,BoundNetwork]]
|
||||||
|
):
|
||||||
|
# type: (...) -> CreateLoadBalancerResponse
|
||||||
|
"""Creates a Load Balancer .
|
||||||
|
|
||||||
|
:param name: str
|
||||||
|
Name of the Load Balancer
|
||||||
|
:param load_balancer_type: LoadBalancerType
|
||||||
|
Type of the Load Balancer
|
||||||
|
:param labels: Dict[str, str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:param location: Location
|
||||||
|
Location of the Load Balancer
|
||||||
|
:param network_zone: str
|
||||||
|
Network Zone of the Load Balancer
|
||||||
|
:param algorithm: LoadBalancerAlgorithm (optional)
|
||||||
|
The algorithm the Load Balancer is currently using
|
||||||
|
:param services: LoadBalancerService
|
||||||
|
The services the Load Balancer is currently serving
|
||||||
|
:param targets: LoadBalancerTarget
|
||||||
|
The targets the Load Balancer is currently serving
|
||||||
|
:param public_interface: bool
|
||||||
|
Enable or disable the public interface of the Load Balancer
|
||||||
|
:param network: Network
|
||||||
|
Adds the Load Balancer to a Network
|
||||||
|
:return: :class:`CreateLoadBalancerResponse <hcloud.load_balancers.domain.CreateLoadBalancerResponse>`
|
||||||
|
"""
|
||||||
|
data = {"name": name, "load_balancer_type": load_balancer_type.id_or_name}
|
||||||
|
if network is not None:
|
||||||
|
data["network"] = network.id
|
||||||
|
if public_interface is not None:
|
||||||
|
data["public_interface"] = public_interface
|
||||||
|
if labels is not None:
|
||||||
|
data["labels"] = labels
|
||||||
|
if algorithm is not None:
|
||||||
|
data["algorithm"] = {"type": algorithm.type}
|
||||||
|
if services is not None:
|
||||||
|
service_list = []
|
||||||
|
for service in services:
|
||||||
|
service_list.append(self.get_service_parameters(service))
|
||||||
|
data["services"] = service_list
|
||||||
|
|
||||||
|
if targets is not None:
|
||||||
|
target_list = []
|
||||||
|
for target in targets:
|
||||||
|
target_data = {
|
||||||
|
"type": target.type,
|
||||||
|
"use_private_ip": target.use_private_ip,
|
||||||
|
}
|
||||||
|
if target.type == "server":
|
||||||
|
target_data["server"] = {"id": target.server.id}
|
||||||
|
elif target.type == "label_selector":
|
||||||
|
target_data["label_selector"] = {
|
||||||
|
"selector": target.label_selector.selector
|
||||||
|
}
|
||||||
|
elif target.type == "ip":
|
||||||
|
target_data["ip"] = {"ip": target.ip.ip}
|
||||||
|
target_list.append(target_data)
|
||||||
|
|
||||||
|
data["targets"] = target_list
|
||||||
|
|
||||||
|
if network_zone is not None:
|
||||||
|
data["network_zone"] = network_zone
|
||||||
|
if location is not None:
|
||||||
|
data["location"] = location.id_or_name
|
||||||
|
|
||||||
|
response = self._client.request(url="/load_balancers", method="POST", json=data)
|
||||||
|
|
||||||
|
return CreateLoadBalancerResponse(
|
||||||
|
load_balancer=BoundLoadBalancer(self, response["load_balancer"]),
|
||||||
|
action=BoundAction(self._client.actions, response["action"]),
|
||||||
|
)
|
||||||
|
|
||||||
|
def update(self, load_balancer, name=None, labels=None):
|
||||||
|
# type:(LoadBalancer, Optional[str], Optional[Dict[str, str]]) -> BoundLoadBalancer
|
||||||
|
"""Updates a LoadBalancer. You can update a LoadBalancer’s name and a LoadBalancer’s labels.
|
||||||
|
|
||||||
|
:param load_balancer: :class:`BoundLoadBalancer <hcloud.load_balancers.client.BoundLoadBalancer>` or :class:`LoadBalancer <hcloud.load_balancers.domain.LoadBalancer>`
|
||||||
|
:param name: str (optional)
|
||||||
|
New name to set
|
||||||
|
:param labels: Dict[str, str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:return: :class:`BoundLoadBalancer <hcloud.load_balancers.client.BoundLoadBalancer>`
|
||||||
|
"""
|
||||||
|
data = {}
|
||||||
|
if name is not None:
|
||||||
|
data.update({"name": name})
|
||||||
|
if labels is not None:
|
||||||
|
data.update({"labels": labels})
|
||||||
|
response = self._client.request(
|
||||||
|
url="/load_balancers/{load_balancer_id}".format(
|
||||||
|
load_balancer_id=load_balancer.id
|
||||||
|
),
|
||||||
|
method="PUT",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return BoundLoadBalancer(self, response["load_balancer"])
|
||||||
|
|
||||||
|
def delete(self, load_balancer):
|
||||||
|
# type: (LoadBalancer) -> BoundAction
|
||||||
|
"""Deletes a Load Balancer.
|
||||||
|
|
||||||
|
:param load_balancer: :class:`BoundLoadBalancer <hcloud.load_balancers.client.BoundLoadBalancer>` or :class:`LoadBalancer <hcloud.load_balancers.domain.LoadBalancer>`
|
||||||
|
:return: boolean
|
||||||
|
"""
|
||||||
|
self._client.request(
|
||||||
|
url="/load_balancers/{load_balancer_id}".format(
|
||||||
|
load_balancer_id=load_balancer.id
|
||||||
|
),
|
||||||
|
method="DELETE",
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def get_actions_list(
|
||||||
|
self, load_balancer, status=None, sort=None, page=None, per_page=None
|
||||||
|
):
|
||||||
|
# type: (LoadBalancer, Optional[List[str]], Optional[List[str]], Optional[int], Optional[int]) -> PageResults[List[BoundAction], Meta]
|
||||||
|
"""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 = {}
|
||||||
|
if status is not None:
|
||||||
|
params["status"] = status
|
||||||
|
if sort is not None:
|
||||||
|
params["sort"] = sort
|
||||||
|
if page is not None:
|
||||||
|
params["page"] = page
|
||||||
|
if per_page is not None:
|
||||||
|
params["per_page"] = per_page
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url="/load_balancers/{load_balancer_id}/actions".format(
|
||||||
|
load_balancer_id=load_balancer.id
|
||||||
|
),
|
||||||
|
method="GET",
|
||||||
|
params=params,
|
||||||
|
)
|
||||||
|
actions = [
|
||||||
|
BoundAction(self._client.actions, action_data)
|
||||||
|
for action_data in response["actions"]
|
||||||
|
]
|
||||||
|
return add_meta_to_result(actions, response, "actions")
|
||||||
|
|
||||||
|
def get_actions(self, load_balancer, status=None, sort=None):
|
||||||
|
# type: (LoadBalancer, Optional[List[str]], Optional[List[str]]) -> List[BoundAction]
|
||||||
|
"""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`
|
||||||
|
:return: List[:class:`BoundAction <hcloud.actions.client.BoundAction>`]
|
||||||
|
"""
|
||||||
|
return super().get_actions(load_balancer, status=status, sort=sort)
|
||||||
|
|
||||||
|
def add_service(self, load_balancer, service):
|
||||||
|
# type: (Union[LoadBalancer, BoundLoadBalancer], LoadBalancerService) -> List[BoundAction]
|
||||||
|
"""Adds a service to a Load Balancer.
|
||||||
|
|
||||||
|
:param load_balancer: :class:`BoundLoadBalancer <hcloud.load_balancers.client.BoundLoadBalancer>` or :class:`LoadBalancer <hcloud.load_balancers.domain.LoadBalancer>`
|
||||||
|
:param service: :class:`LoadBalancerService <hcloud.load_balancers.domain.LoadBalancerService>`
|
||||||
|
The LoadBalancerService you want to add to the Load Balancer
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
data = self.get_service_parameters(service)
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url="/load_balancers/{load_balancer_id}/actions/add_service".format(
|
||||||
|
load_balancer_id=load_balancer.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
||||||
|
|
||||||
|
def get_service_parameters(self, service):
|
||||||
|
data = {}
|
||||||
|
if service.protocol is not None:
|
||||||
|
data["protocol"] = service.protocol
|
||||||
|
if service.listen_port is not None:
|
||||||
|
data["listen_port"] = service.listen_port
|
||||||
|
if service.destination_port is not None:
|
||||||
|
data["destination_port"] = service.destination_port
|
||||||
|
if service.proxyprotocol is not None:
|
||||||
|
data["proxyprotocol"] = service.proxyprotocol
|
||||||
|
if service.http is not None:
|
||||||
|
data["http"] = {}
|
||||||
|
if service.http.cookie_name is not None:
|
||||||
|
data["http"]["cookie_name"] = service.http.cookie_name
|
||||||
|
if service.http.cookie_lifetime is not None:
|
||||||
|
data["http"]["cookie_lifetime"] = service.http.cookie_lifetime
|
||||||
|
if service.http.redirect_http is not None:
|
||||||
|
data["http"]["redirect_http"] = service.http.redirect_http
|
||||||
|
if service.http.sticky_sessions is not None:
|
||||||
|
data["http"]["sticky_sessions"] = service.http.sticky_sessions
|
||||||
|
certificate_ids = []
|
||||||
|
for certificate in service.http.certificates:
|
||||||
|
certificate_ids.append(certificate.id)
|
||||||
|
data["http"]["certificates"] = certificate_ids
|
||||||
|
if service.health_check is not None:
|
||||||
|
data["health_check"] = {
|
||||||
|
"protocol": service.health_check.protocol,
|
||||||
|
"port": service.health_check.port,
|
||||||
|
"interval": service.health_check.interval,
|
||||||
|
"timeout": service.health_check.timeout,
|
||||||
|
"retries": service.health_check.retries,
|
||||||
|
}
|
||||||
|
data["health_check"] = {}
|
||||||
|
if service.health_check.protocol is not None:
|
||||||
|
data["health_check"]["protocol"] = service.health_check.protocol
|
||||||
|
if service.health_check.port is not None:
|
||||||
|
data["health_check"]["port"] = service.health_check.port
|
||||||
|
if service.health_check.interval is not None:
|
||||||
|
data["health_check"]["interval"] = service.health_check.interval
|
||||||
|
if service.health_check.timeout is not None:
|
||||||
|
data["health_check"]["timeout"] = service.health_check.timeout
|
||||||
|
if service.health_check.retries is not None:
|
||||||
|
data["health_check"]["retries"] = service.health_check.retries
|
||||||
|
if service.health_check.http is not None:
|
||||||
|
data["health_check"]["http"] = {}
|
||||||
|
if service.health_check.http.domain is not None:
|
||||||
|
data["health_check"]["http"][
|
||||||
|
"domain"
|
||||||
|
] = service.health_check.http.domain
|
||||||
|
if service.health_check.http.path is not None:
|
||||||
|
data["health_check"]["http"][
|
||||||
|
"path"
|
||||||
|
] = service.health_check.http.path
|
||||||
|
if service.health_check.http.response is not None:
|
||||||
|
data["health_check"]["http"][
|
||||||
|
"response"
|
||||||
|
] = service.health_check.http.response
|
||||||
|
if service.health_check.http.status_codes is not None:
|
||||||
|
data["health_check"]["http"][
|
||||||
|
"status_codes"
|
||||||
|
] = service.health_check.http.status_codes
|
||||||
|
if service.health_check.http.tls is not None:
|
||||||
|
data["health_check"]["http"]["tls"] = service.health_check.http.tls
|
||||||
|
return data
|
||||||
|
|
||||||
|
def update_service(self, load_balancer, service):
|
||||||
|
# type: (Union[LoadBalancer, BoundLoadBalancer], LoadBalancerService) -> List[BoundAction]
|
||||||
|
"""Updates a service of an Load Balancer.
|
||||||
|
|
||||||
|
:param load_balancer: :class:`BoundLoadBalancer <hcloud.load_balancers.client.BoundLoadBalancer>` or :class:`LoadBalancer <hcloud.load_balancers.domain.LoadBalancer>`
|
||||||
|
:param service: :class:`LoadBalancerService <hcloud.load_balancers.domain.LoadBalancerService>`
|
||||||
|
The LoadBalancerService with updated values within for the Load Balancer
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
data = self.get_service_parameters(service)
|
||||||
|
response = self._client.request(
|
||||||
|
url="/load_balancers/{load_balancer_id}/actions/update_service".format(
|
||||||
|
load_balancer_id=load_balancer.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
||||||
|
|
||||||
|
def delete_service(self, load_balancer, service):
|
||||||
|
# type: (Union[LoadBalancer, BoundLoadBalancer], LoadBalancerService) -> List[BoundAction]
|
||||||
|
"""Deletes a service from a Load Balancer.
|
||||||
|
|
||||||
|
:param load_balancer: :class:`BoundLoadBalancer <hcloud.load_balancers.client.BoundLoadBalancer>` or :class:`LoadBalancer <hcloud.load_balancers.domain.LoadBalancer>`
|
||||||
|
:param service: :class:`LoadBalancerService <hcloud.load_balancers.domain.LoadBalancerService>`
|
||||||
|
The LoadBalancerService you want to delete from the Load Balancer
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
data = {"listen_port": service.listen_port}
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url="/load_balancers/{load_balancer_id}/actions/delete_service".format(
|
||||||
|
load_balancer_id=load_balancer.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
||||||
|
|
||||||
|
def add_target(self, load_balancer, target):
|
||||||
|
# type: (Union[LoadBalancer, BoundLoadBalancer], LoadBalancerTarget) -> List[BoundAction]
|
||||||
|
"""Adds a target to a Load Balancer.
|
||||||
|
|
||||||
|
:param load_balancer: :class:`BoundLoadBalancer <hcloud.load_balancers.client.BoundLoadBalancer>` or :class:`LoadBalancer <hcloud.load_balancers.domain.LoadBalancer>`
|
||||||
|
:param target: :class:`LoadBalancerTarget <hcloud.load_balancers.domain.LoadBalancerTarget>`
|
||||||
|
The LoadBalancerTarget you want to add to the Load Balancer
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
data = {"type": target.type, "use_private_ip": target.use_private_ip}
|
||||||
|
if target.type == "server":
|
||||||
|
data["server"] = {"id": target.server.id}
|
||||||
|
elif target.type == "label_selector":
|
||||||
|
data["label_selector"] = {"selector": target.label_selector.selector}
|
||||||
|
elif target.type == "ip":
|
||||||
|
data["ip"] = {"ip": target.ip.ip}
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url="/load_balancers/{load_balancer_id}/actions/add_target".format(
|
||||||
|
load_balancer_id=load_balancer.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
||||||
|
|
||||||
|
def remove_target(self, load_balancer, target):
|
||||||
|
# type: (Union[LoadBalancer, BoundLoadBalancer], LoadBalancerTarget) -> List[BoundAction]
|
||||||
|
"""Removes a target from a Load Balancer.
|
||||||
|
|
||||||
|
:param load_balancer: :class:`BoundLoadBalancer <hcloud.load_balancers.client.BoundLoadBalancer>` or :class:`LoadBalancer <hcloud.load_balancers.domain.LoadBalancer>`
|
||||||
|
:param target: :class:`LoadBalancerTarget <hcloud.load_balancers.domain.LoadBalancerTarget>`
|
||||||
|
The LoadBalancerTarget you want to remove from the Load Balancer
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
data = {"type": target.type}
|
||||||
|
if target.type == "server":
|
||||||
|
data["server"] = {"id": target.server.id}
|
||||||
|
elif target.type == "label_selector":
|
||||||
|
data["label_selector"] = {"selector": target.label_selector.selector}
|
||||||
|
elif target.type == "ip":
|
||||||
|
data["ip"] = {"ip": target.ip.ip}
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url="/load_balancers/{load_balancer_id}/actions/remove_target".format(
|
||||||
|
load_balancer_id=load_balancer.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
||||||
|
|
||||||
|
def change_algorithm(self, load_balancer, algorithm):
|
||||||
|
# type: (Union[LoadBalancer, BoundLoadBalancer], Optional[bool]) -> BoundAction
|
||||||
|
"""Changes the algorithm used by the Load Balancer
|
||||||
|
|
||||||
|
:param load_balancer: :class:` <hcloud.load_balancers.client.BoundLoadBalancer>` or :class:`LoadBalancer <hcloud.load_balancers.domain.LoadBalancer>`
|
||||||
|
:param algorithm: :class:`LoadBalancerAlgorithm <hcloud.load_balancers.domain.LoadBalancerAlgorithm>`
|
||||||
|
The LoadBalancerSubnet you want to add to the Load Balancer
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
data = {"type": algorithm.type}
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url="/load_balancers/{load_balancer_id}/actions/change_algorithm".format(
|
||||||
|
load_balancer_id=load_balancer.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
||||||
|
|
||||||
|
def change_dns_ptr(self, load_balancer, ip, dns_ptr):
|
||||||
|
# type: (Union[LoadBalancer, BoundLoadBalancer], str, str) -> BoundAction
|
||||||
|
"""Changes the hostname that will appear when getting the hostname belonging to the public IPs (IPv4 and IPv6) of this Load Balancer.
|
||||||
|
|
||||||
|
:param ip: str
|
||||||
|
The IP address for which to set the reverse DNS entry
|
||||||
|
:param dns_ptr: str
|
||||||
|
Hostname to set as a reverse DNS PTR entry, will reset to original default value if `None`
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url="/load_balancers/{load_balancer_id}/actions/change_dns_ptr".format(
|
||||||
|
load_balancer_id=load_balancer.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
json={"ip": ip, "dns_ptr": dns_ptr},
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
||||||
|
|
||||||
|
def change_protection(self, load_balancer, delete=None):
|
||||||
|
# type: (Union[LoadBalancer, BoundLoadBalancer], Optional[bool]) -> BoundAction
|
||||||
|
"""Changes the protection configuration of a Load Balancer.
|
||||||
|
|
||||||
|
:param load_balancer: :class:` <hcloud.load_balancers.client.BoundLoadBalancer>` or :class:`LoadBalancer <hcloud.load_balancers.domain.LoadBalancer>`
|
||||||
|
:param delete: boolean
|
||||||
|
If True, prevents the Load Balancer from being deleted
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
data = {}
|
||||||
|
if delete is not None:
|
||||||
|
data.update({"delete": delete})
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url="/load_balancers/{load_balancer_id}/actions/change_protection".format(
|
||||||
|
load_balancer_id=load_balancer.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
||||||
|
|
||||||
|
def attach_to_network(
|
||||||
|
self,
|
||||||
|
load_balancer, # type: Union[LoadBalancer, BoundLoadBalancer]
|
||||||
|
network, # type: Union[Network, BoundNetwork]
|
||||||
|
ip=None, # type: Optional[str]
|
||||||
|
):
|
||||||
|
"""Attach a Load Balancer to a Network.
|
||||||
|
|
||||||
|
:param load_balancer: :class:` <hcloud.load_balancers.client.BoundLoadBalancer>` or :class:`LoadBalancer <hcloud.load_balancers.domain.LoadBalancer>`
|
||||||
|
:param network: :class:`BoundNetwork <hcloud.networks.client.BoundNetwork>` or :class:`Network <hcloud.networks.domain.Network>`
|
||||||
|
:param ip: str
|
||||||
|
IP to request to be assigned to this Load Balancer
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
data = {"network": network.id}
|
||||||
|
if ip is not None:
|
||||||
|
data.update({"ip": ip})
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url="/load_balancers/{load_balancer_id}/actions/attach_to_network".format(
|
||||||
|
load_balancer_id=load_balancer.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
||||||
|
|
||||||
|
def detach_from_network(self, load_balancer, network):
|
||||||
|
# type: (Union[LoadBalancer, BoundLoadBalancer], Union[Network,BoundNetwork]) -> BoundAction
|
||||||
|
"""Detaches a Load Balancer from a Network.
|
||||||
|
|
||||||
|
:param load_balancer: :class:` <hcloud.load_balancers.client.BoundLoadBalancer>` or :class:`LoadBalancer <hcloud.load_balancers.domain.LoadBalancer>`
|
||||||
|
:param network: :class:`BoundNetwork <hcloud.networks.client.BoundNetwork>` or :class:`Network <hcloud.networks.domain.Network>`
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
data = {"network": network.id}
|
||||||
|
response = self._client.request(
|
||||||
|
url="/load_balancers/{load_balancer_id}/actions/detach_from_network".format(
|
||||||
|
load_balancer_id=load_balancer.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
||||||
|
|
||||||
|
def enable_public_interface(self, load_balancer):
|
||||||
|
# type: (Union[LoadBalancer, BoundLoadBalancer]) -> BoundAction
|
||||||
|
"""Enables the public interface of a Load Balancer.
|
||||||
|
|
||||||
|
:param load_balancer: :class:` <hcloud.load_balancers.client.BoundLoadBalancer>` or :class:`LoadBalancer <hcloud.load_balancers.domain.LoadBalancer>`
|
||||||
|
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url="/load_balancers/{load_balancer_id}/actions/enable_public_interface".format(
|
||||||
|
load_balancer_id=load_balancer.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
||||||
|
|
||||||
|
def disable_public_interface(self, load_balancer):
|
||||||
|
# type: (Union[LoadBalancer, BoundLoadBalancer]) -> BoundAction
|
||||||
|
"""Disables the public interface of a Load Balancer.
|
||||||
|
|
||||||
|
:param load_balancer: :class:` <hcloud.load_balancers.client.BoundLoadBalancer>` or :class:`LoadBalancer <hcloud.load_balancers.domain.LoadBalancer>`
|
||||||
|
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url="/load_balancers/{load_balancer_id}/actions/disable_public_interface".format(
|
||||||
|
load_balancer_id=load_balancer.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
||||||
|
|
||||||
|
def change_type(self, load_balancer, load_balancer_type):
|
||||||
|
# type: ([LoadBalancer, BoundLoadBalancer], [LoadBalancerType, BoundLoadBalancerType]) ->BoundAction
|
||||||
|
"""Changes the type of a Load Balancer.
|
||||||
|
|
||||||
|
:param load_balancer: :class:`BoundLoadBalancer <hcloud.load_balancers.client.BoundLoadBalancer>` or :class:`LoadBalancer <hcloud.load_balancers.domain.LoadBalancer>`
|
||||||
|
:param load_balancer_type: :class:`BoundLoadBalancerType <hcloud.load_balancer_types.client.BoundLoadBalancerType>` or :class:`LoadBalancerType <hcloud.load_balancer_types.domain.LoadBalancerType>`
|
||||||
|
Load Balancer type the Load Balancer should migrate to
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
data = {"load_balancer_type": load_balancer_type.id_or_name}
|
||||||
|
response = self._client.request(
|
||||||
|
url="/load_balancers/{load_balancer_id}/actions/change_type".format(
|
||||||
|
load_balancer_id=load_balancer.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
370
plugins/module_utils/vendor/hcloud/load_balancers/domain.py
vendored
Normal file
370
plugins/module_utils/vendor/hcloud/load_balancers/domain.py
vendored
Normal file
|
@ -0,0 +1,370 @@
|
||||||
|
try:
|
||||||
|
from dateutil.parser import isoparse
|
||||||
|
except ImportError:
|
||||||
|
isoparse = None
|
||||||
|
|
||||||
|
from ..core.domain import BaseDomain
|
||||||
|
|
||||||
|
|
||||||
|
class LoadBalancer(BaseDomain):
|
||||||
|
"""LoadBalancer Domain
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
ID of the Load Balancer
|
||||||
|
:param name: str
|
||||||
|
Name of the Load Balancer (must be unique per project)
|
||||||
|
:param created: datetime
|
||||||
|
Point in time when the Load Balancer was created
|
||||||
|
:param protection: dict
|
||||||
|
Protection configuration for the Load Balancer
|
||||||
|
:param labels: dict
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:param location: Location
|
||||||
|
Location of the Load Balancer
|
||||||
|
:param public_net: :class:`PublicNetwork <hcloud.load_balancers.domain.PublicNetwork>`
|
||||||
|
Public network information.
|
||||||
|
:param private_net: List[:class:`PrivateNet <hcloud.load_balancers.domain.PrivateNet`]
|
||||||
|
Private networks information.
|
||||||
|
:param algorithm: LoadBalancerAlgorithm
|
||||||
|
The algorithm the Load Balancer is currently using
|
||||||
|
:param services: List[LoadBalancerService]
|
||||||
|
The services the LoadBalancer is currently serving
|
||||||
|
:param targets: LoadBalancerTarget
|
||||||
|
The targets the LoadBalancer is currently serving
|
||||||
|
:param load_balancer_type: LoadBalancerType
|
||||||
|
The type of the Load Balancer
|
||||||
|
:param outgoing_traffic: int, None
|
||||||
|
Outbound Traffic for the current billing period in bytes
|
||||||
|
:param ingoing_traffic: int, None
|
||||||
|
Inbound Traffic for the current billing period in bytes
|
||||||
|
:param included_traffic: int
|
||||||
|
Free Traffic for the current billing period in bytes
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = (
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"public_net",
|
||||||
|
"private_net",
|
||||||
|
"location",
|
||||||
|
"algorithm",
|
||||||
|
"services",
|
||||||
|
"load_balancer_type",
|
||||||
|
"protection",
|
||||||
|
"labels",
|
||||||
|
"targets",
|
||||||
|
"created",
|
||||||
|
"outgoing_traffic",
|
||||||
|
"ingoing_traffic",
|
||||||
|
"included_traffic",
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
id,
|
||||||
|
name=None,
|
||||||
|
public_net=None,
|
||||||
|
private_net=None,
|
||||||
|
location=None,
|
||||||
|
algorithm=None,
|
||||||
|
services=None,
|
||||||
|
load_balancer_type=None,
|
||||||
|
protection=None,
|
||||||
|
labels=None,
|
||||||
|
targets=None,
|
||||||
|
created=None,
|
||||||
|
outgoing_traffic=None,
|
||||||
|
ingoing_traffic=None,
|
||||||
|
included_traffic=None,
|
||||||
|
):
|
||||||
|
self.id = id
|
||||||
|
self.name = name
|
||||||
|
self.created = isoparse(created) if created else None
|
||||||
|
self.public_net = public_net
|
||||||
|
self.private_net = private_net
|
||||||
|
self.location = location
|
||||||
|
self.algorithm = algorithm
|
||||||
|
self.services = services
|
||||||
|
self.load_balancer_type = load_balancer_type
|
||||||
|
self.targets = targets
|
||||||
|
self.protection = protection
|
||||||
|
self.labels = labels
|
||||||
|
self.outgoing_traffic = outgoing_traffic
|
||||||
|
self.ingoing_traffic = ingoing_traffic
|
||||||
|
self.included_traffic = included_traffic
|
||||||
|
|
||||||
|
|
||||||
|
class LoadBalancerService(BaseDomain):
|
||||||
|
"""LoadBalancerService Domain
|
||||||
|
|
||||||
|
:param protocol: str
|
||||||
|
Protocol of the service Choices: tcp, http, https
|
||||||
|
:param listen_port: int
|
||||||
|
Required when protocol is tcp, must be unique per Load Balancer.
|
||||||
|
:param destination_port: int
|
||||||
|
Required when protocol is tcp
|
||||||
|
:param proxyprotocol: bool
|
||||||
|
Enable proxyprotocol
|
||||||
|
:param health_check: LoadBalancerHealthCheck
|
||||||
|
Configuration for health checks
|
||||||
|
:param http: LoadBalancerServiceHttp
|
||||||
|
Configuration for http/https protocols, required when protocol is http/https
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
protocol=None,
|
||||||
|
listen_port=None,
|
||||||
|
destination_port=None,
|
||||||
|
proxyprotocol=None,
|
||||||
|
health_check=None,
|
||||||
|
http=None,
|
||||||
|
):
|
||||||
|
self.protocol = protocol
|
||||||
|
self.listen_port = listen_port
|
||||||
|
self.destination_port = destination_port
|
||||||
|
self.proxyprotocol = proxyprotocol
|
||||||
|
self.health_check = health_check
|
||||||
|
self.http = http
|
||||||
|
|
||||||
|
|
||||||
|
class LoadBalancerServiceHttp(BaseDomain):
|
||||||
|
"""LoadBalancerServiceHttp Domain
|
||||||
|
|
||||||
|
:param cookie_name: str
|
||||||
|
Name of the cookie used for Session Stickness
|
||||||
|
:param cookie_lifetime: str
|
||||||
|
Lifetime of the cookie used for Session Stickness
|
||||||
|
:param certificates: list
|
||||||
|
IDs of the Certificates to use for TLS/SSL termination by the Load Balancer; empty for TLS/SSL passthrough or if protocol is "http"
|
||||||
|
:param redirect_http: bool
|
||||||
|
Redirect traffic from http port 80 to port 443
|
||||||
|
:param sticky_sessions: bool
|
||||||
|
Use sticky sessions. Only available if protocol is "http" or "https".
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
cookie_name=None,
|
||||||
|
cookie_lifetime=None,
|
||||||
|
certificates=None,
|
||||||
|
redirect_http=None,
|
||||||
|
sticky_sessions=None,
|
||||||
|
):
|
||||||
|
self.cookie_name = cookie_name
|
||||||
|
self.cookie_lifetime = cookie_lifetime
|
||||||
|
self.certificates = certificates
|
||||||
|
self.redirect_http = redirect_http
|
||||||
|
self.sticky_sessions = sticky_sessions
|
||||||
|
|
||||||
|
|
||||||
|
class LoadBalancerHealthCheck(BaseDomain):
|
||||||
|
"""LoadBalancerHealthCheck Domain
|
||||||
|
|
||||||
|
:param protocol: str
|
||||||
|
Protocol of the service Choices: tcp, http, https
|
||||||
|
:param port: int
|
||||||
|
Port the healthcheck will be performed on
|
||||||
|
:param interval: int
|
||||||
|
Interval we trigger health check in
|
||||||
|
:param timeout: int
|
||||||
|
Timeout in sec after a try is assumed as timeout
|
||||||
|
:param retries: int
|
||||||
|
Retries we perform until we assume a target as unhealthy
|
||||||
|
:param http: LoadBalancerHealtCheckHttp
|
||||||
|
HTTP Config
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
protocol=None,
|
||||||
|
port=None,
|
||||||
|
interval=None,
|
||||||
|
timeout=None,
|
||||||
|
retries=None,
|
||||||
|
http=None,
|
||||||
|
):
|
||||||
|
self.protocol = protocol
|
||||||
|
self.port = port
|
||||||
|
self.interval = interval
|
||||||
|
self.timeout = timeout
|
||||||
|
self.retries = retries
|
||||||
|
self.http = http
|
||||||
|
|
||||||
|
|
||||||
|
class LoadBalancerHealtCheckHttp(BaseDomain):
|
||||||
|
"""LoadBalancerHealtCheckHttp Domain
|
||||||
|
|
||||||
|
:param domain: str
|
||||||
|
Domain name to send in HTTP request. Can be null: In that case we will not send a domain name
|
||||||
|
:param path: str
|
||||||
|
HTTP Path send in Request
|
||||||
|
:param response: str
|
||||||
|
Optional HTTP response to receive in order to pass the health check
|
||||||
|
:param status_codes: list
|
||||||
|
List of HTTP status codes to receive in order to pass the health check
|
||||||
|
:param tls: bool
|
||||||
|
Type of health check
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self, domain=None, path=None, response=None, status_codes=None, tls=None
|
||||||
|
):
|
||||||
|
self.domain = domain
|
||||||
|
self.path = path
|
||||||
|
self.response = response
|
||||||
|
self.status_codes = status_codes
|
||||||
|
self.tls = tls
|
||||||
|
|
||||||
|
|
||||||
|
class LoadBalancerTarget(BaseDomain):
|
||||||
|
"""LoadBalancerTarget Domain
|
||||||
|
|
||||||
|
:param type: str
|
||||||
|
Type of the resource, can be server or label_selector
|
||||||
|
:param server: Server
|
||||||
|
Target server
|
||||||
|
:param label_selector: LoadBalancerTargetLabelSelector
|
||||||
|
Target label selector
|
||||||
|
:param ip: LoadBalancerTargetIP
|
||||||
|
Target IP
|
||||||
|
:param use_private_ip: bool
|
||||||
|
use the private IP instead of primary public IP
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self, type=None, server=None, label_selector=None, ip=None, use_private_ip=None
|
||||||
|
):
|
||||||
|
self.type = type
|
||||||
|
self.server = server
|
||||||
|
self.label_selector = label_selector
|
||||||
|
self.ip = ip
|
||||||
|
self.use_private_ip = use_private_ip
|
||||||
|
|
||||||
|
|
||||||
|
class LoadBalancerTargetLabelSelector(BaseDomain):
|
||||||
|
"""LoadBalancerTargetLabelSelector Domain
|
||||||
|
|
||||||
|
:param selector: str Target label selector
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, selector=None):
|
||||||
|
self.selector = selector
|
||||||
|
|
||||||
|
|
||||||
|
class LoadBalancerTargetIP(BaseDomain):
|
||||||
|
"""LoadBalancerTargetIP Domain
|
||||||
|
|
||||||
|
:param ip: str Target IP
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, ip=None):
|
||||||
|
self.ip = ip
|
||||||
|
|
||||||
|
|
||||||
|
class LoadBalancerAlgorithm(BaseDomain):
|
||||||
|
"""LoadBalancerAlgorithm Domain
|
||||||
|
|
||||||
|
:param type: str
|
||||||
|
Algorithm of the Load Balancer. Choices: round_robin, least_connections
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, type=None):
|
||||||
|
self.type = type
|
||||||
|
|
||||||
|
|
||||||
|
class PublicNetwork(BaseDomain):
|
||||||
|
"""Public Network Domain
|
||||||
|
|
||||||
|
:param ipv4: :class:`IPv4Address <hcloud.load_balancers.domain.IPv4Address>`
|
||||||
|
:param ipv6: :class:`IPv6Network <hcloud.load_balancers.domain.IPv6Network>`
|
||||||
|
:param enabled: boolean
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("ipv4", "ipv6", "enabled")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
ipv4, # type: IPv4Address
|
||||||
|
ipv6, # type: IPv6Network
|
||||||
|
enabled, # type: bool
|
||||||
|
):
|
||||||
|
self.ipv4 = ipv4
|
||||||
|
self.ipv6 = ipv6
|
||||||
|
self.enabled = enabled
|
||||||
|
|
||||||
|
|
||||||
|
class IPv4Address(BaseDomain):
|
||||||
|
"""IPv4 Address Domain
|
||||||
|
|
||||||
|
:param ip: str
|
||||||
|
The IPv4 Address
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("ip", "dns_ptr")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
ip, # type: str
|
||||||
|
dns_ptr, # type: str
|
||||||
|
):
|
||||||
|
self.ip = ip
|
||||||
|
self.dns_ptr = dns_ptr
|
||||||
|
|
||||||
|
|
||||||
|
class IPv6Network(BaseDomain):
|
||||||
|
"""IPv6 Network Domain
|
||||||
|
|
||||||
|
:param ip: str
|
||||||
|
The IPv6 Network as CIDR Notation
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("ip", "dns_ptr")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
ip, # type: str
|
||||||
|
dns_ptr, # type: str
|
||||||
|
):
|
||||||
|
self.ip = ip
|
||||||
|
self.dns_ptr = dns_ptr
|
||||||
|
|
||||||
|
|
||||||
|
class PrivateNet(BaseDomain):
|
||||||
|
"""PrivateNet Domain
|
||||||
|
|
||||||
|
:param network: :class:`BoundNetwork <hcloud.networks.client.BoundNetwork>`
|
||||||
|
The Network the LoadBalancer is attached to
|
||||||
|
:param ip: str
|
||||||
|
The main IP Address of the LoadBalancer in the Network
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("network", "ip")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
network, # type: BoundNetwork
|
||||||
|
ip, # type: str
|
||||||
|
):
|
||||||
|
self.network = network
|
||||||
|
self.ip = ip
|
||||||
|
|
||||||
|
|
||||||
|
class CreateLoadBalancerResponse(BaseDomain):
|
||||||
|
"""Create Load Balancer Response Domain
|
||||||
|
|
||||||
|
:param load_balancer: :class:`BoundLoadBalancer <hcloud.load_balancers.client.BoundLoadBalancer>`
|
||||||
|
The created Load Balancer
|
||||||
|
:param action: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
Shows the progress of the Load Balancer creation
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("load_balancer", "action")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
load_balancer, # type: BoundLoadBalancer
|
||||||
|
action, # type: BoundAction
|
||||||
|
):
|
||||||
|
self.load_balancer = load_balancer
|
||||||
|
self.action = action
|
0
plugins/module_utils/vendor/hcloud/locations/__init__.py
vendored
Normal file
0
plugins/module_utils/vendor/hcloud/locations/__init__.py
vendored
Normal file
67
plugins/module_utils/vendor/hcloud/locations/client.py
vendored
Normal file
67
plugins/module_utils/vendor/hcloud/locations/client.py
vendored
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
from ..core.client import BoundModelBase, ClientEntityBase, GetEntityByNameMixin
|
||||||
|
from .domain import Location
|
||||||
|
|
||||||
|
|
||||||
|
class BoundLocation(BoundModelBase):
|
||||||
|
model = Location
|
||||||
|
|
||||||
|
|
||||||
|
class LocationsClient(ClientEntityBase, GetEntityByNameMixin):
|
||||||
|
results_list_attribute_name = "locations"
|
||||||
|
|
||||||
|
def get_by_id(self, id):
|
||||||
|
# type: (int) -> locations.client.BoundLocation
|
||||||
|
"""Get a specific location by its ID.
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
:return: :class:`BoundLocation <hcloud.locations.client.BoundLocation>`
|
||||||
|
"""
|
||||||
|
response = self._client.request(url=f"/locations/{id}", method="GET")
|
||||||
|
return BoundLocation(self, response["location"])
|
||||||
|
|
||||||
|
def get_list(self, name=None, page=None, per_page=None):
|
||||||
|
# type: (Optional[str], Optional[int], Optional[int]) -> PageResult[List[BoundLocation], Meta]
|
||||||
|
"""Get a list of locations
|
||||||
|
|
||||||
|
:param name: str (optional)
|
||||||
|
Can be used to filter locations by their name.
|
||||||
|
: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:`BoundLocation <hcloud.locations.client.BoundLocation>`], :class:`Meta <hcloud.core.domain.Meta>`)
|
||||||
|
"""
|
||||||
|
params = {}
|
||||||
|
if name is not None:
|
||||||
|
params["name"] = name
|
||||||
|
if page is not None:
|
||||||
|
params["page"] = page
|
||||||
|
if per_page is not None:
|
||||||
|
params["per_page"] = per_page
|
||||||
|
|
||||||
|
response = self._client.request(url="/locations", method="GET", params=params)
|
||||||
|
locations = [
|
||||||
|
BoundLocation(self, location_data)
|
||||||
|
for location_data in response["locations"]
|
||||||
|
]
|
||||||
|
return self._add_meta_to_result(locations, response)
|
||||||
|
|
||||||
|
def get_all(self, name=None):
|
||||||
|
# type: (Optional[str]) -> List[BoundLocation]
|
||||||
|
"""Get all locations
|
||||||
|
|
||||||
|
:param name: str (optional)
|
||||||
|
Can be used to filter locations by their name.
|
||||||
|
:return: List[:class:`BoundLocation <hcloud.locations.client.BoundLocation>`]
|
||||||
|
"""
|
||||||
|
return super().get_all(name=name)
|
||||||
|
|
||||||
|
def get_by_name(self, name):
|
||||||
|
# type: (str) -> BoundLocation
|
||||||
|
"""Get location by name
|
||||||
|
|
||||||
|
:param name: str
|
||||||
|
Used to get location by name.
|
||||||
|
:return: :class:`BoundLocation <hcloud.locations.client.BoundLocation>`
|
||||||
|
"""
|
||||||
|
return super().get_by_name(name)
|
54
plugins/module_utils/vendor/hcloud/locations/domain.py
vendored
Normal file
54
plugins/module_utils/vendor/hcloud/locations/domain.py
vendored
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
from ..core.domain import BaseDomain, DomainIdentityMixin
|
||||||
|
|
||||||
|
|
||||||
|
class Location(BaseDomain, DomainIdentityMixin):
|
||||||
|
"""Location Domain
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
ID of location
|
||||||
|
:param name: str
|
||||||
|
Name of location
|
||||||
|
:param description: str
|
||||||
|
Description of location
|
||||||
|
:param country: str
|
||||||
|
ISO 3166-1 alpha-2 code of the country the location resides in
|
||||||
|
:param city: str
|
||||||
|
City the location is closest to
|
||||||
|
:param latitude: float
|
||||||
|
Latitude of the city closest to the location
|
||||||
|
:param longitude: float
|
||||||
|
Longitude of the city closest to the location
|
||||||
|
:param network_zone: str
|
||||||
|
Name of network zone this location resides in
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = (
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"description",
|
||||||
|
"country",
|
||||||
|
"city",
|
||||||
|
"latitude",
|
||||||
|
"longitude",
|
||||||
|
"network_zone",
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
id=None,
|
||||||
|
name=None,
|
||||||
|
description=None,
|
||||||
|
country=None,
|
||||||
|
city=None,
|
||||||
|
latitude=None,
|
||||||
|
longitude=None,
|
||||||
|
network_zone=None,
|
||||||
|
):
|
||||||
|
self.id = id
|
||||||
|
self.name = name
|
||||||
|
self.description = description
|
||||||
|
self.country = country
|
||||||
|
self.city = city
|
||||||
|
self.latitude = latitude
|
||||||
|
self.longitude = longitude
|
||||||
|
self.network_zone = network_zone
|
0
plugins/module_utils/vendor/hcloud/networks/__init__.py
vendored
Normal file
0
plugins/module_utils/vendor/hcloud/networks/__init__.py
vendored
Normal file
499
plugins/module_utils/vendor/hcloud/networks/client.py
vendored
Normal file
499
plugins/module_utils/vendor/hcloud/networks/client.py
vendored
Normal file
|
@ -0,0 +1,499 @@
|
||||||
|
from ..actions.client import BoundAction
|
||||||
|
from ..core.client import BoundModelBase, ClientEntityBase, GetEntityByNameMixin
|
||||||
|
from ..core.domain import add_meta_to_result
|
||||||
|
from .domain import Network, NetworkRoute, NetworkSubnet
|
||||||
|
|
||||||
|
|
||||||
|
class BoundNetwork(BoundModelBase):
|
||||||
|
model = Network
|
||||||
|
|
||||||
|
def __init__(self, client, data, complete=True):
|
||||||
|
subnets = data.get("subnets", [])
|
||||||
|
if subnets is not None:
|
||||||
|
subnets = [NetworkSubnet.from_dict(subnet) for subnet in subnets]
|
||||||
|
data["subnets"] = subnets
|
||||||
|
|
||||||
|
routes = data.get("routes", [])
|
||||||
|
if routes is not None:
|
||||||
|
routes = [NetworkRoute.from_dict(route) for route in routes]
|
||||||
|
data["routes"] = routes
|
||||||
|
|
||||||
|
from ..servers.client import BoundServer
|
||||||
|
|
||||||
|
servers = data.get("servers", [])
|
||||||
|
if servers is not None:
|
||||||
|
servers = [
|
||||||
|
BoundServer(client._client.servers, {"id": server}, complete=False)
|
||||||
|
for server in servers
|
||||||
|
]
|
||||||
|
data["servers"] = servers
|
||||||
|
|
||||||
|
super().__init__(client, data, complete)
|
||||||
|
|
||||||
|
def update(
|
||||||
|
self,
|
||||||
|
name=None, # type: Optional[str]
|
||||||
|
expose_routes_to_vswitch=None, # type: Optional[bool]
|
||||||
|
labels=None, # type: Optional[Dict[str, str]]
|
||||||
|
): # type: (...) -> BoundNetwork
|
||||||
|
"""Updates a network. You can update a network’s name and a networks’s labels.
|
||||||
|
|
||||||
|
:param name: str (optional)
|
||||||
|
New name to set
|
||||||
|
:param expose_routes_to_vswitch: Optional[bool]
|
||||||
|
Indicates if the routes from this network should be exposed to the vSwitch connection.
|
||||||
|
The exposing only takes effect if a vSwitch connection is active.
|
||||||
|
:param labels: Dict[str, str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:return: :class:`BoundNetwork <hcloud.networks.client.BoundNetwork>`
|
||||||
|
"""
|
||||||
|
return self._client.update(
|
||||||
|
self,
|
||||||
|
name=name,
|
||||||
|
expose_routes_to_vswitch=expose_routes_to_vswitch,
|
||||||
|
labels=labels,
|
||||||
|
)
|
||||||
|
|
||||||
|
def delete(self):
|
||||||
|
# type: () -> BoundAction
|
||||||
|
"""Deletes a network.
|
||||||
|
|
||||||
|
:return: boolean
|
||||||
|
"""
|
||||||
|
return self._client.delete(self)
|
||||||
|
|
||||||
|
def get_actions_list(self, status=None, sort=None, page=None, per_page=None):
|
||||||
|
# type: (Optional[List[str]], Optional[List[str]], Optional[int], Optional[int]) -> PageResults[List[BoundAction, Meta]]
|
||||||
|
"""Returns all action objects for a network.
|
||||||
|
|
||||||
|
:param status: List[str] (optional)
|
||||||
|
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
||||||
|
:param sort: List[str] (optional)
|
||||||
|
Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
|
||||||
|
:param page: int (optional)
|
||||||
|
Specifies the page to fetch
|
||||||
|
:param per_page: int (optional)
|
||||||
|
Specifies how many results are returned by page
|
||||||
|
:return: (List[:class:`BoundAction <hcloud.actions.client.BoundAction>`], :class:`Meta <hcloud.core.domain.Meta>`)
|
||||||
|
"""
|
||||||
|
return self._client.get_actions_list(self, status, sort, page, per_page)
|
||||||
|
|
||||||
|
def get_actions(self, status=None, sort=None):
|
||||||
|
# type: (Optional[List[str]], Optional[List[str]]) -> List[BoundAction]
|
||||||
|
"""Returns all action objects for a network.
|
||||||
|
|
||||||
|
:param status: List[str] (optional)
|
||||||
|
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
||||||
|
:param sort: List[str] (optional)
|
||||||
|
Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
|
||||||
|
:return: List[:class:`BoundAction <hcloud.actions.client.BoundAction>`]
|
||||||
|
"""
|
||||||
|
return self._client.get_actions(self, status, sort)
|
||||||
|
|
||||||
|
def add_subnet(self, subnet):
|
||||||
|
# type: (NetworkSubnet) -> List[BoundAction]
|
||||||
|
"""Adds a subnet entry to a network.
|
||||||
|
|
||||||
|
:param subnet: :class:`NetworkSubnet <hcloud.networks.domain.NetworkSubnet>`
|
||||||
|
The NetworkSubnet you want to add to the Network
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.add_subnet(self, subnet=subnet)
|
||||||
|
|
||||||
|
def delete_subnet(self, subnet):
|
||||||
|
# type: (NetworkSubnet) -> List[BoundAction]
|
||||||
|
"""Removes a subnet entry from a network
|
||||||
|
|
||||||
|
:param subnet: :class:`NetworkSubnet <hcloud.networks.domain.NetworkSubnet>`
|
||||||
|
The NetworkSubnet you want to remove from the Network
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.delete_subnet(self, subnet=subnet)
|
||||||
|
|
||||||
|
def add_route(self, route):
|
||||||
|
# type: (NetworkRoute) -> List[BoundAction]
|
||||||
|
"""Adds a route entry to a network.
|
||||||
|
|
||||||
|
:param route: :class:`NetworkRoute <hcloud.networks.domain.NetworkRoute>`
|
||||||
|
The NetworkRoute you want to add to the Network
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.add_route(self, route=route)
|
||||||
|
|
||||||
|
def delete_route(self, route):
|
||||||
|
# type: (NetworkRoute) -> List[BoundAction]
|
||||||
|
"""Removes a route entry to a network.
|
||||||
|
|
||||||
|
:param route: :class:`NetworkRoute <hcloud.networks.domain.NetworkRoute>`
|
||||||
|
The NetworkRoute you want to remove from the Network
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.delete_route(self, route=route)
|
||||||
|
|
||||||
|
def change_ip_range(self, ip_range):
|
||||||
|
# type: (str) -> List[BoundAction]
|
||||||
|
"""Changes the IP range of a network.
|
||||||
|
|
||||||
|
:param ip_range: str
|
||||||
|
The new prefix for the whole network.
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.change_ip_range(self, ip_range=ip_range)
|
||||||
|
|
||||||
|
def change_protection(self, delete=None):
|
||||||
|
# type: (Optional[bool]) -> BoundAction
|
||||||
|
"""Changes the protection configuration of a network.
|
||||||
|
|
||||||
|
:param delete: boolean
|
||||||
|
If True, prevents the network from being deleted
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.change_protection(self, delete=delete)
|
||||||
|
|
||||||
|
|
||||||
|
class NetworksClient(ClientEntityBase, GetEntityByNameMixin):
|
||||||
|
results_list_attribute_name = "networks"
|
||||||
|
|
||||||
|
def get_by_id(self, id):
|
||||||
|
# type: (int) -> BoundNetwork
|
||||||
|
"""Get a specific network
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
:return: :class:`BoundNetwork <hcloud.networks.client.BoundNetwork>
|
||||||
|
"""
|
||||||
|
response = self._client.request(url=f"/networks/{id}", method="GET")
|
||||||
|
return BoundNetwork(self, response["network"])
|
||||||
|
|
||||||
|
def get_list(
|
||||||
|
self,
|
||||||
|
name=None, # type: Optional[str]
|
||||||
|
label_selector=None, # type: Optional[str]
|
||||||
|
page=None, # type: Optional[int]
|
||||||
|
per_page=None, # type: Optional[int]
|
||||||
|
):
|
||||||
|
# type: (...) -> PageResults[List[BoundNetwork], Meta]
|
||||||
|
"""Get a list of networks from this account
|
||||||
|
|
||||||
|
:param name: str (optional)
|
||||||
|
Can be used to filter networks by their name.
|
||||||
|
:param label_selector: str (optional)
|
||||||
|
Can be used to filter networks by labels. The response will only contain networks matching the label selector.
|
||||||
|
: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:`BoundNetwork <hcloud.networks.client.BoundNetwork>`], :class:`Meta <hcloud.core.domain.Meta>`)
|
||||||
|
"""
|
||||||
|
params = {}
|
||||||
|
if name is not None:
|
||||||
|
params["name"] = name
|
||||||
|
if label_selector is not None:
|
||||||
|
params["label_selector"] = label_selector
|
||||||
|
if page is not None:
|
||||||
|
params["page"] = page
|
||||||
|
if per_page is not None:
|
||||||
|
params["per_page"] = per_page
|
||||||
|
|
||||||
|
response = self._client.request(url="/networks", method="GET", params=params)
|
||||||
|
|
||||||
|
ass_networks = [
|
||||||
|
BoundNetwork(self, network_data) for network_data in response["networks"]
|
||||||
|
]
|
||||||
|
return self._add_meta_to_result(ass_networks, response)
|
||||||
|
|
||||||
|
def get_all(self, name=None, label_selector=None):
|
||||||
|
# type: (Optional[str], Optional[str]) -> List[BoundNetwork]
|
||||||
|
"""Get all networks from this account
|
||||||
|
|
||||||
|
:param name: str (optional)
|
||||||
|
Can be used to filter networks by their name.
|
||||||
|
:param label_selector: str (optional)
|
||||||
|
Can be used to filter networks by labels. The response will only contain networks matching the label selector.
|
||||||
|
:return: List[:class:`BoundNetwork <hcloud.networks.client.BoundNetwork>`]
|
||||||
|
"""
|
||||||
|
return super().get_all(name=name, label_selector=label_selector)
|
||||||
|
|
||||||
|
def get_by_name(self, name):
|
||||||
|
# type: (str) -> BoundNetwork
|
||||||
|
"""Get network by name
|
||||||
|
|
||||||
|
:param name: str
|
||||||
|
Used to get network by name.
|
||||||
|
:return: :class:`BoundNetwork <hcloud.networks.client.BoundNetwork>`
|
||||||
|
"""
|
||||||
|
return super().get_by_name(name)
|
||||||
|
|
||||||
|
def create(
|
||||||
|
self,
|
||||||
|
name, # type: str
|
||||||
|
ip_range, # type: str
|
||||||
|
subnets=None, # type: Optional[List[NetworkSubnet]]
|
||||||
|
routes=None, # type: Optional[List[NetworkRoute]]
|
||||||
|
expose_routes_to_vswitch=None, # type: Optional[bool]
|
||||||
|
labels=None, # type: Optional[Dict[str, str]]
|
||||||
|
):
|
||||||
|
"""Creates a network with range ip_range.
|
||||||
|
|
||||||
|
:param name: str
|
||||||
|
Name of the network
|
||||||
|
:param ip_range: str
|
||||||
|
IP range of the whole network which must span all included subnets and route destinations
|
||||||
|
:param subnets: List[:class:`NetworkSubnet <hcloud.networks.domain.NetworkSubnet>`]
|
||||||
|
Array of subnets allocated
|
||||||
|
:param routes: List[:class:`NetworkRoute <hcloud.networks.domain.NetworkRoute>`]
|
||||||
|
Array of routes set in this network
|
||||||
|
:param expose_routes_to_vswitch: Optional[bool]
|
||||||
|
Indicates if the routes from this network should be exposed to the vSwitch connection.
|
||||||
|
The exposing only takes effect if a vSwitch connection is active.
|
||||||
|
:param labels: Dict[str, str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:return: :class:`BoundNetwork <hcloud.networks.client.BoundNetwork>`
|
||||||
|
"""
|
||||||
|
data = {"name": name, "ip_range": ip_range}
|
||||||
|
if subnets is not None:
|
||||||
|
data_subnets = []
|
||||||
|
for subnet in subnets:
|
||||||
|
data_subnet = {
|
||||||
|
"type": subnet.type,
|
||||||
|
"ip_range": subnet.ip_range,
|
||||||
|
"network_zone": subnet.network_zone,
|
||||||
|
}
|
||||||
|
if subnet.vswitch_id is not None:
|
||||||
|
data_subnet["vswitch_id"] = subnet.vswitch_id
|
||||||
|
|
||||||
|
data_subnets.append(data_subnet)
|
||||||
|
data["subnets"] = data_subnets
|
||||||
|
|
||||||
|
if routes is not None:
|
||||||
|
data["routes"] = [
|
||||||
|
{"destination": route.destination, "gateway": route.gateway}
|
||||||
|
for route in routes
|
||||||
|
]
|
||||||
|
|
||||||
|
if expose_routes_to_vswitch is not None:
|
||||||
|
data["expose_routes_to_vswitch"] = expose_routes_to_vswitch
|
||||||
|
|
||||||
|
if labels is not None:
|
||||||
|
data["labels"] = labels
|
||||||
|
|
||||||
|
response = self._client.request(url="/networks", method="POST", json=data)
|
||||||
|
|
||||||
|
return BoundNetwork(self, response["network"])
|
||||||
|
|
||||||
|
def update(self, network, name=None, expose_routes_to_vswitch=None, labels=None):
|
||||||
|
# type:(Network, Optional[str], Optional[bool], Optional[Dict[str, str]]) -> BoundNetwork
|
||||||
|
"""Updates a network. You can update a network’s name and a network’s labels.
|
||||||
|
|
||||||
|
:param network: :class:`BoundNetwork <hcloud.networks.client.BoundNetwork>` or :class:`Network <hcloud.networks.domain.Network>`
|
||||||
|
:param name: str (optional)
|
||||||
|
New name to set
|
||||||
|
:param expose_routes_to_vswitch: Optional[bool]
|
||||||
|
Indicates if the routes from this network should be exposed to the vSwitch connection.
|
||||||
|
The exposing only takes effect if a vSwitch connection is active.
|
||||||
|
:param labels: Dict[str, str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:return: :class:`BoundNetwork <hcloud.networks.client.BoundNetwork>`
|
||||||
|
"""
|
||||||
|
data = {}
|
||||||
|
if name is not None:
|
||||||
|
data.update({"name": name})
|
||||||
|
|
||||||
|
if expose_routes_to_vswitch is not None:
|
||||||
|
data["expose_routes_to_vswitch"] = expose_routes_to_vswitch
|
||||||
|
|
||||||
|
if labels is not None:
|
||||||
|
data.update({"labels": labels})
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url=f"/networks/{network.id}",
|
||||||
|
method="PUT",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return BoundNetwork(self, response["network"])
|
||||||
|
|
||||||
|
def delete(self, network):
|
||||||
|
# type: (Network) -> BoundAction
|
||||||
|
"""Deletes a network.
|
||||||
|
|
||||||
|
:param network: :class:`BoundNetwork <hcloud.networks.client.BoundNetwork>` or :class:`Network <hcloud.networks.domain.Network>`
|
||||||
|
:return: boolean
|
||||||
|
"""
|
||||||
|
self._client.request(url=f"/networks/{network.id}", method="DELETE")
|
||||||
|
return True
|
||||||
|
|
||||||
|
def get_actions_list(
|
||||||
|
self, network, status=None, sort=None, page=None, per_page=None
|
||||||
|
):
|
||||||
|
# type: (Network, Optional[List[str]], Optional[List[str]], Optional[int], Optional[int]) -> PageResults[List[BoundAction], Meta]
|
||||||
|
"""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 = {}
|
||||||
|
if status is not None:
|
||||||
|
params["status"] = status
|
||||||
|
if sort is not None:
|
||||||
|
params["sort"] = sort
|
||||||
|
if page is not None:
|
||||||
|
params["page"] = page
|
||||||
|
if per_page is not None:
|
||||||
|
params["per_page"] = per_page
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url=f"/networks/{network.id}/actions",
|
||||||
|
method="GET",
|
||||||
|
params=params,
|
||||||
|
)
|
||||||
|
actions = [
|
||||||
|
BoundAction(self._client.actions, action_data)
|
||||||
|
for action_data in response["actions"]
|
||||||
|
]
|
||||||
|
return add_meta_to_result(actions, response, "actions")
|
||||||
|
|
||||||
|
def get_actions(self, network, status=None, sort=None):
|
||||||
|
# type: (Network, Optional[List[str]], Optional[List[str]]) -> List[BoundAction]
|
||||||
|
"""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`
|
||||||
|
:return: List[:class:`BoundAction <hcloud.actions.client.BoundAction>`]
|
||||||
|
"""
|
||||||
|
return super().get_actions(network, status=status, sort=sort)
|
||||||
|
|
||||||
|
def add_subnet(self, network, subnet):
|
||||||
|
# type: (Union[Network, BoundNetwork], NetworkSubnet) -> List[BoundAction]
|
||||||
|
"""Adds a subnet entry to a network.
|
||||||
|
|
||||||
|
:param network: :class:`BoundNetwork <hcloud.networks.client.BoundNetwork>` or :class:`Network <hcloud.networks.domain.Network>`
|
||||||
|
:param subnet: :class:`NetworkSubnet <hcloud.networks.domain.NetworkSubnet>`
|
||||||
|
The NetworkSubnet you want to add to the Network
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
data = {"type": subnet.type, "network_zone": subnet.network_zone}
|
||||||
|
if subnet.ip_range is not None:
|
||||||
|
data["ip_range"] = subnet.ip_range
|
||||||
|
if subnet.vswitch_id is not None:
|
||||||
|
data["vswitch_id"] = subnet.vswitch_id
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url="/networks/{network_id}/actions/add_subnet".format(
|
||||||
|
network_id=network.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
||||||
|
|
||||||
|
def delete_subnet(self, network, subnet):
|
||||||
|
# type: (Union[Network, BoundNetwork], NetworkSubnet) -> List[BoundAction]
|
||||||
|
"""Removes a subnet entry from a network
|
||||||
|
|
||||||
|
:param network: :class:`BoundNetwork <hcloud.networks.client.BoundNetwork>` or :class:`Network <hcloud.networks.domain.Network>`
|
||||||
|
:param subnet: :class:`NetworkSubnet <hcloud.networks.domain.NetworkSubnet>`
|
||||||
|
The NetworkSubnet you want to remove from the Network
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
data = {"ip_range": subnet.ip_range}
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url="/networks/{network_id}/actions/delete_subnet".format(
|
||||||
|
network_id=network.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
||||||
|
|
||||||
|
def add_route(self, network, route):
|
||||||
|
# type: (Union[Network, BoundNetwork], NetworkRoute) -> List[BoundAction]
|
||||||
|
"""Adds a route entry to a network.
|
||||||
|
|
||||||
|
:param network: :class:`BoundNetwork <hcloud.networks.client.BoundNetwork>` or :class:`Network <hcloud.networks.domain.Network>`
|
||||||
|
:param route: :class:`NetworkRoute <hcloud.networks.domain.NetworkRoute>`
|
||||||
|
The NetworkRoute you want to add to the Network
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
data = {"destination": route.destination, "gateway": route.gateway}
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url="/networks/{network_id}/actions/add_route".format(
|
||||||
|
network_id=network.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
||||||
|
|
||||||
|
def delete_route(self, network, route):
|
||||||
|
# type: (Union[Network, BoundNetwork], NetworkRoute) -> List[BoundAction]
|
||||||
|
"""Removes a route entry to a network.
|
||||||
|
|
||||||
|
:param network: :class:`BoundNetwork <hcloud.networks.client.BoundNetwork>` or :class:`Network <hcloud.networks.domain.Network>`
|
||||||
|
:param route: :class:`NetworkRoute <hcloud.networks.domain.NetworkRoute>`
|
||||||
|
The NetworkRoute you want to remove from the Network
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
data = {"destination": route.destination, "gateway": route.gateway}
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url="/networks/{network_id}/actions/delete_route".format(
|
||||||
|
network_id=network.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
||||||
|
|
||||||
|
def change_ip_range(self, network, ip_range):
|
||||||
|
# type: (Union[Network, BoundNetwork], str) -> List[BoundAction]
|
||||||
|
"""Changes the IP range of a network.
|
||||||
|
|
||||||
|
:param network: :class:`BoundNetwork <hcloud.networks.client.BoundNetwork>` or :class:`Network <hcloud.networks.domain.Network>`
|
||||||
|
:param ip_range: str
|
||||||
|
The new prefix for the whole network.
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
data = {"ip_range": ip_range}
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url="/networks/{network_id}/actions/change_ip_range".format(
|
||||||
|
network_id=network.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
||||||
|
|
||||||
|
def change_protection(self, network, delete=None):
|
||||||
|
# type: (Union[Network, BoundNetwork], Optional[bool]) -> BoundAction
|
||||||
|
"""Changes the protection configuration of a network.
|
||||||
|
|
||||||
|
:param network: :class:`BoundNetwork <hcloud.networks.client.BoundNetwork>` or :class:`Network <hcloud.networks.domain.Network>`
|
||||||
|
:param delete: boolean
|
||||||
|
If True, prevents the network from being deleted
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
data = {}
|
||||||
|
if delete is not None:
|
||||||
|
data.update({"delete": delete})
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url="/networks/{network_id}/actions/change_protection".format(
|
||||||
|
network_id=network.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
136
plugins/module_utils/vendor/hcloud/networks/domain.py
vendored
Normal file
136
plugins/module_utils/vendor/hcloud/networks/domain.py
vendored
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
try:
|
||||||
|
from dateutil.parser import isoparse
|
||||||
|
except ImportError:
|
||||||
|
isoparse = None
|
||||||
|
|
||||||
|
from ..core.domain import BaseDomain
|
||||||
|
|
||||||
|
|
||||||
|
class Network(BaseDomain):
|
||||||
|
"""Network Domain
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
ID of the network
|
||||||
|
:param name: str
|
||||||
|
Name of the network
|
||||||
|
:param ip_range: str
|
||||||
|
IPv4 prefix of the whole network
|
||||||
|
:param subnets: List[:class:`NetworkSubnet <hcloud.networks.domain.NetworkSubnet>`]
|
||||||
|
Subnets allocated in this network
|
||||||
|
:param routes: List[:class:`NetworkRoute <hcloud.networks.domain.NetworkRoute>`]
|
||||||
|
Routes set in this network
|
||||||
|
:param expose_routes_to_vswitch: bool
|
||||||
|
Indicates if the routes from this network should be exposed to the vSwitch connection.
|
||||||
|
:param servers: List[:class:`BoundServer <hcloud.servers.client.BoundServer>`]
|
||||||
|
Servers attached to this network
|
||||||
|
:param protection: dict
|
||||||
|
Protection configuration for the network
|
||||||
|
:param labels: dict
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = (
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"ip_range",
|
||||||
|
"subnets",
|
||||||
|
"routes",
|
||||||
|
"expose_routes_to_vswitch",
|
||||||
|
"servers",
|
||||||
|
"protection",
|
||||||
|
"labels",
|
||||||
|
"created",
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
id,
|
||||||
|
name=None,
|
||||||
|
created=None,
|
||||||
|
ip_range=None,
|
||||||
|
subnets=None,
|
||||||
|
routes=None,
|
||||||
|
expose_routes_to_vswitch=None,
|
||||||
|
servers=None,
|
||||||
|
protection=None,
|
||||||
|
labels=None,
|
||||||
|
):
|
||||||
|
self.id = id
|
||||||
|
self.name = name
|
||||||
|
self.created = isoparse(created) if created else None
|
||||||
|
self.ip_range = ip_range
|
||||||
|
self.subnets = subnets
|
||||||
|
self.routes = routes
|
||||||
|
self.expose_routes_to_vswitch = expose_routes_to_vswitch
|
||||||
|
self.servers = servers
|
||||||
|
self.protection = protection
|
||||||
|
self.labels = labels
|
||||||
|
|
||||||
|
|
||||||
|
class NetworkSubnet(BaseDomain):
|
||||||
|
"""Network Subnet Domain
|
||||||
|
|
||||||
|
:param type: str
|
||||||
|
Type of sub network.
|
||||||
|
:param ip_range: str
|
||||||
|
Range to allocate IPs from.
|
||||||
|
:param network_zone: str
|
||||||
|
Name of network zone.
|
||||||
|
:param gateway: str
|
||||||
|
Gateway for the route.
|
||||||
|
:param vswitch_id: int
|
||||||
|
ID of the vSwitch.
|
||||||
|
"""
|
||||||
|
|
||||||
|
TYPE_SERVER = "server"
|
||||||
|
"""Subnet Type server, deprecated, use TYPE_CLOUD instead"""
|
||||||
|
TYPE_CLOUD = "cloud"
|
||||||
|
"""Subnet Type cloud"""
|
||||||
|
TYPE_VSWITCH = "vswitch"
|
||||||
|
"""Subnet Type vSwitch"""
|
||||||
|
__slots__ = ("type", "ip_range", "network_zone", "gateway", "vswitch_id")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self, ip_range, type=None, network_zone=None, gateway=None, vswitch_id=None
|
||||||
|
):
|
||||||
|
self.type = type
|
||||||
|
self.ip_range = ip_range
|
||||||
|
self.network_zone = network_zone
|
||||||
|
self.gateway = gateway
|
||||||
|
self.vswitch_id = vswitch_id
|
||||||
|
|
||||||
|
|
||||||
|
class NetworkRoute(BaseDomain):
|
||||||
|
"""Network Route Domain
|
||||||
|
|
||||||
|
:param destination: str
|
||||||
|
Destination network or host of this route.
|
||||||
|
:param gateway: str
|
||||||
|
Gateway for the route.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("destination", "gateway")
|
||||||
|
|
||||||
|
def __init__(self, destination, gateway):
|
||||||
|
self.destination = destination
|
||||||
|
self.gateway = gateway
|
||||||
|
|
||||||
|
|
||||||
|
class CreateNetworkResponse(BaseDomain):
|
||||||
|
"""Create Network Response Domain
|
||||||
|
|
||||||
|
:param network: :class:`BoundNetwork <hcloud.networks.client.BoundNetwork>`
|
||||||
|
The network which was created
|
||||||
|
:param action: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
The Action which shows the progress of the network Creation
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("network", "action")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
network, # type: BoundNetwork
|
||||||
|
action, # type: BoundAction
|
||||||
|
):
|
||||||
|
self.network = network
|
||||||
|
self.action = action
|
0
plugins/module_utils/vendor/hcloud/placement_groups/__init__.py
vendored
Normal file
0
plugins/module_utils/vendor/hcloud/placement_groups/__init__.py
vendored
Normal file
194
plugins/module_utils/vendor/hcloud/placement_groups/client.py
vendored
Normal file
194
plugins/module_utils/vendor/hcloud/placement_groups/client.py
vendored
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
from ..actions.client import BoundAction
|
||||||
|
from ..core.client import BoundModelBase, ClientEntityBase, GetEntityByNameMixin
|
||||||
|
from .domain import CreatePlacementGroupResponse, PlacementGroup
|
||||||
|
|
||||||
|
|
||||||
|
class BoundPlacementGroup(BoundModelBase):
|
||||||
|
model = PlacementGroup
|
||||||
|
|
||||||
|
def update(self, labels=None, name=None):
|
||||||
|
# type: (Optional[str], Optional[Dict[str, str]], Optional[str]) -> BoundPlacementGroup
|
||||||
|
"""Updates the name or labels of a Placement Group
|
||||||
|
|
||||||
|
:param labels: Dict[str, str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:param name: str, (optional)
|
||||||
|
New Name to set
|
||||||
|
:return: :class:`BoundPlacementGroup <hcloud.placement_groups.client.BoundPlacementGroup>`
|
||||||
|
"""
|
||||||
|
return self._client.update(self, labels, name)
|
||||||
|
|
||||||
|
def delete(self):
|
||||||
|
# type: () -> bool
|
||||||
|
"""Deletes a Placement Group
|
||||||
|
|
||||||
|
:return: boolean
|
||||||
|
"""
|
||||||
|
return self._client.delete(self)
|
||||||
|
|
||||||
|
|
||||||
|
class PlacementGroupsClient(ClientEntityBase, GetEntityByNameMixin):
|
||||||
|
results_list_attribute_name = "placement_groups"
|
||||||
|
|
||||||
|
def get_by_id(self, id):
|
||||||
|
# type: (int) -> BoundPlacementGroup
|
||||||
|
"""Returns a specific Placement Group object
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
:return: :class:`BoundPlacementGroup <hcloud.placement_groups.client.BoundPlacementGroup>`
|
||||||
|
"""
|
||||||
|
response = self._client.request(
|
||||||
|
url=f"/placement_groups/{id}",
|
||||||
|
method="GET",
|
||||||
|
)
|
||||||
|
return BoundPlacementGroup(self, response["placement_group"])
|
||||||
|
|
||||||
|
def get_list(
|
||||||
|
self,
|
||||||
|
label_selector=None, # type: Optional[str]
|
||||||
|
page=None, # type: Optional[int]
|
||||||
|
per_page=None, # type: Optional[int]
|
||||||
|
name=None, # type: Optional[str]
|
||||||
|
sort=None, # type: Optional[List[str]]
|
||||||
|
type=None, # type: Optional[str]
|
||||||
|
):
|
||||||
|
# type: (...) -> PageResults[List[BoundPlacementGroup]]
|
||||||
|
"""Get a list of Placement Groups
|
||||||
|
|
||||||
|
:param label_selector: str (optional)
|
||||||
|
Can be used to filter Placement Groups by labels. The response will only contain Placement Groups matching the label selector values.
|
||||||
|
:param page: int (optional)
|
||||||
|
Specifies the page to fetch
|
||||||
|
:param per_page: int (optional)
|
||||||
|
Specifies how many results are returned by page
|
||||||
|
:param name: str (optional)
|
||||||
|
Can be used to filter Placement Groups by their name.
|
||||||
|
:param sort: List[str] (optional)
|
||||||
|
Choices: id name created (You can add one of ":asc", ":desc" to modify sort order. ( ":asc" is default))
|
||||||
|
:return: (List[:class:`BoundPlacementGroup <hcloud.placement_groups.client.BoundPlacementGroup>`], :class:`Meta <hcloud.core.domain.Meta>`)
|
||||||
|
"""
|
||||||
|
|
||||||
|
params = {}
|
||||||
|
|
||||||
|
if label_selector is not None:
|
||||||
|
params["label_selector"] = label_selector
|
||||||
|
if page is not None:
|
||||||
|
params["page"] = page
|
||||||
|
if per_page is not None:
|
||||||
|
params["per_page"] = per_page
|
||||||
|
if name is not None:
|
||||||
|
params["name"] = name
|
||||||
|
if sort is not None:
|
||||||
|
params["sort"] = sort
|
||||||
|
if type is not None:
|
||||||
|
params["type"] = type
|
||||||
|
response = self._client.request(
|
||||||
|
url="/placement_groups", method="GET", params=params
|
||||||
|
)
|
||||||
|
placement_groups = [
|
||||||
|
BoundPlacementGroup(self, placement_group_data)
|
||||||
|
for placement_group_data in response["placement_groups"]
|
||||||
|
]
|
||||||
|
|
||||||
|
return self._add_meta_to_result(placement_groups, response)
|
||||||
|
|
||||||
|
def get_all(self, label_selector=None, name=None, sort=None):
|
||||||
|
# type: (Optional[str], Optional[str], Optional[List[str]]) -> List[BoundPlacementGroup]
|
||||||
|
"""Get all Placement Groups
|
||||||
|
|
||||||
|
:param label_selector: str (optional)
|
||||||
|
Can be used to filter Placement Groups by labels. The response will only contain Placement Groups matching the label selector values.
|
||||||
|
:param name: str (optional)
|
||||||
|
Can be used to filter Placement Groups by their name.
|
||||||
|
:param sort: List[str] (optional)
|
||||||
|
Choices: id name created (You can add one of ":asc", ":desc" to modify sort order. ( ":asc" is default))
|
||||||
|
:return: List[:class:`BoundPlacementGroup <hcloud.placement_groups.client.BoundPlacementGroup>`]
|
||||||
|
"""
|
||||||
|
return super().get_all(label_selector=label_selector, name=name, sort=sort)
|
||||||
|
|
||||||
|
def get_by_name(self, name):
|
||||||
|
# type: (str) -> BoundPlacementGroup
|
||||||
|
"""Get Placement Group by name
|
||||||
|
|
||||||
|
:param name: str
|
||||||
|
Used to get Placement Group by name
|
||||||
|
:return: class:`BoundPlacementGroup <hcloud.placement_groups.client.BoundPlacementGroup>`
|
||||||
|
"""
|
||||||
|
return super().get_by_name(name)
|
||||||
|
|
||||||
|
def create(
|
||||||
|
self,
|
||||||
|
name, # type: str
|
||||||
|
type, # type: str
|
||||||
|
labels=None, # type: Optional[Dict[str, str]]
|
||||||
|
):
|
||||||
|
# type: (...) -> CreatePlacementGroupResponse
|
||||||
|
"""Creates a new Placement Group.
|
||||||
|
|
||||||
|
:param name: str
|
||||||
|
Placement Group Name
|
||||||
|
:param type: str
|
||||||
|
Type of the Placement Group
|
||||||
|
:param labels: Dict[str, str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
|
||||||
|
:return: :class:`CreatePlacementGroupResponse <hcloud.placement_groups.domain.CreatePlacementGroupResponse>`
|
||||||
|
"""
|
||||||
|
data = {"name": name, "type": type}
|
||||||
|
if labels is not None:
|
||||||
|
data["labels"] = labels
|
||||||
|
response = self._client.request(
|
||||||
|
url="/placement_groups", json=data, method="POST"
|
||||||
|
)
|
||||||
|
|
||||||
|
action = None
|
||||||
|
if response.get("action") is not None:
|
||||||
|
action = BoundAction(self._client.action, response["action"])
|
||||||
|
|
||||||
|
result = CreatePlacementGroupResponse(
|
||||||
|
placement_group=BoundPlacementGroup(self, response["placement_group"]),
|
||||||
|
action=action,
|
||||||
|
)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def update(self, placement_group, labels=None, name=None):
|
||||||
|
# type: (PlacementGroup, Optional[Dict[str, str]], Optional[str]) -> BoundPlacementGroup
|
||||||
|
"""Updates the description or labels of a Placement Group.
|
||||||
|
|
||||||
|
:param placement_group: :class:`BoundPlacementGroup <hcloud.placement_groups.client.BoundPlacementGroup>` or :class:`PlacementGroup <hcloud.placement_groups.domain.PlacementGroup>`
|
||||||
|
:param labels: Dict[str, str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:param name: str (optional)
|
||||||
|
New name to set
|
||||||
|
:return: :class:`BoundPlacementGroup <hcloud.placement_groups.client.BoundPlacementGroup>`
|
||||||
|
"""
|
||||||
|
|
||||||
|
data = {}
|
||||||
|
if labels is not None:
|
||||||
|
data["labels"] = labels
|
||||||
|
if name is not None:
|
||||||
|
data["name"] = name
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url="/placement_groups/{placement_group_id}".format(
|
||||||
|
placement_group_id=placement_group.id
|
||||||
|
),
|
||||||
|
method="PUT",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return BoundPlacementGroup(self, response["placement_group"])
|
||||||
|
|
||||||
|
def delete(self, placement_group):
|
||||||
|
# type: (PlacementGroup) -> bool
|
||||||
|
"""Deletes a Placement Group.
|
||||||
|
|
||||||
|
:param placement_group: :class:`BoundPlacementGroup <hcloud.placement_groups.client.BoundPlacementGroup>` or :class:`PlacementGroup <hcloud.placement_groups.domain.PlacementGroup>`
|
||||||
|
:return: boolean
|
||||||
|
"""
|
||||||
|
self._client.request(
|
||||||
|
url="/placement_groups/{placement_group_id}".format(
|
||||||
|
placement_group_id=placement_group.id
|
||||||
|
),
|
||||||
|
method="DELETE",
|
||||||
|
)
|
||||||
|
return True
|
61
plugins/module_utils/vendor/hcloud/placement_groups/domain.py
vendored
Normal file
61
plugins/module_utils/vendor/hcloud/placement_groups/domain.py
vendored
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
try:
|
||||||
|
from dateutil.parser import isoparse
|
||||||
|
except ImportError:
|
||||||
|
isoparse = None
|
||||||
|
|
||||||
|
from ..core.domain import BaseDomain
|
||||||
|
|
||||||
|
|
||||||
|
class PlacementGroup(BaseDomain):
|
||||||
|
"""Placement Group Domain
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
ID of the Placement Group
|
||||||
|
:param name: str
|
||||||
|
Name of the Placement Group
|
||||||
|
:param labels: dict
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:param servers: List[ int ]
|
||||||
|
List of server IDs assigned to the Placement Group
|
||||||
|
:param type: str
|
||||||
|
Type of the Placement Group
|
||||||
|
:param created: datetime
|
||||||
|
Point in time when the image was created
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("id", "name", "labels", "servers", "type", "created")
|
||||||
|
|
||||||
|
"""Placement Group type spread
|
||||||
|
spreads all servers in the group on different vhosts
|
||||||
|
"""
|
||||||
|
TYPE_SPREAD = "spread"
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self, id=None, name=None, labels=None, servers=None, type=None, created=None
|
||||||
|
):
|
||||||
|
self.id = id
|
||||||
|
self.name = name
|
||||||
|
self.labels = labels
|
||||||
|
self.servers = servers
|
||||||
|
self.type = type
|
||||||
|
self.created = isoparse(created) if created else None
|
||||||
|
|
||||||
|
|
||||||
|
class CreatePlacementGroupResponse(BaseDomain):
|
||||||
|
"""Create Placement Group Response Domain
|
||||||
|
|
||||||
|
:param placement_group: :class:`BoundPlacementGroup <hcloud.placement_groups.client.BoundPlacementGroup>`
|
||||||
|
The Placement Group which was created
|
||||||
|
:param action: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
The Action which shows the progress of the Placement Group Creation
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("placement_group", "action")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
placement_group, # type: BoundPlacementGroup
|
||||||
|
action, # type: BoundAction
|
||||||
|
):
|
||||||
|
self.placement_group = placement_group
|
||||||
|
self.action = action
|
0
plugins/module_utils/vendor/hcloud/primary_ips/__init__.py
vendored
Normal file
0
plugins/module_utils/vendor/hcloud/primary_ips/__init__.py
vendored
Normal file
329
plugins/module_utils/vendor/hcloud/primary_ips/client.py
vendored
Normal file
329
plugins/module_utils/vendor/hcloud/primary_ips/client.py
vendored
Normal file
|
@ -0,0 +1,329 @@
|
||||||
|
from ..actions.client import BoundAction
|
||||||
|
from ..core.client import BoundModelBase, ClientEntityBase, GetEntityByNameMixin
|
||||||
|
from .domain import CreatePrimaryIPResponse, PrimaryIP
|
||||||
|
|
||||||
|
|
||||||
|
class BoundPrimaryIP(BoundModelBase):
|
||||||
|
model = PrimaryIP
|
||||||
|
|
||||||
|
def __init__(self, client, data, complete=True):
|
||||||
|
from ..datacenters.client import BoundDatacenter
|
||||||
|
|
||||||
|
datacenter = data.get("datacenter", {})
|
||||||
|
if datacenter:
|
||||||
|
data["datacenter"] = BoundDatacenter(client._client.datacenters, datacenter)
|
||||||
|
|
||||||
|
super().__init__(client, data, complete)
|
||||||
|
|
||||||
|
def update(self, auto_delete=None, labels=None, name=None):
|
||||||
|
# type: (Optional[bool], Optional[Dict[str, str]], Optional[str]) -> BoundPrimaryIP
|
||||||
|
"""Updates the description or labels of a Primary IP.
|
||||||
|
|
||||||
|
:param auto_delete: bool (optional)
|
||||||
|
Auto delete IP when assignee gets deleted
|
||||||
|
:param labels: Dict[str, str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:param name: str (optional)
|
||||||
|
New Name to set
|
||||||
|
:return: :class:`BoundPrimaryIP <hcloud.primary_ips.client.BoundPrimaryIP>`
|
||||||
|
"""
|
||||||
|
return self._client.update(
|
||||||
|
self, auto_delete=auto_delete, labels=labels, name=name
|
||||||
|
)
|
||||||
|
|
||||||
|
def delete(self):
|
||||||
|
# type: () -> bool
|
||||||
|
"""Deletes a Primary IP. If it is currently assigned to a server it will automatically get unassigned.
|
||||||
|
|
||||||
|
:return: boolean
|
||||||
|
"""
|
||||||
|
return self._client.delete(self)
|
||||||
|
|
||||||
|
def change_protection(self, delete=None):
|
||||||
|
# type: (Optional[bool]) -> BoundAction
|
||||||
|
"""Changes the protection configuration of the Primary IP.
|
||||||
|
|
||||||
|
:param delete: boolean
|
||||||
|
If true, prevents the Primary IP from being deleted
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.change_protection(self, delete)
|
||||||
|
|
||||||
|
def assign(self, assignee_id, assignee_type):
|
||||||
|
# type: (int,str) -> BoundAction
|
||||||
|
"""Assigns a Primary IP to a assignee.
|
||||||
|
|
||||||
|
:param assignee_id: int`
|
||||||
|
Id of an assignee the Primary IP shall be assigned to
|
||||||
|
:param assignee_type: string`
|
||||||
|
Assignee type (e.g server) the Primary IP shall be assigned to
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.assign(self, assignee_id, assignee_type)
|
||||||
|
|
||||||
|
def unassign(self):
|
||||||
|
# type: () -> BoundAction
|
||||||
|
"""Unassigns a Primary IP, resulting in it being unreachable. You may assign it to a server again at a later time.
|
||||||
|
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.unassign(self)
|
||||||
|
|
||||||
|
def change_dns_ptr(self, ip, dns_ptr):
|
||||||
|
# type: (str, str) -> BoundAction
|
||||||
|
"""Changes the hostname that will appear when getting the hostname belonging to this Primary IP.
|
||||||
|
|
||||||
|
:param ip: str
|
||||||
|
The IP address for which to set the reverse DNS entry
|
||||||
|
:param dns_ptr: str
|
||||||
|
Hostname to set as a reverse DNS PTR entry, will reset to original default value if `None`
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.change_dns_ptr(self, ip, dns_ptr)
|
||||||
|
|
||||||
|
|
||||||
|
class PrimaryIPsClient(ClientEntityBase, GetEntityByNameMixin):
|
||||||
|
results_list_attribute_name = "primary_ips"
|
||||||
|
|
||||||
|
def get_by_id(self, id):
|
||||||
|
# type: (int) -> BoundPrimaryIP
|
||||||
|
"""Returns a specific Primary IP object.
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
:return: :class:`BoundPrimaryIP <hcloud.primary_ips.client.BoundPrimaryIP>`
|
||||||
|
"""
|
||||||
|
response = self._client.request(url=f"/primary_ips/{id}", method="GET")
|
||||||
|
return BoundPrimaryIP(self, response["primary_ip"])
|
||||||
|
|
||||||
|
def get_list(
|
||||||
|
self,
|
||||||
|
label_selector=None, # type: Optional[str]
|
||||||
|
page=None, # type: Optional[int]
|
||||||
|
per_page=None, # type: Optional[int]
|
||||||
|
name=None, # type: Optional[str]
|
||||||
|
ip=None, # type: Optional[ip]
|
||||||
|
):
|
||||||
|
# type: (...) -> PageResults[List[BoundPrimaryIP]]
|
||||||
|
"""Get a list of primary ips from this account
|
||||||
|
|
||||||
|
:param label_selector: str (optional)
|
||||||
|
Can be used to filter Primary IPs by labels. The response will only contain Primary IPs matching the label selectorable values.
|
||||||
|
:param page: int (optional)
|
||||||
|
Specifies the page to fetch
|
||||||
|
:param per_page: int (optional)
|
||||||
|
Specifies how many results are returned by page
|
||||||
|
:param name: str (optional)
|
||||||
|
Can be used to filter networks by their name.
|
||||||
|
:param ip: str (optional)
|
||||||
|
Can be used to filter resources by their ip. The response will only contain the resources matching the specified ip.
|
||||||
|
:return: (List[:class:`BoundPrimaryIP <hcloud.primary_ips.client.BoundPrimaryIP>`], :class:`Meta <hcloud.core.domain.Meta>`)
|
||||||
|
"""
|
||||||
|
params = {}
|
||||||
|
|
||||||
|
if label_selector is not None:
|
||||||
|
params["label_selector"] = label_selector
|
||||||
|
if page is not None:
|
||||||
|
params["page"] = page
|
||||||
|
if per_page is not None:
|
||||||
|
params["per_page"] = per_page
|
||||||
|
if name is not None:
|
||||||
|
params["name"] = name
|
||||||
|
if ip is not None:
|
||||||
|
params["ip"] = ip
|
||||||
|
|
||||||
|
response = self._client.request(url="/primary_ips", method="GET", params=params)
|
||||||
|
primary_ips = [
|
||||||
|
BoundPrimaryIP(self, primary_ip_data)
|
||||||
|
for primary_ip_data in response["primary_ips"]
|
||||||
|
]
|
||||||
|
|
||||||
|
return self._add_meta_to_result(primary_ips, response)
|
||||||
|
|
||||||
|
def get_all(self, label_selector=None, name=None):
|
||||||
|
# type: (Optional[str], Optional[str]) -> List[BoundPrimaryIP]
|
||||||
|
"""Get all primary ips from this account
|
||||||
|
|
||||||
|
:param label_selector: str (optional)
|
||||||
|
Can be used to filter Primary IPs by labels. The response will only contain Primary IPs matching the label selector.able values.
|
||||||
|
:param name: str (optional)
|
||||||
|
Can be used to filter networks by their name.
|
||||||
|
:return: List[:class:`BoundPrimaryIP <hcloud.primary_ips.client.BoundPrimaryIP>`]
|
||||||
|
"""
|
||||||
|
return super().get_all(label_selector=label_selector, name=name)
|
||||||
|
|
||||||
|
def get_by_name(self, name):
|
||||||
|
# type: (str) -> BoundPrimaryIP
|
||||||
|
"""Get Primary IP by name
|
||||||
|
|
||||||
|
:param name: str
|
||||||
|
Used to get Primary IP by name.
|
||||||
|
:return: :class:`BoundPrimaryIP <hcloud.primary_ips.client.BoundPrimaryIP>`
|
||||||
|
"""
|
||||||
|
return super().get_by_name(name)
|
||||||
|
|
||||||
|
def create(
|
||||||
|
self,
|
||||||
|
type, # type: str
|
||||||
|
datacenter, # type: Datacenter
|
||||||
|
name, # type: str
|
||||||
|
assignee_type="server", # type: Optional[str]
|
||||||
|
assignee_id=None, # type: Optional[int]
|
||||||
|
auto_delete=False, # type: Optional[bool]
|
||||||
|
labels=None, # type: Optional[dict]
|
||||||
|
):
|
||||||
|
# type: (...) -> CreatePrimaryIPResponse
|
||||||
|
"""Creates a new Primary IP assigned to a server.
|
||||||
|
|
||||||
|
:param type: str
|
||||||
|
Primary IP type Choices: ipv4, ipv6
|
||||||
|
:param assignee_type: str
|
||||||
|
:param assignee_id: int (optional)
|
||||||
|
:param datacenter: Datacenter
|
||||||
|
:param labels: Dict[str, str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:param name: str
|
||||||
|
:param auto_delete: bool (optional)
|
||||||
|
:return: :class:`CreatePrimaryIPResponse <hcloud.primary_ips.domain.CreatePrimaryIPResponse>`
|
||||||
|
"""
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"type": type,
|
||||||
|
"assignee_type": assignee_type,
|
||||||
|
"auto_delete": auto_delete,
|
||||||
|
"datacenter": datacenter.id_or_name,
|
||||||
|
"name": name,
|
||||||
|
}
|
||||||
|
if assignee_id:
|
||||||
|
data["assignee_id"] = assignee_id
|
||||||
|
if labels is not None:
|
||||||
|
data["labels"] = labels
|
||||||
|
|
||||||
|
response = self._client.request(url="/primary_ips", json=data, method="POST")
|
||||||
|
|
||||||
|
action = None
|
||||||
|
if response.get("action") is not None:
|
||||||
|
action = BoundAction(self._client.actions, response["action"])
|
||||||
|
|
||||||
|
result = CreatePrimaryIPResponse(
|
||||||
|
primary_ip=BoundPrimaryIP(self, response["primary_ip"]), action=action
|
||||||
|
)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def update(self, primary_ip, auto_delete=None, labels=None, name=None):
|
||||||
|
# type: (PrimaryIP, Optional[bool], Optional[Dict[str, str]], Optional[str]) -> BoundPrimaryIP
|
||||||
|
"""Updates the name, auto_delete or labels of a Primary IP.
|
||||||
|
|
||||||
|
:param primary_ip: :class:`BoundPrimaryIP <hcloud.primary_ips.client.BoundPrimaryIP>` or :class:`PrimaryIP <hcloud.primary_ips.domain.PrimaryIP>`
|
||||||
|
:param auto_delete: bool (optional)
|
||||||
|
Delete this Primary IP when the resource it is assigned to is deleted
|
||||||
|
:param labels: Dict[str, str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:param name: str (optional)
|
||||||
|
New name to set
|
||||||
|
:return: :class:`BoundPrimaryIP <hcloud.primary_ips.client.BoundPrimaryIP>`
|
||||||
|
"""
|
||||||
|
data = {}
|
||||||
|
if auto_delete is not None:
|
||||||
|
data["auto_delete"] = auto_delete
|
||||||
|
if labels is not None:
|
||||||
|
data["labels"] = labels
|
||||||
|
if name is not None:
|
||||||
|
data["name"] = name
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url=f"/primary_ips/{primary_ip.id}",
|
||||||
|
method="PUT",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return BoundPrimaryIP(self, response["primary_ip"])
|
||||||
|
|
||||||
|
def delete(self, primary_ip):
|
||||||
|
# type: (PrimaryIP) -> bool
|
||||||
|
"""Deletes a Primary IP. If it is currently assigned to an assignee it will automatically get unassigned.
|
||||||
|
|
||||||
|
:param primary_ip: :class:`BoundPrimaryIP <hcloud.primary_ips.client.BoundPrimaryIP>` or :class:`PrimaryIP <hcloud.primary_ips.domain.PrimaryIP>`
|
||||||
|
:return: boolean
|
||||||
|
"""
|
||||||
|
self._client.request(
|
||||||
|
url=f"/primary_ips/{primary_ip.id}",
|
||||||
|
method="DELETE",
|
||||||
|
)
|
||||||
|
# Return always true, because the API does not return an action for it. When an error occurs a HcloudAPIException will be raised
|
||||||
|
return True
|
||||||
|
|
||||||
|
def change_protection(self, primary_ip, delete=None):
|
||||||
|
# type: (PrimaryIP, Optional[bool]) -> BoundAction
|
||||||
|
"""Changes the protection configuration of the Primary IP.
|
||||||
|
|
||||||
|
:param primary_ip: :class:`BoundPrimaryIP <hcloud.primary_ips.client.BoundPrimaryIP>` or :class:`PrimaryIP <hcloud.primary_ips.domain.PrimaryIP>`
|
||||||
|
:param delete: boolean
|
||||||
|
If true, prevents the Primary IP from being deleted
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
data = {}
|
||||||
|
if delete is not None:
|
||||||
|
data.update({"delete": delete})
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url="/primary_ips/{primary_ip_id}/actions/change_protection".format(
|
||||||
|
primary_ip_id=primary_ip.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
||||||
|
|
||||||
|
def assign(self, primary_ip, assignee_id, assignee_type="server"):
|
||||||
|
# type: (PrimaryIP, int, str) -> BoundAction
|
||||||
|
"""Assigns a Primary IP to a assignee_id.
|
||||||
|
|
||||||
|
:param primary_ip: :class:`BoundPrimaryIP <hcloud.primary_ips.client.BoundPrimaryIP>` or :class:`PrimaryIP <hcloud.primary_ips.domain.PrimaryIP>`
|
||||||
|
:param assignee_id: int
|
||||||
|
Assignee the Primary IP shall be assigned to
|
||||||
|
:param assignee_type: str
|
||||||
|
Assignee the Primary IP shall be assigned to
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
response = self._client.request(
|
||||||
|
url="/primary_ips/{primary_ip_id}/actions/assign".format(
|
||||||
|
primary_ip_id=primary_ip.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
json={"assignee_id": assignee_id, "assignee_type": assignee_type},
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
||||||
|
|
||||||
|
def unassign(self, primary_ip):
|
||||||
|
# type: (PrimaryIP) -> BoundAction
|
||||||
|
"""Unassigns a Primary IP, resulting in it being unreachable. You may assign it to a server again at a later time.
|
||||||
|
|
||||||
|
:param primary_ip: :class:`BoundPrimaryIP <hcloud.primary_ips.client.BoundPrimaryIP>` or :class:`PrimaryIP <hcloud.primary_ips.domain.PrimaryIP>`
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
response = self._client.request(
|
||||||
|
url="/primary_ips/{primary_ip_id}/actions/unassign".format(
|
||||||
|
primary_ip_id=primary_ip.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
||||||
|
|
||||||
|
def change_dns_ptr(self, primary_ip, ip, dns_ptr):
|
||||||
|
# type: (PrimaryIP, str, str) -> BoundAction
|
||||||
|
"""Changes the dns ptr that will appear when getting the dns ptr belonging to this Primary IP.
|
||||||
|
|
||||||
|
:param primary_ip: :class:`BoundPrimaryIP <hcloud.primary_ips.client.BoundPrimaryIP>` or :class:`PrimaryIP <hcloud.primary_ips.domain.PrimaryIP>`
|
||||||
|
:param ip: str
|
||||||
|
The IP address for which to set the reverse DNS entry
|
||||||
|
:param dns_ptr: str
|
||||||
|
Hostname to set as a reverse DNS PTR entry, will reset to original default value if `None`
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
response = self._client.request(
|
||||||
|
url="/primary_ips/{primary_ip_id}/actions/change_dns_ptr".format(
|
||||||
|
primary_ip_id=primary_ip.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
json={"ip": ip, "dns_ptr": dns_ptr},
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
104
plugins/module_utils/vendor/hcloud/primary_ips/domain.py
vendored
Normal file
104
plugins/module_utils/vendor/hcloud/primary_ips/domain.py
vendored
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
try:
|
||||||
|
from dateutil.parser import isoparse
|
||||||
|
except ImportError:
|
||||||
|
isoparse = None
|
||||||
|
|
||||||
|
from ..core.domain import BaseDomain
|
||||||
|
|
||||||
|
|
||||||
|
class PrimaryIP(BaseDomain):
|
||||||
|
"""Primary IP Domain
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
ID of the Primary IP
|
||||||
|
:param ip: str
|
||||||
|
IP address of the Primary IP
|
||||||
|
:param type: str
|
||||||
|
Type of Primary IP. Choices: `ipv4`, `ipv6`
|
||||||
|
:param dns_ptr: List[Dict]
|
||||||
|
Array of reverse DNS entries
|
||||||
|
:param datacenter: :class:`Datacenter <hcloud.datacenters.client.BoundDatacenter>`
|
||||||
|
Datacenter the Primary IP was created in.
|
||||||
|
:param blocked: boolean
|
||||||
|
Whether the IP is blocked
|
||||||
|
:param protection: dict
|
||||||
|
Protection configuration for the Primary IP
|
||||||
|
:param labels: dict
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:param created: datetime
|
||||||
|
Point in time when the Primary IP was created
|
||||||
|
:param name: str
|
||||||
|
Name of the Primary IP
|
||||||
|
:param assignee_id: int
|
||||||
|
Assignee ID the Primary IP is assigned to
|
||||||
|
:param assignee_type: str
|
||||||
|
Assignee Type of entity the Primary IP is assigned to
|
||||||
|
:param auto_delete: bool
|
||||||
|
Delete the Primary IP when the Assignee it is assigned to is deleted.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = (
|
||||||
|
"id",
|
||||||
|
"ip",
|
||||||
|
"type",
|
||||||
|
"dns_ptr",
|
||||||
|
"datacenter",
|
||||||
|
"blocked",
|
||||||
|
"protection",
|
||||||
|
"labels",
|
||||||
|
"created",
|
||||||
|
"name",
|
||||||
|
"assignee_id",
|
||||||
|
"assignee_type",
|
||||||
|
"auto_delete",
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
id=None,
|
||||||
|
type=None,
|
||||||
|
ip=None,
|
||||||
|
dns_ptr=None,
|
||||||
|
datacenter=None,
|
||||||
|
blocked=None,
|
||||||
|
protection=None,
|
||||||
|
labels=None,
|
||||||
|
created=None,
|
||||||
|
name=None,
|
||||||
|
assignee_id=None,
|
||||||
|
assignee_type=None,
|
||||||
|
auto_delete=None,
|
||||||
|
):
|
||||||
|
self.id = id
|
||||||
|
self.type = type
|
||||||
|
self.ip = ip
|
||||||
|
self.dns_ptr = dns_ptr
|
||||||
|
self.datacenter = datacenter
|
||||||
|
self.blocked = blocked
|
||||||
|
self.protection = protection
|
||||||
|
self.labels = labels
|
||||||
|
self.created = isoparse(created) if created else None
|
||||||
|
self.name = name
|
||||||
|
self.assignee_id = assignee_id
|
||||||
|
self.assignee_type = assignee_type
|
||||||
|
self.auto_delete = auto_delete
|
||||||
|
|
||||||
|
|
||||||
|
class CreatePrimaryIPResponse(BaseDomain):
|
||||||
|
"""Create Primary IP Response Domain
|
||||||
|
|
||||||
|
:param primary_ip: :class:`BoundPrimaryIP <hcloud.primary_ips.client.BoundPrimaryIP>`
|
||||||
|
The Primary IP which was created
|
||||||
|
:param action: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
The Action which shows the progress of the Primary IP Creation
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("primary_ip", "action")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
primary_ip, # type: BoundPrimaryIP
|
||||||
|
action, # type: BoundAction
|
||||||
|
):
|
||||||
|
self.primary_ip = primary_ip
|
||||||
|
self.action = action
|
0
plugins/module_utils/vendor/hcloud/server_types/__init__.py
vendored
Normal file
0
plugins/module_utils/vendor/hcloud/server_types/__init__.py
vendored
Normal file
69
plugins/module_utils/vendor/hcloud/server_types/client.py
vendored
Normal file
69
plugins/module_utils/vendor/hcloud/server_types/client.py
vendored
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
from ..core.client import BoundModelBase, ClientEntityBase, GetEntityByNameMixin
|
||||||
|
from .domain import ServerType
|
||||||
|
|
||||||
|
|
||||||
|
class BoundServerType(BoundModelBase):
|
||||||
|
model = ServerType
|
||||||
|
|
||||||
|
|
||||||
|
class ServerTypesClient(ClientEntityBase, GetEntityByNameMixin):
|
||||||
|
results_list_attribute_name = "server_types"
|
||||||
|
|
||||||
|
def get_by_id(self, id):
|
||||||
|
# type: (int) -> BoundServerType
|
||||||
|
"""Returns a specific Server Type.
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
:return: :class:`BoundServerType <hcloud.server_types.client.BoundServerType>`
|
||||||
|
"""
|
||||||
|
response = self._client.request(url=f"/server_types/{id}", method="GET")
|
||||||
|
return BoundServerType(self, response["server_type"])
|
||||||
|
|
||||||
|
def get_list(self, name=None, page=None, per_page=None):
|
||||||
|
# type: (Optional[str], Optional[int], Optional[int]) -> PageResults[List[BoundServerType], Meta]
|
||||||
|
"""Get a list of Server types
|
||||||
|
|
||||||
|
:param name: str (optional)
|
||||||
|
Can be used to filter server type by their name.
|
||||||
|
: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:`BoundServerType <hcloud.server_types.client.BoundServerType>`], :class:`Meta <hcloud.core.domain.Meta>`)
|
||||||
|
"""
|
||||||
|
params = {}
|
||||||
|
if name is not None:
|
||||||
|
params["name"] = name
|
||||||
|
if page is not None:
|
||||||
|
params["page"] = page
|
||||||
|
if per_page is not None:
|
||||||
|
params["per_page"] = per_page
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url="/server_types", method="GET", params=params
|
||||||
|
)
|
||||||
|
server_types = [
|
||||||
|
BoundServerType(self, server_type_data)
|
||||||
|
for server_type_data in response["server_types"]
|
||||||
|
]
|
||||||
|
return self._add_meta_to_result(server_types, response)
|
||||||
|
|
||||||
|
def get_all(self, name=None):
|
||||||
|
# type: (Optional[str]) -> List[BoundServerType]
|
||||||
|
"""Get all Server types
|
||||||
|
|
||||||
|
:param name: str (optional)
|
||||||
|
Can be used to filter server type by their name.
|
||||||
|
:return: List[:class:`BoundServerType <hcloud.server_types.client.BoundServerType>`]
|
||||||
|
"""
|
||||||
|
return super().get_all(name=name)
|
||||||
|
|
||||||
|
def get_by_name(self, name):
|
||||||
|
# type: (str) -> BoundServerType
|
||||||
|
"""Get Server type by name
|
||||||
|
|
||||||
|
:param name: str
|
||||||
|
Used to get Server type by name.
|
||||||
|
:return: :class:`BoundServerType <hcloud.server_types.client.BoundServerType>`
|
||||||
|
"""
|
||||||
|
return super().get_by_name(name)
|
83
plugins/module_utils/vendor/hcloud/server_types/domain.py
vendored
Normal file
83
plugins/module_utils/vendor/hcloud/server_types/domain.py
vendored
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
from ..core.domain import BaseDomain, DomainIdentityMixin
|
||||||
|
from ..deprecation.domain import DeprecationInfo
|
||||||
|
|
||||||
|
|
||||||
|
class ServerType(BaseDomain, DomainIdentityMixin):
|
||||||
|
"""ServerType Domain
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
ID of the server type
|
||||||
|
:param name: str
|
||||||
|
Unique identifier of the server type
|
||||||
|
:param description: str
|
||||||
|
Description of the server type
|
||||||
|
:param cores: int
|
||||||
|
Number of cpu cores a server of this type will have
|
||||||
|
:param memory: int
|
||||||
|
Memory a server of this type will have in GB
|
||||||
|
:param disk: int
|
||||||
|
Disk size a server of this type will have in GB
|
||||||
|
:param prices: Dict
|
||||||
|
Prices in different locations
|
||||||
|
:param storage_type: str
|
||||||
|
Type of server boot drive. Local has higher speed. Network has better availability. Choices: `local`, `network`
|
||||||
|
:param cpu_type: string
|
||||||
|
Type of cpu. Choices: `shared`, `dedicated`
|
||||||
|
:param architecture: string
|
||||||
|
Architecture of cpu. Choices: `x86`, `arm`
|
||||||
|
:param deprecated: bool
|
||||||
|
True if server type is deprecated. This field is deprecated. Use `deprecation` instead.
|
||||||
|
:param deprecation: :class:`DeprecationInfo <hcloud.deprecation.domain.DeprecationInfo>`, None
|
||||||
|
Describes if, when & how the resources was deprecated. If this field is set to None the resource is not
|
||||||
|
deprecated. If it has a value, it is considered deprecated.
|
||||||
|
:param included_traffic: int
|
||||||
|
Free traffic per month in bytes
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = (
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"description",
|
||||||
|
"cores",
|
||||||
|
"memory",
|
||||||
|
"disk",
|
||||||
|
"prices",
|
||||||
|
"storage_type",
|
||||||
|
"cpu_type",
|
||||||
|
"architecture",
|
||||||
|
"deprecated",
|
||||||
|
"deprecation",
|
||||||
|
"included_traffic",
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
id=None,
|
||||||
|
name=None,
|
||||||
|
description=None,
|
||||||
|
cores=None,
|
||||||
|
memory=None,
|
||||||
|
disk=None,
|
||||||
|
prices=None,
|
||||||
|
storage_type=None,
|
||||||
|
cpu_type=None,
|
||||||
|
architecture=None,
|
||||||
|
deprecated=None,
|
||||||
|
deprecation=None,
|
||||||
|
included_traffic=None,
|
||||||
|
):
|
||||||
|
self.id = id
|
||||||
|
self.name = name
|
||||||
|
self.description = description
|
||||||
|
self.cores = cores
|
||||||
|
self.memory = memory
|
||||||
|
self.disk = disk
|
||||||
|
self.prices = prices
|
||||||
|
self.storage_type = storage_type
|
||||||
|
self.cpu_type = cpu_type
|
||||||
|
self.architecture = architecture
|
||||||
|
self.deprecated = deprecated
|
||||||
|
self.deprecation = (
|
||||||
|
DeprecationInfo.from_dict(deprecation) if deprecation is not None else None
|
||||||
|
)
|
||||||
|
self.included_traffic = included_traffic
|
0
plugins/module_utils/vendor/hcloud/servers/__init__.py
vendored
Normal file
0
plugins/module_utils/vendor/hcloud/servers/__init__.py
vendored
Normal file
1089
plugins/module_utils/vendor/hcloud/servers/client.py
vendored
Normal file
1089
plugins/module_utils/vendor/hcloud/servers/client.py
vendored
Normal file
File diff suppressed because it is too large
Load diff
395
plugins/module_utils/vendor/hcloud/servers/domain.py
vendored
Normal file
395
plugins/module_utils/vendor/hcloud/servers/domain.py
vendored
Normal file
|
@ -0,0 +1,395 @@
|
||||||
|
try:
|
||||||
|
from dateutil.parser import isoparse
|
||||||
|
except ImportError:
|
||||||
|
isoparse = None
|
||||||
|
|
||||||
|
from ..core.domain import BaseDomain
|
||||||
|
|
||||||
|
|
||||||
|
class Server(BaseDomain):
|
||||||
|
"""Server Domain
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
ID of the server
|
||||||
|
:param name: str
|
||||||
|
Name of the server (must be unique per project and a valid hostname as per RFC 1123)
|
||||||
|
:param status: str
|
||||||
|
Status of the server Choices: `running`, `initializing`, `starting`, `stopping`, `off`, `deleting`, `migrating`, `rebuilding`, `unknown`
|
||||||
|
:param created: datetime
|
||||||
|
Point in time when the server was created
|
||||||
|
:param public_net: :class:`PublicNetwork <hcloud.servers.domain.PublicNetwork>`
|
||||||
|
Public network information.
|
||||||
|
:param server_type: :class:`BoundServerType <hcloud.server_types.client.BoundServerType>`
|
||||||
|
:param datacenter: :class:`BoundDatacenter <hcloud.datacenters.client.BoundDatacenter>`
|
||||||
|
:param image: :class:`BoundImage <hcloud.images.client.BoundImage>`, None
|
||||||
|
:param iso: :class:`BoundIso <hcloud.isos.client.BoundIso>`, None
|
||||||
|
:param rescue_enabled: bool
|
||||||
|
True if rescue mode is enabled: Server will then boot into rescue system on next reboot.
|
||||||
|
:param locked: bool
|
||||||
|
True if server has been locked and is not available to user.
|
||||||
|
:param backup_window: str, None
|
||||||
|
Time window (UTC) in which the backup will run, or None if the backups are not enabled
|
||||||
|
:param outgoing_traffic: int, None
|
||||||
|
Outbound Traffic for the current billing period in bytes
|
||||||
|
:param ingoing_traffic: int, None
|
||||||
|
Inbound Traffic for the current billing period in bytes
|
||||||
|
:param included_traffic: int
|
||||||
|
Free Traffic for the current billing period in bytes
|
||||||
|
:param primary_disk_size: int
|
||||||
|
Size of the primary Disk
|
||||||
|
:param protection: dict
|
||||||
|
Protection configuration for the server
|
||||||
|
:param labels: dict
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:param volumes: List[:class:`BoundVolume <hcloud.volumes.client.BoundVolume>`]
|
||||||
|
Volumes assigned to this server.
|
||||||
|
:param private_net: List[:class:`PrivateNet <hcloud.servers.domain.PrivateNet>`]
|
||||||
|
Private networks information.
|
||||||
|
"""
|
||||||
|
|
||||||
|
STATUS_RUNNING = "running"
|
||||||
|
"""Server Status running"""
|
||||||
|
STATUS_INIT = "initializing"
|
||||||
|
"""Server Status initializing"""
|
||||||
|
STATUS_STARTING = "starting"
|
||||||
|
"""Server Status starting"""
|
||||||
|
STATUS_STOPPING = "stopping"
|
||||||
|
"""Server Status stopping"""
|
||||||
|
STATUS_OFF = "off"
|
||||||
|
"""Server Status off"""
|
||||||
|
STATUS_DELETING = "deleting"
|
||||||
|
"""Server Status deleting"""
|
||||||
|
STATUS_MIGRATING = "migrating"
|
||||||
|
"""Server Status migrating"""
|
||||||
|
STATUS_REBUILDING = "rebuilding"
|
||||||
|
"""Server Status rebuilding"""
|
||||||
|
STATUS_UNKNOWN = "unknown"
|
||||||
|
"""Server Status unknown"""
|
||||||
|
__slots__ = (
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"status",
|
||||||
|
"public_net",
|
||||||
|
"server_type",
|
||||||
|
"datacenter",
|
||||||
|
"image",
|
||||||
|
"iso",
|
||||||
|
"rescue_enabled",
|
||||||
|
"locked",
|
||||||
|
"backup_window",
|
||||||
|
"outgoing_traffic",
|
||||||
|
"ingoing_traffic",
|
||||||
|
"included_traffic",
|
||||||
|
"protection",
|
||||||
|
"labels",
|
||||||
|
"volumes",
|
||||||
|
"private_net",
|
||||||
|
"created",
|
||||||
|
"primary_disk_size",
|
||||||
|
"placement_group",
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
id,
|
||||||
|
name=None,
|
||||||
|
status=None,
|
||||||
|
created=None,
|
||||||
|
public_net=None,
|
||||||
|
server_type=None,
|
||||||
|
datacenter=None,
|
||||||
|
image=None,
|
||||||
|
iso=None,
|
||||||
|
rescue_enabled=None,
|
||||||
|
locked=None,
|
||||||
|
backup_window=None,
|
||||||
|
outgoing_traffic=None,
|
||||||
|
ingoing_traffic=None,
|
||||||
|
included_traffic=None,
|
||||||
|
protection=None,
|
||||||
|
labels=None,
|
||||||
|
volumes=None,
|
||||||
|
private_net=None,
|
||||||
|
primary_disk_size=None,
|
||||||
|
placement_group=None,
|
||||||
|
):
|
||||||
|
self.id = id
|
||||||
|
self.name = name
|
||||||
|
self.status = status
|
||||||
|
self.created = isoparse(created) if created else None
|
||||||
|
self.public_net = public_net
|
||||||
|
self.server_type = server_type
|
||||||
|
self.datacenter = datacenter
|
||||||
|
self.image = image
|
||||||
|
self.iso = iso
|
||||||
|
self.rescue_enabled = rescue_enabled
|
||||||
|
self.locked = locked
|
||||||
|
self.backup_window = backup_window
|
||||||
|
self.outgoing_traffic = outgoing_traffic
|
||||||
|
self.ingoing_traffic = ingoing_traffic
|
||||||
|
self.included_traffic = included_traffic
|
||||||
|
self.protection = protection
|
||||||
|
self.labels = labels
|
||||||
|
self.volumes = volumes
|
||||||
|
self.private_net = private_net
|
||||||
|
self.primary_disk_size = primary_disk_size
|
||||||
|
self.placement_group = placement_group
|
||||||
|
|
||||||
|
|
||||||
|
class CreateServerResponse(BaseDomain):
|
||||||
|
"""Create Server Response Domain
|
||||||
|
|
||||||
|
:param server: :class:`BoundServer <hcloud.servers.client.BoundServer>`
|
||||||
|
The created server
|
||||||
|
:param action: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
Shows the progress of the server creation
|
||||||
|
:param next_actions: List[:class:`BoundAction <hcloud.actions.client.BoundAction>`]
|
||||||
|
Additional actions like a `start_server` action after the server creation
|
||||||
|
:param root_password: str, None
|
||||||
|
The root password of the server if no SSH-Key was given on server creation
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("server", "action", "next_actions", "root_password")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
server, # type: BoundServer
|
||||||
|
action, # type: BoundAction
|
||||||
|
next_actions, # type: List[Action]
|
||||||
|
root_password, # type: str
|
||||||
|
):
|
||||||
|
self.server = server
|
||||||
|
self.action = action
|
||||||
|
self.next_actions = next_actions
|
||||||
|
self.root_password = root_password
|
||||||
|
|
||||||
|
|
||||||
|
class ResetPasswordResponse(BaseDomain):
|
||||||
|
"""Reset Password Response Domain
|
||||||
|
|
||||||
|
:param action: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
Shows the progress of the server passwort reset action
|
||||||
|
:param root_password: str
|
||||||
|
The root password of the server
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("action", "root_password")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
action, # type: BoundAction
|
||||||
|
root_password, # type: str
|
||||||
|
):
|
||||||
|
self.action = action
|
||||||
|
self.root_password = root_password
|
||||||
|
|
||||||
|
|
||||||
|
class EnableRescueResponse(BaseDomain):
|
||||||
|
"""Enable Rescue Response Domain
|
||||||
|
|
||||||
|
:param action: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
Shows the progress of the server enable rescue action
|
||||||
|
:param root_password: str
|
||||||
|
The root password of the server in the rescue mode
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("action", "root_password")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
action, # type: BoundAction
|
||||||
|
root_password, # type: str
|
||||||
|
):
|
||||||
|
self.action = action
|
||||||
|
self.root_password = root_password
|
||||||
|
|
||||||
|
|
||||||
|
class RequestConsoleResponse(BaseDomain):
|
||||||
|
"""Request Console Response Domain
|
||||||
|
|
||||||
|
:param action: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
Shows the progress of the server request console action
|
||||||
|
:param wss_url: str
|
||||||
|
URL of websocket proxy to use. This includes a token which is valid for a limited time only.
|
||||||
|
:param password: str
|
||||||
|
VNC password to use for this connection. This password only works in combination with a wss_url with valid token.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("action", "wss_url", "password")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
action, # type: BoundAction
|
||||||
|
wss_url, # type: str
|
||||||
|
password, # type: str
|
||||||
|
):
|
||||||
|
self.action = action
|
||||||
|
self.wss_url = wss_url
|
||||||
|
self.password = password
|
||||||
|
|
||||||
|
|
||||||
|
class PublicNetwork(BaseDomain):
|
||||||
|
"""Public Network Domain
|
||||||
|
|
||||||
|
:param ipv4: :class:`IPv4Address <hcloud.servers.domain.IPv4Address>`
|
||||||
|
:param ipv6: :class:`IPv6Network <hcloud.servers.domain.IPv6Network>`
|
||||||
|
:param floating_ips: List[:class:`BoundFloatingIP <hcloud.floating_ips.client.BoundFloatingIP>`]
|
||||||
|
:param primary_ipv4: :class:`BoundPrimaryIP <hcloud.primary_ips.domain.BoundPrimaryIP>`
|
||||||
|
:param primary_ipv6: :class:`BoundPrimaryIP <hcloud.primary_ips.domain.BoundPrimaryIP>`
|
||||||
|
:param firewalls: List[:class:`PublicNetworkFirewall <hcloud.servers.client.PublicNetworkFirewall>`]
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = (
|
||||||
|
"ipv4",
|
||||||
|
"ipv6",
|
||||||
|
"floating_ips",
|
||||||
|
"firewalls",
|
||||||
|
"primary_ipv4",
|
||||||
|
"primary_ipv6",
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
ipv4, # type: IPv4Address
|
||||||
|
ipv6, # type: IPv6Network
|
||||||
|
floating_ips, # type: List[BoundFloatingIP]
|
||||||
|
primary_ipv4, # type: BoundPrimaryIP
|
||||||
|
primary_ipv6, # type: BoundPrimaryIP
|
||||||
|
firewalls=None, # type: List[PublicNetworkFirewall]
|
||||||
|
):
|
||||||
|
self.ipv4 = ipv4
|
||||||
|
self.ipv6 = ipv6
|
||||||
|
self.floating_ips = floating_ips
|
||||||
|
self.firewalls = firewalls
|
||||||
|
self.primary_ipv4 = primary_ipv4
|
||||||
|
self.primary_ipv6 = primary_ipv6
|
||||||
|
|
||||||
|
|
||||||
|
class PublicNetworkFirewall(BaseDomain):
|
||||||
|
"""Public Network Domain
|
||||||
|
|
||||||
|
:param firewall: :class:`BoundFirewall <hcloud.firewalls.domain.BoundFirewall>`
|
||||||
|
:param status: str
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("firewall", "status")
|
||||||
|
|
||||||
|
STATUS_APPLIED = "applied"
|
||||||
|
"""Public Network Firewall Status applied"""
|
||||||
|
STATUS_PENDING = "pending"
|
||||||
|
"""Public Network Firewall Status pending"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
firewall, # type: BoundFirewall
|
||||||
|
status, # type: str
|
||||||
|
):
|
||||||
|
self.firewall = firewall
|
||||||
|
self.status = status
|
||||||
|
|
||||||
|
|
||||||
|
class IPv4Address(BaseDomain):
|
||||||
|
"""IPv4 Address Domain
|
||||||
|
|
||||||
|
:param ip: str
|
||||||
|
The IPv4 Address
|
||||||
|
:param blocked: bool
|
||||||
|
Determine if the IP is blocked
|
||||||
|
:param dns_ptr: str
|
||||||
|
DNS PTR for the ip
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("ip", "blocked", "dns_ptr")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
ip, # type: str
|
||||||
|
blocked, # type: bool
|
||||||
|
dns_ptr, # type: str
|
||||||
|
):
|
||||||
|
self.ip = ip
|
||||||
|
self.blocked = blocked
|
||||||
|
self.dns_ptr = dns_ptr
|
||||||
|
|
||||||
|
|
||||||
|
class IPv6Network(BaseDomain):
|
||||||
|
"""IPv6 Network Domain
|
||||||
|
|
||||||
|
:param ip: str
|
||||||
|
The IPv6 Network as CIDR Notation
|
||||||
|
:param blocked: bool
|
||||||
|
Determine if the Network is blocked
|
||||||
|
:param dns_ptr: dict
|
||||||
|
DNS PTR Records for the Network as Dict
|
||||||
|
:param network: str
|
||||||
|
The network without the network mask
|
||||||
|
:param network_mask: str
|
||||||
|
The network mask
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("ip", "blocked", "dns_ptr", "network", "network_mask")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
ip, # type: str
|
||||||
|
blocked, # type: bool
|
||||||
|
dns_ptr, # type: list
|
||||||
|
):
|
||||||
|
self.ip = ip
|
||||||
|
self.blocked = blocked
|
||||||
|
self.dns_ptr = dns_ptr
|
||||||
|
ip_parts = self.ip.split("/") # 2001:db8::/64 to 2001:db8:: and 64
|
||||||
|
self.network = ip_parts[0]
|
||||||
|
self.network_mask = ip_parts[1]
|
||||||
|
|
||||||
|
|
||||||
|
class PrivateNet(BaseDomain):
|
||||||
|
"""PrivateNet Domain
|
||||||
|
|
||||||
|
:param network: :class:`BoundNetwork <hcloud.networks.client.BoundNetwork>`
|
||||||
|
The network the server is attached to
|
||||||
|
:param ip: str
|
||||||
|
The main IP Address of the server in the Network
|
||||||
|
:param alias_ips: List[str]
|
||||||
|
The alias ips for a server
|
||||||
|
:param mac_address: str
|
||||||
|
The mac address of the interface on the server
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("network", "ip", "alias_ips", "mac_address")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
network, # type: BoundNetwork
|
||||||
|
ip, # type: str
|
||||||
|
alias_ips, # type: List[str]
|
||||||
|
mac_address, # type: str
|
||||||
|
):
|
||||||
|
self.network = network
|
||||||
|
self.ip = ip
|
||||||
|
self.alias_ips = alias_ips
|
||||||
|
self.mac_address = mac_address
|
||||||
|
|
||||||
|
|
||||||
|
class ServerCreatePublicNetwork(BaseDomain):
|
||||||
|
"""Server Create Public Network Domain
|
||||||
|
|
||||||
|
:param ipv4: Optional[:class:`PrimaryIP <hcloud.primary_ips.domain.PrimaryIP>`]
|
||||||
|
:param ipv6: Optional[:class:`PrimaryIP <hcloud.primary_ips.domain.PrimaryIP>`]
|
||||||
|
:param enable_ipv4: bool
|
||||||
|
:param enable_ipv6: bool
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("ipv4", "ipv6", "enable_ipv4", "enable_ipv6")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
ipv4=None, # type: hcloud.primary_ips.domain.PrimaryIP
|
||||||
|
ipv6=None, # type: hcloud.primary_ips.domain.PrimaryIP
|
||||||
|
enable_ipv4=True, # type: bool
|
||||||
|
enable_ipv6=True, # type: bool
|
||||||
|
):
|
||||||
|
self.ipv4 = ipv4
|
||||||
|
self.ipv6 = ipv6
|
||||||
|
self.enable_ipv4 = enable_ipv4
|
||||||
|
self.enable_ipv6 = enable_ipv6
|
0
plugins/module_utils/vendor/hcloud/ssh_keys/__init__.py
vendored
Normal file
0
plugins/module_utils/vendor/hcloud/ssh_keys/__init__.py
vendored
Normal file
170
plugins/module_utils/vendor/hcloud/ssh_keys/client.py
vendored
Normal file
170
plugins/module_utils/vendor/hcloud/ssh_keys/client.py
vendored
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
from ..core.client import BoundModelBase, ClientEntityBase, GetEntityByNameMixin
|
||||||
|
from .domain import SSHKey
|
||||||
|
|
||||||
|
|
||||||
|
class BoundSSHKey(BoundModelBase):
|
||||||
|
model = SSHKey
|
||||||
|
|
||||||
|
def update(self, name=None, labels=None):
|
||||||
|
# type: (Optional[str], Optional[Dict[str, str]]) -> BoundSSHKey
|
||||||
|
"""Updates an SSH key. You can update an SSH key name and an SSH key labels.
|
||||||
|
|
||||||
|
:param description: str (optional)
|
||||||
|
New Description to set
|
||||||
|
:param labels: Dict[str, str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:return: :class:`BoundSSHKey <hcloud.ssh_keys.client.BoundSSHKey>
|
||||||
|
"""
|
||||||
|
return self._client.update(self, name, labels)
|
||||||
|
|
||||||
|
def delete(self):
|
||||||
|
# type: () -> bool
|
||||||
|
"""Deletes an SSH key. It cannot be used anymore.
|
||||||
|
:return: boolean
|
||||||
|
"""
|
||||||
|
return self._client.delete(self)
|
||||||
|
|
||||||
|
|
||||||
|
class SSHKeysClient(ClientEntityBase, GetEntityByNameMixin):
|
||||||
|
results_list_attribute_name = "ssh_keys"
|
||||||
|
|
||||||
|
def get_by_id(self, id):
|
||||||
|
# type: (int) -> BoundSSHKey
|
||||||
|
"""Get a specific SSH Key by its ID
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
:return: :class:`BoundSSHKey <hcloud.ssh_keys.client.BoundSSHKey>`
|
||||||
|
"""
|
||||||
|
response = self._client.request(url=f"/ssh_keys/{id}", method="GET")
|
||||||
|
return BoundSSHKey(self, response["ssh_key"])
|
||||||
|
|
||||||
|
def get_list(
|
||||||
|
self,
|
||||||
|
name=None, # type: Optional[str]
|
||||||
|
fingerprint=None, # type: Optional[str]
|
||||||
|
label_selector=None, # type: Optional[str]
|
||||||
|
page=None, # type: Optional[int]
|
||||||
|
per_page=None, # type: Optional[int]
|
||||||
|
):
|
||||||
|
# type: (...) -> PageResults[List[BoundSSHKey], Meta]
|
||||||
|
"""Get a list of SSH keys from the account
|
||||||
|
|
||||||
|
:param name: str (optional)
|
||||||
|
Can be used to filter SSH keys by their name. The response will only contain the SSH key matching the specified name.
|
||||||
|
:param fingerprint: str (optional)
|
||||||
|
Can be used to filter SSH keys by their fingerprint. The response will only contain the SSH key matching the specified fingerprint.
|
||||||
|
:param label_selector: str (optional)
|
||||||
|
Can be used to filter SSH keys by labels. The response will only contain SSH keys matching the label selector.
|
||||||
|
: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:`BoundSSHKey <hcloud.ssh_keys.client.BoundSSHKey>`], :class:`Meta <hcloud.core.domain.Meta>`)
|
||||||
|
"""
|
||||||
|
params = {}
|
||||||
|
if name is not None:
|
||||||
|
params["name"] = name
|
||||||
|
if fingerprint is not None:
|
||||||
|
params["fingerprint"] = fingerprint
|
||||||
|
if label_selector is not None:
|
||||||
|
params["label_selector"] = label_selector
|
||||||
|
if page is not None:
|
||||||
|
params["page"] = page
|
||||||
|
if per_page is not None:
|
||||||
|
params["per_page"] = per_page
|
||||||
|
|
||||||
|
response = self._client.request(url="/ssh_keys", method="GET", params=params)
|
||||||
|
|
||||||
|
ass_ssh_keys = [
|
||||||
|
BoundSSHKey(self, server_data) for server_data in response["ssh_keys"]
|
||||||
|
]
|
||||||
|
return self._add_meta_to_result(ass_ssh_keys, response)
|
||||||
|
|
||||||
|
def get_all(self, name=None, fingerprint=None, label_selector=None):
|
||||||
|
# type: (Optional[str], Optional[str], Optional[str]) -> List[BoundSSHKey]
|
||||||
|
"""Get all SSH keys from the account
|
||||||
|
|
||||||
|
:param name: str (optional)
|
||||||
|
Can be used to filter SSH keys by their name. The response will only contain the SSH key matching the specified name.
|
||||||
|
:param fingerprint: str (optional)
|
||||||
|
Can be used to filter SSH keys by their fingerprint. The response will only contain the SSH key matching the specified fingerprint.
|
||||||
|
:param label_selector: str (optional)
|
||||||
|
Can be used to filter SSH keys by labels. The response will only contain SSH keys matching the label selector.
|
||||||
|
:return: List[:class:`BoundSSHKey <hcloud.ssh_keys.client.BoundSSHKey>`]
|
||||||
|
"""
|
||||||
|
return super().get_all(
|
||||||
|
name=name, fingerprint=fingerprint, label_selector=label_selector
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_by_name(self, name):
|
||||||
|
# type: (str) -> SSHKeysClient
|
||||||
|
"""Get ssh key by name
|
||||||
|
|
||||||
|
:param name: str
|
||||||
|
Used to get ssh key by name.
|
||||||
|
:return: :class:`BoundSSHKey <hcloud.ssh_keys.client.BoundSSHKey>`
|
||||||
|
"""
|
||||||
|
return super().get_by_name(name)
|
||||||
|
|
||||||
|
def get_by_fingerprint(self, fingerprint):
|
||||||
|
# type: (str) -> BoundSSHKey
|
||||||
|
"""Get ssh key by fingerprint
|
||||||
|
|
||||||
|
:param fingerprint: str
|
||||||
|
Used to get ssh key by fingerprint.
|
||||||
|
:return: :class:`BoundSSHKey <hcloud.ssh_keys.client.BoundSSHKey>`
|
||||||
|
"""
|
||||||
|
response = self.get_list(fingerprint=fingerprint)
|
||||||
|
sshkeys = response.ssh_keys
|
||||||
|
return sshkeys[0] if sshkeys else None
|
||||||
|
|
||||||
|
def create(self, name, public_key, labels=None):
|
||||||
|
# type: (str, str, Optional[Dict[str, str]]) -> BoundSSHKey
|
||||||
|
"""Creates a new SSH key with the given name and public_key.
|
||||||
|
|
||||||
|
:param name: str
|
||||||
|
:param public_key: str
|
||||||
|
Public Key of the SSH Key you want create
|
||||||
|
:param labels: Dict[str, str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:return: :class:`BoundSSHKey <hcloud.ssh_keys.client.BoundSSHKey>`
|
||||||
|
"""
|
||||||
|
data = {"name": name, "public_key": public_key}
|
||||||
|
if labels is not None:
|
||||||
|
data["labels"] = labels
|
||||||
|
response = self._client.request(url="/ssh_keys", method="POST", json=data)
|
||||||
|
return BoundSSHKey(self, response["ssh_key"])
|
||||||
|
|
||||||
|
def update(self, ssh_key, name=None, labels=None):
|
||||||
|
# type: (SSHKey, Optional[str], Optional[Dict[str, str]]) -> BoundSSHKey
|
||||||
|
"""Updates an SSH key. You can update an SSH key name and an SSH key labels.
|
||||||
|
|
||||||
|
:param ssh_key: :class:`BoundSSHKey <hcloud.ssh_keys.client.BoundSSHKey>` or :class:`SSHKey <hcloud.ssh_keys.domain.SSHKey>`
|
||||||
|
:param name: str (optional)
|
||||||
|
New Description to set
|
||||||
|
:param labels: Dict[str, str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:return: :class:`BoundSSHKey <hcloud.ssh_keys.client.BoundSSHKey>`
|
||||||
|
"""
|
||||||
|
data = {}
|
||||||
|
if name is not None:
|
||||||
|
data["name"] = name
|
||||||
|
if labels is not None:
|
||||||
|
data["labels"] = labels
|
||||||
|
response = self._client.request(
|
||||||
|
url=f"/ssh_keys/{ssh_key.id}",
|
||||||
|
method="PUT",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return BoundSSHKey(self, response["ssh_key"])
|
||||||
|
|
||||||
|
def delete(self, ssh_key):
|
||||||
|
# type: (SSHKey) -> bool
|
||||||
|
self._client.request(url=f"/ssh_keys/{ssh_key.id}", method="DELETE")
|
||||||
|
"""Deletes an SSH key. It cannot be used anymore.
|
||||||
|
|
||||||
|
:param ssh_key: :class:`BoundSSHKey <hcloud.ssh_keys.client.BoundSSHKey>` or :class:`SSHKey <hcloud.ssh_keys.domain.SSHKey>`
|
||||||
|
:return: True
|
||||||
|
"""
|
||||||
|
# Return always true, because the API does not return an action for it. When an error occurs a HcloudAPIException will be raised
|
||||||
|
return True
|
42
plugins/module_utils/vendor/hcloud/ssh_keys/domain.py
vendored
Normal file
42
plugins/module_utils/vendor/hcloud/ssh_keys/domain.py
vendored
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
try:
|
||||||
|
from dateutil.parser import isoparse
|
||||||
|
except ImportError:
|
||||||
|
isoparse = None
|
||||||
|
|
||||||
|
from ..core.domain import BaseDomain, DomainIdentityMixin
|
||||||
|
|
||||||
|
|
||||||
|
class SSHKey(BaseDomain, DomainIdentityMixin):
|
||||||
|
"""SSHKey Domain
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
ID of the SSH key
|
||||||
|
:param name: str
|
||||||
|
Name of the SSH key (must be unique per project)
|
||||||
|
:param fingerprint: str
|
||||||
|
Fingerprint of public key
|
||||||
|
:param public_key: str
|
||||||
|
Public Key
|
||||||
|
:param labels: Dict
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:param created: datetime
|
||||||
|
Point in time when the SSH Key was created
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("id", "name", "fingerprint", "public_key", "labels", "created")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
id=None,
|
||||||
|
name=None,
|
||||||
|
fingerprint=None,
|
||||||
|
public_key=None,
|
||||||
|
labels=None,
|
||||||
|
created=None,
|
||||||
|
):
|
||||||
|
self.id = id
|
||||||
|
self.name = name
|
||||||
|
self.fingerprint = fingerprint
|
||||||
|
self.public_key = public_key
|
||||||
|
self.labels = labels
|
||||||
|
self.created = isoparse(created) if created else None
|
0
plugins/module_utils/vendor/hcloud/volumes/__init__.py
vendored
Normal file
0
plugins/module_utils/vendor/hcloud/volumes/__init__.py
vendored
Normal file
395
plugins/module_utils/vendor/hcloud/volumes/client.py
vendored
Normal file
395
plugins/module_utils/vendor/hcloud/volumes/client.py
vendored
Normal file
|
@ -0,0 +1,395 @@
|
||||||
|
from ..actions.client import BoundAction
|
||||||
|
from ..core.client import BoundModelBase, ClientEntityBase, GetEntityByNameMixin
|
||||||
|
from ..core.domain import add_meta_to_result
|
||||||
|
from ..locations.client import BoundLocation
|
||||||
|
from .domain import CreateVolumeResponse, Volume
|
||||||
|
|
||||||
|
|
||||||
|
class BoundVolume(BoundModelBase):
|
||||||
|
model = Volume
|
||||||
|
|
||||||
|
def __init__(self, client, data, complete=True):
|
||||||
|
location = data.get("location")
|
||||||
|
if location is not None:
|
||||||
|
data["location"] = BoundLocation(client._client.locations, location)
|
||||||
|
|
||||||
|
from ..servers.client import BoundServer
|
||||||
|
|
||||||
|
server = data.get("server")
|
||||||
|
if server is not None:
|
||||||
|
data["server"] = BoundServer(
|
||||||
|
client._client.servers, {"id": server}, complete=False
|
||||||
|
)
|
||||||
|
super().__init__(client, data, complete)
|
||||||
|
|
||||||
|
def get_actions_list(self, status=None, sort=None, page=None, per_page=None):
|
||||||
|
# type: (Optional[List[str]], Optional[List[str]], Optional[int], Optional[int]) -> PageResults[List[BoundAction, Meta]]
|
||||||
|
"""Returns all action objects for a volume.
|
||||||
|
|
||||||
|
:param status: List[str] (optional)
|
||||||
|
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
||||||
|
:param sort: List[str] (optional)
|
||||||
|
Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
|
||||||
|
:param page: int (optional)
|
||||||
|
Specifies the page to fetch
|
||||||
|
:param per_page: int (optional)
|
||||||
|
Specifies how many results are returned by page
|
||||||
|
:return: (List[:class:`BoundAction <hcloud.actions.client.BoundAction>`], :class:`Meta <hcloud.core.domain.Meta>`)
|
||||||
|
"""
|
||||||
|
return self._client.get_actions_list(self, status, sort, page, per_page)
|
||||||
|
|
||||||
|
def get_actions(self, status=None, sort=None):
|
||||||
|
# type: (Optional[List[str]], Optional[List[str]]) -> List[BoundAction]
|
||||||
|
"""Returns all action objects for a volume.
|
||||||
|
|
||||||
|
:param status: List[str] (optional)
|
||||||
|
Response will have only actions with specified statuses. Choices: `running` `success` `error`
|
||||||
|
:param sort:List[str] (optional)
|
||||||
|
Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc`
|
||||||
|
:return: List[:class:`BoundAction <hcloud.actions.client.BoundAction>`]
|
||||||
|
"""
|
||||||
|
return self._client.get_actions(self, status, sort)
|
||||||
|
|
||||||
|
def update(self, name=None, labels=None):
|
||||||
|
# type: (Optional[str], Optional[Dict[str, str]]) -> BoundAction
|
||||||
|
"""Updates the volume properties.
|
||||||
|
|
||||||
|
:param name: str (optional)
|
||||||
|
New volume name
|
||||||
|
:param labels: Dict[str, str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.update(self, name, labels)
|
||||||
|
|
||||||
|
def delete(self):
|
||||||
|
# type: () -> BoundAction
|
||||||
|
"""Deletes a volume. All volume data is irreversibly destroyed. The volume must not be attached to a server and it must not have delete protection enabled.
|
||||||
|
|
||||||
|
:return: boolean
|
||||||
|
"""
|
||||||
|
return self._client.delete(self)
|
||||||
|
|
||||||
|
def attach(self, server, automount=None):
|
||||||
|
# type: (Union[Server, BoundServer], Optional[bool]) -> BoundAction
|
||||||
|
"""Attaches a volume to a server. Works only if the server is in the same location as the volume.
|
||||||
|
|
||||||
|
:param server: :class:`BoundServer <hcloud.servers.client.BoundServer>` or :class:`Server <hcloud.servers.domain.Server>`
|
||||||
|
:param automount: boolean
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.attach(self, server, automount)
|
||||||
|
|
||||||
|
def detach(self):
|
||||||
|
# type: () -> BoundAction
|
||||||
|
"""Detaches a volume from the server it’s attached to. You may attach it to a server again at a later time.
|
||||||
|
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.detach(self)
|
||||||
|
|
||||||
|
def resize(self, size):
|
||||||
|
# type: (int) -> BoundAction
|
||||||
|
"""Changes the size of a volume. Note that downsizing a volume is not possible.
|
||||||
|
|
||||||
|
:param size: int
|
||||||
|
New volume size in GB (must be greater than current size)
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.resize(self, size)
|
||||||
|
|
||||||
|
def change_protection(self, delete=None):
|
||||||
|
# type: (Optional[bool]) -> BoundAction
|
||||||
|
"""Changes the protection configuration of a volume.
|
||||||
|
|
||||||
|
:param delete: boolean
|
||||||
|
If True, prevents the volume from being deleted
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
return self._client.change_protection(self, delete)
|
||||||
|
|
||||||
|
|
||||||
|
class VolumesClient(ClientEntityBase, GetEntityByNameMixin):
|
||||||
|
results_list_attribute_name = "volumes"
|
||||||
|
|
||||||
|
def get_by_id(self, id):
|
||||||
|
# type: (int) -> volumes.client.BoundVolume
|
||||||
|
"""Get a specific volume by its id
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
:return: :class:`BoundVolume <hcloud.volumes.client.BoundVolume>`
|
||||||
|
"""
|
||||||
|
response = self._client.request(url=f"/volumes/{id}", method="GET")
|
||||||
|
return BoundVolume(self, response["volume"])
|
||||||
|
|
||||||
|
def get_list(
|
||||||
|
self, name=None, label_selector=None, page=None, per_page=None, status=None
|
||||||
|
):
|
||||||
|
# type: (Optional[str], Optional[str], Optional[int], Optional[int], Optional[List[str]]) -> PageResults[List[BoundVolume], Meta]
|
||||||
|
"""Get a list of volumes from this account
|
||||||
|
|
||||||
|
:param name: str (optional)
|
||||||
|
Can be used to filter volumes by their name.
|
||||||
|
:param label_selector: str (optional)
|
||||||
|
Can be used to filter volumes by labels. The response will only contain volumes matching the label selector.
|
||||||
|
:param status: List[str] (optional)
|
||||||
|
Can be used to filter volumes by their status. The response will only contain volumes matching the status.
|
||||||
|
: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:`BoundVolume <hcloud.volumes.client.BoundVolume>`], :class:`Meta <hcloud.core.domain.Meta>`)
|
||||||
|
"""
|
||||||
|
params = {}
|
||||||
|
if name is not None:
|
||||||
|
params["name"] = name
|
||||||
|
if label_selector is not None:
|
||||||
|
params["label_selector"] = label_selector
|
||||||
|
if status is not None:
|
||||||
|
params["status"] = status
|
||||||
|
if page is not None:
|
||||||
|
params["page"] = page
|
||||||
|
if per_page is not None:
|
||||||
|
params["per_page"] = per_page
|
||||||
|
|
||||||
|
response = self._client.request(url="/volumes", method="GET", params=params)
|
||||||
|
volumes = [
|
||||||
|
BoundVolume(self, volume_data) for volume_data in response["volumes"]
|
||||||
|
]
|
||||||
|
return self._add_meta_to_result(volumes, response)
|
||||||
|
|
||||||
|
def get_all(self, label_selector=None, status=None):
|
||||||
|
# type: (Optional[str], Optional[List[str]]) -> List[BoundVolume]
|
||||||
|
"""Get all volumes from this account
|
||||||
|
|
||||||
|
:param label_selector:
|
||||||
|
Can be used to filter volumes by labels. The response will only contain volumes matching the label selector.
|
||||||
|
:param status: List[str] (optional)
|
||||||
|
Can be used to filter volumes by their status. The response will only contain volumes matching the status.
|
||||||
|
:return: List[:class:`BoundVolume <hcloud.volumes.client.BoundVolume>`]
|
||||||
|
"""
|
||||||
|
return super().get_all(label_selector=label_selector, status=status)
|
||||||
|
|
||||||
|
def get_by_name(self, name):
|
||||||
|
# type: (str) -> BoundVolume
|
||||||
|
"""Get volume by name
|
||||||
|
|
||||||
|
:param name: str
|
||||||
|
Used to get volume by name.
|
||||||
|
:return: :class:`BoundVolume <hcloud.volumes.client.BoundVolume>`
|
||||||
|
"""
|
||||||
|
return super().get_by_name(name)
|
||||||
|
|
||||||
|
def create(
|
||||||
|
self,
|
||||||
|
size, # type: int
|
||||||
|
name, # type: str
|
||||||
|
labels=None, # type: Optional[str]
|
||||||
|
location=None, # type: Optional[Location]
|
||||||
|
server=None, # type: Optional[Server],
|
||||||
|
automount=None, # type: Optional[bool],
|
||||||
|
format=None, # type: Optional[str],
|
||||||
|
):
|
||||||
|
# type: (...) -> CreateVolumeResponse
|
||||||
|
"""Creates a new volume attached to a server.
|
||||||
|
|
||||||
|
:param size: int
|
||||||
|
Size of the volume in GB
|
||||||
|
:param name: str
|
||||||
|
Name of the volume
|
||||||
|
:param labels: Dict[str,str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:param location: :class:`BoundLocation <hcloud.locations.client.BoundLocation>` or :class:`Location <hcloud.locations.domain.Location>`
|
||||||
|
:param server: :class:`BoundServer <hcloud.servers.client.BoundServer>` or :class:`Server <hcloud.servers.domain.Server>`
|
||||||
|
:param automount: boolean (optional)
|
||||||
|
Auto mount volumes after attach.
|
||||||
|
:param format: str (optional)
|
||||||
|
Format volume after creation. One of: xfs, ext4
|
||||||
|
:return: :class:`CreateVolumeResponse <hcloud.volumes.domain.CreateVolumeResponse>`
|
||||||
|
"""
|
||||||
|
|
||||||
|
if size <= 0:
|
||||||
|
raise ValueError("size must be greater than 0")
|
||||||
|
|
||||||
|
if not (bool(location) ^ bool(server)):
|
||||||
|
raise ValueError("only one of server or location must be provided")
|
||||||
|
|
||||||
|
data = {"name": name, "size": size}
|
||||||
|
if labels is not None:
|
||||||
|
data["labels"] = labels
|
||||||
|
if location is not None:
|
||||||
|
data["location"] = location.id_or_name
|
||||||
|
|
||||||
|
if server is not None:
|
||||||
|
data["server"] = server.id
|
||||||
|
if automount is not None:
|
||||||
|
data["automount"] = automount
|
||||||
|
if format is not None:
|
||||||
|
data["format"] = format
|
||||||
|
|
||||||
|
response = self._client.request(url="/volumes", json=data, method="POST")
|
||||||
|
|
||||||
|
result = CreateVolumeResponse(
|
||||||
|
volume=BoundVolume(self, response["volume"]),
|
||||||
|
action=BoundAction(self._client.actions, response["action"]),
|
||||||
|
next_actions=[
|
||||||
|
BoundAction(self._client.actions, action)
|
||||||
|
for action in response["next_actions"]
|
||||||
|
],
|
||||||
|
)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def get_actions_list(
|
||||||
|
self, volume, status=None, sort=None, page=None, per_page=None
|
||||||
|
):
|
||||||
|
# type: (Volume, Optional[List[str]], Optional[List[str]], Optional[int], Optional[int]) -> PageResults[List[BoundAction], Meta]
|
||||||
|
"""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 = {}
|
||||||
|
if status is not None:
|
||||||
|
params["status"] = status
|
||||||
|
if sort is not None:
|
||||||
|
params["sort"] = sort
|
||||||
|
if page is not None:
|
||||||
|
params["page"] = page
|
||||||
|
if per_page is not None:
|
||||||
|
params["per_page"] = per_page
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url=f"/volumes/{volume.id}/actions",
|
||||||
|
method="GET",
|
||||||
|
params=params,
|
||||||
|
)
|
||||||
|
actions = [
|
||||||
|
BoundAction(self._client.actions, action_data)
|
||||||
|
for action_data in response["actions"]
|
||||||
|
]
|
||||||
|
return add_meta_to_result(actions, response, "actions")
|
||||||
|
|
||||||
|
def get_actions(self, volume, status=None, sort=None):
|
||||||
|
# type: (Union[Volume, BoundVolume], Optional[List[str]], Optional[List[str]]) -> List[BoundAction]
|
||||||
|
"""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`
|
||||||
|
:return: List[:class:`BoundAction <hcloud.actions.client.BoundAction>`]
|
||||||
|
"""
|
||||||
|
return super().get_actions(volume, status=status, sort=sort)
|
||||||
|
|
||||||
|
def update(self, volume, name=None, labels=None):
|
||||||
|
# type:(Union[Volume, BoundVolume], Optional[str], Optional[Dict[str, str]]) -> BoundVolume
|
||||||
|
"""Updates the volume properties.
|
||||||
|
|
||||||
|
:param volume: :class:`BoundVolume <hcloud.volumes.client.BoundVolume>` or :class:`Volume <hcloud.volumes.domain.Volume>`
|
||||||
|
:param name: str (optional)
|
||||||
|
New volume name
|
||||||
|
:param labels: Dict[str, str] (optional)
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
data = {}
|
||||||
|
if name is not None:
|
||||||
|
data.update({"name": name})
|
||||||
|
if labels is not None:
|
||||||
|
data.update({"labels": labels})
|
||||||
|
response = self._client.request(
|
||||||
|
url=f"/volumes/{volume.id}",
|
||||||
|
method="PUT",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return BoundVolume(self, response["volume"])
|
||||||
|
|
||||||
|
def delete(self, volume):
|
||||||
|
# type: (Union[Volume, BoundVolume]) -> BoundAction
|
||||||
|
"""Deletes a volume. All volume data is irreversibly destroyed. The volume must not be attached to a server and it must not have delete protection enabled.
|
||||||
|
|
||||||
|
:param volume: :class:`BoundVolume <hcloud.volumes.client.BoundVolume>` or :class:`Volume <hcloud.volumes.domain.Volume>`
|
||||||
|
:return: boolean
|
||||||
|
"""
|
||||||
|
self._client.request(url=f"/volumes/{volume.id}", method="DELETE")
|
||||||
|
return True
|
||||||
|
|
||||||
|
def resize(self, volume, size):
|
||||||
|
# type: (Union[Volume, BoundVolume], int) -> BoundAction
|
||||||
|
"""Changes the size of a volume. Note that downsizing a volume is not possible.
|
||||||
|
|
||||||
|
:param volume: :class:`BoundVolume <hcloud.volumes.client.BoundVolume>` or :class:`Volume <hcloud.volumes.domain.Volume>`
|
||||||
|
:param size: int
|
||||||
|
New volume size in GB (must be greater than current size)
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
data = self._client.request(
|
||||||
|
url=f"/volumes/{volume.id}/actions/resize",
|
||||||
|
json={"size": size},
|
||||||
|
method="POST",
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, data["action"])
|
||||||
|
|
||||||
|
def attach(self, volume, server, automount=None):
|
||||||
|
# type: (Union[Volume, BoundVolume], Union[Server, BoundServer], Optional[bool]) -> BoundAction
|
||||||
|
"""Attaches a volume to a server. Works only if the server is in the same location as the volume.
|
||||||
|
|
||||||
|
:param volume: :class:`BoundVolume <hcloud.volumes.client.BoundVolume>` or :class:`Volume <hcloud.volumes.domain.Volume>`
|
||||||
|
:param server: :class:`BoundServer <hcloud.servers.client.BoundServer>` or :class:`Server <hcloud.servers.domain.Server>`
|
||||||
|
:param automount: boolean
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
data = {"server": server.id}
|
||||||
|
if automount is not None:
|
||||||
|
data["automount"] = automount
|
||||||
|
|
||||||
|
data = self._client.request(
|
||||||
|
url=f"/volumes/{volume.id}/actions/attach",
|
||||||
|
json=data,
|
||||||
|
method="POST",
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, data["action"])
|
||||||
|
|
||||||
|
def detach(self, volume):
|
||||||
|
# type: (Union[Volume, BoundVolume]) -> BoundAction
|
||||||
|
"""Detaches a volume from the server it’s attached to. You may attach it to a server again at a later time.
|
||||||
|
|
||||||
|
:param volume: :class:`BoundVolume <hcloud.volumes.client.BoundVolume>` or :class:`Volume <hcloud.volumes.domain.Volume>`
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
data = self._client.request(
|
||||||
|
url=f"/volumes/{volume.id}/actions/detach",
|
||||||
|
method="POST",
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, data["action"])
|
||||||
|
|
||||||
|
def change_protection(self, volume, delete=None):
|
||||||
|
# type: (Union[Volume, BoundVolume], Optional[bool], Optional[bool]) -> BoundAction
|
||||||
|
"""Changes the protection configuration of a volume.
|
||||||
|
|
||||||
|
:param volume: :class:`BoundVolume <hcloud.volumes.client.BoundVolume>` or :class:`Volume <hcloud.volumes.domain.Volume>`
|
||||||
|
:param delete: boolean
|
||||||
|
If True, prevents the volume from being deleted
|
||||||
|
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
"""
|
||||||
|
data = {}
|
||||||
|
if delete is not None:
|
||||||
|
data.update({"delete": delete})
|
||||||
|
|
||||||
|
response = self._client.request(
|
||||||
|
url="/volumes/{volume_id}/actions/change_protection".format(
|
||||||
|
volume_id=volume.id
|
||||||
|
),
|
||||||
|
method="POST",
|
||||||
|
json=data,
|
||||||
|
)
|
||||||
|
return BoundAction(self._client.actions, response["action"])
|
103
plugins/module_utils/vendor/hcloud/volumes/domain.py
vendored
Normal file
103
plugins/module_utils/vendor/hcloud/volumes/domain.py
vendored
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
try:
|
||||||
|
from dateutil.parser import isoparse
|
||||||
|
except ImportError:
|
||||||
|
isoparse = None
|
||||||
|
|
||||||
|
from ..core.domain import BaseDomain, DomainIdentityMixin
|
||||||
|
|
||||||
|
|
||||||
|
class Volume(BaseDomain, DomainIdentityMixin):
|
||||||
|
"""Volume Domain
|
||||||
|
|
||||||
|
:param id: int
|
||||||
|
ID of the Volume
|
||||||
|
:param name: str
|
||||||
|
Name of the Volume
|
||||||
|
:param server: :class:`BoundServer <hcloud.servers.client.BoundServer>`, None
|
||||||
|
Server the Volume is attached to, None if it is not attached at all.
|
||||||
|
:param created: datetime
|
||||||
|
Point in time when the Volume was created
|
||||||
|
:param location: :class:`BoundLocation <hcloud.locations.client.BoundLocation>`
|
||||||
|
Location of the Volume. Volume can only be attached to Servers in the same location.
|
||||||
|
:param size: int
|
||||||
|
Size in GB of the Volume
|
||||||
|
:param linux_device: str
|
||||||
|
Device path on the file system for the Volume
|
||||||
|
:param protection: dict
|
||||||
|
Protection configuration for the Volume
|
||||||
|
:param labels: dict
|
||||||
|
User-defined labels (key-value pairs)
|
||||||
|
:param status: str
|
||||||
|
Current status of the volume Choices: `creating`, `available`
|
||||||
|
:param format: str, None
|
||||||
|
Filesystem of the volume if formatted on creation, None if not formatted on creation.
|
||||||
|
"""
|
||||||
|
|
||||||
|
STATUS_CREATING = "creating"
|
||||||
|
"""Volume Status creating"""
|
||||||
|
STATUS_AVAILABLE = "available"
|
||||||
|
"""Volume Status available"""
|
||||||
|
|
||||||
|
__slots__ = (
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"server",
|
||||||
|
"location",
|
||||||
|
"size",
|
||||||
|
"linux_device",
|
||||||
|
"format",
|
||||||
|
"protection",
|
||||||
|
"labels",
|
||||||
|
"status",
|
||||||
|
"created",
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
id,
|
||||||
|
name=None,
|
||||||
|
server=None,
|
||||||
|
created=None,
|
||||||
|
location=None,
|
||||||
|
size=None,
|
||||||
|
linux_device=None,
|
||||||
|
format=None,
|
||||||
|
protection=None,
|
||||||
|
labels=None,
|
||||||
|
status=None,
|
||||||
|
):
|
||||||
|
self.id = id
|
||||||
|
self.name = name
|
||||||
|
self.server = server
|
||||||
|
self.created = isoparse(created) if created else None
|
||||||
|
self.location = location
|
||||||
|
self.size = size
|
||||||
|
self.linux_device = linux_device
|
||||||
|
self.format = format
|
||||||
|
self.protection = protection
|
||||||
|
self.labels = labels
|
||||||
|
self.status = status
|
||||||
|
|
||||||
|
|
||||||
|
class CreateVolumeResponse(BaseDomain):
|
||||||
|
"""Create Volume Response Domain
|
||||||
|
|
||||||
|
:param volume: :class:`BoundVolume <hcloud.volumes.client.BoundVolume>`
|
||||||
|
The created volume
|
||||||
|
:param action: :class:`BoundAction <hcloud.actions.client.BoundAction>`
|
||||||
|
The action that shows the progress of the Volume Creation
|
||||||
|
:param next_actions: List[:class:`BoundAction <hcloud.actions.client.BoundAction>`]
|
||||||
|
List of actions that are performed after the creation, like attaching to a server
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ("volume", "action", "next_actions")
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
volume, # type: BoundVolume
|
||||||
|
action, # type: BoundAction
|
||||||
|
next_actions, # type: List[BoundAction]
|
||||||
|
):
|
||||||
|
self.volume = volume
|
||||||
|
self.action = action
|
||||||
|
self.next_actions = next_actions
|
|
@ -171,13 +171,12 @@ import time
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
from ansible.module_utils.common.text.converters import to_native
|
||||||
from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
|
from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
|
||||||
|
from ansible_collections.hetzner.hcloud.plugins.module_utils.vendor.hcloud import (
|
||||||
try:
|
APIException,
|
||||||
from hcloud import APIException
|
)
|
||||||
from hcloud.firewalls.domain import FirewallRule
|
from ansible_collections.hetzner.hcloud.plugins.module_utils.vendor.hcloud.firewalls.domain import (
|
||||||
except ImportError:
|
FirewallRule,
|
||||||
APIException = None
|
)
|
||||||
FirewallRule = None
|
|
||||||
|
|
||||||
|
|
||||||
class AnsibleHcloudFirewall(Hcloud):
|
class AnsibleHcloudFirewall(Hcloud):
|
||||||
|
|
|
@ -282,17 +282,15 @@ hcloud_load_balancer_service:
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
from ansible.module_utils.common.text.converters import to_native
|
||||||
from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
|
from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
|
||||||
|
from ansible_collections.hetzner.hcloud.plugins.module_utils.vendor.hcloud import (
|
||||||
try:
|
APIException,
|
||||||
from hcloud import APIException
|
)
|
||||||
from hcloud.load_balancers.domain import (
|
from ansible_collections.hetzner.hcloud.plugins.module_utils.vendor.hcloud.load_balancers.domain import (
|
||||||
LoadBalancerHealtCheckHttp,
|
LoadBalancerHealtCheckHttp,
|
||||||
LoadBalancerHealthCheck,
|
LoadBalancerHealthCheck,
|
||||||
LoadBalancerService,
|
LoadBalancerService,
|
||||||
LoadBalancerServiceHttp,
|
LoadBalancerServiceHttp,
|
||||||
)
|
)
|
||||||
except ImportError:
|
|
||||||
APIException = None
|
|
||||||
|
|
||||||
|
|
||||||
class AnsibleHcloudLoadBalancerService(Hcloud):
|
class AnsibleHcloudLoadBalancerService(Hcloud):
|
||||||
|
|
|
@ -138,17 +138,11 @@ hcloud_load_balancer_target:
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
from ansible.module_utils.common.text.converters import to_native
|
||||||
from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
|
from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
|
||||||
|
from ansible_collections.hetzner.hcloud.plugins.module_utils.vendor.hcloud.load_balancers.domain import (
|
||||||
try:
|
LoadBalancerTarget,
|
||||||
from hcloud.load_balancers.domain import (
|
LoadBalancerTargetIP,
|
||||||
LoadBalancerTarget,
|
LoadBalancerTargetLabelSelector,
|
||||||
LoadBalancerTargetIP,
|
)
|
||||||
LoadBalancerTargetLabelSelector,
|
|
||||||
)
|
|
||||||
except ImportError:
|
|
||||||
LoadBalancerTarget = None
|
|
||||||
LoadBalancerTargetLabelSelector = None
|
|
||||||
LoadBalancerTargetIP = None
|
|
||||||
|
|
||||||
|
|
||||||
class AnsibleHcloudLoadBalancerTarget(Hcloud):
|
class AnsibleHcloudLoadBalancerTarget(Hcloud):
|
||||||
|
|
|
@ -90,11 +90,9 @@ hcloud_route:
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
from ansible.module_utils.common.text.converters import to_native
|
||||||
from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
|
from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
|
||||||
|
from ansible_collections.hetzner.hcloud.plugins.module_utils.vendor.hcloud.networks.domain import (
|
||||||
try:
|
NetworkRoute,
|
||||||
from hcloud.networks.domain import NetworkRoute
|
)
|
||||||
except ImportError:
|
|
||||||
NetworkRoute = None
|
|
||||||
|
|
||||||
|
|
||||||
class AnsibleHcloudRoute(Hcloud):
|
class AnsibleHcloudRoute(Hcloud):
|
||||||
|
|
|
@ -333,18 +333,19 @@ from datetime import datetime, timedelta, timezone
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
from ansible.module_utils.common.text.converters import to_native
|
||||||
from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
|
from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
|
||||||
|
from ansible_collections.hetzner.hcloud.plugins.module_utils.vendor.hcloud.firewalls.domain import (
|
||||||
try:
|
FirewallResource,
|
||||||
from hcloud.firewalls.domain import FirewallResource
|
)
|
||||||
from hcloud.servers.domain import Server, ServerCreatePublicNetwork
|
from ansible_collections.hetzner.hcloud.plugins.module_utils.vendor.hcloud.servers.domain import (
|
||||||
from hcloud.ssh_keys.domain import SSHKey
|
Server,
|
||||||
from hcloud.volumes.domain import Volume
|
ServerCreatePublicNetwork,
|
||||||
except ImportError:
|
)
|
||||||
Volume = None
|
from ansible_collections.hetzner.hcloud.plugins.module_utils.vendor.hcloud.ssh_keys.domain import (
|
||||||
SSHKey = None
|
SSHKey,
|
||||||
Server = None
|
)
|
||||||
ServerCreatePublicNetwork = None
|
from ansible_collections.hetzner.hcloud.plugins.module_utils.vendor.hcloud.volumes.domain import (
|
||||||
FirewallResource = None
|
Volume,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class AnsibleHcloudServer(Hcloud):
|
class AnsibleHcloudServer(Hcloud):
|
||||||
|
|
|
@ -115,11 +115,9 @@ hcloud_server_network:
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
from ansible.module_utils.common.text.converters import to_native
|
||||||
from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
|
from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
|
||||||
|
from ansible_collections.hetzner.hcloud.plugins.module_utils.vendor.hcloud import (
|
||||||
try:
|
APIException,
|
||||||
from hcloud import APIException
|
)
|
||||||
except ImportError:
|
|
||||||
APIException = None
|
|
||||||
|
|
||||||
|
|
||||||
class AnsibleHcloudServerNetwork(Hcloud):
|
class AnsibleHcloudServerNetwork(Hcloud):
|
||||||
|
|
|
@ -127,11 +127,9 @@ hcloud_subnetwork:
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
from ansible.module_utils.common.text.converters import to_native
|
||||||
from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
|
from ansible_collections.hetzner.hcloud.plugins.module_utils.hcloud import Hcloud
|
||||||
|
from ansible_collections.hetzner.hcloud.plugins.module_utils.vendor.hcloud.networks.domain import (
|
||||||
try:
|
NetworkSubnet,
|
||||||
from hcloud.networks.domain import NetworkSubnet
|
)
|
||||||
except ImportError:
|
|
||||||
NetworkSubnet = None
|
|
||||||
|
|
||||||
|
|
||||||
class AnsibleHcloudSubnetwork(Hcloud):
|
class AnsibleHcloudSubnetwork(Hcloud):
|
||||||
|
|
103
scripts/vendor.py
Executable file
103
scripts/vendor.py
Executable file
|
@ -0,0 +1,103 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
"""
|
||||||
|
Fetch and bundles the hcloud package inside the collection.
|
||||||
|
|
||||||
|
Fetch the desired version `HCLOUD_VERSION` from https://github.com/hetznercloud/hcloud-python
|
||||||
|
`HCLOUD_SOURCE_URL` using git, apply some code modifications to comply with ansible,
|
||||||
|
move the modified files at the vendor location `HCLOUD_VENDOR_PATH`.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import re
|
||||||
|
from pathlib import Path
|
||||||
|
from shutil import move, rmtree
|
||||||
|
from subprocess import check_call
|
||||||
|
from tempfile import TemporaryDirectory
|
||||||
|
from textwrap import dedent
|
||||||
|
|
||||||
|
logger = logging.getLogger("vendor")
|
||||||
|
|
||||||
|
HCLOUD_SOURCE_URL = "https://github.com/hetznercloud/hcloud-python"
|
||||||
|
HCLOUD_VERSION = "v1.24.0"
|
||||||
|
HCLOUD_VENDOR_PATH = "plugins/module_utils/vendor/hcloud"
|
||||||
|
|
||||||
|
|
||||||
|
def apply_code_modifications(source_path: Path):
|
||||||
|
# The ansible galaxy-importer consider __version___.py to be an invalid filename in module_utils/
|
||||||
|
# Move the __version__.py file to _version.py
|
||||||
|
move(source_path / "__version__.py", source_path / "_version.py")
|
||||||
|
|
||||||
|
for file in source_path.rglob("*.py"):
|
||||||
|
content = file.read_text()
|
||||||
|
content_orig = content
|
||||||
|
|
||||||
|
# Move the __version__.py file to _version.py
|
||||||
|
content = re.sub(
|
||||||
|
r"from .__version__ import VERSION",
|
||||||
|
r"from ._version import VERSION",
|
||||||
|
content,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Wrap requests imports
|
||||||
|
content = re.sub(
|
||||||
|
r"import requests",
|
||||||
|
dedent(
|
||||||
|
r"""
|
||||||
|
try:
|
||||||
|
import requests
|
||||||
|
except ImportError:
|
||||||
|
requests = None
|
||||||
|
"""
|
||||||
|
).strip(),
|
||||||
|
content,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Wrap dateutil imports
|
||||||
|
content = re.sub(
|
||||||
|
r"from dateutil.parser import isoparse",
|
||||||
|
dedent(
|
||||||
|
r"""
|
||||||
|
try:
|
||||||
|
from dateutil.parser import isoparse
|
||||||
|
except ImportError:
|
||||||
|
isoparse = None
|
||||||
|
"""
|
||||||
|
).strip(),
|
||||||
|
content,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Remove requests.Response typings
|
||||||
|
content = re.sub(
|
||||||
|
r": requests\.Response",
|
||||||
|
r"",
|
||||||
|
content,
|
||||||
|
)
|
||||||
|
|
||||||
|
if content != content_orig:
|
||||||
|
logger.info("Applied code modifications on %s", file)
|
||||||
|
|
||||||
|
file.write_text(content)
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
with TemporaryDirectory() as tmp_dir:
|
||||||
|
tmp_dir_path = Path(tmp_dir)
|
||||||
|
logger.info("Created temporary directory %s", tmp_dir_path)
|
||||||
|
|
||||||
|
check_call(["git", "clone", "--depth=1", "--branch", HCLOUD_VERSION, HCLOUD_SOURCE_URL, tmp_dir_path])
|
||||||
|
logger.info("Cloned the source files in %s", tmp_dir_path)
|
||||||
|
|
||||||
|
apply_code_modifications(tmp_dir_path / "hcloud")
|
||||||
|
logger.info("Applied code modifications on the source files")
|
||||||
|
|
||||||
|
rmtree(HCLOUD_VENDOR_PATH)
|
||||||
|
move(tmp_dir_path / "hcloud", HCLOUD_VENDOR_PATH)
|
||||||
|
logger.info("Bundled the modified sources files in the collection")
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
logging.basicConfig(level=logging.INFO, format="%(levelname)-8s: %(message)s")
|
||||||
|
raise SystemExit(main())
|
|
@ -1 +1,2 @@
|
||||||
hcloud >= 1.10.0 # minimum version
|
python-dateutil>=2.7.5
|
||||||
|
requests>=2.20
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
netaddr
|
netaddr
|
||||||
hcloud
|
python-dateutil
|
||||||
|
requests
|
||||||
|
|
|
@ -59,7 +59,8 @@ retry ansible-galaxy -vvv collection install community.general
|
||||||
retry ansible-galaxy -vvv collection install ansible.netcommon
|
retry ansible-galaxy -vvv collection install ansible.netcommon
|
||||||
retry ansible-galaxy -vvv collection install community.internal_test_tools
|
retry ansible-galaxy -vvv collection install community.internal_test_tools
|
||||||
retry pip install netaddr --disable-pip-version-check
|
retry pip install netaddr --disable-pip-version-check
|
||||||
retry pip install hcloud
|
retry pip install python-dateutil
|
||||||
|
retry pip install requests
|
||||||
retry pip install rstcheck
|
retry pip install rstcheck
|
||||||
# END: HACK
|
# END: HACK
|
||||||
|
|
||||||
|
|
|
@ -43,5 +43,7 @@ pip install pylint==2.5.3
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
ansible-test sanity --color -v --junit ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} \
|
ansible-test sanity --color -v --junit ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} \
|
||||||
--base-branch "${base_branch}" \
|
--base-branch "${base_branch}" \
|
||||||
|
--exclude plugins/module_utils/vendor/ \
|
||||||
|
--exclude scripts/ \
|
||||||
--exclude tests/utils/ \
|
--exclude tests/utils/ \
|
||||||
"${options[@]}" --allow-disabled
|
"${options[@]}" --allow-disabled
|
||||||
|
|
|
@ -24,4 +24,6 @@ fi
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
ansible-test sanity --color -v --junit ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} \
|
ansible-test sanity --color -v --junit ${COVERAGE:+"$COVERAGE"} ${CHANGED:+"$CHANGED"} \
|
||||||
--docker --base-branch "${base_branch}" \
|
--docker --base-branch "${base_branch}" \
|
||||||
|
--exclude plugins/module_utils/vendor/ \
|
||||||
|
--exclude scripts/ \
|
||||||
--allow-disabled
|
--allow-disabled
|
||||||
|
|
|
@ -77,7 +77,8 @@ fi
|
||||||
retry ansible-galaxy -vvv collection install community.general
|
retry ansible-galaxy -vvv collection install community.general
|
||||||
retry ansible-galaxy -vvv collection install ansible.netcommon
|
retry ansible-galaxy -vvv collection install ansible.netcommon
|
||||||
|
|
||||||
retry pip install hcloud
|
retry pip install python-dateutil
|
||||||
|
retry pip install requests
|
||||||
retry pip install netaddr --disable-pip-version-check
|
retry pip install netaddr --disable-pip-version-check
|
||||||
retry ansible-galaxy -vvv collection install community.internal_test_tools
|
retry ansible-galaxy -vvv collection install community.internal_test_tools
|
||||||
# END: HACK
|
# END: HACK
|
||||||
|
|
Loading…
Reference in a new issue