Create flavor-access for the tenant when creating

a private flavor

In FlavorManage extension, a change has been made to
create flavor-access for a corresponding tenant on
creating a private flavor

This also requires the api-samples for flavor-access
to be changed, since there will be a flavor-access created
by default on creating a private flavor

This commit has a DocImpact

Change-Id: I7795fbd04ae9fc8b1ea6fb27203dfa5217d310ce
Fixes: bug 1209101
This commit is contained in:
Sumanth Nagadavalli 2013-08-08 11:45:42 +05:30
parent 321037b648
commit 6ba248635b
30 changed files with 267 additions and 14 deletions

View File

@ -3,6 +3,10 @@
{
"flavor_id": "10",
"tenant_id": "fake_tenant"
},
{
"flavor_id": "10",
"tenant_id": "openstack"
}
]
}

View File

@ -1,4 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?>
<flavor_access>
<access tenant_id="fake_tenant" flavor_id="10"/>
<access tenant_id="openstack" flavor_id="10"/>
</flavor_access>

View File

@ -3,6 +3,10 @@
{
"flavor_id": "10",
"tenant_id": "fake_tenant"
},
{
"flavor_id": "10",
"tenant_id": "openstack"
}
]
}

View File

@ -1,4 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?>
<flavor_access>
<access tenant_id="fake_tenant" flavor_id="10"/>
<access tenant_id="openstack" flavor_id="10"/>
</flavor_access>

View File

@ -1,3 +1,6 @@
{
"flavor_access": []
"flavor_access": [{
"flavor_id": "10",
"tenant_id": "openstack"
}]
}

View File

@ -1,2 +1,4 @@
<?xml version='1.0' encoding='UTF-8'?>
<flavor_access/>
<flavor_access>
<access tenant_id="openstack" flavor_id="10"/>
</flavor_access>

View File

@ -3,6 +3,10 @@
{
"flavor_id": "10",
"tenant_id": "fake_tenant"
},
{
"flavor_id": "10",
"tenant_id": "openstack"
}
]
}

View File

@ -1,4 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?>
<flavor_access>
<access tenant_id="fake_tenant" flavor_id="10"/>
<access tenant_id="openstack" flavor_id="10"/>
</flavor_access>

View File

@ -3,6 +3,10 @@
{
"flavor_id": "10",
"tenant_id": "fake_tenant"
},
{
"flavor_id": "10",
"tenant_id": "openstack"
}
]
}

View File

@ -1,4 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?>
<flavor_access>
<access tenant_id="fake_tenant" flavor_id="10"/>
<access tenant_id="openstack" flavor_id="10"/>
</flavor_access>

View File

@ -1,3 +1,6 @@
{
"flavor_access": []
"flavor_access": [{
"flavor_id": "10",
"tenant_id": "openstack"
}]
}

View File

@ -1,2 +1,4 @@
<?xml version='1.0' encoding='UTF-8'?>
<flavor_access/>
<flavor_access>
<access tenant_id="openstack" flavor_id="10"/>
</flavor_access>

View File

@ -75,6 +75,9 @@ class FlavorManageController(wsgi.Controller):
flavorid=flavorid, swap=swap,
rxtx_factor=rxtx_factor,
is_public=is_public)
if not flavor['is_public']:
flavors.add_flavor_access(flavor['flavorid'],
context.project_id, context)
req.cache_db_flavor(flavor)
except (exception.InstanceTypeExists,
exception.InstanceTypeIdExists) as err:

View File

@ -79,6 +79,9 @@ class FlavorManageController(wsgi.Controller):
flavorid=flavorid, swap=swap,
rxtx_factor=rxtx_factor,
is_public=is_public)
if not flavor['is_public']:
flavors.add_flavor_access(flavor['flavorid'],
context.project_id, context)
req.cache_db_flavor(flavor)
except (exception.InstanceTypeExists,
exception.InstanceTypeIdExists) as err:

View File

