diff options
| author | Vishvananda Ishaya <vishvananda@gmail.com> | 2010-11-29 21:19:31 +0000 |
|---|---|---|
| committer | Vishvananda Ishaya <vishvananda@gmail.com> | 2010-11-29 21:19:31 +0000 |
| commit | 6d472828a0e88678f873a6abf267acf04f4ab8ee (patch) | |
| tree | d76a1bc85049ad0435efad2b996c2d9a20e9cd5e /nova/api | |
| parent | f74094cd303b21c12e8a83790d405bcae8103be8 (diff) | |
| parent | 4112e432c6a7b0e82bfc72fac0ceae8eca8bba49 (diff) | |
merged trunk
Diffstat (limited to 'nova/api')
| -rw-r--r-- | nova/api/__init__.py | 8 | ||||
| -rw-r--r-- | nova/api/ec2/__init__.py | 8 | ||||
| -rw-r--r-- | nova/api/ec2/cloud.py | 30 | ||||
| -rw-r--r-- | nova/api/ec2/images.py | 123 | ||||
| -rw-r--r-- | nova/api/openstack/faults.py | 2 | ||||
| -rw-r--r-- | nova/api/openstack/images.py | 13 |
6 files changed, 36 insertions, 148 deletions
diff --git a/nova/api/__init__.py b/nova/api/__init__.py index 176d571a8..95fc6b145 100644 --- a/nova/api/__init__.py +++ b/nova/api/__init__.py @@ -15,15 +15,21 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. - """ Root WSGI middleware for all API controllers. + +**Related Flags** + +:osapi_subdomain: subdomain running the OpenStack API (default: api) +:ec2api_subdomain: subdomain running the EC2 API (default: ec2) + """ import routes import webob.dec from nova import flags +from nova import utils from nova import wsgi from nova.api import ec2 from nova.api import openstack diff --git a/nova/api/ec2/__init__.py b/nova/api/ec2/__init__.py index c53ce6f5e..a6ee16c33 100644 --- a/nova/api/ec2/__init__.py +++ b/nova/api/ec2/__init__.py @@ -15,8 +15,10 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. +""" +Starting point for routing EC2 requests. -"""Starting point for routing EC2 requests""" +""" import logging import routes @@ -242,8 +244,8 @@ class Executor(wsgi.Application): resp = webob.Response() resp.status = 400 resp.headers['Content-Type'] = 'text/xml' - resp.body = ('<?xml version="1.0"?>\n' + resp.body = str('<?xml version="1.0"?>\n' '<Response><Errors><Error><Code>%s</Code>' '<Message>%s</Message></Error></Errors>' - '<RequestID>?</RequestID></Response>') % (code, message) + '<RequestID>?</RequestID></Response>' % (code, message)) return resp diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index fbe4caa48..9327bf0d4 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -41,7 +41,7 @@ from nova import rpc from nova import utils from nova.compute.instance_types import INSTANCE_TYPES from nova.api import cloud -from nova.api.ec2 import images +from nova.image.s3 import S3ImageService FLAGS = flags.FLAGS @@ -100,6 +100,7 @@ class CloudController(object): def __init__(self): self.network_manager = utils.import_object(FLAGS.network_manager) self.compute_manager = utils.import_object(FLAGS.compute_manager) + self.image_service = S3ImageService() self.setup() def __str__(self): @@ -679,7 +680,7 @@ class CloudController(object): context.project_id) for floating_ip_ref in iterator: address = floating_ip_ref['address'] - instance_id = None + ec2_id = None if (floating_ip_ref['fixed_ip'] and floating_ip_ref['fixed_ip']['instance']): internal_id = floating_ip_ref['fixed_ip']['instance']['ec2_id'] @@ -717,8 +718,8 @@ class CloudController(object): "args": {"floating_address": floating_ip_ref['address']}}) return {'releaseResponse': ["Address released."]} - def associate_address(self, context, ec2_id, public_ip, **kwargs): - internal_id = ec2_id_to_internal_id(ec2_id) + def associate_address(self, context, instance_id, public_ip, **kwargs): + internal_id = ec2_id_to_internal_id(instance_id) instance_ref = db.instance_get_by_internal_id(context, internal_id) fixed_address = db.instance_get_fixed_address(context, instance_ref['id']) @@ -785,7 +786,7 @@ class CloudController(object): vpn = kwargs['image_id'] == FLAGS.vpn_image_id if not vpn: - image = images.get(context, kwargs['image_id']) + image = self.image_service.show(context, kwargs['image_id']) # FIXME(ja): if image is vpn, this breaks # get defaults from imagestore @@ -798,8 +799,8 @@ class CloudController(object): ramdisk_id = kwargs.get('ramdisk_id', ramdisk_id) # make sure we have access to kernel and ramdisk - images.get(context, kernel_id) - images.get(context, ramdisk_id) + self.image_service.show(context, kernel_id) + self.image_service.show(context, ramdisk_id) logging.debug("Going to run %s instances...", num_instances) launch_time = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()) @@ -993,20 +994,17 @@ class CloudController(object): return True def describe_images(self, context, image_id=None, **kwargs): - # The objectstore does its own authorization for describe - imageSet = images.list(context, image_id) + imageSet = self.image_service.index(context, image_id) return {'imagesSet': imageSet} def deregister_image(self, context, image_id, **kwargs): - # FIXME: should the objectstore be doing these authorization checks? - images.deregister(context, image_id) + self.image_service.deregister(context, image_id) return {'imageId': image_id} def register_image(self, context, image_location=None, **kwargs): - # FIXME: should the objectstore be doing these authorization checks? if image_location is None and 'name' in kwargs: image_location = kwargs['name'] - image_id = images.register(context, image_location) + image_id = self.image_service.register(context, image_location) logging.debug("Registered %s as %s" % (image_location, image_id)) return {'imageId': image_id} @@ -1014,7 +1012,7 @@ class CloudController(object): if attribute != 'launchPermission': raise exception.ApiError('attribute not supported: %s' % attribute) try: - image = images.list(context, image_id)[0] + image = self.image_service.show(context, image_id) except IndexError: raise exception.ApiError('invalid id: %s' % image_id) result = {'image_id': image_id, 'launchPermission': []} @@ -1033,8 +1031,8 @@ class CloudController(object): raise exception.ApiError('only group "all" is supported') if not operation_type in ['add', 'remove']: raise exception.ApiError('operation_type must be add or remove') - return images.modify(context, image_id, operation_type) + return self.image_service.modify(context, image_id, operation_type) def update_image(self, context, image_id, **kwargs): - result = images.update(context, image_id, dict(kwargs)) + result = self.image_service.update(context, image_id, dict(kwargs)) return result diff --git a/nova/api/ec2/images.py b/nova/api/ec2/images.py deleted file mode 100644 index 60f9008e9..000000000 --- a/nova/api/ec2/images.py +++ /dev/null @@ -1,123 +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. - -""" -Proxy AMI-related calls from the cloud controller, to the running -objectstore service. -""" - -import json -import urllib - -import boto.s3.connection - -from nova import exception -from nova import flags -from nova import utils -from nova.auth import manager - - -FLAGS = flags.FLAGS - - -def modify(context, image_id, operation): - conn(context).make_request( - method='POST', - bucket='_images', - query_args=qs({'image_id': image_id, 'operation': operation})) - - return True - - -def update(context, image_id, attributes): - """update an image's attributes / info.json""" - attributes.update({"image_id": image_id}) - conn(context).make_request( - method='POST', - bucket='_images', - query_args=qs(attributes)) - return True - - -def register(context, image_location): - """ rpc call to register a new image based from a manifest """ - - image_id = utils.generate_uid('ami') - conn(context).make_request( - method='PUT', - bucket='_images', - query_args=qs({'image_location': image_location, - 'image_id': image_id})) - - return image_id - - -def list(context, filter_list=[]): - """ return a list of all images that a user can see - - optionally filtered by a list of image_id """ - - if FLAGS.connection_type == 'fake': - return [{'imageId': 'bar'}] - - # FIXME: send along the list of only_images to check for - response = conn(context).make_request( - method='GET', - bucket='_images') - - result = json.loads(response.read()) - if not filter_list is None: - return [i for i in result if i['imageId'] in filter_list] - return result - - -def get(context, image_id): - """return a image object if the context has permissions""" - result = list(context, [image_id]) - if not result: - raise exception.NotFound('Image %s could not be found' % image_id) - image = result[0] - return image - - -def deregister(context, image_id): - """ unregister an image """ - conn(context).make_request( - method='DELETE', - bucket='_images', - query_args=qs({'image_id': image_id})) - - -def conn(context): - access = manager.AuthManager().get_access_key(context.user, - context.project) - secret = str(context.user.secret) - calling = boto.s3.connection.OrdinaryCallingFormat() - return boto.s3.connection.S3Connection(aws_access_key_id=access, - aws_secret_access_key=secret, - is_secure=False, - calling_format=calling, - port=FLAGS.s3_port, - host=FLAGS.s3_host) - - -def qs(params): - pairs = [] - for key in params.keys(): - pairs.append(key + '=' + urllib.quote(params[key])) - return '&'.join(pairs) diff --git a/nova/api/openstack/faults.py b/nova/api/openstack/faults.py index e69e51439..224a7ef0b 100644 --- a/nova/api/openstack/faults.py +++ b/nova/api/openstack/faults.py @@ -47,7 +47,7 @@ class Fault(webob.exc.HTTPException): """Generate a WSGI response based on the exception passed to ctor.""" # Replace the body with fault details. code = self.wrapped_exc.status_int - fault_name = self._fault_names.get(code, "cloudServersFault") + fault_name = self._fault_names.get(code, "computeFault") fault_data = { fault_name: { 'code': code, diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py index 5bc915e63..cdbdc9bdd 100644 --- a/nova/api/openstack/images.py +++ b/nova/api/openstack/images.py @@ -17,6 +17,7 @@ from webob import exc +from nova import context from nova import flags from nova import utils from nova import wsgi @@ -46,19 +47,23 @@ class Controller(wsgi.Controller): def detail(self, req): """Return all public images in detail.""" + user_id = req.environ['nova.context']['user']['id'] + ctxt = context.RequestContext(user_id, user_id) try: - images = self._service.detail() + images = self._service.detail(ctxt) images = nova.api.openstack.limited(images, req) except NotImplementedError: # Emulate detail() using repeated calls to show() - images = self._service.index() + images = self._service.index(ctxt) images = nova.api.openstack.limited(images, req) - images = [self._service.show(i['id']) for i in images] + images = [self._service.show(ctxt, i['id']) for i in images] return dict(images=images) def show(self, req, id): """Return data about the given image id.""" - return dict(image=self._service.show(id)) + user_id = req.environ['nova.context']['user']['id'] + ctxt = context.RequestContext(user_id, user_id) + return dict(image=self._service.show(ctxt, id)) def delete(self, req, id): # Only public images are supported for now. |
