Merge "Add Quota Enforcement API"
This commit is contained in:
commit
c40315291c
@ -16,6 +16,7 @@ from barbican import api
|
||||
from barbican.api import controllers
|
||||
from barbican.common import exception
|
||||
from barbican.common import hrefs
|
||||
from barbican.common import quota
|
||||
from barbican.common import resources as res
|
||||
from barbican.common import utils
|
||||
from barbican.common import validators
|
||||
@ -73,6 +74,7 @@ class ContainerConsumersController(controllers.ACLMixin):
|
||||
self.consumer_repo = repo.get_container_consumer_repository()
|
||||
self.container_repo = repo.get_container_repository()
|
||||
self.validator = validators.ContainerConsumerValidator()
|
||||
self.quota_enforcer = quota.QuotaEnforcer('consumers')
|
||||
|
||||
@pecan.expose()
|
||||
def _lookup(self, consumer_id, *remainder):
|
||||
@ -139,6 +141,8 @@ class ContainerConsumersController(controllers.ACLMixin):
|
||||
except exception.NotFound:
|
||||
controllers.containers.container_not_found()
|
||||
|
||||
self.quota_enforcer.enforce(project)
|
||||
|
||||
new_consumer = models.ContainerConsumerMetadatum(self.container_id,
|
||||
data)
|
||||
new_consumer.project_id = project.id
|
||||
|
@ -18,6 +18,7 @@ from barbican.api.controllers import acls
|
||||
from barbican.api.controllers import consumers
|
||||
from barbican.common import exception
|
||||
from barbican.common import hrefs
|
||||
from barbican.common import quota
|
||||
from barbican.common import resources as res
|
||||
from barbican.common import utils
|
||||
from barbican.common import validators
|
||||
@ -111,6 +112,7 @@ class ContainersController(controllers.ACLMixin):
|
||||
self.container_repo = repo.get_container_repository()
|
||||
self.secret_repo = repo.get_secret_repository()
|
||||
self.validator = validators.ContainerValidator()
|
||||
self.quota_enforcer = quota.QuotaEnforcer('containers')
|
||||
|
||||
@pecan.expose()
|
||||
def _lookup(self, container_id, *remainder):
|
||||
@ -178,6 +180,8 @@ class ContainersController(controllers.ACLMixin):
|
||||
if ctxt: # in authenticated pipleline case, always use auth token user
|
||||
data['creator_id'] = ctxt.user
|
||||
|
||||
self.quota_enforcer.enforce(project)
|
||||
|
||||
LOG.debug('Start on_post...%s', data)
|
||||
|
||||
new_container = models.Container(data)
|
||||
|
@ -15,6 +15,7 @@ import pecan
|
||||
from barbican import api
|
||||
from barbican.api import controllers
|
||||
from barbican.common import hrefs
|
||||
from barbican.common import quota
|
||||
from barbican.common import resources as res
|
||||
from barbican.common import utils
|
||||
from barbican.common import validators
|
||||
@ -127,6 +128,7 @@ class OrdersController(controllers.ACLMixin):
|
||||
self.order_repo = repo.get_order_repository()
|
||||
self.queue = queue_resource or async_client.TaskClient()
|
||||
self.type_order_validator = validators.TypeOrderValidator()
|
||||
self.quota_enforcer = quota.QuotaEnforcer('orders')
|
||||
|
||||
@pecan.expose()
|
||||
def _lookup(self, order_id, *remainder):
|
||||
@ -209,6 +211,8 @@ class OrdersController(controllers.ACLMixin):
|
||||
external_project_id,
|
||||
container_ref, pecan.request)
|
||||
|
||||
self.quota_enforcer.enforce(project)
|
||||
|
||||
new_order = models.Order()
|
||||
new_order.meta = body.get('meta')
|
||||
new_order.type = order_type
|
||||
|
@ -19,6 +19,7 @@ from barbican.api import controllers
|
||||
from barbican.api.controllers import acls
|
||||
from barbican.common import exception
|
||||
from barbican.common import hrefs
|
||||
from barbican.common import quota
|
||||
from barbican.common import resources as res
|
||||
from barbican.common import utils
|
||||
from barbican.common import validators
|
||||
@ -227,6 +228,7 @@ class SecretsController(controllers.ACLMixin):
|
||||
LOG.debug('Creating SecretsController')
|
||||
self.validator = validators.NewSecretValidator()
|
||||
self.secret_repo = repo.get_secret_repository()
|
||||
self.quota_enforcer = quota.QuotaEnforcer('secrets')
|
||||
|
||||
@pecan.expose()
|
||||
def _lookup(self, secret_id, *remainder):
|
||||
@ -310,6 +312,8 @@ class SecretsController(controllers.ACLMixin):
|
||||
data = api.load_body(pecan.request, validator=self.validator)
|
||||
project = res.get_or_create_project(external_project_id)
|
||||
|
||||
self.quota_enforcer.enforce(project)
|
||||
|
||||
transport_key_needed = data.get('transport_key_needed',
|
||||
'false').lower() == 'true'
|
||||
ctxt = controllers._get_barbican_context(pecan.request)
|
||||
|
@ -438,3 +438,17 @@ class CANotDefinedForProject(BarbicanHTTPException):
|
||||
client_message = u._("The ca_id provided in the request is not defined "
|
||||
"for this project")
|
||||
status_code = 403
|
||||
|
||||
|
||||
class QuotaReached(BarbicanHTTPException):
|
||||
message = u._("Quota reached for project %(project_id)s. Only "
|
||||
"%(count)s %(resource_type)s are allowed.")
|
||||
client_message = u._("Creation not allowed because a quota has "
|
||||
"been reached")
|
||||
status_code = 403
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(QuotaReached, self).__init__(*args, **kwargs)
|
||||
self.project_id = kwargs.get('project_id')
|
||||
self.count = kwargs.get('count')
|
||||
self.resource_type = kwargs.get('resource_type')
|
||||
|
@ -13,7 +13,6 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
|
||||
@ -184,3 +183,17 @@ class QuotaDriver(object):
|
||||
self._extract_project_quotas(retrieved_project_quotas))
|
||||
resp = {'quotas': resp_quotas}
|
||||
return resp
|
||||
|
||||
|
||||
class QuotaEnforcer(object):
|
||||
"""Checks quotas limits and current resource usage levels"""
|
||||
def __init__(self, resource_type):
|
||||
self.resource_type = resource_type
|
||||
|
||||
def enforce(self, project):
|
||||
"""This is a dummy implementation for developing the API"""
|
||||
# TODO(dave) implement
|
||||
if project.id is None: # dummy logic, dummy code
|
||||
raise exception.QuotaReached(project_id=project.external_id,
|
||||
resource_type=self.resource_type,
|
||||
count=0)
|
||||
|
@ -15,9 +15,11 @@
|
||||
|
||||
import unittest
|
||||
|
||||
from barbican.common import exception
|
||||
from barbican.common import exception as excep
|
||||
from barbican.common import quota
|
||||
from barbican.model import models
|
||||
from barbican.tests import database_utils
|
||||
from barbican.tests import utils
|
||||
|
||||
|
||||
class WhenTestingQuotaDriverFunctions(database_utils.RepositoryTestCase):
|
||||
@ -98,7 +100,7 @@ class WhenTestingQuotaDriverFunctions(database_utils.RepositoryTestCase):
|
||||
|
||||
def test_should_raise_not_found_delete_project_quotas(self):
|
||||
self.assertRaises(
|
||||
exception.NotFound,
|
||||
excep.NotFound,
|
||||
self.quota_driver.delete_project_quotas,
|
||||
'dummy')
|
||||
|
||||
@ -192,5 +194,34 @@ class WhenTestingQuotaDriverFunctions(database_utils.RepositoryTestCase):
|
||||
for index in [1, 2, 3]:
|
||||
self.create_a_test_project_quotas(index)
|
||||
|
||||
|
||||
class WhenTestingQuotaEnforcingFunctions(utils.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(WhenTestingQuotaEnforcingFunctions, self).setUp()
|
||||
self.project = models.Project()
|
||||
self.project.id = 'my_internal_id'
|
||||
self.project.external_id = 'my_keystone_id'
|
||||
|
||||
def test_should_pass(self):
|
||||
quota_enforcer = quota.QuotaEnforcer('my_resource')
|
||||
quota_enforcer.enforce(self.project)
|
||||
|
||||
def test_should_raise(self):
|
||||
"""This is a dummy implementation for developing the API"""
|
||||
# TODO(dave) implement
|
||||
quota_enforcer = quota.QuotaEnforcer('my_resource')
|
||||
self.project.id = None
|
||||
exception = self.assertRaises(
|
||||
excep.QuotaReached,
|
||||
quota_enforcer.enforce,
|
||||
self.project
|
||||
)
|
||||
self.assertIn('Quota reached for project', exception.message)
|
||||
self.assertIn('my_keystone_id', exception.message)
|
||||
self.assertIn('my_resource', exception.message)
|
||||
self.assertIn(str(0), exception.message)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
Loading…
Reference in New Issue
Block a user