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", "flavor_id": "10",
"tenant_id": "fake_tenant" "tenant_id": "fake_tenant"
},
{
"flavor_id": "10",
"tenant_id": "openstack"
} }
] ]
} }

View File

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

View File

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

View File

@@ -1,4 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<flavor_access> <flavor_access>
<access tenant_id="fake_tenant" flavor_id="10"/> <access tenant_id="fake_tenant" flavor_id="10"/>
<access tenant_id="openstack" flavor_id="10"/>
</flavor_access> </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'?> <?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", "flavor_id": "10",
"tenant_id": "fake_tenant" "tenant_id": "fake_tenant"
},
{
"flavor_id": "10",
"tenant_id": "openstack"
} }
] ]
} }

View File

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

View File

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

View File

@@ -1,4 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<flavor_access> <flavor_access>
<access tenant_id="fake_tenant" flavor_id="10"/> <access tenant_id="fake_tenant" flavor_id="10"/>
<access tenant_id="openstack" flavor_id="10"/>
</flavor_access> </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'?> <?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, flavorid=flavorid, swap=swap,
rxtx_factor=rxtx_factor, rxtx_factor=rxtx_factor,
is_public=is_public) is_public=is_public)
if not flavor['is_public']:
flavors.add_flavor_access(flavor['flavorid'],
context.project_id, context)
req.cache_db_flavor(flavor) req.cache_db_flavor(flavor)
except (exception.InstanceTypeExists, except (exception.InstanceTypeExists,
exception.InstanceTypeIdExists) as err: exception.InstanceTypeIdExists) as err:

View File

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

View File

@@ -17,8 +17,10 @@ import datetime
import webob import webob
from nova.api.openstack.compute.contrib import flavor_access
from nova.api.openstack.compute.contrib import flavormanage from nova.api.openstack.compute.contrib import flavormanage
from nova.compute import flavors from nova.compute import flavors
from nova import context
from nova import db from nova import db
from nova import exception from nova import exception
from nova.openstack.common import jsonutils from nova.openstack.common import jsonutils
@@ -391,3 +393,92 @@ class FlavorManageTest(test.NoDBTestCase):
512, 2, None, 1, 1234, 512, 1, True) 512, 2, None, 1, 1234, 512, 1, True)
self.assertRaises(exception.InvalidInput, flavors.create, "abcdef", self.assertRaises(exception.InvalidInput, flavors.create, "abcdef",
"test_memory_mb", 2, None, 1, 1234, 512, 1, True) "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 import webob
from nova.api.openstack.compute.plugins.v3 import flavor_access
from nova.api.openstack.compute.plugins.v3 import flavor_manage from nova.api.openstack.compute.plugins.v3 import flavor_manage
from nova.compute import flavors from nova.compute import flavors
from nova import context
from nova import exception from nova import exception
from nova.openstack.common import jsonutils from nova.openstack.common import jsonutils
from nova import test from nova import test
@@ -209,3 +211,89 @@ class FlavorManageTest(test.NoDBTestCase):
512, 2, None, 1, 1234, 512, 1, True) 512, 2, None, 1, 1234, 512, 1, True)
self.assertRaises(exception.InvalidInput, flavors.create, "abcdef", self.assertRaises(exception.InvalidInput, flavors.create, "abcdef",
"test_memory_mb", 2, None, 1, 1234, 512, 1, True) "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_access": [
{
"flavor_id": "%(flavor_id)s",
"tenant_id": "openstack"
},
{ {
"flavor_id": "%(flavor_id)s", "flavor_id": "%(flavor_id)s",
"tenant_id": "%(tenant_id)s" "tenant_id": "%(tenant_id)s"

View File

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

View File

@@ -3,6 +3,10 @@
{ {
"flavor_id": "%(flavor_id)s", "flavor_id": "%(flavor_id)s",
"tenant_id": "fake_tenant" "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'?> <?xml version='1.0' encoding='UTF-8'?>
<flavor_access> <flavor_access>
<access tenant_id="%(tenant_id)s" flavor_id="%(flavor_id)s"/> <access tenant_id="fake_tenant" flavor_id="10"/>
</flavor_access> <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'?> <?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', response = self._do_post('flavors/10/action',
"flavor-access-remove-tenant-req", "flavor-access-remove-tenant-req",
subs) subs)
exp_subs = {
"tenant_id": self.api.project_id,
"flavor_id": "10"
}
self._verify_response('flavor-access-remove-tenant-resp', self._verify_response('flavor-access-remove-tenant-resp',
{}, response, 200) exp_subs, response, 200)
class FlavorAccessSampleXmlTests(FlavorAccessSampleJsonTests): class FlavorAccessSampleXmlTests(FlavorAccessSampleJsonTests):

View File

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

View File

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

View File

@@ -3,6 +3,10 @@
{ {
"flavor_id": "%(flavor_id)s", "flavor_id": "%(flavor_id)s",
"tenant_id": "fake_tenant" "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'?> <?xml version='1.0' encoding='UTF-8'?>
<flavor_access> <flavor_access>
<access tenant_id="%(tenant_id)s" flavor_id="%(flavor_id)s"/> <access tenant_id="fake_tenant" flavor_id="10"/>
</flavor_access> <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'?> <?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', response = self._do_post('flavors/10/action',
"flavor-access-remove-tenant-req", "flavor-access-remove-tenant-req",
subs) subs)
exp_subs = {
"tenant_id": self.api.project_id,
"flavor_id": "10"
}
self._verify_response('flavor-access-remove-tenant-resp', self._verify_response('flavor-access-remove-tenant-resp',
{}, response, 200) exp_subs, response, 200)
class FlavorAccessSampleXmlTests(FlavorAccessSampleJsonTests): class FlavorAccessSampleXmlTests(FlavorAccessSampleJsonTests):