@ -17,8 +17,10 @@ import datetime
import webob
from nova.api.openstack.compute.contrib import flavor_access
from nova.api.openstack.compute.contrib import flavormanage
from nova.compute import flavors
from nova import context
from nova import db
from nova import exception
from nova.openstack.common import jsonutils
@ -391,3 +393,92 @@ class FlavorManageTest(test.NoDBTestCase):
512, 2, None, 1, 1234, 512, 1, True)
self.assertRaises(exception.InvalidInput, flavors.create, "abcdef",
"test_memory_mb", 2, None, 1, 1234, 512, 1, True)
class FakeRequest(object):
environ = {"nova.context": context.get_admin_context()}
class PrivateFlavorManageTest(test.TestCase):
def setUp(self):
super(PrivateFlavorManageTest, self).setUp()
# self.stubs.Set(flavors,
# "get_flavor_by_flavor_id",
# fake_get_flavor_by_flavor_id)
# self.stubs.Set(flavors, "destroy", fake_destroy)
# self.stubs.Set(flavors, "create", fake_create)
self.flags(
osapi_compute_extension=[
'nova.api.openstack.compute.contrib.select_extensions'],
osapi_compute_ext_list=['Flavormanage', 'Flavorextradata',
'Flavor_access', 'Flavor_rxtx', 'Flavor_swap'])
self.controller = flavormanage.FlavorManageController()
self.flavor_access_controller = flavor_access.FlavorAccessController()
self.app = fakes.wsgi_app(init_only=('flavors',))
def test_create_private_flavor_should_create_flavor_access(self):
expected = {
"flavor": {
"name": "test",
"ram": 512,
"vcpus": 2,
"disk": 1,
"OS-FLV-EXT-DATA:ephemeral": 1,
"swap": 512,
"rxtx_factor": 1,
"os-flavor-access:is_public": False
}
}
ctxt = context.RequestContext('fake', 'fake',
is_admin=True, auth_token=True)
self.app = fakes.wsgi_app(init_only=('flavors',),
fake_auth_context=ctxt)
url = '/v2/fake/flavors'
req = webob.Request.blank(url)
req.headers['Content-Type'] = 'application/json'
req.method = 'POST'
req.body = jsonutils.dumps(expected)
res = req.get_response(self.app)
body = jsonutils.loads(res.body)
for key in expected["flavor"]:
self.assertEquals(body["flavor"][key], expected["flavor"][key])
flavor_access_body = self.flavor_access_controller.index(
FakeRequest(), body["flavor"]["id"])
expected_flavor_access_body = {
"tenant_id": "%s" % ctxt.project_id,
"flavor_id": "%s" % body["flavor"]["id"]
}
self.assertTrue(expected_flavor_access_body in
flavor_access_body["flavor_access"])
def test_create_public_flavor_should_not_create_flavor_access(self):
expected = {
"flavor": {
"name": "test",
"ram": 512,
"vcpus": 2,
"disk": 1,
"OS-FLV-EXT-DATA:ephemeral": 1,
"swap": 512,
"rxtx_factor": 1,
"os-flavor-access:is_public": True
}
}
ctxt = context.RequestContext('fake', 'fake',
is_admin=True, auth_token=True)
self.app = fakes.wsgi_app(init_only=('flavors',),
fake_auth_context=ctxt)
self.mox.StubOutWithMock(flavors, "add_flavor_access")
self.mox.ReplayAll()
url = '/v2/fake/flavors'
req = webob.Request.blank(url)
req.headers['Content-Type'] = 'application/json'
req.method = 'POST'
req.body = jsonutils.dumps(expected)
res = req.get_response(self.app)
body = jsonutils.loads(res.body)
for key in expected["flavor"]:
self.assertEquals(body["flavor"][key], expected["flavor"][key])

View File

@ -17,8 +17,10 @@ import datetime
import webob
from nova.api.openstack.compute.plugins.v3 import flavor_access
from nova.api.openstack.compute.plugins.v3 import flavor_manage
from nova.compute import flavors
from nova import context
from nova import exception
from nova.openstack.common import jsonutils
from nova import test
@ -209,3 +211,89 @@ class FlavorManageTest(test.NoDBTestCase):
512, 2, None, 1, 1234, 512, 1, True)
self.assertRaises(exception.InvalidInput, flavors.create, "abcdef",
"test_memory_mb", 2, None, 1, 1234, 512, 1, True)
class FakeRequest(object):
environ = {"nova.context": context.get_admin_context()}
class PrivateFlavorManageTest(test.TestCase):
def setUp(self):
super(PrivateFlavorManageTest, self).setUp()
# self.stubs.Set(flavors,
# "get_flavor_by_flavor_id",
# fake_get_flavor_by_flavor_id)
# self.stubs.Set(flavors, "destroy", fake_destroy)
# self.stubs.Set(flavors, "create", fake_create)
self.controller = flavor_manage.FlavorManageController()
self.flavor_access_controller = flavor_access.FlavorAccessController()
self.app = fakes.wsgi_app(init_only=('flavors',))
def test_create_private_flavor_should_create_flavor_access(self):
req_body = {
"flavor": {
"name": "test",
"ram": 512,
"vcpus": 2,
"disk": 1,
"OS-FLV-EXT-DATA:ephemeral": 1,
"swap": 512,
"rxtx_factor": 1,
"os-flavor-access:is_public": False
}
}
expected = {
"flavor": {
"name": "test",
"ram": 512,
"vcpus": 2,
"disk": 1
}
}
ctxt = context.RequestContext('fake', 'fake',
is_admin=True, auth_token=True)
url = '/os-flavor-manage'
req = fakes.HTTPRequestV3.blank(url, use_admin_context=True)
body = self.controller._create(req, req_body)
for key in expected["flavor"]:
self.assertEquals(body["flavor"][key], expected["flavor"][key])
flavor_access_body = self.flavor_access_controller.index(
FakeRequest(), body["flavor"]["id"])
expected_flavor_access_body = {
"tenant_id": "%s" % ctxt.project_id,
"flavor_id": "%s" % body["flavor"]["id"]
}
self.assertTrue(expected_flavor_access_body in
flavor_access_body["flavor_access"])
def test_create_public_flavor_should_not_create_flavor_access(self):
req_body = {
"flavor": {
"name": "test",
"ram": 512,
"vcpus": 2,
"disk": 1,
"OS-FLV-EXT-DATA:ephemeral": 1,
"swap": 512,
"rxtx_factor": 1,
"os-flavor-access:is_public": True
}
}
expected = {
"flavor": {
"name": "test",
"ram": 512,
"vcpus": 2,
"disk": 1
}
}
self.mox.StubOutWithMock(flavors, "add_flavor_access")
self.mox.ReplayAll()
url = '/os-flavor-manage'
req = fakes.HTTPRequestV3.blank(url, use_admin_context=True)
body = self.controller._create(req, req_body)
for key in expected["flavor"]:
self.assertEquals(body["flavor"][key], expected["flavor"][key])

