[placement] Idempotent PUT /resource_classes/{name}
In a microversion 1.7 change PUT /resource_classes/{name} so that creation and existence validation of a custom resource class can happen in a single request and prevent the previous behavior of being able to update a single resource class to a new name, which is not desirable. The previous update_resource_class is still in place to support microversion 1.2-1.6. The original resource-classs.yaml sets the default microversion header to 'latest' so for those existing tests that are using the old style of PUT, a '1.6' header has been added. New files for version 1.6 (to add a "no 1.7 behavior here" test) and 1.7 (testing the new PUT behavior and explicitly verifying POST to create is still around) are added. Change-Id: I95f62ab2cb1ab76d18fb52b93f87ed28e4e7b5f3 Implements: bp placement-put-resource-class
This commit is contained in:
parent
36aa8b3782
commit
d6658d268d
@ -164,7 +164,7 @@ def list_resource_classes(req):
|
|||||||
|
|
||||||
|
|
||||||
@wsgi_wrapper.PlacementWsgify
|
@wsgi_wrapper.PlacementWsgify
|
||||||
@microversion.version_handler('1.2')
|
@microversion.version_handler('1.2', '1.6')
|
||||||
@util.require_content('application/json')
|
@util.require_content('application/json')
|
||||||
def update_resource_class(req):
|
def update_resource_class(req):
|
||||||
"""PUT to update a single resource class.
|
"""PUT to update a single resource class.
|
||||||
@ -199,3 +199,38 @@ def update_resource_class(req):
|
|||||||
req.response.status = 200
|
req.response.status = 200
|
||||||
req.response.content_type = 'application/json'
|
req.response.content_type = 'application/json'
|
||||||
return req.response
|
return req.response
|
||||||
|
|
||||||
|
|
||||||
|
@wsgi_wrapper.PlacementWsgify # noqa
|
||||||
|
@microversion.version_handler('1.7')
|
||||||
|
def update_resource_class(req):
|
||||||
|
"""PUT to create or validate the existence of single resource class.
|
||||||
|
|
||||||
|
On a successful create return 201. Return 204 if the class already
|
||||||
|
exists. If the resource class is not a custom resource class, return
|
||||||
|
a 400. 409 might be a better choice, but 400 aligns with previous code.
|
||||||
|
"""
|
||||||
|
name = util.wsgi_path_item(req.environ, 'name')
|
||||||
|
context = req.environ['placement.context']
|
||||||
|
|
||||||
|
# Use JSON validation to validation resource class name.
|
||||||
|
util.extract_json('{"name": "%s"}' % name, PUT_RC_SCHEMA_V1_2)
|
||||||
|
|
||||||
|
status = 204
|
||||||
|
try:
|
||||||
|
rc = objects.ResourceClass.get_by_name(context, name)
|
||||||
|
except exception.NotFound:
|
||||||
|
try:
|
||||||
|
rc = objects.ResourceClass(context, name=name)
|
||||||
|
rc.create()
|
||||||
|
status = 201
|
||||||
|
# We will not see ResourceClassCannotUpdateStandard because
|
||||||
|
# that was already caught when validating the {name}.
|
||||||
|
except exception.ResourceClassExists:
|
||||||
|
# Someone just now created the class, so stick with 204
|
||||||
|
pass
|
||||||
|
|
||||||
|
req.response.status = status
|
||||||
|
req.response.content_type = None
|
||||||
|
req.response.location = util.resource_class_url(req.environ, rc)
|
||||||
|
return req.response
|
||||||
|
@ -43,6 +43,7 @@ VERSIONS = [
|
|||||||
'1.5', # Adds DELETE /resource_providers/{uuid}/inventories
|
'1.5', # Adds DELETE /resource_providers/{uuid}/inventories
|
||||||
'1.6', # Adds /traits and /resource_providers{uuid}/traits resource
|
'1.6', # Adds /traits and /resource_providers{uuid}/traits resource
|
||||||
# endpoints
|
# endpoints
|
||||||
|
'1.7', # PUT /resource_classes/{name} is bodiless create or update
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -113,3 +113,13 @@ The following new routes are added:
|
|||||||
Custom traits must begin with the prefix "CUSTOM\_" and contain only
|
Custom traits must begin with the prefix "CUSTOM\_" and contain only
|
||||||
the letters A through Z, the numbers 0 through 9 and the underscore "\_"
|
the letters A through Z, the numbers 0 through 9 and the underscore "\_"
|
||||||
character.
|
character.
|
||||||
|
|
||||||
|
1.7 Idempotent PUT /resource_classes/{name}
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
The 1.7 version changes handling of `PUT /resource_classes/{name}` to be a
|
||||||
|
create or verification of the resource class with `{name}`. If the resource
|
||||||
|
class is a custom resource class and does not already exist it will be created
|
||||||
|
and a ``201`` response code returned. If the class already exists the response
|
||||||
|
code will be ``204``. This makes it possible to check or create a resource
|
||||||
|
class in one request.
|
||||||
|
@ -39,13 +39,13 @@ tests:
|
|||||||
response_json_paths:
|
response_json_paths:
|
||||||
$.errors[0].title: Not Acceptable
|
$.errors[0].title: Not Acceptable
|
||||||
|
|
||||||
- name: latest microversion is 1.6
|
- name: latest microversion is 1.7
|
||||||
GET: /
|
GET: /
|
||||||
request_headers:
|
request_headers:
|
||||||
openstack-api-version: placement latest
|
openstack-api-version: placement latest
|
||||||
response_headers:
|
response_headers:
|
||||||
vary: /OpenStack-API-Version/
|
vary: /OpenStack-API-Version/
|
||||||
openstack-api-version: placement 1.6
|
openstack-api-version: placement 1.7
|
||||||
|
|
||||||
- name: other accept header bad version
|
- name: other accept header bad version
|
||||||
GET: /
|
GET: /
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
# Confirm that 1.7 behavior of PUT resource classes is not in
|
||||||
|
# microversion 1.6.
|
||||||
|
fixtures:
|
||||||
|
- APIFixture
|
||||||
|
|
||||||
|
defaults:
|
||||||
|
request_headers:
|
||||||
|
x-auth-token: admin
|
||||||
|
accept: application/json
|
||||||
|
content-type: application/json
|
||||||
|
OpenStack-API-Version: placement 1.6
|
||||||
|
|
||||||
|
tests:
|
||||||
|
|
||||||
|
- name: bodiless put
|
||||||
|
PUT: /resource_classes/CUSTOM_COW
|
||||||
|
status: 400
|
||||||
|
response_strings:
|
||||||
|
# We don't check much of this string because it is different
|
||||||
|
# between python 2 and 3.
|
||||||
|
- "Malformed JSON:"
|
@ -0,0 +1,49 @@
|
|||||||
|
fixtures:
|
||||||
|
- APIFixture
|
||||||
|
|
||||||
|
defaults:
|
||||||
|
request_headers:
|
||||||
|
x-auth-token: admin
|
||||||
|
accept: application/json
|
||||||
|
content-type: application/json
|
||||||
|
OpenStack-API-Version: placement 1.7
|
||||||
|
|
||||||
|
tests:
|
||||||
|
|
||||||
|
- name: create new custom class with put
|
||||||
|
PUT: /resource_classes/CUSTOM_COW
|
||||||
|
status: 201
|
||||||
|
response_headers:
|
||||||
|
location: //resource_classes/CUSTOM_COW/
|
||||||
|
|
||||||
|
- name: verify that class with put
|
||||||
|
PUT: /resource_classes/CUSTOM_COW
|
||||||
|
status: 204
|
||||||
|
response_headers:
|
||||||
|
location: //resource_classes/CUSTOM_COW/
|
||||||
|
|
||||||
|
- name: fail to put non custom class
|
||||||
|
PUT: /resource_classes/COW
|
||||||
|
status: 400
|
||||||
|
response_strings:
|
||||||
|
- "Failed validating 'pattern'"
|
||||||
|
|
||||||
|
- name: try to put standard class
|
||||||
|
PUT: /resource_classes/VCPU
|
||||||
|
status: 400
|
||||||
|
response_strings:
|
||||||
|
- "Failed validating 'pattern'"
|
||||||
|
|
||||||
|
- name: try to put too long class
|
||||||
|
PUT: /resource_classes/CUSTOM_SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
|
||||||
|
status: 400
|
||||||
|
response_strings:
|
||||||
|
- "Failed validating 'maxLength'"
|
||||||
|
|
||||||
|
- name: post to create still works
|
||||||
|
POST: /resource_classes
|
||||||
|
data:
|
||||||
|
name: CUSTOM_SHEEP
|
||||||
|
status: 201
|
||||||
|
response_headers:
|
||||||
|
location: //resource_classes/CUSTOM_SHEEP/
|
@ -125,6 +125,7 @@ tests:
|
|||||||
PUT: /resource_classes/VCPU
|
PUT: /resource_classes/VCPU
|
||||||
request_headers:
|
request_headers:
|
||||||
content-type: application/json
|
content-type: application/json
|
||||||
|
OpenStack-API-Version: placement 1.6
|
||||||
data:
|
data:
|
||||||
name: VCPU_ALTERNATE
|
name: VCPU_ALTERNATE
|
||||||
status: 400
|
status: 400
|
||||||
@ -137,6 +138,7 @@ tests:
|
|||||||
PUT: /resource_classes/$ENVIRON['CUSTOM_RES_CLASS']
|
PUT: /resource_classes/$ENVIRON['CUSTOM_RES_CLASS']
|
||||||
request_headers:
|
request_headers:
|
||||||
content-type: application/json
|
content-type: application/json
|
||||||
|
OpenStack-API-Version: placement 1.6
|
||||||
data:
|
data:
|
||||||
name: VCPU
|
name: VCPU
|
||||||
status: 400
|
status: 400
|
||||||
@ -157,6 +159,7 @@ tests:
|
|||||||
PUT: /resource_classes/CUSTOM_NFV_FOO
|
PUT: /resource_classes/CUSTOM_NFV_FOO
|
||||||
request_headers:
|
request_headers:
|
||||||
content-type: application/json
|
content-type: application/json
|
||||||
|
OpenStack-API-Version: placement 1.6
|
||||||
data:
|
data:
|
||||||
name: $ENVIRON['CUSTOM_RES_CLASS']
|
name: $ENVIRON['CUSTOM_RES_CLASS']
|
||||||
status: 409
|
status: 409
|
||||||
@ -170,6 +173,7 @@ tests:
|
|||||||
PUT: /resource_classes/$ENVIRON['CUSTOM_RES_CLASS']
|
PUT: /resource_classes/$ENVIRON['CUSTOM_RES_CLASS']
|
||||||
request_headers:
|
request_headers:
|
||||||
content-type: application/json
|
content-type: application/json
|
||||||
|
OpenStack-API-Version: placement 1.6
|
||||||
data:
|
data:
|
||||||
name: CUSTOM_NFV_BAR
|
name: CUSTOM_NFV_BAR
|
||||||
status: 200
|
status: 200
|
||||||
@ -234,6 +238,7 @@ tests:
|
|||||||
PUT: /resource_classes/$ENVIRON['CUSTOM_RES_CLASS']
|
PUT: /resource_classes/$ENVIRON['CUSTOM_RES_CLASS']
|
||||||
request_headers:
|
request_headers:
|
||||||
content-type: application/json
|
content-type: application/json
|
||||||
|
OpenStack-API-Version: placement 1.6
|
||||||
data:
|
data:
|
||||||
name: *name_exceeds_max_length_check
|
name: *name_exceeds_max_length_check
|
||||||
status: 400
|
status: 400
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
The 1.7 version of the placement API changes handling of
|
||||||
|
`PUT /resource_classes/{name}` to be a create or verification of the
|
||||||
|
resource class with `{name}`. If the resource class is a custom resource
|
||||||
|
class and does not already exist it will be created and a ``201`` response
|
||||||
|
code returned. If the class already exists the response code will be
|
||||||
|
``204``. This makes it possible to check or create a resource class in one
|
||||||
|
request.
|
Loading…
Reference in New Issue
Block a user