Add floating IPs to server dict ourselves

The nova/neutron interaction as it relates to updating the network info
cache in nova apparently does not believe in an object reality and
instead prefers to think of things as unrealized quantum superpositions.
While those are great for particle physics, they make getting the
address of the server hard. It therefore follows that we should
undertake the burden of providing consistent and objective information
about the floating ip of the server ourselves, regardless of the sadness
this adds to the world.

Change-Id: I75ba0318c9a5a011b5a530d86ace275f19511f1f
This commit is contained in:
Monty Taylor 2016-05-12 13:28:25 -05:00 committed by Ricardo Carrillo Cruz
parent 8481c6baa2
commit 7dd138c8f4
4 changed files with 64 additions and 5 deletions

View File

@ -277,6 +277,32 @@ def expand_server_vars(cloud, server):
return add_server_interfaces(cloud, server)
def _make_address_dict(fip):
address = dict(version=4, addr=fip['floating_ip_address'])
address['OS-EXT-IPS:type'] = 'floating'
# MAC address comes from the port, not the FIP. It also doesn't matter
# to anyone at the moment, so just make a fake one
address['OS-EXT-IPS-MAC:mac_addr'] = 'de:ad:be:ef:be:ef'
return address
def _get_suplemental_addresses(cloud, server):
fixed_ip_mapping = {}
for name, network in server['addresses'].items():
for address in network:
if address['version'] == 6:
continue
if address['OS-EXT-IPS:type'] == 'floating':
# We have a floating IP that nova knows about, do nothing
return server['addresses']
fixed_ip_mapping[address['addr']] = name
for fip in cloud.list_floating_ips():
if fip['fixed_ip_address'] in fixed_ip_mapping:
fixed_net = fixed_ip_mapping[fip['fixed_ip_address']]
server['addresses'][fixed_net].append(_make_address_dict(fip))
return server['addresses']
def add_server_interfaces(cloud, server):
"""Add network interface information to server.
@ -288,6 +314,7 @@ def add_server_interfaces(cloud, server):
"""
# First, add an IP address. Set it to '' rather than None if it does
# not exist to remain consistent with the pre-existing missing values
server['addresses'] = _get_suplemental_addresses(cloud, server)
server['public_v4'] = get_server_external_ipv4(cloud, server) or ''
server['public_v6'] = get_server_external_ipv6(server) or ''
server['private_v4'] = get_server_private_ip(server, cloud) or ''

View File

