From 584e91fc512a6c8cb9c6572261107f39b5536323 Mon Sep 17 00:00:00 2001 From: Tetiana Lashchova Date: Wed, 17 Dec 2014 19:30:25 +0200 Subject: [PATCH] Support path attributes in OS::Heat::AutoScalingGroup Change-Id: I5cd6a711ae778dec1a205c6954efe57837a2db5c Closes-Bug: #1400684 --- heat/common/grouputils.py | 32 +++++++++++++++++++ .../resources/openstack/autoscaling_group.py | 3 ++ heat/engine/resources/resource_group.py | 32 ++++--------------- .../autoscaling/test_heat_scaling_group.py | 16 ++++++++++ 4 files changed, 58 insertions(+), 25 deletions(-) diff --git a/heat/common/grouputils.py b/heat/common/grouputils.py index 9efb75f8e..bb33025ca 100644 --- a/heat/common/grouputils.py +++ b/heat/common/grouputils.py @@ -13,6 +13,8 @@ import six +from heat.common import exception + def get_size(group, include_failed=False): """Get number of member resources managed by the specified group. @@ -61,3 +63,33 @@ def get_member_names(group): Failed resources will be ignored. """ return [r.name for r in get_members(group)] + + +def get_resource(stack, resource_name, use_indices, key): + nested_stack = stack.nested() + try: + if use_indices: + return get_members(stack)[int(resource_name)] + else: + return nested_stack[resource_name] + except (IndexError, KeyError): + raise exception.InvalidTemplateAttribute(resource=stack.name, + key=key) + + +def get_rsrc_attr(stack, key, use_indices, resource_name, *attr_path): + resource = get_resource(stack, resource_name, use_indices, key) + return resource.FnGetAtt(*attr_path) + + +def get_rsrc_id(stack, key, use_indices, resource_name): + resource = get_resource(stack, resource_name, use_indices, key) + return resource.FnGetRefId() + + +def get_nested_attrs(stack, key, use_indices, *path): + path = key.split(".", 2)[1:] + list(path) + if len(path) > 1: + return get_rsrc_attr(stack, key, use_indices, *path) + else: + return get_rsrc_id(stack, key, use_indices, *path) diff --git a/heat/engine/resources/openstack/autoscaling_group.py b/heat/engine/resources/openstack/autoscaling_group.py index 31ac84231..b38c31e9a 100644 --- a/heat/engine/resources/openstack/autoscaling_group.py +++ b/heat/engine/resources/openstack/autoscaling_group.py @@ -158,6 +158,9 @@ class AutoScalingResourceGroup(aws_asg.AutoScalingGroup): if key == self.OUTPUTS_LIST: return [value for name, value in attrs] + if key.startswith("resource."): + return grouputils.get_nested_attrs(self, key, True, *path) + raise exception.InvalidTemplateAttribute(resource=self.name, key=key) diff --git a/heat/engine/resources/resource_group.py b/heat/engine/resources/resource_group.py index ecb4ba9d0..b77ae7fea 100644 --- a/heat/engine/resources/resource_group.py +++ b/heat/engine/resources/resource_group.py @@ -17,6 +17,7 @@ import copy import six from heat.common import exception +from heat.common import grouputils from heat.common.i18n import _ from heat.engine import attributes from heat.engine import constraints @@ -258,41 +259,22 @@ class ResourceGroup(stack_resource.StackResource): return self.delete_nested() def FnGetAtt(self, key, *path): - nested_stack = self.nested() - - def get_resource(resource_name): - try: - return nested_stack[resource_name] - except KeyError: - raise exception.InvalidTemplateAttribute(resource=self.name, - key=key) - - def get_rsrc_attr(resource_name, *attr_path): - resource = get_resource(resource_name) - return resource.FnGetAtt(*attr_path) - - def get_rsrc_id(resource_name): - resource = get_resource(resource_name) - return resource.FnGetRefId() - if key.startswith("resource."): - path = key.split(".", 2)[1:] + list(path) - if len(path) > 1: - return get_rsrc_attr(*path) - else: - return get_rsrc_id(*path) + return grouputils.get_nested_attrs(self, key, False, *path) names = self._resource_names() if key == self.REFS: - return [get_rsrc_id(n) for n in names] + return [grouputils.get_rsrc_id(self, key, False, n) for n in names] if key == self.ATTR_ATTRIBUTES: if not path: raise exception.InvalidTemplateAttribute( resource=self.name, key=key) - return dict((n, get_rsrc_attr(n, *path)) for n in names) + return dict((n, grouputils.get_rsrc_attr( + self, key, False, n, *path)) for n in names) path = [key] + list(path) - return [get_rsrc_attr(n, *path) for n in names] + return [grouputils.get_rsrc_attr(self, key, False, n, *path) + for n in names] def _build_resource_definition(self, include_all=False): res_def = self.properties[self.RESOURCE_DEF] diff --git a/heat/tests/autoscaling/test_heat_scaling_group.py b/heat/tests/autoscaling/test_heat_scaling_group.py index d35a022ef..4309bed26 100644 --- a/heat/tests/autoscaling/test_heat_scaling_group.py +++ b/heat/tests/autoscaling/test_heat_scaling_group.py @@ -309,3 +309,19 @@ class HeatScalingGroupAttrTest(common.HeatTestCase): mock_instances = self.patchobject(grouputils, 'get_size') mock_instances.return_value = 4 self.assertEqual(4, self.group.FnGetAtt('current_size', 'name')) + + def test_index_dotted_attribute(self): + mock_members = self.patchobject(grouputils, 'get_members') + members = [] + output = [] + for ip_ex in six.moves.range(0, 2): + inst = mock.Mock() + inst.name = str(ip_ex) + inst.FnGetAtt.return_value = '2.1.3.%d' % ip_ex + output.append('2.1.3.%d' % ip_ex) + members.append(inst) + mock_members.return_value = members + self.assertEqual(output[0], self.group.FnGetAtt('resource.0', 'Bar')) + self.assertEqual(output[1], self.group.FnGetAtt('resource.1.Bar')) + self.assertRaises(exception.InvalidTemplateAttribute, + self.group.FnGetAtt, 'resource.2')