summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nova/api/ec2/cloud.py19
-rw-r--r--nova/compute/manager.py6
-rw-r--r--nova/context.py9
-rw-r--r--nova/db/sqlalchemy/api.py25
-rw-r--r--nova/network/manager.py10
-rw-r--r--nova/quota.py9
-rw-r--r--nova/scheduler/manager.py5
-rw-r--r--nova/volume/manager.py3
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,