@ -92,11 +92,15 @@ class TestCreateServer(base.TestCase):
with patch("shade.OpenStackCloud"):
build_server = fakes.FakeServer('1234', '', 'BUILD')
error_server = fakes.FakeServer('1234', '', 'ERROR')
fake_floating_ip = fakes.FakeFloatingIP('1234', 'ippool',
'1.1.1.1', '2.2.2.2',
'5678')
config = {
"servers.create.return_value": build_server,
"servers.get.return_value": build_server,
"servers.list.side_effect": [
[build_server], [error_server]]
[build_server], [error_server]],
"floating_ips.list.return_value": [fake_floating_ip]
}
OpenStackCloud.nova_client = Mock(**config)
self.assertRaises(
@ -129,9 +133,13 @@ class TestCreateServer(base.TestCase):
"""
with patch("shade.OpenStackCloud"):
fake_server = fakes.FakeServer('1234', '', 'BUILD')
fake_floating_ip = fakes.FakeFloatingIP('1234', 'ippool',
'1.1.1.1', '2.2.2.2',
'5678')
config = {
"servers.create.return_value": fake_server,
"servers.get.return_value": fake_server
"servers.get.return_value": fake_server,
"floating_ips.list.return_value": [fake_floating_ip]
}
OpenStackCloud.nova_client = Mock(**config)
self.assertEqual(
@ -151,9 +159,13 @@ class TestCreateServer(base.TestCase):
fake_server = fakes.FakeServer('1234', '', 'BUILD')
fake_create_server = fakes.FakeServer('1234', '', 'BUILD',
adminPass='ooBootheiX0edoh')
fake_floating_ip = fakes.FakeFloatingIP('1234', 'ippool',
'1.1.1.1', '2.2.2.2',
'5678')
config = {
"servers.create.return_value": fake_create_server,
"servers.get.return_value": fake_server
"servers.get.return_value": fake_server,
"floating_ips.list.return_value": [fake_floating_ip]
}
OpenStackCloud.nova_client = Mock(**config)
self.assertEqual(
@ -256,12 +268,16 @@ class TestCreateServer(base.TestCase):
with patch("shade.OpenStackCloud"):
build_server = fakes.FakeServer('1234', '', 'BUILD')
fake_server = fakes.FakeServer('1234', '', 'ACTIVE')
fake_floating_ip = fakes.FakeFloatingIP('1234', 'ippool',
'1.1.1.1', '2.2.2.2',
'5678')
config = {
"servers.create.return_value": build_server,
"servers.get.return_value": [build_server, None],
"servers.list.side_effect": [
[build_server], [fake_server]],
"servers.delete.return_value": None,
"floating_ips.list.return_value": [fake_floating_ip]
}
OpenStackCloud.nova_client = Mock(**config)
self.client._SERVER_AGE = 0

View File

@ -182,6 +182,7 @@ class TestMeta(base.TestCase):
mock_has_service.assert_called_with('network')
mock_list_networks.assert_called_once_with()
@mock.patch.object(shade.OpenStackCloud, 'list_floating_ips')
@mock.patch.object(shade.OpenStackCloud, 'list_subnets')
@mock.patch.object(shade.OpenStackCloud, 'list_server_security_groups')
@mock.patch.object(shade.OpenStackCloud, 'get_volumes')
@ -194,7 +195,8 @@ class TestMeta(base.TestCase):
mock_get_flavor_name, mock_get_image_name,
mock_get_volumes,
mock_list_server_security_groups,
mock_list_subnets):
mock_list_subnets,
mock_list_floating_ips):
mock_get_image_name.return_value = 'cirros-0.3.4-x86_64-uec'
mock_get_flavor_name.return_value = 'm1.tiny'
mock_has_service.return_value = True
@ -211,6 +213,7 @@ class TestMeta(base.TestCase):
'name': 'private',
},
]
mock_list_floating_ips.return_value = []
srv = self.cloud.get_openstack_vars(meta.obj_to_dict(fakes.FakeServer(
id='test-id', name='test-name', status='ACTIVE',
@ -230,6 +233,7 @@ class TestMeta(base.TestCase):
self.assertEqual(PRIVATE_V4, srv['private_v4'])
mock_has_service.assert_called_with('volume')
mock_list_networks.assert_called_once_with()
mock_list_floating_ips.assert_called_once_with()
@mock.patch.object(shade.OpenStackCloud, 'has_service')
@mock.patch.object(shade.OpenStackCloud, 'list_subnets')

View File

@ -56,10 +56,14 @@ class TestRebuildServer(base.TestCase):
"""
rebuild_server = fakes.FakeServer('1234', '', 'REBUILD')
error_server = fakes.FakeServer('1234', '', 'ERROR')
fake_floating_ip = fakes.FakeFloatingIP('1234', 'ippool',
'1.1.1.1', '2.2.2.2',
'5678')
with patch("shade.OpenStackCloud"):
config = {
"servers.rebuild.return_value": rebuild_server,
"servers.get.return_value": error_server,
"floating_ips.list.return_value": [fake_floating_ip]
}
OpenStackCloud.nova_client = Mock(**config)
self.assertRaises(
@ -122,9 +126,13 @@ class TestRebuildServer(base.TestCase):
active_server = fakes.FakeServer('1234', '', 'ACTIVE')
ret_active_server = fakes.FakeServer('1234', '', 'ACTIVE',
adminPass='ooBootheiX0edoh')
fake_floating_ip = fakes.FakeFloatingIP('1234', 'ippool',
'1.1.1.1', '2.2.2.2',
'5678')
config = {
"servers.rebuild.return_value": rebuild_server,
"servers.get.return_value": active_server,
"floating_ips.list.return_value": [fake_floating_ip]
}
OpenStackCloud.nova_client = Mock(**config)
self.client.name = 'cloud-name'
@ -143,9 +151,13 @@ class TestRebuildServer(base.TestCase):
with patch("shade.OpenStackCloud"):
rebuild_server = fakes.FakeServer('1234', '', 'REBUILD')
active_server = fakes.FakeServer('1234', '', 'ACTIVE')
fake_floating_ip = fakes.FakeFloatingIP('1234', 'ippool',
'1.1.1.1', '2.2.2.2',
'5678')
config = {
"servers.rebuild.return_value": rebuild_server,
"servers.get.return_value": active_server
"servers.get.return_value": active_server,
"floating_ips.list.return_value": [fake_floating_ip]
}
OpenStackCloud.nova_client = Mock(**config)
self.client.name = 'cloud-name'