Fix authentication and service endpoint fetching
Make the client library take environment variables by default
This commit is contained in:
@@ -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', '')
|
||||
|
||||
41
keep
41
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()
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user