Merge "Hide IPv6-addresses when assigning floating IP addresses"

This commit is contained in:
Zuul 2017-10-21 00:38:17 +00:00 committed by Gerrit Code Review
commit 842e2cdd0c
6 changed files with 101 additions and 38 deletions

View File

@ -669,6 +669,9 @@ class FloatingIpManager(object):
for ip in p.fixed_ips:
if ip['subnet_id'] not in reachable_subnets:
continue
# Floating IPs can only target IPv4 addresses.
if netaddr.IPAddress(ip['ip_address']).version != 4:
continue
targets.append(FloatingIpTarget(p, ip['ip_address'],
server_name))
return targets

View File

@ -175,7 +175,7 @@ class NetworkSubnetTests(test.TestCase):
'subnetpool_list')})
def test_subnet_create_post_with_additional_attributes(self):
network = self.networks.list()[1]
subnet = self.subnets.list()[1]
subnet = self.subnets.list()[2]
api.neutron.network_get(IsA(http.HttpRequest),
network.id)\
.AndReturn(self.networks.first())
@ -951,7 +951,7 @@ class NetworkSubnetTests(test.TestCase):
'is_extension_supported',
'subnetpool_list')})
def test_subnet_update_post_with_additional_attributes(self):
subnet = self.subnets.list()[1]
subnet = self.subnets.list()[2]
api.neutron.subnet_get(IsA(http.HttpRequest), subnet.id)\
.AndReturn(subnet)
api.neutron.subnet_get(IsA(http.HttpRequest), subnet.id)\

View File

@ -685,7 +685,7 @@ class NetworkTests(test.TestCase, NetworkStubMixin):
test_with_subnetpool=False
):
network = self.networks.first()
subnet_v6 = self.subnets.list()[3]
subnet_v6 = self.subnets.list()[4]
api.neutron.is_extension_supported(IsA(http.HttpRequest),
'subnet_allocation').\
@ -936,12 +936,14 @@ class NetworkTests(test.TestCase, NetworkStubMixin):
network = self.networks.first()
network.subnets = [subnet.id for subnet in network.subnets]
subnet_id = network.subnets[0]
subnetv6_id = network.subnets[1]
api.neutron.network_get(IsA(http.HttpRequest),
network.id,
expand_subnet=False)\
.AndReturn(network)
self._stub_net_list()
api.neutron.subnet_delete(IsA(http.HttpRequest), subnet_id)
api.neutron.subnet_delete(IsA(http.HttpRequest), subnetv6_id)
api.neutron.network_delete(IsA(http.HttpRequest), network.id)
self.mox.ReplayAll()
@ -959,12 +961,14 @@ class NetworkTests(test.TestCase, NetworkStubMixin):
network = self.networks.first()
network.subnets = [subnet.id for subnet in network.subnets]
subnet_id = network.subnets[0]
subnetv6_id = network.subnets[1]
api.neutron.network_get(IsA(http.HttpRequest),
network.id,
expand_subnet=False)\
.AndReturn(network)
self._stub_net_list()
api.neutron.subnet_delete(IsA(http.HttpRequest), subnet_id)
api.neutron.subnet_delete(IsA(http.HttpRequest), subnetv6_id)
api.neutron.network_delete(IsA(http.HttpRequest), network.id)\
.AndRaise(self.exceptions.neutron)

View File

