¡@

Home 

OpenStack Study: qos_specs_manage.py

OpenStack Index

**** CubicPower OpenStack Study ****

# Copyright (c) 2013 eBay Inc.

# Copyright (c) 2013 OpenStack Foundation

#

# 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.

"""The QoS specs extension"""

import six

import webob

from cinder.api import extensions

from cinder.api.openstack import wsgi

from cinder.api.views import qos_specs as view_qos_specs

from cinder.api import xmlutil

from cinder import exception

from cinder.openstack.common import log as logging

from cinder.openstack.common import strutils

from cinder import rpc

from cinder.volume import qos_specs

LOG = logging.getLogger(__name__)

authorize = extensions.extension_authorizer('volume', 'qos_specs_manage')

**** CubicPower OpenStack Study ****

def make_qos_specs(elem):

    elem.set('id')

    elem.set('name')

    elem.set('consumer')

    elem.append(SpecsTemplate())

**** CubicPower OpenStack Study ****

def make_associations(elem):

    elem.set('association_type')

    elem.set('name')

    elem.set('id')

**** CubicPower OpenStack Study ****

class SpecsTemplate(xmlutil.TemplateBuilder):

**** CubicPower OpenStack Study ****

    def construct(self):

        return xmlutil.MasterTemplate(xmlutil.make_flat_dict('specs'), 1)

**** CubicPower OpenStack Study ****

class QoSSpecsTemplate(xmlutil.TemplateBuilder):

**** CubicPower OpenStack Study ****

    def construct(self):

        root = xmlutil.TemplateElement('qos_specs')

        elem = xmlutil.SubTemplateElement(root, 'qos_spec',

                                          selector='qos_specs')

        make_qos_specs(elem)

        return xmlutil.MasterTemplate(root, 1)

**** CubicPower OpenStack Study ****

class AssociationsTemplate(xmlutil.TemplateBuilder):

**** CubicPower OpenStack Study ****

    def construct(self):

        root = xmlutil.TemplateElement('qos_associations')

        elem = xmlutil.SubTemplateElement(root, 'associations',

                                          selector='qos_associations')

        make_associations(elem)

        return xmlutil.MasterTemplate(root, 1)

def _check_specs(context, specs_id):

    try:

        qos_specs.get_qos_specs(context, specs_id)

    except exception.NotFound as ex:

        raise webob.exc.HTTPNotFound(explanation=six.text_type(ex))

**** CubicPower OpenStack Study ****

def _check_specs(context, specs_id):

    try:

        qos_specs.get_qos_specs(context, specs_id)

    except exception.NotFound as ex:

        raise webob.exc.HTTPNotFound(explanation=six.text_type(ex))

**** CubicPower OpenStack Study ****

class QoSSpecsController(wsgi.Controller):

"""The volume type extra specs API controller for the OpenStack API."""

_view_builder_class = view_qos_specs.ViewBuilder

@staticmethod

**** CubicPower OpenStack Study ****

    def _notify_qos_specs_error(context, method, payload):

        rpc.get_notifier('QoSSpecs').error(context,

                                           method,

                                           payload)

    @wsgi.serializers(xml=QoSSpecsTemplate)

**** CubicPower OpenStack Study ****

    def index(self, req):

        """Returns the list of qos_specs."""

        context = req.environ['cinder.context']

        authorize(context)

        specs = qos_specs.get_all_specs(context)

        return self._view_builder.summary_list(req, specs)

    @wsgi.serializers(xml=QoSSpecsTemplate)

