From 6825959560e06725d26625fd21f5c0b78b305492 Mon Sep 17 00:00:00 2001 From: Russell Bryant Date: Tue, 20 Aug 2013 11:06:12 -0400 Subject: [PATCH] Enforce flavor access during instance boot The code in the servers API did not pass the context when retrieving flavor details. That means it would use an admin context instead, bypassing all flavor access control checks. This patch includes the fix, and the corresponding unit test for the v2 API. Closes-bug: #1212179 (cherry picked from commit 4054cc4a22a1fea997dec76afb5646fd6c6ea6b9) Conflicts: nova/api/openstack/compute/plugins/v3/servers.py nova/api/openstack/compute/servers.py nova/tests/api/openstack/compute/plugins/v3/test_servers.py nova/tests/api/openstack/compute/test_servers.py Change-Id: I681ae9965e19767df22fa74c3315e4e03a459d3b --- nova/api/openstack/compute/servers.py | 3 ++- .../api/openstack/compute/test_servers.py | 23 +++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/nova/api/openstack/compute/servers.py b/nova/api/openstack/compute/servers.py index 6908262d9e5..ab06595b26c 100644 --- a/nova/api/openstack/compute/servers.py +++ b/nova/api/openstack/compute/servers.py @@ -844,7 +844,8 @@ def create(self, req, body): try: _get_inst_type = instance_types.get_instance_type_by_flavor_id - inst_type = _get_inst_type(flavor_id, read_deleted="no") + inst_type = _get_inst_type(flavor_id, ctxt=context, + read_deleted="no") (instances, resv_id) = self.compute_api.create(context, inst_type, diff --git a/nova/tests/api/openstack/compute/test_servers.py b/nova/tests/api/openstack/compute/test_servers.py index cd88a2aa59e..5cb26bd4e7d 100644 --- a/nova/tests/api/openstack/compute/test_servers.py +++ b/nova/tests/api/openstack/compute/test_servers.py @@ -34,6 +34,7 @@ from nova.compute import instance_types from nova.compute import task_states from nova.compute import vm_states +import nova.context import nova.db from nova.db.sqlalchemy import models from nova import flags @@ -1703,10 +1704,10 @@ def _check_admin_pass_missing(self, server_dict): """ self.assertTrue("adminPass" not in server_dict) - def _test_create_instance(self): + def _test_create_instance(self, flavor=2): image_uuid = 'c905cedb-7281-47e4-8a62-f26bc5fc4c77' body = dict(server=dict( - name='server_test', imageRef=image_uuid, flavorRef=2, + name='server_test', imageRef=image_uuid, flavorRef=flavor, metadata={'hello': 'world', 'open': 'stack'}, personality={})) req = fakes.HTTPRequest.blank('/v2/fake/servers') @@ -1718,6 +1719,24 @@ def _test_create_instance(self): self._check_admin_pass_len(server) self.assertEqual(FAKE_UUID, server['id']) + def test_create_instance_private_flavor(self): + values = { + 'name': 'fake_name', + 'memory_mb': 512, + 'vcpus': 1, + 'root_gb': 10, + 'ephemeral_gb': 10, + 'flavorid': '1324', + 'swap': 0, + 'rxtx_factor': 0.5, + 'vcpu_weight': 1, + 'disabled': False, + 'is_public': False, + } + nova.db.instance_type_create(nova.context.get_admin_context(), values) + self.assertRaises(webob.exc.HTTPBadRequest, self._test_create_instance, + flavor=1324) + def test_create_server_bad_image_href(self): image_href = 1 flavor_ref = 'http://localhost/123/flavors/3'