Merge "NSXv: Make VDR transit net configurable"
This commit is contained in:
commit
1ee49d510e
@ -627,6 +627,10 @@ nsxv_opts = [
|
|||||||
help=_("(Optional) If use_nsx_policies is True, this value "
|
help=_("(Optional) If use_nsx_policies is True, this value "
|
||||||
"will determine if a tenants can add rules to their "
|
"will determine if a tenants can add rules to their "
|
||||||
"security groups.")),
|
"security groups.")),
|
||||||
|
cfg.StrOpt('vdr_transit_network', default="169.254.2.0/28",
|
||||||
|
help=_("(Optional) Sets the network address for distributed "
|
||||||
|
"router TLR-PLR connectivity, with "
|
||||||
|
"<network IP>/<prefix> syntax")),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Register the configuration options
|
# Register the configuration options
|
||||||
|
@ -59,5 +59,4 @@ CSR_REQUEST = ("<csr><subject>"
|
|||||||
# Reserved IPs that cannot overlap defined subnets
|
# Reserved IPs that cannot overlap defined subnets
|
||||||
RESERVED_IPS = ["169.254.128.0/17",
|
RESERVED_IPS = ["169.254.128.0/17",
|
||||||
"169.254.1.0/24",
|
"169.254.1.0/24",
|
||||||
"169.254.2.0/28",
|
|
||||||
"169.254.64.192/26"]
|
"169.254.64.192/26"]
|
||||||
|
@ -26,8 +26,6 @@ from vmware_nsx.db import nsxv_db
|
|||||||
from vmware_nsx.plugins.nsx_v.drivers import (
|
from vmware_nsx.plugins.nsx_v.drivers import (
|
||||||
abstract_router_driver as router_driver)
|
abstract_router_driver as router_driver)
|
||||||
from vmware_nsx.plugins.nsx_v import plugin as nsx_v
|
from vmware_nsx.plugins.nsx_v import plugin as nsx_v
|
||||||
from vmware_nsx.plugins.nsx_v.vshield.common import (
|
|
||||||
constants as vcns_const)
|
|
||||||
from vmware_nsx.plugins.nsx_v.vshield import edge_utils
|
from vmware_nsx.plugins.nsx_v.vshield import edge_utils
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
@ -52,8 +50,7 @@ class RouterDistributedDriver(router_driver.RouterBaseDriver):
|
|||||||
for subnet in subnets:
|
for subnet in subnets:
|
||||||
routes.append({
|
routes.append({
|
||||||
'destination': subnet,
|
'destination': subnet,
|
||||||
'nexthop': (vcns_const.INTEGRATION_LR_IPADDRESS.
|
'nexthop': (edge_utils.get_vdr_transit_network_tlr_address()),
|
||||||
split('/')[0]),
|
|
||||||
'network_id': lswitch_id
|
'network_id': lswitch_id
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -67,7 +64,7 @@ class RouterDistributedDriver(router_driver.RouterBaseDriver):
|
|||||||
|
|
||||||
def _update_routes_on_tlr(
|
def _update_routes_on_tlr(
|
||||||
self, context, router_id,
|
self, context, router_id,
|
||||||
newnexthop=vcns_const.INTEGRATION_EDGE_IPADDRESS,
|
newnexthop=edge_utils.get_vdr_transit_network_plr_address(),
|
||||||
metadata_gateway=None):
|
metadata_gateway=None):
|
||||||
routes = []
|
routes = []
|
||||||
|
|
||||||
|
@ -1845,22 +1845,14 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
For the V plugin we have a limitation that we should not use
|
For the V plugin we have a limitation that we should not use
|
||||||
some reserved ranges like: 169.254.128.0/17 and 169.254.1.0/24
|
some reserved ranges like: 169.254.128.0/17 and 169.254.1.0/24
|
||||||
"""
|
"""
|
||||||
reserved_subnets = nsxv_constants.RESERVED_IPS
|
|
||||||
|
|
||||||
# translate the given subnet to a range object
|
# translate the given subnet to a range object
|
||||||
data = subnet['subnet']
|
data = subnet['subnet']
|
||||||
|
|
||||||
if data['cidr'] not in (constants.ATTR_NOT_SPECIFIED, None):
|
if data['cidr'] not in (constants.ATTR_NOT_SPECIFIED, None):
|
||||||
range = netaddr.IPNetwork(data['cidr'])
|
reserved_subnets = list(nsxv_constants.RESERVED_IPS)
|
||||||
|
reserved_subnets.append(cfg.CONF.nsxv.vdr_transit_network)
|
||||||
# Check each reserved subnet for intersection
|
return edge_utils.is_overlapping_reserved_subnets(data['cidr'],
|
||||||
for reserved_subnet in reserved_subnets:
|
reserved_subnets)
|
||||||
# translate the reserved subnet to a range object
|
|
||||||
reserved_range = netaddr.IPNetwork(reserved_subnet)
|
|
||||||
# check if new subnet overlaps this reserved subnet
|
|
||||||
if (range.first <= reserved_range.last
|
|
||||||
and reserved_range.first <= range.last):
|
|
||||||
return True
|
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -3556,6 +3548,9 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
error = _("Configured %s not found") % field
|
error = _("Configured %s not found") % field
|
||||||
raise nsx_exc.NsxPluginException(err_msg=error)
|
raise nsx_exc.NsxPluginException(err_msg=error)
|
||||||
|
|
||||||
|
if cfg.CONF.nsxv.vdr_transit_network:
|
||||||
|
edge_utils.validate_vdr_transit_network()
|
||||||
|
|
||||||
def _handle_qos_notification(self, qos_policys, event_type):
|
def _handle_qos_notification(self, qos_policys, event_type):
|
||||||
qos_utils.handle_qos_notification(qos_policys, event_type, self._dvs)
|
qos_utils.handle_qos_notification(qos_policys, event_type, self._dvs)
|
||||||
|
|
||||||
|
@ -40,10 +40,6 @@ MAX_TUNNEL_NUM = (cfg.CONF.nsxv.maximum_tunnels_per_vnic if
|
|||||||
cfg.CONF.nsxv.maximum_tunnels_per_vnic > 0)
|
cfg.CONF.nsxv.maximum_tunnels_per_vnic > 0)
|
||||||
else 10)
|
else 10)
|
||||||
|
|
||||||
INTEGRATION_LR_IPADDRESS = "169.254.2.1/28"
|
|
||||||
INTEGRATION_EDGE_IPADDRESS = "169.254.2.3"
|
|
||||||
INTEGRATION_SUBNET_NETMASK = "255.255.255.240"
|
|
||||||
|
|
||||||
# SNAT rule location
|
# SNAT rule location
|
||||||
PREPEND = 0
|
PREPEND = 0
|
||||||
APPEND = -1
|
APPEND = -1
|
||||||
|
@ -383,8 +383,8 @@ class EdgeApplianceDriver(object):
|
|||||||
vnic_inside = self._assemble_edge_vnic(
|
vnic_inside = self._assemble_edge_vnic(
|
||||||
constants.INTERNAL_VNIC_NAME, constants.INTERNAL_VNIC_INDEX,
|
constants.INTERNAL_VNIC_NAME, constants.INTERNAL_VNIC_INDEX,
|
||||||
internal_network,
|
internal_network,
|
||||||
constants.INTEGRATION_EDGE_IPADDRESS,
|
edge_utils.get_vdr_transit_network_plr_address(),
|
||||||
constants.INTEGRATION_SUBNET_NETMASK,
|
edge_utils.get_vdr_transit_network_netmask(),
|
||||||
type="internal")
|
type="internal")
|
||||||
edge['vnics']['vnics'].append(vnic_inside)
|
edge['vnics']['vnics'].append(vnic_inside)
|
||||||
|
|
||||||
@ -457,8 +457,8 @@ class EdgeApplianceDriver(object):
|
|||||||
internal_vnic = self._assemble_edge_vnic(
|
internal_vnic = self._assemble_edge_vnic(
|
||||||
constants.INTERNAL_VNIC_NAME, constants.INTERNAL_VNIC_INDEX,
|
constants.INTERNAL_VNIC_NAME, constants.INTERNAL_VNIC_INDEX,
|
||||||
internal_network,
|
internal_network,
|
||||||
constants.INTEGRATION_EDGE_IPADDRESS,
|
edge_utils.get_vdr_transit_network_plr_address(),
|
||||||
constants.INTEGRATION_SUBNET_NETMASK,
|
edge_utils.get_vdr_transit_network_netmask(),
|
||||||
type="internal")
|
type="internal")
|
||||||
edge['vnics']['vnics'].append(internal_vnic)
|
edge['vnics']['vnics'].append(internal_vnic)
|
||||||
if not dist and loadbalancer_enable:
|
if not dist and loadbalancer_enable:
|
||||||
|
@ -56,6 +56,59 @@ LOG = logging.getLogger(__name__)
|
|||||||
_uuid = uuidutils.generate_uuid
|
_uuid = uuidutils.generate_uuid
|
||||||
|
|
||||||
|
|
||||||
|
def _get_vdr_transit_network_ipobj():
|
||||||
|
transit_net = cfg.CONF.nsxv.vdr_transit_network
|
||||||
|
return netaddr.IPNetwork(transit_net)
|
||||||
|
|
||||||
|
|
||||||
|
def get_vdr_transit_network_netmask():
|
||||||
|
ip = _get_vdr_transit_network_ipobj()
|
||||||
|
return str(ip.netmask)
|
||||||
|
|
||||||
|
|
||||||
|
def get_vdr_transit_network_tlr_address():
|
||||||
|
ip = _get_vdr_transit_network_ipobj()
|
||||||
|
return str(ip[1])
|
||||||
|
|
||||||
|
|
||||||
|
def get_vdr_transit_network_plr_address():
|
||||||
|
ip = _get_vdr_transit_network_ipobj()
|
||||||
|
return str(ip[2])
|
||||||
|
|
||||||
|
|
||||||
|
def validate_vdr_transit_network():
|
||||||
|
try:
|
||||||
|
ip = _get_vdr_transit_network_ipobj()
|
||||||
|
except Exception:
|
||||||
|
raise n_exc.Invalid(_("Invalid VDR transit network"))
|
||||||
|
if len(ip) < 4:
|
||||||
|
raise n_exc.Invalid(_("VDR transit address range too small"))
|
||||||
|
|
||||||
|
if is_overlapping_reserved_subnets(cfg.CONF.nsxv.vdr_transit_network,
|
||||||
|
nsxv_constants.RESERVED_IPS):
|
||||||
|
raise n_exc.Invalid(_("VDR transit network overlaps reserved subnet"))
|
||||||
|
|
||||||
|
|
||||||
|
def is_overlapping_reserved_subnets(cidr, reserved_subnets):
|
||||||
|
"""Return True if the subnet overlaps with reserved subnets.
|
||||||
|
|
||||||
|
For the V plugin we have a limitation that we should not use
|
||||||
|
some reserved ranges like: 169.254.128.0/17 and 169.254.1.0/24
|
||||||
|
"""
|
||||||
|
range = netaddr.IPNetwork(cidr)
|
||||||
|
|
||||||
|
# Check each reserved subnet for intersection
|
||||||
|
for reserved_subnet in reserved_subnets:
|
||||||
|
# translate the reserved subnet to a range object
|
||||||
|
reserved_range = netaddr.IPNetwork(reserved_subnet)
|
||||||
|
# check if new subnet overlaps this reserved subnet
|
||||||
|
if (range.first <= reserved_range.last
|
||||||
|
and reserved_range.first <= range.last):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def parse_backup_edge_pool_opt():
|
def parse_backup_edge_pool_opt():
|
||||||
"""Parse edge pool opts and returns result."""
|
"""Parse edge pool opts and returns result."""
|
||||||
edge_pool_opts = cfg.CONF.nsxv.backup_edge_pool
|
edge_pool_opts = cfg.CONF.nsxv.backup_edge_pool
|
||||||
@ -1523,8 +1576,8 @@ class EdgeManager(object):
|
|||||||
# add vdr's external interface to the lswitch
|
# add vdr's external interface to the lswitch
|
||||||
tlr_vnic_index = self.nsxv_manager.add_vdr_internal_interface(
|
tlr_vnic_index = self.nsxv_manager.add_vdr_internal_interface(
|
||||||
tlr_edge_id, lswitch_id,
|
tlr_edge_id, lswitch_id,
|
||||||
address=vcns_const.INTEGRATION_LR_IPADDRESS.split('/')[0],
|
address=get_vdr_transit_network_tlr_address(),
|
||||||
netmask=vcns_const.INTEGRATION_SUBNET_NETMASK,
|
netmask=get_vdr_transit_network_netmask(),
|
||||||
type="uplink")
|
type="uplink")
|
||||||
nsxv_db.create_edge_vnic_binding(
|
nsxv_db.create_edge_vnic_binding(
|
||||||
context.session, tlr_edge_id, tlr_vnic_index, lswitch_id)
|
context.session, tlr_edge_id, tlr_vnic_index, lswitch_id)
|
||||||
@ -1548,8 +1601,8 @@ class EdgeManager(object):
|
|||||||
#TODO(berlin): the internal ip should change based on vnic_index
|
#TODO(berlin): the internal ip should change based on vnic_index
|
||||||
self.nsxv_manager.update_interface(
|
self.nsxv_manager.update_interface(
|
||||||
plr_router['id'], plr_edge_id, plr_vnic_index, lswitch_id,
|
plr_router['id'], plr_edge_id, plr_vnic_index, lswitch_id,
|
||||||
address=vcns_const.INTEGRATION_EDGE_IPADDRESS,
|
address=get_vdr_transit_network_plr_address(),
|
||||||
netmask=vcns_const.INTEGRATION_SUBNET_NETMASK)
|
netmask=get_vdr_transit_network_netmask())
|
||||||
return plr_router['id']
|
return plr_router['id']
|
||||||
|
|
||||||
def delete_plr_by_tlr_id(self, context, plr_id, router_id):
|
def delete_plr_by_tlr_id(self, context, plr_id, router_id):
|
||||||
|
@ -773,3 +773,72 @@ class EdgeManagerTestCase(EdgeUtilsTestCaseMixin):
|
|||||||
availability_zone=self.az)
|
availability_zone=self.az)
|
||||||
self.edge_manager._free_edge_appliance(
|
self.edge_manager._free_edge_appliance(
|
||||||
self.ctx, 'fake_id')
|
self.ctx, 'fake_id')
|
||||||
|
|
||||||
|
|
||||||
|
class VdrTransitNetUtilDefaultTestCase(EdgeUtilsTestCaseMixin):
|
||||||
|
EXPECTED_NETMASK = '255.255.255.240'
|
||||||
|
EXPECTED_TLR_IP = '169.254.2.1'
|
||||||
|
EXPECTED_PLR_IP = '169.254.2.2'
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(VdrTransitNetUtilDefaultTestCase, self).setUp()
|
||||||
|
|
||||||
|
def test_get_vdr_transit_network_netmask(self):
|
||||||
|
self.assertEqual(edge_utils.get_vdr_transit_network_netmask(),
|
||||||
|
self.EXPECTED_NETMASK)
|
||||||
|
|
||||||
|
def test_get_vdr_transit_network_tlr_address(self):
|
||||||
|
self.assertEqual(edge_utils.get_vdr_transit_network_tlr_address(),
|
||||||
|
self.EXPECTED_TLR_IP)
|
||||||
|
|
||||||
|
def test_get_vdr_transit_network_plr_address(self):
|
||||||
|
self.assertEqual(edge_utils.get_vdr_transit_network_plr_address(),
|
||||||
|
self.EXPECTED_PLR_IP)
|
||||||
|
|
||||||
|
def test_is_overlapping_reserved_subnets(self):
|
||||||
|
self.assertTrue(
|
||||||
|
edge_utils.is_overlapping_reserved_subnets('169.254.1.0/24',
|
||||||
|
['169.254.0.0/16']))
|
||||||
|
self.assertTrue(
|
||||||
|
edge_utils.is_overlapping_reserved_subnets('169.254.1.0/24',
|
||||||
|
['192.168.2.0/24',
|
||||||
|
'169.254.0.0/16']))
|
||||||
|
self.assertFalse(
|
||||||
|
edge_utils.is_overlapping_reserved_subnets('169.254.1.0/24',
|
||||||
|
['169.253.0.0/16']))
|
||||||
|
self.assertFalse(
|
||||||
|
edge_utils.is_overlapping_reserved_subnets('169.254.1.0/24',
|
||||||
|
['192.168.2.0/24',
|
||||||
|
'169.253.0.0/16']))
|
||||||
|
|
||||||
|
|
||||||
|
class VdrTransitNetUtilTestCase(EdgeUtilsTestCaseMixin):
|
||||||
|
EXPECTED_NETMASK = '255.255.255.0'
|
||||||
|
EXPECTED_TLR_IP = '192.168.1.1'
|
||||||
|
EXPECTED_PLR_IP = '192.168.1.2'
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(VdrTransitNetUtilTestCase, self).setUp()
|
||||||
|
|
||||||
|
|
||||||
|
class VdrTransitNetValidatorTestCase(EdgeUtilsTestCaseMixin):
|
||||||
|
def setUp(self):
|
||||||
|
super(VdrTransitNetValidatorTestCase, self).setUp()
|
||||||
|
|
||||||
|
def _test_validator(self, cidr):
|
||||||
|
cfg.CONF.set_override('vdr_transit_network', cidr, 'nsxv')
|
||||||
|
return edge_utils.validate_vdr_transit_network()
|
||||||
|
|
||||||
|
def test_vdr_transit_net_validator_success(self):
|
||||||
|
self.assertIsNone(self._test_validator('192.168.253.0/24'))
|
||||||
|
|
||||||
|
def test_vdr_transit_net_validator_junk_cidr(self):
|
||||||
|
self.assertRaises(n_exc.Invalid, self._test_validator, 'not_a_subnet')
|
||||||
|
|
||||||
|
def test_vdr_transit_net_validator_too_small_cidr(self):
|
||||||
|
self.assertRaises(
|
||||||
|
n_exc.Invalid, self._test_validator, '169.254.2.0/31')
|
||||||
|
|
||||||
|
def test_vdr_transit_net_validator_overlap_cidr(self):
|
||||||
|
self.assertRaises(
|
||||||
|
n_exc.Invalid, self._test_validator, '169.254.0.0/16')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user