Update Client to use hrefs instead of parsing IDs
This commit is contained in:
@@ -91,16 +91,14 @@ class Client(object):
|
||||
self.secrets = secrets.SecretManager(self)
|
||||
self.orders = orders.OrderManager(self)
|
||||
|
||||
def get(self, path, params=None):
|
||||
url = '{0}/{1}/'.format(self.base_url, path)
|
||||
def get(self, href, params=None):
|
||||
headers = {'Accept': 'application/json'}
|
||||
resp = self._session.get(url, params=params, headers=headers)
|
||||
resp = self._session.get(href, params=params, headers=headers)
|
||||
self._check_status_code(resp)
|
||||
return resp.json()
|
||||
|
||||
def get_raw(self, path, headers):
|
||||
url = '{0}/{1}/'.format(self.base_url, path)
|
||||
resp = self._session.get(url, headers=headers)
|
||||
def get_raw(self, href, headers):
|
||||
resp = self._session.get(href, headers=headers)
|
||||
self._check_status_code(resp)
|
||||
return resp.content
|
||||
|
||||
@@ -111,9 +109,8 @@ class Client(object):
|
||||
self._check_status_code(resp)
|
||||
return resp.json()
|
||||
|
||||
def delete(self, path):
|
||||
url = '{0}/{1}/'.format(self.base_url, path)
|
||||
resp = self._session.delete(url)
|
||||
def delete(self, href):
|
||||
resp = self._session.delete(href)
|
||||
self._check_status_code(resp)
|
||||
|
||||
def _check_status_code(self, resp):
|
||||
@@ -122,10 +119,10 @@ class Client(object):
|
||||
if status == 401:
|
||||
LOG.error('Auth error: {0}'.format(resp.content))
|
||||
raise HTTPAuthError('{0}'.format(resp.content))
|
||||
if status >=500:
|
||||
if status >= 500:
|
||||
LOG.error('5xx Server error: {0}'.format(resp.content))
|
||||
raise HTTPServerError('{0}'.format(resp.content))
|
||||
if status >=400:
|
||||
if status >= 400:
|
||||
LOG.error('4xx Client error: {0}'.format(resp.content))
|
||||
raise HTTPClientError('{0}'.format(resp.content))
|
||||
|
||||
|
||||
@@ -28,8 +28,7 @@ class Order(object):
|
||||
|
||||
def __init__(self, order_dict):
|
||||
"""
|
||||
Builds an order object from a json representation. Includes the
|
||||
connection object for subtasks.
|
||||
Builds an order object from a dictionary.
|
||||
"""
|
||||
self.order_ref = order_dict['order_ref']
|
||||
self.status = order_dict.get('status')
|
||||
@@ -38,30 +37,19 @@ class Order(object):
|
||||
self.updated = timeutils.parse_isotime(order_dict['updated'])
|
||||
else:
|
||||
self.updated = None
|
||||
secret_dict = order_dict['secret']
|
||||
#TODO(dmend): This is a hack because secret_ref is in different
|
||||
# spots. Secret will be missing content_types also.
|
||||
# Maybe we should fetch the secret for this?
|
||||
secret_dict.update({'secret_ref': order_dict['secret_ref'],
|
||||
'created': order_dict['created']})
|
||||
self.secret = secrets.Secret(secret_dict)
|
||||
|
||||
self.id = urlparse.urlparse(self.order_ref).path.split('/').pop()
|
||||
self.secret_ref = order_dict.get('secret_ref')
|
||||
|
||||
def __str__(self):
|
||||
return ("Order - ID: {0}\n"
|
||||
" order href: {1}\n"
|
||||
" secret href: {2}\n"
|
||||
" created: {3}\n"
|
||||
" status: {4}\n"
|
||||
.format(self.id, self.order_ref, self.secret.secret_ref,
|
||||
return ("Order - order href: {0}\n"
|
||||
" secret href: {1}\n"
|
||||
" created: {2}\n"
|
||||
" status: {3}\n"
|
||||
.format(self.order_ref, self.secret.secret_ref,
|
||||
self.created, self.status)
|
||||
)
|
||||
|
||||
def __repr__(self):
|
||||
return 'Order(id="{0}", secret=Secret(id="{1}")'.format(
|
||||
self.id, self.secret.id
|
||||
)
|
||||
return 'Order(order_ref={0})'.format(self.order_ref)
|
||||
|
||||
|
||||
class OrderManager(base.BaseEntityManager):
|
||||
@@ -79,14 +67,14 @@ class OrderManager(base.BaseEntityManager):
|
||||
"""
|
||||
Creates a new Order in Barbican
|
||||
|
||||
:param name: A friendly name for the
|
||||
:param name: A friendly name for the secret
|
||||
:param payload_content_type: The format/type of the secret data
|
||||
:param algorithm: The algorithm the secret is used with
|
||||
:param algorithm: The algorithm the secret associated with
|
||||
:param bit_length: The bit length of the secret
|
||||
:param mode: The algorithm mode (e.g. CBC or CTR mode)
|
||||
:param expiration: The expiration time of the secret in ISO 8601
|
||||
format
|
||||
:returns: Order ID for the created order
|
||||
:returns: Order href for the created order
|
||||
"""
|
||||
LOG.debug(_("Creating order"))
|
||||
|
||||
@@ -96,42 +84,36 @@ class OrderManager(base.BaseEntityManager):
|
||||
'payload_content_type'] = payload_content_type
|
||||
order_dict['secret']['algorithm'] = algorithm
|
||||
order_dict['secret']['bit_length'] = bit_length
|
||||
#TODO(dmend): Change this to mode
|
||||
order_dict['secret']['cypher_type'] = mode
|
||||
order_dict['secret']['mode'] = mode
|
||||
order_dict['secret']['expiration'] = expiration
|
||||
self._remove_empty_keys(order_dict['secret'])
|
||||
|
||||
LOG.debug(_("Request body: {0}").format(order_dict['secret']))
|
||||
|
||||
resp = self.api.post(self.entity, order_dict)
|
||||
#TODO(dmend): return order object?
|
||||
order_id = resp['order_ref'].split('/')[-1]
|
||||
return resp['order_ref']
|
||||
|
||||
return order_id
|
||||
|
||||
def get(self, order_id):
|
||||
def get(self, order_ref):
|
||||
"""
|
||||
Returns an Order object
|
||||
|
||||
:param order_id: The UUID of the order
|
||||
:param order_ref: The href for the order
|
||||
"""
|
||||
LOG.debug(_("Getting order - Order ID: {0}").format(order_id))
|
||||
if not order_id:
|
||||
raise ValueError('order_id is required.')
|
||||
path = '{0}/{1}'.format(self.entity, order_id)
|
||||
resp = self.api.get(path)
|
||||
LOG.debug(_("Getting order - Order href: {0}").format(secret_ref))
|
||||
if not order_ref:
|
||||
raise ValueError('order_ref is required.')
|
||||
resp = self.api.get(order_ref)
|
||||
return Order(resp)
|
||||
|
||||
def delete(self, order_id):
|
||||
def delete(self, order_ref):
|
||||
"""
|
||||
Deletes an order
|
||||
|
||||
:param order_id: The UUID of the order
|
||||
:param order_ref: The href for the order
|
||||
"""
|
||||
if not order_id:
|
||||
raise ValueError('order_id is required.')
|
||||
path = '{0}/{1}'.format(self.entity, order_id)
|
||||
self.api.delete(path)
|
||||
if not order_ref:
|
||||
raise ValueError('order_ref is required.')
|
||||
self.api.delete(order_ref)
|
||||
|
||||
def list(self, limit=10, offset=0):
|
||||
params = {'limit': limit, 'offset': offset}
|
||||
|
||||
@@ -34,6 +34,7 @@ class Secret(object):
|
||||
self.secret_ref = secret_dict.get('secret_ref')
|
||||
self.name = secret_dict.get('name')
|
||||
self.status = secret_dict.get('status')
|
||||
self.content_types = secret_dict.get('content_types')
|
||||
|
||||
self.created = parse_isotime(secret_dict.get('created'))
|
||||
if secret_dict.get('expiration') is not None:
|
||||
@@ -47,23 +48,19 @@ class Secret(object):
|
||||
|
||||
self.algorithm = secret_dict.get('algorithm')
|
||||
self.bit_length = secret_dict.get('bit_length')
|
||||
self.mode = secret_dict.get('cypher_type')
|
||||
|
||||
self.content_types = secret_dict.get('content_types')
|
||||
self.id = urlparse.urlparse(self.secret_ref).path.split('/').pop()
|
||||
self.mode = secret_dict.get('mode')
|
||||
|
||||
def __str__(self):
|
||||
return ("Secret - ID: {0}\n"
|
||||
" href: {1}\n"
|
||||
" name: {2}\n"
|
||||
" created: {3}\n"
|
||||
" status: {4}\n"
|
||||
" content types: {5}\n"
|
||||
" algorithm: {6}\n"
|
||||
" bit length: {7}\n"
|
||||
" mode: {8}\n"
|
||||
" expiration: {9}\n"
|
||||
.format(self.id, self.secret_ref, self.name, self.created,
|
||||
return ("Secret - href: {0}\n"
|
||||
" name: {1}\n"
|
||||
" created: {2}\n"
|
||||
" status: {3}\n"
|
||||
" content types: {4}\n"
|
||||
" algorithm: {5}\n"
|
||||
" bit length: {6}\n"
|
||||
" mode: {7}\n"
|
||||
" expiration: {8}\n"
|
||||
.format(self.secret_ref, self.name, self.created,
|
||||
self.status, self.content_types, self.algorithm,
|
||||
self.bit_length, self.mode, self.expiration)
|
||||
)
|
||||
@@ -93,12 +90,12 @@ class SecretManager(base.BaseEntityManager):
|
||||
:param payload: The unencrypted secret data
|
||||
:param payload_content_type: The format/type of the secret data
|
||||
:param payload_content_encoding: The encoding of the secret data
|
||||
:param algorithm: The algorithm barbican should use to encrypt
|
||||
:param bit_length: The bit length of the key used for ecnryption
|
||||
:param mode: The algorithm mode (e.g. CBC or CTR mode)
|
||||
:param algorithm: The algorithm associated with this secret key
|
||||
:param bit_length: The bit length of this secret key
|
||||
:param mode: The algorithm mode used with this secret key
|
||||
:param expiration: The expiration time of the secret in ISO 8601
|
||||
format
|
||||
:returns: Secret ID for the stored secret
|
||||
:returns: Secret href for the stored secret
|
||||
"""
|
||||
LOG.debug("Creating secret of payload content type {0}".format(
|
||||
payload_content_type))
|
||||
@@ -109,8 +106,7 @@ class SecretManager(base.BaseEntityManager):
|
||||
secret_dict['payload_content_type'] = payload_content_type
|
||||
secret_dict['payload_content_encoding'] = payload_content_encoding
|
||||
secret_dict['algorithm'] = algorithm
|
||||
#TODO(dmend): Change this to 'mode'
|
||||
secret_dict['cypher_type'] = mode
|
||||
secret_dict['mode'] = mode
|
||||
secret_dict['bit_length'] = bit_length
|
||||
secret_dict['expiration'] = expiration
|
||||
self._remove_empty_keys(secret_dict)
|
||||
@@ -118,48 +114,41 @@ class SecretManager(base.BaseEntityManager):
|
||||
LOG.debug("Request body: {0}".format(secret_dict))
|
||||
|
||||
resp = self.api.post(self.entity, secret_dict)
|
||||
#TODO(dmend): return secret object?
|
||||
#secret = Secret(resp)
|
||||
secret_id = resp['secret_ref'].split('/')[-1]
|
||||
return resp['secret_ref']
|
||||
|
||||
return secret_id
|
||||
|
||||
def get(self, secret_id):
|
||||
def get(self, secret_ref):
|
||||
"""
|
||||
Returns a Secret object with information about the secret.
|
||||
|
||||
:param secret_id: The UUID of the secret
|
||||
:param secret_ref: The href for the secret
|
||||
"""
|
||||
if not secret_id:
|
||||
raise ValueError('secret_id is required.')
|
||||
path = '{0}/{1}'.format(self.entity, secret_id)
|
||||
resp = self.api.get(path)
|
||||
if not secret_ref:
|
||||
raise ValueError('secret_ref is required.')
|
||||
resp = self.api.get(secret_ref)
|
||||
return Secret(resp)
|
||||
|
||||
def raw(self, secret_id, content_type):
|
||||
def decrypt(self, secret_ref, content_type):
|
||||
"""
|
||||
Returns the actual secret data stored in Barbican.
|
||||
|
||||
:param secret_id: The UUID of the secret
|
||||
:param secret_ref: The href for the secret
|
||||
:param content_type: The content_type of the secret
|
||||
:returns: secret data
|
||||
"""
|
||||
if not all([secret_id, content_type]):
|
||||
raise ValueError('secret_id and content_type are required.')
|
||||
path = '{0}/{1}'.format(self.entity, secret_id)
|
||||
if not all([secret_ref, content_type]):
|
||||
raise ValueError('secret_ref and content_type are required.')
|
||||
headers = {'Accept': content_type}
|
||||
return self.api.get_raw(path, headers)
|
||||
return self.api.get_raw(secret_ref, headers)
|
||||
|
||||
def delete(self, secret_id):
|
||||
def delete(self, secret_ref):
|
||||
"""
|
||||
Deletes a secret
|
||||
|
||||
:param secret_id: The UUID of the secret
|
||||
:param secret_ref: The href for the secret
|
||||
"""
|
||||
if not secret_id:
|
||||
raise ValueError('secret_id is required.')
|
||||
path = '{0}/{1}'.format(self.entity, secret_id)
|
||||
self.api.delete(path)
|
||||
if not secret_ref:
|
||||
raise ValueError('secret_ref is required.')
|
||||
self.api.delete(secret_ref)
|
||||
|
||||
def list(self, limit=10, offset=0):
|
||||
|
||||
|
||||
Reference in New Issue
Block a user