diff options
| author | Dan Wendlandt <dan@nicira.com> | 2011-08-25 21:09:15 -0700 |
|---|---|---|
| committer | Dan Wendlandt <dan@nicira.com> | 2011-08-25 21:09:15 -0700 |
| commit | 5823a72690155d9d69e4d23a81be2ea0945809dc (patch) | |
| tree | 4c5e2786d8fdfad82499bf5647d38a8db45756ac | |
| parent | 632526f0cf7a5be3a26c3ae14683b75bfb6afbfd (diff) | |
add priority for static networks
| -rw-r--r-- | nova/network/quantum/fake.py | 13 | ||||
| -rw-r--r-- | nova/network/quantum/manager.py | 9 | ||||
| -rw-r--r-- | nova/network/quantum/melange_ipam_lib.py | 30 | ||||
| -rw-r--r-- | nova/network/quantum/nova_ipam_lib.py | 22 | ||||
| -rw-r--r-- | nova/tests/test_quantum.py | 38 |
5 files changed, 69 insertions, 43 deletions
diff --git a/nova/network/quantum/fake.py b/nova/network/quantum/fake.py index ff2b1e9d5..a923bbf1a 100644 --- a/nova/network/quantum/fake.py +++ b/nova/network/quantum/fake.py @@ -102,8 +102,8 @@ class FakeQuantumIPAMLib(): self.subnets = {} def create_subnet(self, context, label, tenant_id, quantum_net_id, - cidr=None, gateway_v6=None, cidr_v6=None, - dns1=None, dns2=None): + priority, cidr=None, gateway_v6=None, + cidr_v6=None, dns1=None, dns2=None): if int(cidr.split("/")[1]) != 24: raise Exception("fake ipam_lib only supports /24s") v4_ips = [] @@ -116,6 +116,7 @@ class FakeQuantumIPAMLib(): "instance_id": None}) self.subnets[quantum_net_id] = {\ "label": label, + "priority": priority, "gateway": net_start + "1", "netmask": "255.255.255.0", "broadcast": net_start + "255", @@ -138,12 +139,14 @@ class FakeQuantumIPAMLib(): del self.subnets[net_id] def get_project_and_global_net_ids(self, context, project_id): - net_ids = [] + net_list = [] + id_priority_map = {} for nid, s in self.subnets.items(): if s['project_id'] == project_id or \ s['project_id'] == None: - net_ids.append((nid, s['project_id'])) - return net_ids + net_list.append((nid, s['project_id'])) + id_priority_map[nid] = s['priority'] + return sorted(net_list, key=lambda x: id_priority_map[x[0]]) def allocate_fixed_ip(self, context, tenant_id, quantum_net_id, vif_rec): subnet = self.subnets[quantum_net_id] diff --git a/nova/network/quantum/manager.py b/nova/network/quantum/manager.py index f712a93c4..2c2fd4dd7 100644 --- a/nova/network/quantum/manager.py +++ b/nova/network/quantum/manager.py @@ -59,7 +59,7 @@ class QuantumManager(manager.FlatManager): FLAGS.quantum_default_tenant_id quantum_net_id = bridge if quantum_net_id: - if not q_conn.network_exists(q_tenant_id, quantum_net_id): + if not self.q_conn.network_exists(q_tenant_id, quantum_net_id): raise Exception("Unable to find existing quantum " \ " network for tenant '%s' with net-id '%s'" % \ (q_tenant_id, quantum_net_id)) @@ -68,8 +68,9 @@ class QuantumManager(manager.FlatManager): quantum_net_id = self.q_conn.create_network(q_tenant_id, label) ipam_tenant_id = kwargs.get("project_id", None) + priority = kwargs.get("priority", 0) self.ipam.create_subnet(context, label, ipam_tenant_id, quantum_net_id, - cidr, gateway_v6, cidr_v6, dns1, dns2) + priority, cidr, gateway_v6, cidr_v6, dns1, dns2) def delete_network(self, context, fixed_range): project_id = context.project_id @@ -105,7 +106,7 @@ class QuantumManager(manager.FlatManager): # Create a port via quantum and attach the vif for (net_id, project_id) in net_proj_pairs: vif_rec = manager.FlatManager.add_virtual_interface(self, - context, instance, None) + context, instance_id, None) q_tenant_id = project_id or FLAGS.quantum_default_tenant_id self.q_conn.create_and_attach_port(q_tenant_id, net_id, @@ -212,7 +213,7 @@ class QuantumManager(manager.FlatManager): self.ipam.deallocate_ips_by_vif(context, ipam_tenant_id, net_id, vif_ref) - self.net_manager.db.virtual_interface_delete_by_instance(admin_context, + db.virtual_interface_delete_by_instance(admin_context, instance_id) self._do_trigger_security_group_members_refresh_for_instance( instance_id) diff --git a/nova/network/quantum/melange_ipam_lib.py b/nova/network/quantum/melange_ipam_lib.py index 46038c349..526be6327 100644 --- a/nova/network/quantum/melange_ipam_lib.py +++ b/nova/network/quantum/melange_ipam_lib.py @@ -36,7 +36,7 @@ class QuantumMelangeIPAMLib: self.m_conn = melange_connection.MelangeConnection() def create_subnet(self, context, label, project_id, - quantum_net_id, cidr=None, + quantum_net_id, priority, cidr=None, gateway_v6=None, cidr_v6=None, dns1=None, dns2=None): tenant_id = project_id or FLAGS.quantum_default_tenant_id @@ -49,6 +49,13 @@ class QuantumMelangeIPAMLib: project_id=tenant_id, dns1=dns1, dns2=dns2) + # create a entry in the network table just to store + # the priority order for this network + net = {"bridge": quantum_net_id, + "project_id": project_id, + "priority": priority} + network = self.db.network_create_safe(context, net) + def allocate_fixed_ip(self, context, project_id, quantum_net_id, vif_ref): tenant_id = project_id or FLAGS.quantum_default_tenant_id self.m_conn.allocate_ip(quantum_net_id, @@ -61,19 +68,26 @@ class QuantumMelangeIPAMLib: for b in all_blocks['ip_blocks']: if b['cidr'] == cidr: return b['network_id'] + raise Exception("No network found for cidr %s" % cidr) def delete_subnets_by_net_id(self, context, net_id, project_id): + admin_context = context.elevated() tenant_id = project_id or FLAGS.quantum_default_tenant_id all_blocks = self.m_conn.get_blocks(tenant_id) for b in all_blocks['ip_blocks']: if b['network_id'] == net_id: self.m_conn.delete_block(b['id'], tenant_id) + network = db.network_get_by_bridge(admin_context, net_id) + if network is not None: + db.network_delete_safe(context, network['id']) + # get all networks with this project_id, as well as all networks # where the project-id is not set (these are shared networks) def get_project_and_global_net_ids(self, context, project_id): + admin_context = context.elevated() id_proj_map = {} - if not project_id: + if project_id is None: raise Exception("get_project_and_global_net_ids must be called" \ " with a non-null project_id") tenant_id = project_id @@ -84,7 +98,17 @@ class QuantumMelangeIPAMLib: all_provider_blocks = self.m_conn.get_blocks(tenant_id) for b in all_provider_blocks['ip_blocks']: id_proj_map[b['network_id']] = tenant_id - return id_proj_map.items() + + id_priority_map = {} + network = db.network_get_by_bridge(admin_context, net_id) + for net_id, project_id in id_project_map.item(): + network = db.network_get_by_bridge(admin_context, net_id) + if network is None: + del id_proj_map[net_id] + else: + id_priority_map[net_id] = network['priority'] + return sorted(id_priority_map.items(), + key=lambda x: id_priority_map[x[0]]) # FIXME: there must be a more efficient way to do this, # talk to the melange folks diff --git a/nova/network/quantum/nova_ipam_lib.py b/nova/network/quantum/nova_ipam_lib.py index 0fc74fa49..a9a6dcb29 100644 --- a/nova/network/quantum/nova_ipam_lib.py +++ b/nova/network/quantum/nova_ipam_lib.py @@ -42,10 +42,9 @@ class QuantumNovaIPAMLib: self.net_manager = net_manager def create_subnet(self, context, label, tenant_id, - quantum_net_id, cidr=None, + quantum_net_id, priority, cidr=None, gateway_v6=None, cidr_v6=None, dns1=None, dns2=None): - print "creating subnet %s" % cidr admin_context = context.elevated() subnet_size = int(math.pow(2, (32 - int(cidr.split("/")[1])))) manager.FlatManager.create_networks(self.net_manager, @@ -53,9 +52,10 @@ class QuantumNovaIPAMLib: False, 1, subnet_size, cidr_v6, gateway_v6, quantum_net_id, None, dns1, dns2) - # now grab the network and update project_id + # now grab the network and update project_id + priority network = db.network_get_by_bridge(admin_context, quantum_net_id) - net = {"project_id": tenant_id} + net = {"project_id": tenant_id, + "priority": priority} db.network_update(admin_context, network['id'], net) def get_network_id_by_cidr(self, context, cidr, project_id): @@ -82,7 +82,13 @@ class QuantumNovaIPAMLib: admin_context = context.elevated() networks = db.project_get_networks(admin_context, project_id, False) networks.extend(db.project_get_networks(admin_context, None, False)) - return [(n['bridge'], n['project_id']) for n in networks] + id_priority_map = {} + net_list = [] + for n in networks: + net_id = n['bridge'] + net_list.append((net_id, n["project_id"])) + id_priority_map[net_id] = n['priority'] + return sorted(net_list, key=lambda x: id_priority_map[x[0]]) def allocate_fixed_ip(self, context, tenant_id, quantum_net_id, vif_rec): admin_context = context.elevated() @@ -104,8 +110,7 @@ class QuantumNovaIPAMLib: 'broadcast': n['broadcast'], 'netmask': n['netmask'], 'dns1': n['dns1'], - 'dns2': n['dns2'] - } + 'dns2': n['dns2']} subnet_data_v6 = { 'network_id': n['bridge'], 'cidr': n['cidr_v6'], @@ -113,8 +118,7 @@ class QuantumNovaIPAMLib: 'broadcast': None, 'netmask': None, 'dns1': None, - 'dns2': None - } + 'dns2': None} return (subnet_data_v4, subnet_data_v6) def get_v4_ips_by_interface(self, context, net_id, vif_id, project_id): diff --git a/nova/tests/test_quantum.py b/nova/tests/test_quantum.py index 378beb6ed..80cab950e 100644 --- a/nova/tests/test_quantum.py +++ b/nova/tests/test_quantum.py @@ -41,7 +41,8 @@ networks = [{'label': 'project1-net1', 'vlan': None, 'host': None, 'vpn_public_address': None, - 'project_id': 'fake_project1'}, + 'project_id': 'fake_project1', + 'priority': 1}, {'label': 'project2-net1', 'injected': False, 'multi_host': False, @@ -59,7 +60,7 @@ networks = [{'label': 'project1-net1', 'vlan': None, 'host': None, 'project_id': 'fake_project2', - 'vpn_public_address': '192.168.1.2'}, + 'priority': 1}, {'label': "public", 'injected': False, 'multi_host': False, @@ -76,8 +77,8 @@ networks = [{'label': 'project1-net1', 'dns2': '10.0.0.2', 'vlan': None, 'host': None, - 'vpn_public_address': None, - 'project_id': None}, + 'project_id': None, + 'priority': 0}, {'label': "project2-net2", 'injected': False, 'multi_host': False, @@ -94,8 +95,8 @@ networks = [{'label': 'project1-net1', 'dns2': '9.0.0.2', 'vlan': None, 'host': None, - 'vpn_public_address': None, - 'project_id': "fake_project2"}] + 'project_id': "fake_project2", + 'priority': 2}] # this is a base class to be used by all other Quantum Test classes @@ -114,7 +115,8 @@ class QuantumTestCaseBase(object): num_networks=1, network_size=256, cidr_v6=n['cidr_v6'], gateway_v6=n['gateway_v6'], bridge=None, bridge_interface=None, dns1=n['dns1'], - dns2=n['dns2'], project_id=n['project_id']) + dns2=n['dns2'], project_id=n['project_id'], + priority=n['priority']) def _delete_nets(self): for n in networks: @@ -138,29 +140,21 @@ class QuantumTestCaseBase(object): # we don't know which order the NICs will be in until we # introduce the notion of priority # v4 cidr - self.assertTrue(nw_info[0][0]['cidr'].startswith("10.") or \ - nw_info[1][0]['cidr'].startswith("10.")) - self.assertTrue(nw_info[0][0]['cidr'].startswith("192.") or \ - nw_info[1][0]['cidr'].startswith("192.")) + self.assertTrue(nw_info[0][0]['cidr'].startswith("10.")) + self.assertTrue(nw_info[1][0]['cidr'].startswith("192.")) # v4 address - self.assertTrue(nw_info[0][1]['ips'][0]['ip'].startswith("10.") or \ - nw_info[1][1]['ips'][0]['ip'].startswith("10.")) - self.assertTrue(nw_info[0][1]['ips'][0]['ip'].startswith("192.") or \ - nw_info[1][1]['ips'][0]['ip'].startswith("192.")) + self.assertTrue(nw_info[0][1]['ips'][0]['ip'].startswith("10.")) + self.assertTrue(nw_info[1][1]['ips'][0]['ip'].startswith("192.")) # v6 cidr - self.assertTrue(nw_info[0][0]['cidr_v6'].startswith("2001:1dba:") or \ - nw_info[1][0]['cidr_v6'].startswith("2001:1dba:")) - self.assertTrue(nw_info[0][0]['cidr_v6'].startswith("2001:1db8:") or \ - nw_info[1][0]['cidr_v6'].startswith("2001:1db8:")) + self.assertTrue(nw_info[0][0]['cidr_v6'].startswith("2001:1dba:")) + self.assertTrue(nw_info[1][0]['cidr_v6'].startswith("2001:1db8:")) # v6 address self.assertTrue(\ - nw_info[0][1]['ip6s'][0]['ip'].startswith("2001:1dba:") or \ - nw_info[1][1]['ip6s'][0]['ip'].startswith("2001:1dba:")) + nw_info[0][1]['ip6s'][0]['ip'].startswith("2001:1dba:")) self.assertTrue(\ - nw_info[0][1]['ip6s'][0]['ip'].startswith("2001:1db8:") or \ nw_info[1][1]['ip6s'][0]['ip'].startswith("2001:1db8:")) self.net_man.deallocate_for_instance(ctx, |
