Merge "Nicira NVP plugin support for l3_ext_gw_mode extension"
This commit is contained in:
commit
7750c38e12
@ -43,7 +43,9 @@ class L3_NAT_db_mixin(l3_db.L3_NAT_db_mixin):
|
|||||||
'enable_snat': router.enable_snat}
|
'enable_snat': router.enable_snat}
|
||||||
return self._fields(res, fields)
|
return self._fields(res, fields)
|
||||||
|
|
||||||
def _update_router_gw_info(self, context, router_id, info):
|
def _update_router_gw_info(self, context, router_id, info, router=None):
|
||||||
|
# Load the router only if necessary
|
||||||
|
if not router:
|
||||||
router = self._get_router(context, router_id)
|
router = self._get_router(context, router_id)
|
||||||
# if enable_snat is not specified use the value
|
# if enable_snat is not specified use the value
|
||||||
# stored in the database (default:True)
|
# stored in the database (default:True)
|
||||||
@ -54,6 +56,9 @@ class L3_NAT_db_mixin(l3_db.L3_NAT_db_mixin):
|
|||||||
# Calls superclass, pass router db object for avoiding re-loading
|
# Calls superclass, pass router db object for avoiding re-loading
|
||||||
super(L3_NAT_db_mixin, self)._update_router_gw_info(
|
super(L3_NAT_db_mixin, self)._update_router_gw_info(
|
||||||
context, router_id, info, router=router)
|
context, router_id, info, router=router)
|
||||||
|
# Returning the router might come back useful if this
|
||||||
|
# method is overriden in child classes
|
||||||
|
return router
|
||||||
|
|
||||||
def _build_routers_list(self, routers, gw_ports):
|
def _build_routers_list(self, routers, gw_ports):
|
||||||
gw_port_id_gw_port_dict = {}
|
gw_port_id_gw_port_dict = {}
|
||||||
|
@ -34,6 +34,7 @@ migration_for_plugins = [
|
|||||||
'neutron.plugins.linuxbridge.lb_neutron_plugin.LinuxBridgePluginV2',
|
'neutron.plugins.linuxbridge.lb_neutron_plugin.LinuxBridgePluginV2',
|
||||||
'neutron.plugins.metaplugin.meta_neutron_plugin.MetaPluginV2',
|
'neutron.plugins.metaplugin.meta_neutron_plugin.MetaPluginV2',
|
||||||
'neutron.plugins.nec.nec_plugin.NECPluginV2',
|
'neutron.plugins.nec.nec_plugin.NECPluginV2',
|
||||||
|
'neutron.plugins.nicira.NeutronPlugin.NvpPluginV2',
|
||||||
'neutron.plugins.openvswitch.ovs_neutron_plugin.OVSNeutronPluginV2',
|
'neutron.plugins.openvswitch.ovs_neutron_plugin.OVSNeutronPluginV2',
|
||||||
'neutron.plugins.ryu.ryu_neutron_plugin.RyuNeutronPluginV2'
|
'neutron.plugins.ryu.ryu_neutron_plugin.RyuNeutronPluginV2'
|
||||||
]
|
]
|
||||||
|
@ -44,6 +44,7 @@ from neutron.db import db_base_plugin_v2
|
|||||||
from neutron.db import dhcp_rpc_base
|
from neutron.db import dhcp_rpc_base
|
||||||
from neutron.db import extraroute_db
|
from neutron.db import extraroute_db
|
||||||
from neutron.db import l3_db
|
from neutron.db import l3_db
|
||||||
|
from neutron.db import l3_gwmode_db
|
||||||
from neutron.db import models_v2
|
from neutron.db import models_v2
|
||||||
from neutron.db import portsecurity_db
|
from neutron.db import portsecurity_db
|
||||||
from neutron.db import quota_db # noqa
|
from neutron.db import quota_db # noqa
|
||||||
@ -73,6 +74,7 @@ from neutron.plugins.nicira import nvplib
|
|||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger("NeutronPlugin")
|
LOG = logging.getLogger("NeutronPlugin")
|
||||||
|
|
||||||
NVP_NOSNAT_RULES_ORDER = 10
|
NVP_NOSNAT_RULES_ORDER = 10
|
||||||
NVP_FLOATINGIP_NAT_RULES_ORDER = 224
|
NVP_FLOATINGIP_NAT_RULES_ORDER = 224
|
||||||
NVP_EXTGW_NAT_RULES_ORDER = 255
|
NVP_EXTGW_NAT_RULES_ORDER = 255
|
||||||
@ -127,6 +129,7 @@ class NVPRpcCallbacks(dhcp_rpc_base.DhcpRpcCallbackMixin):
|
|||||||
|
|
||||||
class NvpPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
|
class NvpPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
|
||||||
extraroute_db.ExtraRoute_db_mixin,
|
extraroute_db.ExtraRoute_db_mixin,
|
||||||
|
l3_gwmode_db.L3_NAT_db_mixin,
|
||||||
portsecurity_db.PortSecurityDbMixin,
|
portsecurity_db.PortSecurityDbMixin,
|
||||||
securitygroups_db.SecurityGroupDbMixin,
|
securitygroups_db.SecurityGroupDbMixin,
|
||||||
mac_db.MacLearningDbMixin,
|
mac_db.MacLearningDbMixin,
|
||||||
@ -141,7 +144,8 @@ class NvpPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
|
|||||||
functionality using NVP.
|
functionality using NVP.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
supported_extension_aliases = ["extraroute",
|
supported_extension_aliases = ["ext_gw_mode",
|
||||||
|
"extraroute",
|
||||||
"mac-learning",
|
"mac-learning",
|
||||||
"network-gateway",
|
"network-gateway",
|
||||||
"nvp-qos",
|
"nvp-qos",
|
||||||
@ -278,6 +282,58 @@ class NvpPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
|
|||||||
attachment_vlan)
|
attachment_vlan)
|
||||||
return lrouter_port
|
return lrouter_port
|
||||||
|
|
||||||
|
def _update_router_gw_info(self, context, router_id, info):
|
||||||
|
# NOTE(salvatore-orlando): We need to worry about rollback of NVP
|
||||||
|
# configuration in case of failures in the process
|
||||||
|
# Ref. LP bug 1102301
|
||||||
|
router = self._get_router(context, router_id)
|
||||||
|
# Check whether SNAT rule update should be triggered
|
||||||
|
# NVP also supports multiple external networks so there is also
|
||||||
|
# the possibility that NAT rules should be replaced
|
||||||
|
current_ext_net_id = router.gw_port_id and router.gw_port.network_id
|
||||||
|
new_ext_net_id = info and info.get('network_id')
|
||||||
|
# SNAT should be enabled unless info['enable_snat'] is
|
||||||
|
# explicitly set to false
|
||||||
|
enable_snat = new_ext_net_id and info.get('enable_snat', True)
|
||||||
|
# Remove if ext net removed, changed, or if snat disabled
|
||||||
|
remove_snat_rules = (current_ext_net_id and
|
||||||
|
new_ext_net_id != current_ext_net_id or
|
||||||
|
router.enable_snat and not enable_snat)
|
||||||
|
# Add rules if snat is enabled, and if either the external network
|
||||||
|
# changed or snat was previously disabled
|
||||||
|
# NOTE: enable_snat == True implies new_ext_net_id != None
|
||||||
|
add_snat_rules = (enable_snat and
|
||||||
|
(new_ext_net_id != current_ext_net_id or
|
||||||
|
not router.enable_snat))
|
||||||
|
router = super(NvpPluginV2, self)._update_router_gw_info(
|
||||||
|
context, router_id, info, router=router)
|
||||||
|
# Add/Remove SNAT rules as needed
|
||||||
|
# Create an elevated context for dealing with metadata access
|
||||||
|
# cidrs which are created within admin context
|
||||||
|
ctx_elevated = context.elevated()
|
||||||
|
if remove_snat_rules or add_snat_rules:
|
||||||
|
cidrs = self._find_router_subnets_cidrs(ctx_elevated, router_id)
|
||||||
|
if remove_snat_rules:
|
||||||
|
# Be safe and concede NAT rules might not exist.
|
||||||
|
# Therefore use min_num_expected=0
|
||||||
|
for cidr in cidrs:
|
||||||
|
nvplib.delete_nat_rules_by_match(
|
||||||
|
self.cluster, router_id, "SourceNatRule",
|
||||||
|
max_num_expected=1, min_num_expected=0,
|
||||||
|
source_ip_addresses=cidr)
|
||||||
|
if add_snat_rules:
|
||||||
|
ip_addresses = self._build_ip_address_list(
|
||||||
|
ctx_elevated, router.gw_port['fixed_ips'])
|
||||||
|
# Set the SNAT rule for each subnet (only first IP)
|
||||||
|
for cidr in cidrs:
|
||||||
|
cidr_prefix = int(cidr.split('/')[1])
|
||||||
|
nvplib.create_lrouter_snat_rule(
|
||||||
|
self.cluster, router_id,
|
||||||
|
ip_addresses[0].split('/')[0],
|
||||||
|
ip_addresses[0].split('/')[0],
|
||||||
|
order=NVP_EXTGW_NAT_RULES_ORDER - cidr_prefix,
|
||||||
|
match_criteria={'source_ip_addresses': cidr})
|
||||||
|
|
||||||
def _update_router_port_attachment(self, cluster, context,
|
def _update_router_port_attachment(self, cluster, context,
|
||||||
router_id, port_data,
|
router_id, port_data,
|
||||||
nvp_router_port_id,
|
nvp_router_port_id,
|
||||||
@ -526,15 +582,6 @@ class NvpPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
|
|||||||
"L3GatewayAttachment",
|
"L3GatewayAttachment",
|
||||||
ext_network[pnet.PHYSICAL_NETWORK],
|
ext_network[pnet.PHYSICAL_NETWORK],
|
||||||
ext_network[pnet.SEGMENTATION_ID])
|
ext_network[pnet.SEGMENTATION_ID])
|
||||||
# Set the SNAT rule for each subnet (only first IP)
|
|
||||||
for cidr in self._find_router_subnets_cidrs(context, router_id):
|
|
||||||
cidr_prefix = int(cidr.split('/')[1])
|
|
||||||
nvplib.create_lrouter_snat_rule(
|
|
||||||
self.cluster, router_id,
|
|
||||||
ip_addresses[0].split('/')[0],
|
|
||||||
ip_addresses[0].split('/')[0],
|
|
||||||
order=NVP_EXTGW_NAT_RULES_ORDER - cidr_prefix,
|
|
||||||
match_criteria={'source_ip_addresses': cidr})
|
|
||||||
|
|
||||||
LOG.debug(_("_nvp_create_ext_gw_port completed on external network "
|
LOG.debug(_("_nvp_create_ext_gw_port completed on external network "
|
||||||
"%(ext_net_id)s, attached to router:%(router_id)s. "
|
"%(ext_net_id)s, attached to router:%(router_id)s. "
|
||||||
@ -559,13 +606,6 @@ class NvpPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
|
|||||||
port_data['name'],
|
port_data['name'],
|
||||||
True,
|
True,
|
||||||
['0.0.0.0/31'])
|
['0.0.0.0/31'])
|
||||||
# Delete the SNAT rule for each subnet, keep in mind
|
|
||||||
# that the rule might have already been removed from NVP
|
|
||||||
for cidr in self._find_router_subnets_cidrs(context, router_id):
|
|
||||||
nvplib.delete_nat_rules_by_match(
|
|
||||||
self.cluster, router_id, "SourceNatRule",
|
|
||||||
max_num_expected=1, min_num_expected=0,
|
|
||||||
source_ip_addresses=cidr)
|
|
||||||
# Reset attachment
|
# Reset attachment
|
||||||
self._update_router_port_attachment(
|
self._update_router_port_attachment(
|
||||||
self.cluster, context, router_id, port_data,
|
self.cluster, context, router_id, port_data,
|
||||||
@ -1654,7 +1694,7 @@ class NvpPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
|
|||||||
# Fetch router from DB
|
# Fetch router from DB
|
||||||
router = self._get_router(context, router_id)
|
router = self._get_router(context, router_id)
|
||||||
gw_port = router.gw_port
|
gw_port = router.gw_port
|
||||||
if gw_port:
|
if gw_port and router.enable_snat:
|
||||||
# There is a change gw_port might have multiple IPs
|
# There is a change gw_port might have multiple IPs
|
||||||
# In that case we will consider only the first one
|
# In that case we will consider only the first one
|
||||||
if gw_port.get('fixed_ips'):
|
if gw_port.get('fixed_ips'):
|
||||||
|
@ -39,6 +39,7 @@ from neutron.plugins.nicira import nvplib
|
|||||||
from neutron.tests.unit.nicira import fake_nvpapiclient
|
from neutron.tests.unit.nicira import fake_nvpapiclient
|
||||||
import neutron.tests.unit.nicira.test_networkgw as test_l2_gw
|
import neutron.tests.unit.nicira.test_networkgw as test_l2_gw
|
||||||
import neutron.tests.unit.test_db_plugin as test_plugin
|
import neutron.tests.unit.test_db_plugin as test_plugin
|
||||||
|
import neutron.tests.unit.test_extension_ext_gw_mode as test_ext_gw_mode
|
||||||
import neutron.tests.unit.test_extension_portsecurity as psec
|
import neutron.tests.unit.test_extension_portsecurity as psec
|
||||||
import neutron.tests.unit.test_extension_security_group as ext_sg
|
import neutron.tests.unit.test_extension_security_group as ext_sg
|
||||||
from neutron.tests.unit import test_extensions
|
from neutron.tests.unit import test_extensions
|
||||||
@ -830,6 +831,11 @@ class TestNiciraQoSQueue(NiciraPluginV2TestCase):
|
|||||||
self.assertEqual(queue['qos_queue']['max'], 20)
|
self.assertEqual(queue['qos_queue']['max'], 20)
|
||||||
|
|
||||||
|
|
||||||
|
class NiciraExtGwModeTestCase(test_ext_gw_mode.ExtGwModeTestCase,
|
||||||
|
NiciraPluginV2TestCase):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class NiciraNeutronNVPOutOfSync(test_l3_plugin.L3NatTestCaseBase,
|
class NiciraNeutronNVPOutOfSync(test_l3_plugin.L3NatTestCaseBase,
|
||||||
NiciraPluginV2TestCase):
|
NiciraPluginV2TestCase):
|
||||||
|
|
||||||
|
@ -302,7 +302,7 @@ class ExtGwModeTestCase(test_db_plugin.NeutronDbPluginV2TestCase,
|
|||||||
test_l3_plugin.L3NatTestCaseMixin):
|
test_l3_plugin.L3NatTestCaseMixin):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
# Store l3 resource attribute map as it's will be updated
|
# Store l3 resource attribute map as it will be updated
|
||||||
self._l3_attribute_map_bk = {}
|
self._l3_attribute_map_bk = {}
|
||||||
for item in l3.RESOURCE_ATTRIBUTE_MAP:
|
for item in l3.RESOURCE_ATTRIBUTE_MAP:
|
||||||
self._l3_attribute_map_bk[item] = (
|
self._l3_attribute_map_bk[item] = (
|
||||||
|
Loading…
Reference in New Issue
Block a user