summaryrefslogtreecommitdiffstats
path: root/nova/api
diff options
context:
space:
mode:
authorWilliam Wolf <throughnothing@gmail.com>2011-08-01 14:20:10 -0400
committerWilliam Wolf <throughnothing@gmail.com>2011-08-01 14:20:10 -0400
commit324c95415fcd66265da62ff6280d4e7e6a4434f1 (patch)
treeb5ff3bd2b57c6fdc8117128076ef515e056c2914 /nova/api
parent6d62453f4834447f6c06a58ec52c1037d4142293 (diff)
parentbdcfaa5b927a096f507fb0f7e2d81989173957f8 (diff)
downloadnova-324c95415fcd66265da62ff6280d4e7e6a4434f1.tar.gz
nova-324c95415fcd66265da62ff6280d4e7e6a4434f1.tar.xz
nova-324c95415fcd66265da62ff6280d4e7e6a4434f1.zip
merge from trunk
Diffstat (limited to 'nova/api')
-rw-r--r--nova/api/direct.py3
-rw-r--r--nova/api/ec2/__init__.py32
-rw-r--r--nova/api/openstack/auth.py28
-rw-r--r--nova/api/openstack/create_instance_helper.py7
-rw-r--r--nova/api/openstack/servers.py57
-rw-r--r--nova/api/openstack/views/servers.py14
6 files changed, 76 insertions, 65 deletions
diff --git a/nova/api/direct.py b/nova/api/direct.py
index ec79151b1..993815fc7 100644
--- a/nova/api/direct.py
+++ b/nova/api/direct.py
@@ -107,7 +107,8 @@ class DelegatedAuthMiddleware(wsgi.Middleware):
def process_request(self, request):
os_user = request.headers['X-OpenStack-User']
os_project = request.headers['X-OpenStack-Project']
- context_ref = context.RequestContext(user=os_user, project=os_project)
+ context_ref = context.RequestContext(user_id=os_user,
+ project_id=os_project)
request.environ['openstack.context'] = context_ref
diff --git a/nova/api/ec2/__init__.py b/nova/api/ec2/__init__.py
index cf1734281..af232edda 100644
--- a/nova/api/ec2/__init__.py
+++ b/nova/api/ec2/__init__.py
@@ -66,7 +66,7 @@ class RequestLogging(wsgi.Middleware):
else:
controller = None
action = None
- ctxt = request.environ.get('ec2.context', None)
+ ctxt = request.environ.get('nova.context', None)
delta = utils.utcnow() - start
seconds = delta.seconds
microseconds = delta.microseconds
@@ -139,8 +139,7 @@ class Lockout(wsgi.Middleware):
class Authenticate(wsgi.Middleware):
-
- """Authenticate an EC2 request and add 'ec2.context' to WSGI environ."""
+ """Authenticate an EC2 request and add 'nova.context' to WSGI environ."""
@webob.dec.wsgify(RequestClass=wsgi.Request)
def __call__(self, req):
@@ -157,8 +156,9 @@ class Authenticate(wsgi.Middleware):
auth_params.pop('Signature')
# Authenticate the request.
+ authman = manager.AuthManager()
try:
- (user, project) = manager.AuthManager().authenticate(
+ (user, project) = authman.authenticate(
access,
signature,
auth_params,
@@ -174,14 +174,17 @@ class Authenticate(wsgi.Middleware):
remote_address = req.remote_addr
if FLAGS.use_forwarded_for:
remote_address = req.headers.get('X-Forwarded-For', remote_address)
- ctxt = context.RequestContext(user=user,
- project=project,
+ roles = authman.get_active_roles(user, project)
+ ctxt = context.RequestContext(user_id=user.id,
+ project_id=project.id,
+ is_admin=user.is_admin(),
+ roles=roles,
remote_address=remote_address)
- req.environ['ec2.context'] = ctxt
+ req.environ['nova.context'] = ctxt
uname = user.name
pname = project.name
msg = _('Authenticated Request For %(uname)s:%(pname)s)') % locals()
- LOG.audit(msg, context=req.environ['ec2.context'])
+ LOG.audit(msg, context=req.environ['nova.context'])
return self.application
@@ -228,7 +231,7 @@ class Authorizer(wsgi.Middleware):
"""Authorize an EC2 API request.
Return a 401 if ec2.controller and ec2.action in WSGI environ may not be
- executed in ec2.context.
+ executed in nova.context.
"""
def __init__(self, application):
@@ -282,7 +285,7 @@ class Authorizer(wsgi.Middleware):
@webob.dec.wsgify(RequestClass=wsgi.Request)
def __call__(self, req):
- context = req.environ['ec2.context']
+ context = req.environ['nova.context']
controller = req.environ['ec2.request'].controller.__class__.__name__
action = req.environ['ec2.request'].action
allowed_roles = self.action_roles[controller].get(action, ['none'])
@@ -295,28 +298,27 @@ class Authorizer(wsgi.Middleware):
def _matches_any_role(self, context, roles):
"""Return True if any role in roles is allowed in context."""
- if context.user.is_superuser():
+ if context.is_admin:
return True
if 'all' in roles:
return True
if 'none' in roles:
return False
- return any(context.project.has_role(context.user_id, role)
- for role in roles)
+ return any(role in context.roles for role in roles)
class Executor(wsgi.Application):
"""Execute an EC2 API request.
- Executes 'ec2.action' upon 'ec2.controller', passing 'ec2.context' and
+ Executes 'ec2.action' upon 'ec2.controller', passing 'nova.context' and
'ec2.action_args' (all variables in WSGI environ.) Returns an XML
response, or a 400 upon failure.
"""
@webob.dec.wsgify(RequestClass=wsgi.Request)
def __call__(self, req):
- context = req.environ['ec2.context']
+ context = req.environ['nova.context']
api_request = req.environ['ec2.request']
result = None
try:
diff --git a/nova/api/openstack/auth.py b/nova/api/openstack/auth.py
index 7c3e683d6..d42abe1f8 100644
--- a/nova/api/openstack/auth.py
+++ b/nova/api/openstack/auth.py
@@ -48,31 +48,35 @@ class AuthMiddleware(wsgi.Middleware):
def __call__(self, req):
if not self.has_authentication(req):
return self.authenticate(req)
- user = self.get_user_by_authentication(req)
- if not user:
+ user_id = self.get_user_by_authentication(req)
+ if not user_id:
token = req.headers["X-Auth-Token"]
- msg = _("%(user)s could not be found with token '%(token)s'")
+ msg = _("%(user_id)s could not be found with token '%(token)s'")
LOG.warn(msg % locals())
return faults.Fault(webob.exc.HTTPUnauthorized())
try:
- account = req.headers["X-Auth-Project-Id"]
+ project_id = req.headers["X-Auth-Project-Id"]
except KeyError:
# FIXME(usrleon): It needed only for compatibility
# while osapi clients don't use this header
- accounts = self.auth.get_projects(user=user)
- if accounts:
- account = accounts[0]
+ projects = self.auth.get_projects(user_id)
+ if projects:
+ project_id = projects[0].id
else:
return faults.Fault(webob.exc.HTTPUnauthorized())
- if not self.auth.is_admin(user) and \
- not self.auth.is_project_member(user, account):
- msg = _("%(user)s must be an admin or a member of %(account)s")
+ is_admin = self.auth.is_admin(user_id)
+ req.environ['nova.context'] = context.RequestContext(user_id,
+ project_id,
+ is_admin)
+ if not is_admin and not self.auth.is_project_member(user_id,
+ project_id):
+ msg = _("%(user_id)s must be an admin or a "
+ "member of %(project_id)s")
LOG.warn(msg % locals())
return faults.Fault(webob.exc.HTTPUnauthorized())
- req.environ['nova.context'] = context.RequestContext(user, account)
return self.application
def has_authentication(self, req):
@@ -133,7 +137,7 @@ class AuthMiddleware(wsgi.Middleware):
if delta.days >= 2:
self.db.auth_token_destroy(ctxt, token['token_hash'])
else:
- return self.auth.get_user(token['user_id'])
+ return token['user_id']
return None
def _authorize_user(self, username, key, req):
diff --git a/nova/api/openstack/create_instance_helper.py b/nova/api/openstack/create_instance_helper.py
index 1342397c4..9199c193d 100644
--- a/nova/api/openstack/create_instance_helper.py
+++ b/nova/api/openstack/create_instance_helper.py
@@ -20,6 +20,7 @@ import webob
from webob import exc
from xml.dom import minidom
+from nova import db
from nova import exception
from nova import flags
from nova import log as logging
@@ -29,7 +30,6 @@ from nova import utils
from nova.compute import instance_types
from nova.api.openstack import wsgi
-from nova.auth import manager as auth_manager
LOG = logging.getLogger('nova.api.openstack.create_instance_helper')
@@ -80,7 +80,10 @@ class CreateInstanceHelper(object):
key_name = None
key_data = None
- key_pairs = auth_manager.AuthManager.get_key_pairs(context)
+ # TODO(vish): Key pair access should move into a common library
+ # instead of being accessed directly from the db.
+ key_pairs = db.key_pair_get_all_by_user(context.elevated(),
+ context.user_id)
if key_pairs:
key_pair = key_pairs[0]
key_name = key_pair['name']
diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py
index f6841318d..30169d450 100644
--- a/nova/api/openstack/servers.py
+++ b/nova/api/openstack/servers.py
@@ -17,11 +17,10 @@ import base64
import traceback
from webob import exc
-import webob
from xml.dom import minidom
+import webob
from nova import compute
-from nova import db
from nova import exception
from nova import flags
from nova import log as logging
@@ -29,13 +28,14 @@ from nova import utils
from nova.api.openstack import common
from nova.api.openstack import create_instance_helper as helper
from nova.api.openstack import ips
+from nova.api.openstack import wsgi
+from nova.compute import instance_types
+from nova.scheduler import api as scheduler_api
+import nova.api.openstack
import nova.api.openstack.views.addresses
import nova.api.openstack.views.flavors
import nova.api.openstack.views.images
import nova.api.openstack.views.servers
-from nova.api.openstack import wsgi
-import nova.api.openstack
-from nova.scheduler import api as scheduler_api
LOG = logging.getLogger('nova.api.openstack.servers')
@@ -438,13 +438,21 @@ class ControllerV10(Controller):
def _action_resize(self, input_dict, req, id):
""" Resizes a given instance to the flavor size requested """
- if 'resize' in input_dict and 'flavorId' in input_dict['resize']:
- flavor_id = input_dict['resize']['flavorId']
- self.compute_api.resize(req.environ['nova.context'], id,
- flavor_id)
- else:
- LOG.exception(_("Missing 'flavorId' argument for resize"))
- raise exc.HTTPUnprocessableEntity()
+ try:
+ flavor_id = input_dict["resize"]["flavorId"]
+ except (KeyError, TypeError):
+ msg = _("Resize requests require 'flavorId' attribute.")
+ raise exc.HTTPBadRequest(explanation=msg)
+
+ try:
+ i_type = instance_types.get_instance_type_by_flavor_id(flavor_id)
+ except exception.FlavorNotFound:
+ msg = _("Unable to locate requested flavor.")
+ raise exc.HTTPBadRequest(explanation=msg)
+
+ context = req.environ["nova.context"]
+ self.compute_api.resize(context, id, i_type["id"])
+
return webob.Response(status_int=202)
def _action_rebuild(self, info, request, instance_id):
@@ -555,17 +563,20 @@ class ControllerV11(Controller):
def _action_resize(self, input_dict, req, id):
""" Resizes a given instance to the flavor size requested """
try:
- if 'resize' in input_dict and 'flavorRef' in input_dict['resize']:
- flavor_ref = input_dict['resize']['flavorRef']
- flavor_id = common.get_id_from_href(flavor_ref)
- self.compute_api.resize(req.environ['nova.context'], id,
- flavor_id)
- else:
- LOG.exception(_("Missing 'flavorRef' argument for resize"))
- raise exc.HTTPUnprocessableEntity()
- except Exception, e:
- LOG.exception(_("Error in resize %s"), e)
- raise exc.HTTPBadRequest()
+ flavor_ref = input_dict["resize"]["flavorRef"]
+ except (KeyError, TypeError):
+ msg = _("Resize requests require 'flavorRef' attribute.")
+ raise exc.HTTPBadRequest(explanation=msg)
+
+ try:
+ i_type = instance_types.get_instance_type_by_flavor_id(flavor_ref)
+ except exception.FlavorNotFound:
+ msg = _("Unable to locate requested flavor.")
+ raise exc.HTTPBadRequest(explanation=msg)
+
+ context = req.environ["nova.context"]
+ self.compute_api.resize(context, id, i_type["id"])
+
return webob.Response(status_int=202)
def _action_rebuild(self, info, request, instance_id):
diff --git a/nova/api/openstack/views/servers.py b/nova/api/openstack/views/servers.py
index 659a43522..2873a8e0f 100644
--- a/nova/api/openstack/views/servers.py
+++ b/nova/api/openstack/views/servers.py
@@ -150,10 +150,8 @@ class ViewBuilderV11(ViewBuilder):
def _build_detail(self, inst):
response = super(ViewBuilderV11, self)._build_detail(inst)
- response['server']['created'] = \
- self._convert_timeformat(inst['created_at'])
- response['server']['updated'] = \
- self._convert_timeformat(inst['updated_at'])
+ response['server']['created'] = utils.isotime(inst['created_at'])
+ response['server']['updated'] = utils.isotime(inst['updated_at'])
if 'status' in response['server']:
if response['server']['status'] == "ACTIVE":
response['server']['progress'] = 100
@@ -224,11 +222,3 @@ class ViewBuilderV11(ViewBuilder):
"""Create an url that refers to a specific flavor id."""
return os.path.join(common.remove_version_from_href(self.base_url),
"servers", str(server_id))
-
- def _convert_timeformat(self, date_time):
- """Converts the given time into the common time format
-
- :param date_time: the datetime object to convert
-
- """
- return date_time.strftime(utils.TIME_FORMAT)