Merge lp:~midokura/nova/network-service into lp:~ntt-pf-lab/nova/network-service

Proposed by Ryu Ishimoto
Status: Merged
Merge reported by: Ryu Ishimoto
Merged at revision: not available
Proposed branch: lp:~midokura/nova/network-service
Merge into: lp:~ntt-pf-lab/nova/network-service
Diff against target: 1969 lines (+633/-357)
13 files modified
bin/nova-net-flat-vlan-manage (+192/-0)
nova/api/ec2/cloud.py (+31/-9)
nova/compute/api.py (+0/-6)
nova/network/flat_vlan/api/__init__.py (+93/-7)
nova/network/flat_vlan/common.py (+12/-0)
nova/network/flat_vlan/compute.py (+7/-18)
nova/network/flat_vlan/db/__init__.py (+1/-0)
nova/network/flat_vlan/db/api.py (+84/-51)
nova/network/flat_vlan/db/sqlalchemy/api.py (+14/-64)
nova/network/flat_vlan/db/sqlalchemy/models.py (+48/-84)
nova/network/flat_vlan/network.py (+87/-66)
nova/network/service.py (+63/-48)
nova/virt/libvirt_conn.py (+1/-4)
To merge this branch: bzr merge lp:~midokura/nova/network-service
Reviewer Review Type Date Requested Status
NTT PF Lab. Pending
Review via email: mp+56616@code.launchpad.net

Commit message

Added EC2 floating IP API support.

Description of the change

