From: Zane Bitter Date: Thu, 27 Sep 2012 09:49:07 +0000 (+0200) Subject: Make the keystone service type configurable X-Git-Tag: 2014.1~1350 X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=e890e7d422fd07dc022b9b755a575519d849b1f8;p=openstack-build%2Fheat-build.git Make the keystone service type configurable We will eventually need to have clients for both the OpenStack and CloudFormation-compatible APIs, and they will need to have different service types. Change-Id: I06ae727c17c245ae60934bbed6e1631c7ad5fd77 Signed-off-by: Zane Bitter --- diff --git a/heat/client.py b/heat/client.py index bb1284a9..74739e8a 100644 --- a/heat/client.py +++ b/heat/client.py @@ -179,4 +179,5 @@ def get_client(host, port=None, username=None, use_ssl=use_ssl, auth_tok=auth_token, creds=creds, - insecure=insecure) + insecure=insecure, + service_type='orchestration') diff --git a/heat/common/auth.py b/heat/common/auth.py index 571fbdaf..52811cdf 100644 --- a/heat/common/auth.py +++ b/heat/common/auth.py @@ -69,8 +69,9 @@ class NoAuthStrategy(BaseStrategy): class KeystoneStrategy(BaseStrategy): MAX_REDIRECTS = 10 - def __init__(self, creds): + def __init__(self, creds, service_type): self.creds = creds + self.service_type = service_type super(KeystoneStrategy, self).__init__() def check_auth_params(self): @@ -184,32 +185,26 @@ class KeystoneStrategy(BaseStrategy): We search the full service catalog for services matching both type and region. If the client - supplied no region then any 'heat' endpoint + supplied no region then any endpoint for the service is considered a match. There must be one -- and only one -- successful match in the catalog, otherwise we will raise an exception. """ - # FIXME(sirp): for now just use the public url. - endpoint = None region = self.creds.get('region') - for service in service_catalog: - try: - service_type = service['type'] - except KeyError: - msg = _('Encountered service with no "type": %s' % service) - logger.warn(msg) - continue - - if service_type == 'orchestration': - for ep in service['endpoints']: - if region is None or region == ep['region']: - if endpoint is not None: - # This is a second match, abort - raise exception.RegionAmbiguity(region=region) - endpoint = ep - if endpoint is None: + + service_type_matches = lambda s: s.get('type') == self.service_type + region_matches = lambda e: region is None or e['region'] == region + + endpoints = [ep for s in service_catalog if service_type_matches(s) + for ep in s['endpoints'] if region_matches(ep)] + + if len(endpoints) > 1: + raise exception.RegionAmbiguity(region=region) + elif not endpoints: raise exception.NoServiceEndpoint() - return endpoint['publicURL'] + else: + # FIXME(sirp): for now just use the public url. + return endpoints[0]['publicURL'] creds = self.creds @@ -268,10 +263,10 @@ class KeystoneStrategy(BaseStrategy): return resp, resp_body -def get_plugin_from_strategy(strategy, creds=None): +def get_plugin_from_strategy(strategy, creds=None, service_type=None): if strategy == 'noauth': return NoAuthStrategy() elif strategy == 'keystone': - return KeystoneStrategy(creds) + return KeystoneStrategy(creds, service_type) else: raise Exception(_("Unknown auth strategy '%s'") % strategy) diff --git a/heat/common/client.py b/heat/common/client.py index be465c85..ba4e294c 100644 --- a/heat/common/client.py +++ b/heat/common/client.py @@ -223,7 +223,7 @@ class BaseClient(object): def __init__(self, host, port=None, use_ssl=False, auth_tok=None, creds=None, doc_root=None, key_file=None, cert_file=None, ca_file=None, insecure=False, - configure_via_auth=True): + configure_via_auth=True, service_type=None): """ Creates a new client to some service. @@ -260,6 +260,7 @@ class BaseClient(object): self.creds = creds or {} self.connection = None self.configure_via_auth = configure_via_auth + self.service_type = service_type # doc_root can be a nullstring, which is valid, and why we # cannot simply do doc_root or self.DEFAULT_DOC_ROOT below. self.doc_root = (doc_root if doc_root is not None @@ -368,7 +369,8 @@ class BaseClient(object): Returns an instantiated authentication plugin. """ strategy = creds.get('strategy', 'noauth') - plugin = auth.get_plugin_from_strategy(strategy, creds) + plugin = auth.get_plugin_from_strategy(strategy, + creds, self.service_type) return plugin def get_connection_type(self):