diff options
-rw-r--r-- | nova/api/ec2/cloud.py | 19 | ||||
-rw-r--r-- | nova/compute/manager.py | 6 | ||||
-rw-r--r-- | nova/context.py | 9 | ||||
-rw-r--r-- | nova/db/sqlalchemy/api.py | 25 | ||||
-rw-r--r-- | nova/network/manager.py | 10 | ||||
-rw-r--r-- | nova/quota.py | 9 | ||||
-rw-r--r-- | nova/scheduler/manager.py | 5 | ||||
-rw-r--r-- | nova/volume/manager.py | 3 |
8 files changed, 56 insertions, 30 deletions
diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 02508344c..2226a0a5e 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -52,6 +52,11 @@ class QuotaError(exception.ApiError): """Quota Exceeeded""" pass +../deploy/nova/api/ec2/cloud.py: db.security_group_get_by_name(context.admin(), +../deploy/nova/api/ec2/cloud.py: instance_ref = db.volume_get_instance(context.admin(), volume_ref['id']) +../deploy/nova/api/ec2/cloud.py: db.instance_add_security_group(context.admin(), inst_id, +../deploy/nova/api/ec2/cloud.py: rpc.cast(context.admin(), +../deploy/nova/api/ec2/cloud.py: self.network_manager.deallocate_fixed_ip(context.admin(), def _gen_key(context, user_id, key_name): """Generate a key @@ -310,7 +315,7 @@ class CloudController(object): source_security_group_owner_id) source_security_group = \ - db.security_group_get_by_name(context, + db.security_group_get_by_name(context.elevated(), source_project_id, source_security_group_name) values['group_id'] = source_security_group['id'] @@ -556,7 +561,8 @@ class CloudController(object): def detach_volume(self, context, volume_id, **kwargs): volume_ref = db.volume_get_by_ec2_id(context, volume_id) - instance_ref = db.volume_get_instance(context, volume_ref['id']) + instance_ref = db.volume_get_instance(context.elevated(), + volume_ref['id']) if not instance_ref: raise exception.ApiError("Volume isn't attached to anything!") # TODO(vish): abstract status checking? @@ -842,13 +848,15 @@ class CloudController(object): base_options['memory_mb'] = type_data['memory_mb'] base_options['vcpus'] = type_data['vcpus'] base_options['local_gb'] = type_data['local_gb'] + elevated = context.elevated() for num in range(num_instances): instance_ref = db.instance_create(context, base_options) inst_id = instance_ref['id'] for security_group_id in security_groups: - db.instance_add_security_group(context, inst_id, + db.instance_add_security_group(elevated, + inst_id, security_group_id) inst = {} @@ -866,7 +874,7 @@ class CloudController(object): inst_id, vpn) network_topic = self._get_network_topic(context) - rpc.call(context, + rpc.cast(elevated, network_topic, {"method": "setup_fixed_ip", "args": {"address": address}}) @@ -924,7 +932,8 @@ class CloudController(object): # NOTE(vish): Currently, nothing needs to be done on the # network node until release. If this changes, # we will need to cast here. - self.network_manager.deallocate_fixed_ip(context, address) + self.network_manager.deallocate_fixed_ip(context.elevated(), + address) host = instance_ref['host'] if host: diff --git a/nova/compute/manager.py b/nova/compute/manager.py index c602d013d..694c4ff56 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -71,6 +71,7 @@ class ComputeManager(manager.Manager): @exception.wrap_exception def run_instance(self, context, instance_id, **_kwargs): """Launch a new instance with specified options.""" + context = context.elevated() instance_ref = self.db.instance_get(context, instance_id) if instance_ref['name'] in self.driver.list_instances(): raise exception.Error("Instance has already been created") @@ -106,6 +107,7 @@ class ComputeManager(manager.Manager): @exception.wrap_exception def terminate_instance(self, context, instance_id): """Terminate an instance on this machine.""" + context = context.elevated() logging.debug("instance %s: terminating", instance_id) instance_ref = self.db.instance_get(context, instance_id) @@ -127,6 +129,7 @@ class ComputeManager(manager.Manager): @exception.wrap_exception def reboot_instance(self, context, instance_id): """Reboot an instance on this server.""" + context = context.elevated() self._update_state(context, instance_id) instance_ref = self.db.instance_get(context, instance_id) @@ -149,6 +152,7 @@ class ComputeManager(manager.Manager): @exception.wrap_exception def get_console_output(self, context, instance_id): """Send the console output for an instance.""" + context = context.elevated() logging.debug("instance %s: getting console output", instance_id) instance_ref = self.db.instance_get(context, instance_id) @@ -158,6 +162,7 @@ class ComputeManager(manager.Manager): @exception.wrap_exception def attach_volume(self, context, instance_id, volume_id, mountpoint): """Attach a volume to an instance.""" + context = context.elevated() logging.debug("instance %s: attaching volume %s to %s", instance_id, volume_id, mountpoint) instance_ref = self.db.instance_get(context, instance_id) @@ -173,6 +178,7 @@ class ComputeManager(manager.Manager): @exception.wrap_exception def detach_volume(self, context, instance_id, volume_id): """Detach a volume from an instance.""" + context = context.elevated() logging.debug("instance %s: detaching volume %s", instance_id, volume_id) diff --git a/nova/context.py b/nova/context.py index 3f9de519d..977866d59 100644 --- a/nova/context.py +++ b/nova/context.py @@ -41,9 +41,10 @@ class RequestContext(object): self._project = None self.project_id = project if is_admin is None: - if not user: - user = self.user - self.is_admin = user.is_admin() + if self.user_id and self.user: + self.is_admin = self.user.is_admin() + else: + self.is_admin = False else: self.is_admin = is_admin self.read_deleted = read_deleted @@ -91,7 +92,7 @@ class RequestContext(object): def from_dict(cls, values): return cls(**values) - def admin(self, read_deleted=False): + def elevated(self, read_deleted=False): """Return a version of this context with admin flag set""" return RequestContext(self.user_id, self.project_id, diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index d0adcd9a4..a4b2eaea5 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -33,7 +33,6 @@ from sqlalchemy.orm import joinedload from sqlalchemy.orm import joinedload_all from sqlalchemy.sql import exists from sqlalchemy.sql import func -from sqlalchemy.orm.exc import NoResultFound FLAGS = flags.FLAGS @@ -52,7 +51,9 @@ def is_user_context(context): """Indicates if the request context is a normal user.""" if not context: return False - if not context.user or not context.project: + if context.is_admin: + return False + if not context.user_id or not context.project_id: return False return True @@ -64,7 +65,7 @@ def authorize_project_context(context, project_id): if is_user_context(context): if not context.project: raise exception.NotAuthorized() - elif context.project.id != project_id: + elif context.project_id != project_id: raise exception.NotAuthorized() @@ -75,7 +76,7 @@ def authorize_user_context(context, user_id): if is_user_context(context): if not context.user: raise exception.NotAuthorized() - elif context.user.id != user_id: + elif context.user_id != user_id: raise exception.NotAuthorized() @@ -540,7 +541,7 @@ def instance_create(context, values): with session.begin(): while instance_ref.internal_id == None: internal_id = utils.generate_uid(instance_ref.__prefix__) - if not instance_internal_id_exists(context, internal_id, + if not instance_internal_id_exists(context, internal_id, session=session): instance_ref.internal_id = internal_id instance_ref.save(session=session) @@ -582,7 +583,7 @@ def instance_get(context, instance_id, session=None): elif is_user_context(context): result = session.query(models.Instance ).options(joinedload('security_groups') - ).filter_by(project_id=context.project.id + ).filter_by(project_id=context.project_id ).filter_by(id=instance_id ).filter_by(deleted=False ).first() @@ -641,7 +642,7 @@ def instance_get_all_by_reservation(context, reservation_id): return session.query(models.Instance ).options(joinedload_all('fixed_ip.floating_ips') ).options(joinedload('security_groups') - ).filter_by(project_id=context.project.id + ).filter_by(project_id=context.project_id ).filter_by(reservation_id=reservation_id ).filter_by(deleted=False ).all() @@ -660,7 +661,7 @@ def instance_get_by_internal_id(context, internal_id): elif is_user_context(context): result = session.query(models.Instance ).options(joinedload('security_groups') - ).filter_by(project_id=context.project.id + ).filter_by(project_id=context.project_id ).filter_by(internal_id=internal_id ).filter_by(deleted=False ).first() @@ -898,7 +899,7 @@ def network_get(context, network_id, session=None): ).first() elif is_user_context(context): result = session.query(models.Network - ).filter_by(project_id=context.project.id + ).filter_by(project_id=context.project_id ).filter_by(id=network_id ).filter_by(deleted=False ).first() @@ -1199,7 +1200,7 @@ def volume_get(context, volume_id, session=None): ).first() elif is_user_context(context): result = session.query(models.Volume - ).filter_by(project_id=context.project.id + ).filter_by(project_id=context.project_id ).filter_by(id=volume_id ).filter_by(deleted=False ).first() @@ -1239,7 +1240,7 @@ def volume_get_by_ec2_id(context, ec2_id): ).first() elif is_user_context(context): result = session.query(models.Volume - ).filter_by(project_id=context.project.id + ).filter_by(project_id=context.project_id ).filter_by(ec2_id=ec2_id ).filter_by(deleted=False ).first() @@ -1632,7 +1633,7 @@ def user_remove_project_role(context, user_id, project_id, role): with session.begin(): session.execute('delete from user_project_role_association where ' + \ 'user_id=:user_id and project_id=:project_id and ' + \ - 'role=:role', { 'user_id' : user_id, + 'role=:role', { 'user_id' : user_id, 'project_id' : project_id, 'role' : role }) diff --git a/nova/network/manager.py b/nova/network/manager.py index 391a4fc7f..cb5759a2b 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -229,7 +229,7 @@ class FlatManager(NetworkManager): # network_get_by_compute_host network_ref = self.db.network_get_by_bridge(context, FLAGS.flat_network_bridge) - address = self.db.fixed_ip_associate_pool(context.admin(), + address = self.db.fixed_ip_associate_pool(context.elevated(), network_ref['id'], instance_id) self.db.fixed_ip_update(context, address, {'allocated': True}) @@ -338,12 +338,13 @@ class VlanManager(NetworkManager): # TODO(vish): This should probably be getting project_id from # the instance, but it is another trip to the db. # Perhaps this method should take an instance_ref. - network_ref = self.db.project_get_network(context, context.project.id) + network_ref = self.db.project_get_network(context.elevated(), + context.project_id) if kwargs.get('vpn', None): address = network_ref['vpn_private_address'] self.db.fixed_ip_associate(None, address, instance_id) else: - address = self.db.fixed_ip_associate_pool(context.admin(), + address = self.db.fixed_ip_associate_pool(context.elevated(), network_ref['id'], instance_id) self.db.fixed_ip_update(context, address, {'allocated': True}) @@ -402,7 +403,8 @@ class VlanManager(NetworkManager): def get_network(self, context): """Get the network for the current context""" - return self.db.project_get_network(None, context.project.id) + return self.db.project_get_network(context.elevated(), + context.project_id) def _on_set_network_host(self, context, network_id): """Called when this host becomes the host for a network""" diff --git a/nova/quota.py b/nova/quota.py index edbb83111..045051207 100644 --- a/nova/quota.py +++ b/nova/quota.py @@ -54,7 +54,8 @@ def get_quota(context, project_id): def allowed_instances(context, num_instances, instance_type): """Check quota and return min(num_instances, allowed_instances)""" - project_id = context.project.id + project_id = context.project_id + context = context.elevated() used_instances, used_cores = db.instance_data_get_for_project(context, project_id) quota = get_quota(context, project_id) @@ -69,7 +70,8 @@ def allowed_instances(context, num_instances, instance_type): def allowed_volumes(context, num_volumes, size): """Check quota and return min(num_volumes, allowed_volumes)""" - project_id = context.project.id + project_id = context.project_id + context = context.elevated() used_volumes, used_gigabytes = db.volume_data_get_for_project(context, project_id) quota = get_quota(context, project_id) @@ -84,7 +86,8 @@ def allowed_volumes(context, num_volumes, size): def allowed_floating_ips(context, num_floating_ips): """Check quota and return min(num_floating_ips, allowed_floating_ips)""" - project_id = context.project.id + project_id = context.project_id + context = context.elevated() used_floating_ips = db.floating_ip_count_by_project(context, project_id) quota = get_quota(context, project_id) allowed_floating_ips = quota['floating_ips'] - used_floating_ips diff --git a/nova/scheduler/manager.py b/nova/scheduler/manager.py index 6a933fb37..b3b2b4dce 100644 --- a/nova/scheduler/manager.py +++ b/nova/scheduler/manager.py @@ -54,10 +54,11 @@ class SchedulerManager(manager.Manager): Falls back to schedule(context, topic) if method doesn't exist. """ driver_method = 'schedule_%s' % method + elevated = context.elevated() try: - host = getattr(self.driver, driver_method)(context, *args, **kwargs) + host = getattr(self.driver, driver_method)(elevated, *args, **kwargs) except AttributeError: - host = self.driver.schedule(context, topic, *args, **kwargs) + host = self.driver.schedule(elevated, topic, *args, **kwargs) rpc.cast(context, db.queue_get_for(context, topic, host), diff --git a/nova/volume/manager.py b/nova/volume/manager.py index 8508f27b2..89290cc16 100644 --- a/nova/volume/manager.py +++ b/nova/volume/manager.py @@ -67,6 +67,7 @@ class AOEManager(manager.Manager): @defer.inlineCallbacks def create_volume(self, context, volume_id): """Creates and exports the volume""" + context = context.elevated() logging.info("volume %s: creating", volume_id) volume_ref = self.db.volume_get(context, volume_id) @@ -103,6 +104,7 @@ class AOEManager(manager.Manager): @defer.inlineCallbacks def delete_volume(self, context, volume_id): """Deletes and unexports volume""" + context = context.elevated() logging.debug("Deleting volume with id of: %s", volume_id) volume_ref = self.db.volume_get(context, volume_id) if volume_ref['attach_status'] == "attached": @@ -124,6 +126,7 @@ class AOEManager(manager.Manager): Returns path to device. """ + context = context.elevated() volume_ref = self.db.volume_get(context, volume_id) yield self.driver.discover_volume(volume_ref['ec2_id']) shelf_id, blade_id = self.db.volume_get_shelf_and_blade(context, |