From 98851c82fd9fab193e034e8fe3b13e249f3b53bd Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Fri, 23 Dec 2011 09:22:38 -0500 Subject: Converting accounts resource to admin extension Relates to blueprint separate-nova-adminapi Change-Id: I672c14df30eea4807930a0975916237542fe9d68 --- nova/api/openstack/v2/__init__.py | 5 -- nova/api/openstack/v2/accounts.py | 103 -------------------------- nova/api/openstack/v2/contrib/accounts.py | 116 ++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 108 deletions(-) delete mode 100644 nova/api/openstack/v2/accounts.py create mode 100644 nova/api/openstack/v2/contrib/accounts.py (limited to 'nova/api') diff --git a/nova/api/openstack/v2/__init__.py b/nova/api/openstack/v2/__init__.py index 82a8764a0..1d3830b05 100644 --- a/nova/api/openstack/v2/__init__.py +++ b/nova/api/openstack/v2/__init__.py @@ -24,7 +24,6 @@ import routes import webob.dec import webob.exc -from nova.api.openstack.v2 import accounts from nova.api.openstack.v2 import consoles from nova.api.openstack.v2 import extensions from nova.api.openstack.v2 import flavors @@ -139,10 +138,6 @@ class APIRouter(base_wsgi.Router): controller=users.create_resource(), collection={'detail': 'GET'}) - mapper.resource("account", "accounts", - controller=accounts.create_resource(), - collection={'detail': 'GET'}) - mapper.resource("zone", "zones", controller=zones.create_resource(), collection={'detail': 'GET', diff --git a/nova/api/openstack/v2/accounts.py b/nova/api/openstack/v2/accounts.py deleted file mode 100644 index 0f1584261..000000000 --- a/nova/api/openstack/v2/accounts.py +++ /dev/null @@ -1,103 +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. - -import webob.exc - -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.v2.accounts') - - -def _translate_keys(account): - return dict(id=account.id, - name=account.name, - description=account.description, - manager=account.project_manager_id) - - -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): - raise webob.exc.HTTPNotImplemented() - - def detail(self, req): - raise webob.exc.HTTPNotImplemented() - - def show(self, req, id): - """Return data about the given account id""" - account = self.manager.get_project(id) - return dict(account=_translate_keys(account)) - - def delete(self, req, id): - self._check_admin(req.environ['nova.context']) - self.manager.delete_project(id) - return {} - - def create(self, req, body): - """We use update with create-or-update semantics - because the id comes from an external source""" - raise webob.exc.HTTPNotImplemented() - - def update(self, req, id, body): - """This is really create or update.""" - self._check_admin(req.environ['nova.context']) - description = body['account'].get('description') - manager = body['account'].get('manager') - try: - account = self.manager.get_project(id) - self.manager.modify_project(id, manager, description) - except exception.NotFound: - account = self.manager.create_project(id, manager, description) - return dict(account=_translate_keys(account)) - - -class AccountTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('account', selector='account') - root.set('id', 'id') - root.set('name', 'name') - root.set('description', 'description') - root.set('manager', 'manager') - - return xmlutil.MasterTemplate(root, 1) - - -class AccountXMLSerializer(xmlutil.XMLTemplateSerializer): - def default(self): - return AccountTemplate() - - -def create_resource(): - body_serializers = { - 'application/xml': AccountXMLSerializer(), - } - serializer = wsgi.ResponseSerializer(body_serializers) - return wsgi.Resource(Controller(), serializer=serializer) diff --git a/nova/api/openstack/v2/contrib/accounts.py b/nova/api/openstack/v2/contrib/accounts.py new file mode 100644 index 000000000..263eda640 --- /dev/null +++ b/nova/api/openstack/v2/contrib/accounts.py @@ -0,0 +1,116 @@ +# 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. + +import webob.exc + +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.v2.contrib.accounts') + + +def _translate_keys(account): + return dict(id=account.id, + name=account.name, + description=account.description, + manager=account.project_manager_id) + + +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): + raise webob.exc.HTTPNotImplemented() + + def show(self, req, id): + """Return data about the given account id""" + account = self.manager.get_project(id) + return dict(account=_translate_keys(account)) + + def delete(self, req, id): + self._check_admin(req.environ['nova.context']) + self.manager.delete_project(id) + return {} + + def create(self, req, body): + """We use update with create-or-update semantics + because the id comes from an external source""" + raise webob.exc.HTTPNotImplemented() + + def update(self, req, id, body): + """This is really create or update.""" + self._check_admin(req.environ['nova.context']) + description = body['account'].get('description') + manager = body['account'].get('manager') + try: + account = self.manager.get_project(id) + self.manager.modify_project(id, manager, description) + except exception.NotFound: + account = self.manager.create_project(id, manager, description) + return dict(account=_translate_keys(account)) + + +class AccountTemplate(xmlutil.TemplateBuilder): + def construct(self): + root = xmlutil.TemplateElement('account', selector='account') + root.set('id', 'id') + root.set('name', 'name') + root.set('description', 'description') + root.set('manager', 'manager') + + return xmlutil.MasterTemplate(root, 1) + + +class AccountXMLSerializer(xmlutil.XMLTemplateSerializer): + def default(self): + return AccountTemplate() + + +class Accounts(extensions.ExtensionDescriptor): + """Admin-only access to accounts""" + + name = "Accounts" + alias = "os-accounts" + namespace = "http://docs.openstack.org/compute/ext/accounts/api/v1.1" + updated = "2011-12-23T00:00:00+00:00" + admin_only = True + + def get_resources(self): + body_serializers = { + 'application/xml': AccountXMLSerializer(), + } + serializer = wsgi.ResponseSerializer(body_serializers) + + #TODO(bcwaldon): This should be prefixed with 'os-' + res = extensions.ResourceExtension('accounts', + Controller(), + serializer=serializer) + + return [res] -- cgit