diff options
-rw-r--r-- | nova/network/quantumv2/api.py | 112 | ||||
-rw-r--r-- | nova/tests/network/test_quantumv2.py | 124 |
2 files changed, 187 insertions, 49 deletions
diff --git a/nova/network/quantumv2/api.py b/nova/network/quantumv2/api.py index 39c3d47d0..6b2cac9bd 100644 --- a/nova/network/quantumv2/api.py +++ b/nova/network/quantumv2/api.py @@ -807,6 +807,63 @@ class API(base.Base): """Force add a network to the project.""" raise NotImplementedError() + def _nw_info_get_ips(self, client, port): + 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) + return network_IPs + + def _nw_info_get_subnets(self, context, port, network_IPs): + subnets = self._get_subnets_from_port(context, port) + for subnet in subnets: + subnet['ips'] = [fixed_ip for fixed_ip in network_IPs + if fixed_ip.is_in_subnet(subnet)] + return subnets + + def _nw_info_build_network(self, port, networks, subnets): + # NOTE(danms): This loop can't fail to find a network since we + # filtered ports to only the ones matching networks in our parent + for net in networks: + if port['network_id'] == net['id']: + network_name = net['name'] + break + + bridge = None + ovs_interfaceid = None + # Network model metadata + should_create_bridge = None + vif_type = port.get('binding:vif_type') + # TODO(berrange) Quantum should pass the bridge name + # in another binding metadata field + if vif_type == network_model.VIF_TYPE_OVS: + bridge = CONF.quantum_ovs_bridge + ovs_interfaceid = port['id'] + elif vif_type == network_model.VIF_TYPE_BRIDGE: + bridge = "brq" + port['network_id'] + should_create_bridge = True + + if bridge is not None: + bridge = bridge[:network_model.NIC_NAME_LEN] + + network = network_model.Network( + id=port['network_id'], + bridge=bridge, + injected=CONF.flat_injected, + label=network_name, + tenant_id=net['tenant_id'] + ) + network['subnets'] = subnets + if should_create_bridge is not None: + network['should_create_bridge'] = should_create_bridge + return network, ovs_interfaceid + def _build_network_info_model(self, context, instance, networks=None): search_opts = {'tenant_id': instance['project_id'], 'device_id': instance['uuid'], } @@ -826,59 +883,16 @@ class API(base.Base): nw_info = network_model.NetworkInfo() for port in ports: - # NOTE(danms): This loop can't fail to find a network since we - # filtered ports to only the ones matching networks above. - for net in networks: - if port['network_id'] == net['id']: - network_name = net['name'] - break - - 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: - subnet['ips'] = [fixed_ip for fixed_ip in network_IPs - if fixed_ip.is_in_subnet(subnet)] - - bridge = None - ovs_interfaceid = None - # Network model metadata - should_create_bridge = None - vif_type = port.get('binding:vif_type') - # TODO(berrange) Quantum should pass the bridge name - # in another binding metadata field - if vif_type == network_model.VIF_TYPE_OVS: - bridge = CONF.quantum_ovs_bridge - ovs_interfaceid = port['id'] - elif vif_type == network_model.VIF_TYPE_BRIDGE: - bridge = "brq" + port['network_id'] - should_create_bridge = True - - if bridge is not None: - bridge = bridge[:network_model.NIC_NAME_LEN] + network_IPs = self._nw_info_get_ips(client, port) + subnets = self._nw_info_get_subnets(context, port, network_IPs) devname = "tap" + port['id'] devname = devname[:network_model.NIC_NAME_LEN] - network = network_model.Network( - id=port['network_id'], - bridge=bridge, - injected=CONF.flat_injected, - label=network_name, - tenant_id=net['tenant_id'] - ) - network['subnets'] = subnets - if should_create_bridge is not None: - network['should_create_bridge'] = should_create_bridge + network, ovs_interfaceid = self._nw_info_build_network(port, + networks, + subnets) + nw_info.append(network_model.VIF( id=port['id'], address=port['mac_address'], diff --git a/nova/tests/network/test_quantumv2.py b/nova/tests/network/test_quantumv2.py index 6a00b4723..5922d7e1e 100644 --- a/nova/tests/network/test_quantumv2.py +++ b/nova/tests/network/test_quantumv2.py @@ -1233,6 +1233,130 @@ class TestQuantumv2(test.TestCase): self.moxed_client, '1.1.1.1', 1) self.assertEqual(floatingips, []) + def test_nw_info_get_ips(self): + fake_port = { + 'fixed_ips': [ + {'ip_address': '1.1.1.1'}], + 'id': 'port-id', + } + api = quantumapi.API() + self.mox.StubOutWithMock(api, '_get_floating_ips_by_fixed_and_port') + api._get_floating_ips_by_fixed_and_port( + self.moxed_client, '1.1.1.1', 'port-id').AndReturn( + [{'floating_ip_address': '10.0.0.1'}]) + self.mox.ReplayAll() + quantumv2.get_client('fake') + result = api._nw_info_get_ips(self.moxed_client, fake_port) + self.assertEqual(len(result), 1) + self.assertEqual(result[0]['address'], '1.1.1.1') + self.assertEqual(result[0]['floating_ips'][0]['address'], '10.0.0.1') + + def test_nw_info_get_subnets(self): + fake_port = { + 'fixed_ips': [ + {'ip_address': '1.1.1.1'}, + {'ip_address': '2.2.2.2'}], + 'id': 'port-id', + } + fake_subnet = model.Subnet(cidr='1.0.0.0/8') + fake_ips = [model.IP(x['ip_address']) for x in fake_port['fixed_ips']] + api = quantumapi.API() + self.mox.StubOutWithMock(api, '_get_subnets_from_port') + api._get_subnets_from_port(self.context, fake_port).AndReturn( + [fake_subnet]) + self.mox.ReplayAll() + quantumv2.get_client('fake') + subnets = api._nw_info_get_subnets(self.context, fake_port, fake_ips) + self.assertEqual(len(subnets), 1) + self.assertEqual(len(subnets[0]['ips']), 1) + self.assertEqual(subnets[0]['ips'][0]['address'], '1.1.1.1') + + def _test_nw_info_build_network(self, vif_type): + fake_port = { + 'fixed_ips': [{'ip_address': '1.1.1.1'}], + 'id': 'port-id', + 'network_id': 'net-id', + 'binding:vif_type': vif_type, + } + fake_subnets = [model.Subnet(cidr='1.0.0.0/8')] + fake_nets = [{'id': 'net-id', 'name': 'foo', 'tenant_id': 'tenant'}] + api = quantumapi.API() + self.mox.ReplayAll() + quantumv2.get_client('fake') + net, iid = api._nw_info_build_network(fake_port, fake_nets, + fake_subnets) + self.assertEqual(net['subnets'], fake_subnets) + self.assertEqual(net['id'], 'net-id') + self.assertEqual(net['label'], 'foo') + self.assertEqual(net.get_meta('tenant_id'), 'tenant') + self.assertEqual(net.get_meta('injected'), CONF.flat_injected) + return net, iid + + def test_nw_info_build_network_ovs(self): + net, iid = self._test_nw_info_build_network(model.VIF_TYPE_OVS) + self.assertEqual(net['bridge'], CONF.quantum_ovs_bridge) + self.assertFalse('should_create_bridge' in net) + self.assertEqual(iid, 'port-id') + + def test_nw_info_build_network_bridge(self): + net, iid = self._test_nw_info_build_network(model.VIF_TYPE_BRIDGE) + self.assertEqual(net['bridge'], 'brqnet-id') + self.assertTrue(net['should_create_bridge']) + self.assertEqual(iid, None) + + def test_nw_info_build_network_other(self): + net, iid = self._test_nw_info_build_network(None) + self.assertEqual(net['bridge'], None) + self.assertFalse('should_create_bridge' in net) + self.assertEqual(iid, None) + + def test_build_network_info_model(self): + api = quantumapi.API() + fake_inst = {'project_id': 'fake', 'uuid': 'uuid'} + fake_ports = [ + {'id': 'port0', + 'network_id': 'net-id', + 'fixed_ips': [{'ip_address': '1.1.1.1'}], + 'mac_address': 'de:ad:be:ef:00:01', + 'binding:vif_type': model.VIF_TYPE_BRIDGE, + }, + # This does not match the networks we provide below, + # so it should be ignored (and is here to verify that) + {'id': 'port1', + 'network_id': 'other-net-id', + }, + ] + fake_subnets = [model.Subnet(cidr='1.0.0.0/8')] + fake_nets = [ + {'id': 'net-id', + 'name': 'foo', + 'tenant_id': 'fake', + } + ] + quantumv2.get_client(mox.IgnoreArg(), admin=True).MultipleTimes( + ).AndReturn(self.moxed_client) + self.moxed_client.list_ports( + tenant_id='fake', device_id='uuid').AndReturn( + {'ports': fake_ports}) + self.mox.StubOutWithMock(api, '_get_floating_ips_by_fixed_and_port') + api._get_floating_ips_by_fixed_and_port( + self.moxed_client, '1.1.1.1', 'port0').AndReturn( + [{'floating_ip_address': '10.0.0.1'}]) + self.mox.StubOutWithMock(api, '_get_subnets_from_port') + api._get_subnets_from_port(self.context, fake_ports[0]).AndReturn( + fake_subnets) + self.mox.ReplayAll() + quantumv2.get_client('fake') + nw_info = api._build_network_info_model(self.context, fake_inst, + fake_nets) + self.assertEqual(len(nw_info), 1) + self.assertEqual(nw_info[0]['id'], 'port0') + self.assertEqual(nw_info[0]['address'], 'de:ad:be:ef:00:01') + self.assertEqual(nw_info[0]['devname'], 'tapport0') + self.assertEqual(nw_info[0]['ovs_interfaceid'], None) + self.assertEqual(nw_info[0]['type'], model.VIF_TYPE_BRIDGE) + self.assertEqual(nw_info[0]['network']['bridge'], 'brqnet-id') + class TestQuantumv2ModuleMethods(test.TestCase): def test_ensure_requested_network_ordering_no_preference_ids(self): |