summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVishvananda Ishaya <vishvananda@gmail.com>2013-03-19 14:38:56 -0700
committerVishvananda Ishaya <vishvananda@gmail.com>2013-03-19 15:56:53 -0700
commit32cd2fee38a4c3aec02615a2144eee65109b5734 (patch)
treee95e0c5bc8dd922de976a9cc7d9d3916d7c65068
parent07694d4ffa2b64b7cb21d76af70b8f0df1166915 (diff)
downloadnova-32cd2fee38a4c3aec02615a2144eee65109b5734.tar.gz
Update the network info when using quantum.
The network info cache in quantum was not updated with floating ips. Also it wasn't updated properly updating the network info cache during some operations that changed it. This adds floating ips and updates the cache properly. Fixes bug 1108975 Change-Id: I9e9c211d014f9671d724cded1fb9a74313c458b6
-rw-r--r--nova/network/quantumv2/api.py34
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_quantum_security_groups.py3
-rw-r--r--nova/tests/network/test_quantumv2.py44
3 files changed, 65 insertions, 16 deletions
diff --git a/nova/network/quantumv2/api.py b/nova/network/quantumv2/api.py
index 53e22c077e..b7e44b4369 100644
--- a/nova/network/quantumv2/api.py
+++ b/nova/network/quantumv2/api.py
@@ -125,6 +125,7 @@ class API(base.Base):
return nets
+ @refresh_cache
def allocate_for_instance(self, context, instance, **kwargs):
"""Allocate network resources for the instance.
@@ -280,8 +281,7 @@ class API(base.Base):
self.trigger_security_group_members_refresh(context, instance)
self.trigger_instance_add_security_group_refresh(context, instance)
- nw_info = self.get_instance_nw_info(context, instance, networks=nets,
- conductor_api=kwargs.get('conductor_api'))
+ nw_info = self._get_instance_nw_info(context, instance, networks=nets)
# NOTE(danms): Only return info about ports we created in this run.
# In the initial allocation case, this will be everything we created,
# and in later runs will only be what was created that time. Thus,
@@ -324,6 +324,7 @@ class API(base.Base):
self.trigger_security_group_members_refresh(context, instance)
self.trigger_instance_remove_security_group_refresh(context, instance)
+ @refresh_cache
def allocate_port_for_instance(self, context, instance, port_id,
network_id=None, requested_ip=None,
conductor_api=None):
@@ -331,6 +332,7 @@ class API(base.Base):
requested_networks=[(network_id, requested_ip, port_id)],
conductor_api=conductor_api)
+ @refresh_cache
def deallocate_port_for_instance(self, context, instance, port_id,
conductor_api=None):
try:
@@ -342,8 +344,7 @@ class API(base.Base):
self.trigger_security_group_members_refresh(context, instance)
self.trigger_instance_remove_security_group_refresh(context, instance)
- return self.get_instance_nw_info(context, instance,
- conductor_api=conductor_api)
+ return self._get_instance_nw_info(context, instance)
def list_ports(self, context, **search_opts):
return quantumv2.get_client(context).list_ports(**search_opts)
@@ -364,6 +365,7 @@ class API(base.Base):
nw_info = self._build_network_info_model(context, instance, networks)
return network_model.NetworkInfo.hydrate(nw_info)
+ @refresh_cache
def add_fixed_ip_to_instance(self, context, instance, network_id,
conductor_api=None):
"""Add a fixed ip to the instance from specified network."""
@@ -398,6 +400,7 @@ class API(base.Base):
raise exception.NetworkNotFoundForInstance(
instance_id=instance['uuid'])
+ @refresh_cache
def remove_fixed_ip_from_instance(self, context, instance, address,
conductor_api=None):
"""Remove a fixed ip from the instance."""
@@ -712,6 +715,11 @@ class API(base.Base):
raise exception.FloatingIpMultipleFoundForAddress(address=address)
return fips[0]
+ def _get_floating_ips_by_fixed_and_port(self, client, fixed_ip, port):
+ """Get floatingips from fixed ip and port."""
+ data = client.list_floatingips(fixed_ip_address=fixed_ip, port_id=port)
+ return data['floatingips']
+
def release_floating_ip(self, context, address,
affect_auto_assigned=False):
"""Remove a floating ip with the given address from a project."""
@@ -763,8 +771,8 @@ class API(base.Base):
def _build_network_info_model(self, context, instance, networks=None):
search_opts = {'tenant_id': instance['project_id'],
'device_id': instance['uuid'], }
- data = quantumv2.get_client(context,
- admin=True).list_ports(**search_opts)
+ client = quantumv2.get_client(context, admin=True)
+ data = client.list_ports(**search_opts)
ports = data.get('ports', [])
if networks is None:
networks = self._get_available_networks(context,
@@ -790,10 +798,16 @@ class API(base.Base):
{'net': port['network_id'],
'port': port['id']})
- network_IPs = [network_model.FixedIP(address=ip_address)
- for ip_address in [ip['ip_address']
- for ip in port['fixed_ips']]]
- # TODO(gongysh) get floating_ips for each fixed_ip
+ network_IPs = []
+ for fixed_ip in port['fixed_ips']:
+ fixed = network_model.FixedIP(address=fixed_ip['ip_address'])
+ floats = self._get_floating_ips_by_fixed_and_port(
+ client, fixed_ip['ip_address'], port['id'])
+ for ip in floats:
+ fip = network_model.IP(address=ip['floating_ip_address'],
+ type='floating')
+ fixed.add_floating_ip(fip)
+ network_IPs.append(fixed)
subnets = self._get_subnets_from_port(context, port)
for subnet in subnets:
diff --git a/nova/tests/api/openstack/compute/contrib/test_quantum_security_groups.py b/nova/tests/api/openstack/compute/contrib/test_quantum_security_groups.py
index a413babdf1..a8eadd2a60 100644
--- a/nova/tests/api/openstack/compute/contrib/test_quantum_security_groups.py
+++ b/nova/tests/api/openstack/compute/contrib/test_quantum_security_groups.py
@@ -618,6 +618,9 @@ class MockClient(object):
return {'subnets':
[subnet for subnet in self._fake_subnets.values()]}
+ def list_floatingips(self, **_params):
+ return {'floatingips': []}
+
def delete_security_group(self, security_group):
self.show_security_group(security_group)
ports = self.list_ports()
diff --git a/nova/tests/network/test_quantumv2.py b/nova/tests/network/test_quantumv2.py
index 660123866b..0d2c099ab4 100644
--- a/nova/tests/network/test_quantumv2.py
+++ b/nova/tests/network/test_quantumv2.py
@@ -167,6 +167,9 @@ class TestQuantumv2(test.TestCase):
'fixed_ips': [{'ip_address': self.port_address,
'subnet_id': 'my_subid1'}],
'mac_address': 'my_mac1', }]
+ self.float_data1 = [{'port_id': 'my_portid1',
+ 'fixed_ip_address': self.port_address,
+ 'floating_ip_address': '172.0.1.2'}]
self.dhcp_port_data1 = [{'fixed_ips': [{'ip_address': '10.0.1.9',
'subnet_id': 'my_subid1'}]}]
self.port_data2 = []
@@ -178,6 +181,11 @@ class TestQuantumv2(test.TestCase):
'fixed_ips': [{'ip_address': '10.0.2.2',
'subnet_id': 'my_subid2'}],
'mac_address': 'my_mac2', })
+ self.float_data2 = []
+ self.float_data2.append(self.float_data1[0])
+ self.float_data2.append({'port_id': 'my_portid2',
+ 'fixed_ip_address': '10.0.2.2',
+ 'floating_ip_address': '172.0.2.2'})
self.port_data3 = [{'network_id': 'my_netid1',
'device_id': 'device_id3',
'device_owner': 'compute:nova',
@@ -242,6 +250,8 @@ class TestQuantumv2(test.TestCase):
id_suffix = index + 1
self.assertEquals('10.0.%s.2' % id_suffix,
nw_inf.fixed_ips()[index]['address'])
+ self.assertEquals('172.0.%s.2' % id_suffix,
+ nw_inf.fixed_ips()[index].floating_ip_addresses()[0])
self.assertEquals('my_netname%s' % id_suffix,
nw_inf[index]['network']['label'])
self.assertEquals('my_portid%s' % id_suffix, nw_inf[index]['id'])
@@ -269,6 +279,14 @@ class TestQuantumv2(test.TestCase):
self.moxed_client.list_networks(
shared=True).AndReturn({'networks': []})
for i in xrange(1, number + 1):
+ float_data = number == 1 and self.float_data1 or self.float_data2
+ for ip in port_data[i - 1]['fixed_ips']:
+ float_data = [x for x in float_data
+ if x['fixed_ip_address'] == ip['ip_address']]
+ self.moxed_client.list_floatingips(
+ fixed_ip_address=ip['ip_address'],
+ port_id=port_data[i - 1]['id']).AndReturn(
+ {'floatingips': float_data})
subnet_data = i == 1 and self.subnet_data1 or self.subnet_data2
self.moxed_client.list_subnets(
id=mox.SameElementsAs(['my_subid%s' % i])).AndReturn(
@@ -307,6 +325,12 @@ class TestQuantumv2(test.TestCase):
tenant_id=self.instance['project_id'],
device_id=self.instance['uuid']).AndReturn(
{'ports': self.port_data1})
+ port_data = self.port_data1
+ for ip in port_data[0]['fixed_ips']:
+ self.moxed_client.list_floatingips(
+ fixed_ip_address=ip['ip_address'],
+ port_id=port_data[0]['id']).AndReturn(
+ {'floatingips': self.float_data1})
self.moxed_client.list_subnets(
id=mox.SameElementsAs(['my_subid1'])).AndReturn(
{'subnets': self.subnet_data1})
@@ -379,7 +403,7 @@ class TestQuantumv2(test.TestCase):
def _stub_allocate_for_instance(self, net_idx=1, **kwargs):
api = quantumapi.API()
- self.mox.StubOutWithMock(api, 'get_instance_nw_info')
+ self.mox.StubOutWithMock(api, '_get_instance_nw_info')
self.mox.StubOutWithMock(api, '_populate_quantum_extension_values')
# Net idx is 1-based for compatibility with existing unit tests
nets = self.nets[net_idx - 1]
@@ -461,11 +485,10 @@ class TestQuantumv2(test.TestCase):
if kwargs.get('_break') == 'pre_get_instance_nw_info':
self.mox.ReplayAll()
return api
- api.get_instance_nw_info(mox.IgnoreArg(),
- self.instance,
- networks=nets,
- conductor_api=mox.IgnoreArg()).AndReturn(
- self._returned_nw_info)
+ api._get_instance_nw_info(mox.IgnoreArg(),
+ self.instance,
+ networks=nets).AndReturn(
+ self._returned_nw_info)
self.mox.ReplayAll()
return api
@@ -702,6 +725,13 @@ class TestQuantumv2(test.TestCase):
{'networks': [self.nets2[1]]})
self.moxed_client.list_networks(shared=True).AndReturn(
{'networks': []})
+ float_data = number == 1 and self.float_data1 or self.float_data2
+ for data in port_data[1:]:
+ for ip in data['fixed_ips']:
+ self.moxed_client.list_floatingips(
+ fixed_ip_address=ip['ip_address'],
+ port_id=data['id']).AndReturn(
+ {'floatingips': float_data[1:]})
for port in port_data[1:]:
self.moxed_client.list_subnets(id=['my_subid2']).AndReturn({})
@@ -1124,6 +1154,7 @@ class TestQuantumv2(test.TestCase):
def test_add_fixed_ip_to_instance(self):
api = quantumapi.API()
+ self._setup_mock_for_refresh_cache(api)
network_id = 'my_netid1'
search_opts = {'network_id': network_id}
self.moxed_client.list_subnets(
@@ -1150,6 +1181,7 @@ class TestQuantumv2(test.TestCase):
def test_remove_fixed_ip_from_instance(self):
api = quantumapi.API()
+ self._setup_mock_for_refresh_cache(api)
address = '10.0.0.3'
zone = 'compute:%s' % self.instance['availability_zone']
search_opts = {'device_id': self.instance['uuid'],