diff --git a/plugins/module_utils/vendor/hcloud/_client.py b/plugins/module_utils/vendor/hcloud/_client.py index 0875dafa..257d361c 100644 --- a/plugins/module_utils/vendor/hcloud/_client.py +++ b/plugins/module_utils/vendor/hcloud/_client.py @@ -45,7 +45,7 @@ def __init__( poll_interval: int = 1, timeout: float | tuple[float, float] | None = None, ): - """Create an new Client instance + """Create a new Client instance :param token: Hetzner Cloud API token :param api_endpoint: Hetzner Cloud API endpoint diff --git a/plugins/module_utils/vendor/hcloud/_version.py b/plugins/module_utils/vendor/hcloud/_version.py index 112641f0..b65a355b 100644 --- a/plugins/module_utils/vendor/hcloud/_version.py +++ b/plugins/module_utils/vendor/hcloud/_version.py @@ -1,3 +1,3 @@ from __future__ import annotations -VERSION = "1.28.0" # x-release-please-version +VERSION = "1.29.0" # x-release-please-version diff --git a/plugins/module_utils/vendor/hcloud/actions/client.py b/plugins/module_utils/vendor/hcloud/actions/client.py index 2433bcdc..a188f624 100644 --- a/plugins/module_utils/vendor/hcloud/actions/client.py +++ b/plugins/module_utils/vendor/hcloud/actions/client.py @@ -11,7 +11,7 @@ from .._client import Client -class BoundAction(BoundModelBase): +class BoundAction(BoundModelBase, Action): _client: ActionsClient model = Action @@ -27,6 +27,7 @@ def wait_until_finished(self, max_retries: int = 100) -> None: while self.status == Action.STATUS_RUNNING: if max_retries > 0: self.reload() + # pylint: disable=protected-access time.sleep(self._client._client.poll_interval) max_retries = max_retries - 1 else: diff --git a/plugins/module_utils/vendor/hcloud/certificates/client.py b/plugins/module_utils/vendor/hcloud/certificates/client.py index e368a952..a5fe1d77 100644 --- a/plugins/module_utils/vendor/hcloud/certificates/client.py +++ b/plugins/module_utils/vendor/hcloud/certificates/client.py @@ -15,7 +15,7 @@ from .._client import Client -class BoundCertificate(BoundModelBase): +class BoundCertificate(BoundModelBase, Certificate): _client: CertificatesClient model = Certificate diff --git a/plugins/module_utils/vendor/hcloud/core/client.py b/plugins/module_utils/vendor/hcloud/core/client.py index 16c37e5d..1d4edfd1 100644 --- a/plugins/module_utils/vendor/hcloud/core/client.py +++ b/plugins/module_utils/vendor/hcloud/core/client.py @@ -45,6 +45,7 @@ def _iter_pages( # type: ignore[no-untyped-def] def _get_first_by(self, **kwargs): # type: ignore[no-untyped-def] assert hasattr(self, "get_list") + # pylint: disable=no-member entities, _ = self.get_list(**kwargs) return entities[0] if entities else None diff --git a/plugins/module_utils/vendor/hcloud/core/domain.py b/plugins/module_utils/vendor/hcloud/core/domain.py index 21aed341..692f7488 100644 --- a/plugins/module_utils/vendor/hcloud/core/domain.py +++ b/plugins/module_utils/vendor/hcloud/core/domain.py @@ -6,6 +6,9 @@ class BaseDomain: @classmethod def from_dict(cls, data: dict): # type: ignore[no-untyped-def] + """ + Build the domain object from the data dict. + """ supported_data = {k: v for k, v in data.items() if k in cls.__slots__} return cls(**supported_data) @@ -22,12 +25,14 @@ class DomainIdentityMixin: @property def id_or_name(self) -> int | str: + """ + Return the first defined value, and fails if none is defined. + """ if self.id is not None: return self.id - elif self.name is not None: + if self.name is not None: return self.name - else: - raise ValueError("id or name must be set") + raise ValueError("id or name must be set") class Pagination(BaseDomain): @@ -65,6 +70,9 @@ def __init__(self, pagination: Pagination | None = None): @classmethod def parse_meta(cls, response: dict) -> Meta | None: + """ + If present, extract the meta details from the response and return a meta object. + """ meta = None if response and "meta" in response: meta = cls() diff --git a/plugins/module_utils/vendor/hcloud/datacenters/client.py b/plugins/module_utils/vendor/hcloud/datacenters/client.py index ab5aa5e0..1be1e126 100644 --- a/plugins/module_utils/vendor/hcloud/datacenters/client.py +++ b/plugins/module_utils/vendor/hcloud/datacenters/client.py @@ -11,7 +11,7 @@ from .._client import Client -class BoundDatacenter(BoundModelBase): +class BoundDatacenter(BoundModelBase, Datacenter): _client: DatacentersClient model = Datacenter diff --git a/plugins/module_utils/vendor/hcloud/datacenters/domain.py b/plugins/module_utils/vendor/hcloud/datacenters/domain.py index 1c59bfa9..05d5f793 100644 --- a/plugins/module_utils/vendor/hcloud/datacenters/domain.py +++ b/plugins/module_utils/vendor/hcloud/datacenters/domain.py @@ -36,7 +36,7 @@ def __init__( self.server_types = server_types -class DatacenterServerTypes: +class DatacenterServerTypes(BaseDomain): """DatacenterServerTypes Domain :param available: List[:class:`BoundServerTypes `] diff --git a/plugins/module_utils/vendor/hcloud/firewalls/__init__.py b/plugins/module_utils/vendor/hcloud/firewalls/__init__.py index 42bde369..5205d766 100644 --- a/plugins/module_utils/vendor/hcloud/firewalls/__init__.py +++ b/plugins/module_utils/vendor/hcloud/firewalls/__init__.py @@ -5,6 +5,7 @@ CreateFirewallResponse, Firewall, FirewallResource, + FirewallResourceAppliedToResources, FirewallResourceLabelSelector, FirewallRule, ) diff --git a/plugins/module_utils/vendor/hcloud/firewalls/client.py b/plugins/module_utils/vendor/hcloud/firewalls/client.py index b9b341b6..fbcd1008 100644 --- a/plugins/module_utils/vendor/hcloud/firewalls/client.py +++ b/plugins/module_utils/vendor/hcloud/firewalls/client.py @@ -8,6 +8,7 @@ CreateFirewallResponse, Firewall, FirewallResource, + FirewallResourceAppliedToResources, FirewallResourceLabelSelector, FirewallRule, ) @@ -16,7 +17,7 @@ from .._client import Client -class BoundFirewall(BoundModelBase): +class BoundFirewall(BoundModelBase, Firewall): _client: FirewallsClient model = Firewall @@ -39,29 +40,53 @@ def __init__(self, client: FirewallsClient, data: dict, complete: bool = True): applied_to = data.get("applied_to", []) if applied_to: + # pylint: disable=import-outside-toplevel from ..servers import BoundServer - ats = [] - for a in applied_to: - if a["type"] == FirewallResource.TYPE_SERVER: - ats.append( + data_applied_to = [] + for firewall_resource in applied_to: + applied_to_resources = None + if firewall_resource.get("applied_to_resources"): + applied_to_resources = [ + FirewallResourceAppliedToResources( + type=resource["type"], + server=( + BoundServer( + client._client.servers, + resource.get("server"), + complete=False, + ) + if resource.get("server") is not None + else None + ), + ) + for resource in firewall_resource.get("applied_to_resources") + ] + + if firewall_resource["type"] == FirewallResource.TYPE_SERVER: + data_applied_to.append( FirewallResource( - type=a["type"], + type=firewall_resource["type"], server=BoundServer( - client._client.servers, a["server"], complete=False + client._client.servers, + firewall_resource["server"], + complete=False, ), + applied_to_resources=applied_to_resources, ) ) - elif a["type"] == FirewallResource.TYPE_LABEL_SELECTOR: - ats.append( + elif firewall_resource["type"] == FirewallResource.TYPE_LABEL_SELECTOR: + data_applied_to.append( FirewallResource( - type=a["type"], + type=firewall_resource["type"], label_selector=FirewallResourceLabelSelector( - selector=a["label_selector"]["selector"] + selector=firewall_resource["label_selector"]["selector"] ), + applied_to_resources=applied_to_resources, ) ) - data["applied_to"] = ats + + data["applied_to"] = data_applied_to super().__init__(client, data, complete) diff --git a/plugins/module_utils/vendor/hcloud/firewalls/domain.py b/plugins/module_utils/vendor/hcloud/firewalls/domain.py index 0c3aa916..5ce9281d 100644 --- a/plugins/module_utils/vendor/hcloud/firewalls/domain.py +++ b/plugins/module_utils/vendor/hcloud/firewalls/domain.py @@ -51,7 +51,7 @@ def __init__( self.created = isoparse(created) if created else None -class FirewallRule: +class FirewallRule(BaseDomain): """Firewall Rule Domain :param direction: str @@ -111,6 +111,9 @@ def __init__( self.description = description def to_payload(self) -> dict[str, Any]: + """ + Generates the request payload from this domain object. + """ payload: dict[str, Any] = { "direction": self.direction, "protocol": self.protocol, @@ -125,7 +128,7 @@ def to_payload(self) -> dict[str, Any]: return payload -class FirewallResource: +class FirewallResource(BaseDomain): """Firewall Used By Domain :param type: str @@ -134,9 +137,11 @@ class FirewallResource: Server the Firewall is applied to :param label_selector: Optional[FirewallResourceLabelSelector] Label Selector for Servers the Firewall should be applied to + :param applied_to_resources: (read-only) List of effective resources the firewall is + applied to. """ - __slots__ = ("type", "server", "label_selector") + __slots__ = ("type", "server", "label_selector", "applied_to_resources") TYPE_SERVER = "server" """Firewall Used By Type Server""" @@ -148,12 +153,17 @@ def __init__( type: str, server: Server | BoundServer | None = None, label_selector: FirewallResourceLabelSelector | None = None, + applied_to_resources: list[FirewallResourceAppliedToResources] | None = None, ): self.type = type self.server = server self.label_selector = label_selector + self.applied_to_resources = applied_to_resources def to_payload(self) -> dict[str, Any]: + """ + Generates the request payload from this domain object. + """ payload: dict[str, Any] = {"type": self.type} if self.server is not None: payload["server"] = {"id": self.server.id} @@ -163,6 +173,24 @@ def to_payload(self) -> dict[str, Any]: return payload +class FirewallResourceAppliedToResources(BaseDomain): + """Firewall Resource applied to Domain + + :param type: Type of resource referenced + :param server: Server the Firewall is applied to + """ + + __slots__ = ("type", "server") + + def __init__( + self, + type: str, + server: BoundServer | None = None, + ): + self.type = type + self.server = server + + class FirewallResourceLabelSelector(BaseDomain): """FirewallResourceLabelSelector Domain diff --git a/plugins/module_utils/vendor/hcloud/floating_ips/client.py b/plugins/module_utils/vendor/hcloud/floating_ips/client.py index 49d7c8e5..00600e48 100644 --- a/plugins/module_utils/vendor/hcloud/floating_ips/client.py +++ b/plugins/module_utils/vendor/hcloud/floating_ips/client.py @@ -13,12 +13,13 @@ from ..servers import BoundServer, Server -class BoundFloatingIP(BoundModelBase): +class BoundFloatingIP(BoundModelBase, FloatingIP): _client: FloatingIPsClient model = FloatingIP def __init__(self, client: FloatingIPsClient, data: dict, complete: bool = True): + # pylint: disable=import-outside-toplevel from ..servers import BoundServer server = data.get("server") diff --git a/plugins/module_utils/vendor/hcloud/hcloud.py b/plugins/module_utils/vendor/hcloud/hcloud.py index df67a5be..9de1cfe5 100644 --- a/plugins/module_utils/vendor/hcloud/hcloud.py +++ b/plugins/module_utils/vendor/hcloud/hcloud.py @@ -8,4 +8,5 @@ stacklevel=2, ) +# pylint: disable=wildcard-import,wrong-import-position,unused-wildcard-import from ._client import * # noqa diff --git a/plugins/module_utils/vendor/hcloud/helpers/labels.py b/plugins/module_utils/vendor/hcloud/helpers/labels.py index d5af8bcc..36041578 100644 --- a/plugins/module_utils/vendor/hcloud/helpers/labels.py +++ b/plugins/module_utils/vendor/hcloud/helpers/labels.py @@ -18,10 +18,10 @@ def validate(labels: dict[str, str]) -> bool: :return: bool """ - for k, v in labels.items(): - if LabelValidator.KEY_REGEX.match(k) is None: + for key, value in labels.items(): + if LabelValidator.KEY_REGEX.match(key) is None: return False - if LabelValidator.VALUE_REGEX.match(v) is None: + if LabelValidator.VALUE_REGEX.match(value) is None: return False return True @@ -32,9 +32,15 @@ def validate_verbose(labels: dict[str, str]) -> tuple[bool, str]: :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" + for key, value in labels.items(): + if LabelValidator.KEY_REGEX.match(key) is None: + return ( + False, + f"label key {key} is not correctly formatted", + ) + if LabelValidator.VALUE_REGEX.match(value) is None: + return ( + False, + f"label value {value} (key: {key}) is not correctly formatted", + ) return True, "" diff --git a/plugins/module_utils/vendor/hcloud/images/client.py b/plugins/module_utils/vendor/hcloud/images/client.py index dee910f0..65b7546a 100644 --- a/plugins/module_utils/vendor/hcloud/images/client.py +++ b/plugins/module_utils/vendor/hcloud/images/client.py @@ -10,12 +10,13 @@ from .._client import Client -class BoundImage(BoundModelBase): +class BoundImage(BoundModelBase, Image): _client: ImagesClient model = Image def __init__(self, client: ImagesClient, data: dict): + # pylint: disable=import-outside-toplevel from ..servers import BoundServer created_from = data.get("created_from") diff --git a/plugins/module_utils/vendor/hcloud/images/domain.py b/plugins/module_utils/vendor/hcloud/images/domain.py index e55de7fd..9a58a3cc 100644 --- a/plugins/module_utils/vendor/hcloud/images/domain.py +++ b/plugins/module_utils/vendor/hcloud/images/domain.py @@ -74,6 +74,7 @@ class Image(BaseDomain, DomainIdentityMixin): "deprecated", ) + # pylint: disable=too-many-locals def __init__( self, id: int | None = None, diff --git a/plugins/module_utils/vendor/hcloud/isos/client.py b/plugins/module_utils/vendor/hcloud/isos/client.py index 1ab5fc9f..cc46af7f 100644 --- a/plugins/module_utils/vendor/hcloud/isos/client.py +++ b/plugins/module_utils/vendor/hcloud/isos/client.py @@ -10,7 +10,7 @@ from .._client import Client -class BoundIso(BoundModelBase): +class BoundIso(BoundModelBase, Iso): _client: IsosClient model = Iso diff --git a/plugins/module_utils/vendor/hcloud/load_balancer_types/client.py b/plugins/module_utils/vendor/hcloud/load_balancer_types/client.py index fa91c01d..9a83dc70 100644 --- a/plugins/module_utils/vendor/hcloud/load_balancer_types/client.py +++ b/plugins/module_utils/vendor/hcloud/load_balancer_types/client.py @@ -9,7 +9,7 @@ from .._client import Client -class BoundLoadBalancerType(BoundModelBase): +class BoundLoadBalancerType(BoundModelBase, LoadBalancerType): _client: LoadBalancerTypesClient model = LoadBalancerType diff --git a/plugins/module_utils/vendor/hcloud/load_balancers/client.py b/plugins/module_utils/vendor/hcloud/load_balancers/client.py index 72325f1d..56b93c8b 100644 --- a/plugins/module_utils/vendor/hcloud/load_balancers/client.py +++ b/plugins/module_utils/vendor/hcloud/load_balancers/client.py @@ -34,11 +34,12 @@ from ..networks import Network -class BoundLoadBalancer(BoundModelBase): +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: diff --git a/plugins/module_utils/vendor/hcloud/load_balancers/domain.py b/plugins/module_utils/vendor/hcloud/load_balancers/domain.py index 9071daab..0b8450d6 100644 --- a/plugins/module_utils/vendor/hcloud/load_balancers/domain.py +++ b/plugins/module_utils/vendor/hcloud/load_balancers/domain.py @@ -72,6 +72,7 @@ class LoadBalancer(BaseDomain): "included_traffic", ) + # pylint: disable=too-many-locals def __init__( self, id: int, @@ -140,7 +141,11 @@ def __init__( self.health_check = health_check self.http = http + # pylint: disable=too-many-branches def to_payload(self) -> dict[str, Any]: + """ + Generates the request payload from this domain object. + """ payload: dict[str, Any] = {} if self.protocol is not None: @@ -337,6 +342,9 @@ def __init__( self.health_status = health_status def to_payload(self) -> dict[str, Any]: + """ + Generates the request payload from this domain object. + """ payload: dict[str, Any] = { "type": self.type, } diff --git a/plugins/module_utils/vendor/hcloud/locations/client.py b/plugins/module_utils/vendor/hcloud/locations/client.py index 2e2b6b47..047ad9d4 100644 --- a/plugins/module_utils/vendor/hcloud/locations/client.py +++ b/plugins/module_utils/vendor/hcloud/locations/client.py @@ -9,7 +9,7 @@ from .._client import Client -class BoundLocation(BoundModelBase): +class BoundLocation(BoundModelBase, Location): _client: LocationsClient model = Location diff --git a/plugins/module_utils/vendor/hcloud/networks/client.py b/plugins/module_utils/vendor/hcloud/networks/client.py index 36eaaa40..d819d580 100644 --- a/plugins/module_utils/vendor/hcloud/networks/client.py +++ b/plugins/module_utils/vendor/hcloud/networks/client.py @@ -10,7 +10,7 @@ from .._client import Client -class BoundNetwork(BoundModelBase): +class BoundNetwork(BoundModelBase, Network): _client: NetworksClient model = Network @@ -26,6 +26,7 @@ def __init__(self, client: NetworksClient, data: dict, complete: bool = True): routes = [NetworkRoute.from_dict(route) for route in routes] data["routes"] = routes + # pylint: disable=import-outside-toplevel from ..servers import BoundServer servers = data.get("servers", []) diff --git a/plugins/module_utils/vendor/hcloud/placement_groups/client.py b/plugins/module_utils/vendor/hcloud/placement_groups/client.py index b551904f..fcfd86ae 100644 --- a/plugins/module_utils/vendor/hcloud/placement_groups/client.py +++ b/plugins/module_utils/vendor/hcloud/placement_groups/client.py @@ -10,7 +10,7 @@ from .._client import Client -class BoundPlacementGroup(BoundModelBase): +class BoundPlacementGroup(BoundModelBase, PlacementGroup): _client: PlacementGroupsClient model = PlacementGroup diff --git a/plugins/module_utils/vendor/hcloud/primary_ips/client.py b/plugins/module_utils/vendor/hcloud/primary_ips/client.py index acd2f69e..ece8d88f 100644 --- a/plugins/module_utils/vendor/hcloud/primary_ips/client.py +++ b/plugins/module_utils/vendor/hcloud/primary_ips/client.py @@ -11,12 +11,13 @@ from ..datacenters import BoundDatacenter, Datacenter -class BoundPrimaryIP(BoundModelBase): +class BoundPrimaryIP(BoundModelBase, PrimaryIP): _client: PrimaryIPsClient model = PrimaryIP def __init__(self, client: PrimaryIPsClient, data: dict, complete: bool = True): + # pylint: disable=import-outside-toplevel from ..datacenters import BoundDatacenter datacenter = data.get("datacenter", {}) diff --git a/plugins/module_utils/vendor/hcloud/server_types/client.py b/plugins/module_utils/vendor/hcloud/server_types/client.py index 12cf34a0..31f56a20 100644 --- a/plugins/module_utils/vendor/hcloud/server_types/client.py +++ b/plugins/module_utils/vendor/hcloud/server_types/client.py @@ -9,7 +9,7 @@ from .._client import Client -class BoundServerType(BoundModelBase): +class BoundServerType(BoundModelBase, ServerType): _client: ServerTypesClient model = ServerType diff --git a/plugins/module_utils/vendor/hcloud/servers/client.py b/plugins/module_utils/vendor/hcloud/servers/client.py index d19180c5..5cbd48a2 100644 --- a/plugins/module_utils/vendor/hcloud/servers/client.py +++ b/plugins/module_utils/vendor/hcloud/servers/client.py @@ -42,11 +42,12 @@ from .domain import ServerCreatePublicNetwork -class BoundServer(BoundModelBase): +class BoundServer(BoundModelBase, Server): _client: ServersClient model = Server + # pylint: disable=too-many-locals def __init__(self, client: ServersClient, data: dict, complete: bool = True): datacenter = data.get("datacenter") if datacenter is not None: @@ -540,6 +541,7 @@ def get_by_name(self, name: str) -> BoundServer | None: """ return self._get_first_by(name=name) + # pylint: disable=too-many-branches,too-many-locals def create( self, name: str, diff --git a/plugins/module_utils/vendor/hcloud/servers/domain.py b/plugins/module_utils/vendor/hcloud/servers/domain.py index 09c5526f..b78dd599 100644 --- a/plugins/module_utils/vendor/hcloud/servers/domain.py +++ b/plugins/module_utils/vendor/hcloud/servers/domain.py @@ -107,6 +107,7 @@ class Server(BaseDomain): "placement_group", ) + # pylint: disable=too-many-locals def __init__( self, id: int, diff --git a/plugins/module_utils/vendor/hcloud/ssh_keys/client.py b/plugins/module_utils/vendor/hcloud/ssh_keys/client.py index 1c16f03d..69c1683d 100644 --- a/plugins/module_utils/vendor/hcloud/ssh_keys/client.py +++ b/plugins/module_utils/vendor/hcloud/ssh_keys/client.py @@ -9,7 +9,7 @@ from .._client import Client -class BoundSSHKey(BoundModelBase): +class BoundSSHKey(BoundModelBase, SSHKey): _client: SSHKeysClient model = SSHKey diff --git a/plugins/module_utils/vendor/hcloud/volumes/client.py b/plugins/module_utils/vendor/hcloud/volumes/client.py index 9017ff49..a4709748 100644 --- a/plugins/module_utils/vendor/hcloud/volumes/client.py +++ b/plugins/module_utils/vendor/hcloud/volumes/client.py @@ -13,7 +13,7 @@ from ..servers import BoundServer, Server -class BoundVolume(BoundModelBase): +class BoundVolume(BoundModelBase, Volume): _client: VolumesClient model = Volume @@ -23,6 +23,7 @@ def __init__(self, client: VolumesClient, data: dict, complete: bool = True): if location is not None: data["location"] = BoundLocation(client._client.locations, location) + # pylint: disable=import-outside-toplevel from ..servers import BoundServer server = data.get("server") @@ -254,7 +255,7 @@ def create( if size <= 0: raise ValueError("size must be greater than 0") - if not (bool(location) ^ bool(server)): + if not bool(location) ^ bool(server): raise ValueError("only one of server or location must be provided") data: dict[str, Any] = {"name": name, "size": size} diff --git a/scripts/vendor.py b/scripts/vendor.py index 5102b2a9..f9c86914 100755 --- a/scripts/vendor.py +++ b/scripts/vendor.py @@ -19,7 +19,7 @@ logger = logging.getLogger("vendor") HCLOUD_SOURCE_URL = "https://github.com/hetznercloud/hcloud-python" -HCLOUD_VERSION = "v1.28.0" +HCLOUD_VERSION = "v1.29.0" HCLOUD_VENDOR_PATH = "plugins/module_utils/vendor/hcloud"