diff --git a/plugins/modules/certificate.py b/plugins/modules/certificate.py index 853a271c..53466e48 100644 --- a/plugins/modules/certificate.py +++ b/plugins/modules/certificate.py @@ -202,7 +202,9 @@ def _create_certificate(self): if not self.module.check_mode: try: resp = self.client.certificates.create_managed(**params) - resp.action.wait_until_finished(max_retries=1000) + # Action should take 60 to 90 seconds on average, wait for 5m to + # allow DNS or Let's Encrypt slowdowns. + resp.action.wait_until_finished(max_retries=300) except HCloudException as exception: self.fail_json_hcloud(exception) diff --git a/plugins/modules/floating_ip.py b/plugins/modules/floating_ip.py index 55d1b469..02203612 100644 --- a/plugins/modules/floating_ip.py +++ b/plugins/modules/floating_ip.py @@ -216,7 +216,8 @@ def _create_floating_ip(self): delete_protection = self.module.params.get("delete_protection") if delete_protection is not None: - self.hcloud_floating_ip.change_protection(delete=delete_protection).wait_until_finished() + action = self.hcloud_floating_ip.change_protection(delete=delete_protection) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._mark_as_changed() @@ -261,7 +262,8 @@ def _update_floating_ip(self): delete_protection = self.module.params.get("delete_protection") if delete_protection is not None and delete_protection != self.hcloud_floating_ip.protection["delete"]: if not self.module.check_mode: - self.hcloud_floating_ip.change_protection(delete=delete_protection).wait_until_finished() + action = self.hcloud_floating_ip.change_protection(delete=delete_protection) + action.wait_until_finished() self._mark_as_changed() self._get_floating_ip() diff --git a/plugins/modules/load_balancer.py b/plugins/modules/load_balancer.py index ca005c61..11dbf96f 100644 --- a/plugins/modules/load_balancer.py +++ b/plugins/modules/load_balancer.py @@ -213,12 +213,13 @@ def _create_load_balancer(self): if not self.module.check_mode: resp = self.client.load_balancers.create(**params) - resp.action.wait_until_finished(max_retries=1000) + resp.action.wait_until_finished() delete_protection = self.module.params.get("delete_protection") if delete_protection is not None: self._get_load_balancer() - self.hcloud_load_balancer.change_protection(delete=delete_protection).wait_until_finished() + action = self.hcloud_load_balancer.change_protection(delete=delete_protection) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._mark_as_changed() @@ -235,7 +236,8 @@ def _update_load_balancer(self): delete_protection = self.module.params.get("delete_protection") if delete_protection is not None and delete_protection != self.hcloud_load_balancer.protection["delete"]: if not self.module.check_mode: - self.hcloud_load_balancer.change_protection(delete=delete_protection).wait_until_finished() + action = self.hcloud_load_balancer.change_protection(delete=delete_protection) + action.wait_until_finished() self._mark_as_changed() self._get_load_balancer() @@ -245,9 +247,11 @@ def _update_load_balancer(self): ): if not self.module.check_mode: if disable_public_interface is True: - self.hcloud_load_balancer.disable_public_interface().wait_until_finished() + action = self.hcloud_load_balancer.disable_public_interface() + action.wait_until_finished() else: - self.hcloud_load_balancer.enable_public_interface().wait_until_finished() + action = self.hcloud_load_balancer.enable_public_interface() + action.wait_until_finished() self._mark_as_changed() load_balancer_type = self.module.params.get("load_balancer_type") @@ -259,17 +263,17 @@ def _update_load_balancer(self): if not new_load_balancer_type: self.module.fail_json(msg="unknown load balancer type") if not self.module.check_mode: - self.hcloud_load_balancer.change_type( + action = self.hcloud_load_balancer.change_type( load_balancer_type=new_load_balancer_type, - ).wait_until_finished(max_retries=1000) + ) + action.wait_until_finished() self._mark_as_changed() algorithm = self.module.params.get("algorithm") if algorithm is not None and self.hcloud_load_balancer.algorithm.type != algorithm: - self.hcloud_load_balancer.change_algorithm( - algorithm=LoadBalancerAlgorithm(type=algorithm) - ).wait_until_finished() + action = self.hcloud_load_balancer.change_algorithm(algorithm=LoadBalancerAlgorithm(type=algorithm)) + action.wait_until_finished() self._mark_as_changed() self._get_load_balancer() diff --git a/plugins/modules/load_balancer_network.py b/plugins/modules/load_balancer_network.py index 97dc317b..b6ec486e 100644 --- a/plugins/modules/load_balancer_network.py +++ b/plugins/modules/load_balancer_network.py @@ -139,7 +139,8 @@ def _create_load_balancer_network(self): if not self.module.check_mode: try: - self.hcloud_load_balancer.attach_to_network(**params).wait_until_finished() + action = self.hcloud_load_balancer.attach_to_network(**params) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) @@ -159,9 +160,8 @@ def delete_load_balancer_network(self): if self.hcloud_load_balancer_network is not None and self.hcloud_load_balancer is not None: if not self.module.check_mode: try: - self.hcloud_load_balancer.detach_from_network( - self.hcloud_load_balancer_network.network - ).wait_until_finished() + action = self.hcloud_load_balancer.detach_from_network(self.hcloud_load_balancer_network.network) + action.wait_until_finished() self._mark_as_changed() except HCloudException as exception: self.fail_json_hcloud(exception) diff --git a/plugins/modules/load_balancer_service.py b/plugins/modules/load_balancer_service.py index 8af84a9f..29e37083 100644 --- a/plugins/modules/load_balancer_service.py +++ b/plugins/modules/load_balancer_service.py @@ -368,9 +368,8 @@ def _create_load_balancer_service(self): if not self.module.check_mode: try: - self.hcloud_load_balancer.add_service(LoadBalancerService(**params)).wait_until_finished( - max_retries=1000 - ) + action = self.hcloud_load_balancer.add_service(LoadBalancerService(**params)) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._mark_as_changed() @@ -464,9 +463,8 @@ def _update_load_balancer_service(self): changed = True if not self.module.check_mode: - self.hcloud_load_balancer.update_service(LoadBalancerService(**params)).wait_until_finished( - max_retries=1000 - ) + action = self.hcloud_load_balancer.update_service(LoadBalancerService(**params)) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._get_load_balancer() @@ -492,9 +490,8 @@ def delete_load_balancer_service(self): if self.hcloud_load_balancer_service is not None: if not self.module.check_mode: try: - self.hcloud_load_balancer.delete_service(self.hcloud_load_balancer_service).wait_until_finished( - max_retries=1000 - ) + action = self.hcloud_load_balancer.delete_service(self.hcloud_load_balancer_service) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._mark_as_changed() diff --git a/plugins/modules/load_balancer_target.py b/plugins/modules/load_balancer_target.py index e58f60e5..c392ae71 100644 --- a/plugins/modules/load_balancer_target.py +++ b/plugins/modules/load_balancer_target.py @@ -224,7 +224,8 @@ def _create_load_balancer_target(self): if not self.module.check_mode: try: - self.hcloud_load_balancer.add_target(**params).wait_until_finished() + action = self.hcloud_load_balancer.add_target(**params) + action.wait_until_finished() except APIException as exception: if exception.code == "locked" or exception.code == "conflict": self._create_load_balancer_target() @@ -269,7 +270,8 @@ def delete_load_balancer_target(self): use_private_ip=False, ) try: - self.hcloud_load_balancer.remove_target(target).wait_until_finished() + action = self.hcloud_load_balancer.remove_target(target) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._mark_as_changed() diff --git a/plugins/modules/network.py b/plugins/modules/network.py index f7be7a98..92fe9461 100644 --- a/plugins/modules/network.py +++ b/plugins/modules/network.py @@ -164,7 +164,8 @@ def _create_network(self): delete_protection = self.module.params.get("delete_protection") if delete_protection is not None: self._get_network() - self.hcloud_network.change_protection(delete=delete_protection).wait_until_finished() + action = self.hcloud_network.change_protection(delete=delete_protection) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._mark_as_changed() @@ -188,7 +189,8 @@ def _update_network(self): ip_range = self.module.params.get("ip_range") if ip_range is not None and ip_range != self.hcloud_network.ip_range: if not self.module.check_mode: - self.hcloud_network.change_ip_range(ip_range=ip_range).wait_until_finished() + action = self.hcloud_network.change_ip_range(ip_range=ip_range) + action.wait_until_finished() self._mark_as_changed() expose_routes_to_vswitch = self.module.params.get("expose_routes_to_vswitch") @@ -203,7 +205,8 @@ def _update_network(self): delete_protection = self.module.params.get("delete_protection") if delete_protection is not None and delete_protection != self.hcloud_network.protection["delete"]: if not self.module.check_mode: - self.hcloud_network.change_protection(delete=delete_protection).wait_until_finished() + action = self.hcloud_network.change_protection(delete=delete_protection) + action.wait_until_finished() self._mark_as_changed() except HCloudException as exception: self.fail_json_hcloud(exception) diff --git a/plugins/modules/primary_ip.py b/plugins/modules/primary_ip.py index 0c122ad4..08bcea49 100644 --- a/plugins/modules/primary_ip.py +++ b/plugins/modules/primary_ip.py @@ -232,7 +232,8 @@ def _create_primary_ip(self): delete_protection = self.module.params.get("delete_protection") if delete_protection is not None: - self.hcloud_primary_ip.change_protection(delete=delete_protection).wait_until_finished() + action = self.hcloud_primary_ip.change_protection(delete=delete_protection) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._mark_as_changed() @@ -258,7 +259,8 @@ def _update_primary_ip(self): delete_protection = self.module.params.get("delete_protection") if delete_protection is not None and delete_protection != self.hcloud_primary_ip.protection["delete"]: if not self.module.check_mode: - self.hcloud_primary_ip.change_protection(delete=delete_protection).wait_until_finished() + action = self.hcloud_primary_ip.change_protection(delete=delete_protection) + action.wait_until_finished() self._mark_as_changed() self._get_primary_ip() diff --git a/plugins/modules/rdns.py b/plugins/modules/rdns.py index ef167b91..4e21f3e9 100644 --- a/plugins/modules/rdns.py +++ b/plugins/modules/rdns.py @@ -276,7 +276,8 @@ def _create_rdns(self): if not self.module.check_mode: try: - self.hcloud_resource.change_dns_ptr(**params).wait_until_finished() + action = self.hcloud_resource.change_dns_ptr(**params) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._mark_as_changed() @@ -293,7 +294,8 @@ def _update_rdns(self): if not self.module.check_mode: try: - self.hcloud_resource.change_dns_ptr(**params).wait_until_finished() + action = self.hcloud_resource.change_dns_ptr(**params) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._mark_as_changed() diff --git a/plugins/modules/route.py b/plugins/modules/route.py index 3529f686..37ff50b0 100644 --- a/plugins/modules/route.py +++ b/plugins/modules/route.py @@ -129,7 +129,8 @@ def _create_route(self): if not self.module.check_mode: try: - self.hcloud_network.add_route(route=route).wait_until_finished() + action = self.hcloud_network.add_route(route=route) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) @@ -149,7 +150,8 @@ def delete_route(self): if self.hcloud_route is not None and self.hcloud_network is not None: if not self.module.check_mode: try: - self.hcloud_network.delete_route(self.hcloud_route).wait_until_finished() + action = self.hcloud_network.delete_route(self.hcloud_route) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._mark_as_changed() diff --git a/plugins/modules/server.py b/plugins/modules/server.py index 1579e662..d7bae3fc 100644 --- a/plugins/modules/server.py +++ b/plugins/modules/server.py @@ -469,7 +469,9 @@ def _create_server(self): try: resp = self.client.servers.create(**params) self.result["root_password"] = resp.root_password - resp.action.wait_until_finished(max_retries=1000) + # Action should take 60 to 90 seconds on average, but can be >10m when creating a + # server from a custom images + resp.action.wait_until_finished(max_retries=1800) for action in resp.next_actions: action.wait_until_finished() @@ -481,16 +483,18 @@ def _create_server(self): backups = self.module.params.get("backups") if backups: self._get_server() - self.hcloud_server.enable_backup().wait_until_finished() + action = self.hcloud_server.enable_backup() + action.wait_until_finished() delete_protection = self.module.params.get("delete_protection") rebuild_protection = self.module.params.get("rebuild_protection") if delete_protection is not None and rebuild_protection is not None: self._get_server() - self.hcloud_server.change_protection( + action = self.hcloud_server.change_protection( delete=delete_protection, rebuild=rebuild_protection, - ).wait_until_finished() + ) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._mark_as_changed() @@ -568,17 +572,20 @@ def _update_server(self) -> None: self._mark_as_changed() elif not rescue_mode and self.hcloud_server.rescue_enabled is True: if not self.module.check_mode: - self.hcloud_server.disable_rescue().wait_until_finished() + action = self.hcloud_server.disable_rescue() + action.wait_until_finished() self._mark_as_changed() backups = self.module.params.get("backups") if backups and self.hcloud_server.backup_window is None: if not self.module.check_mode: - self.hcloud_server.enable_backup().wait_until_finished() + action = self.hcloud_server.enable_backup() + action.wait_until_finished() self._mark_as_changed() elif backups is not None and not backups and self.hcloud_server.backup_window is not None: if not self.module.check_mode: - self.hcloud_server.disable_backup().wait_until_finished() + action = self.hcloud_server.disable_backup() + action.wait_until_finished() self._mark_as_changed() if self.module.params.get("firewalls") is not None: @@ -612,10 +619,11 @@ def _update_server(self) -> None: or rebuild_protection != self.hcloud_server.protection["rebuild"] ): if not self.module.check_mode: - self.hcloud_server.change_protection( + action = self.hcloud_server.change_protection( delete=delete_protection, rebuild=rebuild_protection, - ).wait_until_finished() + ) + action.wait_until_finished() self._mark_as_changed() self._get_server() except HCloudException as exception: @@ -636,7 +644,8 @@ def _update_server_placement_group(self) -> None: # Remove if current is defined if current is not None: if not self.module.check_mode: - self.hcloud_server.remove_from_placement_group().wait_until_finished() + action = self.hcloud_server.remove_from_placement_group() + action.wait_until_finished() self._mark_as_changed() # Return if parameter is falsy @@ -646,7 +655,8 @@ def _update_server_placement_group(self) -> None: # Assign new self.stop_server_if_forced() if not self.module.check_mode: - self.hcloud_server.add_to_placement_group(placement_group).wait_until_finished() + action = self.hcloud_server.add_to_placement_group(placement_group) + action.wait_until_finished() self._mark_as_changed() def _update_server_server_type(self) -> None: @@ -662,14 +672,16 @@ def _update_server_server_type(self) -> None: self.stop_server_if_forced() upgrade_disk = self.module.params.get("upgrade_disk") - # Upgrading the disk takes some more time - upgrade_timeout = 1000 if upgrade_disk else 100 + # Upgrading a server takes 160 seconds on average, upgrading the disk should + # take more time + upgrade_timeout = 600 if upgrade_disk else 180 if not self.module.check_mode: - self.hcloud_server.change_type( + action = self.hcloud_server.change_type( server_type=self._get_server_type(), upgrade_disk=upgrade_disk, - ).wait_until_finished(upgrade_timeout) + ) + action.wait_until_finished(max_retries=upgrade_timeout) self._mark_as_changed() def _update_server_ip(self, kind: Literal["ipv4", "ipv6"]) -> None: @@ -689,7 +701,8 @@ def _update_server_ip(self, kind: Literal["ipv4", "ipv6"]) -> None: if current is not None: self.stop_server_if_forced() if not self.module.check_mode: - self.client.primary_ips.unassign(current).wait_until_finished() + action = self.client.primary_ips.unassign(current) + action.wait_until_finished() self._mark_as_changed() # Return if parameter is falsy or resource is disabled @@ -699,11 +712,12 @@ def _update_server_ip(self, kind: Literal["ipv4", "ipv6"]) -> None: # Assign new self.stop_server_if_forced() if not self.module.check_mode: - self.client.primary_ips.assign( + action = self.client.primary_ips.assign( primary_ip, assignee_id=self.hcloud_server.id, assignee_type="server", - ).wait_until_finished() + ) + action.wait_until_finished() self._mark_as_changed() def _update_server_networks(self) -> None: @@ -815,7 +829,8 @@ def start_server(self): if self.hcloud_server: if self.hcloud_server.status != Server.STATUS_RUNNING: if not self.module.check_mode: - self.client.servers.power_on(self.hcloud_server).wait_until_finished() + action = self.client.servers.power_on(self.hcloud_server) + action.wait_until_finished() self._mark_as_changed() self._get_server() except HCloudException as exception: @@ -826,7 +841,8 @@ def stop_server(self): if self.hcloud_server: if self.hcloud_server.status != Server.STATUS_OFF: if not self.module.check_mode: - self.client.servers.power_off(self.hcloud_server).wait_until_finished() + action = self.client.servers.power_off(self.hcloud_server) + action.wait_until_finished() self._mark_as_changed() self._get_server() except HCloudException as exception: @@ -872,7 +888,8 @@ def delete_server(self): self._get_server() if self.hcloud_server is not None: if not self.module.check_mode: - self.client.servers.delete(self.hcloud_server).wait_until_finished() + action = self.client.servers.delete(self.hcloud_server) + action.wait_until_finished() self._mark_as_changed() self.hcloud_server = None except HCloudException as exception: diff --git a/plugins/modules/server_network.py b/plugins/modules/server_network.py index 872a501d..bc6dec42 100644 --- a/plugins/modules/server_network.py +++ b/plugins/modules/server_network.py @@ -164,7 +164,8 @@ def _create_server_network(self): if not self.module.check_mode: try: - self.hcloud_server.attach_to_network(**params).wait_until_finished() + action = self.hcloud_server.attach_to_network(**params) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) @@ -182,7 +183,8 @@ def _update_server_network(self): if not self.module.check_mode: try: - self.hcloud_server.change_alias_ips(**params).wait_until_finished() + action = self.hcloud_server.change_alias_ips(**params) + action.wait_until_finished() except APIException as exception: self.fail_json_hcloud(exception) @@ -204,7 +206,8 @@ def delete_server_network(self): if self.hcloud_server_network is not None and self.hcloud_server is not None: if not self.module.check_mode: try: - self.hcloud_server.detach_from_network(self.hcloud_server_network.network).wait_until_finished() + action = self.hcloud_server.detach_from_network(self.hcloud_server_network.network) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._mark_as_changed() diff --git a/plugins/modules/subnetwork.py b/plugins/modules/subnetwork.py index 9c4695e8..6f7feeaa 100644 --- a/plugins/modules/subnetwork.py +++ b/plugins/modules/subnetwork.py @@ -173,7 +173,8 @@ def _create_subnetwork(self): if not self.module.check_mode: try: - self.hcloud_network.add_subnet(subnet=NetworkSubnet(**params)).wait_until_finished() + action = self.hcloud_network.add_subnet(subnet=NetworkSubnet(**params)) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) @@ -193,7 +194,8 @@ def delete_subnetwork(self): if self.hcloud_subnetwork is not None and self.hcloud_network is not None: if not self.module.check_mode: try: - self.hcloud_network.delete_subnet(self.hcloud_subnetwork).wait_until_finished() + action = self.hcloud_network.delete_subnet(self.hcloud_subnetwork) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._mark_as_changed() diff --git a/plugins/modules/volume.py b/plugins/modules/volume.py index 02971d28..1bcb4425 100644 --- a/plugins/modules/volume.py +++ b/plugins/modules/volume.py @@ -216,7 +216,8 @@ def _create_volume(self): delete_protection = self.module.params.get("delete_protection") if delete_protection is not None: self._get_volume() - self.hcloud_volume.change_protection(delete=delete_protection).wait_until_finished() + action = self.hcloud_volume.change_protection(delete=delete_protection) + action.wait_until_finished() except HCloudException as exception: self.fail_json_hcloud(exception) self._mark_as_changed() @@ -228,7 +229,8 @@ def _update_volume(self): if size: if self.hcloud_volume.size < size: if not self.module.check_mode: - self.hcloud_volume.resize(size).wait_until_finished() + action = self.hcloud_volume.resize(size) + action.wait_until_finished() self._mark_as_changed() elif self.hcloud_volume.size > size: self.module.warn("Shrinking of volumes is not supported") @@ -239,12 +241,14 @@ def _update_volume(self): if self.hcloud_volume.server is None or self.hcloud_volume.server.name != server.name: if not self.module.check_mode: automount = self.module.params.get("automount", False) - self.hcloud_volume.attach(server, automount=automount).wait_until_finished() + action = self.hcloud_volume.attach(server, automount=automount) + action.wait_until_finished() self._mark_as_changed() else: if self.hcloud_volume.server is not None: if not self.module.check_mode: - self.hcloud_volume.detach().wait_until_finished() + action = self.hcloud_volume.detach() + action.wait_until_finished() self._mark_as_changed() labels = self.module.params.get("labels") @@ -256,7 +260,8 @@ def _update_volume(self): delete_protection = self.module.params.get("delete_protection") if delete_protection is not None and delete_protection != self.hcloud_volume.protection["delete"]: if not self.module.check_mode: - self.hcloud_volume.change_protection(delete=delete_protection).wait_until_finished() + action = self.hcloud_volume.change_protection(delete=delete_protection) + action.wait_until_finished() self._mark_as_changed() self._get_volume() @@ -276,7 +281,8 @@ def delete_volume(self): if self.hcloud_volume is not None: if not self.module.check_mode: if self.hcloud_volume.server is not None: - self.hcloud_volume.detach().wait_until_finished() + action = self.hcloud_volume.detach() + action.wait_until_finished() self.client.volumes.delete(self.hcloud_volume) self._mark_as_changed() self.hcloud_volume = None