[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
|
||||
@microversion.version_handler('1.2')
|
||||
@microversion.version_handler('1.2', '1.6')
|
||||
@util.require_content('application/json')
|
||||
def update_resource_class(req):
|
||||
"""PUT to update a single resource class.
|
||||
@ -199,3 +199,38 @@ def update_resource_class(req):
|
||||
req.response.status = 200
|
||||
req.response.content_type = 'application/json'
|
||||
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.6', # Adds /traits and /resource_providers{uuid}/traits resource
|
||||
# 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
|
||||
the letters A through Z, the numbers 0 through 9 and the underscore "\_"
|
||||
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:
|
||||
$.errors[0].title: Not Acceptable
|
||||
|
||||
- name: latest microversion is 1.6
|
||||
- name: latest microversion is 1.7
|
||||
GET: /
|
||||
request_headers:
|
||||
openstack-api-version: placement latest
|
||||
response_headers:
|
||||
vary: /OpenStack-API-Version/
|
||||
openstack-api-version: placement 1.6
|
||||
openstack-api-version: placement 1.7
|
||||
|
||||
- name: other accept header bad version
|
||||
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
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
OpenStack-API-Version: placement 1.6
|
||||
data:
|
||||
name: VCPU_ALTERNATE
|
||||
status: 400
|
||||
@ -137,6 +138,7 @@ tests:
|
||||
PUT: /resource_classes/$ENVIRON['CUSTOM_RES_CLASS']
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
OpenStack-API-Version: placement 1.6
|
||||
data:
|
||||
name: VCPU
|
||||
status: 400
|
||||
@ -157,6 +159,7 @@ tests:
|
||||
PUT: /resource_classes/CUSTOM_NFV_FOO
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
OpenStack-API-Version: placement 1.6
|
||||
data:
|
||||
name: $ENVIRON['CUSTOM_RES_CLASS']
|
||||
status: 409
|
||||
@ -170,6 +173,7 @@ tests:
|
||||
PUT: /resource_classes/$ENVIRON['CUSTOM_RES_CLASS']
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
OpenStack-API-Version: placement 1.6
|
||||
data:
|
||||
name: CUSTOM_NFV_BAR
|
||||
status: 200
|
||||
@ -234,6 +238,7 @@ tests:
|
||||
PUT: /resource_classes/$ENVIRON['CUSTOM_RES_CLASS']
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
OpenStack-API-Version: placement 1.6
|
||||
data:
|
||||
name: *name_exceeds_max_length_check
|
||||
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