Convergence: add support for the path_component
store the attr name and path so attributes don't get shadowed e.g. get_attr: [res1, attr_x, show] get_attr: [res1, attr_x, something] Change-Id: I724e91b32776aa5813d2b821c2062424e0635a69
This commit is contained in:
parent
bdfd84e19d
commit
dd0859a080
|
@ -125,6 +125,19 @@ class GetAttThenSelect(cfn_funcs.GetAtt):
|
|||
path_components = function.resolve(self._path_components)
|
||||
return attributes.select_from_attribute(attribute, path_components)
|
||||
|
||||
def dep_attrs(self, resource_name):
|
||||
if self._resource().name == resource_name:
|
||||
path = function.resolve(self._path_components)
|
||||
attr = [function.resolve(self._attribute)]
|
||||
if path:
|
||||
attrs = [tuple(attr + path)]
|
||||
else:
|
||||
attrs = attr
|
||||
else:
|
||||
attrs = []
|
||||
return itertools.chain(function.dep_attrs(self.args, resource_name),
|
||||
attrs)
|
||||
|
||||
|
||||
class GetAtt(GetAttThenSelect):
|
||||
'''
|
||||
|
|
|
@ -1474,8 +1474,11 @@ class Resource(object):
|
|||
'''
|
||||
if self.stack.has_cache_data(self.name):
|
||||
# Load from cache for lightweight resources.
|
||||
complex_key = key
|
||||
if path:
|
||||
complex_key = tuple([key] + list(path))
|
||||
attribute = self.stack.cache_data_resource_attribute(
|
||||
self.name, key)
|
||||
self.name, complex_key)
|
||||
else:
|
||||
try:
|
||||
attribute = self.attributes[key]
|
||||
|
|
|
@ -315,7 +315,10 @@ def construct_input_data(rsrc):
|
|||
resolved_attributes = {}
|
||||
for attr in attributes:
|
||||
try:
|
||||
resolved_attributes[attr] = rsrc.FnGetAtt(attr)
|
||||
if isinstance(attr, six.string_types):
|
||||
resolved_attributes[attr] = rsrc.FnGetAtt(attr)
|
||||
else:
|
||||
resolved_attributes[attr] = rsrc.FnGetAtt(*attr)
|
||||
except exception.InvalidTemplateAttribute as ita:
|
||||
LOG.info(six.text_type(ita))
|
||||
|
||||
|
|
|
@ -520,12 +520,15 @@ class MiscMethodsTest(common.HeatTestCase):
|
|||
self.ctx = utils.dummy_context()
|
||||
self.stack = tools.get_stack(
|
||||
'check_workflow_create_stack', self.ctx,
|
||||
template=tools.string_template_five, convergence=True)
|
||||
template=tools.attr_cache_template, convergence=True)
|
||||
self.stack.converge_stack(self.stack.t)
|
||||
self.resource = self.stack['A']
|
||||
|
||||
def test_construct_input_data_ok(self):
|
||||
expected_input_data = {'attrs': {'value': None},
|
||||
expected_input_data = {'attrs': {(u'flat_dict', u'key2'): 'val2',
|
||||
(u'flat_dict', u'key3'): 'val3',
|
||||
(u'nested_dict', u'dict', u'a'): 1,
|
||||
(u'nested_dict', u'dict', u'b'): 2},
|
||||
'id': mock.ANY,
|
||||
'reference_id': 'A',
|
||||
'name': 'A'}
|
||||
|
|
|
@ -123,6 +123,32 @@ resources:
|
|||
salt: {get_param: salt}
|
||||
'''
|
||||
|
||||
attr_cache_template = '''
|
||||
heat_template_version: 2013-05-23
|
||||
resources:
|
||||
A:
|
||||
type: ResourceWithComplexAttributesType
|
||||
B:
|
||||
type: OS::Heat::RandomString
|
||||
properties:
|
||||
salt: {get_attr: [A, flat_dict, key2]}
|
||||
C:
|
||||
type: OS::Heat::RandomString
|
||||
depends_on: [A, B]
|
||||
properties:
|
||||
salt: {get_attr: [A, nested_dict, dict, a]}
|
||||
D:
|
||||
type: OS::Heat::RandomString
|
||||
depends_on: C
|
||||
properties:
|
||||
salt: {get_attr: [A, nested_dict, dict, b]}
|
||||
E:
|
||||
type: OS::Heat::RandomString
|
||||
depends_on: C
|
||||
properties:
|
||||
salt: {get_attr: [A, flat_dict, key3]}
|
||||
'''
|
||||
|
||||
|
||||
def get_stack(stack_name, ctx, template=None, with_params=True,
|
||||
convergence=False):
|
||||
|
|
|
@ -130,6 +130,23 @@ outputs:
|
|||
{get_attr: [BResource, attr_B3]}]
|
||||
"""
|
||||
|
||||
tmpl6 = """
|
||||
heat_template_version: 2015-04-30
|
||||
resources:
|
||||
AResource:
|
||||
type: ResourceWithComplexAttributesType
|
||||
BResource:
|
||||
type: ResourceWithPropsType
|
||||
properties:
|
||||
Foo: {get_attr: [AResource, list, 1]}
|
||||
Doo: {get_attr: [AResource, nested_dict, dict, b]}
|
||||
outputs:
|
||||
out1:
|
||||
value: [{get_attr: [AResource, flat_dict, key2]},
|
||||
{get_attr: [AResource, nested_dict, string]},
|
||||
{get_attr: [BResource, attr_B3]}]
|
||||
"""
|
||||
|
||||
|
||||
class DepAttrsTest(common.HeatTestCase):
|
||||
|
||||
|
@ -159,7 +176,14 @@ class DepAttrsTest(common.HeatTestCase):
|
|||
'attr_A3', 'attr_A4'},
|
||||
'BResource': {'attr_B1', 'attr_B2', 'meta_B2',
|
||||
'attr_B3'},
|
||||
'CResource': set()}))
|
||||
'CResource': set()})),
|
||||
('nested_attr',
|
||||
dict(tmpl=tmpl6,
|
||||
expected={'AResource': set([(u'flat_dict', u'key2'),
|
||||
(u'list', 1),
|
||||
(u'nested_dict', u'dict', u'b'),
|
||||
(u'nested_dict', u'string')]),
|
||||
'BResource': set(['attr_B3'])}))
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
|
|
Loading…
Reference in New Issue