**** CubicPower OpenStack Study ****

    def create(self, req, body=None):

        context = req.environ['cinder.context']

        authorize(context)

        if not self.is_valid_body(body, 'qos_specs'):

            raise webob.exc.HTTPBadRequest()

        specs = body['qos_specs']

        name = specs.get('name', None)

        if name is None or name == "":

            msg = _("Please specify a name for QoS specs.")

            raise webob.exc.HTTPBadRequest(explanation=msg)

        try:

            qos_specs.create(context, name, specs)

            spec = qos_specs.get_qos_specs_by_name(context, name)

            notifier_info = dict(name=name, specs=specs)

            rpc.get_notifier('QoSSpecs').info(context,

                                              'QoSSpecs.create',

                                              notifier_info)

        except exception.InvalidInput as err:

            notifier_err = dict(name=name, error_message=err)

            self._notify_qos_specs_error(context,

                                         'qos_specs.create',

                                         notifier_err)

            raise webob.exc.HTTPBadRequest(explanation=six.text_type(err))

        except exception.QoSSpecsExists as err:

            notifier_err = dict(name=name, error_message=err)

            self._notify_qos_specs_error(context,

                                         'qos_specs.create',

                                         notifier_err)

            raise webob.exc.HTTPConflict(explanation=six.text_type(err))

        except exception.QoSSpecsCreateFailed as err:

            notifier_err = dict(name=name, error_message=err)

            self._notify_qos_specs_error(context,

                                         'qos_specs.create',

                                         notifier_err)

            raise webob.exc.HTTPInternalServerError(

                explanation=six.text_type(err))

        return self._view_builder.detail(req, spec)

    @wsgi.serializers(xml=QoSSpecsTemplate)

**** CubicPower OpenStack Study ****

    def update(self, req, id, body=None):

        context = req.environ['cinder.context']

        authorize(context)

        if not self.is_valid_body(body, 'qos_specs'):

            raise webob.exc.HTTPBadRequest()

        specs = body['qos_specs']

        try:

            qos_specs.update(context, id, specs)

            notifier_info = dict(id=id, specs=specs)

            rpc.get_notifier('QoSSpecs').info(context,

                                              'qos_specs.update',

                                              notifier_info)

        except exception.QoSSpecsNotFound as err:

            notifier_err = dict(id=id, error_message=err)

            self._notify_qos_specs_error(context,

                                         'qos_specs.update',

                                         notifier_err)

            raise webob.exc.HTTPNotFound(explanation=six.text_type(err))

        except exception.InvalidQoSSpecs as err:

            notifier_err = dict(id=id, error_message=err)

            self._notify_qos_specs_error(context,

                                         'qos_specs.update',

                                         notifier_err)

            raise webob.exc.HTTPBadRequest(explanation=six.text_type(err))

        except exception.QoSSpecsUpdateFailed as err:

            notifier_err = dict(id=id, error_message=err)

            self._notify_qos_specs_error(context,

                                         'qos_specs.update',

                                         notifier_err)

            raise webob.exc.HTTPInternalServerError(

                explanation=six.text_type(err))

        return body

    @wsgi.serializers(xml=QoSSpecsTemplate)

**** CubicPower OpenStack Study ****

    def show(self, req, id):

        """Return a single qos spec item."""

        context = req.environ['cinder.context']

        authorize(context)

        try:

            spec = qos_specs.get_qos_specs(context, id)

        except exception.QoSSpecsNotFound as err:

            raise webob.exc.HTTPNotFound(explanation=six.text_type(err))

        return self._view_builder.detail(req, spec)

**** CubicPower OpenStack Study ****

    def delete(self, req, id):

        """Deletes an existing qos specs."""

        context = req.environ['cinder.context']

        authorize(context)

        force = req.params.get('force', None)

        #convert string to bool type in strict manner

        force = strutils.bool_from_string(force)

        LOG.debug("Delete qos_spec: %(id)s, force: %(force)s" %

                  {'id': id, 'force': force})

        try:

            qos_specs.delete(context, id, force)

            notifier_info = dict(id=id)

            rpc.get_notifier('QoSSpecs').info(context,

                                              'qos_specs.delete',

                                              notifier_info)

        except exception.QoSSpecsNotFound as err:

            notifier_err = dict(id=id, error_message=err)

            self._notify_qos_specs_error(context,

                                         'qos_specs.delete',

                                         notifier_err)

            raise webob.exc.HTTPNotFound(explanation=six.text_type(err))

        except exception.QoSSpecsInUse as err:

            notifier_err = dict(id=id, error_message=err)

            self._notify_qos_specs_error(context,

                                         'qos_specs.delete',

                                         notifier_err)

            if force:

                msg = _('Failed to disassociate qos specs.')

                raise webob.exc.HTTPInternalServerError(explanation=msg)

            msg = _('Qos specs still in use.')

            raise webob.exc.HTTPBadRequest(explanation=msg)

        return webob.Response(status_int=202)

