Codebase list python-castellan / 2d5be1a
Fix Vault K/V API compatibility. Starting from version 0.10.0, HashiCorp Vault has a different API for the Key/Value Secrets Engine. This fix implements both the new API support and the fallback for the legacy one. Fixes https://bugs.launchpad.net/castellan/+bug/1788375 Change-Id: I7fed7b5091440dae15551d83f0ee0895651e47bf Signed-off-by: Moises Guimaraes de Medeiros <moguimar@redhat.com> Moises Guimaraes de Medeiros 5 years ago
1 changed file(s) with 54 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
9292 self._verify_server = self._conf.vault.ssl_ca_crt_file or True
9393 else:
9494 self._verify_server = False
95 self._vault_kv_version = None
9596
9697 def _get_url(self):
9798 if not self._vault_url.endswith('/'):
9899 self._vault_url += '/'
99100 return self._vault_url
101
102 def _get_api_version(self):
103 if self._vault_kv_version:
104 return self._vault_kv_version
105
106 headers = {'X-Vault-Token': self._root_token_id}
107 try:
108 resource_url = self._get_url() + 'v1/sys/internal/ui/mounts/secret'
109 resp = self._session.get(resource_url,
110 verify=self._verify_server,
111 headers=headers)
112 except requests.exceptions.Timeout as ex:
113 raise exception.KeyManagerError(six.text_type(ex))
114 except requests.exceptions.ConnectionError as ex:
115 raise exception.KeyManagerError(six.text_type(ex))
116 except Exception as ex:
117 raise exception.KeyManagerError(six.text_type(ex))
118
119 if resp.status_code in _EXCEPTIONS_BY_CODE:
120 raise exception.KeyManagerError(resp.reason)
121 if resp.status_code == requests.codes['forbidden']:
122 raise exception.Forbidden()
123 if resp.status_code == requests.codes['not_found']:
124 self._vault_kv_version = '1'
125 else:
126 self._vault_kv_version = resp.json()['data']['options']['version']
127
128 return self._vault_kv_version
100129
101130 def create_key_pair(self, context, algorithm, length,
102131 expiration=None, name=None):
158187
159188 headers = {'X-Vault-Token': self._root_token_id}
160189 try:
161 resource_url = self._get_url() + 'v1/secret/' + key_id
190 resource_url = '{}v1/secret/{}{}'.format(
191 self._get_url(),
192 '' if self._get_api_version() == '1' else 'data/',
193 key_id)
194
162195 record = {
163196 'type': type_value,
164197 'value': binascii.hexlify(value.get_encoded()).decode('utf-8'),
169202 'name': value.name,
170203 'created': value.created
171204 }
205 if self._get_api_version() != '1':
206 record = {'data': record}
207
172208 resp = self._session.post(resource_url,
173209 verify=self._verify_server,
174210 json=record,
228264
229265 headers = {'X-Vault-Token': self._root_token_id}
230266 try:
231 resource_url = self._get_url() + 'v1/secret/' + key_id
267 resource_url = '{}v1/secret/{}{}'.format(
268 self._get_url(),
269 '' if self._get_api_version() == '1' else 'data/',
270 key_id)
271
232272 resp = self._session.get(resource_url,
233273 verify=self._verify_server,
234274 headers=headers)
247287 raise exception.ManagedObjectNotFoundError(uuid=key_id)
248288
249289 record = resp.json()['data']
290 if self._get_api_version() != '1':
291 record = record['data']
292
250293 key = None if metadata_only else binascii.unhexlify(record['value'])
251294
252295 clazz = None
284327
285328 headers = {'X-Vault-Token': self._root_token_id}
286329 try:
287 resource_url = self._get_url() + 'v1/secret/' + key_id
330 resource_url = '{}v1/secret/{}{}'.format(
331 self._get_url(),
332 '' if self._get_api_version() == '1' else 'data/',
333 key_id)
334
288335 resp = self._session.delete(resource_url,
289336 verify=self._verify_server,
290337 headers=headers)
316363
317364 headers = {'X-Vault-Token': self._root_token_id}
318365 try:
319 resource_url = self._get_url() + 'v1/secret/?list=true'
366 resource_url = '{}v1/secret/{}?list=true'.format(
367 self._get_url(),
368 '' if self._get_api_version() == '1' else 'metadata/')
369
320370 resp = self._session.get(resource_url,
321371 verify=self._verify_server,
322372 headers=headers)