diff --git a/heat/engine/template.py b/heat/engine/template.py index 7c411126c8..070ded3051 100644 --- a/heat/engine/template.py +++ b/heat/engine/template.py @@ -155,7 +155,13 @@ class Template(collections.Mapping): def handle_getatt(args): resource, att = args try: - return resources[resource].FnGetAtt(att) + r = resources[resource] + if r.state in ( + r.CREATE_IN_PROGRESS, + r.CREATE_COMPLETE, + r.UPDATE_IN_PROGRESS, + r.UPDATE_COMPLETE): + return r.FnGetAtt(att) except KeyError: raise exception.InvalidTemplateAttribute(resource=resource, key=att) diff --git a/heat/tests/test_metadata_refresh.py b/heat/tests/test_metadata_refresh.py index 26c1101520..178110324b 100644 --- a/heat/tests/test_metadata_refresh.py +++ b/heat/tests/test_metadata_refresh.py @@ -179,6 +179,7 @@ class MetadataRefreshTest(HeatTestCase): s2 = self.stack.resources['S2'] files = s1.metadata['AWS::CloudFormation::Init']['config']['files'] cont = files['/tmp/random_file']['content'] + self.assertEqual(s2.CREATE_COMPLETE, s2.state) self.assertEqual(cont, 's2-ip=1.2.3.5') s1.metadata_update() @@ -247,7 +248,7 @@ class WaitCondMetadataUpdateTest(HeatTestCase): def check_empty(sleep_time): self.assertEqual(watch.FnGetAtt('Data'), '{}') - self.assertEqual(inst.metadata['test'], '{}') + self.assertEqual(inst.metadata['test'], None) def update_metadata(id, data, reason): self.man.metadata_update(self.ctx, diff --git a/heat/tests/test_parser.py b/heat/tests/test_parser.py index adad9e6b2f..dcdff3095e 100644 --- a/heat/tests/test_parser.py +++ b/heat/tests/test_parser.py @@ -1203,3 +1203,41 @@ class StackTest(HeatTestCase): parser.Template({})) self.assertRaises(ValueError, parser.Stack, None, '#test', parser.Template({})) + + @stack_delete_after + def test_resource_state_get_att(self): + tmpl = { + 'Resources': {'AResource': {'Type': 'GenericResourceType'}}, + 'Outputs': {'TestOutput': {'Value': { + 'Fn::GetAtt': ['AResource', 'Foo']}} + } + } + + self.stack = parser.Stack(self.ctx, 'resource_state_get_att', + template.Template(tmpl)) + self.stack.store() + self.stack.create() + self.assertEqual(self.stack.state, parser.Stack.CREATE_COMPLETE) + self.assertTrue('AResource' in self.stack) + rsrc = self.stack['AResource'] + rsrc.resource_id_set('aaaa') + self.assertEqual('AResource', rsrc.FnGetAtt('foo')) + + for state in ( + rsrc.CREATE_IN_PROGRESS, + rsrc.CREATE_COMPLETE, + rsrc.UPDATE_IN_PROGRESS, + rsrc.UPDATE_COMPLETE): + rsrc.state = state + self.assertEqual('AResource', self.stack.output('TestOutput')) + for state in ( + rsrc.CREATE_FAILED, + rsrc.DELETE_IN_PROGRESS, + rsrc.DELETE_FAILED, + rsrc.DELETE_COMPLETE, + rsrc.UPDATE_FAILED, + None): + rsrc.state = state + self.assertEqual(None, self.stack.output('TestOutput')) + + rsrc.state = rsrc.CREATE_COMPLETE