Skip to content

Commit f980636

Browse files
authored
Revert "DIARCHERS-610: generate batch token to connect vault"
1 parent 59d9b59 commit f980636

1 file changed

Lines changed: 44 additions & 135 deletions

File tree

src/api/handlers/job_api.py

Lines changed: 44 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#pylint: disable=too-many-lines,too-few-public-methods,too-many-locals,too-many-statements,too-many-branches
1+
#pylint: disable=too-many-lines,too-few-public-methods,too-many-locals,too-many-statements,too-many-branches
22
import os
33
import json
44
import time
@@ -43,117 +43,34 @@ def delete_file(path):
4343
except Exception as error:
4444
logger.warning("Failed to delete file: %s", error)
4545

46-
class Vault():
47-
def __init__(self, base_url, namespace, version, role_id, secret_id):
48-
self.base_url = base_url
49-
self.namespace = namespace
50-
self.version = version
51-
self.role_id = role_id
52-
self.secret_id = secret_id
53-
self.token = None
54-
self.policies = None
55-
56-
def get_token_by_app_role(self):
57-
self.policies = self.get_policies(self.token)
58-
if self.token and self.policies:
59-
return self.token
60-
app_role = {'role_id': self.role_id, 'secret_id': self.secret_id}
61-
app_role_url = self.base_url + '/v1/' + self.namespace + '/auth/approle/login' if self.namespace else self.base_url + '/v1/auth/approle/login'
62-
json_data = json.dumps(app_role)
63-
for i in range(0, 10):
64-
res = requests.post(url=app_role_url, data=json_data, verify=False)
65-
if res.status_code == 200:
66-
json_res = json.loads(res.content)
67-
self.token = json_res['auth']['client_token']
68-
self.policies = self.get_policies(self.token)
69-
return self.token
70-
time.sleep(5)
71-
err_msg = "Getting token from Vault error even tried 10 times, url is {}, API response is {}:{}".format(app_role_url, res.status_code, res.text)
72-
abort(400, err_msg)
73-
74-
def get_policies(self, token):
75-
"""Return the policies associated with the provided token."""
76-
if not token:
77-
return None
78-
try:
79-
lookup_url = self.base_url + '/v1/' + self.namespace + '/auth/token/lookup-self' if self.namespace else self.base_url + 'v1/auth/token/lookup-self'
80-
res = requests.get(url=lookup_url, headers={"X-Vault-Token": token}, verify=False)
81-
if res.status_code == 200:
82-
json_res = json.loads(res.content)
83-
policies = json_res['data']['policies']
84-
return policies
85-
return None
86-
except Exception as e:
87-
logger.debug("Token validation failed: %s", str(e))
88-
return None
89-
90-
def generate_batch_token(self, service_token, ttl="1h"):
91-
"""
92-
Generate a batch token using AppRole credentials.
93-
:param service_token: A service token generated when logging in with AppRole.
94-
:param ttl: Time-to-live for the batch token.
95-
:return: The generated batch token.
96-
"""
97-
try:
98-
if self.policies is None:
99-
self.policies = self.get_policies(service_token) or ['default']
100-
if self.policies and 'token-creator' in self.policies:
101-
self.policies.remove('token-creator')
102-
103-
batch_payload = {
104-
"type": "batch",
105-
"policies": self.policies or ['default'],
106-
"ttl": ttl
107-
}
108-
url = self.base_url + '/v1/' + self.namespace + '/auth/token/create' if self.namespace else self.base_url + '/v1/auth/token/create'
109-
110-
for i in range(0, 10):
111-
res = requests.post(url=url, json=batch_payload, headers={"X-Vault-Token": service_token}, verify=False)
112-
if res.status_code == 200:
113-
json_res = json.loads(res.content)
114-
token = json_res['auth']['client_token']
115-
return token
116-
elif res.status_code == 403:
117-
logger.info("Getting batch token from Vault forbidden: {}".format(res.text))
118-
return None
119-
time.sleep(5)
120-
msg = "Getting batch token from Vault failed even tried 10 times, url is {}, API response is {}:{}".format(
121-
url, res.status_code, res.text)
122-
logger.info(msg)
123-
return None
124-
except Exception as e:
125-
logger.info("Exception when getting batch token from Vault: {}".format(e))
126-
return None
127-
128-
def _get_api_url(self, secret_path):
129-
url = self.base_url
130-
if not self.namespace:
131-
self.namespace = ''
132-
if self.version == 'v1':
133-
url += '/v1/' + self.namespace + '/' + secret_path if self.namespace else '/v1/' + secret_path
134-
elif self.version == 'v2':
135-
paths = secret_path.split('/')
136-
url += '/v1/' + self.namespace + '/' + paths[0] + '/data/' + '/'.join(paths[1:]) if self.namespace else '/v1/' + paths[0] + '/data/' + '/'.join(paths[1:])
137-
return url
138-
139-
def get_value_from_vault(self, token, secret_path, secret_key, verify):
140-
try:
141-
url = self._get_api_url(secret_path)
142-
for i in range(0, 10):
143-
response = requests.get(url=url, headers={'X-Vault-Token': token}, verify=verify, timeout=30)
144-
if response.status_code == 200:
145-
json_res = json.loads(response.content)
146-
if json_res['data'].get('data') and isinstance(json_res['data'].get('data'), dict):
147-
value = json_res['data'].get('data').get(secret_key)
148-
else:
149-
value = json_res['data'].get(secret_key)
150-
return value
151-
time.sleep(5)
152-
err_msg = "Getting value from Vault error even tried 10 times, url is {}, API response is {}:{}".format(url, response.status_code, response.text)
153-
abort(400, err_msg)
154-
except Exception as e:
155-
err_msg = "Getting value from Vault exception: {}, url is {}".format(str(e), url)
156-
abort(400, err_msg)
46+
47+
def get_token_by_app_role(app_role_url, role_id, secret_id):
48+
app_role = {'role_id': role_id, 'secret_id': secret_id}
49+
json_data = json.dumps(app_role)
50+
for i in range(0, 10):
51+
res = requests.post(url=app_role_url, data=json_data, verify=False)
52+
if res.status_code == 200:
53+
json_res = json.loads(res.content)
54+
token = json_res['auth']['client_token']
55+
return token
56+
time.sleep(5)
57+
err_msg = "Getting token from Vault error even tried 10 times, url is {}, API response is {}:{}".format(app_role_url, res.status_code, res.text)
58+
abort(400, err_msg)
59+
60+
61+
def get_value_from_vault(url, token, secret_key, verify):
62+
for i in range(0, 10):
63+
response = requests.get(url=url, headers={'X-Vault-Token': token}, verify=verify)
64+
if response.status_code == 200:
65+
json_res = json.loads(response.content)
66+
if json_res['data'].get('data') and isinstance(json_res['data'].get('data'), dict):
67+
value = json_res['data'].get('data').get(secret_key)
68+
else:
69+
value = json_res['data'].get(secret_key)
70+
return value
71+
time.sleep(5)
72+
err_msg = "Getting value from Vault error even tried 10 times, url is {}, API response is {}:{}".format(url, response.status_code, response.text)
73+
abort(400, err_msg)
15774

