Expose endpoint to return enforcement model
This commit wires up the last couple pieces of code to expose a deployment's enforcement model information via the API. This is going to be consumed by other services to make decisions about quota calculation. Change-Id: I02431d58b50aab2a2da8ca5f90938472aad7a935 Closes-Bug: 1765193
This commit is contained in:
parent
a006db559a
commit
5a52e5aab7
@ -1132,6 +1132,22 @@ limit_id:
|
|||||||
in: body
|
in: body
|
||||||
required: true
|
required: true
|
||||||
type: string
|
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:
|
limits:
|
||||||
description: |
|
description: |
|
||||||
A list of ``limits`` objects
|
A list of ``limits`` objects
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"description": "Limit enforcement and validation does not take project hierarchy into consideration.",
|
||||||
|
"name": "flat"
|
||||||
|
}
|
||||||
|
}
|
@ -306,6 +306,46 @@ Status Codes
|
|||||||
- 404
|
- 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
|
List Limits
|
||||||
===========
|
===========
|
||||||
|
|
||||||
|
@ -79,6 +79,11 @@ class LimitV3(controller.V3Controller):
|
|||||||
super(LimitV3, self).__init__()
|
super(LimitV3, self).__init__()
|
||||||
self.get_member_from_driver = self.unified_limit_api.get_limit
|
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()
|
@controller.protected()
|
||||||
def create_limits(self, request, limits):
|
def create_limits(self, request, limits):
|
||||||
validation.lazy_validate(schema.limit_create, limits)
|
validation.lazy_validate(schema.limit_create, limits)
|
||||||
|
@ -53,6 +53,14 @@ class Routers(wsgi.RoutersBase):
|
|||||||
rel=json_home.build_v3_resource_relation('limits')
|
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(
|
self._add_resource(
|
||||||
mapper, controllers.LimitV3(),
|
mapper, controllers.LimitV3(),
|
||||||
path='/limits/{limit_id}',
|
path='/limits/{limit_id}',
|
||||||
|
@ -16,12 +16,68 @@ from six.moves import http_client
|
|||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from keystone.common import provider_api
|
from keystone.common import provider_api
|
||||||
|
from keystone.common.validation import validators
|
||||||
|
import keystone.conf
|
||||||
from keystone.tests import unit
|
from keystone.tests import unit
|
||||||
from keystone.tests.unit import test_v3
|
from keystone.tests.unit import test_v3
|
||||||
|
|
||||||
|
CONF = keystone.conf.CONF
|
||||||
PROVIDERS = provider_api.ProviderAPIs
|
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):
|
class RegisteredLimitsTestCase(test_v3.RestfulTestCase):
|
||||||
"""Test registered_limits CRUD."""
|
"""Test registered_limits CRUD."""
|
||||||
|
|
||||||
|
@ -623,6 +623,10 @@ V3_JSON_HOME_RESOURCES = {
|
|||||||
},
|
},
|
||||||
'hints': {'status': 'experimental'}
|
'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'): {
|
json_home.build_v3_resource_relation('application_credential'): {
|
||||||
'href-template': APPLICATION_CREDENTIAL,
|
'href-template': APPLICATION_CREDENTIAL,
|
||||||
'href-vars': {
|
'href-vars': {
|
||||||
|
6
releasenotes/notes/bug-1765193-b40318b9fb5d1c7b.yaml
Normal file
6
releasenotes/notes/bug-1765193-b40318b9fb5d1c7b.yaml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
fixes:
|
||||||
|
- |
|
||||||
|
[`bug 1765193 <https://bugs.launchpad.net/keystone/+bug/1765193>`_]
|
||||||
|
The unified limit API now exposes a deployment's configured enforcement
|
||||||
|
model via the ``GET /limits/model`` endpoint.
|
Loading…
Reference in New Issue
Block a user