@ -14,6 +14,8 @@
import collections
import netaddr
from django.test.utils import override_settings
from openstack_dashboard import api
@ -34,23 +36,24 @@ class NetworkApiNeutronTests(NetworkApiNeutronTestBase):
for p in server_ports:
net_name = self.networks.get(id=p['network_id']).name
for ip in p.fixed_ips:
version = netaddr.IPAddress(ip['ip_address']).version
addresses[net_name].append(
{'version': 4,
{'version': version,
'addr': ip['ip_address'],
'OS-EXT-IPS-MAC:mac_addr': p.mac_address,
'OS-EXT-IPS:type': 'fixed'})
if no_fip_expected:
continue
fips = self.floating_ips.filter(port_id=p['id'])
if not fips:
continue
# Only one FIP should match.
fip = fips[0]
addresses[net_name].append(
{'version': 4,
'addr': fip.floating_ip_address,
'OS-EXT-IPS-MAC:mac_addr': p.mac_address,
'OS-EXT-IPS:type': 'floating'})
if no_fip_expected:
continue
fips = self.floating_ips.filter(port_id=p['id'])
if not fips:
continue
# Only one FIP should match.
fip = fips[0]
addresses[net_name].append(
{'version': 4,
'addr': fip.floating_ip_address,
'OS-EXT-IPS-MAC:mac_addr': p.mac_address,
'OS-EXT-IPS:type': 'floating'})
return addresses
def _check_server_address(self, res_server_data, no_fip_expected=False):
@ -105,12 +108,14 @@ class NetworkApiNeutronTests(NetworkApiNeutronTestBase):
# The expected is also calculated, we examine the result manually once.
addrs = servers[0].addresses['net1']
if router_enabled:
self.assertEqual(3, len(addrs))
self.assertEqual('fixed', addrs[0]['OS-EXT-IPS:type'])
self.assertEqual('fixed', addrs[1]['OS-EXT-IPS:type'])
self.assertEqual('floating', addrs[2]['OS-EXT-IPS:type'])
else:
self.assertEqual(2, len(addrs))
self.assertEqual('fixed', addrs[0]['OS-EXT-IPS:type'])
self.assertEqual('floating', addrs[1]['OS-EXT-IPS:type'])
else:
self.assertEqual(1, len(addrs))
self.assertEqual('fixed', addrs[0]['OS-EXT-IPS:type'])
self.assertEqual('fixed', addrs[1]['OS-EXT-IPS:type'])
# server[1] has one fixed IP.
self._check_server_address(servers[1], no_fip_expected)

View File

@ -14,6 +14,7 @@
import copy
from mox3.mox import IsA
import netaddr
from neutronclient.common import exceptions as neutron_exc
from oslo_utils import uuidutils
import six
@ -165,17 +166,20 @@ class NeutronApiTests(test.APITestCase):
def test_network_get(self):
network = {'network': self.api_networks.first()}
subnet = {'subnet': self.api_subnets.first()}
subnetv6 = {'subnet': self.api_subnets.list()[1]}
network_id = self.api_networks.first()['id']
subnet_id = self.api_networks.first()['subnets'][0]
subnetv6_id = self.api_networks.first()['subnets'][1]
neutronclient = self.stub_neutronclient()
neutronclient.show_network(network_id).AndReturn(network)
neutronclient.show_subnet(subnet_id).AndReturn(subnet)
neutronclient.show_subnet(subnetv6_id).AndReturn(subnetv6)
self.mox.ReplayAll()
ret_val = api.neutron.network_get(self.request, network_id)
self.assertIsInstance(ret_val, api.neutron.Network)
self.assertEqual(1, len(ret_val['subnets']))
self.assertEqual(2, len(ret_val['subnets']))
self.assertIsInstance(ret_val['subnets'][0], api.neutron.Subnet)
def test_network_get_with_subnet_get_notfound(self):
@ -190,7 +194,7 @@ class NeutronApiTests(test.APITestCase):
ret_val = api.neutron.network_get(self.request, network_id)
self.assertIsInstance(ret_val, api.neutron.Network)
self.assertEqual(1, len(ret_val['subnets']))
self.assertEqual(2, len(ret_val['subnets']))
self.assertNotIsInstance(ret_val['subnets'][0], api.neutron.Subnet)
self.assertIsInstance(ret_val['subnets'][0], str)
@ -1160,19 +1164,16 @@ class NeutronApiFloatingIpTests(NeutronApiTestBase):
api.neutron.floating_ip_disassociate(self.request, fip['id'])
def _get_target_id(self, port):
def _get_target_id(self, port, ip=None):
param = {'id': port['id'],
'addr': port['fixed_ips'][0]['ip_address']}
'addr': ip or port['fixed_ips'][0]['ip_address']}
return '%(id)s_%(addr)s' % param
def _get_target_name(self, port):
def _get_target_name(self, port, ip=None):
param = {'svrid': port['device_id'],
'addr': port['fixed_ips'][0]['ip_address']}
'addr': ip or port['fixed_ips'][0]['ip_address']}
return 'server_%(svrid)s: %(addr)s' % param
def _subs_from_port(self, port):
return [ip['subnet_id'] for ip in port['fixed_ips']]
@override_settings(
OPENSTACK_NEUTRON_NETWORK={
'enable_fip_topology_check': True,
@ -1185,12 +1186,20 @@ class NeutronApiFloatingIpTests(NeutronApiTestBase):
subnet_id = self.subnets.first().id
shared_nets = [n for n in self.api_networks.list() if n['shared']]
shared_subnet_ids = [s for n in shared_nets for s in n['subnets']]
target_ports = [
(self._get_target_id(p), self._get_target_name(p)) for p in ports
if (not p['device_owner'].startswith('network:') and
(subnet_id in self._subs_from_port(p) or
(set(shared_subnet_ids) & set(self._subs_from_port(p)))))
]
target_ports = []
for p in ports:
if p['device_owner'].startswith('network:'):
continue
port_subnets = [ip['subnet_id'] for ip in p['fixed_ips']]
if not (subnet_id in port_subnets or
(set(shared_subnet_ids) & set(port_subnets))):
continue
for ip in p['fixed_ips']:
if netaddr.IPAddress(ip['ip_address']).version != 4:
continue
target_ports.append((
self._get_target_id(p, ip['ip_address']),
self._get_target_name(p, ip['ip_address'])))
filters = {'tenant_id': self.request.user.tenant_id}
self.qclient.list_ports(**filters).AndReturn({'ports': ports})
servers = self.servers.list()
@ -1219,6 +1228,8 @@ class NeutronApiFloatingIpTests(NeutronApiTestBase):
rets = api.neutron.floating_ip_target_list(self.request)
self.assertEqual(len(target_ports), len(rets))
for ret, exp in zip(rets, target_ports):
pid, ip_address = ret.id.split('_', 1)
self.assertEqual(4, netaddr.IPAddress(ip['ip_address']).version)
self.assertEqual(exp[0], ret.id)
self.assertEqual(exp[1], ret.name)

View File

@ -75,7 +75,8 @@ def data(TEST):
'id': '82288d84-e0a5-42ac-95be-e6af08727e42',
'name': 'net1',
'status': 'ACTIVE',
'subnets': ['e8abc972-eb0c-41f1-9edd-4bc6e3bcd8c9'],
'subnets': ['e8abc972-eb0c-41f1-9edd-4bc6e3bcd8c9',
'41e53a49-442b-4307-9e9a-88967a6b6657'],
'tenant_id': '1',
'router:external': False,
'shared': False}
@ -91,15 +92,34 @@ def data(TEST):
'name': 'mysubnet1',
'network_id': network_dict['id'],
'tenant_id': network_dict['tenant_id']}
subnetv6_dict = {
'allocation_pools': [{'start': 'fdb6:b88a:488e::2',
'end': 'fdb6:b88a:488e:0:ffff:ffff:ffff:ffff'}],
'dns_nameservers': [],
'host_routes': [],
'cidr': 'fdb6:b88a:488e::/64',
'enable_dhcp': True,
'gateway_ip': 'fdb6:b88a:488e::1',
'id': network_dict['subnets'][1],
'ip_version': 6,
'name': 'myv6subnet',
'network_id': network_dict['id'],
'tenant_id': network_dict['tenant_id'],
'ipv6_ra_mode': 'slaac',
'ipv6_address_mode': 'slaac'
}
TEST.api_networks.add(network_dict)
TEST.api_subnets.add(subnet_dict)
TEST.api_subnets.add(subnetv6_dict)
network = copy.deepcopy(network_dict)
subnet = neutron.Subnet(subnet_dict)
network['subnets'] = [subnet]
subnetv6 = neutron.Subnet(subnetv6_dict)
network['subnets'] = [subnet, subnetv6]
TEST.networks.add(neutron.Network(network))
TEST.subnets.add(subnet)
TEST.subnets.add(subnetv6)
# Ports on 1st network.
port_dict = {
@ -131,7 +151,9 @@ def data(TEST):
'device_id': '1',
'device_owner': 'compute:nova',
'fixed_ips': [{'ip_address': '10.0.0.4',
'subnet_id': subnet_dict['id']}],
'subnet_id': subnet_dict['id']},
{'ip_address': 'fdb6:b88a:488e:0:f816:3eff:fe9d:e62f',
'subnet_id': subnetv6_dict['id']}],
'id': '7e6ce62c-7ea2-44f8-b6b4-769af90a8406',
'mac_address': 'fa:16:3e:9d:e6:2f',
'name': '',
@ -169,6 +191,24 @@ def data(TEST):
}
TEST.api_ports.add(port_dict)
TEST.ports.add(neutron.Port(port_dict))
port_dict = {
'admin_state_up': True,
'device_id': '279989f7-54bb-41d9-ba42-0d61f12fda61',
'device_owner': 'network:router_interface',
'fixed_ips': [{'ip_address': 'fdb6:b88a:488e::1',
'subnet_id': subnetv6_dict['id']}],
'id': '8047e0d5-5ef5-4b6e-a1a7-d3a52ad980f7',
'mac_address': 'fa:16:3e:69:6e:e9',
'name': '',
'network_id': network_dict['id'],
'status': 'ACTIVE',
'tenant_id': network_dict['tenant_id'],
'binding:vnic_type': 'normal',
'binding:host_id': 'host',
'security_groups': [],
}
TEST.api_ports.add(port_dict)
TEST.ports.add(neutron.Port(port_dict))
# 2nd network.
network_dict = {'admin_state_up': True,