Skip to content

Commit 0305dce

Browse files
committed
Replace code for old API with hard-coded 'storagebox ID unknown'.
1 parent a45fad2 commit 0305dce

20 files changed

+294
-3140
lines changed

changelogs/fragments/173-storagebox.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@ deprecated_features:
22
- "storagebox* modules - the ``hetzner_user`` and ``hetzner_pass`` options for these modules are deprecated; support will be removed in community.hrobot 3.0.0. Use ``hetzner_token`` instead (https://github.com/ansible-collections/community.hrobot/pull/173)."
33
- "storagebox* modules - the ``hetzner_token`` option for these modules will be required from community.hrobot 3.0.0 on (https://github.com/ansible-collections/community.hrobot/pull/173)."
44
- "storagebox* modules - membership in the ``community.hrobot.robot`` action group (module defaults group) is deprecated; the modules will be removed from the group in community.hrobot 3.0.0. Use ``community.hrobot.api`` instead (https://github.com/ansible-collections/community.hrobot/pull/173)."
5+
minor_changes:
6+
- "storagebox* modules - the code for the old API (that has been removed by Hetzner) has been replaced by hard-coding the result of the API, namely that no storagebox of this ID exists (https://github.com/ansible-collections/community.hrobot/pull/173)."

plugins/modules/storagebox.py

Lines changed: 59 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,8 @@
124124
from ansible.module_utils.common.text.converters import to_native
125125

126126
from ansible_collections.community.hrobot.plugins.module_utils.robot import (
127-
BASE_URL,
128127
ROBOT_DEFAULT_ARGUMENT_SPEC,
129128
_ROBOT_DEFAULT_ARGUMENT_SPEC_COMPAT_DEPRECATED,
130-
fetch_url_json,
131129
)
132130

133131
from ansible_collections.community.hrobot.plugins.module_utils.api import (
@@ -139,21 +137,6 @@
139137
api_fetch_url_json,
140138
)
141139

142-
try:
143-
from urllib.parse import urlencode
144-
except ImportError:
145-
# Python 2.x fallback:
146-
from urllib import urlencode
147-
148-
149-
PARAMETERS_LEGACY = {
150-
'name': ('name', 'storagebox_name'),
151-
'webdav': ('webdav', 'webdav'),
152-
'samba': ('samba', 'samba'),
153-
'ssh': ('ssh', 'ssh'),
154-
'external_reachability': ('external_reachability', 'external_reachability'),
155-
'zfs': ('zfs', 'zfs'),
156-
}
157140

