Source code for hcloud.load_balancers.client

from __future__ import annotations

from datetime import datetime
from typing import TYPE_CHECKING, Any, NamedTuple

from dateutil.parser import isoparse

from ..actions import ActionsPageResult, BoundAction, ResourceActionsClient
from ..certificates import BoundCertificate
from ..core import BoundModelBase, ClientEntityBase, Meta
from ..load_balancer_types import BoundLoadBalancerType
from ..locations import BoundLocation
from ..metrics import Metrics
from ..networks import BoundNetwork
from ..servers import BoundServer
from .domain import (
    CreateLoadBalancerResponse,
    GetMetricsResponse,
    IPv4Address,
    IPv6Network,
    LoadBalancer,
    LoadBalancerAlgorithm,
    LoadBalancerHealtCheckHttp,
    LoadBalancerHealthCheck,
    LoadBalancerService,
    LoadBalancerServiceHttp,
    LoadBalancerTarget,
    LoadBalancerTargetHealthStatus,
    LoadBalancerTargetIP,
    LoadBalancerTargetLabelSelector,
    MetricsType,
    PrivateNet,
    PublicNetwork,
)

if TYPE_CHECKING:
    from .._client import Client
    from ..load_balancer_types import LoadBalancerType
    from ..locations import Location
    from ..networks import Network


