From 5682d2a27b252c1aca294eb8a0749ff3fbb13b26 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Fri, 23 Dec 2011 10:20:37 -0500 Subject: Convering /users to admin extension Relates to blueprint separate-nova-adminapi Change-Id: I0ef13569586be022ba533c4e850793b37b098fea --- nova/api/openstack/v2/__init__.py | 5 -- nova/api/openstack/v2/contrib/users.py | 154 +++++++++++++++++++++++++++++++++ nova/api/openstack/v2/users.py | 139 ----------------------------- 3 files changed, 154 insertions(+), 144 deletions(-) create mode 100644 nova/api/openstack/v2/contrib/users.py delete mode 100644 nova/api/openstack/v2/users.py (limited to 'nova/api') diff --git a/nova/api/openstack/v2/__init__.py b/nova/api/openstack/v2/__init__.py index 1d3830b05..1dadd7bef 100644 --- a/nova/api/openstack/v2/__init__.py +++ b/nova/api/openstack/v2/__init__.py @@ -33,7 +33,6 @@ from nova.api.openstack.v2 import ips from nova.api.openstack.v2 import limits from nova.api.openstack.v2 import servers from nova.api.openstack.v2 import server_metadata -from nova.api.openstack.v2 import users from nova.api.openstack.v2 import versions from nova.api.openstack.v2 import zones from nova.api.openstack import wsgi @@ -134,10 +133,6 @@ class APIRouter(base_wsgi.Router): if FLAGS.allow_admin_api: LOG.debug(_("Including admin operations in API.")) - mapper.resource("user", "users", - controller=users.create_resource(), - collection={'detail': 'GET'}) - mapper.resource("zone", "zones", controller=zones.create_resource(), collection={'detail': 'GET', diff --git a/nova/api/openstack/v2/contrib/users.py b/nova/api/openstack/v2/contrib/users.py new file mode 100644 index 000000000..b9bdd75e4 --- /dev/null +++ b/nova/api/openstack/v2/contrib/users.py @@ -0,0 +1,154 @@ +# Copyright 2011 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 webob import exc + +from nova.api.openstack import common +from nova.api.openstack.v2 import extensions +from nova.api.openstack import wsgi +from nova.api.openstack import xmlutil +from nova.auth import manager +from nova import exception +from nova import flags +from nova import log as logging + + +FLAGS = flags.FLAGS +LOG = logging.getLogger('nova.api.openstack.users') + + +def _translate_keys(user): + return dict(id=user.id, + name=user.name, + access=user.access, + secret=user.secret, + admin=user.admin) + + +class Controller(object): + + def __init__(self): + self.manager = manager.AuthManager() + + def _check_admin(self, context): + """We cannot depend on the db layer to check for admin access + for the auth manager, so we do it here""" + if not context.is_admin: + raise exception.AdminRequired() + + def index(self, req): + """Return all users in brief""" + users = self.manager.get_users() + users = common.limited(users, req) + users = [_translate_keys(user) for user in users] + return dict(users=users) + + def detail(self, req): + """Return all users in detail""" + return self.index(req) + + def show(self, req, id): + """Return data about the given user id""" + + #NOTE(justinsb): The drivers are a little inconsistent in how they + # deal with "NotFound" - some throw, some return None. + try: + user = self.manager.get_user(id) + except exception.NotFound: + user = None + + if user is None: + raise exc.HTTPNotFound() + + return dict(user=_translate_keys(user)) + + def delete(self, req, id): + self._check_admin(req.environ['nova.context']) + self.manager.delete_user(id) + return {} + + def create(self, req, body): + self._check_admin(req.environ['nova.context']) + is_admin = body['user'].get('admin') in ('T', 'True', True) + name = body['user'].get('name') + access = body['user'].get('access') + secret = body['user'].get('secret') + user = self.manager.create_user(name, access, secret, is_admin) + return dict(user=_translate_keys(user)) + + def update(self, req, id, body): + self._check_admin(req.environ['nova.context']) + is_admin = body['user'].get('admin') + if is_admin is not None: + is_admin = is_admin in ('T', 'True', True) + access = body['user'].get('access') + secret = body['user'].get('secret') + self.manager.modify_user(id, access, secret, is_admin) + return dict(user=_translate_keys(self.manager.get_user(id))) + + +def make_user(elem): + elem.set('id') + elem.set('name') + elem.set('access') + elem.set('secret') + elem.set('admin') + + +class UserTemplate(xmlutil.TemplateBuilder): + def construct(self): + root = xmlutil.TemplateElement('user', selector='user') + make_user(root) + return xmlutil.MasterTemplate(root, 1) + + +class UsersTemplate(xmlutil.TemplateBuilder): + def construct(self): + root = xmlutil.TemplateElement('users') + elem = xmlutil.SubTemplateElement(root, 'user', selector='users') + make_user(elem) + return xmlutil.MasterTemplate(root, 1) + + +class UserXMLSerializer(xmlutil.XMLTemplateSerializer): + def index(self): + return UsersTemplate() + + def default(self): + return UserTemplate() + + +class Users(extensions.ExtensionDescriptor): + """Allow admins to acces user information""" + + name = "Users" + alias = "os-users" + namespace = "http://docs.openstack.org/compute/ext/users/api/v1.1" + updated = "2011-08-08T00:00:00+00:00" + admin_only = True + + def get_resources(self): + body_serializers = { + 'application/xml': UserXMLSerializer(), + } + serializer = wsgi.ResponseSerializer(body_serializers) + + coll_actions = {'detail': 'GET'} + res = extensions.ResourceExtension('users', + Controller(), + serializer=serializer, + collection_actions=coll_actions) + + return [res] diff --git a/nova/api/openstack/v2/users.py b/nova/api/openstack/v2/users.py deleted file mode 100644 index 9dba79e03..000000000 --- a/nova/api/openstack/v2/users.py +++ /dev/null @@ -1,139 +0,0 @@ -# Copyright 2011 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 webob import exc - -from nova.api.openstack import common -from nova.api.openstack import wsgi -from nova.api.openstack import xmlutil -from nova.auth import manager -from nova import exception -from nova import flags -from nova import log as logging - - -FLAGS = flags.FLAGS -LOG = logging.getLogger('nova.api.openstack.users') - - -def _translate_keys(user): - return dict(id=user.id, - name=user.name, - access=user.access, - secret=user.secret, - admin=user.admin) - - -class Controller(object): - - def __init__(self): - self.manager = manager.AuthManager() - - def _check_admin(self, context): - """We cannot depend on the db layer to check for admin access - for the auth manager, so we do it here""" - if not context.is_admin: - raise exception.AdminRequired() - - def index(self, req): - """Return all users in brief""" - users = self.manager.get_users() - users = common.limited(users, req) - users = [_translate_keys(user) for user in users] - return dict(users=users) - - def detail(self, req): - """Return all users in detail""" - return self.index(req) - - def show(self, req, id): - """Return data about the given user id""" - - #NOTE(justinsb): The drivers are a little inconsistent in how they - # deal with "NotFound" - some throw, some return None. - try: - user = self.manager.get_user(id) - except exception.NotFound: - user = None - - if user is None: - raise exc.HTTPNotFound() - - return dict(user=_translate_keys(user)) - - def delete(self, req, id): - self._check_admin(req.environ['nova.context']) - self.manager.delete_user(id) - return {} - - def create(self, req, body): - self._check_admin(req.environ['nova.context']) - is_admin = body['user'].get('admin') in ('T', 'True', True) - name = body['user'].get('name') - access = body['user'].get('access') - secret = body['user'].get('secret') - user = self.manager.create_user(name, access, secret, is_admin) - return dict(user=_translate_keys(user)) - - def update(self, req, id, body): - self._check_admin(req.environ['nova.context']) - is_admin = body['user'].get('admin') - if is_admin is not None: - is_admin = is_admin in ('T', 'True', True) - access = body['user'].get('access') - secret = body['user'].get('secret') - self.manager.modify_user(id, access, secret, is_admin) - return dict(user=_translate_keys(self.manager.get_user(id))) - - -def make_user(elem): - elem.set('id') - elem.set('name') - elem.set('access') - elem.set('secret') - elem.set('admin') - - -class UserTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('user', selector='user') - make_user(root) - return xmlutil.MasterTemplate(root, 1) - - -class UsersTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('users') - elem = xmlutil.SubTemplateElement(root, 'user', selector='users') - make_user(elem) - return xmlutil.MasterTemplate(root, 1) - - -class UserXMLSerializer(xmlutil.XMLTemplateSerializer): - def index(self): - return UsersTemplate() - - def default(self): - return UserTemplate() - - -def create_resource(): - body_serializers = { - 'application/xml': UserXMLSerializer(), - } - - serializer = wsgi.ResponseSerializer(body_serializers) - - return wsgi.Resource(Controller(), serializer=serializer) -- cgit