15875

15976
@api.route("/api/job/job", doc=False)
@@ -361,8 +278,6 @@ def get(self):
361278
''', [data['project']['id']])
362279

363280
is_fork = data['job'].get('fork', False)
364-
# Cache Vault instances per vault name+project so we create them only once
365-
vault_cache = {}
366281

367282
def get_secret_type(name):
368283
try:
@@ -385,10 +300,10 @@ def get_auth_type(res):
385300
def get_secret(name):
386301
secret_type = get_secret_type(name)
387302
if secret_type == 'vault':
388-
vault_cfg = json.loads(name)
389-
vault_name = vault_cfg['$vault']
390-
secret_path = vault_cfg['$vault_secret_path']
391-
secret_key = vault_cfg['$vault_secret_key']
303+
vault = json.loads(name)
304+
vault_name = vault['$vault']
305+
secret_path = vault['$vault_secret_path']
306+
secret_key = vault['$vault_secret_key']
392307

393308
result = g.db.execute_one("""
394309
SELECT url, version, token, ca, namespace, role_id, secret_id FROM vault WHERE name = %s and project_id = %s
@@ -398,36 +313,30 @@ def get_secret(name):
398313
abort(400, "Cannot get Vault '%s' in project '%s' " % (vault_name, data['project']['id']))
399314

400315
url, version, token, ca, namespace, role_id, secret_id = result[0], result[1], result[2], result[3], result[4], result[5], result[6]
316+
if not namespace:
317+
namespace = ''
318+
if version == 'v1':
319+
url += '/v1/' + namespace + '/' + secret_path if namespace else '/v1/' + secret_path
320+
elif version == 'v2':
321+
paths = secret_path.split('/')
322+
url += '/v1/' + namespace + '/' + paths[0] + '/data/' + '/'.join(paths[1:]) if namespace else '/v1/' + paths[0] + '/data/' + '/'.join(paths[1:])
401323
# choose validate way
402324
validate_res = get_auth_type(result)
403-
404-
# key vault per project to avoid collisions
405-
vault_key = f"{vault_name}-{data['project']['id']}"
406-
vault_client = vault_cache.get(vault_key)
407-
if not vault_client:
408-
vault_client = Vault(url, namespace, version, role_id, secret_id)
409-
vault_cache[vault_key] = vault_client
410-
411325
if validate_res == 'token':
412326
logger.info('validate way is token')
413-
token_to_use = token
414327
elif validate_res == 'appRole':
415-
logger.info('validate way is appRole')
416-
token_to_use = vault_client.get_token_by_app_role()
417-
batch_token = vault_client.generate_batch_token(token_to_use)
418-
if batch_token:
419-
token_to_use = batch_token
328+
app_role_url = result[0] + '/v1/' + namespace + '/auth/approle/login' if namespace else result[0] + '/v1/auth/approle/login'
329+
token = get_token_by_app_role(app_role_url, role_id, secret_id)
420330
else:
421331
abort(400, "Validate way is '%s' ! result is '%s' " % (validate_res, result))
422332

423333
if not ca:
424-
logger.info('Start to get value fron vault %s %s %s' % (token_to_use, secret_path, secret_key))
425-
return vault_client.get_value_from_vault(token_to_use, secret_path, secret_key, False)
334+
return get_value_from_vault(url, token, secret_key, False)
426335
else:
427336
with tempfile.NamedTemporaryFile(delete=False) as f:
428337
f.write(ca)
429338
f.flush() # ensure all data written
430-
return vault_client.get_value_from_vault(token_to_use, secret_path, secret_key, f.name)
339+
return get_value_from_vault(url, token, secret_key, f.name)
431340
else:
432341
if is_fork:
433342
abort(400, 'Access to secret %s is not allowed from a fork' % name)

0 commit comments

Comments
 (0)