Important changes for service filtering
Some important changes for service filtering to support resources: * Support the notion of ANY service_type in the service filter for user preferences. * Create a join method in ServiceFilter to join a resource filter with a user preference. * Support service filter preference in session. For example if a user wanted to use region='East' they would create a service filter preference in their session with that region and use that session with any resource. Change-Id: I13fc2838b66ec85bdd0191c78b27b3cd685a8322
This commit is contained in:
@@ -106,6 +106,11 @@ def option_parser():
|
||||
default=env('OS_PASSWORD'),
|
||||
help='Authentication password (Env: OS_PASSWORD)',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--os-region',
|
||||
metavar='<region>',
|
||||
default=env('OS_REGION'),
|
||||
help='Service region (Env: OS_REGION)')
|
||||
parser.add_argument(
|
||||
'--os-cacert',
|
||||
metavar='<ca-bundle-file>',
|
||||
|
@@ -20,9 +20,11 @@ from openstack import session
|
||||
|
||||
|
||||
def make_session(opts):
|
||||
region = opts.os_region
|
||||
preference = service_filter.ServiceFilter(region=region)
|
||||
xport = transport.make_transport(opts)
|
||||
auth = authenticate.make_authenticate(opts)
|
||||
return session.Session(xport, auth)
|
||||
return session.Session(xport, auth, preference=preference)
|
||||
|
||||
|
||||
def run_session(opts):
|
||||
@@ -30,7 +32,7 @@ def run_session(opts):
|
||||
if argument is None:
|
||||
raise Exception("A path argument must be specified")
|
||||
sess = make_session(opts)
|
||||
filtration = service_filter.ServiceFilter('Identity')
|
||||
filtration = service_filter.ServiceFilter(service_type='Identity')
|
||||
print("Session: %s" % sess)
|
||||
print(sess.get(argument, service=filtration).text)
|
||||
return
|
||||
|
@@ -16,12 +16,13 @@ from openstack import exceptions
|
||||
class ServiceFilter(object):
|
||||
"""The basic structure of an authentication plugin."""
|
||||
|
||||
ANY = 'any'
|
||||
PUBLIC = 'public'
|
||||
INTERNAL = 'internal'
|
||||
ADMIN = 'admin'
|
||||
VISIBILITY = [PUBLIC, INTERNAL, ADMIN]
|
||||
|
||||
def __init__(self, service_type, visibility=PUBLIC, region=None,
|
||||
def __init__(self, service_type=ANY, visibility=PUBLIC, region=None,
|
||||
service_name=None):
|
||||
"""" Create a service identifier.
|
||||
|
||||
@@ -31,9 +32,6 @@ class ServiceFilter(object):
|
||||
:param string region: The desired region (optional).
|
||||
:param string service_name: Name of the service
|
||||
"""
|
||||
if not service_type:
|
||||
msg = "Service type must be specified to locate service"
|
||||
raise exceptions.SDKException(msg)
|
||||
self.service_type = service_type.lower()
|
||||
if not visibility:
|
||||
msg = "Visibility must be specified to locate service"
|
||||
@@ -55,7 +53,15 @@ class ServiceFilter(object):
|
||||
ret += ",service_name=%s" % self.service_name
|
||||
return ret
|
||||
|
||||
def join(self, default):
|
||||
return ServiceFilter(service_type=default.service_type,
|
||||
visibility=default.visibility,
|
||||
region=self.region,
|
||||
service_name=self.service_name)
|
||||
|
||||
def match_service_type(self, service_type):
|
||||
if self.service_type == self.ANY:
|
||||
return True
|
||||
return self.service_type == service_type
|
||||
|
||||
def match_service_name(self, service_name):
|
||||
|
@@ -20,7 +20,7 @@ _logger = logging.getLogger(__name__)
|
||||
|
||||
class Session(object):
|
||||
|
||||
def __init__(self, transport, authenticator):
|
||||
def __init__(self, transport, authenticator, preference=None):
|
||||
"""Maintains client communication session.
|
||||
|
||||
Session layer which uses the transport for communication. The
|
||||
@@ -28,9 +28,12 @@ class Session(object):
|
||||
|
||||
:param transport: A transport layer for the session.
|
||||
:param authenticator: An authenticator to authenticate the session.
|
||||
:param ServiceFilter preference: Service filter preference.
|
||||
:type preference: :class:`openstack.auth.service_filter.ServiceFilter`
|
||||
"""
|
||||
self.transport = transport
|
||||
self.authenticator = authenticator
|
||||
self.preference = preference
|
||||
|
||||
def _request(self, path, method, service=None, authenticate=True,
|
||||
**kwargs):
|
||||
@@ -55,6 +58,8 @@ class Session(object):
|
||||
token = self.authenticator.get_token(self.transport)
|
||||
if token:
|
||||
headers['X-Auth-Token'] = token
|
||||
if service and self.preference:
|
||||
service = self.preference.join(service)
|
||||
|
||||
endpoint = self.authenticator.get_endpoint(self.transport, service)
|
||||
url = utils.urljoin(endpoint, path)
|
||||
|
@@ -20,37 +20,44 @@ from openstack.tests.auth import common
|
||||
|
||||
class TestServiceCatalog(testtools.TestCase):
|
||||
def get_urls(self, sot):
|
||||
sf = service_filter.ServiceFilter('compute')
|
||||
sf = service_filter.ServiceFilter(service_type='compute')
|
||||
exp = ["http://compute.region2.public/",
|
||||
"http://compute.region1.public/"]
|
||||
self.assertEqual(exp, sot.get_urls(sf))
|
||||
sf = service_filter.ServiceFilter('image')
|
||||
sf = service_filter.ServiceFilter(service_type='image')
|
||||
self.assertEqual(["http://image.region1.public/"], sot.get_urls(sf))
|
||||
sf = service_filter.ServiceFilter('identity')
|
||||
sf = service_filter.ServiceFilter(service_type='identity')
|
||||
self.assertEqual(["http://identity.region1.public/"], sot.get_urls(sf))
|
||||
sf = service_filter.ServiceFilter('object-store')
|
||||
sf = service_filter.ServiceFilter(service_type='object-store')
|
||||
self.assertEqual(["http://object-store.region1.public/"],
|
||||
sot.get_urls(sf))
|
||||
|
||||
def get_urls_name(self, sot):
|
||||
sf = service_filter.ServiceFilter('compute', service_name='nova')
|
||||
sf = service_filter.ServiceFilter(service_type='compute',
|
||||
service_name='nova')
|
||||
self.assertEqual(["http://compute.region1.public/"], sot.get_urls(sf))
|
||||
sf = service_filter.ServiceFilter('compute', service_name='nova2')
|
||||
sf = service_filter.ServiceFilter(service_type='compute',
|
||||
service_name='nova2')
|
||||
self.assertEqual(["http://compute.region2.public/"], sot.get_urls(sf))
|
||||
|
||||
def get_urls_region(self, sot):
|
||||
sf = service_filter.ServiceFilter('compute', region='RegionTwo')
|
||||
sf = service_filter.ServiceFilter(service_type='compute',
|
||||
region='RegionTwo')
|
||||
self.assertEqual(["http://compute.region2.public/"], sot.get_urls(sf))
|
||||
sf = service_filter.ServiceFilter('compute', region='RegionOne')
|
||||
sf = service_filter.ServiceFilter(service_type='compute',
|
||||
region='RegionOne')
|
||||
self.assertEqual(["http://compute.region1.public/"], sot.get_urls(sf))
|
||||
|
||||
def get_urls_visibility(self, sot):
|
||||
sf = service_filter.ServiceFilter('identity', visibility='admin')
|
||||
sf = service_filter.ServiceFilter(service_type='identity',
|
||||
visibility='admin')
|
||||
self.assertEqual(["http://identity.region1.admin/"], sot.get_urls(sf))
|
||||
sf = service_filter.ServiceFilter('identity', visibility='internal')
|
||||
sf = service_filter.ServiceFilter(service_type='identity',
|
||||
visibility='internal')
|
||||
self.assertEqual(["http://identity.region1.internal/"],
|
||||
sot.get_urls(sf))
|
||||
sf = service_filter.ServiceFilter('identity', visibility='public')
|
||||
sf = service_filter.ServiceFilter(service_type='identity',
|
||||
visibility='public')
|
||||
self.assertEqual(["http://identity.region1.public/"], sot.get_urls(sf))
|
||||
|
||||
|
||||
|
@@ -19,69 +19,89 @@ from openstack import exceptions
|
||||
|
||||
class TestServiceFilter(testtools.TestCase):
|
||||
def test_minimum(self):
|
||||
sot = filt.ServiceFilter('identity')
|
||||
self.assertEqual("service_type=identity,visibility=public",
|
||||
sot = filt.ServiceFilter()
|
||||
self.assertEqual("service_type=any,visibility=public",
|
||||
six.text_type(sot))
|
||||
|
||||
def test_maximum(self):
|
||||
sot = filt.ServiceFilter('compute', visibility='admin', region='b',
|
||||
service_name='c')
|
||||
sot = filt.ServiceFilter(service_type='compute', visibility='admin',
|
||||
region='b', service_name='c')
|
||||
exp = "service_type=compute,visibility=admin,region=b,service_name=c"
|
||||
self.assertEqual(exp, six.text_type(sot))
|
||||
|
||||
def test_visibility(self):
|
||||
sot = filt.ServiceFilter('identity', visibility='public')
|
||||
sot = filt.ServiceFilter(service_type='identity', visibility='public')
|
||||
self.assertEqual("service_type=identity,visibility=public",
|
||||
six.text_type(sot))
|
||||
sot = filt.ServiceFilter('identity', visibility='internal')
|
||||
sot = filt.ServiceFilter(service_type='identity',
|
||||
visibility='internal')
|
||||
self.assertEqual("service_type=identity,visibility=internal",
|
||||
six.text_type(sot))
|
||||
sot = filt.ServiceFilter('identity', visibility='admin')
|
||||
sot = filt.ServiceFilter(service_type='identity', visibility='admin')
|
||||
self.assertEqual("service_type=identity,visibility=admin",
|
||||
six.text_type(sot))
|
||||
sot = filt.ServiceFilter('identity', visibility='publicURL')
|
||||
sot = filt.ServiceFilter(service_type='identity',
|
||||
visibility='publicURL')
|
||||
self.assertEqual("service_type=identity,visibility=public",
|
||||
six.text_type(sot))
|
||||
sot = filt.ServiceFilter('identity', visibility='internalURL')
|
||||
sot = filt.ServiceFilter(service_type='identity',
|
||||
visibility='internalURL')
|
||||
self.assertEqual("service_type=identity,visibility=internal",
|
||||
six.text_type(sot))
|
||||
sot = filt.ServiceFilter('identity', visibility='adminURL')
|
||||
sot = filt.ServiceFilter(service_type='identity',
|
||||
visibility='adminURL')
|
||||
self.assertEqual("service_type=identity,visibility=admin",
|
||||
six.text_type(sot))
|
||||
self.assertRaises(exceptions.SDKException,
|
||||
filt.ServiceFilter, 'identity', visibility='b')
|
||||
self.assertRaises(exceptions.SDKException, filt.ServiceFilter,
|
||||
'identity', visibility=None)
|
||||
self.assertRaises(exceptions.SDKException, filt.ServiceFilter, None)
|
||||
self.assertRaises(exceptions.SDKException, filt.ServiceFilter, None)
|
||||
service_type='identity', visibility='b')
|
||||
self.assertRaises(exceptions.SDKException, filt.ServiceFilter,
|
||||
service_type='identity', visibility=None)
|
||||
|
||||
def test_match_service_type(self):
|
||||
sot = filt.ServiceFilter('identity')
|
||||
sot = filt.ServiceFilter(service_type='identity')
|
||||
self.assertTrue(sot.match_service_type('identity'))
|
||||
self.assertFalse(sot.match_service_type('compute'))
|
||||
|
||||
def test_match_service_type_any(self):
|
||||
sot = filt.ServiceFilter()
|
||||
self.assertTrue(sot.match_service_type('identity'))
|
||||
self.assertTrue(sot.match_service_type('compute'))
|
||||
|
||||
def test_match_service_name(self):
|
||||
sot = filt.ServiceFilter('identity')
|
||||
sot = filt.ServiceFilter(service_type='identity')
|
||||
self.assertTrue(sot.match_service_name('keystone'))
|
||||
self.assertTrue(sot.match_service_name('ldap'))
|
||||
self.assertTrue(sot.match_service_name(None))
|
||||
sot = filt.ServiceFilter('identity', service_name='keystone')
|
||||
sot = filt.ServiceFilter(service_type='identity',
|
||||
service_name='keystone')
|
||||
self.assertTrue(sot.match_service_name('keystone'))
|
||||
self.assertFalse(sot.match_service_name('ldap'))
|
||||
self.assertFalse(sot.match_service_name(None))
|
||||
|
||||
def test_match_region(self):
|
||||
sot = filt.ServiceFilter('identity')
|
||||
sot = filt.ServiceFilter(service_type='identity')
|
||||
self.assertTrue(sot.match_region('East'))
|
||||
self.assertTrue(sot.match_region('West'))
|
||||
self.assertTrue(sot.match_region(None))
|
||||
sot = filt.ServiceFilter('identity', region='East')
|
||||
sot = filt.ServiceFilter(service_type='identity', region='East')
|
||||
self.assertTrue(sot.match_region('East'))
|
||||
self.assertFalse(sot.match_region('West'))
|
||||
self.assertFalse(sot.match_region(None))
|
||||
|
||||
def test_match_visibility(self):
|
||||
sot = filt.ServiceFilter('identity', visibility='internal')
|
||||
sot = filt.ServiceFilter(service_type='identity',
|
||||
visibility='internal')
|
||||
self.assertFalse(sot.match_visibility('admin'))
|
||||
self.assertTrue(sot.match_visibility('internal'))
|
||||
self.assertFalse(sot.match_visibility('public'))
|
||||
|
||||
def test_join(self):
|
||||
a = filt.ServiceFilter(region='east')
|
||||
b = filt.ServiceFilter(service_type='identity')
|
||||
result = a.join(b)
|
||||
self.assertEqual("service_type=identity,visibility=public,region=east",
|
||||
six.text_type(result))
|
||||
self.assertEqual("service_type=any,visibility=public,region=east",
|
||||
six.text_type(a))
|
||||
self.assertEqual("service_type=identity,visibility=public",
|
||||
six.text_type(b))
|
||||
|
@@ -24,7 +24,7 @@ class TestSession(base.TestCase):
|
||||
super(TestSession, self).setUp()
|
||||
self.xport = fakes.FakeTransport()
|
||||
self.auth = fakes.FakeAuthenticator()
|
||||
self.serv = service_filter.ServiceFilter('identity')
|
||||
self.serv = service_filter.ServiceFilter(service_type='identity')
|
||||
self.sess = session.Session(self.xport, self.auth)
|
||||
self.expected = {'headers': {'X-Auth-Token': self.auth.TOKEN}}
|
||||
|
||||
|
Reference in New Issue
Block a user