View File

@ -1,5 +1,9 @@
{
"flavor_access": [
{
"flavor_id": "%(flavor_id)s",
"tenant_id": "openstack"
},
{
"flavor_id": "%(flavor_id)s",
"tenant_id": "%(tenant_id)s"

View File

@ -1,4 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?>
<flavor_access>
<access tenant_id="%(tenant_id)s" flavor_id="%(flavor_id)s"/>
<access tenant_id="openstack" flavor_id="%(flavor_id)s"/>
</flavor_access>

View File

@ -3,6 +3,10 @@
{
"flavor_id": "%(flavor_id)s",
"tenant_id": "fake_tenant"
},
{
"flavor_id": "%(flavor_id)s",
"tenant_id": "openstack"
}
]
}

View File

@ -1,4 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?>
<flavor_access>
<access tenant_id="%(tenant_id)s" flavor_id="%(flavor_id)s"/>
</flavor_access>
<access tenant_id="fake_tenant" flavor_id="10"/>
<access tenant_id="openstack" flavor_id="10"/>
</flavor_access>

View File

@ -1,3 +1,6 @@
{
"flavor_access": []
"flavor_access": [{
"tenant_id": "openstack",
"flavor_id": "%(flavor_id)s"
}]
}

View File

@ -1,2 +1,4 @@
<?xml version='1.0' encoding='UTF-8'?>
<flavor_access/>
<flavor_access>
<access tenant_id="openstack" flavor_id="%(flavor_id)s"/>
</flavor_access>

View File

@ -3386,8 +3386,12 @@ class FlavorAccessSampleJsonTests(ApiSampleTestBaseV2):
response = self._do_post('flavors/10/action',
"flavor-access-remove-tenant-req",
subs)
exp_subs = {
"tenant_id": self.api.project_id,
"flavor_id": "10"
}
self._verify_response('flavor-access-remove-tenant-resp',
{}, response, 200)
exp_subs, response, 200)
class FlavorAccessSampleXmlTests(FlavorAccessSampleJsonTests):

View File

@ -1,5 +1,9 @@
{
"flavor_access": [
{
"flavor_id": "%(flavor_id)s",
"tenant_id": "openstack"
},
{
"flavor_id": "%(flavor_id)s",
"tenant_id": "%(tenant_id)s"

View File

@ -1,4 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?>
<flavor_access>
<access tenant_id="%(tenant_id)s" flavor_id="%(flavor_id)s"/>
<access tenant_id="openstack" flavor_id="%(flavor_id)s"/>
</flavor_access>

View File

@ -3,6 +3,10 @@
{
"flavor_id": "%(flavor_id)s",
"tenant_id": "fake_tenant"
},
{
"flavor_id": "%(flavor_id)s",
"tenant_id": "openstack"
}
]
}

View File

@ -1,4 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?>
<flavor_access>
<access tenant_id="%(tenant_id)s" flavor_id="%(flavor_id)s"/>
</flavor_access>
<access tenant_id="fake_tenant" flavor_id="10"/>
<access tenant_id="openstack" flavor_id="10"/>
</flavor_access>

View File

@ -1,3 +1,6 @@
{
"flavor_access": []
"flavor_access": [{
"tenant_id": "openstack",
"flavor_id": "%(flavor_id)s"
}]
}

View File

@ -1,2 +1,4 @@
<?xml version='1.0' encoding='UTF-8'?>
<flavor_access/>
<flavor_access>
<access tenant_id="openstack" flavor_id="%(flavor_id)s"/>
</flavor_access>

View File

@ -83,8 +83,12 @@ class FlavorAccessSampleJsonTests(api_sample_base.ApiSampleTestBaseV3):
response = self._do_post('flavors/10/action',
"flavor-access-remove-tenant-req",
subs)
exp_subs = {
"tenant_id": self.api.project_id,
"flavor_id": "10"
}
self._verify_response('flavor-access-remove-tenant-resp',
{}, response, 200)
exp_subs, response, 200)
class FlavorAccessSampleXmlTests(FlavorAccessSampleJsonTests):