b65d506a5f
When you create a flavor, you can set an is_public flag to be True or False. It is True by default. When False, the intention is that the flavor is only accessible by an admin, unless you use the flavor_access API extension to grant access to specific tenants. Unfortunately, the only place in the code where this was being enforced was when listing flavors through the API. It would filter out the non-public ones for a non-admin. Otherwise, the flavor was accessible. You could get the details, and you could boot an instance with it, if you figured out a valid flavor ID. This patch adds enforcement down in the db layer. It also fixes one place in the API where the context wasn't passed down to enable the enforcement to happen. Fix bug 1194093. Change-Id: I5b37fa0bb19683fe1642fd81222547d4a317054e
111 lines
3.4 KiB
Python
111 lines
3.4 KiB
Python
# Copyright 2012 OpenStack Foundation
|
|
# All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import datetime
|
|
|
|
import webob
|
|
|
|
from nova.compute import flavors
|
|
from nova.openstack.common import jsonutils
|
|
from nova import test
|
|
from nova.tests.api.openstack import fakes
|
|
|
|
|
|
def fake_get_flavor_by_flavor_id(flavorid, ctxt=None):
|
|
return {
|
|
'id': flavorid,
|
|
'flavorid': str(flavorid),
|
|
'root_gb': 1,
|
|
'ephemeral_gb': 1,
|
|
'name': u'test',
|
|
'deleted': False,
|
|
'created_at': datetime.datetime(2012, 1, 1, 1, 1, 1, 1),
|
|
'updated_at': None,
|
|
'memory_mb': 512,
|
|
'vcpus': 1,
|
|
'extra_specs': {},
|
|
'deleted_at': None,
|
|
'vcpu_weight': None,
|
|
}
|
|
|
|
|
|
def fake_get_all_flavors(inactive=0, filters=None):
|
|
return {
|
|
'fake1': fake_get_flavor_by_flavor_id(1),
|
|
'fake2': fake_get_flavor_by_flavor_id(2)
|
|
}
|
|
|
|
|
|
class FlavorextradataTest(test.TestCase):
|
|
def setUp(self):
|
|
super(FlavorextradataTest, self).setUp()
|
|
ext = ('nova.api.openstack.compute.contrib'
|
|
'.flavorextradata.Flavorextradata')
|
|
self.flags(osapi_compute_extension=[ext])
|
|
self.stubs.Set(flavors, 'get_flavor_by_flavor_id',
|
|
fake_get_flavor_by_flavor_id)
|
|
self.stubs.Set(flavors, 'get_all_flavors', fake_get_all_flavors)
|
|
|
|
def _verify_flavor_response(self, flavor, expected):
|
|
for key in expected:
|
|
self.assertEquals(flavor[key], expected[key])
|
|
|
|
def test_show(self):
|
|
expected = {
|
|
'flavor': {
|
|
'id': '1',
|
|
'name': 'test',
|
|
'ram': 512,
|
|
'vcpus': 1,
|
|
'disk': 1,
|
|
'OS-FLV-EXT-DATA:ephemeral': 1,
|
|
}
|
|
}
|
|
|
|
url = '/v2/fake/flavors/1'
|
|
req = webob.Request.blank(url)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
res = req.get_response(fakes.wsgi_app(init_only=('flavors',)))
|
|
body = jsonutils.loads(res.body)
|
|
self._verify_flavor_response(body['flavor'], expected['flavor'])
|
|
|
|
def test_detail(self):
|
|
expected = [
|
|
{
|
|
'id': '1',
|
|
'name': 'test',
|
|
'ram': 512,
|
|
'vcpus': 1,
|
|
'disk': 1,
|
|
'OS-FLV-EXT-DATA:ephemeral': 1,
|
|
},
|
|
{
|
|
'id': '2',
|
|
'name': 'test',
|
|
'ram': 512,
|
|
'vcpus': 1,
|
|
'disk': 1,
|
|
'OS-FLV-EXT-DATA:ephemeral': 1,
|
|
},
|
|
]
|
|
|
|
url = '/v2/fake/flavors/detail'
|
|
req = webob.Request.blank(url)
|
|
req.headers['Content-Type'] = 'application/json'
|
|
res = req.get_response(fakes.wsgi_app(init_only=('flavors',)))
|
|
body = jsonutils.loads(res.body)
|
|
for i, flavor in enumerate(body['flavors']):
|
|
self._verify_flavor_response(flavor, expected[i])
|