Implement get and set aggregates in the placement API
/resource_providers/{uuid}/aggregates GET for a list of aggregate uuids associated with this resource provider PUT to set the list of aggregate uuids associated with this this provider The API requests map directly to set_ and get_ aggregates on the ResourceProvider object. This is implemented as placement API microversion 1.1. To make that easier a raise_404_if_not_version helper method is added to the microversion module. The new rest_api_version_history doc is updated to reflect this new version. Change-Id: I514c15c7d387cf25bf7986d07baccf0e7a785f46 Partially-Implements: blueprint generic-resource-pools-ocata
This commit is contained in:
parent
b3745f92e0
commit
44ca84a7e1
@ -28,6 +28,7 @@ import webob
|
||||
|
||||
from oslo_log import log as logging
|
||||
|
||||
from nova.api.openstack.placement.handlers import aggregate
|
||||
from nova.api.openstack.placement.handlers import allocation
|
||||
from nova.api.openstack.placement.handlers import inventory
|
||||
from nova.api.openstack.placement.handlers import resource_provider
|
||||
@ -79,6 +80,10 @@ ROUTE_DECLARATIONS = {
|
||||
'/resource_providers/{uuid}/usages': {
|
||||
'GET': usage.list_usages
|
||||
},
|
||||
'/resource_providers/{uuid}/aggregates': {
|
||||
'GET': aggregate.get_aggregates,
|
||||
'PUT': aggregate.set_aggregates
|
||||
},
|
||||
'/resource_providers/{uuid}/allocations': {
|
||||
'GET': allocation.list_for_resource_provider,
|
||||
},
|
||||
|
74
nova/api/openstack/placement/handlers/aggregate.py
Normal file
74
nova/api/openstack/placement/handlers/aggregate.py
Normal file
@ -0,0 +1,74 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""Aggregate handlers for Placement API."""
|
||||
|
||||
from oslo_serialization import jsonutils
|
||||
import webob
|
||||
|
||||
from nova.api.openstack.placement import microversion
|
||||
from nova.api.openstack.placement import util
|
||||
from nova import objects
|
||||
|
||||
|
||||
PUT_AGGREGATES_SCHEMA = {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"uniqueItems": True
|
||||
}
|
||||
|
||||
|
||||
def _send_aggregates(response, aggregate_uuids):
|
||||
response.status = 200
|
||||
response.body = jsonutils.dumps(_serialize_aggregates(aggregate_uuids))
|
||||
response.content_type = 'application/json'
|
||||
return response
|
||||
|
||||
|
||||
def _serialize_aggregates(aggregate_uuids):
|
||||
return {'aggregates': aggregate_uuids}
|
||||
|
||||
|
||||
@webob.dec.wsgify
|
||||
@util.check_accept('application/json')
|
||||
def get_aggregates(req):
|
||||
"""GET a list of aggregates associated with a resource provider.
|
||||
|
||||
If the resource provider does not exist return a 404.
|
||||
|
||||
On success return a 200 with an application/json body containing a
|
||||
list of aggregate uuids.
|
||||
"""
|
||||
microversion.raise_404_if_not_version(req, (1, 1))
|
||||
context = req.environ['placement.context']
|
||||
uuid = util.wsgi_path_item(req.environ, 'uuid')
|
||||
resource_provider = objects.ResourceProvider.get_by_uuid(
|
||||
context, uuid)
|
||||
aggregate_uuids = resource_provider.get_aggregates()
|
||||
|
||||
return _send_aggregates(req.response, aggregate_uuids)
|
||||
|
||||
|
||||
@webob.dec.wsgify
|
||||
@util.require_content('application/json')
|
||||
def set_aggregates(req):
|
||||
microversion.raise_404_if_not_version(req, (1, 1))
|
||||
context = req.environ['placement.context']
|
||||
uuid = util.wsgi_path_item(req.environ, 'uuid')
|
||||
resource_provider = objects.ResourceProvider.get_by_uuid(
|
||||
context, uuid)
|
||||
aggregate_uuids = util.extract_json(req.body, PUT_AGGREGATES_SCHEMA)
|
||||
resource_provider.set_aggregates(aggregate_uuids)
|
||||
|
||||
return _send_aggregates(req.response, aggregate_uuids)
|
@ -35,6 +35,7 @@ VERSIONED_METHODS = collections.defaultdict(list)
|
||||
# The Canonical Version List
|
||||
VERSIONS = [
|
||||
'1.0',
|
||||
'1.1', # initial support for aggregate.get_aggregates and set_aggregates
|
||||
]
|
||||
|
||||
|
||||
@ -68,6 +69,13 @@ def parse_version_string(version_string):
|
||||
version_string, exc))
|
||||
|
||||
|
||||
def raise_404_if_not_version(req, min_version, max_version=None):
|
||||
"""Utility to raise a 404 if the wanted microversion does not match."""
|
||||
want_version = req.environ[MICROVERSION_ENVIRON]
|
||||
if not want_version.matches(min_version, max_version):
|
||||
raise webob.exc.HTTPNotFound
|
||||
|
||||
|
||||
class MicroversionMiddleware(object):
|
||||
"""WSGI middleware for getting microversion info."""
|
||||
|
||||
|
@ -17,3 +17,12 @@ Nova 14.0.0 (Newton). This contains the following routes:
|
||||
* /resource_providers/inventories
|
||||
* /resource_providers/usages
|
||||
* /allocations
|
||||
|
||||
1.1
|
||||
___
|
||||
|
||||
The 1.1 version adds support for associating aggregates with
|
||||
resource providers with ``GET`` and ``PUT`` methods on one new
|
||||
route:
|
||||
|
||||
* /resource_providers/{uuid}/aggregates
|
||||
|
@ -0,0 +1,104 @@
|
||||
|
||||
fixtures:
|
||||
- APIFixture
|
||||
|
||||
defaults:
|
||||
request_headers:
|
||||
x-auth-token: admin
|
||||
content-type: application/json
|
||||
openstack-api-version: placement latest
|
||||
|
||||
vars:
|
||||
- &agg_1 f918801a-5e54-4bee-9095-09a9d0c786b8
|
||||
- &agg_2 a893eb5c-e2a0-4251-ab26-f71d3b0cfc0b
|
||||
|
||||
tests:
|
||||
- name: get aggregates for bad resource provider
|
||||
GET: /resource_providers/6984bb2d-830d-4c8d-ac64-c5a8103664be/aggregates
|
||||
status: 404
|
||||
|
||||
- name: put aggregates for bad resource provider
|
||||
PUT: /resource_providers/6984bb2d-830d-4c8d-ac64-c5a8103664be/aggregates
|
||||
data: []
|
||||
status: 404
|
||||
|
||||
- name: post new resource provider
|
||||
POST: /resource_providers
|
||||
data:
|
||||
name: $ENVIRON['RP_NAME']
|
||||
uuid: $ENVIRON['RP_UUID']
|
||||
status: 201
|
||||
response_headers:
|
||||
location: //resource_providers/[a-f0-9-]+/
|
||||
|
||||
- name: get empty aggregates
|
||||
GET: /resource_providers/$ENVIRON['RP_UUID']/aggregates
|
||||
response_json_paths:
|
||||
$.aggregates: []
|
||||
|
||||
- name: aggregates 404 for out of date microversion get
|
||||
GET: /resource_providers/$ENVIRON['RP_UUID']/aggregates
|
||||
request_headers:
|
||||
openstack-api-version: placement 1.0
|
||||
status: 404
|
||||
|
||||
- name: aggregates 404 for out of date microversion put
|
||||
PUT: /resource_providers/$ENVIRON['RP_UUID']/aggregates
|
||||
request_headers:
|
||||
openstack-api-version: placement 1.0
|
||||
status: 404
|
||||
|
||||
- name: put some aggregates
|
||||
PUT: $LAST_URL
|
||||
data:
|
||||
- *agg_1
|
||||
- *agg_2
|
||||
status: 200
|
||||
response_headers:
|
||||
content-type: /application/json/
|
||||
response_json_paths:
|
||||
$.aggregates[0]: *agg_1
|
||||
$.aggregates[1]: *agg_2
|
||||
|
||||
- name: get those aggregates
|
||||
GET: $LAST_URL
|
||||
response_json_paths:
|
||||
$.aggregates.`len`: 2
|
||||
|
||||
- name: clear those aggregates
|
||||
PUT: $LAST_URL
|
||||
data: []
|
||||
status: 200
|
||||
response_json_paths:
|
||||
$.aggregates: []
|
||||
|
||||
- name: get empty aggregates again
|
||||
GET: /resource_providers/$ENVIRON['RP_UUID']/aggregates
|
||||
response_json_paths:
|
||||
$.aggregates: []
|
||||
|
||||
- name: put non json
|
||||
PUT: $LAST_URL
|
||||
data: '{"bad", "not json"}'
|
||||
status: 400
|
||||
response_strings:
|
||||
- Malformed JSON
|
||||
|
||||
- name: put invalid json not array
|
||||
PUT: $LAST_URL
|
||||
data:
|
||||
aggregates:
|
||||
- *agg_1
|
||||
- *agg_2
|
||||
status: 400
|
||||
response_strings:
|
||||
- JSON does not validate
|
||||
|
||||
- name: put invalid json not uuids
|
||||
PUT: $LAST_URL
|
||||
data:
|
||||
- harry
|
||||
- sally
|
||||
status: 400
|
||||
response_strings:
|
||||
- JSON does not validate
|
@ -37,13 +37,13 @@ tests:
|
||||
response_strings:
|
||||
- "Unacceptable version header: 0.5"
|
||||
|
||||
- name: latest microversion is 1.0
|
||||
- name: latest microversion is 1.1
|
||||
GET: /
|
||||
request_headers:
|
||||
openstack-api-version: placement latest
|
||||
response_headers:
|
||||
vary: /OpenStack-API-Version/
|
||||
openstack-api-version: placement 1.0
|
||||
openstack-api-version: placement 1.1
|
||||
|
||||
- name: other accept header bad version
|
||||
GET: /
|
||||
|
Loading…
Reference in New Issue
Block a user