Add router-size when creating an exclusive router
Enables a user to specify router-size while creating an exclusive router for creating a load-balancer service Change-Id: If03b51ce0bc61a8e2aa46de4f1b5869306e1bd7e
This commit is contained in:
parent
e56011b06d
commit
9329762d3e
@ -20,6 +20,9 @@ XLARGE = 'xlarge'
|
||||
QUADLARGE = 'quadlarge'
|
||||
|
||||
|
||||
SHARED = "shared"
|
||||
EXCLUSIVE = "exclusive"
|
||||
|
||||
# Edge type
|
||||
SERVICE_EDGE = 'service'
|
||||
VDR_EDGE = 'vdr'
|
||||
|
56
vmware_nsx/extensions/routersize.py
Normal file
56
vmware_nsx/extensions/routersize.py
Normal file
@ -0,0 +1,56 @@
|
||||
# Copyright 2015 VMware, Inc. 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.
|
||||
|
||||
from neutron.api import extensions
|
||||
from neutron.api.v2 import attributes
|
||||
|
||||
|
||||
ROUTER_SIZE = 'router_size'
|
||||
EXTENDED_ATTRIBUTES_2_0 = {
|
||||
'routers': {
|
||||
ROUTER_SIZE: {'allow_post': True, 'allow_put': False,
|
||||
'validate': {'type:values': ['compact', 'large',
|
||||
'xlarge', 'quadlarge']},
|
||||
'default': attributes.ATTR_NOT_SPECIFIED,
|
||||
'is_visible': True},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Routersize(extensions.ExtensionDescriptor):
|
||||
"""Extension class supporting router size."""
|
||||
|
||||
@classmethod
|
||||
def get_name(cls):
|
||||
return "Router Size"
|
||||
|
||||
@classmethod
|
||||
def get_alias(cls):
|
||||
return "nsxv-router-size"
|
||||
|
||||
@classmethod
|
||||
def get_description(cls):
|
||||
return "Enables configuration of NSXv Edge Size"
|
||||
|
||||
@classmethod
|
||||
def get_updated(cls):
|
||||
return "2015-9-22T10:00:00-00:00"
|
||||
|
||||
def get_required_extensions(self):
|
||||
return ["router"]
|
||||
|
||||
def get_extended_resources(self, version):
|
||||
if version == "2.0":
|
||||
return EXTENDED_ATTRIBUTES_2_0
|
||||
return {}
|
@ -26,7 +26,8 @@ class RouterAbstractDriver(object):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def create_router(self, context, lrouter):
|
||||
def create_router(self, context, lrouter, appliance_size=None,
|
||||
allow_metadata=True):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
|
@ -86,7 +86,8 @@ class RouterDistributedDriver(router_driver.RouterBaseDriver):
|
||||
router_id, routes, newnexthop,
|
||||
gateway_vnic_index=internal_vnic_index)
|
||||
|
||||
def create_router(self, context, lrouter, allow_metadata=True):
|
||||
def create_router(self, context, lrouter, appliance_size=None,
|
||||
allow_metadata=True):
|
||||
self.edge_manager.create_lrouter(context, lrouter, dist=True)
|
||||
|
||||
def update_router(self, context, router_id, router):
|
||||
|
@ -32,8 +32,10 @@ class RouterExclusiveDriver(router_driver.RouterBaseDriver):
|
||||
def get_type(self):
|
||||
return "exclusive"
|
||||
|
||||
def create_router(self, context, lrouter, allow_metadata=True):
|
||||
self.edge_manager.create_lrouter(context, lrouter, dist=False)
|
||||
def create_router(self, context, lrouter, appliance_size=None,
|
||||
allow_metadata=True):
|
||||
self.edge_manager.create_lrouter(
|
||||
context, lrouter, dist=False, appliance_size=appliance_size)
|
||||
if allow_metadata:
|
||||
self.plugin.metadata_proxy_handler.configure_router_edge(
|
||||
lrouter['id'])
|
||||
|
@ -41,7 +41,8 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
|
||||
def get_type(self):
|
||||
return "shared"
|
||||
|
||||
def create_router(self, context, lrouter, allow_metadata=True):
|
||||
def create_router(self, context, lrouter,
|
||||
appliance_size=None, allow_metadata=True):
|
||||
pass
|
||||
|
||||
def update_router(self, context, router_id, router):
|
||||
|
@ -55,6 +55,7 @@ from vmware_nsx.common import config # noqa
|
||||
from vmware_nsx.common import exceptions as nsx_exc
|
||||
from vmware_nsx.common import locking
|
||||
from vmware_nsx.common import nsx_constants
|
||||
from vmware_nsx.common import nsxv_constants
|
||||
from vmware_nsx.common import utils as c_utils
|
||||
from vmware_nsx.db import (
|
||||
routertype as rt_rtr)
|
||||
@ -65,6 +66,7 @@ from vmware_nsx.extensions import (
|
||||
advancedserviceproviders as as_providers)
|
||||
from vmware_nsx.extensions import (
|
||||
vnicindex as ext_vnic_idx)
|
||||
from vmware_nsx.extensions import routersize
|
||||
from vmware_nsx.plugins.nsx_v import managers
|
||||
from vmware_nsx.plugins.nsx_v import md_proxy as nsx_v_md_proxy
|
||||
from vmware_nsx.plugins.nsx_v.vshield.common import (
|
||||
@ -77,6 +79,7 @@ from vmware_nsx.plugins.nsx_v.vshield import vcns_driver
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
PORTGROUP_PREFIX = 'dvportgroup'
|
||||
ROUTER_SIZE = routersize.ROUTER_SIZE
|
||||
|
||||
|
||||
class NsxVPluginV2(agents_db.AgentDbMixin,
|
||||
@ -103,6 +106,7 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
|
||||
"router",
|
||||
"security-group",
|
||||
"nsxv-router-type",
|
||||
"nsxv-router-size",
|
||||
"vnic-index",
|
||||
"advanced-service-providers"]
|
||||
|
||||
@ -1347,23 +1351,47 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
|
||||
raise n_exc.BadRequest(resource='router', msg=msg)
|
||||
return gw_info
|
||||
|
||||
def _validate_router_size(self, router):
|
||||
# Check if router-size is specified. router-size can only be specified
|
||||
# for a exclusive non-distributed router; else raise a BadRequest
|
||||
# exception.
|
||||
r = router['router']
|
||||
if r.get(ROUTER_SIZE) != attr.ATTR_NOT_SPECIFIED:
|
||||
if r.get('router_type') == nsxv_constants.SHARED:
|
||||
msg = _("Cannot specify router-size for shared router")
|
||||
raise n_exc.BadRequest(resource="router", msg=msg)
|
||||
elif r.get('distributed') is True:
|
||||
msg = _("Cannot specify router-size for distributed router")
|
||||
raise n_exc.BadRequest(resource="router", msg=msg)
|
||||
elif r.get(ROUTER_SIZE) == attr.ATTR_NOT_SPECIFIED:
|
||||
if r.get('router_type') == nsxv_constants.EXCLUSIVE:
|
||||
r[ROUTER_SIZE] = nsxv_constants.COMPACT
|
||||
|
||||
def create_router(self, context, router, allow_metadata=True):
|
||||
self._validate_router_size(router)
|
||||
r = router['router']
|
||||
self._decide_router_type(context, r)
|
||||
# First extract the gateway info in case of updating
|
||||
# gateway before edge is deployed.
|
||||
# TODO(berlin): admin_state_up and routes update
|
||||
r = router['router']
|
||||
gw_info = self._extract_external_gw(context, router)
|
||||
self._decide_router_type(context, r)
|
||||
lrouter = super(NsxVPluginV2, self).create_router(context, router)
|
||||
with context.session.begin(subtransactions=True):
|
||||
router_db = self._get_router(context, lrouter['id'])
|
||||
self._process_nsx_router_create(context, router_db, r)
|
||||
try:
|
||||
router_driver = self._get_router_driver(context, router_db)
|
||||
router_driver.create_router(
|
||||
context, lrouter,
|
||||
allow_metadata=(allow_metadata and
|
||||
self.metadata_proxy_handler))
|
||||
if router_driver.get_type() == nsxv_constants.EXCLUSIVE:
|
||||
router_driver.create_router(
|
||||
context, lrouter,
|
||||
appliance_size=r.get(ROUTER_SIZE),
|
||||
allow_metadata=(allow_metadata and
|
||||
self.metadata_proxy_handler))
|
||||
else:
|
||||
router_driver.create_router(
|
||||
context, lrouter,
|
||||
allow_metadata=(allow_metadata and
|
||||
self.metadata_proxy_handler))
|
||||
if gw_info != attr.ATTR_NOT_SPECIFIED:
|
||||
router_driver._update_router_gw_info(
|
||||
context, lrouter['id'], gw_info)
|
||||
@ -1413,6 +1441,10 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
|
||||
router = super(NsxVPluginV2, self).get_router(context, id, fields)
|
||||
if router.get("distributed") and 'router_type' in router:
|
||||
del router['router_type']
|
||||
if router.get("router_type") == nsxv_constants.EXCLUSIVE:
|
||||
binding = nsxv_db.get_nsxv_router_binding(context.session,
|
||||
router.get("id"))
|
||||
router[ROUTER_SIZE] = binding.get("appliance_size")
|
||||
return router
|
||||
|
||||
def _get_external_attachment_info(self, context, router):
|
||||
|
@ -641,12 +641,14 @@ class EdgeManager(object):
|
||||
router_id = (vcns_const.DHCP_EDGE_PREFIX + network_id)[:36]
|
||||
self._free_edge_appliance(context, router_id)
|
||||
|
||||
def create_lrouter(self, context, lrouter, lswitch=None, dist=False):
|
||||
def create_lrouter(
|
||||
self, context, lrouter, lswitch=None, dist=False,
|
||||
appliance_size=vcns_const.SERVICE_SIZE_MAPPING['router']):
|
||||
"""Create an edge for logical router support."""
|
||||
router_name = lrouter['name'] + '-' + lrouter['id']
|
||||
self._allocate_edge_appliance(
|
||||
context, lrouter['id'], router_name,
|
||||
appliance_size=vcns_const.SERVICE_SIZE_MAPPING['router'],
|
||||
appliance_size=appliance_size,
|
||||
dist=dist)
|
||||
|
||||
def delete_lrouter(self, context, router_id, dist=False):
|
||||
|
@ -47,6 +47,8 @@ import webob.exc
|
||||
|
||||
from vmware_nsx.common import nsx_constants
|
||||
from vmware_nsx.db import nsxv_db
|
||||
from vmware_nsx.extensions import (
|
||||
routersize as router_size)
|
||||
from vmware_nsx.extensions import (
|
||||
routertype as router_type)
|
||||
from vmware_nsx.extensions import (
|
||||
@ -1159,6 +1161,8 @@ class TestL3ExtensionManager(object):
|
||||
dist_router.EXTENDED_ATTRIBUTES_2_0.get(key, {}))
|
||||
l3.RESOURCE_ATTRIBUTE_MAP[key].update(
|
||||
router_type.EXTENDED_ATTRIBUTES_2_0.get(key, {}))
|
||||
l3.RESOURCE_ATTRIBUTE_MAP[key].update(
|
||||
router_size.EXTENDED_ATTRIBUTES_2_0.get(key, {}))
|
||||
# Finally add l3 resources to the global attribute map
|
||||
attributes.RESOURCE_ATTRIBUTE_MAP.update(
|
||||
l3.RESOURCE_ATTRIBUTE_MAP)
|
||||
@ -1626,6 +1630,18 @@ class TestExclusiveRouterTestCase(L3NatTest, L3NatTestCaseBase,
|
||||
def test_router_create_with_gwinfo_and_l3_ext_net_with_vlan(self):
|
||||
self._test_router_create_with_gwinfo_and_l3_ext_net(444)
|
||||
|
||||
def test_router_create_with_different_sizes(self):
|
||||
data = {'router': {
|
||||
'tenant_id': 'whatever',
|
||||
'name': 'test_router',
|
||||
'router_type': 'exclusive'}}
|
||||
for size in ['compact', 'large', 'xlarge', 'quadlarge']:
|
||||
data['router']['router_size'] = size
|
||||
router_req = self.new_create_request('routers', data, self.fmt)
|
||||
res = router_req.get_response(self.ext_api)
|
||||
router = self.deserialize(self.fmt, res)
|
||||
self.assertEqual(size, router['router']['router_size'])
|
||||
|
||||
def test_router_add_gateway_invalid_network_returns_404(self):
|
||||
# NOTE(salv-orlando): This unit test has been overriden
|
||||
# as the nsx plugin support the ext_gw_mode extension
|
||||
@ -2298,6 +2314,19 @@ class TestSharedRouterTestCase(L3NatTest, L3NatTestCaseBase,
|
||||
self.plugin_instance.edge_manager.get_routers_on_same_edge(
|
||||
context.get_admin_context(), router['router']['id']))
|
||||
|
||||
def test_router_create_with_size_fail_at_backend(self):
|
||||
data = {'router': {
|
||||
'tenant_id': 'whatever',
|
||||
'router_type': 'shared',
|
||||
'router_size': 'large'}}
|
||||
router_req = self.new_create_request('routers', data, self.fmt)
|
||||
res = router_req.get_response(self.ext_api)
|
||||
router = self.deserialize(self.fmt, res)
|
||||
msg = ('Bad router request: '
|
||||
'Cannot specify router-size for shared router')
|
||||
self.assertEqual("BadRequest", router['NeutronError']['type'])
|
||||
self.assertEqual(msg, router['NeutronError']['message'])
|
||||
|
||||
def test_router_create_with_gwinfo_with_no_edge(self):
|
||||
with self._create_l3_ext_network() as net:
|
||||
with self.subnet(network=net, enable_dhcp=False) as s:
|
||||
|
Loading…
Reference in New Issue
Block a user