diff --git a/api-ref/source/v3/parameters.yaml b/api-ref/source/v3/parameters.yaml index 307e7e2547..c7eb5d6388 100644 --- a/api-ref/source/v3/parameters.yaml +++ b/api-ref/source/v3/parameters.yaml @@ -1132,6 +1132,22 @@ limit_id: in: body required: true type: string +limit_model_description_required_response_body: + description: A short description of the enforcement model used + in: body + required: true + type: string +limit_model_name_required_response_body: + description: The name of the enforcement model + in: body + required: true + type: string +limit_model_required_response_body: + description: A model object describing the configured enforcement model used + by the deployment. + in: body + required: true + type: object limits: description: | A list of ``limits`` objects diff --git a/api-ref/source/v3/samples/admin/limit-flat-model-response.json b/api-ref/source/v3/samples/admin/limit-flat-model-response.json new file mode 100644 index 0000000000..43b01f9b35 --- /dev/null +++ b/api-ref/source/v3/samples/admin/limit-flat-model-response.json @@ -0,0 +1,6 @@ +{ + "model": { + "description": "Limit enforcement and validation does not take project hierarchy into consideration.", + "name": "flat" + } +} diff --git a/api-ref/source/v3/unified_limits.inc b/api-ref/source/v3/unified_limits.inc index 41dc2eb5be..7f5b0a7254 100644 --- a/api-ref/source/v3/unified_limits.inc +++ b/api-ref/source/v3/unified_limits.inc @@ -306,6 +306,46 @@ Status Codes - 404 +Get Enforcement Model +===================== + +.. rest_method:: GET /v3/limits/model + +Return the configured limit enforcement model. + +Relationship: ``https://docs.openstack.org/api/openstack-identity/3/rel/limit_model`` + +Response +-------- + +Parameters +~~~~~~~~~~ + +.. rest_parameters:: parameters.yaml + + - model: limit_model_required_response_body + - name: limit_model_name_required_response_body + - description: limit_model_description_required_response_body + +Status Codes +~~~~~~~~~~~~ + +.. rest_status_code:: success status.yaml + + - 200 + +.. rest_status_code:: error status.yaml + + - 401 + - 403 + +Flat Enforcement Example +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. literalinclude:: ./samples/admin/limit-flat-model-response.json + :language: javascript + + List Limits =========== diff --git a/keystone/limit/controllers.py b/keystone/limit/controllers.py index 84b6e38ac2..440b55f94d 100644 --- a/keystone/limit/controllers.py +++ b/keystone/limit/controllers.py @@ -79,6 +79,11 @@ class LimitV3(controller.V3Controller): super(LimitV3, self).__init__() self.get_member_from_driver = self.unified_limit_api.get_limit + @controller.protected() + def get_limit_model(self, request): + model = PROVIDERS.unified_limit_api.get_model() + return {'model': model} + @controller.protected() def create_limits(self, request, limits): validation.lazy_validate(schema.limit_create, limits) diff --git a/keystone/limit/routers.py b/keystone/limit/routers.py index 6a2f16ff9c..36e62d4014 100644 --- a/keystone/limit/routers.py +++ b/keystone/limit/routers.py @@ -53,6 +53,14 @@ class Routers(wsgi.RoutersBase): rel=json_home.build_v3_resource_relation('limits') ) + self._add_resource( + mapper, controllers.LimitV3(), + path='/limits/model', + get_head_action='get_limit_model', + status=json_home.Status.EXPERIMENTAL, + rel=json_home.build_v3_resource_relation('limit_model') + ) + self._add_resource( mapper, controllers.LimitV3(), path='/limits/{limit_id}', diff --git a/keystone/tests/unit/test_limits.py b/keystone/tests/unit/test_limits.py index 1c8e0a12c7..29ac0611ed 100644 --- a/keystone/tests/unit/test_limits.py +++ b/keystone/tests/unit/test_limits.py @@ -16,12 +16,68 @@ from six.moves import http_client import uuid from keystone.common import provider_api +from keystone.common.validation import validators +import keystone.conf from keystone.tests import unit from keystone.tests.unit import test_v3 +CONF = keystone.conf.CONF PROVIDERS = provider_api.ProviderAPIs +class LimitModelTestCase(test_v3.RestfulTestCase): + + def test_get_default_limit_model_response_schema(self): + schema = { + 'type': 'object', + 'properties': { + 'model': { + 'type': 'object', + 'properties': { + 'name': {'type': 'string'}, + 'description': {'type': 'string'} + }, + 'required': ['name', 'description'], + 'additionalProperties': False, + }, + }, + 'required': ['model'], + 'additionalProperties': False, + } + validator = validators.SchemaValidator(schema) + response = self.get('/limits/model') + validator.validate(response.json_body) + + def test_head_limit_model(self): + self.head('/limits/model', expected_status=http_client.OK) + + def test_get_limit_model_returns_default_model(self): + response = self.get('/limits/model') + model = response.result + expected = { + 'model': { + 'name': 'flat', + 'description': ( + 'Limit enforcement and validation does not take project ' + 'hierarchy into consideration.' + ) + } + } + self.assertDictEqual(expected, model) + + def test_get_limit_model_without_token_fails(self): + self.get( + '/limits/model', noauth=True, + expected_status=http_client.UNAUTHORIZED + ) + + def test_head_limit_model_without_token_fails(self): + self.head( + '/limits/model', noauth=True, + expected_status=http_client.UNAUTHORIZED + ) + + class RegisteredLimitsTestCase(test_v3.RestfulTestCase): """Test registered_limits CRUD.""" diff --git a/keystone/tests/unit/test_versions.py b/keystone/tests/unit/test_versions.py index aec4bdcfe6..29766b9fd9 100644 --- a/keystone/tests/unit/test_versions.py +++ b/keystone/tests/unit/test_versions.py @@ -623,6 +623,10 @@ V3_JSON_HOME_RESOURCES = { }, 'hints': {'status': 'experimental'} }, + json_home.build_v3_resource_relation('limit_model'): { + 'href': '/limits/model', + 'hints': {'status': 'experimental'} + }, json_home.build_v3_resource_relation('application_credential'): { 'href-template': APPLICATION_CREDENTIAL, 'href-vars': { diff --git a/releasenotes/notes/bug-1765193-b40318b9fb5d1c7b.yaml b/releasenotes/notes/bug-1765193-b40318b9fb5d1c7b.yaml new file mode 100644 index 0000000000..a808462170 --- /dev/null +++ b/releasenotes/notes/bug-1765193-b40318b9fb5d1c7b.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + [`bug 1765193 `_] + The unified limit API now exposes a deployment's configured enforcement + model via the ``GET /limits/model`` endpoint.