Skip to content

Commit c9a667a

Browse files
committed
add retry when invoke API from vault
1 parent a42d327 commit c9a667a

1 file changed

Lines changed: 47 additions & 19 deletions

File tree

src/api/handlers/job_api.py

Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pylint: disable=too-many-lines,too-few-public-methods,too-many-locals,too-many-statements,too-many-branches
22
import os
33
import json
4+
import time
45
import uuid
56
import copy
67
import urllib.request, urllib.parse, urllib.error
@@ -43,6 +44,49 @@ def delete_file(path):
4344
logger.warning("Failed to delete file: %s", error)
4445

4546

47+
def get_token_by_app_role(app_role_url, role_id, secret_id, retry_times=3):
48+
app_role = {'role_id': role_id, 'secret_id': secret_id}
49+
json_data = json.dumps(app_role)
50+
attempt = 0
51+
while retry_times > 0:
52+
res = requests.post(url=app_role_url, data=json_data, verify=False)
53+
attempt += 1
54+
if res.status_code == 200:
55+
json_res = json.loads(res.content)
56+
token = json_res['auth']['client_token']
57+
return token
58+
else:
59+
if retry_times > 1:
60+
logger.warning("Vault Token returned code is not 200, will retry after %s seconds..." % 10 * pow(2, attempt))
61+
time.sleep(10 * pow(2, attempt))
62+
else:
63+
logger.error("Getting token from Vault error even though retried %s times, url is '%s', API response is '%s':'%s'" % attempt, app_role_url, res.status_code, res.text)
64+
retry_times -= 1
65+
abort(400, "Getting token from vault error")
66+
67+
68+
def get_value_from_vault(url, token, secret_key, verify, retry_times=3):
69+
attempt = 0
70+
while retry_times > 0:
71+
response = requests.get(url=url, headers={'X-Vault-Token': token}, verify=verify)
72+
attempt += 1
73+
if response.status_code == 200:
74+
json_res = json.loads(response.content)
75+
if json_res['data'].get('data') and isinstance(json_res['data'].get('data'), dict):
76+
value = json_res['data'].get('data').get(secret_key)
77+
else:
78+
value = json_res['data'].get(secret_key)
79+
return value
80+
else:
81+
if retry_times > 1:
82+
logger.warning("Vault value returned code is not 200, will retry after %s seconds..." % 10 * pow(2, attempt))
83+
time.sleep(10 * pow(2, attempt))
84+
else:
85+
logger.error("Getting value from Vault error even though retried %s times, url is '%s', API response is '%s':'%s'" % retry_times, url, response.status_code, response.text)
86+
retry_times -= 1
87+
abort(400, "Getting data from vault error")
88+
89+
4690
@api.route("/api/job/job", doc=False)
4791
class Job(Resource):
4892

@@ -295,34 +339,18 @@ def get_secret(name):
295339
if validate_res == 'token':
296340
logger.info('validate way is token')
297341
elif validate_res == 'appRole':
298-
app_role = {'role_id': role_id, 'secret_id': secret_id}
299-
json_data = json.dumps(app_role)
300342
app_role_url = result[0] + '/v1/' + namespace + '/auth/approle/login' if namespace else result[0] + '/v1/auth/approle/login'
301-
res = requests.post(url=app_role_url, data=json_data, verify=False)
302-
if res.status_code == 200:
303-
json_res = json.loads(res.content)
304-
token = json_res['auth']['client_token']
305-
else:
306-
abort(400, "Getting value from vault error: url is '%s', validate way is appRole; API response: '%s'" % (app_role_url, res.text))
343+
token = get_token_by_app_role(app_role_url, role_id, secret_id)
307344
else:
308345
abort(400, "Validate way is '%s' ! result is '%s' " % (validate_res, result))
309346

310347
if not ca:
311-
res = requests.get(url=url, headers={'X-Vault-Token': token}, verify=False)
348+
return get_value_from_vault(url, token, secret_key, False)
312349
else:
313350
with tempfile.NamedTemporaryFile(delete=False) as f:
314351
f.write(ca)
315352
f.flush() # ensure all data written
316-
res = requests.get(url=url, headers={'X-Vault-Token': token}, verify=f.name)
317-
if res.status_code == 200:
318-
json_res = json.loads(res.content)
319-
if json_res['data'].get('data') and isinstance(json_res['data'].get('data'), dict):
320-
value = json_res['data'].get('data').get(secret_key)
321-
else:
322-
value = json_res['data'].get(secret_key)
323-
return value
324-
else:
325-
abort(400, "Getting value from vault error: url is '%s', token is '%s' " % (url, result))
353+
return get_value_from_vault(url, token, secret_key, f.name)
326354
else:
327355
if is_fork:
328356
abort(400, 'Access to secret %s is not allowed from a fork' % name)

0 commit comments

Comments
 (0)