Merge "Add metadata proxy support in NSX/T plugin"

This commit is contained in:
Jenkins 2015-12-17 18:44:09 +00:00 committed by Gerrit Code Review
commit 0b63b0bdf7
7 changed files with 285 additions and 227 deletions

View File

@ -45,7 +45,7 @@ from vmware_nsx.common import exceptions as nsx_exc
from vmware_nsx.common import nsx_constants from vmware_nsx.common import nsx_constants
from vmware_nsx.common import utils as c_utils from vmware_nsx.common import utils as c_utils
from vmware_nsx.db import db as nsx_db from vmware_nsx.db import db as nsx_db
from vmware_nsx import dhcpmeta_modes from vmware_nsx.dhcp_meta import modes as dhcpmeta_modes
from vmware_nsx.dvs import dvs from vmware_nsx.dvs import dvs
from vmware_nsx.dvs import dvs_utils from vmware_nsx.dvs import dvs_utils

View File

@ -72,7 +72,7 @@ from vmware_nsx.db import maclearning as mac_db
from vmware_nsx.db import networkgw_db from vmware_nsx.db import networkgw_db
from vmware_nsx.db import nsx_models from vmware_nsx.db import nsx_models
from vmware_nsx.db import qos_db from vmware_nsx.db import qos_db
from vmware_nsx import dhcpmeta_modes from vmware_nsx.dhcp_meta import modes as dhcpmeta_modes
from vmware_nsx.extensions import maclearning as mac_ext from vmware_nsx.extensions import maclearning as mac_ext
from vmware_nsx.extensions import networkgw from vmware_nsx.extensions import networkgw
from vmware_nsx.extensions import qos from vmware_nsx.extensions import qos

View File

