From a8accbba98b5fc15562864030f49d20570bf8412 Mon Sep 17 00:00:00 2001 From: Oleksii Chuprykov Date: Mon, 7 Mar 2016 17:16:29 +0200 Subject: [PATCH] Check RBAC policy for nested stacks This prevents stacks with forbidden resources start to create/update or stuck in DELETE_IN_PROGRESS state, if delete the stack with admin resources in nested stacks. Also we need to allow get id of resource that in SUSPEND state, because of we use stack preview in SUSPEND state. Change-Id: I328891e62b4f4bcf620c52ef9d4d8ab60801a651 Closes-Bug: #1539145 --- heat/common/policy.py | 8 ++++++- heat/engine/stack.py | 2 ++ .../functional/test_conditional_exposure.py | 21 +++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/heat/common/policy.py b/heat/common/policy.py index 7ade8403ea..6c904efedd 100644 --- a/heat/common/policy.py +++ b/heat/common/policy.py @@ -24,7 +24,6 @@ import six from heat.common import exception - CONF = cfg.CONF LOG = logging.getLogger(__name__) @@ -111,5 +110,12 @@ class ResourceEnforcer(Enforcer): return result def enforce_stack(self, stack, scope=None, target=None): + stack.preview_resources() for res in stack.resources.values(): + if res.has_nested(): + self.enforce_stack(res.nested()) + # After the preview_resources() call nested stack name will + # be equal to stack.name + res.name, without uuid part. Get + # rid of the side effect of preview. + res._nested = None self.enforce(stack.context, res.type(), scope=scope, target=target) diff --git a/heat/engine/stack.py b/heat/engine/stack.py index fcf2cee683..a91f7e3f4b 100644 --- a/heat/engine/stack.py +++ b/heat/engine/stack.py @@ -685,6 +685,8 @@ class Stack(collections.Mapping): (r.CREATE, r.COMPLETE), (r.RESUME, r.IN_PROGRESS), (r.RESUME, r.COMPLETE), + (r.SUSPEND, r.IN_PROGRESS), + (r.SUSPEND, r.COMPLETE), (r.UPDATE, r.IN_PROGRESS), (r.UPDATE, r.COMPLETE)) and (r.FnGetRefId() == refid or r.name == refid)): diff --git a/heat_integrationtests/functional/test_conditional_exposure.py b/heat_integrationtests/functional/test_conditional_exposure.py index c1175f178d..77159fe679 100644 --- a/heat_integrationtests/functional/test_conditional_exposure.py +++ b/heat_integrationtests/functional/test_conditional_exposure.py @@ -76,6 +76,19 @@ resources: ram: 20000 vcpus: 10 """ + fl_tmpl_nested = """ +heat_template_version: 2015-10-15 +resources: + not4everyonerg: + type: OS::Heat::ResourceGroup + properties: + count: 1 + resource_def: + type: OS::Nova::Flavor + properties: + ram: 20000 + vcpus: 10 +""" def test_non_admin_forbidden_create_flavors(self): """Fail to create Flavor resource w/o admin role. @@ -95,3 +108,11 @@ resources: resources = self.client.resource_types.list() self.assertNotIn(self.forbidden_resource_type, (r.resource_type for r in resources)) + + def test_non_admin_forbidden_create_flavors_nested(self): + stack_name = self._stack_rand_name() + ex = self.assertRaises(exc.Forbidden, + self.client.stacks.create, + stack_name=stack_name, + template=self.fl_tmpl_nested) + self.assertIn(self.forbidden_resource_type, ex.message)