diff --git a/barbicanclient/client.py b/barbicanclient/client.py index 22b29892..58699551 100644 --- a/barbicanclient/client.py +++ b/barbicanclient/client.py @@ -1,18 +1,21 @@ - -from eventlet.green.urllib import quote import eventlet eventlet.monkey_patch(socket=True, select=True) import json import requests + from barbicanclient.secrets import Secret +from barbicanclient.orders import Order from barbicanclient.common.auth import authenticate from barbicanclient.common.exceptions import ClientException from urlparse import urljoin class Connection(object): + SECRETS_PATH = 'secrets' + ORDERS_PATH = 'orders' + def __init__(self, auth_endpoint, user, key, tenant, **kwargs): """ :param auth_endpoint: The auth URL to authenticate against @@ -29,9 +32,6 @@ class Connection(object): self.connect() - # Hardcoded uri's right now - self.secrets_href = 'secrets/' - @property def _conn(self): """ @@ -90,8 +90,7 @@ class Connection(object): """ Returns the list of secrets for the auth'd tenant """ - #href = proc_template(self.secrets_href) - href = "%s/%s" % (self._tenant, self.secrets_href) + href = "%s/%s?limit=100" % (self._tenant, self.SECRETS_PATH) hdrs, body = self._perform_http(href=href, method='GET') secrets_dict = body['secrets'] @@ -101,62 +100,42 @@ class Connection(object): return secrets - # - # def create_queue(self, queue_name): - # """ - # Creates a queue with the specified name - # - # :param queue_name: The name of the queue - # :param ttl: The default time-to-live for messages in this queue - # """ - # href = proc_template(self.queue_href, queue_name=queue_name) - # body = {} - # - # self._perform_http(href=href, method='PUT', request_body=body) - # - # return Queue(self, href=href, name=queue_name, metadata=body) - # - # def get_queue(self, queue_name): - # """ - # Gets a queue by name - # - # :param queue_name: The name of the queue - # """ - # href = proc_template(self.queue_href, queue_name=queue_name) - # - # try: - # hdrs, body = self._perform_http(href=href, method='GET') - # except ClientException as ex: - # raise NoSuchQueueError(queue_name) if ex.http_status == 404 else ex - # - # return Queue(self, href=href, name=queue_name, metadata=body) - # - # def get_queues(self): - # href = self.queues_href - # - # hdrs, res = self._perform_http(href=href, method='GET') - # queues = res["queues"] - # - # for queue in queues: - # yield Queue(conn=self._conn, name=queue['name'], - # href=queue['href'], metadata=queue['metadata']) - # - # def delete_queue(self, queue_name): - # """ - # Deletes a queue - # - # :param queue_name: The name of the queue - # """ - # href = proc_template(self.queue_href, queue_name=queue_name) - # self._perform_http(href=href, method='DELETE') - # - # def get_queue_metadata(self, queue_name): - # href = proc_template(self._queue_href, queue_name=queue_name) - # - # try: - # return self._perform_http(conn, href, 'GET') - # except ClientException as ex: - # raise NoSuchQueueError(queue_name) if ex.http_status == 404 else ex + def list_orders(self): + """ + Returns the list of orders + """ + href = "%s/%s?limit=100" % (self._tenant, self.ORDERS_PATH) + hdrs, body = self._perform_http(href=href, method='GET') + + orders_dict = body['orders'] + orders = [] + for o in orders_dict: + orders.append(Order(self._conn, o)) + + return orders + + def create_order(self, + name, + mime_type, + algorithm, + bit_length, + cypher_type): + href = "%s/%s" % (self._tenant, self.ORDERS_PATH) + order_dict = {'secret': {}} + order_dict['secret']['name'] = name + order_dict['secret']['mime_type'] = mime_type + order_dict['secret']['algorithm'] = algorithm + order_dict['secret']['bit_length'] = bit_length + order_dict['secret']['cypher_type'] = cypher_type + hdrs, body = self._perform_http(href=href, + method='POST', + request_body=json.dumps(order_dict)) + return body['order_ref'] + + def delete_order(self, order_id): + href = "%s/%s/%s" % (self._tenant, self.ORDERS_PATH, order_id) + hdrs, body = self._perform_http(href=href, method='DELETE') + # TODO: should this return something def _perform_http(self, method, href, request_body='', headers={}): """ diff --git a/barbicanclient/orders.py b/barbicanclient/orders.py new file mode 100644 index 00000000..28318cf2 --- /dev/null +++ b/barbicanclient/orders.py @@ -0,0 +1,41 @@ +from urlparse import urlparse +from openstack.common.timeutils import parse_isotime + + +class Order(object): + + def __init__(self, connection, dict): + """ + Builds an order object from a json representation. Includes the + connection object for subtasks. + """ + self.connection = connection + self.status = dict.get('status') + self.secret = dict.get('secret') # TODO: figure out what to do here + self.secret_ref = dict.get('secret_ref') + self.order_ref = dict.get('order_ref') + self.created = parse_isotime(dict.get('created')) + if dict.get('updated') is not None: + self.updated = parse_isotime(dict['updated']) + + self._id = urlparse(self.order_ref).path.split('/').pop() + + @property + def id(self): + return self._id + + def save(self): + self.connection.update_order(self) + + def delete(self): + self.connection.delete_order(self) + + def __repr__(self): + s = "" % self.id + s += "\n Status: %s" % self.status + s += "\n Secret: %s" % self.secret + s += "\n Secret ref: %s" % self.secret_ref + s += "\n Order ref: %s" % self.order_ref + s += "\n Created: %s" % self.created + s += "\n Updated: %s" % self.updated + return s diff --git a/barbicanclient/secrets.py b/barbicanclient/secrets.py index c0b4164d..16ac2e80 100644 --- a/barbicanclient/secrets.py +++ b/barbicanclient/secrets.py @@ -12,27 +12,46 @@ class Secret(object): connection object for subtasks. """ self._connection = connection - self._href = dict['secret_ref'] - self._created = parse_isotime(dict['created']) - self._status = dict['status'] + self.secret_ref = dict['secret_ref'] + self.created = parse_isotime(dict['created']) + self.status = dict['status'] - self._algorithm = dict.get('algorithm') - self._bit_length = dict.get('bit_length') - self._mime_type = dict.get('mime_type') - self._name = dict.get('name') - self._cypher_type = dict.get('cypher_type') + self.algorithm = dict.get('algorithm') + self.bit_length = dict.get('bit_length') + self.mime_type = dict.get('mime_type') + self.name = dict.get('name') + self.cypher_type = dict.get('cypher_type') if dict.get('expiration') is not None: - self._expiration = parse_isotime(dict['expiration']) + self.expiration = parse_isotime(dict['expiration']) + else: + self.expiration = None if dict.get('updated') is not None: - self._updated = parse_isotime(dict['updated']) + self.updated = parse_isotime(dict['updated']) + else: + self.updated = None - self._id = urlparse(self._href).path.split('/').pop() + self._id = urlparse(self.secret_ref).path.split('/').pop() @property def id(self): return self._id def __repr__(self): - return "" % self.id + """ + returns a string representation of the object + TODO: properly handle optional fields + """ + s = "" % self.id + s += "\n Name: %s" % self.name + s += "\n Status: %s" % self.status + s += "\n Secret Ref: %s" % self.secret_ref + s += "\n Created: %s" % self.created + s += "\n Updated: %s" % self.updated + if self.expiration is not None: + s += "\n Expiration: %s" % self.expiration + s += "\n Algorithm: %s" % self.algorithm + s += "\n Cypher Type: %s" % self.cypher_type + s += "\n Bit Length: %s" % self.bit_length + return s diff --git a/examples/create_order.py b/examples/create_order.py new file mode 100644 index 00000000..6b2e44aa --- /dev/null +++ b/examples/create_order.py @@ -0,0 +1,77 @@ +import argparse + +from barbicanclient import client + +IDENTITY = 'https://identity.api.rackspacecloud.com/v2.0' +ENDPOINT = 'https://barbican.api.rackspacecloud.com/v1/' + + +def connect(username, password, tenant, endpoint): + connection = client.Connection(IDENTITY, + username, + password, + tenant, + endpoint=endpoint) + return connection + + +def parse_args(): + parser = argparse.ArgumentParser( + description='Testing code for creating barbican order.' + ) + parser.add_argument( + '--username', + help='The keystone username used for for authentication' + ) + parser.add_argument( + '--password', + help='The keystone password used for for authentication' + ) + parser.add_argument( + '--tenant', + help='The keystone tenant used for for authentication' + ) + parser.add_argument( + '--keystone', + default=IDENTITY, + help='The keystone endpoint used for for authentication' + ) + parser.add_argument( + '--endpoint', + default=ENDPOINT, + help='The barbican endpoint to test against' + ) + parser.add_argument( + '--name', + help='Name of secret' + ) + parser.add_argument( + '--mime-type', + help='MIME type of secret to create' + ) + parser.add_argument( + '--algorithm', + help='Algorithm of secret to create' + ) + parser.add_argument( + '--bit-length', + help='Bit length of secret to create' + ) + parser.add_argument( + '--cypher-type', + help='Cypher type of secret to create' + ) + + args = parser.parse_args() + return args + + +if __name__ == '__main__': + args = parse_args() + conn = connect(args.username, args.password, args.tenant, args.endpoint) + order = conn.create_order(args.name, + args.mime_type, + args.algorithm, + args.bit_length, + args.cypher_type) + print order diff --git a/examples/delete_order.py b/examples/delete_order.py new file mode 100644 index 00000000..f0690548 --- /dev/null +++ b/examples/delete_order.py @@ -0,0 +1,56 @@ +import argparse + +from barbicanclient import client + +IDENTITY = 'https://identity.api.rackspacecloud.com/v2.0' +ENDPOINT = 'https://barbican.api.rackspacecloud.com/v1/' + + +def connect(username, password, tenant, endpoint): + connection = client.Connection(IDENTITY, + username, + password, + tenant, + endpoint=endpoint) + return connection + + +def parse_args(): + parser = argparse.ArgumentParser( + description='Testing code for creating barbican order.' + ) + parser.add_argument( + '--username', + help='The keystone username used for for authentication' + ) + parser.add_argument( + '--password', + help='The keystone password used for for authentication' + ) + parser.add_argument( + '--tenant', + help='The keystone tenant used for for authentication' + ) + parser.add_argument( + '--keystone', + default=IDENTITY, + help='The keystone endpoint used for for authentication' + ) + parser.add_argument( + '--endpoint', + default=ENDPOINT, + help='The barbican endpoint to test against' + ) + parser.add_argument( + '--order-id', + help='ID of secret' + ) + + args = parser.parse_args() + return args + + +if __name__ == '__main__': + args = parse_args() + conn = connect(args.username, args.password, args.tenant, args.endpoint) + conn.delete_order(args.order_id) diff --git a/examples/list_orders.py b/examples/list_orders.py new file mode 100644 index 00000000..2674668b --- /dev/null +++ b/examples/list_orders.py @@ -0,0 +1,55 @@ +import argparse + +from barbicanclient import client + +IDENTITY = 'https://identity.api.rackspacecloud.com/v2.0' +ENDPOINT = 'https://barbican.api.rackspacecloud.com/v1/' + + +def list_orders(username, password, tenant, endpoint): + connection = client.Connection(IDENTITY, + username, + password, + tenant, + endpoint=endpoint) + orders = connection.list_orders() + + print 'Current Secrets (%d):' % (len(orders)) + for order in orders: + print '- %s' % order + + +def parse_args(): + parser = argparse.ArgumentParser( + description='Testing code for barbican secrets api resource.' + ) + parser.add_argument( + '--username', + help='The keystone username used for for authentication' + ) + parser.add_argument( + '--password', + help='The keystone password used for for authentication' + ) + parser.add_argument( + '--tenant', + help='The keystone tenant used for for authentication' + ) + parser.add_argument( + '--keystone', + default=IDENTITY, + help='The keystone endpoint used for for authentication' + ) + parser.add_argument( + '--endpoint', + default=ENDPOINT, + help='The barbican endpoint to test against' + ) + + args = parser.parse_args() + return args + + +if __name__ == '__main__': + args = parse_args() + list_orders(args.username, args.password, args.tenant, args.endpoint) diff --git a/examples/secrets.py b/examples/list_secrets.py similarity index 98% rename from examples/secrets.py rename to examples/list_secrets.py index f81cb612..cef47d40 100644 --- a/examples/secrets.py +++ b/examples/list_secrets.py @@ -16,6 +16,7 @@ def list_secrets(username, password, tenant, endpoint): print 'Current Secrets (%d):' % (len(secrets)) for secret in secrets: + print secret print '- %s' % secret