Add requested neworks check with the specified flavor

This adds check for the amount of networks and port_type with
the specified flavor.

Change-Id: Ie30e6a903b559cab862d009841ebd95c34ec3fec
This commit is contained in:
Zhenguo Niu 2017-05-22 19:23:15 +08:00
parent 696f4a0fd2
commit 5938805af9
4 changed files with 64 additions and 6 deletions

View File

@ -610,6 +610,25 @@ class ServerController(ServerControllerBase):
raise exception.NotFound()
return self._get_server_collection(all_tenants=all_tenants)
def _check_flavor_and_networks(self, flavor, networks):
if len(networks) > len(flavor.nics):
raise exception.NetworksNotMatch(
_("Requested networks require more nics than the "
"selected flavor."))
nics = flavor.nics
for net in networks:
if 'port_type' in net:
try:
index = [nic.get('type')
for nic in nics].index(net.get('port_type'))
nics.pop(index)
except ValueError:
raise exception.NetworksNotMatch(
_("Requested networks require more specific nic "
"type %s than the selected flavor."),
net.get('port_type'))
@policy.authorize_wsgi("mogan:server", "create", False)
@expose.expose(Server, body=types.jsontype,
status_code=http_client.CREATED)
@ -642,6 +661,7 @@ class ServerController(ServerControllerBase):
try:
flavor = objects.Flavor.get(pecan.request.context, flavor_uuid)
self._check_flavor_and_networks(flavor, requested_networks)
servers = pecan.request.engine_api.create(
pecan.request.context,
@ -682,7 +702,8 @@ class ServerController(ServerControllerBase):
exception.ServerUserDataTooLarge,
exception.Base64Exception,
exception.NetworkRequiresSubnet,
exception.NetworkNotFound) as e:
exception.NetworkNotFound,
exception.NetworksNotMatch) as e:
raise wsme.exc.ClientSideError(
e.message, status_code=http_client.BAD_REQUEST)

View File

@ -337,6 +337,10 @@ class NetworkRequiresSubnet(Invalid):
" servers on.")
class NetworksNotMatch(Invalid):
_msg_fmt = _("Networks don't match with the specified flavor.")
class ServerIsLocked(Invalid):
_msg_fmt = _("Server %(server_uuid)s is locked")

View File

@ -113,7 +113,8 @@ class TestServers(v1_test.APITestV1):
mocked.side_effect = [self.INSTANCE_TYPE_UUID]
headers = self.gen_headers(self.context, roles="admin")
body = {"name": "type_for_server_testing",
"description": "type for server testing"}
"description": "type for server testing",
"nics": [{"type": "Ethernet", "speed": "10GE"}]}
self.post_json('/flavors', body, headers=headers, status=201)
@mock.patch('oslo_utils.uuidutils.generate_uuid')
@ -131,7 +132,8 @@ class TestServers(v1_test.APITestV1):
'flavor_uuid': 'ff28b5a2-73e5-431c-b4b7-1b96b74bca7b',
'image_uuid': 'b8f82429-3a13-4ffe-9398-4d1abdc256a8',
'networks': [
{'net_id': 'c1940655-8b8e-4370-b8f9-03ba1daeca31'}],
{'net_id': 'c1940655-8b8e-4370-b8f9-03ba1daeca31',
'port_type': 'Ethernet'}],
'extra': {'fake_key': 'fake_value'}
}
responses.append(

View File

@ -26,11 +26,12 @@ from mogan.tests.unit.db import utils
def gen_post_body(**kw):
fake_networks = [
{
"net_id": "c1940655-8b8e-4370-b8f9-03ba1daeca31"
"net_id": "c1940655-8b8e-4370-b8f9-03ba1daeca31",
"port_type": "Ethernet"
},
{
"net_id": "8e8ceb07-4641-4188-9b22-840755e92ee2",
"port_type": "10GE"
"port_type": "Ethernet"
}
]
return {
@ -59,7 +60,10 @@ class TestServerAuthorization(v1_test.APITestV1):
@mock.patch('mogan.engine.api.API.create')
@mock.patch('mogan.objects.Flavor.get')
def test_server_post(self, mock_get, mock_engine_create):
mock_get.side_effect = None
flavor = mock.MagicMock()
flavor.nics = [{"type": "Ethernet", "speed": "10GE"},
{"type": "Ethernet", "speed": "10GE"}]
mock_get.return_value = flavor
mock_engine_create.side_effect = None
mock_engine_create.return_value = [self.server1]
body = gen_post_body()
@ -70,6 +74,33 @@ class TestServerAuthorization(v1_test.APITestV1):
headers = self.gen_headers(self.context)
self.post_json('/servers', body, headers=headers, status=201)
@mock.patch('mogan.objects.Flavor.get')
def test_server_post_with_no_enough_nics(self, mock_get):
flavor = mock.MagicMock()
flavor.nics = [{"type": "Ethernet", "speed": "10GE"}]
mock_get.return_value = flavor
body = gen_post_body()
self.context.roles = "no-admin"
self.context.tenant = self.evil_project
headers = self.gen_headers(self.context)
ret = self.post_json(
'/servers', body, headers=headers, expect_errors=True)
self.assertTrue(ret.json['error_message'])
@mock.patch('mogan.objects.Flavor.get')
def test_server_post_with_no_enough_nic_types(self, mock_get):
flavor = mock.MagicMock()
flavor.nics = [{"type": "Ethernet", "speed": "10GE"},
{"type": "Infiniband", "speed": "100GE"}]
mock_get.return_value = flavor
body = gen_post_body()
self.context.roles = "no-admin"
self.context.tenant = self.evil_project
headers = self.gen_headers(self.context)
ret = self.post_json(
'/servers', body, headers=headers, expect_errors=True)
self.assertTrue(ret.json['error_message'])
def test_server_get_one_by_owner(self):
# not admin but the owner
self.context.tenant = self.server1.project_id