Merge "Add Quota Enforcement API"

This commit is contained in:
Jenkins 2015-08-25 21:28:05 +00:00 committed by Gerrit Code Review
commit c40315291c
7 changed files with 77 additions and 3 deletions

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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')

View File

@ -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)

View File

@ -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()