From bac58eec6381f72e6d5ca827d9a429b81723010d Mon Sep 17 00:00:00 2001 From: Thomas Herve Date: Thu, 9 May 2013 15:23:37 +0200 Subject: [PATCH] Implement CinderVolume.FnGetAtt This allows retrieving Cinder properties in the template. Change-Id: Id20d4d2cbd5f78ad4412f6260d66b43bd2ef6596 --- heat/engine/resources/volume.py | 17 ++++++++++ heat/tests/test_volume.py | 57 ++++++++++++++++++++++++++++++++- 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/heat/engine/resources/volume.py b/heat/engine/resources/volume.py index 9a2adff8..c1a4ae4c 100644 --- a/heat/engine/resources/volume.py +++ b/heat/engine/resources/volume.py @@ -14,6 +14,8 @@ # under the License. import eventlet +import json + from heat.openstack.common import log as logging from heat.openstack.common.importutils import try_import @@ -168,6 +170,21 @@ class CinderVolume(Volume): if self.properties[prop]) return arguments + def FnGetAtt(self, key): + if key == 'id': + return self.resource_id + attributes = ['availability_zone', 'size', 'snapshot_id', + 'display_name', 'display_description', 'volume_type', + 'metadata', 'source_volid', 'status', 'created_at', + 'bootable'] + if key not in attributes: + raise exception.InvalidTemplateAttribute(resource=self.name, + key=key) + vol = self.cinder().volumes.get(self.resource_id) + if key == 'metadata': + return unicode(json.dumps(vol.metadata)) + return unicode(getattr(vol, key)) + def resource_mapping(): return { diff --git a/heat/tests/test_volume.py b/heat/tests/test_volume.py index 141a21aa..3bc19f25 100644 --- a/heat/tests/test_volume.py +++ b/heat/tests/test_volume.py @@ -14,6 +14,7 @@ import eventlet +import json from testtools import skipIf @@ -460,14 +461,68 @@ class VolumeTest(HeatTestCase): self.m.VerifyAll() + def test_cinder_fn_getatt(self): + fv = FakeVolume('creating', 'available', availability_zone='zone1', + size=1, snapshot_id='snap-123', display_name='name', + display_description='desc', volume_type='lvm', + metadata={'key': 'value'}, source_volid=None, + status='available', bootable=False, + created_at='2013-02-25T02:40:21.000000') + stack_name = 'test_volume_stack' + + clients.OpenStackClients.cinder().MultipleTimes().AndReturn( + self.cinder_fc) + self.cinder_fc.volumes.create( + size=u'1', availability_zone='nova', + display_description=None, + display_name='%s.DataVolume' % stack_name).AndReturn(fv) + + eventlet.sleep(1).AndReturn(None) + self.cinder_fc.volumes.get('vol-123').MultipleTimes().AndReturn(fv) + + self.m.ReplayAll() + + t = template_format.parse(volume_template) + t['Resources']['DataVolume']['Properties'] = { + 'size': '1', + 'availability_zone': 'nova', + } + stack = parse_stack(t, stack_name=stack_name) + + resource = vol.CinderVolume('DataVolume', + t['Resources']['DataVolume'], + stack) + scheduler.TaskRunner(resource.create)() + self.assertEqual(u'vol-123', resource.FnGetAtt('id')) + self.assertEqual(u'zone1', resource.FnGetAtt('availability_zone')) + self.assertEqual(u'1', resource.FnGetAtt('size')) + self.assertEqual(u'snap-123', resource.FnGetAtt('snapshot_id')) + self.assertEqual(u'name', resource.FnGetAtt('display_name')) + self.assertEqual(u'desc', resource.FnGetAtt('display_description')) + self.assertEqual(u'lvm', resource.FnGetAtt('volume_type')) + self.assertEqual(json.dumps({'key': 'value'}), + resource.FnGetAtt('metadata')) + self.assertEqual(u'None', resource.FnGetAtt('source_volid')) + self.assertEqual(u'available', resource.FnGetAtt('status')) + self.assertEqual(u'2013-02-25T02:40:21.000000', + resource.FnGetAtt('created_at')) + self.assertEqual(u'False', resource.FnGetAtt('bootable')) + error = self.assertRaises(exception.InvalidTemplateAttribute, + resource.FnGetAtt, 'unknown') + self.assertEqual( + 'The Referenced Attribute (DataVolume unknown) is incorrect.', + str(error)) + class FakeVolume: status = 'attaching' id = 'vol-123' - def __init__(self, initial_status, final_status): + def __init__(self, initial_status, final_status, **attrs): self.status = initial_status self.final_status = final_status + for key, value in attrs.iteritems(): + setattr(self, key, value) def get(self): self.status = self.final_status -- 2.45.2