@ -64,6 +64,7 @@ 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 utils from vmware_nsx.common import utils
from vmware_nsx.db import db as nsx_db from vmware_nsx.db import db as nsx_db
from vmware_nsx.dhcp_meta import rpc as nsx_rpc
from vmware_nsx.nsxlib import v3 as nsxlib from vmware_nsx.nsxlib import v3 as nsxlib
from vmware_nsx.nsxlib.v3 import client as nsx_client from vmware_nsx.nsxlib.v3 import client as nsx_client
from vmware_nsx.nsxlib.v3 import cluster as nsx_cluster from vmware_nsx.nsxlib.v3 import cluster as nsx_cluster
@ -651,6 +652,7 @@ class NsxV3Plugin(addr_pair_db.AllowedAddressPairsMixin,
with context.session.begin(subtransactions=True): with context.session.begin(subtransactions=True):
neutron_db = super(NsxV3Plugin, self).create_port(context, port) neutron_db = super(NsxV3Plugin, self).create_port(context, port)
port["port"].update(neutron_db) port["port"].update(neutron_db)
nsx_rpc.handle_port_metadata_access(self, context, neutron_db)
(is_psec_on, has_ip) = self._create_port_preprocess_security( (is_psec_on, has_ip) = self._create_port_preprocess_security(
context, port, port_data, neutron_db) context, port, port_data, neutron_db)
@ -708,6 +710,8 @@ class NsxV3Plugin(addr_pair_db.AllowedAddressPairsMixin,
context.session, port_id) context.session, port_id)
self._port_client.delete(nsx_port_id) self._port_client.delete(nsx_port_id)
self.disassociate_floatingips(context, port_id) self.disassociate_floatingips(context, port_id)
nsx_rpc.handle_port_metadata_access(self, context, port,
is_delete=True)
ret_val = super(NsxV3Plugin, self).delete_port(context, port_id) ret_val = super(NsxV3Plugin, self).delete_port(context, port_id)
return ret_val return ret_val
@ -1016,6 +1020,8 @@ class NsxV3Plugin(addr_pair_db.AllowedAddressPairsMixin,
return self.get_router(context, router['id']) return self.get_router(context, router['id'])
def delete_router(self, context, router_id): def delete_router(self, context, router_id):
nsx_rpc.handle_router_metadata_access(self, context, router_id,
interface=None)
router = self.get_router(context, router_id) router = self.get_router(context, router_id)
if router.get(l3.EXTERNAL_GW_INFO): if router.get(l3.EXTERNAL_GW_INFO):
self._update_router_gw_info(context, router_id, {}) self._update_router_gw_info(context, router_id, {})
@ -1190,6 +1196,11 @@ class NsxV3Plugin(addr_pair_db.AllowedAddressPairsMixin,
# TODO(berlin): Announce the subnet on tier0 if enable_snat # TODO(berlin): Announce the subnet on tier0 if enable_snat
# is False # is False
pass pass
# Ensure the NSX logical router has a connection to a
# 'metadata access' network (with a proxy listening on
# its DHCP port), by creating it if needed.
nsx_rpc.handle_router_metadata_access(self, context, router_id,
interface=info)
except nsx_exc.ManagerError: except nsx_exc.ManagerError:
with excutils.save_and_reraise_exception(): with excutils.save_and_reraise_exception():
self.remove_router_interface( self.remove_router_interface(
@ -1257,8 +1268,13 @@ class NsxV3Plugin(addr_pair_db.AllowedAddressPairsMixin,
"%(net_id)s not found at the backend"), "%(net_id)s not found at the backend"),
{'router_id': router_id, {'router_id': router_id,
'net_id': subnet['network_id']}) 'net_id': subnet['network_id']})
return super(NsxV3Plugin, self).remove_router_interface( info = super(NsxV3Plugin, self).remove_router_interface(
context, router_id, interface_info) context, router_id, interface_info)
# Ensure the connection to the 'metadata access network' is removed
# (with the network) if this the last subnet on the router.
nsx_rpc.handle_router_metadata_access(self, context, router_id,
interface=info)
return info
def create_floatingip(self, context, floatingip): def create_floatingip(self, context, floatingip):
new_fip = super(NsxV3Plugin, self).create_floatingip( new_fip = super(NsxV3Plugin, self).create_floatingip(

View File

@ -0,0 +1,259 @@
# 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.
import mock
import netaddr
from oslo_config import cfg
import webob.exc
from neutron.common import constants
from neutron.common import exceptions as n_exc
from neutron import manager
from vmware_nsx.api_client import exception as api_exc
from vmware_nsx.common import config
class MetaDataTestCase(object):
def _metadata_setup(self, mode=config.MetadataModes.DIRECT):
cfg.CONF.set_override('metadata_mode', mode, 'NSX')
def _metadata_teardown(self):
cfg.CONF.set_override('metadata_mode', None, 'NSX')
def test_router_add_interface_subnet_with_metadata_access(self):
self._metadata_setup()
self.test_router_add_interface_subnet()
self._metadata_teardown()
def test_router_add_interface_port_with_metadata_access(self):
self._metadata_setup()
self.test_router_add_interface_port()
self._metadata_teardown()
def test_router_add_interface_dupsubnet_returns_400_with_metadata(self):
self._metadata_setup()
self.test_router_add_interface_dup_subnet1_returns_400()
self._metadata_teardown()
def test_router_add_interface_overlapped_cidr_returns_400_with(self):
self._metadata_setup()
self.test_router_add_interface_overlapped_cidr_returns_400()
self._metadata_teardown()
def test_router_remove_interface_inuse_returns_409_with_metadata(self):
self._metadata_setup()
self.test_router_remove_interface_inuse_returns_409()
self._metadata_teardown()
def test_router_remove_iface_wrong_sub_returns_400_with_metadata(self):
self._metadata_setup()
self.test_router_remove_interface_wrong_subnet_returns_400()
self._metadata_teardown()
def test_router_delete_with_metadata_access(self):
self._metadata_setup()
self.test_router_delete()
self._metadata_teardown()
def test_router_delete_with_port_existed_returns_409_with_metadata(self):
self._metadata_setup()
self.test_router_delete_with_port_existed_returns_409()
self._metadata_teardown()
def test_delete_port_with_metadata(self):
self._metadata_setup(config.MetadataModes.INDIRECT)
with self.subnet() as s:
with self.port(subnet=s, fixed_ips=[], device_id='1234',
device_owner=constants.DEVICE_OWNER_DHCP) as port:
self._delete('ports', port['port']['id'])
self._metadata_teardown()
def test_metadatata_network_created_with_router_interface_add(self):
self._metadata_setup()
with mock.patch.object(self._plugin_class, 'schedule_network') as f:
with self.router() as r:
with self.subnet() as s:
self._router_interface_action('add',
r['router']['id'],
s['subnet']['id'],
None)
r_ports = self._list('ports')['ports']
self.assertEqual(len(r_ports), 2)
ips = []
for port in r_ports:
ips.extend([netaddr.IPAddress(fixed_ip['ip_address'])
for fixed_ip in port['fixed_ips']])
meta_cidr = netaddr.IPNetwork('169.254.0.0/16')
self.assertTrue(any([ip in meta_cidr for ip in ips]))
# Needed to avoid 409.
self._router_interface_action('remove',
r['router']['id'],
s['subnet']['id'],
None)
# Verify that the metadata network gets scheduled, so that
# an active dhcp agent can pick it up.
expected_meta_net = {
'status': 'ACTIVE',
'subnets': [],
'name': 'meta-%s' % r['router']['id'],
'admin_state_up': True,
'tenant_id': '',
'port_security_enabled': False,
'shared': False,
'id': mock.ANY,
'mtu': mock.ANY
}
f.assert_any_call(mock.ANY, expected_meta_net)
self._metadata_teardown()
def test_metadata_network_create_rollback_on_create_subnet_failure(self):
self._metadata_setup()
with self.router() as r:
with self.subnet() as s:
# Raise a NeutronException (eg: NotFound).
with mock.patch.object(self._plugin_class,
'create_subnet',
side_effect=n_exc.NotFound):
self._router_interface_action(
'add', r['router']['id'], s['subnet']['id'], None)
# Ensure metadata network was removed.
nets = self._list('networks')['networks']
self.assertEqual(len(nets), 1)
# Needed to avoid 409.
self._router_interface_action('remove',
r['router']['id'],
s['subnet']['id'],
None)
self._metadata_teardown()
def test_metadata_network_create_rollback_on_add_rtr_iface_failure(self):
self._metadata_setup()
with self.router() as r:
with self.subnet() as s:
# Save function being mocked.
real_func = self._plugin_class.add_router_interface
plugin_instance = manager.NeutronManager.get_plugin()
# Raise a NeutronException when adding metadata subnet
# to router.
def side_effect(*args):
if args[-1]['subnet_id'] == s['subnet']['id']:
# Do the real thing.
return real_func(plugin_instance, *args)
# Otherwise raise.
raise api_exc.NsxApiException()
with mock.patch.object(self._plugin_class,
'add_router_interface',
side_effect=side_effect):
self._router_interface_action(
'add', r['router']['id'], s['subnet']['id'], None)
# Ensure metadata network was removed.
nets = self._list('networks')['networks']
self.assertEqual(len(nets), 1)
# Needed to avoid 409.
self._router_interface_action('remove',
r['router']['id'],
s['subnet']['id'],
None)
self._metadata_teardown()
def test_metadata_network_removed_with_router_interface_remove(self):
self._metadata_setup()
with self.router() as r:
with self.subnet() as s:
self._router_interface_action('add', r['router']['id'],
s['subnet']['id'], None)
subnets = self._list('subnets')['subnets']
self.assertEqual(len(subnets), 2)
meta_cidr = netaddr.IPNetwork('169.254.0.0/16')
for subnet in subnets:
cidr = netaddr.IPNetwork(subnet['cidr'])
if meta_cidr == cidr or meta_cidr in cidr.supernet(16):
meta_sub_id = subnet['id']
meta_net_id = subnet['network_id']
ports = self._list(
'ports',
query_params='network_id=%s' % meta_net_id)['ports']
self.assertEqual(len(ports), 1)
meta_port_id = ports[0]['id']
self._router_interface_action('remove', r['router']['id'],
s['subnet']['id'], None)
self._show('networks', meta_net_id,
webob.exc.HTTPNotFound.code)
self._show('ports', meta_port_id,
webob.exc.HTTPNotFound.code)
self._show('subnets', meta_sub_id,
webob.exc.HTTPNotFound.code)
self._metadata_teardown()
def test_metadata_network_remove_rollback_on_failure(self):
self._metadata_setup()
with self.router() as r:
with self.subnet() as s:
self._router_interface_action('add', r['router']['id'],
s['subnet']['id'], None)
networks = self._list('networks')['networks']
for network in networks:
if network['id'] != s['subnet']['network_id']:
meta_net_id = network['id']
ports = self._list(
'ports',
query_params='network_id=%s' % meta_net_id)['ports']
meta_port_id = ports[0]['id']
# Save function being mocked.
real_func = self._plugin_class.remove_router_interface
plugin_instance = manager.NeutronManager.get_plugin()
# Raise a NeutronException when removing metadata subnet
# from router.
def side_effect(*args):
if args[-1].get('subnet_id') == s['subnet']['id']:
# Do the real thing.
return real_func(plugin_instance, *args)
# Otherwise raise.
raise api_exc.NsxApiException()
with mock.patch.object(self._plugin_class,
'remove_router_interface',
side_effect=side_effect):
self._router_interface_action('remove', r['router']['id'],
s['subnet']['id'], None)
# Metadata network and subnet should still be there.
self._show('networks', meta_net_id,
webob.exc.HTTPOk.code)
self._show('ports', meta_port_id,
webob.exc.HTTPOk.code)
self._metadata_teardown()
def test_metadata_dhcp_host_route(self):
self._metadata_setup(config.MetadataModes.INDIRECT)
subnets = self._list('subnets')['subnets']
with self.subnet() as s:
with self.port(subnet=s, device_id='1234',
device_owner=constants.DEVICE_OWNER_DHCP) as port:
subnets = self._list('subnets')['subnets']
self.assertEqual(len(subnets), 1)
self.assertEqual(subnets[0]['host_routes'][0]['nexthop'],
'10.0.0.2')
self.assertEqual(subnets[0]['host_routes'][0]['destination'],
'169.254.169.254/32')
self._delete('ports', port['port']['id'])
subnets = self._list('subnets')['subnets']
# Test that route is deleted after dhcp port is removed.
self.assertEqual(len(subnets[0]['host_routes']), 0)
self._metadata_teardown()

View File

@ -16,7 +16,6 @@
import uuid import uuid
import mock import mock
import netaddr
from neutron.api.v2 import attributes from neutron.api.v2 import attributes
from neutron.common import constants from neutron.common import constants
from neutron.common import exceptions as ntn_exc from neutron.common import exceptions as ntn_exc
@ -52,6 +51,7 @@ from vmware_nsx.common import utils
from vmware_nsx.db import db as nsx_db from vmware_nsx.db import db as nsx_db
from vmware_nsx.nsxlib import mh as nsxlib from vmware_nsx.nsxlib import mh as nsxlib
from vmware_nsx.tests import unit as vmware from vmware_nsx.tests import unit as vmware
from vmware_nsx.tests.unit.extensions import test_metadata
from vmware_nsx.tests.unit.nsx_mh.apiclient import fake from vmware_nsx.tests.unit.nsx_mh.apiclient import fake
from vmware_nsx.tests.unit import test_utils from vmware_nsx.tests.unit import test_utils
@ -532,7 +532,8 @@ class L3NatTest(test_l3_plugin.L3BaseForIntTests, NsxPluginV2TestCase):
class TestL3NatTestCase(L3NatTest, class TestL3NatTestCase(L3NatTest,
test_l3_plugin.L3NatDBIntTestCase, test_l3_plugin.L3NatDBIntTestCase,
NsxPluginV2TestCase): NsxPluginV2TestCase,
test_metadata.MetaDataTestCase):
def _test_create_l3_ext_network(self, vlan_id=0): def _test_create_l3_ext_network(self, vlan_id=0):
name = 'l3_ext_net' name = 'l3_ext_net'
@ -761,23 +762,12 @@ class TestL3NatTestCase(L3NatTest,
def test_floatingip_with_invalid_create_port(self): def test_floatingip_with_invalid_create_port(self):
self._test_floatingip_with_invalid_create_port(self._plugin_name) self._test_floatingip_with_invalid_create_port(self._plugin_name)
def _metadata_setup(self):
cfg.CONF.set_override('metadata_mode', 'access_network', 'NSX')
def _metadata_teardown(self):
cfg.CONF.set_override('metadata_mode', None, 'NSX')
def test_create_router_name_exceeds_40_chars(self): def test_create_router_name_exceeds_40_chars(self):
name = 'this_is_a_router_whose_name_is_longer_than_40_chars' name = 'this_is_a_router_whose_name_is_longer_than_40_chars'
with self.router(name=name) as rtr: with self.router(name=name) as rtr:
# Assert Neutron name is not truncated # Assert Neutron name is not truncated
self.assertEqual(rtr['router']['name'], name) self.assertEqual(rtr['router']['name'], name)
def test_router_add_interface_subnet_with_metadata_access(self):
self._metadata_setup()
self.test_router_add_interface_subnet()
self._metadata_teardown()
def test_router_add_interface_port(self): def test_router_add_interface_port(self):
orig_update_port = self.plugin.update_port orig_update_port = self.plugin.update_port
with self.router() as r, ( with self.router() as r, (
@ -804,216 +794,6 @@ class TestL3NatTestCase(L3NatTest,
None, None,
p['port']['id']) p['port']['id'])
def test_router_add_interface_port_with_metadata_access(self):
self._metadata_setup()
self.test_router_add_interface_port()
self._metadata_teardown()
def test_router_add_interface_dupsubnet_returns_400_with_metadata(self):
self._metadata_setup()
self.test_router_add_interface_dup_subnet1_returns_400()
self._metadata_teardown()
def test_router_add_interface_overlapped_cidr_returns_400_with(self):
self._metadata_setup()
self.test_router_add_interface_overlapped_cidr_returns_400()
self._metadata_teardown()
def test_router_remove_interface_inuse_returns_409_with_metadata(self):
self._metadata_setup()
self.test_router_remove_interface_inuse_returns_409()
self._metadata_teardown()
def test_router_remove_iface_wrong_sub_returns_400_with_metadata(self):
self._metadata_setup()
self.test_router_remove_interface_wrong_subnet_returns_400()
self._metadata_teardown()
def test_router_delete_with_metadata_access(self):
self._metadata_setup()
self.test_router_delete()
self._metadata_teardown()
def test_router_delete_with_port_existed_returns_409_with_metadata(self):
self._metadata_setup()
self.test_router_delete_with_port_existed_returns_409()
self._metadata_teardown()
def test_metadatata_network_created_with_router_interface_add(self):
self._metadata_setup()
with mock.patch.object(self._plugin_class, 'schedule_network') as f:
with self.router() as r:
with self.subnet() as s:
self._router_interface_action('add',
r['router']['id'],
s['subnet']['id'],
None)
r_ports = self._list('ports')['ports']
self.assertEqual(len(r_ports), 2)
ips = []
for port in r_ports:
ips.extend([netaddr.IPAddress(fixed_ip['ip_address'])
for fixed_ip in port['fixed_ips']])
meta_cidr = netaddr.IPNetwork('169.254.0.0/16')
self.assertTrue(any([ip in meta_cidr for ip in ips]))
# Needed to avoid 409
self._router_interface_action('remove',
r['router']['id'],
s['subnet']['id'],
None)
# Verify that the metadata network gets scheduled, so that
# an active dhcp agent can pick it up
expected_meta_net = {
'status': 'ACTIVE',
'subnets': [],
'name': 'meta-%s' % r['router']['id'],
'admin_state_up': True,
'tenant_id': '',
'port_security_enabled': False,
'shared': False,
'id': mock.ANY,
'mtu': mock.ANY
}
f.assert_any_call(mock.ANY, expected_meta_net)
self._metadata_teardown()
def test_metadata_network_create_rollback_on_create_subnet_failure(self):
self._metadata_setup()
with self.router() as r:
with self.subnet() as s:
# Raise a NeutronException (eg: NotFound)
with mock.patch.object(self._plugin_class,
'create_subnet',
side_effect=ntn_exc.NotFound):
self._router_interface_action(
'add', r['router']['id'], s['subnet']['id'], None)
# Ensure metadata network was removed
nets = self._list('networks')['networks']
self.assertEqual(len(nets), 1)
# Needed to avoid 409
self._router_interface_action('remove',
r['router']['id'],
s['subnet']['id'],
None)
self._metadata_teardown()
def test_metadata_network_create_rollback_on_add_rtr_iface_failure(self):
self._metadata_setup()
with self.router() as r:
with self.subnet() as s:
# Raise a NeutronException when adding metadata subnet
# to router
# save function being mocked
real_func = self._plugin_class.add_router_interface
plugin_instance = manager.NeutronManager.get_plugin()
def side_effect(*args):
if args[-1]['subnet_id'] == s['subnet']['id']:
# do the real thing
return real_func(plugin_instance, *args)
# otherwise raise
raise api_exc.NsxApiException()
with mock.patch.object(self._plugin_class,
'add_router_interface',
side_effect=side_effect):
self._router_interface_action(
'add', r['router']['id'], s['subnet']['id'], None)
# Ensure metadata network was removed
nets = self._list('networks')['networks']
self.assertEqual(len(nets), 1)
# Needed to avoid 409
self._router_interface_action('remove',
r['router']['id'],
s['subnet']['id'],
None)
self._metadata_teardown()
def test_metadata_network_removed_with_router_interface_remove(self):
self._metadata_setup()
with self.router() as r:
with self.subnet() as s:
self._router_interface_action('add', r['router']['id'],
s['subnet']['id'], None)
subnets = self._list('subnets')['subnets']
self.assertEqual(len(subnets), 2)
meta_cidr = netaddr.IPNetwork('169.254.0.0/16')
for subnet in subnets:
cidr = netaddr.IPNetwork(subnet['cidr'])
if meta_cidr == cidr or meta_cidr in cidr.supernet(16):
meta_sub_id = subnet['id']
meta_net_id = subnet['network_id']
ports = self._list(
'ports',
query_params='network_id=%s' % meta_net_id)['ports']
self.assertEqual(len(ports), 1)
meta_port_id = ports[0]['id']
self._router_interface_action('remove', r['router']['id'],
s['subnet']['id'], None)
self._show('networks', meta_net_id,
webob.exc.HTTPNotFound.code)
self._show('ports', meta_port_id,
webob.exc.HTTPNotFound.code)
self._show('subnets', meta_sub_id,
webob.exc.HTTPNotFound.code)
self._metadata_teardown()
def test_metadata_network_remove_rollback_on_failure(self):
self._metadata_setup()
with self.router() as r:
with self.subnet() as s:
self._router_interface_action('add', r['router']['id'],
s['subnet']['id'], None)
networks = self._list('networks')['networks']
for network in networks:
if network['id'] != s['subnet']['network_id']:
meta_net_id = network['id']
ports = self._list(
'ports',
query_params='network_id=%s' % meta_net_id)['ports']
meta_port_id = ports[0]['id']
# Raise a NeutronException when removing
# metadata subnet from router
# save function being mocked
real_func = self._plugin_class.remove_router_interface
plugin_instance = manager.NeutronManager.get_plugin()
def side_effect(*args):
if args[-1].get('subnet_id') == s['subnet']['id']:
# do the real thing
return real_func(plugin_instance, *args)
# otherwise raise
raise api_exc.NsxApiException()
with mock.patch.object(self._plugin_class,
'remove_router_interface',
side_effect=side_effect):
self._router_interface_action('remove', r['router']['id'],
s['subnet']['id'], None)
# Metadata network and subnet should still be there
self._show('networks', meta_net_id,
webob.exc.HTTPOk.code)
self._show('ports', meta_port_id,
webob.exc.HTTPOk.code)
self._metadata_teardown()
def test_metadata_dhcp_host_route(self):
cfg.CONF.set_override('metadata_mode', 'dhcp_host_route', 'NSX')
subnets = self._list('subnets')['subnets']
with self.subnet() as s:
with self.port(subnet=s, device_id='1234',
device_owner=constants.DEVICE_OWNER_DHCP) as port:
subnets = self._list('subnets')['subnets']
self.assertEqual(len(subnets), 1)
self.assertEqual(subnets[0]['host_routes'][0]['nexthop'],
'10.0.0.2')
self.assertEqual(subnets[0]['host_routes'][0]['destination'],
'169.254.169.254/32')
self._delete('ports', port['port']['id'])
subnets = self._list('subnets')['subnets']
# Test that route is deleted after dhcp port is removed
self.assertEqual(len(subnets[0]['host_routes']), 0)
def _test_floatingip_update(self, expected_status): def _test_floatingip_update(self, expected_status):
super(TestL3NatTestCase, self).test_floatingip_update( super(TestL3NatTestCase, self).test_floatingip_update(
expected_status) expected_status)

View File

@ -45,6 +45,7 @@ from vmware_nsx.nsxlib.v3 import client as nsx_client
from vmware_nsx.nsxlib.v3 import cluster as nsx_cluster from vmware_nsx.nsxlib.v3 import cluster as nsx_cluster
from vmware_nsx.plugins.nsx_v3 import plugin as nsx_plugin from vmware_nsx.plugins.nsx_v3 import plugin as nsx_plugin
from vmware_nsx.tests import unit as vmware from vmware_nsx.tests import unit as vmware
from vmware_nsx.tests.unit.extensions import test_metadata
from vmware_nsx.tests.unit.nsx_v3 import mocks as nsx_v3_mocks from vmware_nsx.tests.unit.nsx_v3 import mocks as nsx_v3_mocks
from vmware_nsx.tests.unit.nsxlib.v3 import nsxlib_testcase from vmware_nsx.tests.unit.nsxlib.v3 import nsxlib_testcase
@ -257,12 +258,14 @@ class L3NatTest(test_l3_plugin.L3BaseForIntTests, NsxV3PluginTestCaseMixin):
class TestL3NatTestCase(L3NatTest, class TestL3NatTestCase(L3NatTest,
test_l3_plugin.L3NatDBIntTestCase, test_l3_plugin.L3NatDBIntTestCase,
test_ext_route.ExtraRouteDBTestCaseBase): test_ext_route.ExtraRouteDBTestCaseBase,
test_metadata.MetaDataTestCase):
def setUp(self, plugin=PLUGIN_NAME, def setUp(self, plugin=PLUGIN_NAME,
ext_mgr=None, ext_mgr=None,
service_plugins=None): service_plugins=None):
super(TestL3NatTestCase, self).setUp(plugin=plugin, ext_mgr=ext_mgr) super(TestL3NatTestCase, self).setUp(plugin=plugin, ext_mgr=ext_mgr)
cfg.CONF.set_override('metadata_mode', None, 'NSX')
def _test_create_l3_ext_network( def _test_create_l3_ext_network(
self, physical_network=nsx_v3_mocks.DEFAULT_TIER0_ROUTER_UUID): self, physical_network=nsx_v3_mocks.DEFAULT_TIER0_ROUTER_UUID):