NSX|v+v3: forbid multiple fixed ips in a port
The nsx backend does not allow adding different static DHCP bindings with the same mac, so an instance cannot be deployed with a port with multiple ips. This patch prevent create/update of a port with more than 1 fixed ip. Change-Id: I4b0ba1f3dc593604a3d6a53f8e0aac385faed985
This commit is contained in:
parent
7bcd7d009f
commit
1dfc0fe59e
@ -22,6 +22,7 @@
|
||||
r="^(?!.*"
|
||||
|
||||
r="$r(?:tempest\.api\.network\.test_ports\.PortsTestJSON\.test_create_update_port_with_second_ip.*)"
|
||||
r="$r|(?:tempest\.api\.network\.test_floating_ips\.FloatingIPTestJSON\.test_create_update_floatingip_with_port_multiple_ip_address.*)"
|
||||
|
||||
# End list of exclusions.
|
||||
r="$r)"
|
||||
|
@ -32,6 +32,7 @@ r="$r|(?:tempest\.api\.network\.test_ports\.PortsTestJSON\.test_create_update_po
|
||||
r="$r|(?:tempest\.api\.network\.test_ports\.PortsTestJSON\.test_update_port_with_security_group_and_extra_attributes.*)"
|
||||
r="$r|(?:tempest\.api\.network\.test_ports\.PortsTestJSON\.test_update_port_with_two_security_groups_and_extra_attributes.*)"
|
||||
r="$r|(?:tempest\.api\.network\.test_extra_dhcp_options\.ExtraDHCPOptionsTestJSON\.test_.*_with_extra_dhcp_options.*)"
|
||||
r="$r|(?:tempest\.api\.network\.test_floating_ips\.FloatingIPTestJSON\.test_create_update_floatingip_with_port_multiple_ip_address.*)"
|
||||
|
||||
# End list of exclusions.
|
||||
r="$r)"
|
||||
|
@ -26,9 +26,11 @@ from neutron_lib.api.definitions import address_scope as ext_address_scope
|
||||
from neutron_lib.api.definitions import network as net_def
|
||||
from neutron_lib.api.definitions import port as port_def
|
||||
from neutron_lib.api.definitions import subnet as subnet_def
|
||||
from neutron_lib.api import validators
|
||||
from neutron_lib import context as n_context
|
||||
from neutron_lib import exceptions as n_exc
|
||||
from neutron_lib.plugins import directory
|
||||
from neutron_lib.utils import net
|
||||
|
||||
from vmware_nsx._i18n import _
|
||||
from vmware_nsx.common import exceptions as nsx_exc
|
||||
@ -254,3 +256,17 @@ class NsxPluginBase(db_base_plugin_v2.NeutronDbPluginV2,
|
||||
|
||||
self.recalculate_snat_rules_for_router(context, rtr,
|
||||
affected_subnets)
|
||||
|
||||
def _validate_max_ips_per_port(self, fixed_ip_list, device_owner):
|
||||
"""Validate the number of fixed ips on a port
|
||||
|
||||
Do not allow multiple ip addresses on a port since the nsx backend
|
||||
cannot add multiple static dhcp bindings with the same port
|
||||
"""
|
||||
if (device_owner and
|
||||
net.is_port_trusted({'device_owner': device_owner})):
|
||||
return
|
||||
|
||||
if validators.is_attr_set(fixed_ip_list) and len(fixed_ip_list) > 1:
|
||||
msg = _('Exceeded maximum amount of fixed ips per port')
|
||||
raise n_exc.InvalidInput(error_message=msg)
|
||||
|
@ -1718,6 +1718,8 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
port_data = port['port']
|
||||
dhcp_opts = port_data.get(ext_edo.EXTRADHCPOPTS)
|
||||
self._validate_extra_dhcp_options(dhcp_opts)
|
||||
self._validate_max_ips_per_port(port_data.get('fixed_ips', []),
|
||||
port_data.get('device_owner'))
|
||||
|
||||
with db_api.context_manager.writer.using(context):
|
||||
# First we allocate port in neutron database
|
||||
@ -1926,6 +1928,9 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
self._validate_extra_dhcp_options(dhcp_opts)
|
||||
if addr_pair.ADDRESS_PAIRS in attrs:
|
||||
self._validate_address_pairs(attrs, original_port)
|
||||
self._validate_max_ips_per_port(
|
||||
port_data.get('fixed_ips', []),
|
||||
port_data.get('device_owner', original_port['device_owner']))
|
||||
orig_has_port_security = (cfg.CONF.nsxv.spoofguard_enabled and
|
||||
original_port[psec.PORTSECURITY])
|
||||
port_ip_change = port_data.get('fixed_ips') is not None
|
||||
|
@ -2081,6 +2081,8 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
port_data = port['port']
|
||||
dhcp_opts = port_data.get(ext_edo.EXTRADHCPOPTS)
|
||||
self._validate_extra_dhcp_options(dhcp_opts)
|
||||
self._validate_max_ips_per_port(port_data.get('fixed_ips', []),
|
||||
port_data.get('device_owner'))
|
||||
|
||||
# TODO(salv-orlando): Undo logical switch creation on failure
|
||||
with db_api.context_manager.writer.using(context):
|
||||
@ -2504,31 +2506,35 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
|
||||
with db_api.context_manager.writer.using(context):
|
||||
original_port = super(NsxV3Plugin, self).get_port(context, id)
|
||||
port_data = port['port']
|
||||
nsx_lswitch_id, nsx_lport_id = nsx_db.get_nsx_switch_and_port_id(
|
||||
context.session, id)
|
||||
is_external_net = self._network_is_external(
|
||||
context, original_port['network_id'])
|
||||
if is_external_net:
|
||||
self._assert_on_external_net_with_compute(port['port'])
|
||||
self._assert_on_external_net_port_with_qos(port['port'])
|
||||
self._assert_on_external_net_with_compute(port_data)
|
||||
self._assert_on_external_net_port_with_qos(port_data)
|
||||
|
||||
dhcp_opts = port['port'].get(ext_edo.EXTRADHCPOPTS)
|
||||
dhcp_opts = port_data.get(ext_edo.EXTRADHCPOPTS)
|
||||
self._validate_extra_dhcp_options(dhcp_opts)
|
||||
|
||||
device_owner = (port['port']['device_owner']
|
||||
if 'device_owner' in port['port']
|
||||
device_owner = (port_data['device_owner']
|
||||
if 'device_owner' in port_data
|
||||
else original_port.get('device_owner'))
|
||||
self._assert_on_router_port_with_qos(
|
||||
port['port'], device_owner)
|
||||
port_data, device_owner)
|
||||
|
||||
self._validate_max_ips_per_port(
|
||||
port_data.get('fixed_ips', []), device_owner)
|
||||
|
||||
updated_port = super(NsxV3Plugin, self).update_port(context,
|
||||
id, port)
|
||||
self._extension_manager.process_update_port(context, port['port'],
|
||||
self._extension_manager.process_update_port(context, port_data,
|
||||
updated_port)
|
||||
# copy values over - except fixed_ips as
|
||||
# they've already been processed
|
||||
port['port'].pop('fixed_ips', None)
|
||||
updated_port.update(port['port'])
|
||||
port_data.pop('fixed_ips', None)
|
||||
updated_port.update(port_data)
|
||||
|
||||
updated_port = self._update_port_preprocess_security(
|
||||
context, port, id, updated_port, validate_port_sec)
|
||||
@ -2544,7 +2550,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
(port_security, has_ip) = self._determine_port_security_and_has_ip(
|
||||
context, updated_port)
|
||||
self._process_portbindings_create_and_update(
|
||||
context, port['port'], updated_port)
|
||||
context, port_data, updated_port)
|
||||
self._extend_nsx_port_dict_binding(context, updated_port)
|
||||
mac_learning_state = updated_port.get(mac_ext.MAC_LEARNING)
|
||||
if mac_learning_state is not None:
|
||||
|
@ -874,15 +874,7 @@ class TestPortsV2(NsxVPluginV2TestCase,
|
||||
self.skipTest('No DHCP v6 Support yet')
|
||||
|
||||
def test_create_port_anticipating_allocation(self):
|
||||
with self.network(shared=True) as network:
|
||||
with self.subnet(network=network, cidr='10.0.0.0/24',
|
||||
enable_dhcp=False) as subnet:
|
||||
fixed_ips = [{'subnet_id': subnet['subnet']['id']},
|
||||
{'subnet_id': subnet['subnet']['id'],
|
||||
'ip_address': '10.0.0.2'}]
|
||||
self._create_port(self.fmt, network['network']['id'],
|
||||
webob.exc.HTTPCreated.code,
|
||||
fixed_ips=fixed_ips)
|
||||
self.skipTest('Multiple fixed ips on a port are not supported')
|
||||
|
||||
def test_update_port_mac_ip(self):
|
||||
with self.subnet(enable_dhcp=False) as subnet:
|
||||
@ -1209,94 +1201,10 @@ class TestPortsV2(NsxVPluginV2TestCase,
|
||||
self.vnic_type))
|
||||
|
||||
def test_range_allocation(self):
|
||||
with self.subnet(enable_dhcp=False, gateway_ip='10.0.0.3',
|
||||
cidr='10.0.0.0/29') as subnet:
|
||||
kwargs = {"fixed_ips":
|
||||
[{'subnet_id': subnet['subnet']['id']},
|
||||
{'subnet_id': subnet['subnet']['id']},
|
||||
{'subnet_id': subnet['subnet']['id']},
|
||||
{'subnet_id': subnet['subnet']['id']},
|
||||
{'subnet_id': subnet['subnet']['id']}]}
|
||||
net_id = subnet['subnet']['network_id']
|
||||
res = self._create_port(self.fmt, net_id=net_id, **kwargs)
|
||||
port = self.deserialize(self.fmt, res)
|
||||
ips = port['port']['fixed_ips']
|
||||
self.assertEqual(len(ips), 5)
|
||||
alloc = ['10.0.0.1', '10.0.0.2', '10.0.0.4', '10.0.0.5',
|
||||
'10.0.0.6']
|
||||
for ip in ips:
|
||||
self.assertIn(ip['ip_address'], alloc)
|
||||
self.assertEqual(ip['subnet_id'],
|
||||
subnet['subnet']['id'])
|
||||
alloc.remove(ip['ip_address'])
|
||||
self.assertEqual(len(alloc), 0)
|
||||
self._delete('ports', port['port']['id'])
|
||||
|
||||
with self.subnet(enable_dhcp=False, gateway_ip='11.0.0.6',
|
||||
cidr='11.0.0.0/29') as subnet:
|
||||
kwargs = {"fixed_ips":
|
||||
[{'subnet_id': subnet['subnet']['id']},
|
||||
{'subnet_id': subnet['subnet']['id']},
|
||||
{'subnet_id': subnet['subnet']['id']},
|
||||
{'subnet_id': subnet['subnet']['id']},
|
||||
{'subnet_id': subnet['subnet']['id']}]}
|
||||
net_id = subnet['subnet']['network_id']
|
||||
res = self._create_port(self.fmt, net_id=net_id, **kwargs)
|
||||
port = self.deserialize(self.fmt, res)
|
||||
ips = port['port']['fixed_ips']
|
||||
self.assertEqual(len(ips), 5)
|
||||
alloc = ['11.0.0.1', '11.0.0.2', '11.0.0.3', '11.0.0.4',
|
||||
'11.0.0.5']
|
||||
for ip in ips:
|
||||
self.assertIn(ip['ip_address'], alloc)
|
||||
self.assertEqual(ip['subnet_id'],
|
||||
subnet['subnet']['id'])
|
||||
alloc.remove(ip['ip_address'])
|
||||
self.assertEqual(len(alloc), 0)
|
||||
self._delete('ports', port['port']['id'])
|
||||
self.skipTest('Multiple fixed ips on a port are not supported')
|
||||
|
||||
def test_requested_subnet_id_v4_and_v6(self):
|
||||
with self.subnet(enable_dhcp=False) as subnet:
|
||||
# Get an IPv4 and IPv6 address
|
||||
tenant_id = subnet['subnet']['tenant_id']
|
||||
net_id = subnet['subnet']['network_id']
|
||||
res = self._create_subnet(
|
||||
self.fmt,
|
||||
tenant_id=tenant_id,
|
||||
net_id=net_id,
|
||||
cidr='2607:f0d0:1002:51::/124',
|
||||
ip_version=6,
|
||||
gateway_ip=constants.ATTR_NOT_SPECIFIED,
|
||||
enable_dhcp=False)
|
||||
subnet2 = self.deserialize(self.fmt, res)
|
||||
kwargs = {"fixed_ips":
|
||||
[{'subnet_id': subnet['subnet']['id']},
|
||||
{'subnet_id': subnet2['subnet']['id']}]}
|
||||
res = self._create_port(self.fmt, net_id=net_id, **kwargs)
|
||||
port3 = self.deserialize(self.fmt, res)
|
||||
ips = port3['port']['fixed_ips']
|
||||
cidr_v4 = subnet['subnet']['cidr']
|
||||
cidr_v6 = subnet2['subnet']['cidr']
|
||||
self.assertEqual(2, len(ips))
|
||||
self._test_requested_port_subnet_ids(ips,
|
||||
[subnet['subnet']['id'],
|
||||
subnet2['subnet']['id']])
|
||||
self._test_dual_stack_port_ip_addresses_in_subnets(ips,
|
||||
cidr_v4,
|
||||
cidr_v6)
|
||||
res = self._create_port(self.fmt, net_id=net_id)
|
||||
port4 = self.deserialize(self.fmt, res)
|
||||
# Check that a v4 and a v6 address are allocated
|
||||
ips = port4['port']['fixed_ips']
|
||||
self.assertEqual(len(ips), 2)
|
||||
self._test_requested_port_subnet_ids(ips,
|
||||
[subnet['subnet']['id'],
|
||||
subnet2['subnet']['id']])
|
||||
self._test_dual_stack_port_ip_addresses_in_subnets(ips,
|
||||
cidr_v4,
|
||||
cidr_v6)
|
||||
self._delete('ports', port3['port']['id'])
|
||||
self._delete('ports', port4['port']['id'])
|
||||
self.skipTest('Multiple fixed ips on a port are not supported')
|
||||
|
||||
def test_update_port_update_ip(self):
|
||||
"""Test update of port IP.
|
||||
@ -1496,36 +1404,47 @@ class TestPortsV2(NsxVPluginV2TestCase,
|
||||
old_ip,
|
||||
None, None)
|
||||
|
||||
def test_update_port_update_ip_address_only(self):
|
||||
with self.subnet(enable_dhcp=False) as subnet:
|
||||
ip_address = '10.0.0.2'
|
||||
fixed_ip_data = [{'ip_address': ip_address,
|
||||
'subnet_id': subnet['subnet']['id']}]
|
||||
with self.port(subnet=subnet, fixed_ips=fixed_ip_data) as port:
|
||||
ips = port['port']['fixed_ips']
|
||||
self.assertEqual(1, len(ips))
|
||||
self.assertEqual(ip_address, ips[0]['ip_address'])
|
||||
self.assertEqual(ips[0]['subnet_id'], subnet['subnet']['id'])
|
||||
data = {'port': {'fixed_ips': [{'subnet_id':
|
||||
subnet['subnet']['id'],
|
||||
'ip_address': "10.0.0.10"},
|
||||
{'ip_address': ip_address}]}}
|
||||
def test_update_port_add_additional_ip(self):
|
||||
"""Test update of port with additional IP fails."""
|
||||
with self.subnet() as subnet:
|
||||
with self.port(subnet=subnet) as port:
|
||||
data = {'port': {'admin_state_up': False,
|
||||
'fixed_ips': [{'subnet_id':
|
||||
subnet['subnet']['id']},
|
||||
{'subnet_id':
|
||||
subnet['subnet']['id']}]}}
|
||||
req = self.new_update_request('ports', data,
|
||||
port['port']['id'])
|
||||
res = self.deserialize(self.fmt, req.get_response(self.api))
|
||||
ips = res['port']['fixed_ips']
|
||||
self.assertEqual(2, len(ips))
|
||||
self.assertIn({'ip_address': ip_address,
|
||||
'subnet_id': subnet['subnet']['id']}, ips)
|
||||
self.assertIn({'ip_address': '10.0.0.10',
|
||||
'subnet_id': subnet['subnet']['id']}, ips)
|
||||
res = req.get_response(self.api)
|
||||
self.assertEqual(webob.exc.HTTPBadRequest.code,
|
||||
res.status_int)
|
||||
|
||||
def test_create_port_additional_ip(self):
|
||||
"""Test that creation of port with additional IP fails."""
|
||||
with self.subnet() as subnet:
|
||||
data = {'port': {'network_id': subnet['subnet']['network_id'],
|
||||
'tenant_id': subnet['subnet']['tenant_id'],
|
||||
'fixed_ips': [{'subnet_id':
|
||||
subnet['subnet']['id']},
|
||||
{'subnet_id':
|
||||
subnet['subnet']['id']}]}}
|
||||
port_req = self.new_create_request('ports', data)
|
||||
res = port_req.get_response(self.api)
|
||||
self.assertEqual(webob.exc.HTTPBadRequest.code,
|
||||
res.status_int)
|
||||
|
||||
def test_update_port_update_ip_address_only(self):
|
||||
self.skipTest('Multiple fixed ips on a port are not supported')
|
||||
|
||||
def test_requested_invalid_fixed_ips(self):
|
||||
self.skipTest('Multiple fixed ips on a port are not supported')
|
||||
|
||||
def test_requested_subnet_id_v4_and_v6_slaac(self):
|
||||
self.skipTest('Multiple fixed ips on a port are not supported')
|
||||
|
||||
def test_update_dhcp_port_with_exceeding_fixed_ips(self):
|
||||
self.skipTest('Updating dhcp port IP is not supported')
|
||||
|
||||
def test_requested_subnet_id_v4_and_v6_slaac(self):
|
||||
self.skipTest('No DHCP v6 Support yet')
|
||||
|
||||
def test_create_router_port_ipv4_and_ipv6_slaac_no_fixed_ips(self):
|
||||
self.skipTest('No DHCP v6 Support yet')
|
||||
|
||||
@ -2246,6 +2165,21 @@ class L3NatTest(test_l3_plugin.L3BaseForIntTests, NsxVPluginV2TestCase):
|
||||
def test_router_add_gateway_no_subnet(self):
|
||||
self.skipTest('No support for no subnet gateway set')
|
||||
|
||||
def test_floatingip_create_different_fixed_ip_same_port(self):
|
||||
self.skipTest('Multiple fixed ips on a port are not supported')
|
||||
|
||||
def test_router_add_interface_multiple_ipv4_subnet_port_returns_400(self):
|
||||
self.skipTest('Multiple fixed ips on a port are not supported')
|
||||
|
||||
def test_router_add_interface_multiple_ipv6_subnet_port(self):
|
||||
self.skipTest('Multiple fixed ips on a port are not supported')
|
||||
|
||||
def test_floatingip_update_different_fixed_ip_same_port(self):
|
||||
self.skipTest('Multiple fixed ips on a port are not supported')
|
||||
|
||||
def test_create_multiple_floatingips_same_fixed_ip_same_port(self):
|
||||
self.skipTest('Multiple fixed ips on a port are not supported')
|
||||
|
||||
def _set_net_external(self, net_id):
|
||||
self._update('networks', net_id,
|
||||
{'network': {external_net.EXTERNAL: True}})
|
||||
@ -2666,29 +2600,6 @@ class L3NatTestCaseBase(test_l3_plugin.L3NatTestCaseMixin):
|
||||
s2['subnet']['id'],
|
||||
None)
|
||||
|
||||
def test_router_add_interface_multiple_ipv6_subnet_port(self):
|
||||
"""A port with multiple IPv6 subnets can be added to a router
|
||||
|
||||
Create a port with multiple associated IPv6 subnets and attach
|
||||
it to a router. The action should succeed.
|
||||
"""
|
||||
with self.network() as n, self.router() as r:
|
||||
with self.subnet(network=n, cidr='fd00::/64',
|
||||
ip_version=6, enable_dhcp=False) as s1, (
|
||||
self.subnet(network=n, cidr='fd01::/64',
|
||||
ip_version=6, enable_dhcp=False)) as s2:
|
||||
fixed_ips = [{'subnet_id': s1['subnet']['id']},
|
||||
{'subnet_id': s2['subnet']['id']}]
|
||||
with self.port(subnet=s1, fixed_ips=fixed_ips) as p:
|
||||
self._router_interface_action('add',
|
||||
r['router']['id'],
|
||||
None,
|
||||
p['port']['id'])
|
||||
self._router_interface_action('remove',
|
||||
r['router']['id'],
|
||||
None,
|
||||
p['port']['id'])
|
||||
|
||||
def test_router_add_interface_ipv6_subnet_without_gateway_ip(self):
|
||||
with self.router() as r:
|
||||
with self.subnet(ip_version=6, cidr='fe80::/64',
|
||||
|
@ -765,49 +765,6 @@ class NsxNativeDhcpTestCase(test_plugin.NsxV3PluginTestCaseMixin):
|
||||
context.get_admin_context(), port['port']['id'], data)
|
||||
update_dhcp_binding.assert_not_called()
|
||||
|
||||
def test_dhcp_binding_with_multiple_ips(self):
|
||||
# Test create/update/delete DHCP binding with multiple IPs on a
|
||||
# compute port.
|
||||
with mock.patch.object(nsx_resources.LogicalDhcpServer,
|
||||
'create_binding',
|
||||
side_effect=[{"id": uuidutils.generate_uuid()},
|
||||
{"id": uuidutils.generate_uuid()}]
|
||||
) as create_dhcp_binding:
|
||||
with mock.patch.object(nsx_resources.LogicalDhcpServer,
|
||||
'update_binding'
|
||||
) as update_dhcp_binding:
|
||||
with mock.patch.object(nsx_resources.LogicalDhcpServer,
|
||||
'delete_binding'
|
||||
) as delete_dhcp_binding:
|
||||
with self.subnet(cidr='10.0.0.0/24', enable_dhcp=True
|
||||
) as subnet:
|
||||
device_owner = (constants.DEVICE_OWNER_COMPUTE_PREFIX +
|
||||
'None')
|
||||
device_id = uuidutils.generate_uuid()
|
||||
fixed_ips = [{'subnet_id': subnet['subnet']['id'],
|
||||
'ip_address': '10.0.0.3'},
|
||||
{'subnet_id': subnet['subnet']['id'],
|
||||
'ip_address': '10.0.0.4'}]
|
||||
with self.port(subnet=subnet,
|
||||
device_owner=device_owner,
|
||||
device_id=device_id,
|
||||
fixed_ips=fixed_ips) as port:
|
||||
self.assertEqual(create_dhcp_binding.call_count, 2)
|
||||
new_fixed_ips = [
|
||||
{'subnet_id': subnet['subnet']['id'],
|
||||
'ip_address': '10.0.0.5'},
|
||||
{'subnet_id': subnet['subnet']['id'],
|
||||
'ip_address': '10.0.0.6'}]
|
||||
self.plugin.update_port(
|
||||
context.get_admin_context(),
|
||||
port['port']['id'],
|
||||
{'port': {'fixed_ips': new_fixed_ips}})
|
||||
self.assertEqual(update_dhcp_binding.call_count, 2)
|
||||
self.plugin.delete_port(
|
||||
context.get_admin_context(),
|
||||
port['port']['id'])
|
||||
self.assertEqual(delete_dhcp_binding.call_count, 2)
|
||||
|
||||
def test_create_network_with_bad_az_hint(self):
|
||||
p = directory.get_plugin()
|
||||
ctx = context.get_admin_context()
|
||||
|
@ -282,6 +282,12 @@ class TestSubnetsV2(test_plugin.TestSubnetsV2, NsxV3PluginTestCaseMixin):
|
||||
self.plugin.create_subnet,
|
||||
context.get_admin_context(), data)
|
||||
|
||||
def test_subnet_update_ipv4_and_ipv6_pd_v6stateless_subnets(self):
|
||||
self.skipTest('Multiple fixed ips on a port are not supported')
|
||||
|
||||
def test_subnet_update_ipv4_and_ipv6_pd_slaac_subnets(self):
|
||||
self.skipTest('Multiple fixed ips on a port are not supported')
|
||||
|
||||
|
||||
class TestPortsV2(test_plugin.TestPortsV2, NsxV3PluginTestCaseMixin,
|
||||
test_bindings.PortBindingsTestCase,
|
||||
@ -502,6 +508,59 @@ class TestPortsV2(test_plugin.TestPortsV2, NsxV3PluginTestCaseMixin,
|
||||
networks = self.plugin.get_ports(ctx)
|
||||
self.assertListEqual([], networks)
|
||||
|
||||
def test_update_port_add_additional_ip(self):
|
||||
"""Test update of port with additional IP fails."""
|
||||
with self.subnet() as subnet:
|
||||
with self.port(subnet=subnet) as port:
|
||||
data = {'port': {'admin_state_up': False,
|
||||
'fixed_ips': [{'subnet_id':
|
||||
subnet['subnet']['id']},
|
||||
{'subnet_id':
|
||||
subnet['subnet']['id']}]}}
|
||||
req = self.new_update_request('ports', data,
|
||||
port['port']['id'])
|
||||
res = req.get_response(self.api)
|
||||
self.assertEqual(exc.HTTPBadRequest.code,
|
||||
res.status_int)
|
||||
|
||||
def test_create_port_additional_ip(self):
|
||||
"""Test that creation of port with additional IP fails."""
|
||||
with self.subnet() as subnet:
|
||||
data = {'port': {'network_id': subnet['subnet']['network_id'],
|
||||
'tenant_id': subnet['subnet']['tenant_id'],
|
||||
'fixed_ips': [{'subnet_id':
|
||||
subnet['subnet']['id']},
|
||||
{'subnet_id':
|
||||
subnet['subnet']['id']}]}}
|
||||
port_req = self.new_create_request('ports', data)
|
||||
res = port_req.get_response(self.api)
|
||||
self.assertEqual(exc.HTTPBadRequest.code,
|
||||
res.status_int)
|
||||
|
||||
def test_update_port_update_ip_address_only(self):
|
||||
self.skipTest('Multiple fixed ips on a port are not supported')
|
||||
|
||||
def test_update_port_with_new_ipv6_slaac_subnet_in_fixed_ips(self):
|
||||
self.skipTest('Multiple fixed ips on a port are not supported')
|
||||
|
||||
def test_update_port_mac_v6_slaac(self):
|
||||
self.skipTest('Multiple fixed ips on a port are not supported')
|
||||
|
||||
def test_requested_subnet_id_v4_and_v6(self):
|
||||
self.skipTest('Multiple fixed ips on a port are not supported')
|
||||
|
||||
def test_requested_invalid_fixed_ips(self):
|
||||
self.skipTest('Multiple fixed ips on a port are not supported')
|
||||
|
||||
def test_requested_subnet_id_v4_and_v6_slaac(self):
|
||||
self.skipTest('Multiple fixed ips on a port are not supported')
|
||||
|
||||
def test_range_allocation(self):
|
||||
self.skipTest('Multiple fixed ips on a port are not supported')
|
||||
|
||||
def test_create_port_anticipating_allocation(self):
|
||||
self.skipTest('Multiple fixed ips on a port are not supported')
|
||||
|
||||
|
||||
class DHCPOptsTestCase(test_dhcpopts.TestExtraDhcpOpt,
|
||||
NsxV3PluginTestCaseMixin):
|
||||
@ -588,6 +647,21 @@ class L3NatTest(test_l3_plugin.L3BaseForIntTests, NsxV3PluginTestCaseMixin,
|
||||
self.plugin_instance.__class__.__name__)
|
||||
self._plugin_class = self.plugin_instance.__class__
|
||||
|
||||
def test_floatingip_create_different_fixed_ip_same_port(self):
|
||||
self.skipTest('Multiple fixed ips on a port are not supported')
|
||||
|
||||
def test_router_add_interface_multiple_ipv4_subnet_port_returns_400(self):
|
||||
self.skipTest('Multiple fixed ips on a port are not supported')
|
||||
|
||||
def test_router_add_interface_multiple_ipv6_subnet_port(self):
|
||||
self.skipTest('Multiple fixed ips on a port are not supported')
|
||||
|
||||
def test_floatingip_update_different_fixed_ip_same_port(self):
|
||||
self.skipTest('Multiple fixed ips on a port are not supported')
|
||||
|
||||
def test_create_multiple_floatingips_same_fixed_ip_same_port(self):
|
||||
self.skipTest('Multiple fixed ips on a port are not supported')
|
||||
|
||||
|
||||
class TestL3NatTestCase(L3NatTest,
|
||||
test_l3_plugin.L3NatDBIntTestCase,
|
||||
|
Loading…
Reference in New Issue
Block a user