Use stevedore to load authorization plugins

Add basic infrastructure to load authorization plugins with
stevedore.

Change-Id: I4828be6537bbe865b43ec43de41f6060ea8f2c98
This commit is contained in:
Terry Howe
2014-09-09 09:58:33 -06:00
parent 549301b24b
commit 836b9e852d
9 changed files with 90 additions and 113 deletions

View File

@@ -47,17 +47,20 @@ class TestAuthenticator(base.BaseAuthPlugin):
def make_authenticate(opts): def make_authenticate(opts):
return authenticator.create( args = {
username=opts.username, 'auth_plugin': opts.auth_plugin,
password=opts.password, 'auth_url': opts.auth_url,
token=opts.token, 'project_name': opts.project_name,
auth_url=opts.auth_url, 'domain_name': opts.domain_name,
version=opts.identity_api_version, 'project_domain_name': opts.project_domain_name,
project_name=opts.project_name, 'user_domain_name': opts.user_domain_name,
domain_name=opts.domain_name, 'user_name': opts.user_name,
project_domain_name=opts.project_domain_name, 'password': opts.password,
user_domain_name=opts.user_domain_name, 'region_name': opts.region_name,
) 'verify': opts.verify,
'token': opts.token,
}
return authenticator.create(**args)
def run_authenticate(opts): def run_authenticate(opts):

View File

