diff options
| author | Eric Day <eday@oddments.org> | 2010-09-23 11:24:26 -0700 |
|---|---|---|
| committer | Eric Day <eday@oddments.org> | 2010-09-23 11:24:26 -0700 |
| commit | 6460a2e9f808c2200274fc41777b6ceaed182d82 (patch) | |
| tree | 4ec9abff5810e5049c6d85dab6c896fdfac885b1 /nova/api | |
| parent | c9ac49b2425b932f60a87da80887d4556806ca60 (diff) | |
| parent | c29c68f0fa27fa81f22ca42958bbd564f719f3ae (diff) | |
| download | nova-6460a2e9f808c2200274fc41777b6ceaed182d82.tar.gz nova-6460a2e9f808c2200274fc41777b6ceaed182d82.tar.xz nova-6460a2e9f808c2200274fc41777b6ceaed182d82.zip | |
Merged gundlach's branch.
Diffstat (limited to 'nova/api')
| -rw-r--r-- | nova/api/__init__.py | 67 | ||||
| -rw-r--r-- | nova/api/ec2/__init__.py | 3 | ||||
| -rw-r--r-- | nova/api/ec2/apirequest.py | 4 | ||||
| -rw-r--r-- | nova/api/ec2/metadatarequesthandler.py | 71 |
4 files changed, 138 insertions, 7 deletions
diff --git a/nova/api/__init__.py b/nova/api/__init__.py index ff9b94de9..744abd621 100644 --- a/nova/api/__init__.py +++ b/nova/api/__init__.py @@ -23,25 +23,65 @@ Root WSGI middleware for all API controllers. import routes import webob.dec +from nova import flags from nova import wsgi from nova.api import cloudpipe from nova.api import ec2 from nova.api import rackspace +from nova.api.ec2 import metadatarequesthandler + + +flags.DEFINE_string('rsapi_subdomain', 'rs', + 'subdomain running the RS API') +flags.DEFINE_string('ec2api_subdomain', 'ec2', + 'subdomain running the EC2 API') +flags.DEFINE_string('FAKE_subdomain', None, + 'set to rs or ec2 to fake the subdomain of the host for testing') +FLAGS = flags.FLAGS class API(wsgi.Router): """Routes top-level requests to the appropriate controller.""" def __init__(self): + rsdomain = {'sub_domain': [FLAGS.rsapi_subdomain]} + ec2domain = {'sub_domain': [FLAGS.ec2api_subdomain]} + # If someone wants to pretend they're hitting the RS subdomain + # on their local box, they can set FAKE_subdomain to 'rs', which + # removes subdomain restrictions from the RS routes below. + if FLAGS.FAKE_subdomain == 'rs': + rsdomain = {} + elif FLAGS.FAKE_subdomain == 'ec2': + ec2domain = {} mapper = routes.Mapper() - mapper.connect("/", controller=self.versions) - mapper.connect("/v1.0/{path_info:.*}", controller=rackspace.API()) - mapper.connect("/services/{path_info:.*}", controller=ec2.API()) + mapper.sub_domains = True + mapper.connect("/", controller=self.rsapi_versions, + conditions=rsdomain) + mapper.connect("/v1.0/{path_info:.*}", controller=rackspace.API(), + conditions=rsdomain) + + mapper.connect("/", controller=self.ec2api_versions, + conditions=ec2domain) + mapper.connect("/services/{path_info:.*}", controller=ec2.API(), + conditions=ec2domain) mapper.connect("/cloudpipe/{path_info:.*}", controller=cloudpipe.API()) + mrh = metadatarequesthandler.MetadataRequestHandler() + for s in ['/latest', + '/2009-04-04', + '/2008-09-01', + '/2008-02-01', + '/2007-12-15', + '/2007-10-10', + '/2007-08-29', + '/2007-03-01', + '/2007-01-19', + '/1.0']: + mapper.connect('%s/{path_info:.*}' % s, controller=mrh, + conditions=ec2domain) super(API, self).__init__(mapper) @webob.dec.wsgify - def versions(self, req): + def rsapi_versions(self, req): """Respond to a request for all OpenStack API versions.""" response = { "versions": [ @@ -50,3 +90,22 @@ class API(wsgi.Router): "application/xml": { "attributes": dict(version=["status", "id"])}} return wsgi.Serializer(req.environ, metadata).to_content_type(response) + + @webob.dec.wsgify + def ec2api_versions(self, req): + """Respond to a request for all EC2 versions.""" + # available api versions + versions = [ + '1.0', + '2007-01-19', + '2007-03-01', + '2007-08-29', + '2007-10-10', + '2007-12-15', + '2008-02-01', + '2008-09-01', + '2009-04-04', + ] + return ''.join('%s\n' % v for v in versions) + + diff --git a/nova/api/ec2/__init__.py b/nova/api/ec2/__init__.py index a7b10e428..b041787c2 100644 --- a/nova/api/ec2/__init__.py +++ b/nova/api/ec2/__init__.py @@ -25,6 +25,7 @@ import webob.dec import webob.exc from nova import exception +from nova import flags from nova import wsgi from nova.api.ec2 import apirequest from nova.api.ec2 import context @@ -33,6 +34,7 @@ from nova.api.ec2 import cloud from nova.auth import manager +FLAGS = flags.FLAGS _log = logging.getLogger("api") _log.setLevel(logging.DEBUG) @@ -176,6 +178,7 @@ class Authorizer(wsgi.Middleware): controller_name = req.environ['ec2.controller'].__class__.__name__ action = req.environ['ec2.action'] allowed_roles = self.action_roles[controller_name].get(action, []) + allowed_roles.extend(FLAGS.superuser_roles) if self._matches_any_role(context, allowed_roles): return self.application else: diff --git a/nova/api/ec2/apirequest.py b/nova/api/ec2/apirequest.py index a3b20118f..a87c21fb3 100644 --- a/nova/api/ec2/apirequest.py +++ b/nova/api/ec2/apirequest.py @@ -68,10 +68,8 @@ class APIRequest(object): key = _camelcase_to_underscore(parts[0]) if len(parts) > 1: d = args.get(key, {}) - d[parts[1]] = value[0] + d[parts[1]] = value value = d - else: - value = value[0] args[key] = value for key in args.keys(): diff --git a/nova/api/ec2/metadatarequesthandler.py b/nova/api/ec2/metadatarequesthandler.py new file mode 100644 index 000000000..229e5a78d --- /dev/null +++ b/nova/api/ec2/metadatarequesthandler.py @@ -0,0 +1,71 @@ +# 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. + +"""Metadata request handler.""" + +import webob.dec +import webob.exc + +from nova.api.ec2 import cloud + + +class MetadataRequestHandler(object): + + """Serve metadata from the EC2 API.""" + + def print_data(self, data): + if isinstance(data, dict): + output = '' + for key in data: + if key == '_name': + continue + output += key + if isinstance(data[key], dict): + if '_name' in data[key]: + output += '=' + str(data[key]['_name']) + else: + output += '/' + output += '\n' + return output[:-1] # cut off last \n + elif isinstance(data, list): + return '\n'.join(data) + else: + return str(data) + + def lookup(self, path, data): + items = path.split('/') + for item in items: + if item: + if not isinstance(data, dict): + return data + if not item in data: + return None + data = data[item] + return data + + @webob.dec.wsgify + def __call__(self, req): + cc = cloud.CloudController() + meta_data = cc.get_metadata(req.remote_addr) + if meta_data is None: + _log.error('Failed to get metadata for ip: %s' % req.remote_addr) + raise webob.exc.HTTPNotFound() + data = self.lookup(path, meta_data) + if data is None: + raise webob.exc.HTTPNotFound() + return self.print_data(data) |
