diff options
Diffstat (limited to 'nova/api')
| -rw-r--r-- | nova/api/cloud.py | 10 | ||||
| -rw-r--r-- | nova/api/context.py | 46 | ||||
| -rw-r--r-- | nova/api/ec2/__init__.py | 7 | ||||
| -rw-r--r-- | nova/api/ec2/cloud.py | 107 | ||||
| -rw-r--r-- | nova/api/rackspace/context.py | 33 | ||||
| -rw-r--r-- | nova/api/rackspace/servers.py | 58 |
6 files changed, 93 insertions, 168 deletions
diff --git a/nova/api/cloud.py b/nova/api/cloud.py index 345677d4f..e16229e7d 100644 --- a/nova/api/cloud.py +++ b/nova/api/cloud.py @@ -30,13 +30,13 @@ FLAGS = flags.FLAGS def reboot(instance_id, context=None): """Reboot the given instance. - + #TODO(gundlach) not actually sure what context is used for by ec2 here -- I think we can just remove it and use None all the time. """ - instance_ref = db.instance_get_by_ec2_id(None, instance_id) + instance_ref = db.instance_get_by_ec2_id(context, instance_id) host = instance_ref['host'] - rpc.cast(db.queue_get_for(context, FLAGS.compute_topic, host), + rpc.cast(context, + db.queue_get_for(context, FLAGS.compute_topic, host), {"method": "reboot_instance", - "args": {"context": None, - "instance_id": instance_ref['id']}}) + "args": {"instance_id": instance_ref['id']}}) diff --git a/nova/api/context.py b/nova/api/context.py deleted file mode 100644 index b66cfe468..000000000 --- a/nova/api/context.py +++ /dev/null @@ -1,46 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2010 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -APIRequestContext -""" - -import random - - -class APIRequestContext(object): - def __init__(self, user, project): - self.user = user - self.project = project - self.request_id = ''.join( - [random.choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-') - for x in xrange(20)] - ) - if user: - self.is_admin = user.is_admin() - else: - self.is_admin = False - self.read_deleted = False - - -def get_admin_context(user=None, read_deleted=False): - context_ref = APIRequestContext(user=user, project=None) - context_ref.is_admin = True - context_ref.read_deleted = read_deleted - return context_ref - diff --git a/nova/api/ec2/__init__.py b/nova/api/ec2/__init__.py index 6b538a7f1..edc818c7d 100644 --- a/nova/api/ec2/__init__.py +++ b/nova/api/ec2/__init__.py @@ -25,9 +25,9 @@ import webob.dec import webob.exc from nova import exception +from nova import context from nova import flags from nova import wsgi -from nova.api import context from nova.api.ec2 import apirequest from nova.api.ec2 import admin from nova.api.ec2 import cloud @@ -78,7 +78,10 @@ class Authenticate(wsgi.Middleware): raise webob.exc.HTTPForbidden() # Authenticated! - req.environ['ec2.context'] = context.APIRequestContext(user, project) + ctxt = context.RequestContext(user=user, + project=project, + remote_address=req.remote_addr) + req.environ['ec2.context'] = ctxt return self.application diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 79c95788b..5e1de9dc0 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -28,6 +28,7 @@ import logging import os import time +from nova import context from nova import crypto from nova import db from nova import exception @@ -100,9 +101,9 @@ class CloudController(object): utils.runthis("Generating root CA: %s", "sh genrootca.sh") os.chdir(start) - def _get_mpi_data(self, project_id): + def _get_mpi_data(self, context, project_id): result = {} - for instance in db.instance_get_all_by_project(None, project_id): + for instance in db.instance_get_all_by_project(context, project_id): if instance['fixed_ip']: line = '%s slots=%d' % (instance['fixed_ip']['address'], INSTANCE_TYPES[instance['instance_type']]['vcpus']) @@ -114,10 +115,11 @@ class CloudController(object): return result def get_metadata(self, address): - instance_ref = db.fixed_ip_get_instance(None, address) + ctxt = context.get_admin_context() + instance_ref = db.fixed_ip_get_instance(ctxt, address) if instance_ref is None: return None - mpi = self._get_mpi_data(instance_ref['project_id']) + mpi = self._get_mpi_data(ctxt, instance_ref['project_id']) if instance_ref['key_name']: keys = { '0': { @@ -128,7 +130,7 @@ class CloudController(object): else: keys = '' hostname = instance_ref['hostname'] - floating_ip = db.instance_get_floating_address(None, + floating_ip = db.instance_get_floating_address(ctxt, instance_ref['id']) data = { 'user-data': base64.b64decode(instance_ref['user_data']), @@ -136,7 +138,7 @@ class CloudController(object): 'ami-id': instance_ref['image_id'], 'ami-launch-index': instance_ref['launch_index'], 'ami-manifest-path': 'FIXME', - 'block-device-mapping': { # TODO(vish): replace with real data + 'block-device-mapping': { # TODO(vish): replace with real data 'ami': 'sda1', 'ephemeral0': 'sda2', 'root': '/dev/sda1', @@ -218,7 +220,7 @@ class CloudController(object): return {'keypairsSet': result} def create_key_pair(self, context, key_name, **kwargs): - data = _gen_key(None, context.user.id, key_name) + data = _gen_key(context, context.user.id, key_name) return {'keyName': key_name, 'keyFingerprint': data['fingerprint'], 'keyMaterial': data['private_key']} @@ -247,11 +249,11 @@ class CloudController(object): def get_console_output(self, context, instance_id, **kwargs): # instance_id is passed in as a list of instances instance_ref = db.instance_get_by_ec2_id(context, instance_id[0]) - return rpc.call('%s.%s' % (FLAGS.compute_topic, + return rpc.call(context, + '%s.%s' % (FLAGS.compute_topic, instance_ref['host']), {"method": "get_console_output", - "args": {"context": None, - "instance_id": instance_ref['id']}}) + "args": {"instance_id": instance_ref['id']}}) def describe_volumes(self, context, **kwargs): if context.user.is_admin(): @@ -310,10 +312,10 @@ class CloudController(object): vol['display_description'] = kwargs.get('display_description') volume_ref = db.volume_create(context, vol) - rpc.cast(FLAGS.scheduler_topic, + rpc.cast(context, + FLAGS.scheduler_topic, {"method": "create_volume", - "args": {"context": None, - "topic": FLAGS.volume_topic, + "args": {"topic": FLAGS.volume_topic, "volume_id": volume_ref['id']}}) return {'volumeSet': [self._format_volume(context, volume_ref)]} @@ -328,10 +330,10 @@ class CloudController(object): raise exception.ApiError("Volume is already attached") instance_ref = db.instance_get_by_ec2_id(context, instance_id) host = instance_ref['host'] - rpc.cast(db.queue_get_for(context, FLAGS.compute_topic, host), + rpc.cast(context, + db.queue_get_for(context, FLAGS.compute_topic, host), {"method": "attach_volume", - "args": {"context": None, - "volume_id": volume_ref['id'], + "args": {"volume_id": volume_ref['id'], "instance_id": instance_ref['id'], "mountpoint": device}}) return {'attachTime': volume_ref['attach_time'], @@ -351,10 +353,10 @@ class CloudController(object): raise exception.ApiError("Volume is already detached") try: host = instance_ref['host'] - rpc.cast(db.queue_get_for(context, FLAGS.compute_topic, host), + rpc.cast(context, + db.queue_get_for(context, FLAGS.compute_topic, host), {"method": "detach_volume", - "args": {"context": None, - "instance_id": instance_ref['id'], + "args": {"instance_id": instance_ref['id'], "volume_id": volume_ref['id']}}) except exception.NotFound: # If the instance doesn't exist anymore, @@ -388,7 +390,7 @@ class CloudController(object): return self._format_describe_instances(context) def _format_describe_instances(self, context): - return { 'reservationSet': self._format_instances(context) } + return {'reservationSet': self._format_instances(context)} def _format_run_instances(self, context, reservation_id): i = self._format_instances(context, reservation_id) @@ -482,20 +484,20 @@ class CloudController(object): raise QuotaError("Address quota exceeded. You cannot " "allocate any more addresses") network_topic = self._get_network_topic(context) - public_ip = rpc.call(network_topic, + public_ip = rpc.call(context, + network_topic, {"method": "allocate_floating_ip", - "args": {"context": None, - "project_id": context.project.id}}) + "args": {"project_id": context.project.id}}) return {'addressSet': [{'publicIp': public_ip}]} def release_address(self, context, public_ip, **kwargs): # NOTE(vish): Should we make sure this works? floating_ip_ref = db.floating_ip_get_by_address(context, public_ip) network_topic = self._get_network_topic(context) - rpc.cast(network_topic, + rpc.cast(context, + network_topic, {"method": "deallocate_floating_ip", - "args": {"context": None, - "floating_address": floating_ip_ref['address']}}) + "args": {"floating_address": floating_ip_ref['address']}}) return {'releaseResponse': ["Address released."]} def associate_address(self, context, instance_id, public_ip, **kwargs): @@ -504,20 +506,20 @@ class CloudController(object): instance_ref['id']) floating_ip_ref = db.floating_ip_get_by_address(context, public_ip) network_topic = self._get_network_topic(context) - rpc.cast(network_topic, + rpc.cast(context, + network_topic, {"method": "associate_floating_ip", - "args": {"context": None, - "floating_address": floating_ip_ref['address'], + "args": {"floating_address": floating_ip_ref['address'], "fixed_address": fixed_address}}) return {'associateResponse': ["Address associated."]} def disassociate_address(self, context, public_ip, **kwargs): floating_ip_ref = db.floating_ip_get_by_address(context, public_ip) network_topic = self._get_network_topic(context) - rpc.cast(network_topic, + rpc.cast(context, + network_topic, {"method": "disassociate_floating_ip", - "args": {"context": None, - "floating_address": floating_ip_ref['address']}}) + "args": {"floating_address": floating_ip_ref['address']}}) return {'disassociateResponse': ["Address disassociated."]} def _get_network_topic(self, context): @@ -525,10 +527,10 @@ class CloudController(object): network_ref = db.project_get_network(context, context.project.id) host = network_ref['host'] if not host: - host = rpc.call(FLAGS.network_topic, + host = rpc.call(context, + FLAGS.network_topic, {"method": "set_network_host", - "args": {"context": None, - "project_id": context.project.id}}) + "args": {"project_id": context.project.id}}) return db.queue_get_for(context, FLAGS.network_topic, host) def run_instances(self, context, **kwargs): @@ -619,15 +621,15 @@ class CloudController(object): # TODO(vish): This probably should be done in the scheduler # network is setup when host is assigned network_topic = self._get_network_topic(context) - rpc.call(network_topic, + rpc.call(context, + network_topic, {"method": "setup_fixed_ip", - "args": {"context": None, - "address": address}}) + "args": {"address": address}}) - rpc.cast(FLAGS.scheduler_topic, + rpc.cast(context, + FLAGS.scheduler_topic, {"method": "run_instance", - "args": {"context": None, - "topic": FLAGS.compute_topic, + "args": {"topic": FLAGS.compute_topic, "instance_id": inst_id}}) logging.debug("Casting to scheduler for %s/%s's instance %s" % (context.project.name, context.user.name, inst_id)) @@ -658,10 +660,10 @@ class CloudController(object): # disassociated. We may need to worry about # checking this later. Perhaps in the scheduler? network_topic = self._get_network_topic(context) - rpc.cast(network_topic, + rpc.cast(context, + network_topic, {"method": "disassociate_floating_ip", - "args": {"context": None, - "floating_address": address}}) + "args": {"floating_address": address}}) address = db.instance_get_fixed_address(context, instance_ref['id']) @@ -674,10 +676,10 @@ class CloudController(object): host = instance_ref['host'] if host: - rpc.cast(db.queue_get_for(context, FLAGS.compute_topic, host), + rpc.cast(context, + db.queue_get_for(context, FLAGS.compute_topic, host), {"method": "terminate_instance", - "args": {"context": None, - "instance_id": instance_ref['id']}}) + "args": {"instance_id": instance_ref['id']}}) else: db.instance_destroy(context, instance_ref['id']) return True @@ -695,9 +697,8 @@ class CloudController(object): if field in kwargs: changes[field] = kwargs[field] if changes: - db_context = {} - inst = db.instance_get_by_ec2_id(db_context, instance_id) - db.instance_update(db_context, inst['id'], kwargs) + inst = db.instance_get_by_ec2_id(context, instance_id) + db.instance_update(context, inst['id'], kwargs) return True def delete_volume(self, context, volume_id, **kwargs): @@ -708,10 +709,10 @@ class CloudController(object): now = datetime.datetime.utcnow() db.volume_update(context, volume_ref['id'], {'terminated_at': now}) host = volume_ref['host'] - rpc.cast(db.queue_get_for(context, FLAGS.volume_topic, host), + rpc.cast(context, + db.queue_get_for(context, FLAGS.volume_topic, host), {"method": "delete_volume", - "args": {"context": None, - "volume_id": volume_ref['id']}}) + "args": {"volume_id": volume_ref['id']}}) return True def describe_images(self, context, image_id=None, **kwargs): diff --git a/nova/api/rackspace/context.py b/nova/api/rackspace/context.py deleted file mode 100644 index 77394615b..000000000 --- a/nova/api/rackspace/context.py +++ /dev/null @@ -1,33 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2010 OpenStack LLC. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -APIRequestContext -""" - -import random - -class Project(object): - def __init__(self, user_id): - self.id = user_id - -class APIRequestContext(object): - """ This is an adapter class to get around all of the assumptions made in - the FlatNetworking """ - def __init__(self, user_id): - self.user_id = user_id - self.project = Project(user_id) diff --git a/nova/api/rackspace/servers.py b/nova/api/rackspace/servers.py index 11efd8aef..866bebb44 100644 --- a/nova/api/rackspace/servers.py +++ b/nova/api/rackspace/servers.py @@ -24,9 +24,9 @@ from nova import flags from nova import rpc from nova import utils from nova import wsgi +from nova import context from nova.api import cloud from nova.api.rackspace import _id_translator -from nova.api.rackspace import context from nova.api.rackspace import faults from nova.compute import instance_types from nova.compute import power_state @@ -64,8 +64,8 @@ def _entity_list(entities): def _entity_detail(inst): """ Maps everything to Rackspace-like attributes for return""" - power_mapping = { - power_state.NOSTATE: 'build', + power_mapping = { + power_state.NOSTATE: 'build', power_state.RUNNING: 'active', power_state.BLOCKED: 'active', power_state.PAUSED: 'suspended', @@ -75,7 +75,7 @@ def _entity_detail(inst): } inst_dict = {} - mapped_keys = dict(status='state', imageId='image_id', + mapped_keys = dict(status='state', imageId='image_id', flavorId='instance_type', name='server_name', id='id') for k, v in mapped_keys.iteritems(): @@ -98,7 +98,7 @@ class Controller(wsgi.Controller): _serialization_metadata = { 'application/xml': { "attributes": { - "server": [ "id", "imageId", "name", "flavorId", "hostId", + "server": [ "id", "imageId", "name", "flavorId", "hostId", "status", "progress", "progress" ] } } @@ -164,11 +164,11 @@ class Controller(wsgi.Controller): inst = self._build_server_instance(req, env) except Exception, e: return faults.Fault(exc.HTTPUnprocessableEntity()) - - rpc.cast( - FLAGS.compute_topic, { - "method": "run_instance", - "args": {"instance_id": inst['id']}}) + user_id = req.environ['nova.context']['user']['id'] + rpc.cast(context.RequestContext(user_id, user_id), + FLAGS.compute_topic, + {"method": "run_instance", + "args": {"instance_id": inst['id']}}) return _entity_inst(inst) def update(self, req, id): @@ -178,7 +178,7 @@ class Controller(wsgi.Controller): user_id = req.environ['nova.context']['user']['id'] inst_dict = self._deserialize(req.body, req) - + if not inst_dict: return faults.Fault(exc.HTTPUnprocessableEntity()) @@ -186,12 +186,12 @@ class Controller(wsgi.Controller): if not instance or instance.user_id != user_id: return faults.Fault(exc.HTTPNotFound()) - self.db_driver.instance_update(None, id, + self.db_driver.instance_update(None, id, _filter_params(inst_dict['server'])) return faults.Fault(exc.HTTPNoContent()) def action(self, req, id): - """ multi-purpose method used to reboot, rebuild, and + """ multi-purpose method used to reboot, rebuild, and resize a server """ input_dict = self._deserialize(req.body, req) try: @@ -217,13 +217,13 @@ class Controller(wsgi.Controller): if v['flavorid'] == flavor_id][0] image_id = env['server']['imageId'] - + img_service, image_id_trans = _image_service() - opaque_image_id = image_id_trans.to_rs_id(image_id) + opaque_image_id = image_id_trans.to_rs_id(image_id) image = img_service.show(opaque_image_id) - if not image: + if not image: raise Exception, "Image not found" inst['server_name'] = env['server']['name'] @@ -259,15 +259,15 @@ class Controller(wsgi.Controller): ref = self.db_driver.instance_create(None, inst) inst['id'] = inst_id_trans.to_rs_id(ref.ec2_id) - + # TODO(dietz): this isn't explicitly necessary, but the networking # calls depend on an object with a project_id property, and therefore # should be cleaned up later - api_context = context.APIRequestContext(user_id) - + api_context = context.RequestContext(user_id) + inst['mac_address'] = utils.generate_mac() - - #TODO(dietz) is this necessary? + + #TODO(dietz) is this necessary? inst['launch_index'] = 0 inst['hostname'] = ref.ec2_id @@ -280,20 +280,20 @@ class Controller(wsgi.Controller): # TODO(vish): This probably should be done in the scheduler # network is setup when host is assigned network_topic = self._get_network_topic(user_id) - rpc.call(network_topic, + rpc.call(context.RequestContext(user_id, user_id), + network_topic, {"method": "setup_fixed_ip", - "args": {"context": None, - "address": address}}) + "args": {"address": address}}) return inst def _get_network_topic(self, user_id): """Retrieves the network host for a project""" - network_ref = self.db_driver.project_get_network(None, + network_ref = self.db_driver.project_get_network(None, user_id) host = network_ref['host'] if not host: - host = rpc.call(FLAGS.network_topic, - {"method": "set_network_host", - "args": {"context": None, - "project_id": user_id}}) + host = rpc.call(context.RequestContext(user_id, user_id), + FLAGS.network_topic, + {"method": "set_network_host", + "args": {"project_id": user_id}}) return self.db_driver.queue_get_for(None, FLAGS.network_topic, host) |