Added EC2 floating IP API support.

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=== added file 'bin/nova-net-flat-vlan-manage'
2--- bin/nova-net-flat-vlan-manage 1970-01-01 00:00:00 +0000
3+++ bin/nova-net-flat-vlan-manage 2011-04-06 17:14:53 +0000
4@@ -0,0 +1,192 @@
5+#!/usr/bin/env python
6+# vim: tabstop=4 shiftwidth=4 softtabstop=4
7+
8+# Copyright 2011 Midokura KK
9+# All Rights Reserved.
10+#
11+# Licensed under the Apache License, Version 2.0 (the "License"); you may
12+# not use this file except in compliance with the License. You may obtain
13+# a copy of the License at
14+#
15+# http://www.apache.org/licenses/LICENSE-2.0
16+#
17+# Unless required by applicable law or agreed to in writing, software
18+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
19+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
20+# License for the specific language governing permissions and limitations
21+# under the License.
22+
23+# Interactive shell based on Django:
24+#
25+# Copyright (c) 2005, the Lawrence Journal-World
26+# All rights reserved.
27+#
28+# Redistribution and use in source and binary forms, with or without
29+# modification, are permitted provided that the following conditions are met:
30+#
31+# 1. Redistributions of source code must retain the above copyright notice,
32+# this list of conditions and the following disclaimer.
33+#
34+# 2. Redistributions in binary form must reproduce the above copyright
35+# notice, this list of conditions and the following disclaimer in the
36+# documentation and/or other materials provided with the distribution.
37+#
38+# 3. Neither the name of Django nor the names of its contributors may be
39+# used to endorse or promote products derived from this software without
40+# specific prior written permission.
41+#
42+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
43+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
44+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
45+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
46+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
47+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
48+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
49+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
50+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
52+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53+
54+
55+"""
56+ CLI interface for nova flat vlan network management.
57+"""
58+
59+import gettext
60+import os
61+import sys
62+
63+import IPy
64+
65+# If ../nova/__init__.py exists, add ../ to Python search path, so that
66+# it will override what happens to be installed in /usr/(local/)lib/python...
67+possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
68+ os.pardir,
69+ os.pardir))
70+if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
71+ sys.path.insert(0, possible_topdir)
72+
73+gettext.install('nova', unicode=1)
74+
75+from nova import context
76+from nova import db as nova_db
77+from nova import exception
78+from nova import flags as nova_flags
79+from nova import log as logging
80+from nova import utils
81+
82+from nova.network.flat_vlan import db
83+
84+NOVA_FLAGS = nova_flags.FLAGS
85+
86+class FloatingIpCommands(object):
87+ """Class for managing floating ip."""
88+
89+ def create(self, host, range):
90+ """Creates floating ips for host by range
91+ arguments: host ip_range"""
92+ for address in IPy.IP(range):
93+ db.floating_ip_create(context.get_admin_context(),
94+ {'address': str(address),
95+ 'host': host})
96+
97+ def delete(self, ip_range):
98+ """Deletes floating ips by range
99+ arguments: range"""
100+ for address in IPy.IP(ip_range):
101+ db.floating_ip_destroy(context.get_admin_context(),
102+ str(address))
103+
104+ def list(self, host=None):
105+ """Lists all floating ips (optionally by host)
106+ arguments: [host]"""
107+ ctxt = context.get_admin_context()
108+ if host == None:
109+ floating_ips = db.floating_ip_get_all(ctxt)
110+ else:
111+ floating_ips = db.floating_ip_get_all_by_host(ctxt, host)
112+ for floating_ip in floating_ips:
113+ instance_id = None
114+ fixed_ip = floating_ip['fixed_ip']
115+ if fixed_ip and fixed_ip['ethernet_card_id']:
116+ vnic_id = fixed_ip['ethernet_card_id']
117+ instance = nova_db.instance_get_by_virtual_nic(ctxt,
118+ vnic_id)
119+ instance_id = instance['ec2_id']
120+ print "%s\t%s\t%s" % (floating_ip['host'],
121+ floating_ip['address'],
122+ instance_id)
123+
124+
125+CATEGORIES = [
126+ ('floating', FloatingIpCommands)]
127+
128+def lazy_match(name, key_value_tuples):
129+ """Finds all objects that have a key that case insensitively contains
130+ [name] key_value_tuples is a list of tuples of the form (key, value)
131+ returns a list of tuples of the form (key, value)"""
132+ result = []
133+ for (k, v) in key_value_tuples:
134+ if k.lower().find(name.lower()) == 0:
135+ result.append((k, v))
136+ if len(result) == 0:
137+ print "%s does not match any options:" % name
138+ for k, _v in key_value_tuples:
139+ print "\t%s" % k
140+ sys.exit(2)
141+ if len(result) > 1:
142+ print "%s matched multiple options:" % name
143+ for k, _v in result:
144+ print "\t%s" % k
145+ sys.exit(2)
146+ return result
147+
148+def methods_of(obj):
149+ """Get all callable methods of an object that don't start with underscore
150+ returns a list of tuples of the form (method_name, method)"""
151+ result = []
152+ for i in dir(obj):
153+ if callable(getattr(obj, i)) and not i.startswith('_'):
154+ result.append((i, getattr(obj, i)))
155+ return result
156+
157+
158+def main():
159+ """Parse options and call the appropriate class/method."""
160+ utils.default_flagfile()
161+ argv = NOVA_FLAGS(sys.argv)
162+ logging.setup()
163+
164+ script_name = argv.pop(0)
165+ if len(argv) < 1:
166+ print script_name + " category action [<args>]"
167+ print "Available categories:"
168+ for k, _ in CATEGORIES:
169+ print "\t%s" % k
170+ sys.exit(2)
171+ category = argv.pop(0)
172+ matches = lazy_match(category, CATEGORIES)
173+ # instantiate the command group object
174+ category, fn = matches[0]
175+ command_object = fn()
176+ actions = methods_of(command_object)
177+ if len(argv) < 1:
178+ print script_name + " category action [<args>]"
179+ print "Available actions for %s category:" % category
180+ for k, _v in actions:
181+ print "\t%s" % k
182+ sys.exit(2)
183+ action = argv.pop(0)
184+ matches = lazy_match(action, actions)
185+ action, fn = matches[0]
186+ # call the action with the remaining arguments
187+ try:
188+ fn(*argv)
189+ sys.exit(0)
190+ except TypeError:
191+ print "Possible wrong number of arguments supplied"
192+ print "%s %s: %s" % (category, action, fn.__doc__)
193+ raise
194+
195+if __name__ == '__main__':
196+ main()
197
198=== modified file 'nova/api/ec2/cloud.py'
199--- nova/api/ec2/cloud.py 2011-03-24 20:20:15 +0000
200+++ nova/api/ec2/cloud.py 2011-04-06 17:14:53 +0000
201@@ -36,7 +36,8 @@
202 from nova import exception
203 from nova import flags
204 from nova import log as logging
205-from nova import network
206+from nova.network import service as net_service
207+from nova import quota
208 from nova import utils
209 from nova import volume
210 from nova.api.ec2 import ec2utils
211@@ -82,10 +83,9 @@
212 """
213 def __init__(self):
214 self.image_service = s3.S3ImageService()
215- self.network_api = network.API()
216 self.volume_api = volume.API()
217 self.compute_api = compute.API(
218- network_api=self.network_api,
219+ network_api=None,
220 volume_api=self.volume_api,
221 hostname_factory=ec2utils.id_to_ec2_id)
222 self.setup()
223@@ -767,26 +767,48 @@
224
225 def allocate_address(self, context, **kwargs):
226 LOG.audit(_("Allocate address"), context=context)
227- public_ip = self.network_api.allocate_floating_ip(context)
228+ _, net_factory = net_service.get_service_factory(context,
229+ context.project_id)
230+ net_api_service = net_factory.get_api_service()
231+ ip_quota = quota.get_quota(context, context.project_id)['floating_ips']
232+ try:
233+ public_ip = net_api_service.allocate_address(context,
234+ context.project_id,
235+ ip_quota)
236+ except quota.QuotaError, ex:
237+ LOG.warn(_("Quota exceeded for %s, tried to allocate "
238+ "address"),
239+ context.project_id)
240+ raise ex
241+
242 return {'addressSet': [{'publicIp': public_ip}]}
243
244 def release_address(self, context, public_ip, **kwargs):
245 LOG.audit(_("Release address %s"), public_ip, context=context)
246- self.network_api.release_floating_ip(context, address=public_ip)
247+ _, net_factory = net_service.get_service_factory(context,
248+ context.project_id)
249+ net_api_service = net_factory.get_api_service()
250+
251+ net_api_service.deallocate_address(context, public_ip)
252 return {'releaseResponse': ["Address released."]}
253
254 def associate_address(self, context, instance_id, public_ip, **kwargs):
255 LOG.audit(_("Associate address %(public_ip)s to"
256 " instance %(instance_id)s") % locals(), context=context)
257 instance_id = ec2utils.ec2_id_to_id(instance_id)
258- self.compute_api.associate_floating_ip(context,
259- instance_id=instance_id,
260- address=public_ip)
261+ vnic_ids = db.virtual_nics_get_by_instance(context, instance_id)
262+ _, net_factory = net_service.get_service_factory(context,
263+ context.project_id)
264+ net_api_service = net_factory.get_api_service()
265+ net_api_service.associate_address(context, vnic_ids[0], public_ip)
266 return {'associateResponse': ["Address associated."]}
267
268 def disassociate_address(self, context, public_ip, **kwargs):
269 LOG.audit(_("Disassociate address %s"), public_ip, context=context)
270- self.network_api.disassociate_floating_ip(context, address=public_ip)
271+ _, net_factory = net_service.get_service_factory(context,
272+ context.project_id)
273+ net_api_service = net_factory.get_api_service()
274+ net_api_service.disassociate_address(context, public_ip)
275 return {'disassociateResponse': ["Address disassociated."]}
276
277 def run_instances(self, context, **kwargs):
278
279=== modified file 'nova/compute/api.py'
280--- nova/compute/api.py 2011-03-30 08:30:38 +0000
281+++ nova/compute/api.py 2011-04-06 17:14:53 +0000
282@@ -681,12 +681,6 @@
283 "volume_id": volume_id}})
284 return instance
285
286- def associate_floating_ip(self, context, instance_id, address):
287- instance = self.get(context, instance_id)
288- self.network_api.associate_floating_ip(context,
289- floating_ip=address,
290- fixed_ip=instance['fixed_ip'])
291-
292 def get_instance_metadata(self, context, instance_id):
293 """Get all metadata associated with an instance."""
294 rv = self.db.instance_metadata_get(context, instance_id)
295
296=== modified file 'nova/network/flat_vlan/api/__init__.py'
297--- nova/network/flat_vlan/api/__init__.py 2011-03-31 07:15:23 +0000
298+++ nova/network/flat_vlan/api/__init__.py 2011-04-06 17:14:53 +0000
299@@ -16,19 +16,26 @@
300 # under the License.
301 from zope import interface
302
303+from nova import exception
304+from nova import quota
305+from nova import rpc
306 from nova.network import service
307+from nova.network.flat_vlan import common
308+from nova.network.flat_vlan import flags
309 from nova.network.flat_vlan import manager
310-from nova.network.flat_vlan.db import api as db_api
311+from nova.network.flat_vlan import db
312+
313+FLAGS = flags.FlagAccessor()
314
315 class NetworkApiService(object):
316 """Network API Service for this plugin."""
317-
318+
319 interface.implements(service.INetworkApiService)
320
321 def create_vnic(self, context):
322 """Generic API to retrieve the default VNIC ID.
323 For flat simple network, create a new vNIC and return its ID.
324-
325+
326 Args:
327 context: Nova context object needed to access the DB.
328
329@@ -38,20 +45,99 @@
330 # Create a new VNIC
331 vnic = manager.ethernet_card_create_with_random_mac(context)
332 return vnic.id
333-
334+
335 def get_project_vpn_address_and_port(self, context, project_id):
336 """Generic API to get network for a given project.
337-
338+
339 Args:
340 context: Nova context object needed to access the DB.
341 project_id: project to get the VPN IP and port for.
342-
343+
344 Returns:
345 A tuple of VPN IP address and port number.
346 """
347- network = db_api.network_get_by_project(context, project_id)
348+ network = db.network_get_by_project(context, project_id)
349 if network:
350 return (network['vpn_public_address'], network['vpn_public_port'])
351 else:
352 return (None, None)
353
354+ def allocate_address(self, context, project_id, ip_quota):
355+ """Gets the number of floating IPs associated with a project.
356+
357+ Args:
358+ context: Nova context object needed to access the DB.
359+ project_id: Project to allocate the address from.
360+ ip_quota: Quota for IP addresses.
361+
362+ Returns:
363+ An IP address.
364+
365+ Raises:
366+ quota.QuotaError: Over the quota limit.
367+ """
368+ used_floating_ips = db.floating_ip_count_by_project(context,
369+ project_id)
370+ allowed_floating_ips = min(1, ip_quota - used_floating_ips)
371+ if allowed_floating_ips < 1:
372+ raise quota.QuotaError(_("Quota exceeeded for %s, tried to allocate"
373+ " address"), project_id)
374+
375+ # Let the network service handle this because the DB update requires the
376+ # network service host name.
377+ host = rpc.call(context,
378+ FLAGS.net_flat_vlan_network_topic,
379+ {"method": "get_host"})
380+
381+ ip = db.floating_ip_allocate_address(context, host, project_id)
382+ return ip.address
383+
384+ def deallocate_address(self, context, floating_address):
385+ """Deallocates the public IP address by removing it from any
386+ project.
387+
388+ Args:
389+ context: nova context object needed to access the DB.
390+ address: Public IP address to deallocate.
391+ """
392+ db.floating_ip_deallocate(context, floating_address)
393+
394+ def associate_address(self, context, vnic_id, floating_address):
395+ """Associates a floating address to the fixed IP address of the vnic.
396+
397+ Args:
398+ context: Nova context object
399+ vnic_id: virtual NIC ID
400+ floating_address: public IP address to assign to the VNIC.
401+ """
402+ fixed_ip = db.fixed_ip_get_by_ethernet_card(context, vnic_id)
403+ floating_ip = db.floating_ip_get_by_address(context, floating_address)
404+ db.floating_ip_fixed_ip_associate(context, floating_ip['address'],
405+ fixed_ip['address'])
406+
407+ host = fixed_ip['network']['host']
408+ rpc.cast(context,
409+ common.queue_get_for(FLAGS.net_flat_vlan_network_topic,
410+ host),
411+ {"method": "activate_public_ip",
412+ "args": {"floating_address": floating_ip['address'],
413+ "fixed_address": fixed_ip['address']}})
414+
415+ def disassociate_address(self, context, floating_address):
416+ """Diassociates public IP.
417+
418+ Args:
419+ context: Nova context object
420+ floating_address: public IP address
421+ """
422+ floating_ip = db.floating_ip_get_by_address(context, floating_address)
423+ if not floating_ip.get('fixed_ip'):
424+ raise exception.ApiError('Address is not associated.')
425+ fixed_ip = db.floating_ip_disassociate(context, floating_address)
426+ host = fixed_ip['network']['host']
427+ rpc.cast(context,
428+ common.queue_get_for(FLAGS.net_flat_vlan_network_topic,
429+ host),
430+ {"method": "deactivate_public_ip",
431+ "args": {"floating_address": floating_ip['address'],
432+ "fixed_address": fixed_ip['address']}})
433
434=== modified file 'nova/network/flat_vlan/common.py'
435--- nova/network/flat_vlan/common.py 2011-03-31 09:36:57 +0000
436+++ nova/network/flat_vlan/common.py 2011-04-06 17:14:53 +0000
437@@ -44,3 +44,15 @@
438 """
439 net = IPy.IP(cidr)
440 return str(net.net()), str(net.netmask())
441+
442+def queue_get_for(topic, physical_node_id):
443+ """Gets the queue name for RPC.
444+
445+ Args:
446+ topic: Topic to listen to
447+ physical_node_id: Node ID to listen to.
448+
449+ Returns:
450+ The queue name to send the RPC to.
451+ """
452+ return "%s.%s" % (topic, physical_node_id)
453\ No newline at end of file
454
455=== modified file 'nova/network/flat_vlan/compute.py'
456--- nova/network/flat_vlan/compute.py 2011-04-04 09:52:18 +0000
457+++ nova/network/flat_vlan/compute.py 2011-04-06 17:14:53 +0000
458@@ -26,18 +26,6 @@
459
460 FLAGS = flags.FlagAccessor()
461
462-def _queue_get_for(topic, physical_node_id):
463- """Gets the queue name for RPC.
464-
465- Args:
466- topic: Topic to listen to
467- physical_node_id: Node ID to listen to.
468-
469- Returns:
470- The queue name to send the RPC to.
471- """
472- return "%s.%s" % (topic, physical_node_id)
473-
474 def _get_network_topic(context, **kwargs):
475 """Retrieves the network host for a project on this host
476
477@@ -51,8 +39,8 @@
478 host = FLAGS.net_flat_vlan_network_host
479 else:
480 host = _get_network_host(context)
481- return _queue_get_for(FLAGS.net_flat_vlan_network_topic,
482- host)
483+ return common.queue_get_for(FLAGS.net_flat_vlan_network_topic,
484+ host)
485
486 def _set_network_host(context, network_id):
487 """Safely sets the host of the network.
488@@ -87,8 +75,8 @@
489 FLAGS.net_flat_vlan_network_bridge)
490 host = network_ref['host']
491 if not host:
492- topic = _queue_get_for(FLAGS.net_flat_vlan_network_topic,
493- FLAGS.net_flat_vlan_network_host)
494+ topic = common.queue_get_for(FLAGS.net_flat_vlan_network_topic,
495+ FLAGS.net_flat_vlan_network_host)
496 if FLAGS.net_flat_vlan_network_fake_call:
497 return _set_network_host(context, network_ref['id'])
498 host = rpc.call(context,
499@@ -146,7 +134,8 @@
500 vnic_ids: list of VNIC IDs
501 """
502 for vnic_id in vnic_ids:
503- fixed_ip = vnic_id.get('fixed_ip')
504+ vnic_ref = db_api.ethernet_card_get(context, vnic_id)
505+ fixed_ip = vnic_ref.get('fixed_ip')
506 if not FLAGS.stub_network and fixed_ip:
507
508 if (FLAGS.net_flat_vlan_use_vlan or
509@@ -156,7 +145,7 @@
510 for floating_ip in floating_ips:
511 address = floating_ip['address']
512
513- network_topic = _queue_get_for(context,
514+ network_topic = common.queue_get_for(context,
515 FLAGS.net_flat_vlan_network_topic,
516 floating_ip['host'])
517
518
519=== modified file 'nova/network/flat_vlan/db/__init__.py'
520--- nova/network/flat_vlan/db/__init__.py 2011-03-31 06:18:29 +0000
521+++ nova/network/flat_vlan/db/__init__.py 2011-04-06 17:14:53 +0000
522@@ -18,3 +18,4 @@
523 DB abstraction for Flat VLAN network service
524 """
525
526+from nova.network.flat_vlan.db.api import *
527
528=== modified file 'nova/network/flat_vlan/db/api.py'
529--- nova/network/flat_vlan/db/api.py 2011-04-02 19:01:17 +0000
530+++ nova/network/flat_vlan/db/api.py 2011-04-06 17:14:53 +0000
531@@ -19,85 +19,95 @@
532
533 The underlying driver is loaded as a :class:`LazyPluggable`.
534 """
535+from nova import exception
536 from nova import utils
537+from nova.db.sqlalchemy import api as nova_api
538 from nova.network.flat_vlan import flags
539
540 FLAGS = flags.FlagAccessor()
541
542-IMPL = utils.LazyPluggable(FLAGS.get('net_flat_vlan_db_backend'),
543- sqlalchemy='nova.network.flat_vlan.db.sqlalchemy.api')
544+IMPL = utils.LazyPluggable(
545+ FLAGS.get('net_flat_vlan_db_backend'),
546+ sqlalchemy='nova.network.flat_vlan.db.sqlalchemy.api')
547
548 ###################
549
550 def ethernet_card_get(context, id):
551 """Get ethernet card by id."""
552- return IMPL.dao_factory.get_dao(context).\
553+ return IMPL.dao_factory.get_dao().\
554 ethernet_card_get(id)
555
556 def ethernet_card_create(context, values):
557 """Create a new ethernet card."""
558- return IMPL.dao_factory.get_dao(context).\
559+ return IMPL.dao_factory.get_dao().\
560 ethernet_card_create(values)
561
562 def ethernet_card_get_all(context):
563 """Get all ethernet cards."""
564- return IMPL.dao_factory.get_dao(context).\
565- ethernet_card_get_all()
566+ can_read_deleted = nova_api.can_read_deleted(context)
567+ return IMPL.dao_factory.get_dao().\
568+ ethernet_card_get_all(read_deleted=can_read_deleted)
569
570 def ethernet_card_update(context, ethernet_card_id, values):
571 """Update ethernet card."""
572- return IMPL.dao_factory.get_dao(context).\
573+ return IMPL.dao_factory.get_dao().\
574 ethernet_card_update(ethernet_card_id, values)
575
576 def ethernet_card_delete(context, ethernet_card_id):
577 """Delete ethernet card."""
578- return IMPL.dao_factory.get_dao(context).\
579+ return IMPL.dao_factory.get_dao().\
580 ethernet_card_delete(ethernet_card_id)
581
582 def network_get(context, id):
583 """Get network by id."""
584- return IMPL.dao_factory.get_dao(context).\
585+ return IMPL.dao_factory.get_dao().\
586 network_get(id)
587
588+@nova_api.require_admin_context
589 def network_get_by_ethernet_card(context, ethernet_card_id):
590 """Get network by ethernet card."""
591- return IMPL.dao_factory.get_dao(context).\
592+ return IMPL.dao_factory.get_dao().\
593 network_get_by_ethernet_card(ethernet_card_id)
594
595+@nova_api.require_admin_context
596 def network_get_associated_fixed_ips(context, network_id):
597 """Get fixed IPs that are associated with ethernet for a given network."""
598- return IMPL.dao_factory.get_dao(context).\
599+ return IMPL.dao_factory.get_dao().\
600 network_get_associated_fixed_ips(network_id)
601
602 def host_get_networks(context, host):
603 """Get networks for a given host."""
604- return IMPL.dao_factory.get_dao(context).\
605+ return IMPL.dao_factory.get_dao().\
606 host_get_networks(host)
607
608+@nova_api.require_admin_context
609 def network_get_by_bridge(context, bridge):
610 """Get a network by bridge or raise if it does not exist."""
611- return IMPL.dao_factory.get_dao(context).\
612+ return IMPL.dao_factory.get_dao().\
613 network_get_by_bridge(bridge)
614
615+@nova_api.require_admin_context
616 def network_get_by_cidr(context, cidr):
617 """Get a network by cidr."""
618- return IMPL.dao_factory.get_dao(context).\
619+ return IMPL.dao_factory.get_dao().\
620 network_get_by_cidr(cidr)
621
622 def network_create(context, values):
623 """Create a new network."""
624- return IMPL.dao_factory.get_dao(context).\
625+ return IMPL.dao_factory.get_dao().\
626 network_create(values)
627
628+@nova_api.require_admin_context
629 def network_create_safe(context, values):
630 """Create a new network. Returns None when there is an exception"""
631- return IMPL.dao_factory.get_dao(context).\
632+ return IMPL.dao_factory.get_dao().\
633 network_create_safe(values)
634
635 def network_get_all(context):
636 """Get all networks."""
637- return IMPL.dao_factory.get_dao(context).\
638- network_get_all()
639+ can_read_deleted = nova_api.can_read_deleted(context)
640+ return IMPL.dao_factory.get_dao().\
641+ network_get_all(read_deleted=can_read_deleted)
642
643 def network_get_by_project(context, project_id, associate=True):
644 """Return the network associated with the project.
645@@ -106,22 +116,25 @@
646 network if one is not found, otherwise it returns None.
647
648 """
649- return IMPL.dao_factory.get_dao(context).\
650+ if associate and not nova_api.is_admin_context(context):
651+ raise exception.NotAuthorized()
652+ return IMPL.dao_factory.get_dao().\
653 network_get_by_project(project_id, associate)
654
655 def network_update(context, network_id, values):
656 """Update network."""
657- return IMPL.dao_factory.get_dao(context).\
658+ return IMPL.dao_factory.get_dao().\
659 network_update(network_id, values)
660
661 def network_delete(context, network_id):
662 """Delete network."""
663- return IMPL.dao_factory.get_dao(context).\
664+ return IMPL.dao_factory.get_dao().\
665 network_delete(network_id)
666
667+@nova_api.require_admin_context
668 def network_associate(context, project_id):
669 """Associate a free network to a project."""
670- return IMPL.dao_factory.get_dao(context).\
671+ return IMPL.dao_factory.get_dao().\
672 network_associate(project_id)
673
674 def floating_ip_allocate_address(context, host, project_id):
675@@ -130,32 +143,38 @@
676 Raises if one is not available.
677
678 """
679- return IMPL.dao_factory.get_dao(context).\
680+ nova_api.authorize_project_context(context, project_id)
681+ return IMPL.dao_factory.get_dao().\
682 floating_ip_allocate_address(host, project_id)
683
684 def floating_ip_create(context, values):
685 """Create a floating ip from the values dictionary."""
686- return IMPL.dao_factory.get_dao(context).\
687+ return IMPL.dao_factory.get_dao().\
688 floating_ip_create(values)
689
690 def floating_ip_count_by_project(context, project_id):
691 """Count floating ips used by project."""
692- return IMPL.dao_factory.get_dao(context).\
693+ nova_api.authorize_project_context(context, project_id)
694+ return IMPL.dao_factory.get_dao().\
695 floating_ip_count_by_project(project_id)
696
697 def floating_ip_deallocate(context, address):
698 """Deallocate an floating ip by address"""
699- return IMPL.dao_factory.get_dao(context).\
700+ # TODO(devcamcar): How to ensure floating id belongs to user?
701+ return IMPL.dao_factory.get_dao().\
702 floating_ip_deallocate(address)
703
704 def floating_ip_destroy(context, address):
705 """Destroy the floating_ip or raise if it does not exist."""
706- return IMPL.dao_factory.get_dao(context).\
707+ # TODO(devcamcar): Ensure address belongs to user.
708+ return IMPL.dao_factory.get_dao().\
709 floating_ip_destroy(address)
710
711 def floating_ip_disassociate(context, floating_ip_id):
712 """Diassociate the floating_ip."""
713- return IMPL.dao_factory.get_dao(context).\
714+ # TODO(devcamcar): Ensure address belongs to user.
715+ # Does get_floating_ip_by_address handle this?
716+ return IMPL.dao_factory.get_dao().\
717 floating_ip_disassociate(floating_ip_id)
718
719 def floating_ip_disassociate_by_address(context, address):
720@@ -164,91 +183,105 @@
721 Returns the address of the existing fixed ip.
722
723 """
724- return IMPL.dao_factory.get_dao(context).\
725+ # TODO(devcamcar): Ensure address belongs to user.
726+ # Does get_floating_ip_by_address handle this?
727+ return IMPL.dao_factory.get_dao().\
728 floating_ip_disassociate_by_address(address)
729
730 def floating_ip_fixed_ip_associate(context, floating_address, fixed_address):
731 """Associate an floating ip to a fixed_ip by address."""
732- return IMPL.dao_factory.get_dao(context).\
733+ # TODO(devcamcar): How to ensure floating_id belongs to user?
734+ return IMPL.dao_factory.get_dao().\
735 floating_ip_fixed_ip_associate(floating_address, fixed_address)
736
737+@nova_api.require_admin_context
738 def floating_ip_get_all(context):
739 """Get all floating ips."""
740- return IMPL.dao_factory.get_dao(context).\
741+ return IMPL.dao_factory.get_dao().\
742 floating_ip_get_all()
743
744+@nova_api.require_admin_context
745 def floating_ip_get_all_by_host(context, host):
746 """Get all floating ips by host."""
747- return IMPL.dao_factory.get_dao(context).\
748+ return IMPL.dao_factory.get_dao().\
749 floating_ip_get_all_by_host(host)
750
751 def floating_ip_get_all_by_project(context, project_id):
752 """Get all floating ips by project."""
753- return IMPL.dao_factory.get_dao(context).\
754+ nova_api.authorize_project_context(context, project_id)
755+ return IMPL.dao_factory.get_dao().\
756 floating_ip_get_all_by_project(project_id)
757
758 def floating_ip_get_by_address(context, address):
759 """Get a floating ip by address or raise if it doesn't exist."""
760- return IMPL.dao_factory.get_dao(context).\
761- floating_ip_get_by_address(address)
762+ # TODO(devcamcar): Ensure the address belongs to user.
763+ can_read_deleted = nova_api.can_read_deleted(context)
764+ return IMPL.dao_factory.get_dao().\
765+ floating_ip_get_by_address(address, read_deleted=can_read_deleted)
766
767 def floating_ip_update(context, address, values):
768 """Update a floating ip by address or raise if it doesn't exist."""
769- return IMPL.dao_factory.get_dao(context).\
770+ return IMPL.dao_factory.get_dao().\
771 floating_ip_update(address, values)
772
773 def fixed_ip_create(context, values):
774 """Creates a fixed IP."""
775- return IMPL.dao_factory.get_dao(context).\
776+ return IMPL.dao_factory.get_dao().\
777 fixed_ip_create(values)
778
779 def fixed_ip_get(context, fixed_ip_id):
780 """Gets fixed IP with ID."""
781- return IMPL.dao_factory.get_dao(context).\
782+ return IMPL.dao_factory.get_dao().\
783 fixed_ip_get(fixed_ip_id)
784
785 def fixed_ip_get_all(context):
786 """Gets all the fixed IPs."""
787- return IMPL.dao_factory.get_dao(context).\
788+ return IMPL.dao_factory.get_dao().\
789 fixed_ip_get_all()
790
791 def fixed_ip_get_by_address(context, address):
792 """Get fixed IP by address."""
793- return IMPL.dao_factory.get_dao(context).\
794- fixed_ip_get_by_address(address)
795+ can_read_deleted = nova_api.can_read_deleted(context)
796+ return IMPL.dao_factory.get_dao().\
797+ fixed_ip_get_by_address(address, read_deleted=can_read_deleted)
798
799 def fixed_ip_get_by_ethernet_card(context, ethernet_card_id):
800 """Get IP address by ethernet card id."""
801- return IMPL.dao_factory.get_dao(context).\
802- fixed_ip_get_by_ethernet_card(ethernet_card_id)
803+ can_read_deleted = nova_api.can_read_deleted(context)
804+ return IMPL.dao_factory.get_dao().\
805+ fixed_ip_get_by_ethernet_card(ethernet_card_id,
806+ read_deleted=can_read_deleted)
807
808+@nova_api.require_admin_context
809 def fixed_ip_get_network(context, address):
810 """Gets network of an IP address."""
811- return IMPL.dao_factory.get_dao(context).\
812- fixed_ip_get_network(address)
813+ can_read_deleted = nova_api.can_read_deleted(context)
814+ return IMPL.dao_factory.get_dao().\
815+ fixed_ip_get_network(address, read_deleted=can_read_deleted)
816
817 def fixed_ip_update(context, fixed_ip_id, values):
818 """Update fixed IP."""
819- return IMPL.dao_factory.get_dao(context).\
820+ return IMPL.dao_factory.get_dao().\
821 fixed_ip_update(fixed_ip_id, values)
822
823 def fixed_ip_disassociate(context, fixed_ip_id):
824 """Removes reference to ethernet card from IP."""
825- return IMPL.dao_factory.get_dao(context).\
826+ return IMPL.dao_factory.get_dao().\
827 fixed_ip_disassociate(fixed_id_ip)
828
829 def fixed_ip_associate(context, fixed_ip_id, ethernet_card_id):
830 """Associates an IP address to an ethernet card."""
831- return IMPL.dao_factory.get_dao(context).\
832+ return IMPL.dao_factory.get_dao().\
833 fixed_ip_associate(fixed_ip_id, ethernet_card_id)
834
835+@nova_api.require_admin_context
836 def fixed_ip_associate_pool(context, network_id, ethernet_card_id):
837 """Associates an IP to an ethernet card."""
838- return IMPL.dao_factory.get_dao(context).\
839+ return IMPL.dao_factory.get_dao().\
840 fixed_ip_associate_pool(network_id, ethernet_card_id)
841
842+@nova_api.require_admin_context
843 def fixed_ip_disassociate_all_by_timeout(context, host, time):
844 """Disassociates fixed IP by timeout."""
845- return IMPL.dao_factory.get_dao(context).\
846+ return IMPL.dao_factory.get_dao().\
847 fixed_ip_disassociate_all_by_timeout(host, time)
848-
849\ No newline at end of file
850
851=== modified file 'nova/network/flat_vlan/db/sqlalchemy/api.py'
852--- nova/network/flat_vlan/db/sqlalchemy/api.py 2011-04-02 17:11:15 +0000
853+++ nova/network/flat_vlan/db/sqlalchemy/api.py 2011-04-06 17:14:53 +0000
854@@ -17,81 +17,31 @@
855 """
856 Implementation of SQLAlchemy backend.
857 """
858-
859-from sqlalchemy import or_
860-from sqlalchemy.exc import IntegrityError
861-from sqlalchemy.orm import joinedload_all
862-import warnings
863-
864-from nova import exception
865-from nova.db import api as nova_db
866-from nova.db.sqlalchemy import api as nova_api
867 from nova.network.flat_vlan.db.sqlalchemy import models
868 from nova.network.flat_vlan.db.sqlalchemy.session import get_session
869
870
871-class DataAccessCache(object):
872- """A cache of Data Access Objects specific to sessions and contexts.
873-
874- Creates one DAO object per session and set of context parameter
875- values, and caches it. The parameters currently used in the
876- context are:
877- - nova.db.sqlalchemy.api.is_admin_context(context)
878- - nova.db.sqlalchemy.api.can_read_deleted(context)
879- """
880-
881- def __init__(self, dao_class):
882- self._dao_class = dao_class
883- self._cached_daos = {}
884-
885- def get_dao(self, context, session):
886- """Get a DataAccess object.
887-
888- If no cached DAO has been created for this session and this
889- context's parameter, a new DAO is created and
890- cached. Otherwise, the cached DAO is returned.
891-
892- :param context: The request context.
893- :param session: The SQLAlchemy session to use as the Data
894- Access Object's data source.
895- """
896- is_admin = nova_api.is_admin_context(context)
897- can_read_deleted = nova_api.can_read_deleted(context)
898- key = (session, is_admin, can_read_deleted)
899- dao = self._cached_daos.get(key)
900- if dao is None:
901- dao = self._dao_class(session, is_admin, can_read_deleted)
902- self._cached_daos[key] = dao
903- return dao
904-
905-
906-class DefaultSessionNetworkDataAccessFactory(object):
907- """A DAO factory that lazily uses the default session.
908+class DefaultSessionFlatVlanNetworkDataAccessFactory(object):
909+ """A DAO factory that lazily creates and uses the default session.
910
911 This factory uses the default session for the flat VLAN network
912 service, which it creates lazily when creating the first DAO.
913 """
914
915 def __init__(self):
916- self._dao_cache = DataAccessCache(models.FlatVlanNetworkDataAccess)
917- self._session = None
918-
919- def get_session(self):
920- if self._session is None:
921- self._session = get_session()
922- return self._session
923-
924- def get_dao(self, context):
925+ self._dao = None
926+
927+ def get_dao(self):
928 """Get a DataAccess object.
929
930- If no cached DAO has been created for this context's
931- parameter, a new DAO is created and cached. Otherwise, the
932- cached DAO is returned.
933-
934- :param context: The request context.
935+ If no cached DAO has been created for the default session, a
936+ new DAO is created and cached. Otherwise, the cached DAO is
937+ returned.
938 """
939- return self._dao_cache.get_dao(context, self.get_session())
940-
941-
942-dao_factory = DefaultSessionNetworkDataAccessFactory()
943+ if self._dao is None:
944+ self._dao = models.FlatVlanNetworkDataAccess(get_session())
945+ return self._dao
946+
947+
948+dao_factory = DefaultSessionFlatVlanNetworkDataAccessFactory()
949
950
951=== modified file 'nova/network/flat_vlan/db/sqlalchemy/models.py'
952--- nova/network/flat_vlan/db/sqlalchemy/models.py 2011-04-04 09:52:18 +0000
953+++ nova/network/flat_vlan/db/sqlalchemy/models.py 2011-04-06 17:14:53 +0000
954@@ -22,6 +22,7 @@
955 from sqlalchemy.orm import joinedload, joinedload_all
956 from sqlalchemy import Column, Boolean, Integer, String
957 from sqlalchemy import ForeignKey
958+from sqlalchemy.exc import IntegrityError
959 from sqlalchemy.ext.declarative import declarative_base
960
961 from nova import exception
962@@ -91,26 +92,20 @@
963 'FloatingIp.fixed_ip_id == FixedIp.id,'
964 'FloatingIp.deleted == False)')
965 project_id = Column(String(255))
966- host = Column(String(255)) # , ForeignKey('hosts.id'))
967+ host = Column(String(255)) # , ForeignKey('hosts.id'))
968
969
970 class DataAccess(object):
971 """The base class to implement Data Access Objects.
972 """
973
974- def __init__(self, session, is_admin, can_read_deleted):
975+ def __init__(self, session):
976 """Initialize this Data Access Object.
977
978 :param session: The SQLAlchemy session to use as this Data
979 Access Object's data source.
980- :param is_admin: Indicates if the request context is an
981- administrator.
982- :param can_read_deleted: Indicates if the request context has
983- access to deleted objects.
984 """
985 self._session = session
986- self._is_admin = is_admin
987- self._can_read_deleted = can_read_deleted
988
989
990 class EthernetCardDataAccess(DataAccess):
991@@ -130,9 +125,9 @@
992
993 return result
994
995- def ethernet_card_get_all(self):
996+ def ethernet_card_get_all(self, read_deleted=False):
997 return self._session.query(self.ethernet_card_dto_class).\
998- filter_by(deleted=self._can_read_deleted).\
999+ filter_by(deleted=read_deleted).\
1000 all()
1001
1002 def ethernet_card_create(self, values):
1003@@ -171,8 +166,6 @@
1004 return result
1005
1006 def network_get_by_bridge(self, bridge):
1007- if not self._is_admin:
1008- raise exception.NotAuthorized()
1009 result = self._session.query(self.network_dto_class).\
1010 filter_by(bridge=bridge).\
1011 filter_by(deleted=False).\
1012@@ -184,8 +177,6 @@
1013 return result
1014
1015 def network_get_by_ethernet_card(self, ethernet_card_id):
1016- if not self._is_admin:
1017- raise exception.NotAuthorized()
1018 rv = self._session.query(self.network_dto_class).\
1019 filter_by(deleted=False).\
1020 join(self.network_dto_class.fixed_ips).\
1021@@ -193,7 +184,7 @@
1022 filter_by(deleted=False).\
1023 first()
1024 if not rv:
1025- raise exception.NotFound(_('No network for ethernet card %s') %
1026+ raise exception.NotFound(_('No network for ethernet card %s') %
1027 ethernet_card_id)
1028 return rv
1029
1030@@ -204,9 +195,9 @@
1031 filter_by(host=host).\
1032 all()
1033
1034- def network_get_all(self):
1035+ def network_get_all(self, read_deleted=False):
1036 return self._session.query(self.network_dto_class).\
1037- filter_by(deleted=self._can_read_deleted).\
1038+ filter_by(deleted=read_deleted).\
1039 all()
1040
1041 def network_create(self, values):
1042@@ -216,8 +207,6 @@
1043 return network_ref
1044
1045 def network_create_safe(self, values):
1046- if not self._is_admin:
1047- raise exception.NotAuthorized()
1048 try:
1049 return self.network_create(values)
1050 except IntegrityError:
1051@@ -272,8 +261,6 @@
1052 return result
1053
1054 def network_get_associated_fixed_ips(self, network_id):
1055- if not self._is_admin:
1056- raise exception.NotAuthorized()
1057 return self._session.query(self.fixed_ip_dto_class).\
1058 options(joinedload_all('ethernet_card')).\
1059 filter_by(network_id=network_id).\
1060@@ -283,10 +270,10 @@
1061
1062 network_get_associated_ips = network_get_associated_fixed_ips
1063
1064- def fixed_ip_get_by_address(self, address):
1065+ def fixed_ip_get_by_address(self, address, read_deleted=False):
1066 result = self._session.query(self.fixed_ip_dto_class).\
1067 filter_by(address=address).\
1068- filter_by(deleted=self._can_read_deleted).\
1069+ filter_by(deleted=read_deleted).\
1070 options(joinedload('network')).\
1071 options(joinedload('ethernet_card')).\
1072 first()
1073@@ -301,16 +288,15 @@
1074 fixed_ip_ref.ethernet_card = None
1075 fixed_ip_ref.save(session=self._session)
1076
1077- def fixed_ip_get_by_ethernet_card(self, ethernet_card_id):
1078+ def fixed_ip_get_by_ethernet_card(self, ethernet_card_id,
1079+ read_deleted=False):
1080 result = self._session.query(self.fixed_ip_dto_class).\
1081 filter_by(ethernet_card_id=ethernet_card_id).\
1082- filter_by(deleted=self._can_read_deleted).\
1083+ filter_by(deleted=read_deleted).\
1084 first()
1085 return result
1086
1087 def fixed_ip_disassociate_all_by_timeout(self, host, time):
1088- if not self._is_admin:
1089- raise exception.NotAuthorized()
1090 inner_q = self._session.query(Network.id).\
1091 filter_by(host=host).\
1092 subquery()
1093@@ -330,53 +316,46 @@
1094
1095 floating_ip_dto_class = FloatingIp
1096
1097+ def floating_ip_count_by_project(self, project_id):
1098+ return self._session.query(self.floating_ip_dto_class).\
1099+ filter_by(project_id=project_id).\
1100+ filter_by(deleted=False).\
1101+ count()
1102+
1103 def floating_ip_allocate_address(self, host, project_id):
1104- # TODO: Check authorizations much earlier before calling
1105- # this. Doing that in DB layer is way too late.
1106- # nova_api.authorize_project_context(context, project_id)
1107 with self._session.begin():
1108 floating_ip_ref = self._session.query(self.floating_ip_dto_class).\
1109- filter_by(host=host).\
1110- filter_by(fixed_ip_id=None).\
1111- filter_by(project_id=None).\
1112- filter_by(deleted=False).\
1113- with_lockmode('update').\
1114- first()
1115+ filter_by(host=host).\
1116+ filter_by(fixed_ip_id=None).\
1117+ filter_by(project_id=None).\
1118+ filter_by(deleted=False).\
1119+ with_lockmode('update').\
1120+ first()
1121 # NOTE(vish): if with_lockmode isn't supported, as in sqlite,
1122 # then this has concurrency issues
1123 if not floating_ip_ref:
1124 raise nova_db.NoMoreAddresses()
1125 floating_ip_ref['project_id'] = project_id
1126 self._session.add(floating_ip_ref)
1127- return floating_ip_ref['address']
1128-
1129- def floating_ip_count_by_project(self, project_id):
1130- # TODO: Check authorizations much earlier before calling
1131- # this. Doing that in DB layer is way too late.
1132- # nova_api.authorize_project_context(context, project_id)
1133- return self._session.query(self.floating_ip_dto_class).\
1134- filter_by(project_id=project_id).\
1135- filter_by(deleted=False).\
1136- count()
1137+ return floating_ip_ref
1138
1139 def floating_ip_deallocate(self, address):
1140 with self._session.begin():
1141- # TODO(devcamcar): How to ensure floating id belongs to user?
1142- floating_ip_ref = self.floating_ip_get_by_address(address)
1143+ floating_ip_ref = self.floating_ip_get_by_address(
1144+ address, read_deleted=False)
1145 floating_ip_ref['project_id'] = None
1146 floating_ip_ref.save(session=self._session)
1147
1148 def floating_ip_destroy(self, address):
1149 with self._session.begin():
1150- # TODO(devcamcar): Ensure address belongs to user.
1151- floating_ip_ref = self.floating_ip_get_by_address(address)
1152+ floating_ip_ref = self.floating_ip_get_by_address(
1153+ address, read_deleted=False)
1154 floating_ip_ref.delete(session=self._session)
1155
1156 def floating_ip_disassociate_by_address(self, address):
1157 with self._session.begin():
1158- # TODO(devcamcar): Ensure address belongs to user.
1159- # Does get_floating_ip_by_address handle this?
1160- floating_ip_ref = self.floating_ip_get_by_address(address)
1161+ floating_ip_ref = self.floating_ip_get_by_address(
1162+ address, read_deleted=False)
1163 fixed_ip_ref = floating_ip_ref.fixed_ip
1164 if fixed_ip_ref:
1165 fixed_ip_address = fixed_ip_ref['address']
1166@@ -387,38 +366,32 @@
1167 return fixed_ip_address
1168
1169 def floating_ip_get_all(self):
1170- if not self._is_admin:
1171- raise exception.NotAuthorized()
1172 return self._session.query(self.floating_ip_dto_class).\
1173 options(joinedload_all('fixed_ip.ethernet_card')).\
1174 filter_by(deleted=False).\
1175 all()
1176
1177 def floating_ip_get_all_by_project(self, project_id):
1178- # TODO: Check authorizations much earlier before calling
1179- # this. Doing that in DB layer is way too late.
1180- # nova_api.authorize_project_context(context, project_id)
1181 return self._session.query(self.floating_ip_dto_class).\
1182 options(joinedload_all('fixed_ip.ethernet_card')).\
1183 filter_by(project_id=project_id).\
1184 filter_by(deleted=False).\
1185 all()
1186
1187- def floating_ip_get_by_address(self, address):
1188- # TODO(devcamcar): Ensure the address belongs to user.
1189- result = session.query(self.floating_ip_dto_class).\
1190+ def floating_ip_get_by_address(self, address, read_deleted=False):
1191+ result = self._session.query(self.floating_ip_dto_class).\
1192 options(joinedload_all('fixed_ip.network')).\
1193 filter_by(address=address).\
1194- filter_by(deleted=self._can_read_deleted).\
1195+ filter_by(deleted=read_deleted).\
1196 first()
1197 if not result:
1198 raise exception.NotFound('No floating ip for address %s' % address)
1199-
1200 return result
1201
1202 def floating_ip_update(self, address, values):
1203 with self._session.begin():
1204- floating_ip_ref = self.floating_ip_get_by_address(address)
1205+ floating_ip_ref = self.floating_ip_get_by_address(
1206+ address, read_deleted=False)
1207 for (key, value) in values.iteritems():
1208 floating_ip_ref[key] = value
1209 floating_ip_ref.save(session=self._session)
1210@@ -431,9 +404,8 @@
1211
1212 def floating_ip_disassociate(self, address):
1213 with self._session.begin():
1214- # TODO(devcamcar): Ensure address belongs to user.
1215- # Does get_floating_ip_by_address handle this?
1216- floating_ip_ref = self.floating_ip_get_by_address(address)
1217+ floating_ip_ref = self.floating_ip_get_by_address(
1218+ address, read_deleted=False)
1219 fixed_ip_ref = floating_ip_ref.fixed_ip
1220 if fixed_ip_ref:
1221 fixed_ip_address = fixed_ip_ref['address']
1222@@ -441,11 +413,9 @@
1223 fixed_ip_address = None
1224 floating_ip_ref.fixed_ip = None
1225 floating_ip_ref.save(session=self._session)
1226- return fixed_ip_address
1227+ return fixed_ip_ref
1228
1229 def floating_ip_get_all_by_host(self, host):
1230- if not self._is_admin:
1231- raise exception.NotAuthorized()
1232 return self._session.query(self.floating_ip_dto_class).\
1233 options(joinedload_all('fixed_ip.ethernet_card')).\
1234 filter_by(host=host).\
1235@@ -495,8 +465,6 @@
1236 return result
1237
1238 def network_get_by_cidr(self, cidr):
1239- if not self._is_admin:
1240- raise exception.NotAuthorized()
1241 result = self._session.query(self.network_dto_class).\
1242 filter_by(cidr=cidr).first()
1243
1244@@ -506,8 +474,6 @@
1245 return result
1246
1247 def network_associate(self, project_id):
1248- if not self._is_admin:
1249- raise exception.NotAuthorized()
1250 with self._session.begin():
1251 network_ref = self._session.query(self.network_dto_class).\
1252 filter_by(deleted=False).\
1253@@ -522,17 +488,17 @@
1254 self._session.add(network_ref)
1255 return network_ref
1256
1257- def fixed_ip_get_network(self, address):
1258- if not self._is_admin:
1259- raise exception.NotAuthorized()
1260- fixed_ip_ref = self.fixed_ip_get_by_address(address)
1261+ def fixed_ip_get_network(self, address, read_deleted=False):
1262+ fixed_ip_ref = self.fixed_ip_get_by_address(
1263+ address, read_deleted=read_deleted)
1264 return fixed_ip_ref.network
1265
1266 def floating_ip_fixed_ip_associate(self, floating_address, fixed_address):
1267 with self._session.begin():
1268- # TODO(devcamcar): How to ensure floating_id belongs to user?
1269- floating_ip_ref = self.floating_ip_get_by_address(floating_address)
1270- fixed_ip_ref = self.fixed_ip_get_by_address(fixed_address)
1271+ floating_ip_ref = self.floating_ip_get_by_address(
1272+ floating_address, read_deleted=False)
1273+ fixed_ip_ref = self.fixed_ip_get_by_address(
1274+ fixed_address, read_deleted=False)
1275 floating_ip_ref.fixed_ip = fixed_ip_ref
1276 floating_ip_ref.save(session=self._session)
1277
1278@@ -553,8 +519,6 @@
1279 self._session.add(fixed_ip_ref)
1280
1281 def fixed_ip_associate_pool(self, network_id, ethernet_card_id):
1282- if not self._is_admin:
1283- raise exception.NotAuthorized()
1284 with self._session.begin():
1285 network_or_none = or_(
1286 self.fixed_ip_dto_class.network_id == network_id,
1287@@ -572,4 +536,4 @@
1288 ip_ref.network = self.network_get(network_id)
1289 ip_ref.ethernet_card = self.ethernet_card_get(ethernet_card_id)
1290 self._session.add(ip_ref)
1291- return ip_ref
1292\ No newline at end of file
1293+ return ip_ref
1294
1295=== modified file 'nova/network/flat_vlan/network.py'
1296--- nova/network/flat_vlan/network.py 2011-04-04 09:52:18 +0000
1297+++ nova/network/flat_vlan/network.py 2011-04-06 17:14:53 +0000
1298@@ -32,18 +32,18 @@
1299 LOG = logging.getLogger("nova.net_flat_vlan")
1300 LOG_DHCP = logging.getLogger('nova.dhcpbridge-flat-vlan')
1301
1302-DhcpHost = collections.namedtuple('DhcpHost',
1303+DhcpHost = collections.namedtuple('DhcpHost',
1304 'mac_address, hostname, ip_address, timestamp')
1305
1306 class NetworkService(nova_manager.SchedulerDependentManager):
1307
1308- timeout_fixed_ips = (FLAGS.net_flat_vlan_use_vlan or
1309+ timeout_fixed_ips = (FLAGS.net_flat_vlan_use_vlan or
1310 FLAGS.net_flat_vlan_use_dhcp)
1311
1312 def __init__(self, network_driver=None, dhcp_driver=None, ra_driver=None,
1313 filter_driver=None, *args, **kwargs):
1314 """Initializes vlan network service.
1315-
1316+
1317 Args:
1318 network_driver: The network driver for the OS.
1319 dhcp_driver: The DHCP driver to use for DHCP service.
1320@@ -57,8 +57,8 @@
1321 ra_driver = FLAGS.net_flat_vlan_ra_driver
1322 if not filter_driver:
1323 filter_driver = FLAGS.net_flat_vlan_filter_driver
1324-
1325- kwargs['db_driver'] = 'nova.network.flat_vlan.db.api'
1326+
1327+ kwargs['db_driver'] = 'nova.network.flat_vlan.db.api'
1328 self.driver = utils.import_object(network_driver)
1329 self.dhcp_driver = utils.import_object(dhcp_driver)
1330 self.ra_driver = utils.import_object(ra_driver)
1331@@ -86,13 +86,14 @@
1332 # NOTE(vish): The False here is because we ignore the case
1333 # that the ip is already bound.
1334 self.driver.bind_floating_ip(floating_ip['address'], False)
1335- self.driver.ensure_floating_forward(floating_ip['address'],
1336- fixed_address)
1337- self.filter_driver.metadata_forward()
1338+ self.filter_driver.ensure_floating_forward(
1339+ floating_ip['address'], fixed_address)
1340+
1341+ self.filter_driver.metadata_forward()
1342
1343 def periodic_tasks(self, context=None):
1344 """Tasks to be run at a periodic interval.
1345-
1346+
1347 Args:
1348 context: Nova context
1349 """
1350@@ -109,7 +110,7 @@
1351
1352 def _set_vlan_host(self, context, network_id):
1353 """Sets up VLAN networking service host.
1354-
1355+
1356 Args:
1357 context: Nova context
1358 network_id: ID of the network
1359@@ -136,11 +137,11 @@
1360 network_ref['vpn_private_address'])
1361
1362 if not FLAGS.fake_network:
1363- hosts = self._get_dhcp_hosts(context, network_id)
1364+ hosts = self._get_dhcp_hosts(context, network_id)
1365 bridge = network_ref['bridge']
1366- self.dhcp_driver.update_dhcp(bridge,
1367- network_ref['gateway'],
1368- network_ref['dhcp_start'],
1369+ self.dhcp_driver.update_dhcp(bridge,
1370+ network_ref['gateway'],
1371+ network_ref['dhcp_start'],
1372 hosts,
1373 dhcp_script=FLAGS.net_flat_vlan_dhcpbridge)
1374 if(FLAGS.net_flat_vlan_use_ipv6):
1375@@ -148,11 +149,11 @@
1376 network_ref['cidr_v6'])
1377 self.db.network_update(context, network_id,
1378 {"gateway_v6":
1379- utils.get_my_linklocal(bridge)})
1380+ utils.get_my_linklocal(bridge)})
1381
1382 def _set_dhcp_host(self, context, network_id):
1383 """Sets up DHCP(no VLAN) networking service host.
1384-
1385+
1386 Args:
1387 context: Nova context
1388 network_id: ID of the network
1389@@ -171,22 +172,22 @@
1390
1391 if not FLAGS.fake_network:
1392 hosts = self._get_dhcp_hosts(context, network_id)
1393- self.dhcp_driver.update_dhcp(bridge,
1394- network_ref['gateway'],
1395- network_ref['dhcp_start'],
1396+ self.dhcp_driver.update_dhcp(bridge,
1397+ network_ref['gateway'],
1398+ network_ref['dhcp_start'],
1399 hosts,
1400 dhcp_script=FLAGS.net_flat_vlan_dhcpbridge)
1401-
1402+
1403 if(FLAGS.net_flat_vlan_use_ipv6):
1404 self.ra_driver.update_ra(bridge,
1405 network_ref['cidr_v6'])
1406 self.db.network_update(context, network_id,
1407 {"gateway_v6":
1408- utils.get_my_linklocal(bridge)})
1409-
1410+ utils.get_my_linklocal(bridge)})
1411+
1412 def set_network_host(self, context, network_id):
1413 """Called when this host becomes the host for a network.
1414-
1415+
1416 Args:
1417 context: Nova context to access DB.
1418 network_id: ID of the network
1419@@ -201,11 +202,11 @@
1420 net['host'] = self.host
1421 self.db.network_update(context, network_id, net)
1422
1423- return self.host
1424-
1425+ return self.host
1426+
1427 def _get_dhcp_hosts(self, context, network_id):
1428 """Get a list containing a network's hosts
1429-
1430+
1431 Args:
1432 context: Nova context
1433 network_id: Network ID to get the DHCP hosts for.
1434@@ -224,10 +225,10 @@
1435 ip_address=fixed_ip_ref['address'],
1436 timestamp=None))
1437 return hosts
1438-
1439+
1440 def allocate_fixed_ips(self, context, vnic_ids, is_vpn):
1441 """Gets a fixed ip from the pool.
1442-
1443+
1444 Args:
1445 context: Nova context needed to access DB.
1446 vnic_ids: List of VNIC IDs.
1447@@ -236,29 +237,29 @@
1448 for vnic_id in vnic_ids:
1449 if FLAGS.net_flat_vlan_use_vlan:
1450 ip_address = manager.bind_ip_to_ethernet_card_by_project(
1451- context,
1452+ context,
1453 vnic_id,
1454 is_vpn)
1455 else:
1456 ip_address = manager.bind_ip_to_ethernet_card_by_bridge(
1457- context,
1458- vnic_id)
1459+ context,
1460+ vnic_id)
1461
1462 if not FLAGS.fake_network and (FLAGS.net_flat_vlan_use_vlan or
1463 FLAGS.net_flat_vlan_use_dhcp):
1464 network_id = ip_address['network_id']
1465 network_ref = self.db.network_get(context, network_id)
1466- hosts = self._get_dhcp_hosts(context, network_id)
1467- self.dhcp_driver.update_dhcp(network_ref['bridge'],
1468+ hosts = self._get_dhcp_hosts(context, network_id)
1469+ self.dhcp_driver.update_dhcp(network_ref['bridge'],
1470 network_ref['gateway'],
1471 network_ref['dhcp_start'],
1472- hosts,
1473+ hosts,
1474 dhcp_script=FLAGS.net_flat_vlan_dhcpbridge)
1475
1476
1477 def lease_fixed_ip(self, context, mac, address):
1478 """Called by dhcp-bridge when ip is leased.
1479-
1480+
1481 Args:
1482 context: Nova context
1483 mac: MAC address to lease the IP address against.
1484@@ -267,19 +268,19 @@
1485 LOG.debug(_("Leasing IP %s"), address, context=context)
1486 fixed_ip_ref = self.db.fixed_ip_get_by_address(context, address)
1487 ethernet_card = fixed_ip_ref['ethernet_card']
1488- instance = nova_db_api.instance_get_by_virtual_nic(context,
1489+ instance = nova_db_api.instance_get_by_virtual_nic(context,
1490 ethernet_card['id'])
1491 if not instance:
1492 raise exception.Error(_("IP %s leased that isn't associated") %
1493 address)
1494-
1495+
1496 if nova_db_api.is_user_context(context):
1497 # Get the project for this IP
1498 nova_db_api.authorize_project_context(context, instance.project_id)
1499-
1500+
1501 if ethernet_card['mac_address'] != mac:
1502 raise exception.Error(_("IP %(address)s leased to bad"
1503- " mac %s vs %s") % (ethernet_card['mac_address'], mac))
1504+ " mac %s vs %s") % (ethernet_card['mac_address'], mac))
1505 now = datetime.datetime.utcnow()
1506 self.db.fixed_ip_update(context,
1507 fixed_ip_ref['id'],
1508@@ -288,13 +289,13 @@
1509 if not fixed_ip_ref['allocated']:
1510 LOG.warn(_("IP %s leased that was already deallocated"), address,
1511 context=context)
1512-
1513+
1514 def get_dhcp_host_leases(self, context, interface):
1515 """Gets a list of leased hosts.
1516-
1517+
1518 Args:
1519 context: Nova context
1520- interface: network interface to get the DHCP leases.
1521+ interface: network interface to get the DHCP leases.
1522 """
1523 network_ref = self.db.network_get_by_bridge(context, interface)
1524 hosts = []
1525@@ -305,21 +306,21 @@
1526 instance = nova_db_api.\
1527 instance_get_by_virtual_nic(context,
1528 ethernet_card['id'])
1529-
1530+
1531 if instance['updated_at']:
1532 timestamp = instance['updated_at']
1533 else:
1534 timestamp = instance['created_at']
1535-
1536+
1537 hosts.append(DhcpHost(mac_address=ethernet_card['mac_address'],
1538 hostname=instance['hostname'],
1539 ip_address=fixed_ip_ref['address'],
1540 timestamp=timestamp))
1541 return self.dhcp_driver.get_dhcp_leases(hosts)
1542-
1543+
1544 def release_fixed_ip(self, context, mac, address):
1545 """Called by dhcp-bridge when ip is released.
1546-
1547+
1548 Args:
1549 context: Nova context
1550 mac: MAC address to release the IP against.
1551@@ -328,7 +329,7 @@
1552 LOG.debug(_("Releasing IP %s"), address, context=context)
1553 fixed_ip_ref = self.db.fixed_ip_get_by_address(context, address)
1554 ethernet_card = fixed_ip_ref['ethernet_card']
1555- instance = nova_db_api.instance_get_by_virtual_nic(context,
1556+ instance = nova_db_api.instance_get_by_virtual_nic(context,
1557 ethernet_card['id'])
1558 if not instance:
1559 raise exception.Error(_("IP %s released that isn't associated") %
1560@@ -340,7 +341,7 @@
1561
1562 if ethernet_card['mac_address'] != mac:
1563 raise exception.Error(_("IP %(address)s leased to bad"
1564- " mac %s vs %s") % (ethernet_card['mac_address'], mac))
1565+ " mac %s vs %s") % (ethernet_card['mac_address'], mac))
1566
1567 if not fixed_ip_ref['leased']:
1568 LOG.warn(_("IP %s released that was not leased"), address,
1569@@ -355,25 +356,45 @@
1570 # the code below will update the file if necessary
1571 if FLAGS.net_flat_vlan_update_dhcp_on_disassociate:
1572 network_ref = fixed_ip['network']
1573- hosts = self._get_dhcp_hosts(context, network_ref['id'])
1574- self.dhcp_driver.update_dhcp(network_ref['bridge'],
1575- network_ref['gateway'],
1576- network_ref['dhcp_start'],
1577+ hosts = self._get_dhcp_hosts(context, network_ref['id'])
1578+ self.dhcp_driver.update_dhcp(network_ref['bridge'],
1579+ network_ref['gateway'],
1580+ network_ref['dhcp_start'],
1581 hosts,
1582 dhcp_script=FLAGS.\
1583 net_flat_vlan_dhcpbridge)
1584
1585- def disassociate_floating_ip(self, context, floating_address):
1586- """Disassociates a floating ip.
1587-
1588- Args:
1589- context: Nova context
1590- floating_address: Floating IP address to diassociate.
1591- """
1592- fixed_address = self.db.floating_ip_disassociate(context,
1593- floating_address)
1594+ def get_host(self, context):
1595+ """Gets the host of the network service.
1596+
1597+ Args:
1598+ context: Nova context object. Unused here.
1599+ """
1600+ return self.host
1601+
1602+ def activate_public_ip(self, context, floating_address, fixed_address):
1603+ """Associates an floating ip to a fixed ip.
1604+
1605+ Args:
1606+ context: Nova context
1607+ floating_address: Floating IP address to map to fixed IP address.
1608+ fixed_address: Fixed IP address to map the floating IP address to.
1609+ """
1610+ self.driver.bind_floating_ip(floating_address)
1611+ self.filter_driver.ensure_floating_forward(floating_address,
1612+ fixed_address)
1613+
1614+ def deactivate_public_ip(self, context, floating_address, fixed_address):
1615+ """Disassociates floating address and fixed address.
1616+
1617+ Args:
1618+ context: Nova context
1619+ floating_address: Floating IP address to map to fixed IP address.
1620+ fixed_address: Fixed IP address to map the floating IP address to.
1621+ """
1622 self.driver.unbind_floating_ip(floating_address)
1623- self.driver.remove_floating_forward(floating_address, fixed_address)
1624+ self.filter_driver.remove_floating_forward(floating_address,
1625+ fixed_address)
1626
1627
1628 class DHCPEventHandler(object):
1629@@ -388,7 +409,7 @@
1630 return NetworkService().get_dhcp_host_leases(ctxt, interface)
1631 else:
1632 return rpc.cast(ctxt,
1633- "%s.%s" % (FLAGS.net_flat_vlan_network_topic,
1634+ "%s.%s" % (FLAGS.net_flat_vlan_network_topic,
1635 FLAGS.host),
1636 {"method": "get_dhcp_host_leases",
1637 "args": {"interface": interface}})
1638@@ -402,7 +423,7 @@
1639 return NetworkService().lease_fixed_ip(ctxt, mac, ip_address)
1640 else:
1641 rpc.cast(ctxt,
1642- "%s.%s" % (FLAGS.net_flat_vlan_network_topic,
1643+ "%s.%s" % (FLAGS.net_flat_vlan_network_topic,
1644 FLAGS.host),
1645 {"method": "lease_fixed_ip",
1646 "args": {"mac": mac,
1647@@ -423,9 +444,9 @@
1648 NetworkService().release_fixed_ip(ctxt, mac, ip_address)
1649 else:
1650 rpc.cast(ctxt,
1651- "%s.%s" % (FLAGS.net_flat_vlan_network_topic,
1652+ "%s.%s" % (FLAGS.net_flat_vlan_network_topic,
1653 FLAGS.host),
1654 {"method": "release_fixed_ip",
1655 "args": {"mac": mac,
1656 "address": ip_address}})
1657-
1658+
1659
1660=== modified file 'nova/network/service.py'
1661--- nova/network/service.py 2011-04-04 09:52:18 +0000
1662+++ nova/network/service.py 2011-04-06 17:14:53 +0000
1663@@ -19,14 +19,14 @@
1664 service management."""
1665
1666 from nova import db
1667-from nova import flags
1668+from nova import flags
1669 from nova import utils
1670
1671 from zope import interface
1672
1673 # Flag definitions
1674 FLAGS = flags.FLAGS
1675-flags.DEFINE_string('network_service_conf',
1676+flags.DEFINE_string('network_service_conf',
1677 '/etc/nova/nova-network-service.conf',
1678 'Path to the network service configuration file.')
1679 flags.DEFINE_string('default_network_service', 'nova.network.flat_vlan',
1680@@ -37,102 +37,117 @@
1681
1682 def get_net_agent():
1683 """Gets the Net agent service object.
1684-
1685+
1686 Returns:
1687 Net agent object.
1688 """
1689-
1690+
1691 def get_api_service():
1692 """Gets the API service object.
1693-
1694+
1695 Returns:
1696 Network API service object.
1697 """
1698-
1699+
1700 def get_os_api_service():
1701 """Gets the OpenStack API service object.
1702-
1703+
1704 Returns:
1705 Network OpenStack API service object.
1706 """
1707
1708 class INetworkApiService(interface.Interface):
1709 """A Network API service object."""
1710-
1711+
1712 def create_vnic():
1713 """Creates a new VNIC.
1714-
1715+
1716 Returns:
1717 The ID of the new VNIC.
1718 """
1719-
1720+
1721 def get_project_vpn_address_and_port(context, project_id):
1722 """Gets the VPN IP address and port for a project
1723-
1724+
1725 Args:
1726 context: Nova context object needed to access DB.
1727 project_id: Project to get the VPN IP and port for.
1728-
1729+
1730 Returns:
1731 A tuple of VPN IP address and port number.
1732 """
1733
1734+ def allocate_address(context, project_id, ip_quota):
1735+ """Gets the number of floating IPs associated with a project.
1736+
1737+ Args:
1738+ context: Nova context object needed to access the DB.
1739+ project_id: Project to allocate the address from.
1740+ ip_quota: Quota for IP addresses.
1741+
1742+ Returns:
1743+ An IP address.
1744+
1745+ Raises:
1746+ quota.QuotaError: Over the quota limit.
1747+ """
1748+
1749 class INetworkOpenStackApiService(interface.Interface):
1750 """An OpenStack Network API service object."""
1751-
1752+
1753 def set_routes(route_map):
1754 """Set necessary routes for the plugin.
1755-
1756+
1757 Args:
1758 route_map: NetworkServiceRouteMap object to add the routes to.
1759- """
1760+ """
1761
1762 class INetworkAgentService(interface.Interface):
1763 """An OpenStack network agent service object."""
1764-
1765+
1766 def bind_vnics_to_ports(context, vnic_ids, is_vpn):
1767 """Gets a fixed ips from the pool.
1768-
1769+
1770 Args:
1771 context: Nova context needed for DB access.
1772 vnic_ids: list of VNIC IDs
1773- is_vpn: Boolean to check if the call is for VPN.
1774+ is_vpn: Boolean to check if the call is for VPN.
1775 """
1776-
1777+
1778 def setup_compute_network(context, vnic_ids, is_vpn):
1779 """Set up the compute node for networking.
1780-
1781+
1782 Args:
1783 context: Nova context needed for DB access.
1784 vnic_ids: list of VNIC IDs
1785 is_vpn: Boolean to check if the call is for VPN.
1786 """
1787-
1788+
1789 def teardown_compute_network(context, vnic_ids):
1790 """Clean up the compute node.
1791-
1792+
1793 Args:
1794 context: Nova context needed for DB access.
1795 vnic_ids: list of VNIC IDs
1796 """
1797-
1798+
1799 def requires_file_injection():
1800 """Indicates whether the plugin requires file injection.
1801-
1802+
1803 Returns:
1804 True if the plugin requires file injection.
1805 """
1806-
1807+
1808 def get_network_info(context, vnic_id):
1809 """Gets network data for a given VNIC.
1810-
1811+
1812 Args:
1813 context: Nova context needed for DB access.
1814 vnic_id: VNIC ID to get the network information for.
1815-
1816+
1817 Returns:
1818 A dictionary containing the following keys:
1819- cidr, cidrv6, netmask, netmask_v6 gateway, gateway_v6,
1820+ cidr, cidrv6, netmask, netmask_v6 gateway, gateway_v6,
1821 dhcp_server, broadcast, dns, mac_address,
1822 ip_address, bridge, gateway_v6, and netmast_v6
1823 """
1824@@ -142,7 +157,7 @@
1825
1826 def __init__(self, mapper, service):
1827 """Initialize a NetworkServiceRouteMap object.
1828-
1829+
1830 Args:
1831 mapper: python-routes mapper object to wrap.
1832 service: module of the network plugin service.
1833@@ -152,34 +167,34 @@
1834
1835 def resource(self, member_name, collection_name, **kwargs):
1836 """Wrapper method for 'resource' method in python-routes mapper object.
1837-
1838+
1839 This method does the same thing 'resource' method does for python-routes
1840- module, but it also adds a route prefix from the network service name.
1841-
1842+ module, but it also adds a route prefix from the network service name.
1843+
1844 Args:
1845 member_name: REST member routes
1846 collection_name: REST collection routes
1847 """
1848 _, _, package_name = str(self._service.__package__).rpartition('.')
1849 kwargs.pop('path_prefix', None)
1850- self._mapper.resource(member_name, collection_name,
1851+ self._mapper.resource(member_name, collection_name,
1852 path_prefix='/%s' % package_name, **kwargs)
1853
1854 class NetworkServiceManager(object):
1855- """Implements Borg design pattern to have a shared state of network
1856+ """Implements Borg design pattern to have a shared state of network
1857 services.
1858 """
1859
1860 __shared_state = {}
1861 _services = {}
1862-
1863+
1864 def __init__(self):
1865 """Initialize services member dictionary variable.
1866 """
1867 self.__dict__ = self.__shared_state
1868
1869 def _import_services(self):
1870- """Loads the content of the configuration file and imports the
1871+ """Loads the content of the configuration file and imports the
1872 modules.
1873 """
1874 self._services = {}
1875@@ -190,11 +205,11 @@
1876 continue
1877 self._services[line] = utils.import_object(line)
1878 f.close()
1879-
1880+
1881 @property
1882 def _services_dict(self):
1883 """Gets the services dictionary. Loads the services if empty.
1884-
1885+
1886 Returns:
1887 A dictionary of service name to service modules.
1888 """
1889@@ -205,11 +220,11 @@
1890 @classmethod
1891 def get_service_name(cls, context, project_id):
1892 """Gets the network service given a project ID.
1893-
1894+
1895 Args:
1896 context: Nova context object needed for DB access.
1897 project_id: Project ID to get the service of.
1898-
1899+
1900 Returns:
1901 Network service name for the project.
1902 """
1903@@ -220,20 +235,20 @@
1904
1905 def get_service(self, context, project_id):
1906 """Gets the network service given a project ID.
1907-
1908+
1909 Args:
1910 context: Nova context object needed for DB access.
1911 project_id: Project ID to get the service of.
1912-
1913+
1914 Returns:
1915 Network service module for the project.
1916 """
1917 service = self.get_service_name(context, project_id)
1918 return self._services_dict[service]
1919-
1920+
1921 def get_all_services(self):
1922 """Gets all the network services available.
1923-
1924+
1925 Returns:
1926 Network service modules available.
1927 """
1928@@ -241,21 +256,21 @@
1929
1930 def get_service_factory(context, project_id):
1931 """Gets the factory object for network service.
1932-
1933+
1934 Args:
1935 context: Nova context needed for accessing DB.
1936 project_id: Project ID to get the appropriate network service.
1937-
1938+
1939 Returns:
1940 A tuple of the service module and its NetworkServiceFactory object.
1941 """
1942 manager = NetworkServiceManager()
1943 service = manager.get_service(context, project_id)
1944 return (service, service.NetworkServiceFactory())
1945-
1946+
1947 def get_all_service_factories():
1948 """Gets all the factory objects for network services.
1949-
1950+
1951 Returns:
1952 A list of tuples of service module and its factory.
1953 """
1954
1955=== modified file 'nova/virt/libvirt_conn.py'
1956--- nova/virt/libvirt_conn.py 2011-04-04 09:52:18 +0000
1957+++ nova/virt/libvirt_conn.py 2011-04-06 17:14:53 +0000
1958@@ -238,10 +238,7 @@
1959
1960 vnics = db.virtual_nics_get_by_instance(ctxt, instance['id'])
1961 for vnic_id in vnics:
1962- try:
1963- self.firewall_driver.prepare_vnic_filter(vnic_id, instance)
1964- except:
1965- pass
1966+ self.firewall_driver.prepare_vnic_filter(vnic_id, instance)
1967
1968 def _get_connection(self):
1969 if not self._wrapped_conn or not self._test_connection():

Subscribers

People subscribed via source and target branches

to status/vote changes: