summaryrefslogtreecommitdiffstats
path: root/nova/api
diff options
context:
space:
mode:
Diffstat (limited to 'nova/api')
-rw-r--r--nova/api/__init__.py38
-rw-r--r--nova/api/ec2/__init__.py42
-rw-r--r--nova/api/rackspace/__init__.py81
-rw-r--r--nova/api/rackspace/base.py39
-rw-r--r--nova/api/rackspace/controllers/__init__.py5
-rw-r--r--nova/api/rackspace/flavors.py18
-rw-r--r--nova/api/rackspace/images.py64
-rw-r--r--nova/api/rackspace/servers.py83
-rw-r--r--nova/api/rackspace/sharedipgroups.py18
9 files changed, 388 insertions, 0 deletions
diff --git a/nova/api/__init__.py b/nova/api/__init__.py
new file mode 100644
index 000000000..a6bb93348
--- /dev/null
+++ b/nova/api/__init__.py
@@ -0,0 +1,38 @@
+# 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.
+
+"""
+Root WSGI middleware for all API controllers.
+"""
+
+import routes
+
+from nova import wsgi
+from nova.api import ec2
+from nova.api import rackspace
+
+
+class API(wsgi.Router):
+ """Routes top-level requests to the appropriate controller."""
+
+ def __init__(self):
+ mapper = routes.Mapper()
+ mapper.connect(None, "/v1.0/{path_info:.*}",
+ controller=rackspace.API())
+ mapper.connect(None, "/ec2/{path_info:.*}", controller=ec2.API())
+ super(API, self).__init__(mapper)
diff --git a/nova/api/ec2/__init__.py b/nova/api/ec2/__init__.py
new file mode 100644
index 000000000..6eec0abf7
--- /dev/null
+++ b/nova/api/ec2/__init__.py
@@ -0,0 +1,42 @@
+# 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.
+
+"""
+WSGI middleware for EC2 API controllers.
+"""
+
+import routes
+import webob.dec
+
+from nova import wsgi
+
+
+class API(wsgi.Router):
+ """Routes EC2 requests to the appropriate controller."""
+
+ def __init__(self):
+ mapper = routes.Mapper()
+ mapper.connect(None, "{all:.*}", controller=self.dummy)
+ super(API, self).__init__(mapper)
+
+ @staticmethod
+ @webob.dec.wsgify
+ def dummy(req):
+ """Temporary dummy controller."""
+ msg = "dummy response -- please hook up __init__() to cloud.py instead"
+ return repr({'dummy': msg,
+ 'kwargs': repr(req.environ['wsgiorg.routing_args'][1])})
diff --git a/nova/api/rackspace/__init__.py b/nova/api/rackspace/__init__.py
new file mode 100644
index 000000000..27e78f801
--- /dev/null
+++ b/nova/api/rackspace/__init__.py
@@ -0,0 +1,81 @@
+# 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.
+
+"""
+WSGI middleware for Rackspace API controllers.
+"""
+
+import json
+import time
+
+import routes
+import webob.dec
+import webob.exc
+
+from nova import flags
+from nova import wsgi
+from nova.api.rackspace import flavors
+from nova.api.rackspace import images
+from nova.api.rackspace import servers
+from nova.api.rackspace import sharedipgroups
+from nova.auth import manager
+
+
+class API(wsgi.Middleware):
+ """WSGI entry point for all Rackspace API requests."""
+
+ def __init__(self):
+ app = AuthMiddleware(APIRouter())
+ super(API, self).__init__(app)
+
+
+class AuthMiddleware(wsgi.Middleware):
+ """Authorize the rackspace API request or return an HTTP Forbidden."""
+
+ #TODO(gundlach): isn't this the old Nova API's auth? Should it be replaced
+ #with correct RS API auth?
+
+ @webob.dec.wsgify
+ def __call__(self, req):
+ context = {}
+ if "HTTP_X_AUTH_TOKEN" in req.environ:
+ context['user'] = manager.AuthManager().get_user_from_access_key(
+ req.environ['HTTP_X_AUTH_TOKEN'])
+ if context['user']:
+ context['project'] = manager.AuthManager().get_project(
+ context['user'].name)
+ if "user" not in context:
+ return webob.exc.HTTPForbidden()
+ req.environ['nova.context'] = context
+ return self.application
+
+
+class APIRouter(wsgi.Router):
+ """
+ Routes requests on the Rackspace API to the appropriate controller
+ and method.
+ """
+
+ def __init__(self):
+ mapper = routes.Mapper()
+ mapper.resource("server", "servers", controller=servers.Controller())
+ mapper.resource("image", "images", controller=images.Controller())
+ mapper.resource("flavor", "flavors", controller=flavors.Controller())
+ mapper.resource("sharedipgroup", "sharedipgroups",
+ controller=sharedipgroups.Controller())
+ super(APIRouter, self).__init__(mapper)
diff --git a/nova/api/rackspace/base.py b/nova/api/rackspace/base.py
new file mode 100644
index 000000000..c85fd7b8e
--- /dev/null
+++ b/nova/api/rackspace/base.py
@@ -0,0 +1,39 @@
+# 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.
+
+from nova import wsgi
+
+
+class Controller(wsgi.Controller):
+ """TODO(eday): Base controller for all rackspace controllers. What is this
+ for? Is this just Rackspace specific? """
+
+ @classmethod
+ def render(cls, instance):
+ if isinstance(instance, list):
+ return {cls.entity_name: cls.render(instance)}
+ else:
+ return { "TODO": "TODO" }
+
+ def serialize(self, data, request):
+ """
+ Serialize the given dict to the response type requested in request.
+ Uses self._serialization_metadata if it exists, which is a dict mapping
+ MIME types to information needed to serialize to that type.
+ """
+ _metadata = getattr(type(self), "_serialization_metadata", {})
+ return Serializer(request.environ, _metadata).to_content_type(data)
diff --git a/nova/api/rackspace/controllers/__init__.py b/nova/api/rackspace/controllers/__init__.py
new file mode 100644
index 000000000..052b6f365
--- /dev/null
+++ b/nova/api/rackspace/controllers/__init__.py
@@ -0,0 +1,5 @@
+from nova.endpoint.rackspace.controllers.images import ImagesController
+from nova.endpoint.rackspace.controllers.flavors import FlavorsController
+from nova.endpoint.rackspace.controllers.servers import ServersController
+from nova.endpoint.rackspace.controllers.sharedipgroups import \
+ SharedIpGroupsController
diff --git a/nova/api/rackspace/flavors.py b/nova/api/rackspace/flavors.py
new file mode 100644
index 000000000..986f11434
--- /dev/null
+++ b/nova/api/rackspace/flavors.py
@@ -0,0 +1,18 @@
+# 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.
+
+class Controller(object): pass
diff --git a/nova/api/rackspace/images.py b/nova/api/rackspace/images.py
new file mode 100644
index 000000000..57c03894a
--- /dev/null
+++ b/nova/api/rackspace/images.py
@@ -0,0 +1,64 @@
+# 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.
+
+from nova.endpoint.rackspace.controllers.base import BaseController
+from nova.endpoint import images
+from webob import exc
+
+#TODO(gundlach): Serialize return values
+class Controller(BaseController):
+
+ _serialization_metadata = {
+ 'application/xml': {
+ "attributes": {
+ "image": [ "id", "name", "updated", "created", "status",
+ "serverId", "progress" ]
+ }
+ }
+ }
+
+ def index(self, req):
+ context = req.environ['nova.api_request_context']
+ return images.list(context)
+
+ def show(self, req, id):
+ context = req.environ['nova.api_request_context']
+ return images.list(context, filter_list=[id])
+
+ def delete(self, req, id):
+ context = req.environ['nova.api_request_context']
+ # TODO(gundlach): make sure it's an image they may delete?
+ return images.deregister(context, id)
+
+ def create(self, **kwargs):
+ # TODO(gundlach): no idea how to hook this up. code below
+ # is from servers.py.
+ inst = self.build_server_instance(kwargs['server'])
+ rpc.cast(
+ FLAGS.compute_topic, {
+ "method": "run_instance",
+ "args": {"instance_id": inst.instance_id}})
+
+ def update(self, **kwargs):
+ # TODO (gundlach): no idea how to hook this up. code below
+ # is from servers.py.
+ instance_id = kwargs['id']
+ instance = compute.InstanceDirectory().get(instance_id)
+ if not instance:
+ raise ServerNotFound("The requested server was not found")
+ instance.update(kwargs['server'])
+ instance.save()
diff --git a/nova/api/rackspace/servers.py b/nova/api/rackspace/servers.py
new file mode 100644
index 000000000..25d1fe9c8
--- /dev/null
+++ b/nova/api/rackspace/servers.py
@@ -0,0 +1,83 @@
+# 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.
+
+from nova import rpc
+from nova.compute import model as compute
+from nova.api.rackspace import base
+
+
+class Controller(base.Controller):
+ entity_name = 'servers'
+
+ def index(self, **kwargs):
+ instances = []
+ for inst in compute.InstanceDirectory().all:
+ instances.append(instance_details(inst))
+
+ def show(self, **kwargs):
+ instance_id = kwargs['id']
+ return compute.InstanceDirectory().get(instance_id)
+
+ def delete(self, **kwargs):
+ instance_id = kwargs['id']
+ instance = compute.InstanceDirectory().get(instance_id)
+ if not instance:
+ raise ServerNotFound("The requested server was not found")
+ instance.destroy()
+ return True
+
+ def create(self, **kwargs):
+ inst = self.build_server_instance(kwargs['server'])
+ rpc.cast(
+ FLAGS.compute_topic, {
+ "method": "run_instance",
+ "args": {"instance_id": inst.instance_id}})
+
+ def update(self, **kwargs):
+ instance_id = kwargs['id']
+ instance = compute.InstanceDirectory().get(instance_id)
+ if not instance:
+ raise ServerNotFound("The requested server was not found")
+ instance.update(kwargs['server'])
+ instance.save()
+
+ def build_server_instance(self, env):
+ """Build instance data structure and save it to the data store."""
+ reservation = utils.generate_uid('r')
+ ltime = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime())
+ inst = self.instdir.new()
+ inst['name'] = env['server']['name']
+ inst['image_id'] = env['server']['imageId']
+ inst['instance_type'] = env['server']['flavorId']
+ inst['user_id'] = env['user']['id']
+ inst['project_id'] = env['project']['id']
+ inst['reservation_id'] = reservation
+ inst['launch_time'] = ltime
+ inst['mac_address'] = utils.generate_mac()
+ address = self.network.allocate_ip(
+ inst['user_id'],
+ inst['project_id'],
+ mac=inst['mac_address'])
+ inst['private_dns_name'] = str(address)
+ inst['bridge_name'] = network.BridgedNetwork.get_network_for_project(
+ inst['user_id'],
+ inst['project_id'],
+ 'default')['bridge_name']
+ # key_data, key_name, ami_launch_index
+ # TODO(todd): key data or root password
+ inst.save()
+ return inst
diff --git a/nova/api/rackspace/sharedipgroups.py b/nova/api/rackspace/sharedipgroups.py
new file mode 100644
index 000000000..986f11434
--- /dev/null
+++ b/nova/api/rackspace/sharedipgroups.py
@@ -0,0 +1,18 @@
+# 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.
+
+class Controller(object): pass