Skip to content

Commit 7585d2a

Browse files
committed
Replace code for old API with hard-coded 'storagebox ID unknown'.
1 parent 788ce67 commit 7585d2a

20 files changed

+294
-3140
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
minor_changes:
2+
- "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

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

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

plugins/modules/storagebox_info.py

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

541541
from ansible_collections.community.hrobot.plugins.module_utils.robot import (
542-
BASE_URL,
543542
ROBOT_DEFAULT_ARGUMENT_SPEC,
544543
_ROBOT_DEFAULT_ARGUMENT_SPEC_COMPAT_DEPRECATED,
545-
fetch_url_json,
546544
)
547545

548546
from ansible_collections.community.hrobot.plugins.module_utils.api import (
@@ -557,12 +555,6 @@
557555
deprecate_value,
558556
)
559557

560-
try:
561-
from urllib.parse import urlencode
562-
except ImportError:
563-
# Python 2.x fallback:
564-
from urllib import urlencode
565-
566558

567559
_CONVERT = {
568560
"login": ["username"],
@@ -621,49 +613,18 @@ def main():
621613
collection_name="community.hrobot",
622614
version="3.0.0",
623615
)
624-
# DEPRECATED: old API
625-
if storagebox_id is not None:
626-
storagebox_ids = [storagebox_id]
627-
else:
628-
url = "{0}/storagebox".format(BASE_URL)
629-
data = None
630-
headers = None
631-
if linked_server_number is not None:
632-
data = urlencode({
633-
"linked_server": linked_server_number,
634-
})
635-
headers = {
636-
"Content-type": "application/x-www-form-urlencoded",
637-
}
638-
result, error = fetch_url_json(module, url, accept_errors=['STORAGEBOX_NOT_FOUND'], data=data)
639-
storagebox_ids = []
640-
if not error:
641-
# When filtering by linked_server, the result should be a dictionary
642-
if isinstance(result, dict):
643-
result = [result]
644-
for entry in result:
645-
if full_info:
646-
storagebox_ids.append(entry['storagebox']['id'])
647-
else:
648-
storageboxes.append(entry['storagebox'])
649-
650-
for storagebox_id in storagebox_ids:
651-
url = "{0}/storagebox/{1}".format(BASE_URL, storagebox_id)
652-
result, error = fetch_url_json(module, url, accept_errors=['STORAGEBOX_NOT_FOUND'])
653-
if not error:
654-
storageboxes.append(result['storagebox'])
616+
module.warn("The old storagebox API has been disabled by Hetzner. The supporting code has been removed.")
617+
module.exit_json(changed=False, storageboxes=[])
655618

619+
if storagebox_id is not None:
620+
url = "{0}/v1/storage_boxes/{1}".format(API_BASE_URL, storagebox_id)
621+
result, dummy, error = api_fetch_url_json(module, url, accept_errors=["not_found"])
622+
if error is None:
623+
storageboxes = [result["storage_box"]]
656624
else:
657-
# NEW API!
658-
if storagebox_id is not None:
659-
url = "{0}/v1/storage_boxes/{1}".format(API_BASE_URL, storagebox_id)
660-
result, dummy, error = api_fetch_url_json(module, url, accept_errors=["not_found"])
661-
if error is None:
662-
storageboxes = [result["storage_box"]]
663-
else:
664-
url = "{0}/v1/storage_boxes".format(API_BASE_URL)
665-
storageboxes, dummy = api_fetch_url_json_list(module, url, data_key="storage_boxes")
666-
storageboxes = [add_hrobot_compat_shim(storagebox) for storagebox in storageboxes]
625+
url = "{0}/v1/storage_boxes".format(API_BASE_URL)
626+
storageboxes, dummy = api_fetch_url_json_list(module, url, data_key="storage_boxes")
627+
storageboxes = [add_hrobot_compat_shim(storagebox) for storagebox in storageboxes]
667628

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

177148

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

0 commit comments

Comments
 (0)