Only call FnGetAtt if resource is in acceptable state.

This will give resource type authors some certainty on what error
checking their FnGetAtt methods will require.

Fixes bug: #1184794

Change-Id: Iec456075c14cd609cf9607f07bce23e4c6b33c0c
This commit is contained in:
Steve Baker 2013-06-04 16:40:12 +12:00
parent 4c556ae933
commit c19a3deb64
3 changed files with 47 additions and 2 deletions

View File

@ -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)

View File

@ -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,

View File

@ -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