"Fossies" - the Fresh Open Source Software Archive

Member "zaqar-10.0.0/zaqar/transport/wsgi/v1_1/flavors.py" (13 May 2020, 6420 Bytes) of package /linux/misc/openstack/zaqar-10.0.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "flavors.py": 9.0.0_vs_10.0.0.

    1 # Copyright (c) 2014 Red Hat, Inc.
    2 #
    3 # Licensed under the Apache License, Version 2.0 (the "License");
    4 # you may not use this file except in compliance with the License.
    5 # You may obtain a copy of the License at
    6 #
    7 #    http://www.apache.org/licenses/LICENSE-2.0
    8 #
    9 # Unless required by applicable law or agreed to in writing, software
   10 # distributed under the License is distributed on an "AS IS" BASIS,
   11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
   12 # implied.
   13 # See the License for the specific language governing permissions and
   14 # limitations under the License.
   15 
   16 import falcon
   17 import jsonschema
   18 from oslo_log import log
   19 import six
   20 
   21 from zaqar.common.api.schemas.v1_1 import flavors as schema
   22 from zaqar.common import utils as common_utils
   23 from zaqar.i18n import _
   24 from zaqar.storage import errors
   25 from zaqar.transport import utils as transport_utils
   26 from zaqar.transport.wsgi import errors as wsgi_errors
   27 from zaqar.transport.wsgi import utils as wsgi_utils
   28 
   29 LOG = log.getLogger(__name__)
   30 
   31 
   32 class Listing(object):
   33     """A resource to list registered flavors
   34 
   35     :param flavors_controller: means to interact with storage
   36     """
   37 
   38     def __init__(self, flavors_controller):
   39         self._ctrl = flavors_controller
   40 
   41     def on_get(self, request, response, project_id):
   42         """Returns a flavor listing as objects embedded in an object:
   43 
   44         ::
   45 
   46             {
   47                 "flavors": [
   48                     {"href": "", "capabilities": {}, "pool": ""},
   49                     ...
   50                 ],
   51                 "links": [
   52                     {"rel": "next", "href": ""},
   53                     ...
   54                 ]
   55             }
   56 
   57         :returns: HTTP | 200
   58         """
   59 
   60         LOG.debug(u'LIST flavors for project_id %s', project_id)
   61 
   62         store = {}
   63         request.get_param('marker', store=store)
   64         request.get_param_as_int('limit', store=store)
   65         request.get_param_as_bool('detailed', store=store)
   66 
   67         cursor = self._ctrl.list(project=project_id, **store)
   68         flavors = list(next(cursor))
   69 
   70         results = {'links': []}
   71 
   72         if flavors:
   73             store['marker'] = next(cursor)
   74 
   75             for entry in flavors:
   76                 entry['href'] = request.path + '/' + entry['name']
   77 
   78             results['links'] = [
   79                 {
   80                     'rel': 'next',
   81                     'href': request.path + falcon.to_query_str(store)
   82                 }
   83             ]
   84 
   85         results['flavors'] = flavors
   86 
   87         response.body = transport_utils.to_json(results)
   88         response.status = falcon.HTTP_200
   89 
   90 
   91 class Resource(object):
   92     """A handler for individual flavor.
   93 
   94     :param flavors_controller: means to interact with storage
   95     """
   96 
   97     def __init__(self, flavors_controller):
   98         self._ctrl = flavors_controller
   99         validator_type = jsonschema.Draft4Validator
  100         self._validators = {
  101             'create': validator_type(schema.create),
  102             'capabilities': validator_type(schema.patch_capabilities),
  103         }
  104 
  105     def on_get(self, request, response, project_id, flavor):
  106         """Returns a JSON object for a single flavor entry:
  107 
  108         ::
  109 
  110             {"pool_group": "", capabilities: {...}}
  111 
  112         :returns: HTTP | [200, 404]
  113         """
  114 
  115         LOG.debug(u'GET flavor - name: %s', flavor)
  116         data = None
  117         detailed = request.get_param_as_bool('detailed') or False
  118 
  119         try:
  120             data = self._ctrl.get(flavor,
  121                                   project=project_id,
  122                                   detailed=detailed)
  123         except errors.FlavorDoesNotExist as ex:
  124             LOG.debug(ex)
  125             raise wsgi_errors.HTTPNotFound(six.text_type(ex))
  126 
  127         data['href'] = request.path
  128 
  129         response.body = transport_utils.to_json(data)
  130 
  131     def on_put(self, request, response, project_id, flavor):
  132         """Registers a new flavor. Expects the following input:
  133 
  134         ::
  135 
  136             {"capabilities": {}}
  137 
  138         A capabilities object may also be provided.
  139 
  140         :returns: HTTP | [201, 400]
  141         """
  142 
  143         LOG.debug(u'PUT flavor - name: %s', flavor)
  144 
  145         data = wsgi_utils.load(request)
  146         wsgi_utils.validate(self._validators['create'], data)
  147         try:
  148             self._ctrl.create(flavor,
  149                               project=project_id,
  150                               capabilities=data['capabilities'])
  151             response.status = falcon.HTTP_201
  152             response.location = request.path
  153         except errors.PoolGroupDoesNotExist:
  154             description = (_(u'Flavor %(flavor)s could not be created. ') %
  155                            dict(flavor=flavor))
  156             LOG.exception(description)
  157             raise falcon.HTTPBadRequest(_('Unable to create'), description)
  158 
  159     def on_delete(self, request, response, project_id, flavor):
  160         """Deregisters a flavor.
  161 
  162         :returns: HTTP | [204]
  163         """
  164 
  165         LOG.debug(u'DELETE flavor - name: %s', flavor)
  166         self._ctrl.delete(flavor, project=project_id)
  167         response.status = falcon.HTTP_204
  168 
  169     def on_patch(self, request, response, project_id, flavor):
  170         """Allows one to update a flavors's pool and/or capabilities.
  171 
  172         This method expects the user to submit a JSON object
  173         containing at least one of: 'pool_group', 'capabilities'. If
  174         none are found, the request is flagged as bad. There is also
  175         strict format checking through the use of
  176         jsonschema. Appropriate errors are returned in each case for
  177         badly formatted input.
  178 
  179         :returns: HTTP | [200, 400]
  180         """
  181 
  182         LOG.debug(u'PATCH flavor - name: %s', flavor)
  183         data = wsgi_utils.load(request)
  184 
  185         EXPECT = ('capabilities')
  186         if not any([(field in data) for field in EXPECT]):
  187             LOG.debug(u'PATCH flavor, bad params')
  188             raise wsgi_errors.HTTPBadRequestBody(
  189                 '`capabilities` needs '
  190                 'to be specified'
  191             )
  192 
  193         for field in EXPECT:
  194             wsgi_utils.validate(self._validators[field], data)
  195 
  196         fields = common_utils.fields(data, EXPECT,
  197                                      pred=lambda v: v is not None)
  198 
  199         try:
  200             self._ctrl.update(flavor, project=project_id, **fields)
  201         except errors.FlavorDoesNotExist as ex:
  202             LOG.exception('Flavor "%s" does not exist', flavor)
  203             raise wsgi_errors.HTTPNotFound(six.text_type(ex))