Fix 500 error when deleting domain

If there are idps in a domain, when users try to delete the
domain, 500 interal error will raise.

This patch added a new callback event to clean up the related
idps.

Closes-bug: #1760809
Change-Id: I37c8745e4509f69aaa659b130ccbdfe51cf6a1b8
This commit is contained in:
wangxiyuan 2018-04-03 19:45:10 +08:00
parent 7c4c6a5fb3
commit 42cf675c40
3 changed files with 50 additions and 6 deletions

View File

@ -14,7 +14,10 @@
import uuid
from oslo_log import log
from keystone.common import cache
from keystone.common import driver_hints
from keystone.common import manager
from keystone.common import provider_api
import keystone.conf
@ -23,6 +26,7 @@ from keystone.federation import utils
from keystone.i18n import _
from keystone import notifications
LOG = log.getLogger(__name__)
# This is a general cache region for service providers.
MEMOIZE = cache.get_memoization_decorator(group='federation')
@ -44,6 +48,25 @@ class Manager(manager.Manager):
def __init__(self):
super(Manager, self).__init__(CONF.federation.driver)
notifications.register_event_callback(
notifications.ACTIONS.internal, notifications.DOMAIN_DELETED,
self._cleanup_identity_provider
)
def _cleanup_identity_provider(self, service, resource_type, operation,
payload):
domain_id = payload['resource_info']
hints = driver_hints.Hints()
hints.add_filter('domain_id', domain_id)
idps = self.driver.list_idps(hints=hints)
for idp in idps:
try:
self.delete_idp(idp['id'])
except exception.IdentityProviderNotFound:
LOG.debug(('Identity Provider %(idpid)s not found when '
'deleting domain contents for %(domainid)s, '
'continuing with cleanup.'),
{'idpid': idp['id'], 'domainid': domain_id})
def create_idp(self, idp_id, idp):
auto_created_domain = False

View File

@ -21,7 +21,6 @@ import keystone.conf
from keystone.credential.providers import fernet as credential_fernet
from keystone import exception
from keystone.tests import unit
from keystone.tests.unit import default_fixtures
from keystone.tests.unit import ksfixtures
from keystone.tests.unit import test_v3
from keystone.tests.unit import utils as test_utils
@ -36,7 +35,7 @@ class ResourceTestCase(test_v3.RestfulTestCase,
"""Test domains and projects."""
def setUp(self):
super(ResourceTestCase, self).setUp()
super(ResourceTestCase, self).setUp(enable_sqlite_foreign_key=True)
self.useFixture(
ksfixtures.KeyRepository(
self.config_fixture,
@ -152,10 +151,6 @@ class ResourceTestCase(test_v3.RestfulTestCase,
self.head(resource_url, expected_status=http_client.OK)
def test_list_limit_for_domains(self):
PROVIDERS.resource_api.create_domain(
default_fixtures.ROOT_DOMAIN['id'], default_fixtures.ROOT_DOMAIN
)
for x in range(6):
domain = {'domain': unit.new_domain_ref()}
self.post('/domains', body=domain)
@ -388,6 +383,26 @@ class ResourceTestCase(test_v3.RestfulTestCase,
r = PROVIDERS.credential_api.get_credential(credential['id'])
self.assertDictEqual(credential, r)
def test_delete_domain_with_idp(self):
# Create a new domain
domain_ref = unit.new_domain_ref()
r = self.post('/domains', body={'domain': domain_ref})
self.assertValidDomainResponse(r, domain_ref)
domain_id = r.result['domain']['id']
# Create a Idp in the domain
self.put('/OS-FEDERATION/identity_providers/test_idp',
body={"identity_provider": {
"domain_id": domain_id}},
expected_status=http_client.CREATED)
# Disable and delete the domain with no error.
self.patch('/domains/%(domain_id)s' % {
'domain_id': domain_id},
body={'domain': {'enabled': False}})
self.delete('/domains/%s' % domain_id)
# The Idp is deleted as well
self.get('/OS-FEDERATION/identity_providers/test_idp',
expected_status=http_client.NOT_FOUND)
def test_delete_domain_deletes_is_domain_project(self):
"""Check the project that acts as a domain is deleted.

View File

@ -0,0 +1,6 @@
---
fixes:
- |
[`bug 1760809 <https://bugs.launchpad.net/keystone/+bug/1760809>`_]
Identity providers registered to domains will now be cleaned up when the
domain is deleted.