Base auto_ip on interface_ip not public_v4

Currently the auto_ip logic checks for a public v4 address to determine
if it should make a FIP. However, we have richer logic that provides
interface_ip that takes in to account IPv6 as well as configured choices
as to what the "default" network should be. That is what should really
be cared about - does the server have an ip that would be considered the
thing to connect to it on.

Change-Id: Ica1feb31cc3477c6336a749c88f4706efd20484f
This commit is contained in:
Monty Taylor 2016-08-12 14:34:43 -05:00
parent 4bdda71fc5
commit 53b1fc4cde
No known key found for this signature in database
GPG Key ID: 7BAE94BC7141A594
3 changed files with 127 additions and 2 deletions

View File

@ -0,0 +1,13 @@
---
fixes:
- shade now correctly does not try to attach a floating ip with auto_ip
if the cloud has given a public IPv6 address and the calling context
supports IPv6 routing. shade has always used this logic to determine
the server 'interface_ip', but the auto floating ip was incorrectly only
looking at the 'public_v4' value to determine whether the server needed
additional networking.
upgrade:
- If your cloud presents a default split IPv4/IPv6 stack with a public
v6 and a private v4 address and you have the expectation that auto_ip
should procure a v4 floating ip, you need to set 'force_ipv4' to True in
your clouds.yaml entry for the cloud.

View File

@ -4028,7 +4028,7 @@ class OpenStackCloud(object):
"""
server = self._add_auto_ip(
server, wait=wait, timeout=timeout, reuse=reuse)
return self.get_server_public_ip(server)
return server['interface_ip'] or None
def _add_auto_ip(self, server, wait=False, timeout=60, reuse=True):
skip_attach = False
@ -4091,7 +4091,7 @@ class OpenStackCloud(object):
server, ips, wait=wait, timeout=timeout,
fixed_address=fixed_address)
elif auto_ip:
if not self.get_server_public_ip(server):
if not server['interface_ip']:
server = self._add_auto_ip(
server, wait=wait, timeout=timeout, reuse=reuse)
return server

View File

@ -80,6 +80,118 @@ class TestFloatingIP(base.TestCase):
server_dict, pool, reuse=True, wait=False, timeout=60,
fixed_address=None, nat_destination=None)
@patch.object(OpenStackCloud, 'has_service')
@patch.object(OpenStackCloud, 'get_floating_ip')
@patch.object(OpenStackCloud, '_add_auto_ip')
def test_add_ips_to_server_ipv6_only(
self, mock_add_auto_ip,
mock_get_floating_ip,
mock_has_service):
self.cloud._floating_ip_source = None
self.cloud.force_ipv4 = False
self.cloud._local_ipv6 = True
mock_has_service.return_value = False
server = FakeServer(
id='server-id', name='test-server', status="ACTIVE",
addresses={
'private': [{
'addr': "10.223.160.141",
'version': 4
}],
'public': [{
u'OS-EXT-IPS-MAC:mac_addr': u'fa:16:3e:ae:7d:42',
u'OS-EXT-IPS:type': u'fixed',
'addr': "2001:4800:7819:103:be76:4eff:fe05:8525",
'version': 6
}]
}
)
server_dict = meta.add_server_interfaces(
self.cloud, meta.obj_to_dict(server))
new_server = self.client.add_ips_to_server(server=server_dict)
mock_get_floating_ip.assert_not_called()
mock_add_auto_ip.assert_not_called()
self.assertEqual(
new_server['interface_ip'],
'2001:4800:7819:103:be76:4eff:fe05:8525')
self.assertEqual(new_server['private_v4'], '10.223.160.141')
self.assertEqual(new_server['public_v4'], '')
self.assertEqual(
new_server['public_v6'], '2001:4800:7819:103:be76:4eff:fe05:8525')
@patch.object(OpenStackCloud, 'has_service')
@patch.object(OpenStackCloud, 'get_floating_ip')
@patch.object(OpenStackCloud, '_add_auto_ip')
def test_add_ips_to_server_rackspace(
self, mock_add_auto_ip,
mock_get_floating_ip,
mock_has_service):
self.cloud._floating_ip_source = None
self.cloud.force_ipv4 = False
self.cloud._local_ipv6 = True
mock_has_service.return_value = False
server = FakeServer(
id='server-id', name='test-server', status="ACTIVE",
addresses={
'private': [{
'addr': "10.223.160.141",
'version': 4
}],
'public': [{
'addr': "104.130.246.91",
'version': 4
}, {
'addr': "2001:4800:7819:103:be76:4eff:fe05:8525",
'version': 6
}]
}
)
server_dict = meta.add_server_interfaces(
self.cloud, meta.obj_to_dict(server))
new_server = self.client.add_ips_to_server(server=server_dict)
mock_get_floating_ip.assert_not_called()
mock_add_auto_ip.assert_not_called()
self.assertEqual(
new_server['interface_ip'],
'2001:4800:7819:103:be76:4eff:fe05:8525')
@patch.object(OpenStackCloud, 'has_service')
@patch.object(OpenStackCloud, 'get_floating_ip')
@patch.object(OpenStackCloud, '_add_auto_ip')
def test_add_ips_to_server_rackspace_local_ipv4(
self, mock_add_auto_ip,
mock_get_floating_ip,
mock_has_service):
self.cloud._floating_ip_source = None
self.cloud.force_ipv4 = False
self.cloud._local_ipv6 = False
mock_has_service.return_value = False
server = FakeServer(
id='server-id', name='test-server', status="ACTIVE",
addresses={
'private': [{
'addr': "10.223.160.141",
'version': 4
}],
'public': [{
'addr': "104.130.246.91",
'version': 4
}, {
'addr': "2001:4800:7819:103:be76:4eff:fe05:8525",
'version': 6
}]
}
)
server_dict = meta.add_server_interfaces(
self.cloud, meta.obj_to_dict(server))
new_server = self.client.add_ips_to_server(server=server_dict)
mock_get_floating_ip.assert_not_called()
mock_add_auto_ip.assert_not_called()
self.assertEqual(new_server['interface_ip'], '104.130.246.91')
@patch.object(OpenStackCloud, 'nova_client')
@patch.object(OpenStackCloud, 'add_ip_list')
def test_add_ips_to_server_ip_list(