Merge "Limit description support"

This commit is contained in:
Zuul 2018-05-17 04:44:36 +00:00 committed by Gerrit Code Review
commit a611f4803f
21 changed files with 249 additions and 49 deletions

View File

@ -626,6 +626,18 @@ default_project_id_update_body:
in: body in: body
required: false required: false
type: string type: string
description_limit_request_body:
description: |
The limit description.
in: body
required: false
type: string
description_limit_response_body:
description: |
The limit description.
in: body
required: true
type: string
description_region_request_body: description_region_request_body:
description: | description: |
The region description. The region description.
@ -638,6 +650,18 @@ description_region_response_body:
in: body in: body
required: true required: true
type: string type: string
description_registered_limit_request_body:
description: |
The registered limit description.
in: body
required: false
type: string
description_registered_limit_response_body:
description: |
The registered limit description.
in: body
required: true
type: string
domain: domain:
description: | description: |
A ``domain`` object, containing: A ``domain`` object, containing:

View File

@ -8,6 +8,7 @@
"service_id": "9408080f1970482aa0e38bc2d4ea34b7", "service_id": "9408080f1970482aa0e38bc2d4ea34b7",
"project_id": "3a705b9f56bb439381b43c4fe59dccce", "project_id": "3a705b9f56bb439381b43c4fe59dccce",
"id": "25a04c7a065c430590881c646cdcdd58", "id": "25a04c7a065c430590881c646cdcdd58",
"resource_limit": 11 "resource_limit": 11,
"description": ""
} }
} }

View File

@ -11,7 +11,8 @@
"service_id": "9408080f1970482aa0e38bc2d4ea34b7", "service_id": "9408080f1970482aa0e38bc2d4ea34b7",
"project_id": "3a705b9f56bb439381b43c4fe59dccce", "project_id": "3a705b9f56bb439381b43c4fe59dccce",
"resource_name": "volume", "resource_name": "volume",
"resource_limit": 10 "resource_limit": 10,
"description": "Number of volumes for project 3a705b9f56bb439381b43c4fe59dccce"
} }
] ]
} }

View File

@ -9,7 +9,8 @@
"service_id": "9408080f1970482aa0e38bc2d4ea34b7", "service_id": "9408080f1970482aa0e38bc2d4ea34b7",
"project_id": "3a705b9f56bb439381b43c4fe59dccce", "project_id": "3a705b9f56bb439381b43c4fe59dccce",
"id": "25a04c7a065c430590881c646cdcdd58", "id": "25a04c7a065c430590881c646cdcdd58",
"resource_limit": 10 "resource_limit": 10,
"description": "Number of volumes for project 3a705b9f56bb439381b43c4fe59dccce"
}, },
{ {
"resource_name": "snapshot", "resource_name": "snapshot",
@ -20,7 +21,8 @@
"service_id": "9408080f1970482aa0e38bc2d4ea34b7", "service_id": "9408080f1970482aa0e38bc2d4ea34b7",
"project_id": "3a705b9f56bb439381b43c4fe59dccce", "project_id": "3a705b9f56bb439381b43c4fe59dccce",
"id": "3229b3849f584faea483d6851f7aab05", "id": "3229b3849f584faea483d6851f7aab05",
"resource_limit": 5 "resource_limit": 5,
"description": ""
} }
] ]
} }

View File

@ -14,7 +14,8 @@
"service_id": "9408080f1970482aa0e38bc2d4ea34b7", "service_id": "9408080f1970482aa0e38bc2d4ea34b7",
"project_id": "3a705b9f56bb439381b43c4fe59dccce", "project_id": "3a705b9f56bb439381b43c4fe59dccce",
"id": "25a04c7a065c430590881c646cdcdd58", "id": "25a04c7a065c430590881c646cdcdd58",
"resource_limit": 11 "resource_limit": 11,
"description": "Number of volumes for project 3a705b9f56bb439381b43c4fe59dccce"
}, },
{ {
"resource_name": "snapshot", "resource_name": "snapshot",
@ -25,7 +26,8 @@
"service_id": "9408080f1970482aa0e38bc2d4ea34b7", "service_id": "9408080f1970482aa0e38bc2d4ea34b7",
"project_id": "3a705b9f56bb439381b43c4fe59dccce", "project_id": "3a705b9f56bb439381b43c4fe59dccce",
"id": "3229b3849f584faea483d6851f7aab05", "id": "3229b3849f584faea483d6851f7aab05",
"resource_limit": 5 "resource_limit": 5,
"description": ""
} }
] ]
} }

View File

@ -6,7 +6,8 @@
}, },
{ {
"id": "3229b3849f584faea483d6851f7aab05", "id": "3229b3849f584faea483d6851f7aab05",
"resource_limit": 5 "resource_limit": 5,
"description": "Number of snapshots for project 3a705b9f56bb439381b43c4fe59dccce"
} }
] ]
} }

View File

