da1a588b8d
Nothing is being translated in placement so, for the sake of being clean and tidy, this patch removes the framework for translation and the import of oslo.i18n. Originally the hope was we could remove the dependency on oslo.i18n and Babel entirely to save some disk space but many other oslo-related libs depend on oslo.i18n so they are present anyway. [1] [1] http://lists.openstack.org/pipermail/openstack-discuss/2019-March/004220.html Change-Id: Ia965d028b6f7c9f04d1f29beb12f4862585631d5
120 lines
4.9 KiB
Python
120 lines
4.9 KiB
Python
# 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
|
|
from oslo_utils import encodeutils
|
|
from oslo_utils import timeutils
|
|
import webob
|
|
|
|
from placement import exception
|
|
from placement import microversion
|
|
from placement.objects import resource_provider as rp_obj
|
|
from placement.objects import usage as usage_obj
|
|
from placement.policies import usage as policies
|
|
from placement.schemas import usage as schema
|
|
from placement import util
|
|
from placement import wsgi_wrapper
|
|
|
|
|
|
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}
|
|
|
|
|
|
@wsgi_wrapper.PlacementWsgify
|
|
@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']
|
|
context.can(policies.PROVIDER_USAGES)
|
|
uuid = util.wsgi_path_item(req.environ, 'uuid')
|
|
want_version = req.environ[microversion.MICROVERSION_ENVIRON]
|
|
|
|
# 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.
|
|
try:
|
|
resource_provider = rp_obj.ResourceProvider.get_by_uuid(
|
|
context, uuid)
|
|
except exception.NotFound as exc:
|
|
raise webob.exc.HTTPNotFound(
|
|
"No resource provider with uuid %(uuid)s found: %(error)s" %
|
|
{'uuid': uuid, 'error': exc})
|
|
|
|
usage = usage_obj.get_all_by_resource_provider_uuid(context, uuid)
|
|
|
|
response = req.response
|
|
response.body = encodeutils.to_utf8(jsonutils.dumps(
|
|
_serialize_usages(resource_provider, usage)))
|
|
req.response.content_type = 'application/json'
|
|
if want_version.matches((1, 15)):
|
|
req.response.cache_control = 'no-cache'
|
|
# While it would be possible to generate a last-modified time
|
|
# based on the collection of allocations that result in a usage
|
|
# value (with some spelunking in the SQL) that doesn't align with
|
|
# the question that is being asked in a request for usages: What
|
|
# is the usage, now? So the last-modified time is set to utcnow.
|
|
req.response.last_modified = timeutils.utcnow(with_timezone=True)
|
|
return req.response
|
|
|
|
|
|
@wsgi_wrapper.PlacementWsgify
|
|
@microversion.version_handler('1.9')
|
|
@util.check_accept('application/json')
|
|
def get_total_usages(req):
|
|
"""GET the sum of usages for a project or a project/user.
|
|
|
|
On success return a 200 and an application/json body representing the
|
|
sum/total of usages.
|
|
Return 404 Not Found if the wanted microversion does not match.
|
|
"""
|
|
context = req.environ['placement.context']
|
|
# TODO(mriedem): When we support non-admins to use GET /usages we
|
|
# should pass the project_id (and user_id?) from the query parameters
|
|
# into context.can() for the target.
|
|
context.can(policies.TOTAL_USAGES)
|
|
want_version = req.environ[microversion.MICROVERSION_ENVIRON]
|
|
|
|
util.validate_query_params(req, schema.GET_USAGES_SCHEMA_1_9)
|
|
|
|
project_id = req.GET.get('project_id')
|
|
user_id = req.GET.get('user_id')
|
|
|
|
usages = usage_obj.get_all_by_project_user(context, project_id,
|
|
user_id=user_id)
|
|
|
|
response = req.response
|
|
usages_dict = {'usages': {resource.resource_class: resource.usage
|
|
for resource in usages}}
|
|
response.body = encodeutils.to_utf8(jsonutils.dumps(usages_dict))
|
|
req.response.content_type = 'application/json'
|
|
if want_version.matches((1, 15)):
|
|
req.response.cache_control = 'no-cache'
|
|
# While it would be possible to generate a last-modified time
|
|
# based on the collection of allocations that result in a usage
|
|
# value (with some spelunking in the SQL) that doesn't align with
|
|
# the question that is being asked in a request for usages: What
|
|
# is the usage, now? So the last-modified time is set to utcnow.
|
|
req.response.last_modified = timeutils.utcnow(with_timezone=True)
|
|
return req.response
|