**** CubicPower OpenStack Study ****

    def delete_keys(self, req, id, body):

        """Deletes specified keys in qos specs."""

        context = req.environ['cinder.context']

        authorize(context)

        if not (body and 'keys' in body

                and isinstance(body.get('keys'), list)):

            raise webob.exc.HTTPBadRequest()

        keys = body['keys']

        LOG.debug("Delete_key spec: %(id)s, keys: %(keys)s" %

                  {'id': id, 'keys': keys})

        try:

            qos_specs.delete_keys(context, id, keys)

            notifier_info = dict(id=id)

            rpc.get_notifier().info(context, 'qos_specs.delete_keys',

                                    notifier_info)

        except exception.QoSSpecsNotFound as err:

            notifier_err = dict(id=id, error_message=err)

            self._notify_qos_specs_error(context,

                                         'qos_specs.delete_keys',

                                         notifier_err)

            raise webob.exc.HTTPNotFound(explanation=six.text_type(err))

        except exception.QoSSpecsKeyNotFound as err:

            notifier_err = dict(id=id, error_message=err)

            self._notify_qos_specs_error(context,

                                         'qos_specs.delete_keys',

                                         notifier_err)

            raise webob.exc.HTTPBadRequest(explanation=six.text_type(err))

        return webob.Response(status_int=202)

    @wsgi.serializers(xml=AssociationsTemplate)

**** CubicPower OpenStack Study ****

    def associations(self, req, id):

        """List all associations of given qos specs."""

        context = req.environ['cinder.context']

        authorize(context)

        LOG.debug("Get associations for qos_spec id: %s" % id)

        try:

            associates = qos_specs.get_associations(context, id)

            notifier_info = dict(id=id)

            rpc.get_notifier('QoSSpecs').info(context,

                                              'qos_specs.associations',

                                              notifier_info)

        except exception.QoSSpecsNotFound as err:

            notifier_err = dict(id=id, error_message=err)

            self._notify_qos_specs_error(context,

                                         'qos_specs.associations',

                                         notifier_err)

            raise webob.exc.HTTPNotFound(explanation=six.text_type(err))

        except exception.CinderException as err:

            notifier_err = dict(id=id, error_message=err)

            self._notify_qos_specs_error(context,

                                         'qos_specs.associations',

                                         notifier_err)

            raise webob.exc.HTTPInternalServerError(

                explanation=six.text_type(err))

        return self._view_builder.associations(req, associates)

**** CubicPower OpenStack Study ****

    def associate(self, req, id):

        """Associate a qos specs with a volume type."""

        context = req.environ['cinder.context']

        authorize(context)

        type_id = req.params.get('vol_type_id', None)

        if not type_id:

            msg = _('Volume Type id must not be None.')

            notifier_err = dict(id=id, error_message=msg)

            self._notify_qos_specs_error(context,

                                         'qos_specs.delete',

                                         notifier_err)

            raise webob.exc.HTTPBadRequest(explanation=msg)

        LOG.debug("Associate qos_spec: %(id)s with type: %(type_id)s" %

                  {'id': id, 'type_id': type_id})

        try:

            qos_specs.associate_qos_with_type(context, id, type_id)

            notifier_info = dict(id=id, type_id=type_id)

            rpc.get_notifier('QoSSpecs').info(context,

                                              'qos_specs.associate',

                                              notifier_info)

        except exception.VolumeTypeNotFound as err:

            notifier_err = dict(id=id, error_message=err)

            self._notify_qos_specs_error(context,

                                         'qos_specs.associate',

                                         notifier_err)

            raise webob.exc.HTTPNotFound(explanation=six.text_type(err))

        except exception.QoSSpecsNotFound as err:

            notifier_err = dict(id=id, error_message=err)

            self._notify_qos_specs_error(context,

                                         'qos_specs.associate',

                                         notifier_err)

            raise webob.exc.HTTPNotFound(explanation=six.text_type(err))

        except exception.InvalidVolumeType as err:

            notifier_err = dict(id=id, error_message=err)

            self._notify_qos_specs_error(context,

                                         'qos_specs.associate',

                                         notifier_err)

            self._notify_qos_specs_error(context,

                                         'qos_specs.associate',

                                         notifier_err)

            raise webob.exc.HTTPBadRequest(explanation=six.text_type(err))

        except exception.QoSSpecsAssociateFailed as err:

            notifier_err = dict(id=id, error_message=err)

            self._notify_qos_specs_error(context,

                                         'qos_specs.associate',

                                         notifier_err)

            raise webob.exc.HTTPInternalServerError(

                explanation=six.text_type(err))

        return webob.Response(status_int=202)

