From 79acbf0ad730a4f58f7606c2f093b22a968f5562 Mon Sep 17 00:00:00 2001 From: Dan Smith Date: Wed, 13 Mar 2013 13:24:23 -0400 Subject: Fix use of potentially-stale instance_type in tenant_usage The simple_tenant_usage API extension may return incorrect billing information if a flavor is changed or deleted while an instance using it is still running. This makes it use the stashed instance_type instead. Fixes bug 1154707 Change-Id: Ifce33488e5ef8aa942051d882407a3e2d088aaf5 --- .../compute/contrib/simple_tenant_usage.py | 15 ++---------- .../compute/contrib/test_simple_tenant_usage.py | 27 +++++++++++++--------- 2 files changed, 18 insertions(+), 24 deletions(-) (limited to 'nova') diff --git a/nova/api/openstack/compute/contrib/simple_tenant_usage.py b/nova/api/openstack/compute/contrib/simple_tenant_usage.py index f759e90b0..0fa9b9e40 100644 --- a/nova/api/openstack/compute/contrib/simple_tenant_usage.py +++ b/nova/api/openstack/compute/contrib/simple_tenant_usage.py @@ -24,7 +24,7 @@ from nova.api.openstack import extensions from nova.api.openstack import wsgi from nova.api.openstack import xmlutil from nova.compute import api -from nova import exception +from nova.compute import instance_types from nova.openstack.common import timeutils authorize_show = extensions.extension_authorizer('compute', @@ -119,18 +119,7 @@ class SimpleTenantUsageController(object): info['hours'] = self._hours_for(instance, period_start, period_stop) - flavor_type = instance['instance_type_id'] - - if not flavors.get(flavor_type): - try: - it_ref = compute_api.get_instance_type(context, - flavor_type) - flavors[flavor_type] = it_ref - except exception.InstanceTypeNotFound: - # can't bill if there is no instance type - continue - - flavor = flavors[flavor_type] + flavor = instance_types.extract_instance_type(instance) info['instance_id'] = instance['uuid'] info['name'] = instance['display_name'] diff --git a/nova/tests/api/openstack/compute/contrib/test_simple_tenant_usage.py b/nova/tests/api/openstack/compute/contrib/test_simple_tenant_usage.py index 4c59e5aa9..ab9906135 100644 --- a/nova/tests/api/openstack/compute/contrib/test_simple_tenant_usage.py +++ b/nova/tests/api/openstack/compute/contrib/test_simple_tenant_usage.py @@ -22,6 +22,7 @@ import webob from nova.api.openstack.compute.contrib import simple_tenant_usage from nova.compute import api +from nova.compute import instance_types from nova import context from nova.openstack.common import jsonutils from nova.openstack.common import policy as common_policy @@ -29,6 +30,7 @@ from nova.openstack.common import timeutils from nova import policy from nova import test from nova.tests.api.openstack import fakes +from nova import utils SERVERS = 5 TENANTS = 2 @@ -42,17 +44,21 @@ START = NOW - datetime.timedelta(hours=HOURS) STOP = NOW -def fake_instance_type_get(self, context, instance_type_id): - return {'id': 1, - 'vcpus': VCPUS, - 'root_gb': ROOT_GB, - 'ephemeral_gb': EPHEMERAL_GB, - 'memory_mb': MEMORY_MB, - 'name': - 'fakeflavor'} +FAKE_INST_TYPE = {'id': 1, + 'vcpus': VCPUS, + 'root_gb': ROOT_GB, + 'ephemeral_gb': EPHEMERAL_GB, + 'memory_mb': MEMORY_MB, + 'name': 'fakeflavor', + 'flavorid': 'foo', + 'rxtx_factor': 1.0, + 'vcpu_weight': 1, + 'swap': 0} def get_fake_db_instance(start, end, instance_id, tenant_id): + sys_meta = utils.dict_to_metadata( + instance_types.save_instance_type_info({}, FAKE_INST_TYPE)) return {'id': instance_id, 'uuid': '00000000-0000-0000-0000-00000000000000%02d' % instance_id, 'image_ref': '1', @@ -62,7 +68,8 @@ def get_fake_db_instance(start, end, instance_id, tenant_id): 'state_description': 'state', 'instance_type_id': 1, 'launched_at': start, - 'terminated_at': end} + 'terminated_at': end, + 'system_metadata': sys_meta} def fake_instance_get_active_by_window_joined(self, context, begin, end, @@ -77,8 +84,6 @@ def fake_instance_get_active_by_window_joined(self, context, begin, end, class SimpleTenantUsageTest(test.TestCase): def setUp(self): super(SimpleTenantUsageTest, self).setUp() - self.stubs.Set(api.API, "get_instance_type", - fake_instance_type_get) self.stubs.Set(api.API, "get_active_by_window", fake_instance_get_active_by_window_joined) self.admin_context = context.RequestContext('fakeadmin_0', -- cgit