From 99f6d9f3678cac74a07d15e091e99edfb2a1d280 Mon Sep 17 00:00:00 2001 From: Arash Ghoreyshi Date: Thu, 20 Jun 2013 16:47:38 -0500 Subject: [PATCH 1/9] Fix authentication and service endpoint fetching Make the client library take environment variables by default --- barbicanclient/client.py | 64 +++++++++++++++++++++++++++++++--------- keep | 41 +++++++++---------------- tests/client_test.py | 18 +++++++++-- 3 files changed, 80 insertions(+), 43 deletions(-) diff --git a/barbicanclient/client.py b/barbicanclient/client.py index acf77240..7f6fb752 100644 --- a/barbicanclient/client.py +++ b/barbicanclient/client.py @@ -2,6 +2,7 @@ import eventlet eventlet.monkey_patch(socket=True, select=True) import json +import os import requests from barbicanclient.secrets import Secret @@ -22,24 +23,36 @@ class Connection(object): SECRETS_PATH = 'secrets' ORDERS_PATH = 'orders' - def __init__(self, auth_endpoint, user, key, tenant, - token=None, authenticate=None, request=None, **kwargs): + def __init__(self, auth_endpoint=None, user=None, key=None, tenant=None, + token=None, authenticate=None, request=None, fake_env=None, + **kwargs): """ + Authenticate and connect to the endpoint + :param auth_endpoint: The auth URL to authenticate against + default: env('OS_AUTH_URL') :param user: The user to authenticate as + default: env('OS_USERNAME') :param key: The API key or password to auth with + default: env('OS_PASSWORD') + :param tenant: The tenant ID + default: env('OS_TENANT_NAME') """ LOG.debug(_("Creating Connection object")) - self._auth_endpoint = auth_endpoint + self.env = fake_env or env + self._auth_endpoint = auth_endpoint or self.env('OS_AUTH_URL') + self._user = user or self.env('OS_USERNAME') + self._key = key or self.env('OS_PASSWORD') + self._tenant = tenant or self.env('OS_TENANT_NAME') + if not all([self._auth_endpoint, self._user, self._key, self._tenant]): + raise ClientException("The authorization endpoint, username, key," + " and tenant name should either be passed i" + "n or defined as environment variables.") self.authenticate = authenticate or auth.authenticate self.request = request or requests.request - self._user = user - self._key = key - self._tenant = tenant - self._endpoint = (kwargs.get('endpoint') - or 'https://barbican.api.rackspacecloud.com/v1/') + self._endpoint = kwargs.get('endpoint') self._cacert = kwargs.get('cacert') self.connect(token=token) @@ -47,8 +60,7 @@ class Connection(object): @property def _conn(self): """ - Property to enable decorators to work - properly + Property to enable decorators to work properly """ return self @@ -62,6 +74,10 @@ class Connection(object): """The fully-qualified URI of the endpoint""" return self._endpoint + @endpoint.setter + def endpoint(self, value): + self._endpoint = value + def connect(self, token=None): """ Establishes a connection. If token is not None the @@ -81,11 +97,12 @@ class Connection(object): self.auth_token = token else: LOG.debug(_("Authenticating token")) - self._endpoint, self.auth_token = self.authenticate( + self.endpoint, self.auth_token = self.authenticate( self._auth_endpoint, self._user, self._key, self._tenant, + service_type='key-store', endpoint=self._endpoint, cacert=self._cacert ) @@ -149,7 +166,7 @@ class Connection(object): cypher_type=None, expiration=None): """ - Creates and returns a Secret object with all of its metadata filled in. + Creates and returns an Order object with all of its metadata filled in. arguments: mime_type - The MIME type of the secret @@ -356,11 +373,15 @@ class Connection(object): if not isinstance(request_body, str): request_body = json.dumps(request_body) - url = urljoin(self._endpoint, href) + if not self.endpoint.endswith('/'): + self.endpoint += '/' + + url = urljoin(self.endpoint, href) + + headers['X-Auth-Token'] = self.auth_token response = self.request(method=method, url=url, data=request_body, headers=headers) - # Check if the status code is 2xx class if not response.ok: LOG.error('Bad response: {0}'.format(response.status_code)) @@ -376,3 +397,18 @@ class Connection(object): resp_body = '' return response.headers, resp_body + + +def env(*vars, **kwargs): + """Search for the first defined of possibly many env vars + + Returns the first environment variable defined in vars, or + returns the default defined in kwargs. + + Source: Keystone's shell.py + """ + for v in vars: + value = os.environ.get(v, None) + if value: + return value + return kwargs.get('default', '') diff --git a/keep b/keep index adcd4a14..d9b49559 100755 --- a/keep +++ b/keep @@ -1,7 +1,6 @@ #!/usr/bin/env python import argparse -import os from barbicanclient import client @@ -24,23 +23,26 @@ class Keep: choices=["order", "secret"], help="type to operate on") parser.add_argument('--auth_endpoint', '-A', - default=env('OS_AUTH_URL'), + default=client.env('OS_AUTH_URL'), help='the URL to authenticate against (default: ' '%(default)s)') - parser.add_argument('--user', '-U', default=env('OS_USERNAME'), + parser.add_argument('--user', '-U', default=client.env('OS_USERNAME'), help='the user to authenticate as (default: %(de' 'fault)s)') - parser.add_argument('--password', '-P', default=env('OS_PASSWORD'), + parser.add_argument('--password', '-P', + default=client.env('OS_PASSWORD'), help='the API key or password to authenticate with' ' (default: %(default)s)') - parser.add_argument('--tenant', '-T', default=env('OS_TENANT_NAME'), + parser.add_argument('--tenant', '-T', + default=client.env('OS_TENANT_NAME'), help='the tenant ID (default: %(default)s)') - parser.add_argument('--endpoint', '-E', default=env('SERVICE_ENDPOINT') - , help='the URL of the barbican server (default: %' + parser.add_argument('--endpoint', '-E', + default=client.env('SERVICE_ENDPOINT'), + help='the URL of the barbican server (default: %' '(default)s)') - parser.add_argument('--token', '-K', default=env('SERVICE_TOKEN'), - help='the authentication token (default: %(default' - ')s)') + parser.add_argument('--token', '-K', + default=client.env('SERVICE_TOKEN'), help='the au' + 'thentication token (default: %(default)s)') return parser def add_create_args(self): @@ -149,8 +151,8 @@ class Keep: l = self.conn.list_orders(args.limit, args.offset) for i in l[0]: print i - print 'Displayed {0} {1}s - offset: {2}'.format(len(l[0]), args.type, - args.offset) + print '{0}s displayed: {1} - offset: {2}'.format(args.type, len(l[0]), + args.offset) def execute(self): args = self.parser.parse_args() @@ -161,21 +163,6 @@ class Keep: args.func(args) -def env(*vars, **kwargs): - """Search for the first defined of possibly many env vars - - Returns the first environment variable defined in vars, or - returns the default defined in kwargs. - - Source: Keystone's shell.py - """ - for v in vars: - value = os.environ.get(v, None) - if value: - return value - return kwargs.get('default', '') - - def main(): k = Keep() k.execute() diff --git a/tests/client_test.py b/tests/client_test.py index 44205c3b..eeebf908 100644 --- a/tests/client_test.py +++ b/tests/client_test.py @@ -40,6 +40,8 @@ class WhenTestingConnection(unittest.TestCase): self.auth_token = 'token' self.href = 'http://localhost:9311/v1/12345/orders' + self.fake_env = MagicMock() + self.fake_env.return_value = None self.authenticate = MagicMock() self.authenticate.return_value = (self.endpoint, self.auth_token) self.request = MagicMock() @@ -62,7 +64,8 @@ class WhenTestingConnection(unittest.TestCase): self.key, self.tenant, token=self.auth_token, authenticate=self.authenticate, - request=self.request) + request=self.request, + endpoint=self.endpoint) def test_should_connect_with_token(self): self.assertFalse(self.authenticate.called) @@ -79,6 +82,7 @@ class WhenTestingConnection(unittest.TestCase): self.user, self.key, self.tenant, + service_type='key-store', endpoint=self.endpoint, cacert=None ) @@ -89,6 +93,16 @@ class WhenTestingConnection(unittest.TestCase): self.assertEqual(self.tenant, self.connection._tenant) self.assertEqual(self.endpoint, self.connection._endpoint) + def test_should_raise_for_bad_args(self): + with self.assertRaises(ClientException): + self.connection = client.Connection(None, self.user, + self.key, self.tenant, + fake_env=self.fake_env, + token=self.auth_token, + authenticate=self.authenticate, + request=self.request, + endpoint=self.endpoint) + def test_should_create_secret(self): body = {'status': 'ACTIVE', 'content_types': {'default': 'text/plain'}, @@ -318,7 +332,7 @@ class WhenTestingConnection(unittest.TestCase): parse_json=False) self.assertEqual(self.request.return_value.content, body) - def test_should_raise_exception(self): + def test_should_raise_for_bad_response(self): self._setup_request() self.request.return_value.ok = False self.request.return_value.status_code = 404 From 3bfa9170fcaa3f7b540673186537e32801cdcd61 Mon Sep 17 00:00:00 2001 From: Arash Ghoreyshi Date: Fri, 21 Jun 2013 11:24:11 -0500 Subject: [PATCH 2/9] Stop overriding the endpoint when it's provided without a token Add a default clientrc file --- barbicanclient/client.py | 12 +++++++++--- clientrc | 6 ++++++ 2 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 clientrc diff --git a/barbicanclient/client.py b/barbicanclient/client.py index 7f6fb752..2908ef01 100644 --- a/barbicanclient/client.py +++ b/barbicanclient/client.py @@ -27,7 +27,8 @@ class Connection(object): token=None, authenticate=None, request=None, fake_env=None, **kwargs): """ - Authenticate and connect to the endpoint + Authenticate and connect to the service endpoint, which is usually + received through authentication. :param auth_endpoint: The auth URL to authenticate against default: env('OS_AUTH_URL') @@ -37,6 +38,9 @@ class Connection(object): default: env('OS_PASSWORD') :param tenant: The tenant ID default: env('OS_TENANT_NAME') + :keyword param endpoint: The service endpoint to connect to + + If a token is provided, an endpoint should be as well. """ LOG.debug(_("Creating Connection object")) @@ -97,7 +101,7 @@ class Connection(object): self.auth_token = token else: LOG.debug(_("Authenticating token")) - self.endpoint, self.auth_token = self.authenticate( + endpoint, self.auth_token = self.authenticate( self._auth_endpoint, self._user, self._key, @@ -106,6 +110,8 @@ class Connection(object): endpoint=self._endpoint, cacert=self._cacert ) + if self.endpoint is None: + self.endpoint = endpoint @property def auth_token(self): @@ -166,7 +172,7 @@ class Connection(object): cypher_type=None, expiration=None): """ - Creates and returns an Order object with all of its metadata filled in. + Creates and returns a Secret object with all of its metadata filled in. arguments: mime_type - The MIME type of the secret diff --git a/clientrc b/clientrc new file mode 100644 index 00000000..e953c919 --- /dev/null +++ b/clientrc @@ -0,0 +1,6 @@ +export OS_TENANT_NAME=demo +export OS_USERNAME=demo +export OS_PASSWORD=password +export OS_AUTH_URL="http://keystone-int.cloudkeep.io:5000/v2.0/" +export SERVICE_ENDPOINT="http://api-01-int.cloudkeep.io:9311/v1/" +export SERVICE_TOKEN='' From a496993c4f96e2d010f58b9e3e314cf516384982 Mon Sep 17 00:00:00 2001 From: Arash Ghoreyshi Date: Fri, 21 Jun 2013 11:24:11 -0500 Subject: [PATCH 3/9] Stop overriding the endpoint when it's provided without a token Add a default clientrc file --- barbicanclient/client.py | 15 +++++++++++---- clientrc | 6 ++++++ 2 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 clientrc diff --git a/barbicanclient/client.py b/barbicanclient/client.py index 7f6fb752..17b32c93 100644 --- a/barbicanclient/client.py +++ b/barbicanclient/client.py @@ -27,7 +27,8 @@ class Connection(object): token=None, authenticate=None, request=None, fake_env=None, **kwargs): """ - Authenticate and connect to the endpoint + Authenticate and connect to the service endpoint, which is usually + received through authentication. :param auth_endpoint: The auth URL to authenticate against default: env('OS_AUTH_URL') @@ -37,6 +38,10 @@ class Connection(object): default: env('OS_PASSWORD') :param tenant: The tenant ID default: env('OS_TENANT_NAME') + :keyword param endpoint: The service endpoint to connect to + default: env('SERVICE_ENDPOINT') + + If a token is provided, an endpoint should be as well. """ LOG.debug(_("Creating Connection object")) @@ -52,7 +57,7 @@ class Connection(object): "n or defined as environment variables.") self.authenticate = authenticate or auth.authenticate self.request = request or requests.request - self._endpoint = kwargs.get('endpoint') + self._endpoint = kwargs.get('endpoint') or self.env('SERVICE_ENDPOINT') self._cacert = kwargs.get('cacert') self.connect(token=token) @@ -97,7 +102,7 @@ class Connection(object): self.auth_token = token else: LOG.debug(_("Authenticating token")) - self.endpoint, self.auth_token = self.authenticate( + endpoint, self.auth_token = self.authenticate( self._auth_endpoint, self._user, self._key, @@ -106,6 +111,8 @@ class Connection(object): endpoint=self._endpoint, cacert=self._cacert ) + if self.endpoint is None: + self.endpoint = endpoint @property def auth_token(self): @@ -166,7 +173,7 @@ class Connection(object): cypher_type=None, expiration=None): """ - Creates and returns an Order object with all of its metadata filled in. + Creates and returns a Secret object with all of its metadata filled in. arguments: mime_type - The MIME type of the secret diff --git a/clientrc b/clientrc new file mode 100644 index 00000000..e953c919 --- /dev/null +++ b/clientrc @@ -0,0 +1,6 @@ +export OS_TENANT_NAME=demo +export OS_USERNAME=demo +export OS_PASSWORD=password +export OS_AUTH_URL="http://keystone-int.cloudkeep.io:5000/v2.0/" +export SERVICE_ENDPOINT="http://api-01-int.cloudkeep.io:9311/v1/" +export SERVICE_TOKEN='' From 7656b99ecbb917b0c4f3f03f9cd84a5c54b33207 Mon Sep 17 00:00:00 2001 From: Arash Ghoreyshi Date: Fri, 21 Jun 2013 17:46:36 -0500 Subject: [PATCH 4/9] Complete docstrings in the client library and make them uniform --- barbicanclient/client.py | 97 +++++++++++++++++++++++++++------------- 1 file changed, 65 insertions(+), 32 deletions(-) diff --git a/barbicanclient/client.py b/barbicanclient/client.py index 17b32c93..8673c343 100644 --- a/barbicanclient/client.py +++ b/barbicanclient/client.py @@ -27,9 +27,12 @@ class Connection(object): token=None, authenticate=None, request=None, fake_env=None, **kwargs): """ - Authenticate and connect to the service endpoint, which is usually + Authenticate and connect to the service endpoint, which can be received through authentication. + Environment variables will be used by default when their corresponding + arguments are not passed in. + :param auth_endpoint: The auth URL to authenticate against default: env('OS_AUTH_URL') :param user: The user to authenticate as @@ -64,9 +67,7 @@ class Connection(object): @property def _conn(self): - """ - Property to enable decorators to work properly - """ + """Property to enable decorators to work properly""" return self @property @@ -85,9 +86,10 @@ class Connection(object): def connect(self, token=None): """ - Establishes a connection. If token is not None the - token will be used for this connection and auth will - not happen. + Establishes a connection. If token is not None or empty, it will be + used for this connection, and authentication will not take place. + + :param token: An authentication token """ LOG.debug(_("Establishing connection")) @@ -132,6 +134,9 @@ class Connection(object): to the given offset and limit, a reference to the previous set of secrets, and a reference to the next set of secrets. Either of the references may be None. + + :param limit: The limit to the number of secrets to list + :param offset: The offset from the beginning to start listing """ LOG.debug(_("Listing secrets - offset: {0}, limit: {1}").format(offset, limit)) @@ -146,6 +151,8 @@ class Connection(object): to the offset and limit within href, a reference to the previous set of secrets, and a reference to the next set of secrets. Either of the references may be None. + + :param href: The full secrets URI """ LOG.debug(_("Listing secrets by href")) LOG.debug("href: {0}".format(href)) @@ -175,14 +182,13 @@ class Connection(object): """ Creates and returns a Secret object with all of its metadata filled in. - arguments: - mime_type - The MIME type of the secret - plain_text - The unencrypted secret - name - A friendly name for the secret - algorithm - The algorithm the secret is used with - bit_length - The bit length of the secret - cypher_type - The cypher type (e.g. block cipher mode of operation) - expiration - The expiration time for the secret in ISO 8601 format + :param mime_type: The MIME type of the secret + :param plain_text: The unencrypted secret + :param name: A friendly name for the secret + :param algorithm: The algorithm the secret is used with + :param bit_length: The bit length of the secret + :param cypher_type: The cypher type (e.g. block cipher mode) + :param expiration: The expiration time of the secret in ISO 8601 format """ LOG.debug(_("Creating secret of mime_type {0}").format(mime_type)) href = "{0}/{1}".format(self._tenant, self.SECRETS_PATH) @@ -209,7 +215,9 @@ class Connection(object): def delete_secret_by_id(self, secret_id): """ - Deletes a secret using its UUID + Deletes a secret + + :param secret_id: The UUID of the secret """ href = "{0}/{1}/{2}".format(self._tenant, self.SECRETS_PATH, secret_id) LOG.info(_("Deleting secret - Secret ID: {0}").format(secret_id)) @@ -217,14 +225,18 @@ class Connection(object): def delete_secret(self, href): """ - Deletes a secret using its full reference + Deletes a secret + + :param href: The full URI of the secret """ hdrs, body = self._perform_http(href=href, method='DELETE') LOG.debug(_("Response - headers: {0}\nbody: {1}").format(hdrs, body)) def get_secret_by_id(self, secret_id): """ - Returns a Secret object using the secret's UUID + Returns a Secret object + + :param secret_id: The UUID of the secret """ LOG.debug(_("Getting secret - Secret ID: {0}").format(secret_id)) href = "{0}/{1}/{2}".format(self._tenant, self.SECRETS_PATH, secret_id) @@ -232,7 +244,9 @@ class Connection(object): def get_secret(self, href): """ - Returns a Secret object using the secret's full reference + Returns a Secret object + + :param href: The full URI of the secret """ hdrs, body = self._perform_http(href=href, method='GET') LOG.debug(_("Response - headers: {0}\nbody: {1}").format(hdrs, body)) @@ -240,7 +254,10 @@ class Connection(object): def get_raw_secret_by_id(self, secret_id, mime_type): """ - Returns the raw secret using the secret's UUID and MIME type + Returns the raw secret + + :param secret_id: The UUID of the secret + :param mime_type: The MIME type of the secret """ LOG.debug(_("Getting raw secret - Secret ID: {0}").format(secret_id)) href = "{0}/{1}/{2}".format(self._tenant, self.SECRETS_PATH, secret_id) @@ -248,7 +265,10 @@ class Connection(object): def get_raw_secret(self, href, mime_type): """ - Returns the raw secret using the secret's UUID and MIME type + Returns the raw secret + + :param href: The reference to the secret + :param mime_type: The MIME type of the secret """ hdrs = {"Accept": mime_type} hdrs, body = self._perform_http(href=href, method='GET', headers=hdrs, @@ -262,6 +282,9 @@ class Connection(object): to the given offset and limit, a reference to the previous set of orders, and a reference to the next set of orders. Either of the references may be None. + + :param limit: The limit to the number of orders to list + :param offset: The offset from the beginning to start listing """ LOG.debug(_("Listing orders - offset: {0}, limit: {1}").format(offset, limit)) @@ -276,6 +299,8 @@ class Connection(object): to the offset and limit within href, a reference to the previous set of orders, and a reference to the next set of orders. Either of the references may be None. + + :param href: The full orders URI """ LOG.debug(_("Listing orders by href")) LOG.debug("href: {0}".format(href)) @@ -303,12 +328,11 @@ class Connection(object): """ Creates and returns an Order object with all of its metadata filled in. - arguments: - mime_type - The MIME type of the secret - name - A friendly name for the secret - algorithm - The algorithm the secret is used with - bit_length - The bit length of the secret - cypher_type - The cypher type (e.g. block cipher mode of operation) + :param mime_type: The MIME type of the secret + :param name: A friendly name for the secret + :param algorithm: The algorithm the secret is used with + :param bit_length: The bit length of the secret + :param cypher_type: The cypher type (e.g. block cipher mode) """ LOG.debug(_("Creating order of mime_type {0}").format(mime_type)) href = "{0}/{1}".format(self._tenant, self.ORDERS_PATH) @@ -331,7 +355,9 @@ class Connection(object): def delete_order_by_id(self, order_id): """ - Deletes an order using its UUID + Deletes an order + + :param order_id: The UUID of the order """ LOG.info(_("Deleting order - Order ID: {0}").format(order_id)) href = "{0}/{1}/{2}".format(self._tenant, self.ORDERS_PATH, order_id) @@ -339,14 +365,18 @@ class Connection(object): def delete_order(self, href): """ - Deletes an order using its full reference + Deletes an order + + :param href: The full URI of the order """ hdrs, body = self._perform_http(href=href, method='DELETE') LOG.debug(_("Response - headers: {0}\nbody: {1}").format(hdrs, body)) def get_order_by_id(self, order_id): """ - Returns an Order object using the order's UUID + Returns an Order object + + :param order_id: The UUID of the order """ LOG.debug(_("Getting order - Order ID: {0}").format(order_id)) href = "{0}/{1}/{2}".format(self._tenant, self.ORDERS_PATH, order_id) @@ -354,7 +384,9 @@ class Connection(object): def get_order(self, href): """ - Returns an Order object using the order's full reference + Returns an Order object + + :param href: The full URI of the order """ hdrs, body = self._perform_http(href=href, method='GET') LOG.debug(_("Response - headers: {0}\nbody: {1}").format(hdrs, body)) @@ -371,11 +403,12 @@ class Connection(object): Perform an HTTP operation, checking for appropriate errors, etc. and returns the response + Returns the headers and body as a tuple. + :param method: The http method to use (GET, PUT, etc) :param body: The optional body to submit :param headers: Any additional headers to submit :param parse_json: Whether the response body should be parsed as json - :return: (headers, body) """ if not isinstance(request_body, str): request_body = json.dumps(request_body) From fbe127502db01902882aa7a139794b19b23da2fe Mon Sep 17 00:00:00 2001 From: Arash Ghoreyshi Date: Mon, 24 Jun 2013 11:00:00 -0500 Subject: [PATCH 5/9] Delete and stop tracking an OSX metadata file --- .gitignore | 3 +++ barbicanclient/openstack/.DS_Store | Bin 6148 -> 0 bytes 2 files changed, 3 insertions(+) delete mode 100644 barbicanclient/openstack/.DS_Store diff --git a/.gitignore b/.gitignore index 76ae125e..d2b22e13 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,6 @@ nosetests.xml # generic venvs .venv + +# OSX metadata +.DS_Store diff --git a/barbicanclient/openstack/.DS_Store b/barbicanclient/openstack/.DS_Store deleted file mode 100644 index 94e8390ae962e15cb3acaeb6fc15ce9a113b765a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKOH0E*5Z-NTji}Iz(BtB{NNSaO@DM@;k3tGPSkc6Y4a96|QhTV;AozRyH~t=H zb~lG$&LVau?0&QJ*vALi2V;!8%dpQ_hcRYBLFA~^2%2kM4HJyWRUeWi!77~xu?%WD z`imx zdgf=#)b$t2bLD3<@F;yOWeob%L{FkHo85N0>-F*JpeOo6JMW40aA^0$$>1!{cR)HH z*1_S?`Q_Mu$zR_J%^wG}5_FOGpe51H=F^u)z$NL&4hJ zU=C>M!~ii+&j9WZ0t%vIu+XTs4yf?@jQ$oP3h4NjKokZYgM~)$fN-4(s8hLlVsM=f zc46WigM~(&&bS&G`Y|Jyj~A{+2fI+=j5`{sCI*OsDg#a3?BMx-0l!S`BfpwLEn Date: Mon, 24 Jun 2013 15:32:47 -0500 Subject: [PATCH 6/9] Change the SERVICE_ENDPOINT env variable to BARBICAN_ENDPOINT Add mock functions to kwargs in the Connection class --- barbicanclient/client.py | 16 ++++++++-------- clientrc | 2 +- keep | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/barbicanclient/client.py b/barbicanclient/client.py index 8673c343..391f5a57 100644 --- a/barbicanclient/client.py +++ b/barbicanclient/client.py @@ -24,8 +24,7 @@ class Connection(object): ORDERS_PATH = 'orders' def __init__(self, auth_endpoint=None, user=None, key=None, tenant=None, - token=None, authenticate=None, request=None, fake_env=None, - **kwargs): + token=None, **kwargs): """ Authenticate and connect to the service endpoint, which can be received through authentication. @@ -41,15 +40,15 @@ class Connection(object): default: env('OS_PASSWORD') :param tenant: The tenant ID default: env('OS_TENANT_NAME') - :keyword param endpoint: The service endpoint to connect to - default: env('SERVICE_ENDPOINT') + :keyword param endpoint: The barbican endpoint to connect to + default: env('BARBICAN_ENDPOINT') If a token is provided, an endpoint should be as well. """ LOG.debug(_("Creating Connection object")) - self.env = fake_env or env + self.env = kwargs.get('fake_env') or env self._auth_endpoint = auth_endpoint or self.env('OS_AUTH_URL') self._user = user or self.env('OS_USERNAME') self._key = key or self.env('OS_PASSWORD') @@ -58,9 +57,10 @@ class Connection(object): raise ClientException("The authorization endpoint, username, key," " and tenant name should either be passed i" "n or defined as environment variables.") - self.authenticate = authenticate or auth.authenticate - self.request = request or requests.request - self._endpoint = kwargs.get('endpoint') or self.env('SERVICE_ENDPOINT') + self.authenticate = kwargs.get('authenticate') or auth.authenticate + self.request = kwargs.get('request') or requests.request + self._endpoint = (kwargs.get('endpoint') or + self.env('BARBICAN_ENDPOINT')) self._cacert = kwargs.get('cacert') self.connect(token=token) diff --git a/clientrc b/clientrc index e953c919..26bee975 100644 --- a/clientrc +++ b/clientrc @@ -2,5 +2,5 @@ export OS_TENANT_NAME=demo export OS_USERNAME=demo export OS_PASSWORD=password export OS_AUTH_URL="http://keystone-int.cloudkeep.io:5000/v2.0/" -export SERVICE_ENDPOINT="http://api-01-int.cloudkeep.io:9311/v1/" +export BARBICAN_ENDPOINT="http://api-01-int.cloudkeep.io:9311/v1/" export SERVICE_TOKEN='' diff --git a/keep b/keep index d9b49559..6a0e8780 100755 --- a/keep +++ b/keep @@ -37,7 +37,7 @@ class Keep: default=client.env('OS_TENANT_NAME'), help='the tenant ID (default: %(default)s)') parser.add_argument('--endpoint', '-E', - default=client.env('SERVICE_ENDPOINT'), + default=client.env('BARBICAN_ENDPOINT'), help='the URL of the barbican server (default: %' '(default)s)') parser.add_argument('--token', '-K', From 4fadb41977053942053bfdf4dfbf1ae0fe3d1f19 Mon Sep 17 00:00:00 2001 From: Douglas Mendizabal Date: Mon, 24 Jun 2013 16:01:46 -0500 Subject: [PATCH 7/9] Move keep script into barbicanclient module. --- .gitignore | 1 + README.md | 4 +++- keep => barbicanclient/keep.py | 4 ---- setup.py | 5 ++++- 4 files changed, 8 insertions(+), 6 deletions(-) rename keep => barbicanclient/keep.py (99%) mode change 100755 => 100644 diff --git a/.gitignore b/.gitignore index d2b22e13..820ed7fb 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,7 @@ nosetests.xml # Idea .idea +*.iml # generic venvs .venv diff --git a/README.md b/README.md index 9921fbc1..9f962b79 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ python-barbicanclient ===================== -A python library for accessing the Barbican key management service. +This is a client for the [Barbican](https://github.com/cloudkeep/barbican) +Key Management API. There is a Python library for accessing the API +(`barbicanclient` module), and a command-line script (`keep`). diff --git a/keep b/barbicanclient/keep.py old mode 100755 new mode 100644 similarity index 99% rename from keep rename to barbicanclient/keep.py index 6a0e8780..1f3ce993 --- a/keep +++ b/barbicanclient/keep.py @@ -166,7 +166,3 @@ class Keep: def main(): k = Keep() k.execute() - - -if __name__ == '__main__': - main() diff --git a/setup.py b/setup.py index 6081cad9..a47308ec 100644 --- a/setup.py +++ b/setup.py @@ -55,5 +55,8 @@ setuptools.setup( 'Programming Language :: Python :: 2.7', 'Environment :: No Input/Output (Daemon)', ], - scripts = ['keep'] + entry_points=""" + [console_scripts] + keep = barbicanclient.keep:main + """ ) From 9f028eb38fc4fd37af5e62fd296a376ce9d85cbd Mon Sep 17 00:00:00 2001 From: Arash Ghoreyshi Date: Mon, 24 Jun 2013 17:25:56 -0500 Subject: [PATCH 8/9] Add an option to provide arguments through kwargs for testing --- barbicanclient/keep.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/barbicanclient/keep.py b/barbicanclient/keep.py index 1f3ce993..05c7248d 100644 --- a/barbicanclient/keep.py +++ b/barbicanclient/keep.py @@ -154,15 +154,20 @@ class Keep: print '{0}s displayed: {1} - offset: {2}'.format(args.type, len(l[0]), args.offset) - def execute(self): - args = self.parser.parse_args() + def execute(self, **kwargs): + args = self.parser.parse_args(kwargs.get('argv')) self.conn = client.Connection(args.auth_endpoint, args.user, args.password, args.tenant, args.token, endpoint=args.endpoint) + args.func(args) def main(): k = Keep() k.execute() + + +if __name__ == '__main__': + main() From 8468800bf41a87d72dd02ed587cb22c1f32d237f Mon Sep 17 00:00:00 2001 From: Arash Ghoreyshi Date: Mon, 24 Jun 2013 17:52:43 -0500 Subject: [PATCH 9/9] Change the SERVICE_TOKEN env variable to AUTH_TOKEN --- barbicanclient/client.py | 3 +-- barbicanclient/keep.py | 2 +- clientrc | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/barbicanclient/client.py b/barbicanclient/client.py index 391f5a57..2deea3e9 100644 --- a/barbicanclient/client.py +++ b/barbicanclient/client.py @@ -62,8 +62,7 @@ class Connection(object): self._endpoint = (kwargs.get('endpoint') or self.env('BARBICAN_ENDPOINT')) self._cacert = kwargs.get('cacert') - - self.connect(token=token) + self.connect(token=(token or self.env('AUTH_TOKEN'))) @property def _conn(self): diff --git a/barbicanclient/keep.py b/barbicanclient/keep.py index 05c7248d..3704e5f3 100644 --- a/barbicanclient/keep.py +++ b/barbicanclient/keep.py @@ -41,7 +41,7 @@ class Keep: help='the URL of the barbican server (default: %' '(default)s)') parser.add_argument('--token', '-K', - default=client.env('SERVICE_TOKEN'), help='the au' + default=client.env('AUTH_TOKEN'), help='the au' 'thentication token (default: %(default)s)') return parser diff --git a/clientrc b/clientrc index 26bee975..023adfcb 100644 --- a/clientrc +++ b/clientrc @@ -3,4 +3,4 @@ export OS_USERNAME=demo export OS_PASSWORD=password export OS_AUTH_URL="http://keystone-int.cloudkeep.io:5000/v2.0/" export BARBICAN_ENDPOINT="http://api-01-int.cloudkeep.io:9311/v1/" -export SERVICE_TOKEN='' +export AUTH_TOKEN=''