Merge "Add support for usages in the placement API"
This commit is contained in:
commit
d7c9d8e0e0
@ -29,6 +29,7 @@ import webob
|
||||
from nova.api.openstack.placement.handlers import inventory
|
||||
from nova.api.openstack.placement.handlers import resource_provider
|
||||
from nova.api.openstack.placement.handlers import root
|
||||
from nova.api.openstack.placement.handlers import usage
|
||||
from nova.api.openstack.placement import util
|
||||
from nova import exception
|
||||
|
||||
@ -61,6 +62,9 @@ ROUTE_DECLARATIONS = {
|
||||
'PUT': inventory.update_inventory,
|
||||
'DELETE': inventory.delete_inventory
|
||||
},
|
||||
'/resource_providers/{uuid}/usages': {
|
||||
'GET': usage.list_usages
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
55
nova/api/openstack/placement/handlers/usage.py
Normal file
55
nova/api/openstack/placement/handlers/usage.py
Normal file
@ -0,0 +1,55 @@
|
||||
# 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.
|
||||
"""Placement API handlers for usage information."""
|
||||
|
||||
from oslo_serialization import jsonutils
|
||||
import webob
|
||||
|
||||
from nova.api.openstack.placement import util
|
||||
from nova import objects
|
||||
|
||||
|
||||
def _serialize_usages(resource_provider, usage):
|
||||
usage_dict = {resource.resource_class: resource.usage
|
||||
for resource in usage}
|
||||
return {'resource_provider_generation': resource_provider.generation,
|
||||
'usages': usage_dict}
|
||||
|
||||
|
||||
@webob.dec.wsgify
|
||||
@util.check_accept('application/json')
|
||||
def list_usages(req):
|
||||
"""GET a dictionary of resource provider usage by resource class.
|
||||
|
||||
If the resource provider does not exist return a 404.
|
||||
|
||||
On success return a 200 with an application/json representation of
|
||||
the usage dictionary.
|
||||
"""
|
||||
context = req.environ['placement.context']
|
||||
uuid = util.wsgi_path_item(req.environ, 'uuid')
|
||||
|
||||
# Resource provider object needed for two things: If it is
|
||||
# NotFound we'll get a 404 here, which needs to happen because
|
||||
# get_all_by_resource_provider_uuid can return an empty list.
|
||||
# It is also needed for the generation, used in the outgoing
|
||||
# representation.
|
||||
resource_provider = objects.ResourceProvider.get_by_uuid(
|
||||
context, uuid)
|
||||
usage = objects.UsageList.get_all_by_resource_provider_uuid(
|
||||
context, uuid)
|
||||
|
||||
response = req.response
|
||||
response.body = jsonutils.dumps(
|
||||
_serialize_usages(resource_provider, usage))
|
||||
req.response.content_type = 'application/json'
|
||||
return req.response
|
@ -18,6 +18,8 @@ from oslo_utils import uuidutils
|
||||
from nova.api.openstack.placement import deploy
|
||||
from nova import conf
|
||||
from nova import config
|
||||
from nova import context
|
||||
from nova import objects
|
||||
from nova.tests import fixtures
|
||||
|
||||
|
||||
@ -66,3 +68,34 @@ class APIFixture(fixture.GabbiFixture):
|
||||
self.main_db_fixture.cleanup()
|
||||
if self.conf:
|
||||
self.conf.reset()
|
||||
|
||||
|
||||
class AllocationFixture(APIFixture):
|
||||
"""An APIFixture that has some pre-made Allocations."""
|
||||
|
||||
def start_fixture(self):
|
||||
super(AllocationFixture, self).start_fixture()
|
||||
self.context = context.get_admin_context()
|
||||
# Stealing from the super
|
||||
rp_name = os.environ['RP_NAME']
|
||||
rp_uuid = os.environ['RP_UUID']
|
||||
rp = objects.ResourceProvider(
|
||||
self.context, name=rp_name, uuid=rp_uuid)
|
||||
rp.create()
|
||||
inventory = objects.Inventory(
|
||||
self.context, resource_provider=rp,
|
||||
resource_class='DISK_GB', total=2048)
|
||||
inventory.obj_set_defaults()
|
||||
rp.add_inventory(inventory)
|
||||
allocation = objects.Allocation(
|
||||
self.context, resource_provider=rp,
|
||||
resource_class='DISK_GB',
|
||||
consumer_id=uuidutils.generate_uuid(),
|
||||
used=512)
|
||||
allocation.create()
|
||||
allocation = objects.Allocation(
|
||||
self.context, resource_provider=rp,
|
||||
resource_class='DISK_GB',
|
||||
consumer_id=uuidutils.generate_uuid(),
|
||||
used=512)
|
||||
allocation.create()
|
||||
|
@ -0,0 +1,34 @@
|
||||
# More interesting tests for usages are in with_allocations
|
||||
|
||||
fixtures:
|
||||
- APIFixture
|
||||
|
||||
defaults:
|
||||
request_headers:
|
||||
x-auth-token: admin
|
||||
|
||||
tests:
|
||||
|
||||
- name: fail to get usages for missing provider
|
||||
GET: /resource_providers/fae14fa3-4b43-498c-a33c-4a1d00edb577/usages
|
||||
status: 404
|
||||
|
||||
- name: create provider
|
||||
POST: /resource_providers
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
data:
|
||||
name: a name
|
||||
status: 201
|
||||
|
||||
- name: check provider exists
|
||||
GET: $LOCATION
|
||||
response_json_paths:
|
||||
name: a name
|
||||
|
||||
- name: get empty usages
|
||||
GET: $LAST_URL/usages
|
||||
request_headers:
|
||||
content-type: application/json
|
||||
response_json_paths:
|
||||
usages: {}
|
@ -0,0 +1,25 @@
|
||||
|
||||
fixtures:
|
||||
- AllocationFixture
|
||||
|
||||
defaults:
|
||||
request_headers:
|
||||
x-auth-token: admin
|
||||
|
||||
tests:
|
||||
|
||||
- name: confirm inventories
|
||||
GET: /resource_providers/$ENVIRON['RP_UUID']/inventories
|
||||
response_json_paths:
|
||||
$.inventories.DISK_GB.total: 2048
|
||||
$.inventories.DISK_GB.reserved: 0
|
||||
|
||||
- name: get usages
|
||||
GET: /resource_providers/$ENVIRON['RP_UUID']/usages
|
||||
response_headers:
|
||||
# use a regex here because charset, which is not only not
|
||||
# required but superfluous, is present
|
||||
content-type: /application/json/
|
||||
response_json_paths:
|
||||
$.resource_provider_generation: 1
|
||||
$.usages.DISK_GB: 1024
|
Loading…
Reference in New Issue
Block a user