Skip to content

Commit b2abc17

Browse files
authored
Implement basic Hetzner API support for storagebox_snapshot_plan[_info] (#167)
* Implement basic Hetzner API support for storagebox_snapshot_plan[_info]. * Add tests.
1 parent 3993c29 commit b2abc17

File tree

10 files changed

+1117
-137
lines changed

10 files changed

+1117
-137
lines changed

antsibull-nox.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@ pattern = "^storagebox.*$"
5151
exclusions = [
5252
"storagebox_set_password",
5353
"storagebox_snapshot_info",
54-
"storagebox_snapshot_plan_info",
55-
"storagebox_snapshot_plan",
5654
"storagebox_snapshot",
5755
"storagebox_subaccount_info",
5856
"storagebox_subaccount",
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
minor_changes:
2+
- "storagebox_snapshot_plan - support the new Hetzner API (https://github.com/ansible-collections/community.hrobot/pull/167)."
3+
- "storagebox_snapshot_plan_info - support the new Hetzner API (https://github.com/ansible-collections/community.hrobot/pull/167)."

meta/runtime.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,5 @@ action_groups:
3131
api:
3232
- storagebox
3333
- storagebox_info
34+
- storagebox_snapshot_plan
35+
- storagebox_snapshot_plan_info

plugins/module_utils/api.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
__metaclass__ = type
99

1010

11+
from ansible.module_utils.common.text.converters import to_native
1112
from ansible.module_utils.six import PY3
1213
from ansible.module_utils.six.moves.urllib.parse import urlencode
1314
from ansible.module_utils.urls import fetch_url
@@ -248,3 +249,38 @@ def api_fetch_url_json_with_retries(module, url, check_done_callback, check_done
248249
return result, info, error
249250
if left_time < check_done_delay:
250251
raise CheckDoneTimeoutException(result, error)
252+
253+
254+
class ApplyActionError(Exception):
255+
pass
256+
257+
258+
def api_apply_action(module, action_url, action_data, action_check_url_provider, check_done_delay=10, check_done_timeout=180):
259+
headers = {"Content-type": "application/json"} if action_data is not None else {}
260+
result, dummy, dummy2 = api_fetch_url_json(
261+
module,
262+
action_url,
263+
data=module.jsonify(action_data) if action_data is not None else None,
264+
headers=headers,
265+
method='POST',
266+
)
267+
action_id = result["action"]["id"]
268+
if result["action"]["status"] == "running":
269+
this_action_url = action_check_url_provider(action_id)
270+
271+
def action_done_callback(result_, info_, error_):
272+
if error_ is not None: # pragma: no cover
273+
return True # pragma: no cover
274+
return result_["action"]["status"] != "running"
275+
276+
try:
277+
result, dummy, dummy2 = api_fetch_url_json_with_retries(
278+
module, this_action_url, action_done_callback, check_done_delay=1, check_done_timeout=60, skip_first=True,
279+
)
280+
except CheckDoneTimeoutException as dummy:
281+
raise ApplyActionError("Timeout")
282+
error = result["action"].get("error")
283+
if isinstance(error, dict):
284+
raise ApplyActionError('[{0}] {1}'.format(to_native(error.get("code")), to_native(error.get("message"))))
285+
elif result["action"]["status"] == "error":
286+
raise ApplyActionError('Unknown error')

plugins/modules/storagebox.py

Lines changed: 13 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,6 @@
124124
from ansible.module_utils.common.text.converters import to_native
125125
from ansible.module_utils.six.moves.urllib.parse import urlencode
126126

127-
from ansible_collections.community.hrobot.plugins.module_utils.common import (
128-
CheckDoneTimeoutException,
129-
)
130127
from ansible_collections.community.hrobot.plugins.module_utils.robot import (
131128
BASE_URL,
132129
ROBOT_DEFAULT_ARGUMENT_SPEC,
@@ -138,7 +135,8 @@
138135
API_BASE_URL,
139136
API_DEFAULT_ARGUMENT_SPEC,
140137
_API_DEFAULT_ARGUMENT_SPEC_COMPAT,
141-
api_fetch_url_json_with_retries,
138+
ApplyActionError,
139+
api_apply_action,
142140
api_fetch_url_json,
143141
)
144142

@@ -297,34 +295,17 @@ def main():
297295
if action and not module.check_mode:
298296
after.update(update_after_update)
299297
action_url = "{0}/actions/update_access_settings".format(url)
300-
headers = {"Content-type": "application/json"}
301-
result, dummy, dummy2 = api_fetch_url_json(
302-
module,
303-
action_url,
304-
data=module.jsonify(action),
305-
headers=headers,
306-
method='POST',
307-
)
308-
action_id = result["action"]["id"]
309-
if result["action"]["status"] == "running":
310-
this_action_url = "{0}/v1/storage_boxes/actions/{1}".format(API_BASE_URL, action_id)
311-
312-
def action_done_callback(result_, info_, error_):
313-
if error_ is not None: # pragma: no cover
314-
return True # pragma: no cover
315-
return result_["action"]["status"] != "running"
316-
317-
try:
318-
result, dummy, dummy2 = api_fetch_url_json_with_retries(
319-
module, this_action_url, action_done_callback, check_done_delay=1, check_done_timeout=60, skip_first=True,
320-
)
321-
except CheckDoneTimeoutException as dummy:
322-
module.fail_json(msg='Timeout while waiting for access settings to be configured.')
323-
error = result["action"].get("error")
324-
if isinstance(error, dict):
325-
module.fail_json(msg='Error while updating access settings: [{0}] {1}'.format(error.get("code"), error.get("message")))
326-
elif result["action"]["status"] == "error":
327-
module.fail_json(msg='Error while updating access settings (unknown error)')
298+
try:
299+
api_apply_action(
300+
module,
301+
action_url,
302+
action,
303+
lambda action_id: "{0}/v1/storage_boxes/actions/{1}".format(API_BASE_URL, action_id),
304+
check_done_delay=1,
305+
check_done_timeout=60,
306+
)
307+
except ApplyActionError as exc:
308+
module.fail_json(msg='Error while updating access settings: {0}'.format(exc))
328309

329310
result = dict(after)
330311
result['changed'] = bool(changes)

0 commit comments

Comments
 (0)