Allow regular user to get quotas

The project user can query the project's own resource quota.

Story: 2009140
Task: 43082

Change-Id: Iebac740e982a89fcf882a2cfc3e447ac53ee6656
This commit is contained in:
Lingxian Kong 2021-08-25 16:11:12 +12:00
parent c3a8930eb1
commit f3459e2662
6 changed files with 98 additions and 3 deletions

View File

@ -38,7 +38,8 @@ Show resources quota for a specific project
.. rest_method:: GET /v1.0/{project_id}/mgmt/quotas/{user_project}
Admin only action by default.
Admin can query resource quota of any project. The project user can only show
the project's own quota.
Normal response codes: 200

View File

@ -0,0 +1,3 @@
---
features:
- The project user can query the project's own resource quota.

View File

@ -324,6 +324,7 @@ class Controller(object):
exception.ModuleAppliedToInstance,
exception.PolicyNotAuthorized,
exception.LogAccessForbidden,
exception.TroveOperationAuthError,
],
webob.exc.HTTPBadRequest: [
exception.InvalidModelError,

View File

@ -29,12 +29,21 @@ LOG = logging.getLogger(__name__)
class QuotaController(wsgi.Controller):
"""Controller for quota functionality."""
@admin_context
def show(self, req, tenant_id, id):
"""Return all quotas for this tenant."""
"""Return all quotas for this tenant.
Regular tenant can get his own resource quota.
Admin user can get quota for any tenant.
"""
LOG.info("Indexing quota info for tenant '%(id)s'\n"
"req : '%(req)s'\n\n", {"id": id, "req": req})
context = req.environ[wsgi.CONTEXT_KEY]
if id != tenant_id and not context.is_admin:
raise exception.TroveOperationAuthError(
tenant_id=tenant_id
)
usages = quota_engine.get_all_quota_usages_by_tenant(id)
limits = quota_engine.get_all_quotas_by_tenant(id)
for key in usages.keys():

View File

@ -0,0 +1,81 @@
# Copyright 2021 Catalyst Cloud
#
# 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 unittest import mock
from trove.common import exception
from trove.common import wsgi
from trove.extensions.mgmt.quota import service as quota_service
from trove.tests.unittests import trove_testtools
from trove.tests.unittests.util import util
class TestQuotaController(trove_testtools.TestCase):
@classmethod
def setUpClass(cls):
util.init_db()
cls.controller = quota_service.QuotaController()
cls.admin_project_id = cls.random_uuid()
super(TestQuotaController, cls).setUpClass()
@classmethod
def tearDownClass(cls):
util.cleanup_db()
super(TestQuotaController, cls).tearDownClass()
def test_show_admin_query(self):
user_project_id = self.random_uuid()
req_mock = mock.MagicMock(
environ={
wsgi.CONTEXT_KEY: mock.MagicMock(
project_id=self.admin_project_id,
is_admin=True
)
}
)
result = self.controller.show(req_mock, self.admin_project_id,
user_project_id)
self.assertEqual(200, result.status)
def test_show_user_query(self):
"""Show the tenant's own quota."""
user_project_id = self.random_uuid()
req_mock = mock.MagicMock(
environ={
wsgi.CONTEXT_KEY: mock.MagicMock(
is_admin=False
)
}
)
result = self.controller.show(req_mock, user_project_id,
user_project_id)
self.assertEqual(200, result.status)
def test_show_user_query_not_allowed(self):
"""Show other tenant's quota should fail."""
user_project_id = self.random_uuid()
req_mock = mock.MagicMock(
environ={
wsgi.CONTEXT_KEY: mock.MagicMock(
is_admin=False
)
}
)
self.assertRaises(
exception.TroveOperationAuthError,
self.controller.show,
req_mock, user_project_id,
self.random_uuid()
)