[docs] class BoundLoadBalancer(BoundModelBase, LoadBalancer): _client: LoadBalancersClient model = LoadBalancer # pylint: disable=too-many-branches,too-many-locals def __init__(self, client: LoadBalancersClient, data: dict, complete: bool = 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"]) target_health_status = target.get("health_status") if target_health_status is not None: tmp_target.health_status = [ LoadBalancerTargetHealthStatus( listen_port=target_health_status_item["listen_port"], status=target_health_status_item["status"], ) for target_health_status_item in target_health_status ] 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)
[docs] def update( self, name: str | None = None, labels: dict[str, str] | None = None, ) -> 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)
[docs] def delete(self) -> bool: """Deletes a Load Balancer. :return: boolean """ return self._client.delete(self)
[docs] def get_metrics( self, type: MetricsType, start: datetime | str, end: datetime | str, step: float | None = None, ) -> GetMetricsResponse: """Get Metrics for a LoadBalancer. :param type: Type of metrics to get. :param start: Start of period to get Metrics for (in ISO-8601 format). :param end: End of period to get Metrics for (in ISO-8601 format). :param step: Resolution of results in seconds. """ return self._client.get_metrics( self, type=type, start=start, end=end, step=step, )
[docs] def get_actions_list( self, status: list[str] | None = None, sort: list[str] | None = None, page: int | None = None, per_page: int | None = None, ) -> ActionsPageResult: """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)
[docs] def get_actions( self, status: list[str] | None = None, sort: list[str] | None = None, ) -> 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)
[docs] def add_service(self, service: LoadBalancerService) -> 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)
[docs] def update_service(self, service: LoadBalancerService) -> 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)
[docs] def delete_service(self, service: LoadBalancerService) -> 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)
[docs] def add_target(self, target: LoadBalancerTarget) -> 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)
[docs] def remove_target(self, target: LoadBalancerTarget) -> 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)
[docs] def change_algorithm(self, algorithm: LoadBalancerAlgorithm) -> 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)
[docs] def change_dns_ptr(self, ip: str, dns_ptr: 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)
[docs] def change_protection(self, delete: bool) -> 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)
[docs] def attach_to_network( self, network: Network | BoundNetwork, ip: str | None = None, ) -> 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)
[docs] def detach_from_network(self, network: 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)
[docs] def enable_public_interface(self) -> BoundAction: """Enables the public interface of a Load Balancer. :return: :class:`BoundAction <hcloud.actions.client.BoundAction>` """ return self._client.enable_public_interface(self)
[docs] def disable_public_interface(self) -> BoundAction: """Disables the public interface of a Load Balancer. :return: :class:`BoundAction <hcloud.actions.client.BoundAction>` """ return self._client.disable_public_interface(self)
[docs] def change_type( self, load_balancer_type: 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 LoadBalancersPageResult(NamedTuple): load_balancers: list[BoundLoadBalancer] meta: Meta | None
[docs] class LoadBalancersClient(ClientEntityBase): _client: Client actions: ResourceActionsClient """Load Balancers scoped actions client :type: :class:`ResourceActionsClient <hcloud.actions.client.ResourceActionsClient>` """ def __init__(self, client: Client): super().__init__(client) self.actions = ResourceActionsClient(client, "/load_balancers")
[docs] def get_by_id(self, id: 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"])
[docs] def get_list( self, name: str | None = None, label_selector: str | None = None, page: int | None = None, per_page: int | None = None, ) -> LoadBalancersPageResult: """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: dict[str, Any] = {} 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 ) load_balancers = [ BoundLoadBalancer(self, load_balancer_data) for load_balancer_data in response["load_balancers"] ] return LoadBalancersPageResult(load_balancers, Meta.parse_meta(response))
[docs] def get_all( self, name: str | None = None, label_selector: str | None = None, ) -> 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 self._iter_pages(self.get_list, name=name, label_selector=label_selector)
[docs] def get_by_name(self, name: str) -> BoundLoadBalancer | None: """Get Load Balancer by name :param name: str Used to get Load Balancer by name. :return: :class:`BoundLoadBalancer <hcloud.load_balancers.client.BoundLoadBalancer>` """ return self._get_first_by(name=name)
[docs] def create( self, name: str, load_balancer_type: LoadBalancerType | BoundLoadBalancerType, algorithm: LoadBalancerAlgorithm | None = None, services: list[LoadBalancerService] | None = None, targets: list[LoadBalancerTarget] | None = None, labels: dict[str, str] | None = None, location: Location | BoundLocation | None = None, network_zone: str | None = None, public_interface: bool | None = None, network: Network | BoundNetwork | None = None, ) -> 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: dict[str, Any] = { "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: data["services"] = [service.to_payload() for service in services] if targets is not None: data["targets"] = [target.to_payload() for target in targets] 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"]), )
[docs] def update( self, load_balancer: LoadBalancer | BoundLoadBalancer, name: str | None = None, labels: dict[str, str] | None = None, ) -> 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: dict[str, Any] = {} if name is not None: data.update({"name": name}) if labels is not None: data.update({"labels": labels}) response = self._client.request( url=f"/load_balancers/{load_balancer.id}", method="PUT", json=data, ) return BoundLoadBalancer(self, response["load_balancer"])
[docs] def delete(self, load_balancer: LoadBalancer | BoundLoadBalancer) -> bool: """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=f"/load_balancers/{load_balancer.id}", method="DELETE", ) return True
[docs] def get_metrics( self, load_balancer: LoadBalancer | BoundLoadBalancer, type: MetricsType | list[MetricsType], start: datetime | str, end: datetime | str, step: float | None = None, ) -> GetMetricsResponse: """Get Metrics for a LoadBalancer. :param load_balancer: The Load Balancer to get the metrics for. :param type: Type of metrics to get. :param start: Start of period to get Metrics for (in ISO-8601 format). :param end: End of period to get Metrics for (in ISO-8601 format). :param step: Resolution of results in seconds. """ if not isinstance(type, list): type = [type] if isinstance(start, str): start = isoparse(start) if isinstance(end, str): end = isoparse(end) params: dict[str, Any] = { "type": ",".join(type), "start": start.isoformat(), "end": end.isoformat(), } if step is not None: params["step"] = step response = self._client.request( url=f"/load_balancers/{load_balancer.id}/metrics", method="GET", params=params, ) return GetMetricsResponse( metrics=Metrics(**response["metrics"]), )
[docs] def get_actions_list( self, load_balancer: LoadBalancer | BoundLoadBalancer, status: list[str] | None = None, sort: list[str] | None = None, page: int | None = None, per_page: int | None = None, ) -> ActionsPageResult: """Returns all action objects for a Load Balancer. :param load_balancer: :class:`BoundLoadBalancer <hcloud.load_balancers.client.BoundLoadBalancer>` or :class:`LoadBalancer <hcloud.load_balancers.domain.LoadBalancer>` :param status: List[str] (optional) Response will have only actions with specified statuses. Choices: `running` `success` `error` :param sort: List[str] (optional) Specify how the results are sorted. Choices: `id` `id:asc` `id:desc` `command` `command:asc` `command:desc` `status` `status:asc` `status:desc` `progress` `progress:asc` `progress:desc` `started` `started:asc` `started:desc` `finished` `finished:asc` `finished:desc` :param page: int (optional) Specifies the page to fetch :param per_page: int (optional) Specifies how many results are returned by page :return: (List[:class:`BoundAction <hcloud.actions.client.BoundAction>`], :class:`Meta <hcloud.core.domain.Meta>`) """ params: dict[str, Any] = {} if status is not None: params["status"] = status if sort is not None: params["sort"] = sort if page is not None: params["page"] = page if per_page is not None: params["per_page"] = per_page response = self._client.request( url=f"/load_balancers/{load_balancer.id}/actions", method="GET", params=params, ) actions = [ BoundAction(self._client.actions, action_data) for action_data in response["actions"] ] return ActionsPageResult(actions, Meta.parse_meta(response))
[docs] def get_actions( self, load_balancer: LoadBalancer | BoundLoadBalancer, status: list[str] | None = None, sort: list[str] | None = None, ) -> 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 self._iter_pages( self.get_actions_list, load_balancer, status=status, sort=sort, )
[docs] def add_service( self, load_balancer: LoadBalancer | BoundLoadBalancer, service: LoadBalancerService, ) -> 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: dict[str, Any] = service.to_payload() response = self._client.request( url=f"/load_balancers/{load_balancer.id}/actions/add_service", method="POST", json=data, ) return BoundAction(self._client.actions, response["action"])
[docs] def update_service( self, load_balancer: LoadBalancer | BoundLoadBalancer, service: LoadBalancerService, ) -> 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: dict[str, Any] = service.to_payload() response = self._client.request( url=f"/load_balancers/{load_balancer.id}/actions/update_service", method="POST", json=data, ) return BoundAction(self._client.actions, response["action"])
[docs] def delete_service( self, load_balancer: LoadBalancer | BoundLoadBalancer, service: LoadBalancerService, ) -> 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: dict[str, Any] = {"listen_port": service.listen_port} response = self._client.request( url=f"/load_balancers/{load_balancer.id}/actions/delete_service", method="POST", json=data, ) return BoundAction(self._client.actions, response["action"])
[docs] def add_target( self, load_balancer: LoadBalancer | BoundLoadBalancer, target: LoadBalancerTarget, ) -> 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: dict[str, Any] = target.to_payload() response = self._client.request( url=f"/load_balancers/{load_balancer.id}/actions/add_target", method="POST", json=data, ) return BoundAction(self._client.actions, response["action"])
[docs] def remove_target( self, load_balancer: LoadBalancer | BoundLoadBalancer, target: LoadBalancerTarget, ) -> 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: dict[str, Any] = target.to_payload() # Do not send use_private_ip on remove_target data.pop("use_private_ip", None) response = self._client.request( url=f"/load_balancers/{load_balancer.id}/actions/remove_target", method="POST", json=data, ) return BoundAction(self._client.actions, response["action"])
[docs] def change_algorithm( self, load_balancer: LoadBalancer | BoundLoadBalancer, algorithm: LoadBalancerAlgorithm, ) -> 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: dict[str, Any] = {"type": algorithm.type} response = self._client.request( url=f"/load_balancers/{load_balancer.id}/actions/change_algorithm", method="POST", json=data, ) return BoundAction(self._client.actions, response["action"])
[docs] def change_dns_ptr( self, load_balancer: LoadBalancer | BoundLoadBalancer, ip: str, dns_ptr: 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=f"/load_balancers/{load_balancer.id}/actions/change_dns_ptr", method="POST", json={"ip": ip, "dns_ptr": dns_ptr}, ) return BoundAction(self._client.actions, response["action"])
[docs] def change_protection( self, load_balancer: LoadBalancer | BoundLoadBalancer, delete: bool | None = None, ) -> 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: dict[str, Any] = {} if delete is not None: data.update({"delete": delete}) response = self._client.request( url=f"/load_balancers/{load_balancer.id}/actions/change_protection", method="POST", json=data, ) return BoundAction(self._client.actions, response["action"])
[docs] def attach_to_network( self, load_balancer: LoadBalancer | BoundLoadBalancer, network: Network | BoundNetwork, ip: str | None = None, ) -> BoundAction: """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: dict[str, Any] = {"network": network.id} if ip is not None: data.update({"ip": ip}) response = self._client.request( url=f"/load_balancers/{load_balancer.id}/actions/attach_to_network", method="POST", json=data, ) return BoundAction(self._client.actions, response["action"])
[docs] def detach_from_network( self, load_balancer: LoadBalancer | BoundLoadBalancer, network: 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: dict[str, Any] = {"network": network.id} response = self._client.request( url=f"/load_balancers/{load_balancer.id}/actions/detach_from_network", method="POST", json=data, ) return BoundAction(self._client.actions, response["action"])
[docs] def enable_public_interface( self, load_balancer: 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=f"/load_balancers/{load_balancer.id}/actions/enable_public_interface", method="POST", ) return BoundAction(self._client.actions, response["action"])
[docs] def disable_public_interface( self, load_balancer: 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=f"/load_balancers/{load_balancer.id}/actions/disable_public_interface", method="POST", ) return BoundAction(self._client.actions, response["action"])
[docs] def change_type( self, load_balancer: LoadBalancer | BoundLoadBalancer, load_balancer_type: 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: dict[str, Any] = {"load_balancer_type": load_balancer_type.id_or_name} response = self._client.request( url=f"/load_balancers/{load_balancer.id}/actions/change_type", method="POST", json=data, ) return BoundAction(self._client.actions, response["action"])