Skip to content

Commit

Permalink
Handle catalog backends that don't support all functions.
Browse files Browse the repository at this point in the history
Using the templated backend for catalogs deleting a project
will currently work but it will return an error to the user
that is raised in the delete notification code handling.

Change-Id: Ie2ecb226389a7ee74dc64b28b0e08817e6375801
Closes-Bug: #1579604
(cherry picked from commit 8232f4f)
  • Loading branch information
sorrison committed Jul 5, 2016
1 parent a4be339 commit ffe584d
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 24 deletions.
26 changes: 19 additions & 7 deletions keystone/catalog/controllers.py
Original file line number Diff line number Diff line change
Expand Up @@ -400,11 +400,19 @@ def _on_project_or_endpoint_delete(self, service, resource_type, operation,
payload):
project_or_endpoint_id = payload['resource_info']
if resource_type == 'project':
self.catalog_api.delete_association_by_project(
project_or_endpoint_id)
try:
self.catalog_api.delete_association_by_project(
project_or_endpoint_id)
except exception.NotImplemented:
# Some catalog drivers don't support this
pass
else:
self.catalog_api.delete_association_by_endpoint(
project_or_endpoint_id)
try:
self.catalog_api.delete_association_by_endpoint(
project_or_endpoint_id)
except exception.NotImplemented:
# Some catalog drivers don't support this
pass

@controller.protected()
def add_endpoint_to_project(self, context, project_id, endpoint_id):
Expand Down Expand Up @@ -572,9 +580,13 @@ def __init__(self):
def _on_project_delete(self, service, resource_type,
operation, payload):
project_id = payload['resource_info']
(self.catalog_api.
delete_endpoint_group_association_by_project(
project_id))
try:
(self.catalog_api.
delete_endpoint_group_association_by_project(
project_id))
except exception.NotImplemented:
# Some catalog drivers don't support this
pass

@controller.protected()
def get_endpoint_group_in_project(self, context, endpoint_group_id,
Expand Down
36 changes: 19 additions & 17 deletions keystone/tests/unit/test_v3.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ def _populate_default_domain(self):
name=u'Default')
self.resource_api.create_domain(DEFAULT_DOMAIN_ID, domain)

def load_sample_data(self):
def load_sample_data(self, create_region_and_endpoints=True):
self._populate_default_domain()
self.domain = unit.new_domain_ref()
self.domain_id = self.domain['id']
Expand Down Expand Up @@ -355,22 +355,24 @@ def load_sample_data(self):
self.default_domain_project_id,
self.role_id)

self.region = unit.new_region_ref()
self.region_id = self.region['id']
self.catalog_api.create_region(self.region)

self.service = unit.new_service_ref()
self.service_id = self.service['id']
self.catalog_api.create_service(self.service_id, self.service.copy())

self.endpoint = unit.new_endpoint_ref(service_id=self.service_id,
interface='public',
region_id=self.region_id)
self.endpoint_id = self.endpoint['id']
self.catalog_api.create_endpoint(self.endpoint_id,
self.endpoint.copy())
# The server adds 'enabled' and defaults to True.
self.endpoint['enabled'] = True
if create_region_and_endpoints:
self.region = unit.new_region_ref()
self.region_id = self.region['id']
self.catalog_api.create_region(self.region)

self.service = unit.new_service_ref()
self.service_id = self.service['id']
self.catalog_api.create_service(self.service_id,
self.service.copy())

self.endpoint = unit.new_endpoint_ref(service_id=self.service_id,
interface='public',
region_id=self.region_id)
self.endpoint_id = self.endpoint['id']
self.catalog_api.create_endpoint(self.endpoint_id,
self.endpoint.copy())
# The server adds 'enabled' and defaults to True.
self.endpoint['enabled'] = True

def create_new_default_project_for_user(self, user_id, domain_id,
enable_project=True):
Expand Down
27 changes: 27 additions & 0 deletions keystone/tests/unit/test_v3_catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -922,3 +922,30 @@ def assertValidCatalogEndpoint(self, entity, ref=None):
for k in keys:
self.assertEqual(ref.get(k), entity[k], k)
self.assertEqual(entity['region_id'], entity['region'])


class TestCatalogAPITemplatedProject(test_v3.RestfulTestCase):
"""Templated Catalog doesn't support full API.
Eg. No region/endpoint creation.
"""

def config_overrides(self):
super(TestCatalogAPITemplatedProject, self).config_overrides()
self.config_fixture.config(group='catalog', driver='templated')

def load_fixtures(self, fixtures):
self.load_sample_data(create_region_and_endpoints=False)

def test_project_delete(self):
"""Deleting a project should not result in an 500 ISE.
The EndpointFilter extension of the Catalog API will create a
notification when a project is deleted (attempting to clean up
project->endpoint relationships). In the case of a templated catalog,
no deletions (via catalog_api.delete_association_by_project) can be
performed and result in a NotImplemented exception. We catch this
exception and ignore it since it is expected.
"""
self.resource_api.delete_project(self.project_id)

0 comments on commit ffe584d

Please sign in to comment.