@ -9,7 +9,8 @@
"service_id": "9408080f1970482aa0e38bc2d4ea34b7", "service_id": "9408080f1970482aa0e38bc2d4ea34b7",
"project_id": "3a705b9f56bb439381b43c4fe59dccce", "project_id": "3a705b9f56bb439381b43c4fe59dccce",
"id": "25a04c7a065c430590881c646cdcdd58", "id": "25a04c7a065c430590881c646cdcdd58",
"resource_limit": 11 "resource_limit": 11,
"description": ""
}, },
{ {
"resource_name": "snapshot", "resource_name": "snapshot",
@ -20,7 +21,8 @@
"service_id": "9408080f1970482aa0e38bc2d4ea34b7", "service_id": "9408080f1970482aa0e38bc2d4ea34b7",
"project_id": "3a705b9f56bb439381b43c4fe59dccce", "project_id": "3a705b9f56bb439381b43c4fe59dccce",
"id": "3229b3849f584faea483d6851f7aab05", "id": "3229b3849f584faea483d6851f7aab05",
"resource_limit": 5 "resource_limit": 5,
"description": "Number of snapshots for project 3a705b9f56bb439381b43c4fe59dccce"
} }
] ]
} }

View File

@ -7,6 +7,7 @@
}, },
"service_id": "9408080f1970482aa0e38bc2d4ea34b7", "service_id": "9408080f1970482aa0e38bc2d4ea34b7",
"default_limit": 10, "default_limit": 10,
"id": "773147dd53cd4a17b921d555cf17c633" "id": "773147dd53cd4a17b921d555cf17c633",
"description": "Number of volumes"
} }
} }

View File

@ -9,7 +9,8 @@
{ {
"service_id": "9408080f1970482aa0e38bc2d4ea34b7", "service_id": "9408080f1970482aa0e38bc2d4ea34b7",
"resource_name": "volume", "resource_name": "volume",
"default_limit": 10 "default_limit": 10,
"description": "Number of volumes"
} }
] ]
} }

View File

@ -8,7 +8,8 @@
}, },
"service_id": "9408080f1970482aa0e38bc2d4ea34b7", "service_id": "9408080f1970482aa0e38bc2d4ea34b7",
"default_limit": 10, "default_limit": 10,
"id": "773147dd53cd4a17b921d555cf17c633" "id": "773147dd53cd4a17b921d555cf17c633",
"description": "Number of volumes"
}, },
{ {
"resource_name": "snapshot", "resource_name": "snapshot",
@ -18,7 +19,8 @@
}, },
"service_id": "9408080f1970482aa0e38bc2d4ea34b7", "service_id": "9408080f1970482aa0e38bc2d4ea34b7",
"default_limit": 5, "default_limit": 5,
"id": "e35a965b2b244209bb0c2b193c55955f" "id": "e35a965b2b244209bb0c2b193c55955f",
"description": ""
} }
] ]
} }

View File

@ -13,7 +13,8 @@
}, },
"service_id": "9408080f1970482aa0e38bc2d4ea34b7", "service_id": "9408080f1970482aa0e38bc2d4ea34b7",
"default_limit": 10, "default_limit": 10,
"id": "195acb8a093e43e9afb23d6628361e7c" "id": "195acb8a093e43e9afb23d6628361e7c",
"description": ""
}, },
{ {
"resource_name": "volume", "resource_name": "volume",
@ -23,7 +24,8 @@
}, },
"service_id": "9408080f1970482aa0e38bc2d4ea34b7", "service_id": "9408080f1970482aa0e38bc2d4ea34b7",
"default_limit": 5, "default_limit": 5,
"id": "ea7f74f15cba4c6db1406fe52532f98d" "id": "ea7f74f15cba4c6db1406fe52532f98d",
"description": "Number of volumes"
} }
] ]
} }

View File

@ -5,13 +5,15 @@
"id": "e35a965b2b244209bb0c2b193c55955f", "id": "e35a965b2b244209bb0c2b193c55955f",
"region_id": "RegionOne", "region_id": "RegionOne",
"resource_name": "snapshot", "resource_name": "snapshot",
"default_limit": 5 "default_limit": 5,
"description": "Number of snapshots"
}, },
{ {
"service_id": "9408080f1970482aa0e38bc2d4ea34b7", "service_id": "9408080f1970482aa0e38bc2d4ea34b7",
"id": "773147dd53cd4a17b921d555cf17c633", "id": "773147dd53cd4a17b921d555cf17c633",
"resource_name": "volume", "resource_name": "volume",
"default_limit": 10 "default_limit": 10,
"description": ""
} }
] ]
} }

View File

