Merge lp:~bgh/nova/qmanager-new-review-feedback into lp:~danwent/nova/qmanager-new
- qmanager-new-review-feedback
- Merge into qmanager-new
Proposed by
Brad Hall
Status: | Merged |
---|---|
Merged at revision: | 1501 |
Proposed branch: | lp:~bgh/nova/qmanager-new-review-feedback |
Merge into: | lp:~danwent/nova/qmanager-new |
Diff against target: |
744 lines (+163/-153) 10 files modified
bin/nova-manage (+5/-6) nova/network/manager.py (+1/-1) nova/network/quantum/client.py (+32/-29) nova/network/quantum/fake.py (+8/-11) nova/network/quantum/manager.py (+34/-25) nova/network/quantum/melange_connection.py (+3/-3) nova/network/quantum/melange_ipam_lib.py (+45/-45) nova/network/quantum/nova_ipam_lib.py (+21/-19) nova/network/quantum/quantum_connection.py (+5/-5) nova/tests/test_quantum.py (+9/-9) |
To merge this branch: | bzr merge lp:~bgh/nova/qmanager-new-review-feedback |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
dan wendlandt | Pending | ||
Review via email: mp+73602@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'bin/nova-manage' |
2 | --- bin/nova-manage 2011-08-29 16:04:43 +0000 |
3 | +++ bin/nova-manage 2011-09-01 05:49:24 +0000 |
4 | @@ -804,11 +804,11 @@ |
5 | def quantum_list(self): |
6 | """List all created networks with Quantum-relevant fields""" |
7 | _fmt = "%-32s\t%-10s\t%-10s\t%s , %s" |
8 | - print _fmt % ( _('uuid'), |
9 | - _('project'), |
10 | - _('priority'), |
11 | - _('cidr_v4'), |
12 | - _('cidr_v6')) |
13 | + print _fmt % (_('uuid'), |
14 | + _('project'), |
15 | + _('priority'), |
16 | + _('cidr_v4'), |
17 | + _('cidr_v6')) |
18 | for network in db.network_get_all(context.get_admin_context()): |
19 | print _fmt % (network.uuid, |
20 | network.project_id, |
21 | @@ -825,7 +825,6 @@ |
22 | net_manager = utils.import_object(FLAGS.network_manager) |
23 | net_manager.delete_network(context.get_admin_context(), fixed_range) |
24 | |
25 | - |
26 | @args('--network', dest="fixed_range", metavar='<x.x.x.x/yy>', |
27 | help='Network to modify') |
28 | @args('--project', dest="project", metavar='<project name>', |
29 | |
30 | === modified file 'nova/network/manager.py' |
31 | --- nova/network/manager.py 2011-08-29 17:43:26 +0000 |
32 | +++ nova/network/manager.py 2011-09-01 05:49:24 +0000 |
33 | @@ -547,7 +547,7 @@ |
34 | 'network_id': network_id, |
35 | 'uuid': str(utils.gen_uuid())} |
36 | # try FLAG times to create a vif record with a unique mac_address |
37 | - for i in range(FLAGS.create_unique_mac_address_attempts): |
38 | + for i in xrange(FLAGS.create_unique_mac_address_attempts): |
39 | try: |
40 | return self.db.virtual_interface_create(context, vif) |
41 | except exception.VirtualInterfaceCreateException: |
42 | |
43 | === modified file 'nova/network/quantum/client.py' |
44 | --- nova/network/quantum/client.py 2011-08-26 22:48:53 +0000 |
45 | +++ nova/network/quantum/client.py 2011-09-01 05:49:24 +0000 |
46 | @@ -22,11 +22,12 @@ |
47 | import urllib |
48 | |
49 | |
50 | -# this is a simple json-only serializer to use until |
51 | -# we can just grab the standard serializer |
52 | -# from the quantum library |
53 | -class Serializer: |
54 | - |
55 | +class JSONSerializer(object): |
56 | + """ |
57 | + This is a simple json-only serializer to use until we can just grab |
58 | + the standard serializer from the quantum library. |
59 | + TODO(danwent): replace serializer with quantum implementation |
60 | + """ |
61 | def serialize(self, data, content_type): |
62 | try: |
63 | return json.dumps(data) |
64 | @@ -40,12 +41,12 @@ |
65 | |
66 | class api_call(object): |
67 | """A Decorator to add support for format and tenant overriding""" |
68 | - def __init__(self, f): |
69 | - self.f = f |
70 | + def __init__(self, func): |
71 | + self.func = func |
72 | |
73 | def __get__(self, instance, owner): |
74 | def with_params(*args, **kwargs): |
75 | - # Temporarily set format and tenant for this request |
76 | + """Temporarily set format and tenant for this request""" |
77 | (format, tenant) = (instance.format, instance.tenant) |
78 | |
79 | if 'format' in kwargs: |
80 | @@ -53,14 +54,16 @@ |
81 | if 'tenant' in kwargs: |
82 | instance.tenant = kwargs['tenant'] |
83 | |
84 | - ret = self.f(instance, *args) |
85 | - (instance.format, instance.tenant) = (format, tenant) |
86 | + ret = None |
87 | + try: |
88 | + ret = self.func(instance, *args) |
89 | + finally: |
90 | + (instance.format, instance.tenant) = (format, tenant) |
91 | return ret |
92 | return with_params |
93 | |
94 | |
95 | class Client(object): |
96 | - |
97 | """A base client class - derived from Glance.BaseClient""" |
98 | |
99 | action_prefix = '/v1.0/tenants/{tenant_id}' |
100 | @@ -73,8 +76,8 @@ |
101 | attachment_path = "/networks/%s/ports/%s/attachment" |
102 | |
103 | def __init__(self, host="127.0.0.1", port=9696, use_ssl=False, tenant=None, |
104 | - format="xml", testingStub=None, key_file=None, cert_file=None, |
105 | - logger=None): |
106 | + format="xml", testing_stub=None, key_file=None, |
107 | + cert_file=None, logger=None): |
108 | """ |
109 | Creates a new client to some service. |
110 | |
111 | @@ -83,7 +86,7 @@ |
112 | :param use_ssl: True to use SSL, False to use HTTP |
113 | :param tenant: The tenant ID to make requests with |
114 | :param format: The format to query the server with |
115 | - :param testingStub: A class that stubs basic server methods for tests |
116 | + :param testing_stub: A class that stubs basic server methods for tests |
117 | :param key_file: The SSL key file to use if use_ssl is true |
118 | :param cert_file: The SSL cert file to use if use_ssl is true |
119 | """ |
120 | @@ -93,7 +96,7 @@ |
121 | self.tenant = tenant |
122 | self.format = format |
123 | self.connection = None |
124 | - self.testingStub = testingStub |
125 | + self.testing_stub = testing_stub |
126 | self.key_file = key_file |
127 | self.cert_file = cert_file |
128 | self.logger = logger |
129 | @@ -102,9 +105,9 @@ |
130 | """ |
131 | Returns the proper connection type |
132 | """ |
133 | - if self.testingStub: |
134 | - return self.testingStub |
135 | - if self.use_ssl: |
136 | + if self.testing_stub: |
137 | + return self.testing_stub |
138 | + elif self.use_ssl: |
139 | return httplib.HTTPSConnection |
140 | else: |
141 | return httplib.HTTPConnection |
142 | @@ -126,7 +129,7 @@ |
143 | |
144 | # Ensure we have a tenant id |
145 | if not self.tenant: |
146 | - raise Exception("Tenant ID not set") |
147 | + raise Exception(_("Tenant ID not set")) |
148 | |
149 | # Add format and tenant_id |
150 | action += ".%s" % self.format |
151 | @@ -151,8 +154,8 @@ |
152 | c = connection_type(self.host, self.port) |
153 | |
154 | if self.logger: |
155 | - self.logger.debug("Quantum Client Request:\n" \ |
156 | - + method + " " + action + "\n") |
157 | + self.logger.debug(_("Quantum Client Request:\n%s %s\n" % |
158 | + (method, action))) |
159 | if body: |
160 | self.logger.debug(body) |
161 | |
162 | @@ -172,11 +175,11 @@ |
163 | if data is not None and len(data): |
164 | return self.deserialize(data, status_code) |
165 | else: |
166 | - raise Exception("Server returned error: %s" % res.read()) |
167 | + raise Exception(_("Server returned error: %s" % res.read())) |
168 | |
169 | except (socket.error, IOError), e: |
170 | - raise Exception("Unable to connect to " |
171 | - "server. Got error: %s" % e) |
172 | + raise Exception(_("Unable to connect to " |
173 | + "server. Got error: %s" % e)) |
174 | |
175 | def get_status_code(self, response): |
176 | """ |
177 | @@ -189,18 +192,18 @@ |
178 | return response.status |
179 | |
180 | def serialize(self, data): |
181 | - if data is None: |
182 | + if not data: |
183 | return None |
184 | elif type(data) is dict: |
185 | - return Serializer().serialize(data, self.content_type()) |
186 | + return JSONSerializer().serialize(data, self.content_type()) |
187 | else: |
188 | - raise Exception("unable to deserialize object of type = '%s'" \ |
189 | - % type(data)) |
190 | + raise Exception(_("unable to deserialize object of type = '%s'" % |
191 | + type(data))) |
192 | |
193 | def deserialize(self, data, status_code): |
194 | if status_code == 202: |
195 | return data |
196 | - return Serializer().deserialize(data, self.content_type()) |
197 | + return JSONSerializer().deserialize(data, self.content_type()) |
198 | |
199 | def content_type(self, format=None): |
200 | if not format: |
201 | |
202 | === modified file 'nova/network/quantum/fake.py' |
203 | --- nova/network/quantum/fake.py 2011-08-29 02:12:43 +0000 |
204 | +++ nova/network/quantum/fake.py 2011-09-01 05:49:24 +0000 |
205 | @@ -15,9 +15,6 @@ |
206 | # License for the specific language governing permissions and limitations |
207 | # under the License. |
208 | |
209 | -import math |
210 | -from netaddr import IPNetwork |
211 | - |
212 | from nova import exception |
213 | from nova import ipv6 |
214 | from nova import log as logging |
215 | @@ -29,7 +26,7 @@ |
216 | |
217 | # this class can be used for unit functional/testing on nova, |
218 | # as it does not actually make remote calls to the Quantum service |
219 | -class FakeQuantumClientConnection: |
220 | +class FakeQuantumClientConnection(object): |
221 | |
222 | def __init__(self): |
223 | self.nets = {} |
224 | @@ -56,20 +53,20 @@ |
225 | def network_exists(self, tenant_id, net_id): |
226 | try: |
227 | return self.nets[net_id]['tenant-id'] == tenant_id |
228 | - except: |
229 | + except KeyError: |
230 | return False |
231 | |
232 | def _confirm_not_attached(self, interface_id): |
233 | for n in self.nets.values(): |
234 | for p in n['ports'].values(): |
235 | if p['attachment-id'] == interface_id: |
236 | - raise Exception("interface '%s' is already attached" %\ |
237 | - interface_id) |
238 | + raise Exception(_("interface '%s' is already attached" % |
239 | + interface_id)) |
240 | |
241 | def create_and_attach_port(self, tenant_id, net_id, interface_id): |
242 | if not self.network_exists(tenant_id, net_id): |
243 | - raise Exception("network %s does not exist for tenant %s" %\ |
244 | - (net_id, tenant_id)) |
245 | + raise Exception(_("network %s does not exist for tenant %s" % |
246 | + (net_id, tenant_id))) |
247 | |
248 | self._confirm_not_attached(interface_id) |
249 | uuid = str(utils.gen_uuid()) |
250 | @@ -79,8 +76,8 @@ |
251 | |
252 | def detach_and_delete_port(self, tenant_id, net_id, port_id): |
253 | if not self.network_exists(tenant_id, net_id): |
254 | - raise Exception("network %s does not exist for tenant %s" %\ |
255 | - (net_id, tenant_id)) |
256 | + raise Exception(_("network %s does not exist for tenant %s" %\ |
257 | + (net_id, tenant_id))) |
258 | del self.nets[net_id]['ports'][port_id] |
259 | |
260 | def get_port_by_attachment(self, tenant_id, attachment_id): |
261 | |
262 | === modified file 'nova/network/quantum/manager.py' |
263 | --- nova/network/quantum/manager.py 2011-08-29 02:13:02 +0000 |
264 | +++ nova/network/quantum/manager.py 2011-09-01 05:49:24 +0000 |
265 | @@ -84,16 +84,15 @@ |
266 | In both cases, we initialize a subnet using the IPAM lib. |
267 | """ |
268 | if num_networks != 1: |
269 | - raise Exception("QuantumManager requires that only one" |
270 | - " network is created per call") |
271 | - q_tenant_id = kwargs["project_id"] or \ |
272 | - FLAGS.quantum_default_tenant_id |
273 | + raise Exception(_("QuantumManager requires that only one" |
274 | + " network is created per call")) |
275 | + q_tenant_id = kwargs["project_id"] or FLAGS.quantum_default_tenant_id |
276 | quantum_net_id = uuid |
277 | if quantum_net_id: |
278 | if not self.q_conn.network_exists(q_tenant_id, quantum_net_id): |
279 | - raise Exception("Unable to find existing quantum " \ |
280 | - " network for tenant '%s' with net-id '%s'" % \ |
281 | - (q_tenant_id, quantum_net_id)) |
282 | + raise Exception(_("Unable to find existing quantum " \ |
283 | + " network for tenant '%s' with net-id '%s'" % \ |
284 | + (q_tenant_id, quantum_net_id))) |
285 | else: |
286 | # otherwise, create network from default quantum pool |
287 | quantum_net_id = self.q_conn.create_network(q_tenant_id, label) |
288 | @@ -156,18 +155,18 @@ |
289 | # Create a port via quantum and attach the vif |
290 | for (quantum_net_id, project_id) in net_proj_pairs: |
291 | |
292 | - # FIXME: (danwent). We'd like to have the manager be completely |
293 | - # decoupled from the nova networks table. |
294 | - # However, other parts of nova sometimes go behind |
295 | - # our back and access network data directly from the DB. So |
296 | + # FIXME(danwent): We'd like to have the manager be |
297 | + # completely decoupled from the nova networks table. |
298 | + # However, other parts of nova sometimes go behind our |
299 | + # back and access network data directly from the DB. So |
300 | # for now, the quantum manager knows that there is a nova |
301 | - # networks DB table and accesses it here. |
302 | - # updating the virtual_interfaces table to use UUIDs would |
303 | - # be one solution, but this would require significant work |
304 | + # networks DB table and accesses it here. updating the |
305 | + # virtual_interfaces table to use UUIDs would be one |
306 | + # solution, but this would require significant work |
307 | # elsewhere. |
308 | admin_context = context.elevated() |
309 | network_ref = db.network_get_by_uuid(admin_context, |
310 | - quantum_net_id) |
311 | + quantum_net_id) |
312 | |
313 | vif_rec = manager.FlatManager.add_virtual_interface(self, |
314 | context, instance_id, network_ref['id']) |
315 | @@ -177,10 +176,10 @@ |
316 | self.q_conn.create_and_attach_port(q_tenant_id, quantum_net_id, |
317 | vif_rec['uuid']) |
318 | self.ipam.allocate_fixed_ip(context, project_id, quantum_net_id, |
319 | - vif_rec) |
320 | + vif_rec) |
321 | |
322 | return self.get_instance_nw_info(context, instance_id, |
323 | - instance_type_id, host) |
324 | + instance_type_id, host) |
325 | |
326 | def get_instance_nw_info(self, context, instance_id, |
327 | instance_type_id, host): |
328 | @@ -214,8 +213,14 @@ |
329 | net_id, port_id = self.q_conn.get_port_by_attachment( |
330 | q_tenant_id, vif['uuid']) |
331 | if not net_id: |
332 | - raise Exception(_("No network for for virtual interface %s") %\ |
333 | - vif['uuid']) |
334 | + # TODO(bgh): We need to figure out a way to tell if we |
335 | + # should actually be raising this exception or not. |
336 | + # In the case that a VM spawn failed it may not have |
337 | + # attached the vif and raising the exception here |
338 | + # prevents deltion of the VM. In that case we should |
339 | + # probably just log, continue, and move on. |
340 | + raise Exception(_("No network for for virtual interface %s") % |
341 | + vif['uuid']) |
342 | (v4_subnet, v6_subnet) = self.ipam.get_subnets_by_net_id(context, |
343 | ipam_tenant_id, net_id) |
344 | v4_ips = self.ipam.get_v4_ips_by_interface(context, |
345 | @@ -288,17 +293,21 @@ |
346 | (net_id, port_id) = self.q_conn.get_port_by_attachment( |
347 | q_tenant_id, interface_id) |
348 | if not net_id: |
349 | - LOG.error("Unable to find port with attachment: %s" % \ |
350 | - (interface_id)) |
351 | + LOG.error("Unable to find port with attachment: %s" % |
352 | + (interface_id)) |
353 | continue |
354 | self.q_conn.detach_and_delete_port(q_tenant_id, |
355 | - net_id, port_id) |
356 | + net_id, port_id) |
357 | |
358 | self.ipam.deallocate_ips_by_vif(context, ipam_tenant_id, |
359 | - net_id, vif_ref) |
360 | + net_id, vif_ref) |
361 | |
362 | - db.virtual_interface_delete_by_instance(admin_context, |
363 | - instance_id) |
364 | + try: |
365 | + db.virtual_interface_delete_by_instance(admin_context, |
366 | + instance_id) |
367 | + except exception.InstanceNotFound: |
368 | + LOG.error(_("Attempted to deallocate non-existent instance: %s" % |
369 | + (instance_id))) |
370 | self._do_trigger_security_group_members_refresh_for_instance( |
371 | instance_id) |
372 | |
373 | |
374 | === modified file 'nova/network/quantum/melange_connection.py' |
375 | --- nova/network/quantum/melange_connection.py 2011-08-26 06:02:46 +0000 |
376 | +++ nova/network/quantum/melange_connection.py 2011-09-01 05:49:24 +0000 |
377 | @@ -73,10 +73,10 @@ |
378 | response_str = response.read() |
379 | if response.status < 400: |
380 | return response_str |
381 | - raise Exception("Server returned error: %s", response_str) |
382 | + raise Exception(_("Server returned error: %s", response_str)) |
383 | except (socket.error, IOError), e: |
384 | - raise Exception("Unable to connect to " |
385 | - "server. Got error: %s" % e) |
386 | + raise Exception(_("Unable to connect to " |
387 | + "server. Got error: %s" % e)) |
388 | |
389 | def allocate_ip(self, network_id, vif_id, |
390 | project_id=None, mac_address=None): |
391 | |
392 | === modified file 'nova/network/quantum/melange_ipam_lib.py' |
393 | --- nova/network/quantum/melange_ipam_lib.py 2011-08-29 02:13:02 +0000 |
394 | +++ nova/network/quantum/melange_ipam_lib.py 2011-09-01 05:49:24 +0000 |
395 | @@ -31,7 +31,7 @@ |
396 | return QuantumMelangeIPAMLib() |
397 | |
398 | |
399 | -class QuantumMelangeIPAMLib: |
400 | +class QuantumMelangeIPAMLib(object): |
401 | """ Implements Quantum IP Address Management (IPAM) interface |
402 | using the Melange service, which is access using the Melange |
403 | web services API. |
404 | @@ -42,9 +42,9 @@ |
405 | self.m_conn = melange_connection.MelangeConnection() |
406 | |
407 | def create_subnet(self, context, label, project_id, |
408 | - quantum_net_id, priority, cidr=None, |
409 | - gateway_v6=None, cidr_v6=None, |
410 | - dns1=None, dns2=None): |
411 | + quantum_net_id, priority, cidr=None, |
412 | + gateway_v6=None, cidr_v6=None, |
413 | + dns1=None, dns2=None): |
414 | """ Contact Melange and create a subnet for any non-NULL |
415 | IPv4 or IPv6 subnets. |
416 | |
417 | @@ -56,25 +56,25 @@ |
418 | tenant_id = project_id or FLAGS.quantum_default_tenant_id |
419 | if cidr: |
420 | self.m_conn.create_block(quantum_net_id, cidr, |
421 | - project_id=tenant_id, |
422 | - dns1=dns1, dns2=dns2) |
423 | + project_id=tenant_id, |
424 | + dns1=dns1, dns2=dns2) |
425 | if cidr_v6: |
426 | self.m_conn.create_block(quantum_net_id, cidr_v6, |
427 | project_id=tenant_id, |
428 | dns1=dns1, dns2=dns2) |
429 | |
430 | net = {"uuid": quantum_net_id, |
431 | - "project_id": project_id, |
432 | - "priority": priority, |
433 | - "label": label} |
434 | + "project_id": project_id, |
435 | + "priority": priority, |
436 | + "label": label} |
437 | network = self.db.network_create_safe(context, net) |
438 | |
439 | def allocate_fixed_ip(self, context, project_id, quantum_net_id, vif_ref): |
440 | """ Pass call to allocate fixed IP on to Melange""" |
441 | tenant_id = project_id or FLAGS.quantum_default_tenant_id |
442 | self.m_conn.allocate_ip(quantum_net_id, |
443 | - vif_ref['uuid'], project_id=tenant_id, |
444 | - mac_address=vif_ref['address']) |
445 | + vif_ref['uuid'], project_id=tenant_id, |
446 | + mac_address=vif_ref['address']) |
447 | |
448 | def get_network_id_by_cidr(self, context, cidr, project_id): |
449 | """ Find the Quantum UUID associated with a IPv4 CIDR |
450 | @@ -85,7 +85,7 @@ |
451 | for b in all_blocks['ip_blocks']: |
452 | if b['cidr'] == cidr: |
453 | return b['network_id'] |
454 | - raise Exception("No network found for cidr %s" % cidr) |
455 | + raise Exception(_("No network found for cidr %s" % cidr)) |
456 | |
457 | def delete_subnets_by_net_id(self, context, net_id, project_id): |
458 | """ Find Melange block associated with the Quantum UUID, |
459 | @@ -107,38 +107,38 @@ |
460 | that are "global" (i.e., have no project set). |
461 | Returns list sorted by 'priority'. |
462 | """ |
463 | - admin_context = context.elevated() |
464 | - id_proj_map = {} |
465 | if project_id is None: |
466 | - raise Exception("get_project_and_global_net_ids must be called" \ |
467 | - " with a non-null project_id") |
468 | - tenant_id = project_id |
469 | - all_tenant_blocks = self.m_conn.get_blocks(tenant_id) |
470 | - for b in all_tenant_blocks['ip_blocks']: |
471 | - id_proj_map[b['network_id']] = tenant_id |
472 | - tenant_id = FLAGS.quantum_default_tenant_id |
473 | - all_provider_blocks = self.m_conn.get_blocks(tenant_id) |
474 | - for b in all_provider_blocks['ip_blocks']: |
475 | - id_proj_map[b['network_id']] = tenant_id |
476 | - |
477 | - id_priority_map = {} |
478 | - for net_id, project_id in id_project_map.item(): |
479 | - network = db.network_get_by_uuid(admin_context, net_id) |
480 | - if network is None: |
481 | - del id_proj_map[net_id] |
482 | - else: |
483 | - id_priority_map[net_id] = network['priority'] |
484 | - return sorted(id_priority_map.items(), |
485 | - key=lambda x: id_priority_map[x[0]]) |
486 | + raise Exception(_("get_project_and_global_net_ids must be called" |
487 | + " with a non-null project_id")) |
488 | + |
489 | + admin_context = context.elevated() |
490 | + |
491 | + # Decorate with priority |
492 | + priority_nets = [] |
493 | + for tenant_id in (project_id, FLAGS.quantum_default_tenant_id): |
494 | + blocks = self.m_conn.get_blocks(tenant_id) |
495 | + for ip_block in blocks['ip_blocks']: |
496 | + network_id = ip_block['network_id'] |
497 | + network = db.network_get_by_uuid(admin_context, network_id) |
498 | + if network: |
499 | + priority = network['priority'] |
500 | + priority_nets.append((priority, network_id, tenant_id)) |
501 | + |
502 | + # Sort by priority |
503 | + priority_nets.sort() |
504 | + |
505 | + # Undecorate |
506 | + return [(network_id, tenant_id) |
507 | + for priority, network_id, tenant_id in priority_nets] |
508 | |
509 | def get_subnets_by_net_id(self, context, project_id, net_id): |
510 | """ Returns information about the IPv4 and IPv6 subnets |
511 | associated with a Quantum Network UUID. |
512 | """ |
513 | |
514 | - # FIXME: (danwent) Melange actually returns the subnet info |
515 | - # when we query for a particular interface. we may want to |
516 | - # reworks the ipam_manager python API to let us take advantage of |
517 | + # FIXME(danwent): Melange actually returns the subnet info |
518 | + # when we query for a particular interface. We may want to |
519 | + # rework the ipam_manager python API to let us take advantage of |
520 | # this, as right now we have to get all blocks and cycle through |
521 | # them. |
522 | subnet_v4 = None |
523 | @@ -148,12 +148,12 @@ |
524 | for b in all_blocks['ip_blocks']: |
525 | if b['network_id'] == net_id: |
526 | subnet = {'network_id': b['network_id'], |
527 | - 'cidr': b['cidr'], |
528 | - 'gateway': b['gateway'], |
529 | - 'broadcast': b['broadcast'], |
530 | - 'netmask': b['netmask'], |
531 | - 'dns1': b['dns1'], |
532 | - 'dns2': b['dns2']} |
533 | + 'cidr': b['cidr'], |
534 | + 'gateway': b['gateway'], |
535 | + 'broadcast': b['broadcast'], |
536 | + 'netmask': b['netmask'], |
537 | + 'dns1': b['dns1'], |
538 | + 'dns2': b['dns2']} |
539 | |
540 | if IPNetwork(b['cidr']).version == 6: |
541 | subnet_v6 = subnet |
542 | @@ -182,8 +182,8 @@ |
543 | """ |
544 | tenant_id = project_id or FLAGS.quantum_default_tenant_id |
545 | ip_list = self.m_conn.get_allocated_ips(net_id, vif_id, tenant_id) |
546 | - return [ip['address'] for ip in ip_list \ |
547 | - if IPNetwork(ip['address']).version == ip_version] |
548 | + return [ip['address'] for ip in ip_list |
549 | + if IPNetwork(ip['address']).version == ip_version] |
550 | |
551 | def verify_subnet_exists(self, context, project_id, quantum_net_id): |
552 | """ Confirms that a subnet exists that is associated with the |
553 | |
554 | === modified file 'nova/network/quantum/nova_ipam_lib.py' |
555 | --- nova/network/quantum/nova_ipam_lib.py 2011-08-29 02:13:02 +0000 |
556 | +++ nova/network/quantum/nova_ipam_lib.py 2011-09-01 05:49:24 +0000 |
557 | @@ -36,7 +36,7 @@ |
558 | return QuantumNovaIPAMLib(net_man) |
559 | |
560 | |
561 | -class QuantumNovaIPAMLib: |
562 | +class QuantumNovaIPAMLib(object): |
563 | """ Implements Quantum IP Address Management (IPAM) interface |
564 | using the local Nova database. This implementation is inline |
565 | with how IPAM is used by other NetworkManagers. |
566 | @@ -50,9 +50,9 @@ |
567 | self.net_manager = net_manager |
568 | |
569 | def create_subnet(self, context, label, tenant_id, |
570 | - quantum_net_id, priority, cidr=None, |
571 | - gateway_v6=None, cidr_v6=None, |
572 | - dns1=None, dns2=None): |
573 | + quantum_net_id, priority, cidr=None, |
574 | + gateway_v6=None, cidr_v6=None, |
575 | + dns1=None, dns2=None): |
576 | """ Re-use the basic FlatManager create_networks method to |
577 | initialize the networks and fixed_ips tables in Nova DB. |
578 | |
579 | @@ -60,6 +60,7 @@ |
580 | are needed by Quantum but not the FlatManager. |
581 | """ |
582 | admin_context = context.elevated() |
583 | + # FIXME(danwent): Use the netaddr library here |
584 | subnet_size = int(math.pow(2, (32 - int(cidr.split("/")[1])))) |
585 | networks = manager.FlatManager.create_networks(self.net_manager, |
586 | admin_context, label, cidr, |
587 | @@ -67,12 +68,12 @@ |
588 | gateway_v6, quantum_net_id, None, dns1, dns2) |
589 | |
590 | if len(networks) != 1: |
591 | - raise Exception("Error creating network entry") |
592 | + raise Exception(_("Error creating network entry")) |
593 | |
594 | network = networks[0] |
595 | net = {"project_id": tenant_id, |
596 | - "priority": priority, |
597 | - "uuid": quantum_net_id} |
598 | + "priority": priority, |
599 | + "uuid": quantum_net_id} |
600 | db.network_update(admin_context, network['id'], net) |
601 | |
602 | def get_network_id_by_cidr(self, context, cidr, project_id): |
603 | @@ -80,7 +81,8 @@ |
604 | admin_context = context.elevated() |
605 | network = db.network_get_by_cidr(admin_context, cidr) |
606 | if not network: |
607 | - raise Exception("No network with fixed_range = %s" % fixed_range) |
608 | + raise Exception(_("No network with fixed_range = %s" % |
609 | + fixed_range)) |
610 | return network['uuid'] |
611 | |
612 | def delete_subnets_by_net_id(self, context, net_id, project_id): |
613 | @@ -90,10 +92,10 @@ |
614 | admin_context = context.elevated() |
615 | network = db.network_get_by_uuid(admin_context, net_id) |
616 | if not network: |
617 | - raise Exception("No network with net_id = %s" % net_id) |
618 | + raise Exception(_("No network with net_id = %s" % net_id)) |
619 | manager.FlatManager.delete_network(self.net_manager, |
620 | - admin_context, network['cidr'], |
621 | - require_disassociated=False) |
622 | + admin_context, network['cidr'], |
623 | + require_disassociated=False) |
624 | |
625 | def get_project_and_global_net_ids(self, context, project_id): |
626 | """ Fetches all networks associated with this project, or |
627 | @@ -118,8 +120,8 @@ |
628 | network = db.network_get_by_uuid(admin_context, quantum_net_id) |
629 | if network['cidr']: |
630 | address = db.fixed_ip_associate_pool(admin_context, |
631 | - network['id'], |
632 | - vif_rec['instance_id']) |
633 | + network['id'], |
634 | + vif_rec['instance_id']) |
635 | values = {'allocated': True, |
636 | 'virtual_interface_id': vif_rec['id']} |
637 | db.fixed_ip_update(admin_context, address, values) |
638 | @@ -186,10 +188,10 @@ |
639 | admin_context = context.elevated() |
640 | fixed_ips = db.fixed_ip_get_by_virtual_interface(admin_context, |
641 | vif_ref['id']) |
642 | - for f in fixed_ips: |
643 | - db.fixed_ip_update(admin_context, f['address'], |
644 | - {'allocated': False, |
645 | - 'virtual_interface_id': None}) |
646 | + for fixed_ip in fixed_ips: |
647 | + db.fixed_ip_update(admin_context, fixed_ip['address'], |
648 | + {'allocated': False, |
649 | + 'virtual_interface_id': None}) |
650 | except exception.FixedIpNotFoundForInstance: |
651 | - LOG.error(_('No fixed IPs to deallocate for vif %s' % \ |
652 | - vif_ref['id'])) |
653 | + LOG.error(_('No fixed IPs to deallocate for vif %s' % |
654 | + vif_ref['id'])) |
655 | |
656 | === modified file 'nova/network/quantum/quantum_connection.py' |
657 | --- nova/network/quantum/quantum_connection.py 2011-08-29 02:13:02 +0000 |
658 | +++ nova/network/quantum/quantum_connection.py 2011-09-01 05:49:24 +0000 |
659 | @@ -37,7 +37,7 @@ |
660 | 'Default tenant id when creating quantum networks') |
661 | |
662 | |
663 | -class QuantumClientConnection: |
664 | +class QuantumClientConnection(object): |
665 | """ Abstracts connection to Quantum service into higher level |
666 | operations performed by the QuantumManager. |
667 | |
668 | @@ -71,7 +71,7 @@ |
669 | try: |
670 | self.client.show_network_details(net_id, tenant=tenant_id) |
671 | except: |
672 | - # FIXME: (danwent) client lib should expose granular exceptions |
673 | + # FIXME(danwent): client lib should expose granular exceptions |
674 | # so we can confirm we're getting a 404 and not some other error |
675 | return False |
676 | return True |
677 | @@ -81,8 +81,8 @@ |
678 | status to ACTIVE to enable traffic, and attaches the |
679 | vNIC with the specified interface-id. |
680 | """ |
681 | - LOG.debug("Connecting interface %s to net %s for %s" % \ |
682 | - (interface_id, net_id, tenant_id)) |
683 | + LOG.debug(_("Connecting interface %s to net %s for %s" % |
684 | + (interface_id, net_id, tenant_id))) |
685 | port_data = {'port': {'state': 'ACTIVE'}} |
686 | resdict = self.client.create_port(net_id, port_data, tenant=tenant_id) |
687 | port_id = resdict["port"]["id"] |
688 | @@ -103,7 +103,7 @@ |
689 | """ Given a tenant, search for the Quantum network and port |
690 | UUID that has the specified interface-id attachment. |
691 | """ |
692 | - # FIXME: (danwent) this will be inefficient until the Quantum |
693 | + # FIXME(danwent): this will be inefficient until the Quantum |
694 | # API implements querying a port by the interface-id |
695 | net_list_resdict = self.client.list_networks(tenant=tenant_id) |
696 | for n in net_list_resdict["networks"]: |
697 | |
698 | === modified file 'nova/tests/test_quantum.py' |
699 | --- nova/tests/test_quantum.py 2011-08-29 03:00:38 +0000 |
700 | +++ nova/tests/test_quantum.py 2011-09-01 05:49:24 +0000 |
701 | @@ -155,9 +155,9 @@ |
702 | self.assertTrue(nw_info[1][0]['cidr_v6'].startswith("2001:1db8:")) |
703 | |
704 | # v6 address |
705 | - self.assertTrue(\ |
706 | + self.assertTrue( |
707 | nw_info[0][1]['ip6s'][0]['ip'].startswith("2001:1dba:")) |
708 | - self.assertTrue(\ |
709 | + self.assertTrue( |
710 | nw_info[1][1]['ip6s'][0]['ip'].startswith("2001:1db8:")) |
711 | |
712 | self.net_man.deallocate_for_instance(ctx, |
713 | @@ -233,24 +233,24 @@ |
714 | self.net_man = quantum_manager.QuantumManager( \ |
715 | ipam_lib="nova.network.quantum.nova_ipam_lib") |
716 | |
717 | - # tests seem to create some networks by default, which |
718 | - # don't want. So we delete them. |
719 | + # Tests seem to create some networks by default, which |
720 | + # we don't want. So we delete them. |
721 | |
722 | ctx = context.RequestContext('user1', 'fake_project1').elevated() |
723 | for n in db.network_get_all(ctx): |
724 | db.network_delete_safe(ctx, n['id']) |
725 | |
726 | - # I've found that other unit tests have a nasty habit of |
727 | - # of creating fixed IPs and not cleaning up, which can |
728 | - # confuse these tests, so we clean them all. |
729 | + # NOTE(danwent): I've found that other unit tests have a nasty |
730 | + # habit of of creating fixed IPs and not cleaning up, which |
731 | + # can confuse these tests, so we clean them all. |
732 | session = get_session() |
733 | result = session.query(models.FixedIp).all() |
734 | with session.begin(): |
735 | for fip_ref in result: |
736 | session.delete(fip_ref) |
737 | |
738 | -# Cannot run this unit tests auotmatically for now, as it requires |
739 | -# melange to be running locally. |
740 | +# FIXME(danwent): Cannot run this unit tests automatically for now, as |
741 | +# it requires melange to be running locally. |
742 | # |
743 | #class QuantumMelangeIPAMTestCase(QuantumTestCaseBase, test.TestCase): |
744 | # |