diff --git a/keystone/backends/sqlalchemy/__init__.py b/keystone/backends/sqlalchemy/__init__.py index 9c8d10095a..31ff5f667b 100755 --- a/keystone/backends/sqlalchemy/__init__.py +++ b/keystone/backends/sqlalchemy/__init__.py @@ -90,6 +90,9 @@ def register_models(options): """Register Models and create properties""" global _ENGINE assert _ENGINE + # Need to decide.Not This is missing + # and prevents foreign key reference checks. + # _ENGINE.execute('pragma foreign_keys=on') supported_alchemy_models = ast.literal_eval( options["backend_entities"]) supported_alchemy_tables = [] diff --git a/keystone/backends/sqlalchemy/api/endpoint_template.py b/keystone/backends/sqlalchemy/api/endpoint_template.py index 8b10dab165..3dd5e67192 100755 --- a/keystone/backends/sqlalchemy/api/endpoint_template.py +++ b/keystone/backends/sqlalchemy/api/endpoint_template.py @@ -58,7 +58,7 @@ class EndpointTemplateAPI(BaseEndpointTemplateAPI): if not session: session = get_session() return session.query(models.EndpointTemplates).\ - filter_by(service=service_id).all() + filter_by(service_id=service_id).all() def get_page(self, marker, limit, session=None): if not session: diff --git a/keystone/backends/sqlalchemy/models.py b/keystone/backends/sqlalchemy/models.py index 09db0c312c..e264ab5580 100755 --- a/keystone/backends/sqlalchemy/models.py +++ b/keystone/backends/sqlalchemy/models.py @@ -166,7 +166,7 @@ class EndpointTemplates(Base, KeystoneBase): __api__ = 'endpoint_template' id = Column(Integer, primary_key=True) region = Column(String(255)) - service = Column(String(255)) + service_id = Column(Integer, ForeignKey('services.id')) public_url = Column(String(2000)) admin_url = Column(String(2000)) internal_url = Column(String(2000)) diff --git a/keystone/frontends/legacy_token_auth.py b/keystone/frontends/legacy_token_auth.py index 7fe83d7908..239c3580f2 100644 --- a/keystone/frontends/legacy_token_auth.py +++ b/keystone/frontends/legacy_token_auth.py @@ -94,9 +94,9 @@ class AuthProtocol(object): service_mappings = ast.literal_eval( self.conf["service-header-mappings"]) for service in services: - service_name = service + service_name = service["name"] service_urls = '' - for endpoint in services[service_name]: + for endpoint in service["endpoints"]: if len(service_urls) > 0: service_urls += ',' service_urls += endpoint["publicURL"] diff --git a/keystone/logic/service.py b/keystone/logic/service.py index fce5b42044..0fc6084685 100755 --- a/keystone/logic/service.py +++ b/keystone/logic/service.py @@ -683,15 +683,18 @@ class IdentityService(object): if not isinstance(endpoint_template, EndpointTemplate): raise fault.BadRequestFault("Expecting a EndpointTemplate") - #Check if the passed service exist. + if endpoint_template.service == None or \ + len(endpoint_template.service.strip()) == 0: + raise fault.BadRequestFault( + "Expecting serviceId.") if endpoint_template.service != None and\ len(endpoint_template.service.strip()) > 0 and\ api.SERVICE.get(endpoint_template.service) == None: raise fault.BadRequestFault( - "A service with that id doesnt exist.") + "A service with that id doesn't exist.") dendpoint_template = models.EndpointTemplates() dendpoint_template.region = endpoint_template.region - dendpoint_template.service = endpoint_template.service + dendpoint_template.service_id = endpoint_template.service dendpoint_template.public_url = endpoint_template.public_url dendpoint_template.admin_url = endpoint_template.admin_url dendpoint_template.internal_url = endpoint_template.internal_url @@ -719,7 +722,7 @@ class IdentityService(object): raise fault.BadRequestFault( "A service with that id doesn't exist.") dendpoint_template.region = endpoint_template.region - dendpoint_template.service = endpoint_template.service + dendpoint_template.service_id = endpoint_template.service dendpoint_template.public_url = endpoint_template.public_url dendpoint_template.admin_url = endpoint_template.admin_url dendpoint_template.internal_url = endpoint_template.internal_url @@ -730,7 +733,7 @@ class IdentityService(object): return EndpointTemplate( dendpoint_template.id, dendpoint_template.region, - dendpoint_template.service, + dendpoint_template.service_id, dendpoint_template.public_url, dendpoint_template.admin_url, dendpoint_template.internal_url, @@ -760,7 +763,7 @@ class IdentityService(object): ts.append(EndpointTemplate( dendpoint_template.id, dendpoint_template.region, - dendpoint_template.service, + dendpoint_template.service_id, dendpoint_template.public_url, dendpoint_template.admin_url, dendpoint_template.internal_url, @@ -786,7 +789,7 @@ class IdentityService(object): return EndpointTemplate( dendpoint_template.id, dendpoint_template.region, - dendpoint_template.service, + dendpoint_template.service_id, dendpoint_template.public_url, dendpoint_template.admin_url, dendpoint_template.internal_url, diff --git a/keystone/logic/types/auth.py b/keystone/logic/types/auth.py index edc942005e..8976331f62 100755 --- a/keystone/logic/types/auth.py +++ b/keystone/logic/types/auth.py @@ -17,6 +17,7 @@ import json from lxml import etree from keystone.logic.types import fault +import keystone.backends.api as db_api class AuthWithPasswordCredentials(object): @@ -235,8 +236,12 @@ class AuthData(object): if self.base_urls != None: service_catalog = etree.Element("serviceCatalog") for key, key_base_urls in self.d.items(): + dservice = db_api.SERVICE.get(key) + if not dservice: + raise fault.ItemNotFoundFault( + "The service could not be found") service = etree.Element("service", - name=key) + name=dservice.name, type=dservice.type) for base_url in key_base_urls: endpoint = etree.Element("endpoint") if base_url.region: @@ -254,9 +259,9 @@ class AuthData(object): def __convert_baseurls_to_dict(self): for base_url in self.base_urls: - if base_url.service not in self.d: - self.d[base_url.service] = list() - self.d[base_url.service].append(base_url) + if base_url.service_id not in self.d: + self.d[base_url.service_id] = list() + self.d[base_url.service_id].append(base_url) def to_json(self): token = {} @@ -265,8 +270,9 @@ class AuthData(object): auth = {} auth["token"] = token if self.base_urls != None: - service_catalog = {} + service_catalog = [] for key, key_base_urls in self.d.items(): + service = {} endpoints = [] for base_url in key_base_urls: endpoint = {} @@ -280,7 +286,14 @@ class AuthData(object): str(self.token.tenant_id)) \ if self.token.tenant_id else base_url_item endpoints.append(endpoint) - service_catalog[key] = endpoints + dservice = db_api.SERVICE.get(key) + if not dservice: + raise fault.ItemNotFoundFault( + "The service could not be found for" + str(key)) + service["name"] = dservice.name + service["type"] = dservice.type + service["endpoints"] = endpoints + service_catalog.append(service) auth["serviceCatalog"] = service_catalog ret = {} ret["access"] = auth diff --git a/keystone/logic/types/endpoint.py b/keystone/logic/types/endpoint.py index 322a5cd22d..526e4a8f40 100644 --- a/keystone/logic/types/endpoint.py +++ b/keystone/logic/types/endpoint.py @@ -114,7 +114,7 @@ class EndpointTemplate(object): if self.region: dom.set("region", self.region) if self.service: - dom.set("serviceId", self.service) + dom.set("serviceId", str(self.service)) if self.public_url: dom.set("publicURL", self.public_url) if self.admin_url: diff --git a/keystone/manage/api.py b/keystone/manage/api.py index a966653a04..fefe0df4a2 100644 --- a/keystone/manage/api.py +++ b/keystone/manage/api.py @@ -108,7 +108,7 @@ def add_endpoint_template(region, service, public_url, admin_url, internal_url, enabled, is_global): obj = db_models.EndpointTemplates() obj.region = region - obj.service = service + obj.service_id = service obj.public_url = public_url obj.admin_url = admin_url obj.internal_url = internal_url diff --git a/keystone/test/functional/test_authentication.py b/keystone/test/functional/test_authentication.py index d860db91da..3adf6e4dde 100755 --- a/keystone/test/functional/test_authentication.py +++ b/keystone/test/functional/test_authentication.py @@ -66,7 +66,7 @@ class AuthenticationTest(common.FunctionalTestCase): self.assertIsNotNone(r.getheader('x-auth-token')) for service in self.services.values(): - self.assertIsNotNone(r.getheader('x-' + service['id'])) + self.assertIsNotNone(r.getheader('x-' + service['name'])) def test_authorize_user_disabled(self): self.disable_user(self.user['id']) diff --git a/keystone/test/sampledata.py b/keystone/test/sampledata.py index 6e59248a66..fa08ddb849 100644 --- a/keystone/test/sampledata.py +++ b/keystone/test/sampledata.py @@ -22,46 +22,68 @@ DEFAULT_FIXTURE = [ ('role', 'grant', 'Admin', 'joeadmin', 'ANOTHER:TENANT'), ('role', 'add', 'Member'), ('role', 'grant', 'Member', 'joeuser', '1234'), +# Add Services + #1 Service Name:exampleservice Type:example type + ('service', 'add', 'exampleservice', + 'example type', 'example description'), + #2 Service Name:swift Type:object-store + ('service', 'add', 'swift', + 'object-store', 'Swift-compatible service'), + #3 Service Name:cdn Type:object-store + ('service', 'add', 'cdn', + 'object-store', 'Swift-compatible service'), + #4 Service Name:nova Type:compute + ('service', 'add', 'nova', + 'compute', 'OpenStack Compute Service'), + #5 Service Name:nova_compat Type:Compute + ('service', 'add', 'nova_compat', + 'compute', 'OpenStack Compute Service'), + #6 Service Name:glance Type:image-service + ('service', 'add', 'glance', + 'image-service', 'OpenStack Compute Service'), + #7 Service Name:glance Type:image-service + ('service', 'add', 'identity', + 'identity-service', 'OpenStack Compute Service'), # Keeping for compatibility for a while till dashboard catches up - ('endpointTemplates', 'add', 'RegionOne', 'swift', + ('endpointTemplates', 'add', 'RegionOne', '2', 'http://swift.publicinternets.com/v1/AUTH_%tenant_id%', 'http://swift.admin-nets.local:8080/', 'http://127.0.0.1:8080/v1/AUTH_%tenant_id%', '1', '0'), - ('endpointTemplates', 'add', 'RegionOne', 'nova_compat', + ('endpointTemplates', 'add', 'RegionOne', '5', 'http://nova.publicinternets.com/v1.0/', 'http://127.0.0.1:8774/v1.0', 'http://localhost:8774/v1.0', '1', '0'), - ('endpointTemplates', 'add', 'RegionOne', 'nova', + ('endpointTemplates', 'add', 'RegionOne', '4', 'http://nova.publicinternets.com/v1.1/', 'http://127.0.0.1:8774/v1.1', 'http://localhost:8774/v1.1', '1', '0'), - ('endpointTemplates', 'add', 'RegionOne', 'glance', + ('endpointTemplates', 'add', 'RegionOne', '6', 'http://glance.publicinternets.com/v1.1/%tenant_id%', 'http://nova.admin-nets.local/v1.1/%tenant_id%', 'http://127.0.0.1:9292/v1.1/%tenant_id%', '1', '0'), - ('endpointTemplates', 'add', 'RegionOne', 'cdn', + ('endpointTemplates', 'add', 'RegionOne', '3', 'http://cdn.publicinternets.com/v1.1/%tenant_id%', 'http://cdn.admin-nets.local/v1.1/%tenant_id%', 'http://127.0.0.1:7777/v1.1/%tenant_id%', '1', '0'), # endpointTemplates - ('endpointTemplates', 'add', 'RegionOne', 'object_store', + ('endpointTemplates', 'add', 'RegionOne', '2', 'http://swift.publicinternets.com/v1/AUTH_%tenant_id%', 'http://swift.admin-nets.local:8080/', 'http://127.0.0.1:8080/v1/AUTH_%tenant_id%', '1', '0'), - ('endpointTemplates', 'add', 'RegionOne', 'compute', + ('endpointTemplates', 'add', 'RegionOne', '4', 'http://nova.publicinternets.com/v1.0/', 'http://127.0.0.1:8774/v1.0', 'http://localhost:8774/v1.0', '1', '0'), - ('endpointTemplates', 'add', 'RegionOne', 'compute_v1', + ('endpointTemplates', 'add', 'RegionOne', '5', 'http://nova.publicinternets.com/v1.1/', 'http://127.0.0.1:8774/v1.1', 'http://localhost:8774/v1.1', '1', '0'), - ('endpointTemplates', 'add', 'RegionOne', 'image', + ('endpointTemplates', 'add', 'RegionOne', '6', 'http://glance.publicinternets.com/v1.1/%tenant_id%', 'http://nova.admin-nets.local/v1.1/%tenant_id%', 'http://127.0.0.1:9292/v1.1/%tenant_id%', '1', '0'), - ('endpointTemplates', 'add', 'RegionOne', 'cdn', + ('endpointTemplates', 'add', 'RegionOne', '3', 'http://cdn.publicinternets.com/v1.1/%tenant_id%', 'http://cdn.admin-nets.local/v1.1/%tenant_id%', 'http://127.0.0.1:7777/v1.1/%tenant_id%', '1', '0'), # Global endpointTemplate - ('endpointTemplates', 'add', 'RegionOne', 'identity', + ('endpointTemplates', 'add', 'RegionOne', '7', 'http://keystone.publicinternets.com/v2.0', 'http://127.0.0.1:5001/v2.0', 'http://127.0.0.1:5000/v2.0', '1', '1'), # Tokens @@ -77,11 +99,8 @@ DEFAULT_FIXTURE = [ ('endpoint', 'add', '1234', '3'), ('endpoint', 'add', '1234', '4'), ('endpoint', 'add', '1234', '5'), -# Add Services - ('service', 'add', 'exampleservice', - 'example type', 'example description'), # Add Credentials - ('credentials', 'add', 'admin', 'EC2', 'admin:admin', 'admin', 'admin'), + ('credentials', 'add', 'admin', 'EC2', 'admin:admin', 'admin', '1'), ] diff --git a/keystone/test/unit/test_ec2_authn.py b/keystone/test/unit/test_ec2_authn.py index c85d274a32..91707e4140 100755 --- a/keystone/test/unit/test_ec2_authn.py +++ b/keystone/test/unit/test_ec2_authn.py @@ -69,7 +69,7 @@ class EC2AuthnMethods(base.ServiceAPITest): expected = { u'access': { - u'serviceCatalog': {}, + u'serviceCatalog': [], u'token': { u'expires': self.expires.strftime("%Y-%m-%dT%H:%M:%S.%f"), u'id': self.auth_token_id,