@ -8,7 +8,8 @@
}, },
"service_id": "9408080f1970482aa0e38bc2d4ea34b7", "service_id": "9408080f1970482aa0e38bc2d4ea34b7",
"default_limit": 10, "default_limit": 10,
"id": "773147dd53cd4a17b921d555cf17c633" "id": "773147dd53cd4a17b921d555cf17c633",
"description": ""
}, },
{ {
"resource_name": "snapshot", "resource_name": "snapshot",
@ -18,7 +19,8 @@
}, },
"service_id": "9408080f1970482aa0e38bc2d4ea34b7", "service_id": "9408080f1970482aa0e38bc2d4ea34b7",
"default_limit": 5, "default_limit": 5,
"id": "e35a965b2b244209bb0c2b193c55955f" "id": "e35a965b2b244209bb0c2b193c55955f",
"description": "Number of snapshots"
} }
] ]
} }

View File

@ -48,6 +48,7 @@ Parameters
- region_id: region_id_response_body - region_id: region_id_response_body
- resource_name: resource_name - resource_name: resource_name
- default_limit: default_limit - default_limit: default_limit
- description: description_registered_limit_response_body
- links: link_response_body - links: link_response_body
@ -93,6 +94,7 @@ Parameters
- region_id: region_id_request_body - region_id: region_id_request_body
- resource_name: resource_name - resource_name: resource_name
- default_limit: default_limit - default_limit: default_limit
- description: description_registered_limit_request_body
Examples Examples
~~~~~~~~ ~~~~~~~~
@ -116,6 +118,7 @@ Parameters
- region_id: region_id_response_body - region_id: region_id_response_body
- resource_name: resource_name - resource_name: resource_name
- default_limit: default_limit - default_limit: default_limit
- description: description_registered_limit_response_body
- links: link_response_body - links: link_response_body
Status Codes Status Codes
@ -164,6 +167,7 @@ Parameters
- region_id: region_id_request_body - region_id: region_id_request_body
- resource_name: resource_name - resource_name: resource_name
- default_limit: default_limit - default_limit: default_limit
- description: description_registered_limit_request_body
Example Example
~~~~~~~ ~~~~~~~
@ -185,6 +189,7 @@ Parameters
- region_id: region_id_response_body - region_id: region_id_response_body
- resource_name: resource_name - resource_name: resource_name
- default_limit: default_limit - default_limit: default_limit
- description: description_registered_limit_response_body
- links: link_response_body - links: link_response_body
@ -243,6 +248,7 @@ Parameters
- region_id: region_id_response_body - region_id: region_id_response_body
- resource_name: resource_name - resource_name: resource_name
- default_limit: default_limit - default_limit: default_limit
- description: description_registered_limit_response_body
- links: link_response_body - links: link_response_body
Status Codes Status Codes
@ -339,6 +345,7 @@ Parameters
- region_id: region_id_response_body - region_id: region_id_response_body
- resource_name: resource_name - resource_name: resource_name
- resource_limit: resource_limit - resource_limit: resource_limit
- description: description_limit_response_body
- links: link_response_body - links: link_response_body
@ -383,6 +390,7 @@ Parameters
- region_id: region_id_request_body - region_id: region_id_request_body
- resource_name: resource_name - resource_name: resource_name
- resource_limit: resource_limit - resource_limit: resource_limit
- description: description_limit_request_body
Examples Examples
~~~~~~~~ ~~~~~~~~
@ -406,6 +414,7 @@ Parameters
- region_id: region_id_response_body - region_id: region_id_response_body
- resource_name: resource_name - resource_name: resource_name
- resource_limit: resource_limit - resource_limit: resource_limit
- description: description_limit_response_body
- links: link_response_body - links: link_response_body
Status Codes Status Codes
@ -451,6 +460,7 @@ Parameters
- limits: limits - limits: limits
- resource_limit: resource_limit - resource_limit: resource_limit
- description: description_limit_request_body
Example Example
~~~~~~~ ~~~~~~~
@ -472,6 +482,7 @@ Parameters
- region_id: region_id_response_body - region_id: region_id_response_body
- resource_name: resource_name - resource_name: resource_name
- resource_limit: resource_limit - resource_limit: resource_limit
- description: description_limit_response_body
- links: link_response_body - links: link_response_body
@ -531,6 +542,7 @@ Parameters
- region_id: region_id_response_body - region_id: region_id_response_body
- resource_name: resource_name - resource_name: resource_name
- resource_limit: resource_limit - resource_limit: resource_limit
- description: description_limit_response_body
- links: link_response_body - links: link_response_body
Status Codes Status Codes

View File

