summaryrefslogtreecommitdiffstats
path: root/nova/api
diff options
context:
space:
mode:
authorSandy Walsh <sandy.walsh@rackspace.com>2011-03-24 19:22:05 +0000
committerTarmac <>2011-03-24 19:22:05 +0000
commita0ea76b26a7725efb2fc4a811dff66b4f8bff6b7 (patch)
tree8b5411b38c5911ae6558f4c5d0de1320b23b0d79 /nova/api
parent0d42b309ac723d18e6795210bc8d8ca6d295de23 (diff)
parent18eee851d86451737102bacca777c93d3eb66bb3 (diff)
In this branch we are forwarding incoming requests to child zones when the requested resource is not found in the current zone.
For example: If 'nova pause 123' is issued against Zone 1, but instance 123 does not live in Zone 1, the call will be forwarded to all child zones hoping someone can deal with it. NOTE: This currently only works with OpenStack API requests and routing checks are only being done against Compute/instance_id checks. Specifically: * servers.get/pause/unpause/diagnostics/suspend/resume/rescue/unrescue/delete * servers.create is pending for distributed scheduler * servers.get_all will get added early in Diablo. What I've been doing for testing: 1. Set up a Nova deployment in a VM (Zone0) 2. Clone the VM and set --zone_name=zone1 (and change all the IP addresses to the new address in nova.conf, glance.conf and novarc) 3. Set --enable_zone_routing=true on all zones 4. use the --connection_type=fake driver for compute to keep things easy 5. Add Zone1 as a child of Zone0 (nova zone-add) (make sure the instance id's are different in each zone) Example of calls being sent to child zones: http://paste.openstack.org/show/964/
Diffstat (limited to 'nova/api')
-rw-r--r--nova/api/openstack/servers.py21
-rw-r--r--nova/api/openstack/zones.py18
2 files changed, 28 insertions, 11 deletions
diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py
index 1b4f28f59..0dad46268 100644
--- a/nova/api/openstack/servers.py
+++ b/nova/api/openstack/servers.py
@@ -37,6 +37,7 @@ from nova.auth import manager as auth_manager
from nova.compute import instance_types
from nova.compute import power_state
import nova.api.openstack
+from nova.scheduler import api as scheduler_api
LOG = logging.getLogger('server')
@@ -87,15 +88,18 @@ class Controller(wsgi.Controller):
for inst in limited_list]
return dict(servers=servers)
+ @scheduler_api.redirect_handler
def show(self, req, id):
""" Returns server details by server id """
try:
- instance = self.compute_api.get(req.environ['nova.context'], id)
+ instance = self.compute_api.routing_get(
+ req.environ['nova.context'], id)
builder = self._get_view_builder(req)
return builder.build(instance, is_detail=True)
except exception.NotFound:
return faults.Fault(exc.HTTPNotFound())
+ @scheduler_api.redirect_handler
def delete(self, req, id):
""" Destroys a server """
try:
@@ -226,6 +230,7 @@ class Controller(wsgi.Controller):
# if the original error is okay, just reraise it
raise error
+ @scheduler_api.redirect_handler
def update(self, req, id):
""" Updates the server name or password """
if len(req.body) == 0:
@@ -251,6 +256,7 @@ class Controller(wsgi.Controller):
return faults.Fault(exc.HTTPNotFound())
return exc.HTTPNoContent()
+ @scheduler_api.redirect_handler
def action(self, req, id):
"""Multi-purpose method used to reboot, rebuild, or
resize a server"""
@@ -316,6 +322,7 @@ class Controller(wsgi.Controller):
return faults.Fault(exc.HTTPUnprocessableEntity())
return exc.HTTPAccepted()
+ @scheduler_api.redirect_handler
def lock(self, req, id):
"""
lock the instance with id
@@ -331,6 +338,7 @@ class Controller(wsgi.Controller):
return faults.Fault(exc.HTTPUnprocessableEntity())
return exc.HTTPAccepted()
+ @scheduler_api.redirect_handler
def unlock(self, req, id):
"""
unlock the instance with id
@@ -346,6 +354,7 @@ class Controller(wsgi.Controller):
return faults.Fault(exc.HTTPUnprocessableEntity())
return exc.HTTPAccepted()
+ @scheduler_api.redirect_handler
def get_lock(self, req, id):
"""
return the boolean state of (instance with id)'s lock
@@ -360,6 +369,7 @@ class Controller(wsgi.Controller):
return faults.Fault(exc.HTTPUnprocessableEntity())
return exc.HTTPAccepted()
+ @scheduler_api.redirect_handler
def reset_network(self, req, id):
"""
Reset networking on an instance (admin only).
@@ -374,6 +384,7 @@ class Controller(wsgi.Controller):
return faults.Fault(exc.HTTPUnprocessableEntity())
return exc.HTTPAccepted()
+ @scheduler_api.redirect_handler
def inject_network_info(self, req, id):
"""
Inject network info for an instance (admin only).
@@ -388,6 +399,7 @@ class Controller(wsgi.Controller):
return faults.Fault(exc.HTTPUnprocessableEntity())
return exc.HTTPAccepted()
+ @scheduler_api.redirect_handler
def pause(self, req, id):
""" Permit Admins to Pause the server. """
ctxt = req.environ['nova.context']
@@ -399,6 +411,7 @@ class Controller(wsgi.Controller):
return faults.Fault(exc.HTTPUnprocessableEntity())
return exc.HTTPAccepted()
+ @scheduler_api.redirect_handler
def unpause(self, req, id):
""" Permit Admins to Unpause the server. """
ctxt = req.environ['nova.context']
@@ -410,6 +423,7 @@ class Controller(wsgi.Controller):
return faults.Fault(exc.HTTPUnprocessableEntity())
return exc.HTTPAccepted()
+ @scheduler_api.redirect_handler
def suspend(self, req, id):
"""permit admins to suspend the server"""
context = req.environ['nova.context']
@@ -421,6 +435,7 @@ class Controller(wsgi.Controller):
return faults.Fault(exc.HTTPUnprocessableEntity())
return exc.HTTPAccepted()
+ @scheduler_api.redirect_handler
def resume(self, req, id):
"""permit admins to resume the server from suspend"""
context = req.environ['nova.context']
@@ -432,6 +447,7 @@ class Controller(wsgi.Controller):
return faults.Fault(exc.HTTPUnprocessableEntity())
return exc.HTTPAccepted()
+ @scheduler_api.redirect_handler
def rescue(self, req, id):
"""Permit users to rescue the server."""
context = req.environ["nova.context"]
@@ -443,6 +459,7 @@ class Controller(wsgi.Controller):
return faults.Fault(exc.HTTPUnprocessableEntity())
return exc.HTTPAccepted()
+ @scheduler_api.redirect_handler
def unrescue(self, req, id):
"""Permit users to unrescue the server."""
context = req.environ["nova.context"]
@@ -454,6 +471,7 @@ class Controller(wsgi.Controller):
return faults.Fault(exc.HTTPUnprocessableEntity())
return exc.HTTPAccepted()
+ @scheduler_api.redirect_handler
def get_ajax_console(self, req, id):
""" Returns a url to an instance's ajaxterm console. """
try:
@@ -463,6 +481,7 @@ class Controller(wsgi.Controller):
return faults.Fault(exc.HTTPNotFound())
return exc.HTTPAccepted()
+ @scheduler_api.redirect_handler
def diagnostics(self, req, id):
"""Permit Admins to retrieve server diagnostics."""
ctxt = req.environ["nova.context"]
diff --git a/nova/api/openstack/zones.py b/nova/api/openstack/zones.py
index d4a59993b..846cb48a1 100644
--- a/nova/api/openstack/zones.py
+++ b/nova/api/openstack/zones.py
@@ -17,6 +17,7 @@ import common
from nova import db
from nova import flags
+from nova import log as logging
from nova import wsgi
from nova.scheduler import api
@@ -38,7 +39,8 @@ def _exclude_keys(item, keys):
def _scrub_zone(zone):
- return _filter_keys(zone, ('id', 'api_url'))
+ return _exclude_keys(zone, ('username', 'password', 'created_at',
+ 'deleted', 'deleted_at', 'updated_at'))
class Controller(wsgi.Controller):
@@ -53,12 +55,8 @@ class Controller(wsgi.Controller):
# Ask the ZoneManager in the Scheduler for most recent data,
# or fall-back to the database ...
items = api.get_zone_list(req.environ['nova.context'])
- if not items:
- items = db.zone_get_all(req.environ['nova.context'])
-
items = common.limited(items, req)
- items = [_exclude_keys(item, ['username', 'password'])
- for item in items]
+ items = [_scrub_zone(item) for item in items]
return dict(zones=items)
def detail(self, req):
@@ -81,23 +79,23 @@ class Controller(wsgi.Controller):
def show(self, req, id):
"""Return data about the given zone id"""
zone_id = int(id)
- zone = db.zone_get(req.environ['nova.context'], zone_id)
+ zone = api.zone_get(req.environ['nova.context'], zone_id)
return dict(zone=_scrub_zone(zone))
def delete(self, req, id):
zone_id = int(id)
- db.zone_delete(req.environ['nova.context'], zone_id)
+ api.zone_delete(req.environ['nova.context'], zone_id)
return {}
def create(self, req):
context = req.environ['nova.context']
env = self._deserialize(req.body, req.get_content_type())
- zone = db.zone_create(context, env["zone"])
+ zone = api.zone_create(context, env["zone"])
return dict(zone=_scrub_zone(zone))
def update(self, req, id):
context = req.environ['nova.context']
env = self._deserialize(req.body, req.get_content_type())
zone_id = int(id)
- zone = db.zone_update(context, zone_id, env["zone"])
+ zone = api.zone_update(context, zone_id, env["zone"])
return dict(zone=_scrub_zone(zone))