@@ -116,6 +116,13 @@ def option_parser():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description='A demonstration framework') description='A demonstration framework')
# Global arguments # Global arguments
parser.add_argument(
'--os-auth-plugin',
dest='auth_plugin',
metavar='<auth-plugin>',
default=env('OS_AUTH_PLUGIN', default='identity_v3'),
help='Authentication plugin (Env: OS_AUTH_PLUGIN)',
)
parser.add_argument( parser.add_argument(
'--os-auth-url', '--os-auth-url',
dest='auth_url', dest='auth_url',
@@ -157,7 +164,7 @@ def option_parser():
) )
parser.add_argument( parser.add_argument(
'--os-username', '--os-username',
dest='username', dest='user_name',
metavar='<auth-username>', metavar='<auth-username>',
default=env('OS_USERNAME'), default=env('OS_USERNAME'),
help='Authentication username (Env: OS_USERNAME)', help='Authentication username (Env: OS_USERNAME)',
@@ -194,15 +201,6 @@ def option_parser():
action='store_false', action='store_false',
help='Disable server certificate verification', help='Disable server certificate verification',
) )
parser.add_argument(
'--os-identity-api-version',
dest='identity_api_version',
metavar='<identity-api-version>',
default=env(
'OS_IDENTITY_API_VERSION',
default=None),
help='Force Identity API version (Env: OS_IDENTITY_API_VERSION)',
)
parser.add_argument( parser.add_argument(
'--os-token', '--os-token',
dest='token', dest='token',

View File

@@ -28,19 +28,23 @@ from openstack import session
def make_session(opts): def make_session(opts):
args = {
'auth_plugin': opts.auth_plugin,
'auth_url': opts.auth_url,
'project_name': opts.project_name,
'domain_name': opts.domain_name,
'project_domain_name': opts.project_domain_name,
'user_domain_name': opts.user_domain_name,
'user_name': opts.user_name,
'password': opts.password,
'region_name': opts.region_name,
'verify': opts.verify,
'token': opts.token,
}
return session.Session.create( return session.Session.create(
username=opts.username,
password=opts.password,
token=opts.token,
auth_url=opts.auth_url,
version=opts.identity_api_version,
project_name=opts.project_name,
domain_name=opts.domain_name,
project_domain_name=opts.project_domain_name,
user_domain_name=opts.user_domain_name,
verify=opts.verify,
user_agent='SDKExample', user_agent='SDKExample',
region=opts.region_name, region=opts.region_name,
**args
) )

View File

@@ -10,60 +10,43 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from openstack.auth.identity import v2
from openstack.auth.identity import v3
from openstack import exceptions from openstack import exceptions
from stevedore import driver
def create(username=None, password=None, token=None, auth_url=None,
version=None, project_name=None, domain_name=None, def create(auth_plugin=None, **auth_args):
project_domain_name=None, user_domain_name=None):
"""Temporary code for creating an authenticator """Temporary code for creating an authenticator
This is temporary code to create an authenticator. This code will be This is temporary code to create an authenticator. This code will be
removed in the future. removed in the future.
:param string username: User name for authentication. :param string auth_plugin: Name of authentication plugin to use.
:param string password: Password associated with the user. :param auth_args: Arguments for auth plugin.
:param string token: Authentication token to use if available.
:param string auth_url: The URL to use for authentication.
:param string version: Version of authentication to use.
:param string project_name: Project name to athenticate.
:param string domain_name: Domain name to athenticate.
:param string project_domain_name: Project domain name to athenticate.
:param string user_domain_name: User domain name to athenticate.
:returns string: An authenticator. :returns string: An authenticator.
""" """
if auth_url is None:
msg = ("auth_url wasn't provided.")
raise exceptions.AuthorizationFailure(msg)
endpoint_version = auth_url.split('v')[-1] if auth_plugin is None:
if version is None: if 'auth_url' not in auth_args:
version = endpoint_version msg = ("auth_url was not provided.")
raise exceptions.AuthorizationFailure(msg)
auth_url = auth_args['auth_url']
endpoint_version = auth_url.split('v')[-1][0]
if endpoint_version == '2':
auth_plugin = 'identity_v2'
else:
auth_plugin = 'identity_v3'
version = version.lower().replace('v', '') mgr = driver.DriverManager(
version = version.split('.')[0] namespace="openstack.auth.plugin",
if version == '3': name=auth_plugin,
args = {'user_name': username, 'password': password} invoke_on_load=False,
if project_name: )
args['project_name'] = project_name plugin = mgr.driver
if domain_name: valid_list = plugin.valid_options
args['domain_name'] = domain_name args = {}
if project_domain_name: for k in valid_list:
args['project_domain_name'] = project_domain_name if k in auth_args:
if user_domain_name: args[k] = auth_args[k]
args['user_domain_name'] = user_domain_name return plugin(**args)
if token:
args['token'] = token
return v3.Auth(auth_url, **args)
elif version == '2':
args = {'user_name': username, 'password': password}
if project_name:
args['project_name'] = project_name
if token:
args['token'] = token
return v2.Auth(auth_url, **args)
msg = ("No support for identity version: %s" % version)
raise exceptions.NoMatchingPlugin(msg)

View File

@@ -39,24 +39,9 @@ class Session(object):
self.preference = preference self.preference = preference
@classmethod @classmethod
def create(cls, username=None, password=None, token=None, auth_url=None, def create(cls, verify=True, region=None, **auth_args):
version=None, project_name=None, verify=None, user_agent=None, xport = transport.Transport(verify=verify)
region=None, domain_name=None, project_domain_name=None, auth = authenticator.create(**auth_args)
user_domain_name=None):
xport = transport.Transport(verify=verify, user_agent=user_agent)
args = {
'username': username,
'password': password,
'token': token,
'auth_url': auth_url,
'project_name': project_name,
'domain_name': domain_name,
'project_domain_name': project_domain_name,
'user_domain_name': user_domain_name,
}
if version:
args['version'] = version
auth = authenticator.create(**args)
preference = service_filter.ServiceFilter(region=region) preference = service_filter.ServiceFilter(region=region)
return cls(xport, auth, preference=preference) return cls(xport, auth, preference=preference)

View File

@@ -18,11 +18,11 @@ from openstack.tests import base
class TestAuthenticatorCreate(base.TestCase): class TestAuthenticatorCreate(base.TestCase):
def test_create_3_password(self): def test_create_3_password(self):
auth = authenticator.create( auth = authenticator.create(
username='1', user_name='1',
password='2', password='2',
token=None, token=None,
auth_url='4', auth_url='4',
version='3', auth_plugin='identity_v3',
project_name='6', project_name='6',
domain_name='7', domain_name='7',
project_domain_name='8', project_domain_name='8',
@@ -38,11 +38,11 @@ class TestAuthenticatorCreate(base.TestCase):
def test_create_3_token(self): def test_create_3_token(self):
auth = authenticator.create( auth = authenticator.create(
username='1', user_name='1',
password='2', password='2',
token='3', token='3',
auth_url='4', auth_url='4',
version='3', auth_plugin='identity_v3',
project_name='6', project_name='6',
) )
self.assertEqual('3', auth.auth_methods[0].token) self.assertEqual('3', auth.auth_methods[0].token)
@@ -50,11 +50,11 @@ class TestAuthenticatorCreate(base.TestCase):
def test_create_2_password(self): def test_create_2_password(self):
auth = authenticator.create( auth = authenticator.create(
username='1', user_name='1',
password='2', password='2',
token=None, token=None,
auth_url='4', auth_url='4',
version='2', auth_plugin='identity_v2',
project_name='6', project_name='6',
) )
self.assertEqual('1', auth.user_name) self.assertEqual('1', auth.user_name)
@@ -64,11 +64,11 @@ class TestAuthenticatorCreate(base.TestCase):
def test_create_2_token(self): def test_create_2_token(self):
auth = authenticator.create( auth = authenticator.create(
username='1', user_name='1',
password='2', password='2',
token='3', token='3',
auth_url='4', auth_url='4',
version='2', auth_plugin='identity_v2',
project_name='6', project_name='6',
) )
self.assertEqual('3', auth.token) self.assertEqual('3', auth.token)
@@ -76,13 +76,13 @@ class TestAuthenticatorCreate(base.TestCase):
def test_create_bogus(self): def test_create_bogus(self):
self.assertRaises( self.assertRaises(
exceptions.NoMatchingPlugin, RuntimeError,
authenticator.create, authenticator.create,
username='1', user_name='1',
password='2', password='2',
token='3', token='3',
auth_url='4', auth_url='4',
version='99', auth_plugin='identity_v99',
project_name='6', project_name='6',
) )
@@ -97,14 +97,14 @@ class TestAuthenticatorCreate(base.TestCase):
project_name='6', project_name='6',
) )
def test_create_no_version_2(self): def test_create_2(self):
auth = authenticator.create(token='1', auth_url='url/v2.0') auth = authenticator.create(token='1', auth_url='url/v2.0')
self.assertTrue('v2' in str(auth)) self.assertTrue('v2' in str(auth))
def test_create_no_version_3(self): def test_create_3(self):
auth = authenticator.create(token='1', auth_url='url/v3.0') auth = authenticator.create(token='1', auth_url='url/v3.0')
self.assertTrue('v3' in str(auth)) self.assertTrue('v3' in str(auth))
def test_create_version_unlike_auth_url(self): def test_create_unlike(self):
auth = authenticator.create(token='1', version='2', auth_url='url/v3') auth = authenticator.create(token='1', auth_url='url/somethingelse')
self.assertTrue('v2' in str(auth)) self.assertTrue('v3' in str(auth))

View File

@@ -86,18 +86,16 @@ class TestSession(base.TestCase):
class TestSessionCreate(base.TestCase): class TestSessionCreate(base.TestCase):
def test_create(self): def test_create(self):
sess = session.Session.create( sess = session.Session.create(
username='1', user_name='1',
password='2', password='2',
token=None, token=None,
auth_url='4', auth_url='4',
version='3', auth_plugin='identity_v3',
project_name='6', project_name='6',
verify='7', verify='7',
user_agent='9',
region='10', region='10',
) )
self.assertEqual('1', sess.authenticator.auth_methods[0].user_name) self.assertEqual('1', sess.authenticator.auth_methods[0].user_name)
self.assertEqual('2', sess.authenticator.auth_methods[0].password) self.assertEqual('2', sess.authenticator.auth_methods[0].password)
self.assertEqual('7', sess.transport.verify) self.assertEqual('7', sess.transport.verify)
self.assertEqual('9', sess.transport._user_agent)
self.assertEqual('10', sess.preference.region) self.assertEqual('10', sess.preference.region)

View File

@@ -4,3 +4,4 @@
pbr>=0.6,!=0.7,<1.0 pbr>=0.6,!=0.7,<1.0
iso8601>=0.1.9 iso8601>=0.1.9
requests>=1.2.1,!=2.4.0 requests>=1.2.1,!=2.4.0
stevedore>=1.0.0 # Apache-2.0

View File

@@ -47,3 +47,8 @@ output_file = openstack/locale/python-openstacksdk.pot
[wheel] [wheel]
universal = 1 universal = 1
[entry_points]
openstack.auth.plugin =
identity_v2 = openstack.auth.identity.v2:Auth
identity_v3 = openstack.auth.identity.v3:Auth