@ -32,7 +32,8 @@ class RegisteredLimitModel(sql.ModelBase, sql.ModelDictMixin):
'service_id', 'service_id',
'region_id', 'region_id',
'resource_name', 'resource_name',
'default_limit' 'default_limit',
'description'
] ]
id = sql.Column(sql.String(length=64), primary_key=True) id = sql.Column(sql.String(length=64), primary_key=True)
@ -42,6 +43,7 @@ class RegisteredLimitModel(sql.ModelBase, sql.ModelDictMixin):
sql.ForeignKey('region.id'), nullable=True) sql.ForeignKey('region.id'), nullable=True)
resource_name = sql.Column(sql.String(255)) resource_name = sql.Column(sql.String(255))
default_limit = sql.Column(sql.Integer, nullable=False) default_limit = sql.Column(sql.Integer, nullable=False)
description = sql.Column(sql.Text())
__table_args__ = ( __table_args__ = (
sqlalchemy.UniqueConstraint('service_id', sqlalchemy.UniqueConstraint('service_id',
@ -57,7 +59,8 @@ class LimitModel(sql.ModelBase, sql.ModelDictMixin):
'service_id', 'service_id',
'region_id', 'region_id',
'resource_name', 'resource_name',
'resource_limit' 'resource_limit',
'description'
] ]
id = sql.Column(sql.String(length=64), primary_key=True) id = sql.Column(sql.String(length=64), primary_key=True)
@ -67,6 +70,7 @@ class LimitModel(sql.ModelBase, sql.ModelDictMixin):
region_id = sql.Column(sql.String(64), nullable=True) region_id = sql.Column(sql.String(64), nullable=True)
resource_name = sql.Column(sql.String(255)) resource_name = sql.Column(sql.String(255))
resource_limit = sql.Column(sql.Integer, nullable=False) resource_limit = sql.Column(sql.Integer, nullable=False)
description = sql.Column(sql.Text())
__table_args__ = ( __table_args__ = (
sqlalchemy.ForeignKeyConstraint(['service_id', sqlalchemy.ForeignKeyConstraint(['service_id',
@ -227,9 +231,10 @@ class UnifiedLimit(base.UnifiedLimitDriverBase):
for limit in limits: for limit in limits:
ref = self._get_limit(session, limit['id']) ref = self._get_limit(session, limit['id'])
old_dict = ref.to_dict() old_dict = ref.to_dict()
old_dict['resource_limit'] = limit['resource_limit'] old_dict.update(limit)
new_limit = LimitModel.from_dict(old_dict) new_limit = LimitModel.from_dict(old_dict)
ref.resource_limit = new_limit.resource_limit ref.resource_limit = new_limit.resource_limit
ref.description = new_limit.description
@driver_hints.truncated @driver_hints.truncated
def list_limits(self, hints): def list_limits(self, hints):

View File

@ -12,6 +12,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from keystone.common import validation
from keystone.common.validation import parameter_types from keystone.common.validation import parameter_types
_registered_limit_create_properties = { _registered_limit_create_properties = {
@ -24,7 +25,8 @@ _registered_limit_create_properties = {
}, },
'default_limit': { 'default_limit': {
'type': 'integer' 'type': 'integer'
} },
'description': validation.nullable(parameter_types.description)
} }
_registered_limit_create = { _registered_limit_create = {
@ -51,7 +53,8 @@ _registered_limit_update_properties = {
}, },
'default_limit': { 'default_limit': {
'type': 'integer' 'type': 'integer'
} },
'description': validation.nullable(parameter_types.description)
} }
_registered_limit_update = { _registered_limit_update = {
@ -78,7 +81,8 @@ _limit_create_properties = {
}, },
'resource_limit': { 'resource_limit': {
'type': 'integer' 'type': 'integer'
} },
'description': validation.nullable(parameter_types.description)
} }
@ -99,14 +103,15 @@ _limit_update_properties = {
'id': parameter_types.id_string, 'id': parameter_types.id_string,
'resource_limit': { 'resource_limit': {
'type': 'integer' 'type': 'integer'
} },
'description': validation.nullable(parameter_types.description)
} }
_limit_update = { _limit_update = {
'type': 'object', 'type': 'object',
'properties': _limit_update_properties, 'properties': _limit_update_properties,
'additionalProperties': False, 'additionalProperties': False,
'required': ['id', 'resource_limit'] 'required': ['id', ]
} }
limit_update = { limit_update = {

View File

@ -467,7 +467,8 @@ def new_registered_limit_ref(**kwargs):
ref = { ref = {
'service_id': uuid.uuid4().hex, 'service_id': uuid.uuid4().hex,
'resource_name': uuid.uuid4().hex, 'resource_name': uuid.uuid4().hex,
'default_limit': 10 'default_limit': 10,
'description': uuid.uuid4().hex
} }
ref.update(kwargs) ref.update(kwargs)
@ -479,7 +480,8 @@ def new_limit_ref(**kwargs):
'project_id': uuid.uuid4().hex, 'project_id': uuid.uuid4().hex,
'service_id': uuid.uuid4().hex, 'service_id': uuid.uuid4().hex,
'resource_name': uuid.uuid4().hex, 'resource_name': uuid.uuid4().hex,
'resource_limit': 10 'resource_limit': 10,
'description': uuid.uuid4().hex
} }
ref.update(kwargs) ref.update(kwargs)

View File

@ -28,7 +28,8 @@ class RegisteredLimitTests(object):
registered_limit_1 = unit.new_registered_limit_ref( registered_limit_1 = unit.new_registered_limit_ref(
service_id=self.service_one['id'], service_id=self.service_one['id'],
region_id=self.region_one['id'], region_id=self.region_one['id'],
resource_name='volume', default_limit=10, id=uuid.uuid4().hex) resource_name='volume', default_limit=10, id=uuid.uuid4().hex,
description='test description')
reg_limits = PROVIDERS.unified_limit_api.create_registered_limits( reg_limits = PROVIDERS.unified_limit_api.create_registered_limits(
[registered_limit_1]) [registered_limit_1])
self.assertDictEqual(registered_limit_1, reg_limits[0]) self.assertDictEqual(registered_limit_1, reg_limits[0])
@ -111,6 +112,26 @@ class RegisteredLimitTests(object):
PROVIDERS.unified_limit_api.create_registered_limits, PROVIDERS.unified_limit_api.create_registered_limits,
[registered_limit_1]) [registered_limit_1])
def test_create_registered_limit_description_none(self):
registered_limit = unit.new_registered_limit_ref(
service_id=self.service_one['id'],
region_id=self.region_one['id'],
resource_name='volume', default_limit=10, id=uuid.uuid4().hex,
description=None)
res = PROVIDERS.unified_limit_api.create_registered_limits(
[registered_limit])
self.assertIsNone(res[0]['description'])
def test_create_registered_limit_without_description(self):
registered_limit = unit.new_registered_limit_ref(
service_id=self.service_one['id'],
region_id=self.region_one['id'],
resource_name='volume', default_limit=10, id=uuid.uuid4().hex)
registered_limit.pop('description')
res = PROVIDERS.unified_limit_api.create_registered_limits(
[registered_limit])
self.assertIsNone(res[0]['description'])
def test_update_registered_limit(self): def test_update_registered_limit(self):
# create two registered limits # create two registered limits
registered_limit_1 = unit.new_registered_limit_ref( registered_limit_1 = unit.new_registered_limit_ref(
@ -380,7 +401,8 @@ class LimitTests(object):
project_id=self.tenant_bar['id'], project_id=self.tenant_bar['id'],
service_id=self.service_one['id'], service_id=self.service_one['id'],
region_id=self.region_one['id'], region_id=self.region_one['id'],
resource_name='volume', resource_limit=10, id=uuid.uuid4().hex) resource_name='volume', resource_limit=10, id=uuid.uuid4().hex,
description='test description')
limits = PROVIDERS.unified_limit_api.create_limits([limit_1]) limits = PROVIDERS.unified_limit_api.create_limits([limit_1])
self.assertDictEqual(limit_1, limits[0]) self.assertDictEqual(limit_1, limits[0])
@ -452,6 +474,26 @@ class LimitTests(object):
PROVIDERS.unified_limit_api.create_limits, PROVIDERS.unified_limit_api.create_limits,
[limit_1]) [limit_1])
def test_create_limit_description_none(self):
limit = unit.new_limit_ref(
project_id=self.tenant_bar['id'],
service_id=self.service_one['id'],
region_id=self.region_one['id'],
resource_name='volume', resource_limit=10, id=uuid.uuid4().hex,
description=None)
res = PROVIDERS.unified_limit_api.create_limits([limit])
self.assertIsNone(res[0]['description'])
def test_create_limit_without_description(self):
limit = unit.new_limit_ref(
project_id=self.tenant_bar['id'],
service_id=self.service_one['id'],
region_id=self.region_one['id'],
resource_name='volume', resource_limit=10, id=uuid.uuid4().hex)
limit.pop('description')
res = PROVIDERS.unified_limit_api.create_limits([limit])
self.assertIsNone(res[0]['description'])
def test_update_limits(self): def test_update_limits(self):
# create two limits # create two limits
limit_1 = unit.new_limit_ref( limit_1 = unit.new_limit_ref(

View File

@ -53,7 +53,7 @@ class RegisteredLimitsTestCase(test_v3.RestfulTestCase):
expected_status=http_client.CREATED) expected_status=http_client.CREATED)
registered_limits = r.result['registered_limits'] registered_limits = r.result['registered_limits']
for key in ['service_id', 'region_id', 'resource_name', for key in ['service_id', 'region_id', 'resource_name',
'default_limit']: 'default_limit', 'description']:
self.assertEqual(registered_limits[0][key], ref[key]) self.assertEqual(registered_limits[0][key], ref[key])
def test_create_registered_limit_without_region(self): def test_create_registered_limit_without_region(self):
@ -67,6 +67,20 @@ class RegisteredLimitsTestCase(test_v3.RestfulTestCase):
self.assertEqual(registered_limits[0][key], ref[key]) self.assertEqual(registered_limits[0][key], ref[key])
self.assertIsNone(registered_limits[0].get('region_id')) self.assertIsNone(registered_limits[0].get('region_id'))
def test_create_registered_without_description(self):
ref = unit.new_registered_limit_ref(service_id=self.service_id,
region_id=self.region_id)
ref.pop('description')
r = self.post(
'/registered_limits',
body={'registered_limits': [ref]},
expected_status=http_client.CREATED)
registered_limits = r.result['registered_limits']
for key in ['service_id', 'region_id', 'resource_name',
'default_limit']:
self.assertEqual(registered_limits[0][key], ref[key])
self.assertIsNone(registered_limits[0]['description'])
def test_create_multi_registered_limit(self): def test_create_multi_registered_limit(self):
ref1 = unit.new_registered_limit_ref(service_id=self.service_id, ref1 = unit.new_registered_limit_ref(service_id=self.service_id,
region_id=self.region_id, region_id=self.region_id,
@ -141,7 +155,8 @@ class RegisteredLimitsTestCase(test_v3.RestfulTestCase):
'service_id': self.service_id2, 'service_id': self.service_id2,
'region_id': self.region_id2, 'region_id': self.region_id2,
'resource_name': 'snapshot', 'resource_name': 'snapshot',
'default_limit': 5 'default_limit': 5,
'description': 'test description'
} }
r = self.put( r = self.put(
'/registered_limits', '/registered_limits',
@ -153,6 +168,37 @@ class RegisteredLimitsTestCase(test_v3.RestfulTestCase):
self.assertEqual(new_registered_limits['region_id'], self.region_id2) self.assertEqual(new_registered_limits['region_id'], self.region_id2)
self.assertEqual(new_registered_limits['resource_name'], 'snapshot') self.assertEqual(new_registered_limits['resource_name'], 'snapshot')
self.assertEqual(new_registered_limits['default_limit'], 5) self.assertEqual(new_registered_limits['default_limit'], 5)
self.assertEqual(new_registered_limits['description'],
'test description')
def test_update_registered_limit_description(self):
ref = unit.new_registered_limit_ref(service_id=self.service_id,
region_id=self.region_id,
resource_name='volume',
default_limit=10)
r = self.post(
'/registered_limits',
body={'registered_limits': [ref]},
expected_status=http_client.CREATED)
update_ref = {
'id': r.result['registered_limits'][0]['id'],
'description': 'test description'
}
r = self.put(
'/registered_limits',
body={'registered_limits': [update_ref]},
expected_status=http_client.OK)
new_registered_limits = r.result['registered_limits'][0]
self.assertEqual(new_registered_limits['description'],
'test description')
update_ref['description'] = ''
r = self.put(
'/registered_limits',
body={'registered_limits': [update_ref]},
expected_status=http_client.OK)
new_registered_limits = r.result['registered_limits'][0]
self.assertEqual(new_registered_limits['description'], '')
def test_update_multi_registered_limit(self): def test_update_multi_registered_limit(self):
ref = unit.new_registered_limit_ref(service_id=self.service_id, ref = unit.new_registered_limit_ref(service_id=self.service_id,
@ -213,8 +259,10 @@ class RegisteredLimitsTestCase(test_v3.RestfulTestCase):
resource_name=123) resource_name=123)
update_ref4 = unit.new_registered_limit_ref(id=uuid.uuid4().hex, update_ref4 = unit.new_registered_limit_ref(id=uuid.uuid4().hex,
region_id='fake_region') region_id='fake_region')
update_ref5 = unit.new_registered_limit_ref(id=uuid.uuid4().hex,
description=123)
for input_limit in [update_ref1, update_ref2, update_ref3, for input_limit in [update_ref1, update_ref2, update_ref3,
update_ref4]: update_ref4, update_ref5]:
self.put( self.put(
'/registered_limits', '/registered_limits',
body={'registered_limits': [input_limit]}, body={'registered_limits': [input_limit]},
@ -325,7 +373,7 @@ class RegisteredLimitsTestCase(test_v3.RestfulTestCase):
expected_status=http_client.OK) expected_status=http_client.OK)
registered_limit = r.result['registered_limit'] registered_limit = r.result['registered_limit']
for key in ['service_id', 'region_id', 'resource_name', for key in ['service_id', 'region_id', 'resource_name',
'default_limit']: 'default_limit', 'description']:
self.assertEqual(registered_limit[key], ref1[key]) self.assertEqual(registered_limit[key], ref1[key])
def test_delete_registered_limit(self): def test_delete_registered_limit(self):
@ -420,7 +468,7 @@ class LimitsTestCase(test_v3.RestfulTestCase):
self. assertIsNotNone(limits[0]['id']) self. assertIsNotNone(limits[0]['id'])
self. assertIsNotNone(limits[0]['project_id']) self. assertIsNotNone(limits[0]['project_id'])
for key in ['service_id', 'region_id', 'resource_name', for key in ['service_id', 'region_id', 'resource_name',
'resource_limit']: 'resource_limit', 'description']:
self.assertEqual(limits[0][key], ref[key]) self.assertEqual(limits[0][key], ref[key])
def test_create_limit_without_region(self): def test_create_limit_without_region(self):
@ -439,6 +487,25 @@ class LimitsTestCase(test_v3.RestfulTestCase):
self.assertEqual(limits[0][key], ref[key]) self.assertEqual(limits[0][key], ref[key])
self.assertIsNone(limits[0].get('region_id')) self.assertIsNone(limits[0].get('region_id'))
def test_create_limit_without_description(self):
ref = unit.new_limit_ref(project_id=self.project_id,
service_id=self.service_id,
region_id=self.region_id,
resource_name='volume')
ref.pop('description')
r = self.post(
'/limits',
body={'limits': [ref]},
expected_status=http_client.CREATED)
limits = r.result['limits']
self. assertIsNotNone(limits[0]['id'])
self. assertIsNotNone(limits[0]['project_id'])
for key in ['service_id', 'region_id', 'resource_name',
'resource_limit']:
self.assertEqual(limits[0][key], ref[key])
self.assertIsNone(limits[0]['description'])
def test_create_multi_limit(self): def test_create_multi_limit(self):
ref1 = unit.new_limit_ref(project_id=self.project_id, ref1 = unit.new_limit_ref(project_id=self.project_id,
service_id=self.service_id, service_id=self.service_id,
@ -535,7 +602,8 @@ class LimitsTestCase(test_v3.RestfulTestCase):
expected_status=http_client.CREATED) expected_status=http_client.CREATED)
update_ref = { update_ref = {
'id': r.result['limits'][0]['id'], 'id': r.result['limits'][0]['id'],
'resource_limit': 5 'resource_limit': 5,
'description': 'test description'
} }
r = self.put( r = self.put(
'/limits', '/limits',
@ -544,6 +612,7 @@ class LimitsTestCase(test_v3.RestfulTestCase):
new_limits = r.result['limits'][0] new_limits = r.result['limits'][0]
self.assertEqual(new_limits['resource_limit'], 5) self.assertEqual(new_limits['resource_limit'], 5)
self.assertEqual(new_limits['description'], 'test description')
def test_update_multi_limit(self): def test_update_multi_limit(self):
ref = unit.new_limit_ref(project_id=self.project_id, ref = unit.new_limit_ref(project_id=self.project_id,
@ -687,7 +756,7 @@ class LimitsTestCase(test_v3.RestfulTestCase):
expected_status=http_client.OK) expected_status=http_client.OK)
limit = r.result['limit'] limit = r.result['limit']
for key in ['service_id', 'region_id', 'resource_name', for key in ['service_id', 'region_id', 'resource_name',
'resource_limit']: 'resource_limit', 'description']:
self.assertEqual(limit[key], ref1[key]) self.assertEqual(limit[key], ref1[key])
def test_delete_limit(self): def test_delete_limit(self):

View File

@ -2519,16 +2519,17 @@ class LimitValidationTestCase(unit.BaseTestCase):
request_to_validate = [{'service_id': uuid.uuid4().hex, request_to_validate = [{'service_id': uuid.uuid4().hex,
'region_id': 'RegionOne', 'region_id': 'RegionOne',
'resource_name': 'volume', 'resource_name': 'volume',
'default_limit': 10}] 'default_limit': 10,
'description': 'test description'}]
self.create_registered_limits_validator.validate(request_to_validate) self.create_registered_limits_validator.validate(request_to_validate)
def test_validate_registered_limit_create_request_without_region(self): def test_validate_registered_limit_create_request_without_optional(self):
request_to_validate = [{'service_id': uuid.uuid4().hex, request_to_validate = [{'service_id': uuid.uuid4().hex,
'resource_name': 'volume', 'resource_name': 'volume',
'default_limit': 10}] 'default_limit': 10}]
self.create_registered_limits_validator.validate(request_to_validate) self.create_registered_limits_validator.validate(request_to_validate)
def test_validate_registered_limit_update_request_without_region(self): def test_validate_registered_limit_update_request_without_optional(self):
request_to_validate = [{'id': uuid.uuid4().hex, request_to_validate = [{'id': uuid.uuid4().hex,
'service_id': uuid.uuid4().hex, 'service_id': uuid.uuid4().hex,
'resource_name': 'volume', 'resource_name': 'volume',
@ -2549,12 +2550,15 @@ class LimitValidationTestCase(unit.BaseTestCase):
_INVALID_FORMATS = [{'service_id': 'fake_id'}, _INVALID_FORMATS = [{'service_id': 'fake_id'},
{'region_id': 123}, {'region_id': 123},
{'resource_name': 123}, {'resource_name': 123},
{'default_limit': 'not_int'}] {'default_limit': 'not_int'},
{'description': 123},
{'description': True}]
for invalid_desc in _INVALID_FORMATS: for invalid_desc in _INVALID_FORMATS:
request_to_validate = [{'service_id': uuid.uuid4().hex, request_to_validate = [{'service_id': uuid.uuid4().hex,
'region_id': 'RegionOne', 'region_id': 'RegionOne',
'resource_name': 'volume', 'resource_name': 'volume',
'default_limit': 10}] 'default_limit': 10,
'description': 'test description'}]
request_to_validate[0].update(invalid_desc) request_to_validate[0].update(invalid_desc)
self.assertRaises(exception.SchemaValidationError, self.assertRaises(exception.SchemaValidationError,
@ -2565,13 +2569,15 @@ class LimitValidationTestCase(unit.BaseTestCase):
_INVALID_FORMATS = [{'service_id': 'fake_id'}, _INVALID_FORMATS = [{'service_id': 'fake_id'},
{'region_id': 123}, {'region_id': 123},
{'resource_name': 123}, {'resource_name': 123},
{'default_limit': 'not_int'}] {'default_limit': 'not_int'},
{'description': 123}]
for invalid_desc in _INVALID_FORMATS: for invalid_desc in _INVALID_FORMATS:
request_to_validate = [{'id': uuid.uuid4().hex, request_to_validate = [{'id': uuid.uuid4().hex,
'service_id': uuid.uuid4().hex, 'service_id': uuid.uuid4().hex,
'region_id': 'RegionOne', 'region_id': 'RegionOne',
'resource_name': 'volume', 'resource_name': 'volume',
'default_limit': 10}] 'default_limit': 10,
'description': 'test description'}]
request_to_validate[0].update(invalid_desc) request_to_validate[0].update(invalid_desc)
self.assertRaises(exception.SchemaValidationError, self.assertRaises(exception.SchemaValidationError,
@ -2624,10 +2630,11 @@ class LimitValidationTestCase(unit.BaseTestCase):
'service_id': uuid.uuid4().hex, 'service_id': uuid.uuid4().hex,
'region_id': 'RegionOne', 'region_id': 'RegionOne',
'resource_name': 'volume', 'resource_name': 'volume',
'resource_limit': 10}] 'resource_limit': 10,
'description': 'test description'}]
self.create_limits_validator.validate(request_to_validate) self.create_limits_validator.validate(request_to_validate)
def test_validate_limit_create_request_without_region(self): def test_validate_limit_create_request_without_optional(self):
request_to_validate = [{'project_id': uuid.uuid4().hex, request_to_validate = [{'project_id': uuid.uuid4().hex,
'service_id': uuid.uuid4().hex, 'service_id': uuid.uuid4().hex,
'resource_name': 'volume', 'resource_name': 'volume',
@ -2635,6 +2642,12 @@ class LimitValidationTestCase(unit.BaseTestCase):
self.create_limits_validator.validate(request_to_validate) self.create_limits_validator.validate(request_to_validate)
def test_validate_limit_update_request_succeeds(self): def test_validate_limit_update_request_succeeds(self):
request_to_validate = [{'id': uuid.uuid4().hex,
'resource_limit': 10,
'description': 'test description'}]
self.update_limits_validator.validate(request_to_validate)
def test_validate_limit_update_request_without_optional(self):
request_to_validate = [{'id': uuid.uuid4().hex, request_to_validate = [{'id': uuid.uuid4().hex,
'resource_limit': 10}] 'resource_limit': 10}]
self.update_limits_validator.validate(request_to_validate) self.update_limits_validator.validate(request_to_validate)
@ -2654,13 +2667,15 @@ class LimitValidationTestCase(unit.BaseTestCase):
{'service_id': 'fake_id'}, {'service_id': 'fake_id'},
{'region_id': 123}, {'region_id': 123},
{'resource_name': 123}, {'resource_name': 123},
{'resource_limit': 'not_int'}] {'resource_limit': 'not_int'},
{'description': 123}]
for invalid_desc in _INVALID_FORMATS: for invalid_desc in _INVALID_FORMATS:
request_to_validate = [{'project_id': uuid.uuid4().hex, request_to_validate = [{'project_id': uuid.uuid4().hex,
'service_id': uuid.uuid4().hex, 'service_id': uuid.uuid4().hex,
'region_id': 'RegionOne', 'region_id': 'RegionOne',
'resource_name': 'volume', 'resource_name': 'volume',
'resource_limit': 10}] 'resource_limit': 10,
'description': 'test description'}]
request_to_validate[0].update(invalid_desc) request_to_validate[0].update(invalid_desc)
self.assertRaises(exception.SchemaValidationError, self.assertRaises(exception.SchemaValidationError,

View File

@ -0,0 +1,7 @@
---
features:
- >
[`bug 1754185 <https://bugs.launchpad.net/keystone/+bug/1754185>`_]
Registered limits and project limits now support an optional, nullable
property called `description`. Users can create/update a registered limit
or project limit with `description` now.