Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions plugins/module_utils/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ def _request(
return Response(e.code, e.read(), e.headers)
except URLError as e:
# TODO: Add other errors here; we need to handle them in modules.
# TimeoutError is handled in the rest_client
if (
e.args
and isinstance(e.args, tuple)
Expand Down
28 changes: 12 additions & 16 deletions plugins/module_utils/cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from time import sleep
from ..module_utils.utils import PayloadMapper
from ..module_utils.rest_client import RestClient
from ..module_utils.errors import ScaleComputingError
from ..module_utils.errors import ScaleTimeoutError
from ..module_utils.typed_classes import TypedClusterToAnsible, TypedTaskTag
from typing import Any

Expand Down Expand Up @@ -84,18 +84,14 @@ def shutdown(
dict(forceShutdown=force_shutdown),
check_mode,
)
except ScaleComputingError as e:
# To avoid timeout when there are a lot of VMs to shutdown
if "Request timed out" in str(e):
try:
while True:
# get cluster until "[Errno 111] Connection refused"
Cluster.get(rest_client)
sleep(5)
except ScaleComputingError as e2:
if "Connection refused" in str(e2): # cluster is shutdown
pass
else:
raise e2 # Some other unexpected error
else:
raise e # UnexpectedAPIResponse error
# To avoid timeout when there are a lot of VMs to shutdown
except ScaleTimeoutError:
pass

try:
while True:
# get cluster until "[Errno 111] Connection refused"
Cluster.get(rest_client)
sleep(5)
except ConnectionRefusedError:
pass
6 changes: 6 additions & 0 deletions plugins/module_utils/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,9 @@ class ApiResponseNotJson(ScaleComputingError):
def __init__(self, data: Union[str, Exception]):
self.message = f"From API expected json got {data}."
super(ApiResponseNotJson, self).__init__(self.message)


class ScaleTimeoutError(ScaleComputingError):
def __init__(self, data: Union[str, Exception]):
self.message = f"Request timed out: {data}."
super(ScaleTimeoutError, self).__init__(self.message)
12 changes: 6 additions & 6 deletions plugins/module_utils/rest_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def list_records(
try:
records = self.client.get(path=endpoint, timeout=timeout).json
except TimeoutError as e:
raise errors.ScaleComputingError(f"Request timed out: {e}")
raise errors.ScaleTimeoutError(e)
return utils.filter_results(records, query)

def get_record(
Expand Down Expand Up @@ -78,7 +78,7 @@ def create_record(
endpoint, payload, query=_query(), timeout=timeout
).json
except TimeoutError as e:
raise errors.ScaleComputingError(f"Request timed out: {e}")
raise errors.ScaleTimeoutError(e)
return response

def update_record(
Expand All @@ -96,7 +96,7 @@ def update_record(
endpoint, payload, query=_query(), timeout=timeout
).json
except TimeoutError as e:
raise errors.ScaleComputingError(f"Request timed out: {e}")
raise errors.ScaleTimeoutError(e)
return response

def delete_record(
Expand All @@ -108,7 +108,7 @@ def delete_record(
try:
response: TypedTaskTag = self.client.delete(endpoint, timeout=timeout).json
except TimeoutError as e:
raise errors.ScaleComputingError(f"Request timed out: {e}")
raise errors.ScaleTimeoutError(e)
return response

def put_record(
Expand All @@ -133,7 +133,7 @@ def put_record(
headers=headers,
).json
except TimeoutError as e:
raise errors.ScaleComputingError(f"Request timed out: {e}")
raise errors.ScaleTimeoutError(e)
except (json.JSONDecodeError, json.decoder.JSONDecodeError) as e:
raise json.JSONDecodeError(e.msg, e.doc, e.pos)
return response
Expand All @@ -159,7 +159,7 @@ def list_records(
try:
records = self.client.get(path=endpoint, timeout=timeout).json
except TimeoutError as e:
raise errors.ScaleComputingError(f"Request timed out: {e}")
raise errors.ScaleTimeoutError(e)
self.cache[endpoint] = records

return utils.filter_results(records, query)
8 changes: 8 additions & 0 deletions tests/unit/plugins/module_utils/test_cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
from ansible_collections.scale_computing.hypercore.plugins.module_utils.cluster import (
Cluster,
)
from ansible_collections.scale_computing.hypercore.plugins.module_utils.errors import (
ScaleTimeoutError,
)
from ansible_collections.scale_computing.hypercore.plugins.module_utils.utils import (
MIN_PYTHON_VERSION,
)
Expand Down Expand Up @@ -111,6 +114,8 @@ def test_cluster_update_name(self, rest_client):

def test_cluster_shutdown(self, rest_client):
force_shutdown = True
rest_client.create_record.side_effect = ScaleTimeoutError("Timeout error")
rest_client.get_record.side_effect = ConnectionRefusedError

Cluster.shutdown(rest_client, force_shutdown)

Expand All @@ -121,6 +126,9 @@ def test_cluster_shutdown(self, rest_client):
)

def test_cluster_shutdown_default_force_shutdown(self, rest_client):
rest_client.create_record.side_effect = ScaleTimeoutError("Timeout error")
rest_client.get_record.side_effect = ConnectionRefusedError

Cluster.shutdown(rest_client)

rest_client.create_record.assert_called_with(
Expand Down