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'
|
QUADLARGE = 'quadlarge'
|
||||||
|
|
||||||
|
|
||||||
|
SHARED = "shared"
|
||||||
|
EXCLUSIVE = "exclusive"
|
||||||
|
|
||||||
# Edge type
|
# Edge type
|
||||||
SERVICE_EDGE = 'service'
|
SERVICE_EDGE = 'service'
|
||||||
VDR_EDGE = 'vdr'
|
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
|
pass
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def create_router(self, context, lrouter):
|
def create_router(self, context, lrouter, appliance_size=None,
|
||||||
|
allow_metadata=True):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
|
@ -86,7 +86,8 @@ class RouterDistributedDriver(router_driver.RouterBaseDriver):
|
|||||||
router_id, routes, newnexthop,
|
router_id, routes, newnexthop,
|
||||||
gateway_vnic_index=internal_vnic_index)
|
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)
|
self.edge_manager.create_lrouter(context, lrouter, dist=True)
|
||||||
|
|
||||||
def update_router(self, context, router_id, router):
|
def update_router(self, context, router_id, router):
|
||||||
|
@ -32,8 +32,10 @@ class RouterExclusiveDriver(router_driver.RouterBaseDriver):
|
|||||||
def get_type(self):
|
def get_type(self):
|
||||||
return "exclusive"
|
return "exclusive"
|
||||||
|
|
||||||
def create_router(self, context, lrouter, allow_metadata=True):
|
def create_router(self, context, lrouter, appliance_size=None,
|
||||||
self.edge_manager.create_lrouter(context, lrouter, dist=False)
|
allow_metadata=True):
|
||||||
|
self.edge_manager.create_lrouter(
|
||||||
|
context, lrouter, dist=False, appliance_size=appliance_size)
|
||||||
if allow_metadata:
|
if allow_metadata:
|
||||||
self.plugin.metadata_proxy_handler.configure_router_edge(
|
self.plugin.metadata_proxy_handler.configure_router_edge(
|
||||||
lrouter['id'])
|
lrouter['id'])
|
||||||
|
@ -41,7 +41,8 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
|
|||||||
def get_type(self):
|
def get_type(self):
|
||||||
return "shared"
|
return "shared"
|
||||||
|
|
||||||
def create_router(self, context, lrouter, allow_metadata=True):
|
def create_router(self, context, lrouter,
|
||||||
|
appliance_size=None, allow_metadata=True):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def update_router(self, context, router_id, router):
|
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 exceptions as nsx_exc
|
||||||
from vmware_nsx.common import locking
|
from vmware_nsx.common import locking
|
||||||
from vmware_nsx.common import nsx_constants
|
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.common import utils as c_utils
|
||||||
from vmware_nsx.db import (
|
from vmware_nsx.db import (
|
||||||
routertype as rt_rtr)
|
routertype as rt_rtr)
|
||||||
@ -65,6 +66,7 @@ from vmware_nsx.extensions import (
|
|||||||
advancedserviceproviders as as_providers)
|
advancedserviceproviders as as_providers)
|
||||||
from vmware_nsx.extensions import (
|
from vmware_nsx.extensions import (
|
||||||
vnicindex as ext_vnic_idx)
|
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 managers
|
||||||
from vmware_nsx.plugins.nsx_v import md_proxy as nsx_v_md_proxy
|
from vmware_nsx.plugins.nsx_v import md_proxy as nsx_v_md_proxy
|
||||||
from vmware_nsx.plugins.nsx_v.vshield.common import (
|
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__)
|
LOG = logging.getLogger(__name__)
|
||||||
PORTGROUP_PREFIX = 'dvportgroup'
|
PORTGROUP_PREFIX = 'dvportgroup'
|
||||||
|
ROUTER_SIZE = routersize.ROUTER_SIZE
|
||||||
|
|
||||||
|
|
||||||
class NsxVPluginV2(agents_db.AgentDbMixin,
|
class NsxVPluginV2(agents_db.AgentDbMixin,
|
||||||
@ -103,6 +106,7 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
|
|||||||
"router",
|
"router",
|
||||||
"security-group",
|
"security-group",
|
||||||
"nsxv-router-type",
|
"nsxv-router-type",
|
||||||
|
"nsxv-router-size",
|
||||||
"vnic-index",
|
"vnic-index",
|
||||||
"advanced-service-providers"]
|
"advanced-service-providers"]
|
||||||
|
|
||||||
@ -1347,19 +1351,43 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
|
|||||||
raise n_exc.BadRequest(resource='router', msg=msg)
|
raise n_exc.BadRequest(resource='router', msg=msg)
|
||||||
return gw_info
|
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):
|
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
|
# First extract the gateway info in case of updating
|
||||||
# gateway before edge is deployed.
|
# gateway before edge is deployed.
|
||||||
# TODO(berlin): admin_state_up and routes update
|
# TODO(berlin): admin_state_up and routes update
|
||||||
r = router['router']
|
|
||||||
gw_info = self._extract_external_gw(context, router)
|
gw_info = self._extract_external_gw(context, router)
|
||||||
self._decide_router_type(context, r)
|
|
||||||
lrouter = super(NsxVPluginV2, self).create_router(context, router)
|
lrouter = super(NsxVPluginV2, self).create_router(context, router)
|
||||||
with context.session.begin(subtransactions=True):
|
with context.session.begin(subtransactions=True):
|
||||||
router_db = self._get_router(context, lrouter['id'])
|
router_db = self._get_router(context, lrouter['id'])
|
||||||
self._process_nsx_router_create(context, router_db, r)
|
self._process_nsx_router_create(context, router_db, r)
|
||||||
try:
|
try:
|
||||||
router_driver = self._get_router_driver(context, router_db)
|
router_driver = self._get_router_driver(context, router_db)
|
||||||
|
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(
|
router_driver.create_router(
|
||||||
context, lrouter,
|
context, lrouter,
|
||||||
allow_metadata=(allow_metadata and
|
allow_metadata=(allow_metadata and
|
||||||
@ -1413,6 +1441,10 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
|
|||||||
router = super(NsxVPluginV2, self).get_router(context, id, fields)
|
router = super(NsxVPluginV2, self).get_router(context, id, fields)
|
||||||
if router.get("distributed") and 'router_type' in router:
|
if router.get("distributed") and 'router_type' in router:
|
||||||
del router['router_type']
|
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
|
return router
|
||||||
|
|
||||||
def _get_external_attachment_info(self, context, 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]
|
router_id = (vcns_const.DHCP_EDGE_PREFIX + network_id)[:36]
|
||||||
self._free_edge_appliance(context, router_id)
|
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."""
|
"""Create an edge for logical router support."""
|
||||||
router_name = lrouter['name'] + '-' + lrouter['id']
|
router_name = lrouter['name'] + '-' + lrouter['id']
|
||||||
self._allocate_edge_appliance(
|
self._allocate_edge_appliance(
|
||||||
context, lrouter['id'], router_name,
|
context, lrouter['id'], router_name,
|
||||||
appliance_size=vcns_const.SERVICE_SIZE_MAPPING['router'],
|
appliance_size=appliance_size,
|
||||||
dist=dist)
|
dist=dist)
|
||||||
|
|
||||||
def delete_lrouter(self, context, router_id, dist=False):
|
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.common import nsx_constants
|
||||||
from vmware_nsx.db import nsxv_db
|
from vmware_nsx.db import nsxv_db
|
||||||
|
from vmware_nsx.extensions import (
|
||||||
|
routersize as router_size)
|
||||||
from vmware_nsx.extensions import (
|
from vmware_nsx.extensions import (
|
||||||
routertype as router_type)
|
routertype as router_type)
|
||||||
from vmware_nsx.extensions import (
|
from vmware_nsx.extensions import (
|
||||||
@ -1159,6 +1161,8 @@ class TestL3ExtensionManager(object):
|
|||||||
dist_router.EXTENDED_ATTRIBUTES_2_0.get(key, {}))
|
dist_router.EXTENDED_ATTRIBUTES_2_0.get(key, {}))
|
||||||
l3.RESOURCE_ATTRIBUTE_MAP[key].update(
|
l3.RESOURCE_ATTRIBUTE_MAP[key].update(
|
||||||
router_type.EXTENDED_ATTRIBUTES_2_0.get(key, {}))
|
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
|
# Finally add l3 resources to the global attribute map
|
||||||
attributes.RESOURCE_ATTRIBUTE_MAP.update(
|
attributes.RESOURCE_ATTRIBUTE_MAP.update(
|
||||||
l3.RESOURCE_ATTRIBUTE_MAP)
|
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):
|
def test_router_create_with_gwinfo_and_l3_ext_net_with_vlan(self):
|
||||||
self._test_router_create_with_gwinfo_and_l3_ext_net(444)
|
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):
|
def test_router_add_gateway_invalid_network_returns_404(self):
|
||||||
# NOTE(salv-orlando): This unit test has been overriden
|
# NOTE(salv-orlando): This unit test has been overriden
|
||||||
# as the nsx plugin support the ext_gw_mode extension
|
# 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(
|
self.plugin_instance.edge_manager.get_routers_on_same_edge(
|
||||||
context.get_admin_context(), router['router']['id']))
|
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):
|
def test_router_create_with_gwinfo_with_no_edge(self):
|
||||||
with self._create_l3_ext_network() as net:
|
with self._create_l3_ext_network() as net:
|
||||||
with self.subnet(network=net, enable_dhcp=False) as s:
|
with self.subnet(network=net, enable_dhcp=False) as s:
|
||||||
|
Loading…
Reference in New Issue
Block a user