summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Hardy <shardy@redhat.com>2014-09-04 22:10:47 +0100
committerKieran Spear <kispear@gmail.com>2014-09-09 15:15:48 +1000
commit2b4f7be44a7c5eae825c9d340aff8abe93efe449 (patch)
tree440a0db1e50736bfc693c1ea0c98faedf89281f9
parent93f3c78a8bd9ecb79fa3d719468b371e67519969 (diff)
downloadheat-2b4f7be44a7c5eae825c9d340aff8abe93efe449.tar.gz
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
-rw-r--r--heat/common/heat_keystoneclient.py20
-rw-r--r--heat/tests/test_heatclient.py72
2 files changed, 87 insertions, 5 deletions
diff --git a/heat/common/heat_keystoneclient.py b/heat/common/heat_keystoneclient.py
index f50746ac6..7ee1c48fb 100644
--- a/heat/common/heat_keystoneclient.py
+++ b/heat/common/heat_keystoneclient.py
@@ -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:
+ 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:
- self.domain_admin_client.projects.delete(project=project_id)
+ project.delete()
except kc_exception.NotFound:
pass
diff --git a/heat/tests/test_heatclient.py b/heat/tests/test_heatclient.py
index c219c4097..e759fe654 100644
--- a/heat/tests/test_heatclient.py
+++ b/heat/tests/test_heatclient.py
@@ -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):