**** CubicPower OpenStack Study ****

    def disassociate(self, req, id):

        """Disassociate a qos specs from a volume type."""

        context = req.environ['cinder.context']

        authorize(context)

        type_id = req.params.get('vol_type_id', None)

        if not type_id:

            msg = _('Volume Type id must not be None.')

            notifier_err = dict(id=id, error_message=msg)

            self._notify_qos_specs_error(context,

                                         'qos_specs.delete',

                                         notifier_err)

            raise webob.exc.HTTPBadRequest(explanation=msg)

        LOG.debug("Disassociate qos_spec: %(id)s from type: %(type_id)s" %

                  {'id': id, 'type_id': type_id})

        try:

            qos_specs.disassociate_qos_specs(context, id, type_id)

            notifier_info = dict(id=id, type_id=type_id)

            rpc.get_notifier('QoSSpecs').info(context,

                                              'qos_specs.disassociate',

                                              notifier_info)

        except exception.VolumeTypeNotFound as err:

            notifier_err = dict(id=id, error_message=err)

            self._notify_qos_specs_error(context,

                                         'qos_specs.disassociate',

                                         notifier_err)

            raise webob.exc.HTTPNotFound(explanation=six.text_type(err))

        except exception.QoSSpecsNotFound as err:

            notifier_err = dict(id=id, error_message=err)

            self._notify_qos_specs_error(context,

                                         'qos_specs.disassociate',

                                         notifier_err)

            raise webob.exc.HTTPNotFound(explanation=six.text_type(err))

        except exception.QoSSpecsDisassociateFailed as err:

            notifier_err = dict(id=id, error_message=err)

            self._notify_qos_specs_error(context,

                                         'qos_specs.disassociate',

                                         notifier_err)

            raise webob.exc.HTTPInternalServerError(

                explanation=six.text_type(err))

        return webob.Response(status_int=202)

**** CubicPower OpenStack Study ****

    def disassociate_all(self, req, id):

        """Disassociate a qos specs from all volume types."""

        context = req.environ['cinder.context']

        authorize(context)

        LOG.debug("Disassociate qos_spec: %s from all." % id)

        try:

            qos_specs.disassociate_all(context, id)

            notifier_info = dict(id=id)

            rpc.get_notifier('QoSSpecs').info(context,

                                              'qos_specs.disassociate_all',

                                              notifier_info)

        except exception.QoSSpecsNotFound as err:

            notifier_err = dict(id=id, error_message=err)

            self._notify_qos_specs_error(context,

                                         'qos_specs.disassociate_all',

                                         notifier_err)

            raise webob.exc.HTTPNotFound(explanation=six.text_type(err))

        except exception.QoSSpecsDisassociateFailed as err:

            notifier_err = dict(id=id, error_message=err)

            self._notify_qos_specs_error(context,

                                         'qos_specs.disassociate_all',

                                         notifier_err)

            raise webob.exc.HTTPInternalServerError(

                explanation=six.text_type(err))

        return webob.Response(status_int=202)

**** CubicPower OpenStack Study ****

class Qos_specs_manage(extensions.ExtensionDescriptor):

"""QoS specs support."""

name = "Qos_specs_manage"

alias = "qos-specs"

namespace = "http://docs.openstack.org/volume/ext/qos-specs/api/v1"

updated = "2013-08-02T00:00:00+00:00"

**** CubicPower OpenStack Study ****

    def get_resources(self):

        resources = []

        res = extensions.ResourceExtension(

            Qos_specs_manage.alias,

            QoSSpecsController(),

            member_actions={"associations": "GET",

                            "associate": "GET",

                            "disassociate": "GET",

                            "disassociate_all": "GET",

                            "delete_keys": "PUT"})

        resources.append(res)

        return resources