Only delete stack user project from correct domain

Check the domain ID for the project matches the configured domain from
heat.conf, so we avoid the bad outcome of deleting the user's project
when heat has been configured for stack domain users after creating
some stacks.

Conflicts:
	heat/common/heat_keystoneclient.py
	heat/tests/test_heatclient.py

Change-Id: I247e732033f44daf0de5b0efeff6c263814d13ab
Closes-Bug: #1365332
This commit is contained in:
Steven Hardy 2014-09-04 22:10:47 +01:00 committed by Kieran Spear
parent 93f3c78a8b
commit 2b4f7be44a
2 changed files with 87 additions and 5 deletions

View File

@ -400,8 +400,26 @@ class KeystoneClientV3(object):
logger.warning(_('Falling back to legacy non-domain project, '
'configure domain in heat.conf'))
return
# If stacks are created before configuring the heat domain, they
# exist in the default domain, in the user's project, which we
# do *not* want to delete! However, if the keystone v3cloudsample
# policy is used, it's possible that we'll get Forbidden when trying
# to get the project, so again we should do nothing
try:
self.domain_admin_client.projects.delete(project=project_id)
project = self.domain_admin_client.projects.get(project=project_id)
except kc_exception.Forbidden:
logger.warning(_('Unable to get details for project %s, '
'not deleting')
% project_id)
return
if project.domain_id != self.stack_domain_id:
logger.warning(_('Not deleting non heat-domain project'))
return
try:
project.delete()
except kc_exception.NotFound:
pass

View File

@ -1177,16 +1177,80 @@ class KeystoneClientTest(HeatTestCase):
self._stub_domain_admin_client()
self.mock_admin_client.projects = self.m.CreateMockAnything()
self.mock_admin_client.projects.delete(project='aprojectid')
self.mock_admin_client.projects.delete(project='aprojectid').AndRaise(
kc_exception.NotFound)
dummy = self.m.CreateMockAnything()
dummy.id = 'aproject123'
dummy.domain_id = 'adomain123'
dummy.delete().AndReturn(None)
self.mock_admin_client.projects.get(project='aprojectid').AndReturn(
dummy)
self.m.ReplayAll()
ctx = utils.dummy_context()
ctx.trust_id = None
heat_ks_client = heat_keystoneclient.KeystoneClient(ctx)
heat_ks_client.delete_stack_domain_project(project_id='aprojectid')
# Second delete will raise ignored NotFound
def test_delete_stack_domain_project_notfound(self):
"""Test the delete_stack_domain_project function."""
self._stub_domain_admin_client()
self.mock_admin_client.projects = self.m.CreateMockAnything()
dummy = self.m.CreateMockAnything()
dummy.id = 'aproject123'
dummy.domain_id = 'adomain123'
dummy.delete().AndRaise(kc_exception.NotFound)
self.mock_admin_client.projects.get(project='aprojectid').AndReturn(
dummy)
self.m.ReplayAll()
ctx = utils.dummy_context()
ctx.trust_id = None
heat_ks_client = heat_keystoneclient.KeystoneClient(ctx)
heat_ks_client.delete_stack_domain_project(project_id='aprojectid')
def test_delete_stack_domain_project_forbidden(self):
"""Test the delete_stack_domain_project function."""
self._stub_domain_admin_client()
self.mock_admin_client.projects = self.m.CreateMockAnything()
self.mock_admin_client.projects.get(project='aprojectid').AndRaise(
kc_exception.Forbidden)
self.m.ReplayAll()
ctx = utils.dummy_context()
ctx.trust_id = None
heat_ks_client = heat_keystoneclient.KeystoneClient(ctx)
heat_ks_client.delete_stack_domain_project(project_id='aprojectid')
def test_delete_stack_domain_project_wrongdomain(self):
"""Test the delete_stack_domain_project function."""
self._stub_domain_admin_client()
self.mock_admin_client.projects = self.m.CreateMockAnything()
dummy = self.m.CreateMockAnything()
dummy.id = 'aproject123'
dummy.domain_id = 'default'
self.mock_admin_client.projects.get(project='aprojectid').AndReturn(
dummy)
self.m.ReplayAll()
ctx = utils.dummy_context()
ctx.trust_id = None
heat_ks_client = heat_keystoneclient.KeystoneClient(ctx)
heat_ks_client.delete_stack_domain_project(project_id='aprojectid')
def test_delete_stack_domain_project_nodomain(self):
"""Test the delete_stack_domain_project function."""
cfg.CONF.clear_override('stack_user_domain')
ctx = utils.dummy_context()
ctx.trust_id = None
heat_ks_client = heat_keystoneclient.KeystoneClient(ctx)
heat_ks_client.delete_stack_domain_project(project_id='aprojectid')
def test_delete_stack_domain_project_legacy_fallback(self):