Merge "Implement Flavor Extra-specs Key/Value Pairs"

This commit is contained in:
Jenkins 2014-07-04 17:48:17 +00:00 committed by Gerrit Code Review
commit 784770366c
3 changed files with 36 additions and 2 deletions

View File

@ -33,6 +33,7 @@ resources:
vcpus: 1 vcpus: 1
disk: 20 disk: 20
swap: 2 swap: 2
extra_specs: {"quota:disk_read_bytes_sec": "10240000"}
``` ```
### Issues with the Nova Flavor plugin ### Issues with the Nova Flavor plugin

View File

@ -37,10 +37,10 @@ class NovaFlavor(resource.Resource):
PROPERTIES = ( PROPERTIES = (
RAM, VCPUS, DISK, SWAP, EPHEMERAL, RAM, VCPUS, DISK, SWAP, EPHEMERAL,
RXTX_FACTOR, RXTX_FACTOR, EXTRA_SPECS,
) = ( ) = (
'ram', 'vcpus', 'disk', 'swap', 'ephemeral', 'ram', 'vcpus', 'disk', 'swap', 'ephemeral',
'rxtx_factor', 'rxtx_factor', 'extra_specs',
) )
properties_schema = { properties_schema = {
@ -76,6 +76,12 @@ class NovaFlavor(resource.Resource):
_('RX/TX factor.'), _('RX/TX factor.'),
default=1.0 default=1.0
), ),
EXTRA_SPECS: properties.Schema(
properties.Schema.MAP,
_('Key/Value pairs to extend the capabilities of the flavor.'),
update_allowed=True,
),
} }
def __init__(self, name, json_snippet, stack): def __init__(self, name, json_snippet, stack):
@ -86,15 +92,28 @@ class NovaFlavor(resource.Resource):
args['flavorid'] = 'auto' args['flavorid'] = 'auto'
args['name'] = self.physical_resource_name() args['name'] = self.physical_resource_name()
args['is_public'] = False args['is_public'] = False
flavor_keys = args.pop(self.EXTRA_SPECS)
flavor = self.nova().flavors.create(**args) flavor = self.nova().flavors.create(**args)
self.resource_id_set(flavor.id) self.resource_id_set(flavor.id)
if flavor_keys:
flavor.set_keys(flavor_keys)
tenant = self.stack.context.tenant_id tenant = self.stack.context.tenant_id
# grant access to the active project and the admin project # grant access to the active project and the admin project
self.nova().flavor_access.add_tenant_access(flavor, tenant) self.nova().flavor_access.add_tenant_access(flavor, tenant)
self.nova().flavor_access.add_tenant_access(flavor, 'admin') self.nova().flavor_access.add_tenant_access(flavor, 'admin')
def handle_update(self, json_snippet, tmpl_diff, prop_diff):
"""Update nova flavor."""
if self.EXTRA_SPECS in prop_diff:
flavor = self.nova().flavors.get(self.resource_id)
old_keys = flavor.get_keys()
flavor.unset_keys(old_keys)
new_keys = prop_diff.get(self.EXTRA_SPECS)
if new_keys is not None:
flavor.set_keys(new_keys)
def handle_delete(self): def handle_delete(self):
if self.resource_id is None: if self.resource_id is None:
return return

View File

@ -35,6 +35,7 @@ flavor_template = {
'swap': 2, 'swap': 2,
'rxtx_factor': 1.0, 'rxtx_factor': 1.0,
'ephemeral': 0, 'ephemeral': 0,
'extra_specs': {"foo": "bar"}
} }
} }
} }
@ -75,8 +76,21 @@ class NovaFlavorTest(HeatTestCase):
value.id = flavor_id value.id = flavor_id
self.flavors.create.return_value = value self.flavors.create.return_value = value
self.my_flavor.handle_create() self.my_flavor.handle_create()
value.set_keys.assert_called_once_with({"foo": "bar"})
self.assertEqual(flavor_id, self.my_flavor.resource_id) self.assertEqual(flavor_id, self.my_flavor.resource_id)
def test_flavor_handle_update_keys(self):
value = mock.MagicMock()
self.flavors.get.return_value = value
value.get_keys.return_value = {}
new_keys = {"new_foo": "new_bar"}
prop_diff = {'extra_specs': new_keys}
self.my_flavor.handle_update(json_snippet=None,
tmpl_diff=None, prop_diff=prop_diff)
value.unset_keys.assert_called_once_with({})
value.set_keys.assert_called_once_with(new_keys)
def test_flavor_handle_delete(self): def test_flavor_handle_delete(self):
self.resource_id = None self.resource_id = None
self.assertIsNone(self.my_flavor.handle_delete()) self.assertIsNone(self.my_flavor.handle_delete())