158141
UPDATE_PARAMETERS = {
159142
'name': ('name', ['name'], 'name'),
@@ -171,11 +154,6 @@
171154
PARAMETERS.update(ACTION_PARAMETERS)
172155

173156

174-
def extract_legacy(result):
175-
sb = result['storagebox']
176-
return {key: sb.get(key) for key, dummy in PARAMETERS_LEGACY.values()}
177-
178-
179157
def extract(result):
180158
sb = result['storage_box']
181159

@@ -222,101 +200,68 @@ def main():
222200
version="3.0.0",
223201
)
224202
if module.params["hetzner_user"] is not None:
225-
# DEPRECATED: old API
226-
url = "{0}/storagebox/{1}".format(BASE_URL, storagebox_id)
227-
result, error = fetch_url_json(module, url, accept_errors=['STORAGEBOX_NOT_FOUND'])
228-
if error:
229-
module.fail_json(msg='Storagebox with ID {0} does not exist'.format(storagebox_id))
230-
231-
before = extract_legacy(result)
232-
after = dict(before)
233-
234-
for option_name, (data_name, change_name) in PARAMETERS_LEGACY.items():
235-
value = module.params[option_name]
236-
if value is not None:
237-
if before[data_name] != value:
238-
after[data_name] = value
239-
if isinstance(value, bool):
240-
changes[change_name] = str(value).lower()
241-
else:
242-
changes[change_name] = value
243-
244-
if changes and not module.check_mode:
245-
headers = {"Content-type": "application/x-www-form-urlencoded"}
246-
result, error = fetch_url_json(
247-
module,
248-
url,
249-
data=urlencode(changes),
250-
headers=headers,
251-
method='POST',
252-
accept_errors=['INVALID_INPUT'],
253-
)
254-
if error:
255-
invalid = result['error'].get('invalid') or []
256-
module.fail_json(msg='The values to update were invalid ({0})'.format(', '.join(invalid)))
257-
after = extract_legacy(result)
258-
259-
else:
260-
# NEW API!
261-
url = "{0}/v1/storage_boxes/{1}".format(API_BASE_URL, storagebox_id)
262-
result, dummy, error = api_fetch_url_json(module, url, accept_errors=['not_found'])
203+
module.warn("The old storagebox API has been disabled by Hetzner. The supporting code has been removed.")
204+
module.fail_json(msg='Storagebox with ID {0} does not exist'.format(storagebox_id))
205+
206+
url = "{0}/v1/storage_boxes/{1}".format(API_BASE_URL, storagebox_id)
207+
result, dummy, error = api_fetch_url_json(module, url, accept_errors=['not_found'])
208+
if error:
209+
module.fail_json(msg='Storagebox with ID {0} does not exist'.format(storagebox_id))
210+
211+
before = extract(result)
212+
after = dict(before)
213+
214+
update = {}
215+
for option_name, (data_name, dummy, change_name) in UPDATE_PARAMETERS.items():
216+
value = module.params[option_name]
217+
if value is not None:
218+
if before[data_name] != value:
219+
after[data_name] = value
220+
changes[change_name] = value
221+
update[change_name] = value
222+
223+
action = {}
224+
update_after_update = {}
225+
for option_name, (data_name, dummy, change_name) in ACTION_PARAMETERS.items():
226+
value = module.params[option_name]
227+
if value is not None:
228+
if before[data_name] != value:
229+
after[data_name] = value
230+
update_after_update[data_name] = value
231+
changes[change_name] = value
232+
action[change_name] = value
233+
234+
if update and not module.check_mode:
235+
headers = {"Content-type": "application/json"}
236+
result, dummy, error = api_fetch_url_json(
237+
module,
238+
url,
239+
data=module.jsonify(update),
240+
headers=headers,
241+
method='PUT',
242+
accept_errors=['invalid_input'],
243+
)
263244
if error:
264-
module.fail_json(msg='Storagebox with ID {0} does not exist'.format(storagebox_id))
265-
266-
before = extract(result)
267-
after = dict(before)
268-
269-
update = {}
270-
for option_name, (data_name, dummy, change_name) in UPDATE_PARAMETERS.items():
271-
value = module.params[option_name]
272-
if value is not None:
273-
if before[data_name] != value:
274-
after[data_name] = value
275-
changes[change_name] = value
276-
update[change_name] = value
277-
278-
action = {}
279-
update_after_update = {}
280-
for option_name, (data_name, dummy, change_name) in ACTION_PARAMETERS.items():
281-
value = module.params[option_name]
282-
if value is not None:
283-
if before[data_name] != value:
284-
after[data_name] = value
285-
update_after_update[data_name] = value
286-
changes[change_name] = value
287-
action[change_name] = value
288-
289-
if update and not module.check_mode:
290-
headers = {"Content-type": "application/json"}
291-
result, dummy, error = api_fetch_url_json(
245+
details = result['error'].get('details') or {}
246+
fields = details.get("fields") or []
247+
details_str = ", ".join(['{0}: {1}'.format(to_native(field["name"]), to_native(field["message"])) for field in fields])
248+
module.fail_json(msg='The values to update were invalid ({0})'.format(details_str or "no details"))
249+
after = extract(result)
250+
251+
if action and not module.check_mode:
252+
after.update(update_after_update)
253+
action_url = "{0}/actions/update_access_settings".format(url)
254+
try:
255+
api_apply_action(
292256
module,
293-
url,
294-
data=module.jsonify(update),
295-
headers=headers,
296-
method='PUT',
297-
accept_errors=['invalid_input'],
257+
action_url,
258+
action,
259+
lambda action_id: "{0}/v1/storage_boxes/actions/{1}".format(API_BASE_URL, action_id),
260+
check_done_delay=1,
261+
check_done_timeout=60,
298262
)
299-
if error:
300-
details = result['error'].get('details') or {}
301-
fields = details.get("fields") or []
302-
details_str = ", ".join(['{0}: {1}'.format(to_native(field["name"]), to_native(field["message"])) for field in fields])
303-
module.fail_json(msg='The values to update were invalid ({0})'.format(details_str or "no details"))
304-
after = extract(result)
305-
306-
if action and not module.check_mode:
307-
after.update(update_after_update)
308-
action_url = "{0}/actions/update_access_settings".format(url)
309-
try:
310-
api_apply_action(
311-
module,
312-
action_url,
313-
action,
314-
lambda action_id: "{0}/v1/storage_boxes/actions/{1}".format(API_BASE_URL, action_id),
315-
check_done_delay=1,
316-
check_done_timeout=60,
317-
)
318-
except ApplyActionError as exc:
319-
module.fail_json(msg='Error while updating access settings: {0}'.format(exc))
263+
except ApplyActionError as exc:
264+
module.fail_json(msg='Error while updating access settings: {0}'.format(exc))
320265

321266
result = dict(after)
322267
result['changed'] = bool(changes)

plugins/modules/storagebox_info.py

Lines changed: 10 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -519,10 +519,8 @@
519519
from ansible.module_utils.basic import AnsibleModule
520520

521521
from ansible_collections.community.hrobot.plugins.module_utils.robot import (
522-
BASE_URL,
523522
ROBOT_DEFAULT_ARGUMENT_SPEC,
524523
_ROBOT_DEFAULT_ARGUMENT_SPEC_COMPAT_DEPRECATED,
525-
fetch_url_json,
526524
)
527525

528526
from ansible_collections.community.hrobot.plugins.module_utils.api import (
@@ -533,12 +531,6 @@
533531
api_fetch_url_json_list,
534532
)
535533

536-
try:
537-
from urllib.parse import urlencode
538-
except ImportError:
539-
# Python 2.x fallback:
540-
from urllib import urlencode
541-
542534

543535
_CONVERT = {
544536
"login": ["username"],
@@ -594,49 +586,18 @@ def main():
594586
version="3.0.0",
595587
)
596588
if module.params["hetzner_user"] is not None:
597-
# DEPRECATED: old API
598-
if storagebox_id is not None:
599-
storagebox_ids = [storagebox_id]
600-
else:
601-
url = "{0}/storagebox".format(BASE_URL)
602-
data = None
603-
headers = None
604-
if linked_server_number is not None:
605-
data = urlencode({
606-
"linked_server": linked_server_number,
607-
})
608-
headers = {
609-
"Content-type": "application/x-www-form-urlencoded",
610-
}
611-
result, error = fetch_url_json(module, url, accept_errors=['STORAGEBOX_NOT_FOUND'], data=data)
612-
storagebox_ids = []
613-
if not error:
614-
# When filtering by linked_server, the result should be a dictionary
615-
if isinstance(result, dict):
616-
result = [result]
617-
for entry in result:
618-
if full_info:
619-
storagebox_ids.append(entry['storagebox']['id'])
620-
else:
621-
storageboxes.append(entry['storagebox'])
622-
623-
for storagebox_id in storagebox_ids:
624-
url = "{0}/storagebox/{1}".format(BASE_URL, storagebox_id)
625-
result, error = fetch_url_json(module, url, accept_errors=['STORAGEBOX_NOT_FOUND'])
626-
if not error:
627-
storageboxes.append(result['storagebox'])
589+
module.warn("The old storagebox API has been disabled by Hetzner. The supporting code has been removed.")
590+
module.exit_json(changed=False, storageboxes=[])
628591

592+
if storagebox_id is not None:
593+
url = "{0}/v1/storage_boxes/{1}".format(API_BASE_URL, storagebox_id)
594+
result, dummy, error = api_fetch_url_json(module, url, accept_errors=["not_found"])
595+
if error is None:
596+
storageboxes = [result["storage_box"]]
629597
else:
630-
# NEW API!
631-
if storagebox_id is not None:
632-
url = "{0}/v1/storage_boxes/{1}".format(API_BASE_URL, storagebox_id)
633-
result, dummy, error = api_fetch_url_json(module, url, accept_errors=["not_found"])
634-
if error is None:
635-
storageboxes = [result["storage_box"]]
636-
else:
637-
url = "{0}/v1/storage_boxes".format(API_BASE_URL)
638-
storageboxes, dummy = api_fetch_url_json_list(module, url, data_key="storage_boxes")
639-
storageboxes = [add_hrobot_compat_shim(storagebox) for storagebox in storageboxes]
598+
url = "{0}/v1/storage_boxes".format(API_BASE_URL)
599+
storageboxes, dummy = api_fetch_url_json_list(module, url, data_key="storage_boxes")
600+
storageboxes = [add_hrobot_compat_shim(storagebox) for storagebox in storageboxes]
640601

641602
module.exit_json(
642603
changed=False,

plugins/modules/storagebox_set_password.py

Lines changed: 24 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,8 @@
8383
from ansible.module_utils.basic import AnsibleModule
8484

8585
from ansible_collections.community.hrobot.plugins.module_utils.robot import (
86-
BASE_URL,
8786
ROBOT_DEFAULT_ARGUMENT_SPEC,
8887
_ROBOT_DEFAULT_ARGUMENT_SPEC_COMPAT_DEPRECATED,
89-
fetch_url_json,
9088
)
9189

9290
from ansible_collections.community.hrobot.plugins.module_utils.api import (
@@ -97,12 +95,6 @@
9795
api_apply_action,
9896
)
9997

100-
try:
101-
from urllib.parse import urlencode
102-
except ImportError:
103-
# Python 2.x fallback:
104-
from urllib import urlencode
105-
10698

10799
def main():
108100
argument_spec = dict(
@@ -129,51 +121,30 @@ def main():
129121
version="3.0.0",
130122
)
131123
if module.params["hetzner_user"] is not None:
132-
# DEPRECATED: old API
133-
url = "{0}/storagebox/{1}/password".format(BASE_URL, id)
134-
accepted_errors = ["STORAGEBOX_NOT_FOUND", "STORAGEBOX_INVALID_PASSWORD"]
135-
136-
if password:
137-
headers = {"Content-type": "application/x-www-form-urlencoded"}
138-
result, error = fetch_url_json(
139-
module, url, method="POST", accept_errors=accepted_errors, data=urlencode({"password": password}), headers=headers)
140-
else:
141-
result, error = fetch_url_json(
142-
module, url, method="POST", accept_errors=accepted_errors)
143-
144-
if error == 'STORAGEBOX_NOT_FOUND':
145-
module.fail_json(
146-
msg='Storage Box with ID {0} not found'.format(id))
147-
148-
if error == 'STORAGEBOX_INVALID_PASSWORD':
149-
module.fail_json(
150-
msg="The chosen password has been considered insecure or does not comply with Hetzner's password guideline")
151-
152-
module.exit_json(changed=True, password=result["password"])
153-
154-
else:
155-
# NEW API!
156-
action_url = "{0}/v1/storage_boxes/{1}/actions/reset_password".format(API_BASE_URL, id)
157-
action = {
158-
"password": password,
159-
}
160-
try:
161-
dummy, error = api_apply_action(
162-
module,
163-
action_url,
164-
action,
165-
lambda action_id: "{0}/v1/storage_boxes/actions/{1}".format(API_BASE_URL, action_id),
166-
check_done_delay=1,
167-
check_done_timeout=60,
168-
accept_errors=["not_found"],
169-
)
170-
except ApplyActionError as exc:
171-
module.fail_json(msg='Error while resetting password: {0}'.format(exc))
172-
173-
if error == "not_found":
174-
module.fail_json(msg='Storage Box with ID {0} not found'.format(id))
175-
176-
module.exit_json(changed=True, password=password)
124+
module.warn("The old storagebox API has been disabled by Hetzner. The supporting code has been removed.")
125+
module.fail_json(msg='Storage Box with ID {0} not found'.format(id))
126+
127+
action_url = "{0}/v1/storage_boxes/{1}/actions/reset_password".format(API_BASE_URL, id)
128+
action = {
129+
"password": password,
130+
}
131+
try:
132+
dummy, error = api_apply_action(
133+
module,
134+
action_url,
135+
action,
136+
lambda action_id: "{0}/v1/storage_boxes/actions/{1}".format(API_BASE_URL, action_id),
137+
check_done_delay=1,
138+
check_done_timeout=60,
139+
accept_errors=["not_found"],
140+
)
141+
except ApplyActionError as exc:
142+
module.fail_json(msg='Error while resetting password: {0}'.format(exc))
143+
144+
if error == "not_found":
145+
module.fail_json(msg='Storage Box with ID {0} not found'.format(id))
146+
147+
module.exit_json(changed=True, password=password)
177148

178149

179150
if __name__ == '__main__': # pragma: no cover

0 commit comments

Comments
 (0)