Add view builder to QoS specs API extension
Add view builder for qos_specs.create(), index(), show() and associations() to in order to make the response more easier to be consumed by client. This patch also: fixed circular reference error when raising HTTP exception. fixed some typo in debug message and removed unused imports. fix bug: # 1219016 Change-Id: I107888e6b4dac8eb5f1b45a87721a7b5efc45632
This commit is contained in:
@@ -21,13 +21,12 @@ import webob
|
|||||||
|
|
||||||
from cinder.api import extensions
|
from cinder.api import extensions
|
||||||
from cinder.api.openstack import wsgi
|
from cinder.api.openstack import wsgi
|
||||||
|
from cinder.api.views import qos_specs as view_qos_specs
|
||||||
from cinder.api import xmlutil
|
from cinder.api import xmlutil
|
||||||
from cinder import db
|
|
||||||
from cinder import exception
|
from cinder import exception
|
||||||
from cinder.openstack.common import log as logging
|
from cinder.openstack.common import log as logging
|
||||||
from cinder.openstack.common.notifier import api as notifier_api
|
from cinder.openstack.common.notifier import api as notifier_api
|
||||||
from cinder.volume import qos_specs
|
from cinder.volume import qos_specs
|
||||||
from cinder.volume import volume_types
|
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
@@ -66,6 +65,8 @@ def _check_specs(context, specs_id):
|
|||||||
class QoSSpecsController(wsgi.Controller):
|
class QoSSpecsController(wsgi.Controller):
|
||||||
"""The volume type extra specs API controller for the OpenStack API."""
|
"""The volume type extra specs API controller for the OpenStack API."""
|
||||||
|
|
||||||
|
_view_builder_class = view_qos_specs.ViewBuilder
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _notify_qos_specs_error(context, method, payload):
|
def _notify_qos_specs_error(context, method, payload):
|
||||||
notifier_api.notify(context,
|
notifier_api.notify(context,
|
||||||
@@ -80,7 +81,7 @@ class QoSSpecsController(wsgi.Controller):
|
|||||||
context = req.environ['cinder.context']
|
context = req.environ['cinder.context']
|
||||||
authorize(context)
|
authorize(context)
|
||||||
specs = qos_specs.get_all_specs(context)
|
specs = qos_specs.get_all_specs(context)
|
||||||
return specs
|
return self._view_builder.summary_list(req, specs)
|
||||||
|
|
||||||
@wsgi.serializers(xml=QoSSpecsTemplate)
|
@wsgi.serializers(xml=QoSSpecsTemplate)
|
||||||
def create(self, req, body=None):
|
def create(self, req, body=None):
|
||||||
@@ -97,8 +98,8 @@ class QoSSpecsController(wsgi.Controller):
|
|||||||
raise webob.exc.HTTPBadRequest(explanation=msg)
|
raise webob.exc.HTTPBadRequest(explanation=msg)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
specs_ref = qos_specs.create(context, name, specs)
|
qos_specs.create(context, name, specs)
|
||||||
qos_specs.get_qos_specs_by_name(context, name)
|
spec = qos_specs.get_qos_specs_by_name(context, name)
|
||||||
notifier_info = dict(name=name, specs=specs)
|
notifier_info = dict(name=name, specs=specs)
|
||||||
notifier_api.notify(context, 'QoSSpecs',
|
notifier_api.notify(context, 'QoSSpecs',
|
||||||
'QoSSpecs.create',
|
'QoSSpecs.create',
|
||||||
@@ -122,7 +123,7 @@ class QoSSpecsController(wsgi.Controller):
|
|||||||
notifier_err)
|
notifier_err)
|
||||||
raise webob.exc.HTTPInternalServerError(explanation=str(err))
|
raise webob.exc.HTTPInternalServerError(explanation=str(err))
|
||||||
|
|
||||||
return body
|
return self._view_builder.detail(req, spec)
|
||||||
|
|
||||||
@wsgi.serializers(xml=QoSSpecsTemplate)
|
@wsgi.serializers(xml=QoSSpecsTemplate)
|
||||||
def update(self, req, id, body=None):
|
def update(self, req, id, body=None):
|
||||||
@@ -166,10 +167,10 @@ class QoSSpecsController(wsgi.Controller):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
spec = qos_specs.get_qos_specs(context, id)
|
spec = qos_specs.get_qos_specs(context, id)
|
||||||
except exception.NotFound:
|
except exception.QoSSpecsNotFound as err:
|
||||||
raise webob.exc.HTTPNotFound()
|
raise webob.exc.HTTPNotFound(explanation=str(err))
|
||||||
|
|
||||||
return spec
|
return self._view_builder.detail(req, spec)
|
||||||
|
|
||||||
def delete(self, req, id):
|
def delete(self, req, id):
|
||||||
"""Deletes an existing qos specs."""
|
"""Deletes an existing qos specs."""
|
||||||
@@ -178,7 +179,8 @@ class QoSSpecsController(wsgi.Controller):
|
|||||||
|
|
||||||
force = req.params.get('force', None)
|
force = req.params.get('force', None)
|
||||||
|
|
||||||
LOG.debug("qos_specs_manage.delete(): id: %s, force: %s" % (id, force))
|
LOG.debug("Delete qos_spec: %(id)s, force: %(force)s" %
|
||||||
|
{'id': id, 'force': force})
|
||||||
|
|
||||||
try:
|
try:
|
||||||
qos_specs.get_qos_specs(context, id)
|
qos_specs.get_qos_specs(context, id)
|
||||||
@@ -187,12 +189,12 @@ class QoSSpecsController(wsgi.Controller):
|
|||||||
notifier_api.notify(context, 'QoSSpecs',
|
notifier_api.notify(context, 'QoSSpecs',
|
||||||
'qos_specs.delete',
|
'qos_specs.delete',
|
||||||
notifier_api.INFO, notifier_info)
|
notifier_api.INFO, notifier_info)
|
||||||
except exception.NotFound as err:
|
except exception.QoSSpecsNotFound as err:
|
||||||
notifier_err = dict(id=id, error_message=str(err))
|
notifier_err = dict(id=id, error_message=str(err))
|
||||||
self._notify_qos_specs_error(context,
|
self._notify_qos_specs_error(context,
|
||||||
'qos_specs.delete',
|
'qos_specs.delete',
|
||||||
notifier_err)
|
notifier_err)
|
||||||
raise webob.exc.HTTPNotFound()
|
raise webob.exc.HTTPNotFound(explanation=str(err))
|
||||||
except exception.QoSSpecsInUse as err:
|
except exception.QoSSpecsInUse as err:
|
||||||
notifier_err = dict(id=id, error_message=str(err))
|
notifier_err = dict(id=id, error_message=str(err))
|
||||||
self._notify_qos_specs_error(context,
|
self._notify_qos_specs_error(context,
|
||||||
@@ -212,7 +214,7 @@ class QoSSpecsController(wsgi.Controller):
|
|||||||
context = req.environ['cinder.context']
|
context = req.environ['cinder.context']
|
||||||
authorize(context)
|
authorize(context)
|
||||||
|
|
||||||
LOG.debug("assocications(): id: %s" % id)
|
LOG.debug("Get associations for qos_spec id: %s" % id)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
associates = qos_specs.get_associations(context, id)
|
associates = qos_specs.get_associations(context, id)
|
||||||
@@ -225,15 +227,15 @@ class QoSSpecsController(wsgi.Controller):
|
|||||||
self._notify_qos_specs_error(context,
|
self._notify_qos_specs_error(context,
|
||||||
'qos_specs.associations',
|
'qos_specs.associations',
|
||||||
notifier_err)
|
notifier_err)
|
||||||
raise webob.exc.HTTPNotFound(explanation=err)
|
raise webob.exc.HTTPNotFound(explanation=str(err))
|
||||||
except exception.CinderException as err:
|
except exception.CinderException as err:
|
||||||
notifier_err = dict(id=id, error_message=str(err))
|
notifier_err = dict(id=id, error_message=str(err))
|
||||||
self._notify_qos_specs_error(context,
|
self._notify_qos_specs_error(context,
|
||||||
'qos_specs.associations',
|
'qos_specs.associations',
|
||||||
notifier_err)
|
notifier_err)
|
||||||
raise webob.exc.HTTPInternalServerError(explanation=err)
|
raise webob.exc.HTTPInternalServerError(explanation=str(err))
|
||||||
|
|
||||||
return associates
|
return self._view_builder.associations(req, associates)
|
||||||
|
|
||||||
def associate(self, req, id):
|
def associate(self, req, id):
|
||||||
"""Associate a qos specs with a volume type."""
|
"""Associate a qos specs with a volume type."""
|
||||||
@@ -249,7 +251,8 @@ class QoSSpecsController(wsgi.Controller):
|
|||||||
'qos_specs.delete',
|
'qos_specs.delete',
|
||||||
notifier_err)
|
notifier_err)
|
||||||
raise webob.exc.HTTPBadRequest(explanation=msg)
|
raise webob.exc.HTTPBadRequest(explanation=msg)
|
||||||
LOG.debug("associcate(): id: %s, type_id: %s" % (id, type_id))
|
LOG.debug("Associate qos_spec: %(id)s with type: %(type_id)s" %
|
||||||
|
{'id': id, 'type_id': type_id})
|
||||||
|
|
||||||
try:
|
try:
|
||||||
qos_specs.get_qos_specs(context, id)
|
qos_specs.get_qos_specs(context, id)
|
||||||
@@ -263,19 +266,19 @@ class QoSSpecsController(wsgi.Controller):
|
|||||||
self._notify_qos_specs_error(context,
|
self._notify_qos_specs_error(context,
|
||||||
'qos_specs.associate',
|
'qos_specs.associate',
|
||||||
notifier_err)
|
notifier_err)
|
||||||
raise webob.exc.HTTPNotFound(explanation=err)
|
raise webob.exc.HTTPNotFound(explanation=str(err))
|
||||||
except exception.QoSSpecsNotFound as err:
|
except exception.QoSSpecsNotFound as err:
|
||||||
notifier_err = dict(id=id, error_message=str(err))
|
notifier_err = dict(id=id, error_message=str(err))
|
||||||
self._notify_qos_specs_error(context,
|
self._notify_qos_specs_error(context,
|
||||||
'qos_specs.associate',
|
'qos_specs.associate',
|
||||||
notifier_err)
|
notifier_err)
|
||||||
raise webob.exc.HTTPNotFound(explanation=err)
|
raise webob.exc.HTTPNotFound(explanation=str(err))
|
||||||
except exception.QoSSpecsAssociateFailed as err:
|
except exception.QoSSpecsAssociateFailed as err:
|
||||||
notifier_err = dict(id=id, error_message=str(err))
|
notifier_err = dict(id=id, error_message=str(err))
|
||||||
self._notify_qos_specs_error(context,
|
self._notify_qos_specs_error(context,
|
||||||
'qos_specs.associate',
|
'qos_specs.associate',
|
||||||
notifier_err)
|
notifier_err)
|
||||||
raise webob.exc.HTTPInternalServerError(explanation=err)
|
raise webob.exc.HTTPInternalServerError(explanation=str(err))
|
||||||
|
|
||||||
return webob.Response(status_int=202)
|
return webob.Response(status_int=202)
|
||||||
|
|
||||||
@@ -293,7 +296,8 @@ class QoSSpecsController(wsgi.Controller):
|
|||||||
'qos_specs.delete',
|
'qos_specs.delete',
|
||||||
notifier_err)
|
notifier_err)
|
||||||
raise webob.exc.HTTPBadRequest(explanation=msg)
|
raise webob.exc.HTTPBadRequest(explanation=msg)
|
||||||
LOG.debug("disassocicate(): id: %s, type_id: %s" % (id, type_id))
|
LOG.debug("Disassociate qos_spec: %(id)s from type: %(type_id)s" %
|
||||||
|
{'id': id, 'type_id': type_id})
|
||||||
|
|
||||||
try:
|
try:
|
||||||
qos_specs.get_qos_specs(context, id)
|
qos_specs.get_qos_specs(context, id)
|
||||||
@@ -307,19 +311,19 @@ class QoSSpecsController(wsgi.Controller):
|
|||||||
self._notify_qos_specs_error(context,
|
self._notify_qos_specs_error(context,
|
||||||
'qos_specs.disassociate',
|
'qos_specs.disassociate',
|
||||||
notifier_err)
|
notifier_err)
|
||||||
raise webob.exc.HTTPNotFound(explanation=err)
|
raise webob.exc.HTTPNotFound(explanation=str(err))
|
||||||
except exception.QoSSpecsNotFound as err:
|
except exception.QoSSpecsNotFound as err:
|
||||||
notifier_err = dict(id=id, error_message=str(err))
|
notifier_err = dict(id=id, error_message=str(err))
|
||||||
self._notify_qos_specs_error(context,
|
self._notify_qos_specs_error(context,
|
||||||
'qos_specs.disassociate',
|
'qos_specs.disassociate',
|
||||||
notifier_err)
|
notifier_err)
|
||||||
raise webob.exc.HTTPNotFound(explanation=err)
|
raise webob.exc.HTTPNotFound(explanation=str(err))
|
||||||
except exception.QoSSpecsDisassociateFailed as err:
|
except exception.QoSSpecsDisassociateFailed as err:
|
||||||
notifier_err = dict(id=id, error_message=str(err))
|
notifier_err = dict(id=id, error_message=str(err))
|
||||||
self._notify_qos_specs_error(context,
|
self._notify_qos_specs_error(context,
|
||||||
'qos_specs.disassociate',
|
'qos_specs.disassociate',
|
||||||
notifier_err)
|
notifier_err)
|
||||||
raise webob.exc.HTTPInternalServerError(explanation=err)
|
raise webob.exc.HTTPInternalServerError(explanation=str(err))
|
||||||
|
|
||||||
return webob.Response(status_int=202)
|
return webob.Response(status_int=202)
|
||||||
|
|
||||||
@@ -328,7 +332,7 @@ class QoSSpecsController(wsgi.Controller):
|
|||||||
context = req.environ['cinder.context']
|
context = req.environ['cinder.context']
|
||||||
authorize(context)
|
authorize(context)
|
||||||
|
|
||||||
LOG.debug("disassocicate_all(): id: %s" % id)
|
LOG.debug("Disassociate qos_spec: %s from all." % id)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
qos_specs.get_qos_specs(context, id)
|
qos_specs.get_qos_specs(context, id)
|
||||||
@@ -342,13 +346,13 @@ class QoSSpecsController(wsgi.Controller):
|
|||||||
self._notify_qos_specs_error(context,
|
self._notify_qos_specs_error(context,
|
||||||
'qos_specs.disassociate_all',
|
'qos_specs.disassociate_all',
|
||||||
notifier_err)
|
notifier_err)
|
||||||
raise webob.exc.HTTPNotFound(explanation=err)
|
raise webob.exc.HTTPNotFound(explanation=str(err))
|
||||||
except exception.QoSSpecsDisassociateFailed as err:
|
except exception.QoSSpecsDisassociateFailed as err:
|
||||||
notifier_err = dict(id=id, error_message=str(err))
|
notifier_err = dict(id=id, error_message=str(err))
|
||||||
self._notify_qos_specs_error(context,
|
self._notify_qos_specs_error(context,
|
||||||
'qos_specs.disassociate_all',
|
'qos_specs.disassociate_all',
|
||||||
notifier_err)
|
notifier_err)
|
||||||
raise webob.exc.HTTPInternalServerError(explanation=err)
|
raise webob.exc.HTTPInternalServerError(explanation=str(err))
|
||||||
|
|
||||||
return webob.Response(status_int=202)
|
return webob.Response(status_int=202)
|
||||||
|
|
||||||
|
|||||||
64
cinder/api/views/qos_specs.py
Normal file
64
cinder/api/views/qos_specs.py
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
# Copyright (C) 2013 eBay Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
from cinder.api import common
|
||||||
|
from cinder.openstack.common import log as logging
|
||||||
|
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class ViewBuilder(common.ViewBuilder):
|
||||||
|
"""Model QoS specs API responses as a python dictionary."""
|
||||||
|
|
||||||
|
_collection_name = "qos_specs"
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
"""Initialize view builder."""
|
||||||
|
super(ViewBuilder, self).__init__()
|
||||||
|
|
||||||
|
def summary_list(self, request, qos_specs):
|
||||||
|
"""Show a list of qos_specs without many details."""
|
||||||
|
return self._list_view(self.detail, request, qos_specs)
|
||||||
|
|
||||||
|
def summary(self, request, qos_spec):
|
||||||
|
"""Generic, non-detailed view of a qos_specs."""
|
||||||
|
return {
|
||||||
|
'qos_specs': qos_spec,
|
||||||
|
'links': self._get_links(request,
|
||||||
|
qos_spec['id']),
|
||||||
|
}
|
||||||
|
|
||||||
|
def detail(self, request, qos_spec):
|
||||||
|
"""Detailed view of a single qos_spec."""
|
||||||
|
#TODO(zhiteng) Add associations to detailed view
|
||||||
|
return {
|
||||||
|
'qos_specs': qos_spec,
|
||||||
|
'links': self._get_links(request,
|
||||||
|
qos_spec['id']),
|
||||||
|
}
|
||||||
|
|
||||||
|
def associations(self, request, associates):
|
||||||
|
"""View of qos specs associations."""
|
||||||
|
return {
|
||||||
|
'qos_associations': associates
|
||||||
|
}
|
||||||
|
|
||||||
|
def _list_view(self, func, request, qos_specs):
|
||||||
|
"""Provide a view for a list of qos_specs."""
|
||||||
|
specs_list = [func(request, specs)['qos_specs'] for specs in qos_specs]
|
||||||
|
specs_dict = dict(qos_specs=specs_list)
|
||||||
|
|
||||||
|
return specs_dict
|
||||||
@@ -2022,7 +2022,7 @@ def qos_specs_create(context, values):
|
|||||||
# the name of QoS specs
|
# the name of QoS specs
|
||||||
root['key'] = 'QoS_Specs_Name'
|
root['key'] = 'QoS_Specs_Name'
|
||||||
root['value'] = values['name']
|
root['value'] = values['name']
|
||||||
LOG.debug("qos_specs_create(): root %s", root)
|
LOG.debug("DB qos_specs_create(): root %s", root)
|
||||||
specs_root.update(root)
|
specs_root.update(root)
|
||||||
specs_root.save(session=session)
|
specs_root.save(session=session)
|
||||||
|
|
||||||
@@ -2036,7 +2036,7 @@ def qos_specs_create(context, values):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise db_exc.DBError(e)
|
raise db_exc.DBError(e)
|
||||||
|
|
||||||
return specs_root
|
return dict(id=specs_root.id, name=specs_root.value)
|
||||||
|
|
||||||
|
|
||||||
@require_admin_context
|
@require_admin_context
|
||||||
@@ -2078,21 +2078,25 @@ def _dict_with_children_specs(specs):
|
|||||||
|
|
||||||
|
|
||||||
def _dict_with_qos_specs(rows):
|
def _dict_with_qos_specs(rows):
|
||||||
"""Convert qos specs query results to dict with name as key.
|
"""Convert qos specs query results to list.
|
||||||
|
|
||||||
Qos specs query results are a list of quality_of_service_specs refs,
|
Qos specs query results are a list of quality_of_service_specs refs,
|
||||||
some are root entry of a qos specs (key == 'QoS_Specs_Name') and the
|
some are root entry of a qos specs (key == 'QoS_Specs_Name') and the
|
||||||
rest are children entry, a.k.a detailed specs for a qos specs. This
|
rest are children entry, a.k.a detailed specs for a qos specs. This
|
||||||
funtion converts query results to a dict using spec name as key.
|
function converts query results to a dict using spec name as key.
|
||||||
"""
|
"""
|
||||||
result = {}
|
result = []
|
||||||
for row in rows:
|
for row in rows:
|
||||||
if row['key'] == 'QoS_Specs_Name':
|
if row['key'] == 'QoS_Specs_Name':
|
||||||
result[row['value']] = dict(id=row['id'])
|
member = {}
|
||||||
|
member['name'] = row['value']
|
||||||
|
member.update(dict(id=row['id']))
|
||||||
if row.specs:
|
if row.specs:
|
||||||
spec_dict = _dict_with_children_specs(row.specs)
|
spec_dict = _dict_with_children_specs(row.specs)
|
||||||
result[row['value']].update(spec_dict)
|
member.update(dict(consumer=spec_dict['consumer']))
|
||||||
|
del spec_dict['consumer']
|
||||||
|
member.update(dict(specs=spec_dict))
|
||||||
|
result.append(member)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
@@ -2100,25 +2104,35 @@ def _dict_with_qos_specs(rows):
|
|||||||
def qos_specs_get(context, qos_specs_id, inactive=False):
|
def qos_specs_get(context, qos_specs_id, inactive=False):
|
||||||
rows = _qos_specs_get_ref(context, qos_specs_id, None, inactive)
|
rows = _qos_specs_get_ref(context, qos_specs_id, None, inactive)
|
||||||
|
|
||||||
return _dict_with_qos_specs(rows)
|
return _dict_with_qos_specs(rows)[0]
|
||||||
|
|
||||||
|
|
||||||
@require_admin_context
|
@require_admin_context
|
||||||
def qos_specs_get_all(context, inactive=False, filters=None):
|
def qos_specs_get_all(context, inactive=False, filters=None):
|
||||||
"""Returns dicts describing all qos_specs.
|
"""Returns a list of all qos_specs.
|
||||||
|
|
||||||
Results is like:
|
Results is like:
|
||||||
{'qos-spec-1': {'id': SPECS-UUID,
|
[{
|
||||||
|
'id': SPECS-UUID,
|
||||||
|
'name': 'qos_spec-1',
|
||||||
|
'consumer': 'back-end',
|
||||||
|
'specs': {
|
||||||
'key1': 'value1',
|
'key1': 'value1',
|
||||||
'key2': 'value2',
|
'key2': 'value2',
|
||||||
...
|
...
|
||||||
'consumer': 'back-end'}
|
|
||||||
'qos-spec-2': {'id': SPECS-UUID,
|
|
||||||
'key1': 'value1',
|
|
||||||
'key2': 'value2',
|
|
||||||
...
|
|
||||||
'consumer': 'back-end'}
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': SPECS-UUID,
|
||||||
|
'name': 'qos_spec-2',
|
||||||
|
'consumer': 'front-end',
|
||||||
|
'specs': {
|
||||||
|
'key1': 'value1',
|
||||||
|
'key2': 'value2',
|
||||||
|
...
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]
|
||||||
"""
|
"""
|
||||||
filters = filters or {}
|
filters = filters or {}
|
||||||
#TODO(zhiteng) Add filters for 'consumer'
|
#TODO(zhiteng) Add filters for 'consumer'
|
||||||
@@ -2135,7 +2149,7 @@ def qos_specs_get_all(context, inactive=False, filters=None):
|
|||||||
def qos_specs_get_by_name(context, name, inactive=False):
|
def qos_specs_get_by_name(context, name, inactive=False):
|
||||||
rows = _qos_specs_get_by_name(context, name, None, inactive)
|
rows = _qos_specs_get_by_name(context, name, None, inactive)
|
||||||
|
|
||||||
return _dict_with_qos_specs(rows)
|
return _dict_with_qos_specs(rows)[0]
|
||||||
|
|
||||||
|
|
||||||
@require_admin_context
|
@require_admin_context
|
||||||
@@ -2148,9 +2162,7 @@ def qos_specs_associations_get(context, qos_specs_id):
|
|||||||
extend qos specs association to other entities, such as volumes,
|
extend qos specs association to other entities, such as volumes,
|
||||||
sometime in future.
|
sometime in future.
|
||||||
"""
|
"""
|
||||||
rows = _qos_specs_get_ref(context, qos_specs_id, None)
|
_qos_specs_get_ref(context, qos_specs_id, None)
|
||||||
if not rows:
|
|
||||||
raise exception.QoSSpecsNotFound(specs_id=qos_specs_id)
|
|
||||||
|
|
||||||
return volume_type_qos_associations_get(context, qos_specs_id)
|
return volume_type_qos_associations_get(context, qos_specs_id)
|
||||||
|
|
||||||
|
|||||||
@@ -26,32 +26,37 @@ from cinder.volume import qos_specs
|
|||||||
|
|
||||||
|
|
||||||
def stub_qos_specs(id):
|
def stub_qos_specs(id):
|
||||||
|
res = dict(name='qos_specs_' + str(id))
|
||||||
|
res.update(dict(consumer='back-end'))
|
||||||
|
res.update(dict(id=str(id)))
|
||||||
specs = {"key1": "value1",
|
specs = {"key1": "value1",
|
||||||
"key2": "value2",
|
"key2": "value2",
|
||||||
"key3": "value3",
|
"key3": "value3",
|
||||||
"key4": "value4",
|
"key4": "value4",
|
||||||
"key5": "value5"}
|
"key5": "value5"}
|
||||||
specs.update(dict(id=str(id)))
|
res.update(dict(specs=specs))
|
||||||
return specs
|
return res
|
||||||
|
|
||||||
|
|
||||||
def stub_qos_associates(id):
|
def stub_qos_associates(id):
|
||||||
return {str(id): {'FakeVolTypeName': 'FakeVolTypeID'}}
|
return [{
|
||||||
|
'association_type': 'volume_type',
|
||||||
|
'name': 'FakeVolTypeName',
|
||||||
|
'id': 'FakeVolTypeID'}]
|
||||||
|
|
||||||
|
|
||||||
def return_qos_specs_get_all(context):
|
def return_qos_specs_get_all(context):
|
||||||
return dict(
|
return [
|
||||||
qos_specs_1=stub_qos_specs(1),
|
stub_qos_specs(1),
|
||||||
qos_specs_2=stub_qos_specs(2),
|
stub_qos_specs(2),
|
||||||
qos_specs_3=stub_qos_specs(3)
|
stub_qos_specs(3),
|
||||||
)
|
]
|
||||||
|
|
||||||
|
|
||||||
def return_qos_specs_get_qos_specs(context, id):
|
def return_qos_specs_get_qos_specs(context, id):
|
||||||
if id == "777":
|
if id == "777":
|
||||||
raise exception.QoSSpecsNotFound(specs_id=id)
|
raise exception.QoSSpecsNotFound(specs_id=id)
|
||||||
name = 'qos_specs_%s' % id
|
return stub_qos_specs(int(id))
|
||||||
return {name: stub_qos_specs(int(id))}
|
|
||||||
|
|
||||||
|
|
||||||
def return_qos_specs_delete(context, id, force):
|
def return_qos_specs_delete(context, id, force):
|
||||||
@@ -142,14 +147,16 @@ class QoSSpecManageApiTest(test.TestCase):
|
|||||||
return_qos_specs_get_all)
|
return_qos_specs_get_all)
|
||||||
|
|
||||||
req = fakes.HTTPRequest.blank('/v2/fake/qos-specs')
|
req = fakes.HTTPRequest.blank('/v2/fake/qos-specs')
|
||||||
res_dict = self.controller.index(req)
|
res = self.controller.index(req)
|
||||||
|
|
||||||
self.assertEqual(3, len(res_dict.keys()))
|
self.assertEqual(3, len(res['qos_specs']))
|
||||||
|
|
||||||
|
names = set()
|
||||||
|
for item in res['qos_specs']:
|
||||||
|
self.assertEqual('value1', item['specs']['key1'])
|
||||||
|
names.add(item['name'])
|
||||||
expected_names = ['qos_specs_1', 'qos_specs_2', 'qos_specs_3']
|
expected_names = ['qos_specs_1', 'qos_specs_2', 'qos_specs_3']
|
||||||
self.assertEqual(set(res_dict.keys()), set(expected_names))
|
self.assertEqual(names, set(expected_names))
|
||||||
for key in res_dict.keys():
|
|
||||||
self.assertEqual('value1', res_dict[key]['key1'])
|
|
||||||
|
|
||||||
def test_qos_specs_delete(self):
|
def test_qos_specs_delete(self):
|
||||||
self.stubs.Set(qos_specs, 'get_qos_specs',
|
self.stubs.Set(qos_specs, 'get_qos_specs',
|
||||||
@@ -212,7 +219,6 @@ class QoSSpecManageApiTest(test.TestCase):
|
|||||||
res_dict = self.controller.create(req, body)
|
res_dict = self.controller.create(req, body)
|
||||||
|
|
||||||
self.assertEquals(len(test_notifier.NOTIFICATIONS), 1)
|
self.assertEquals(len(test_notifier.NOTIFICATIONS), 1)
|
||||||
self.assertEqual(1, len(res_dict))
|
|
||||||
self.assertEqual('qos_specs_1', res_dict['qos_specs']['name'])
|
self.assertEqual('qos_specs_1', res_dict['qos_specs']['name'])
|
||||||
|
|
||||||
def test_create_conflict(self):
|
def test_create_conflict(self):
|
||||||
@@ -318,8 +324,8 @@ class QoSSpecManageApiTest(test.TestCase):
|
|||||||
req = fakes.HTTPRequest.blank('/v2/fake/qos-specs/1')
|
req = fakes.HTTPRequest.blank('/v2/fake/qos-specs/1')
|
||||||
res_dict = self.controller.show(req, '1')
|
res_dict = self.controller.show(req, '1')
|
||||||
|
|
||||||
self.assertEqual(1, len(res_dict))
|
self.assertEqual('1', res_dict['qos_specs']['id'])
|
||||||
self.assertEqual('1', res_dict['qos_specs_1']['id'])
|
self.assertEqual('qos_specs_1', res_dict['qos_specs']['name'])
|
||||||
|
|
||||||
def test_get_associations(self):
|
def test_get_associations(self):
|
||||||
self.stubs.Set(qos_specs, 'get_associations',
|
self.stubs.Set(qos_specs, 'get_associations',
|
||||||
@@ -329,10 +335,10 @@ class QoSSpecManageApiTest(test.TestCase):
|
|||||||
'/v2/fake/qos-specs/1/associations')
|
'/v2/fake/qos-specs/1/associations')
|
||||||
res = self.controller.associations(req, '1')
|
res = self.controller.associations(req, '1')
|
||||||
|
|
||||||
self.assertEqual('1', res.keys()[0])
|
self.assertEqual('FakeVolTypeName',
|
||||||
self.assertEqual('FakeVolTypeName', res['1'].keys()[0])
|
res['qos_associations'][0]['name'])
|
||||||
self.assertEqual('FakeVolTypeID',
|
self.assertEqual('FakeVolTypeID',
|
||||||
res['1']['FakeVolTypeName'])
|
res['qos_associations'][0]['id'])
|
||||||
|
|
||||||
def test_get_associations_not_found(self):
|
def test_get_associations_not_found(self):
|
||||||
self.stubs.Set(qos_specs, 'get_associations',
|
self.stubs.Set(qos_specs, 'get_associations',
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ class QualityOfServiceSpecsTableTestCase(test.TestCase):
|
|||||||
|
|
||||||
specs_id = self._create_qos_specs('NewName')
|
specs_id = self._create_qos_specs('NewName')
|
||||||
query_id = db.qos_specs_get_by_name(
|
query_id = db.qos_specs_get_by_name(
|
||||||
self.ctxt, 'NewName')['NewName']['id']
|
self.ctxt, 'NewName')['id']
|
||||||
self.assertEquals(specs_id, query_id)
|
self.assertEquals(specs_id, query_id)
|
||||||
|
|
||||||
def test_qos_specs_get(self):
|
def test_qos_specs_get(self):
|
||||||
@@ -81,8 +81,9 @@ class QualityOfServiceSpecsTableTestCase(test.TestCase):
|
|||||||
db.qos_specs_get, self.ctxt, fake_id)
|
db.qos_specs_get, self.ctxt, fake_id)
|
||||||
|
|
||||||
specs = db.qos_specs_get(self.ctxt, specs_id)
|
specs = db.qos_specs_get(self.ctxt, specs_id)
|
||||||
value.update(dict(id=specs_id))
|
expected = dict(name='Name1', id=specs_id, consumer='front-end')
|
||||||
expected = dict(Name1=value)
|
del value['consumer']
|
||||||
|
expected.update(dict(specs=value))
|
||||||
self.assertDictMatch(specs, expected)
|
self.assertDictMatch(specs, expected)
|
||||||
|
|
||||||
def test_qos_specs_get_all(self):
|
def test_qos_specs_get_all(self):
|
||||||
@@ -101,12 +102,18 @@ class QualityOfServiceSpecsTableTestCase(test.TestCase):
|
|||||||
self.assertEquals(len(specs), 3,
|
self.assertEquals(len(specs), 3,
|
||||||
"Unexpected number of qos specs records")
|
"Unexpected number of qos specs records")
|
||||||
|
|
||||||
value1.update({'id': spec_id1})
|
expected1 = dict(name='Name1', id=spec_id1, consumer='front-end')
|
||||||
value2.update({'id': spec_id2})
|
expected2 = dict(name='Name2', id=spec_id2, consumer='back-end')
|
||||||
value3.update({'id': spec_id3})
|
expected3 = dict(name='Name3', id=spec_id3, consumer='back-end')
|
||||||
self.assertDictMatch(specs['Name1'], value1)
|
del value1['consumer']
|
||||||
self.assertDictMatch(specs['Name2'], value2)
|
del value2['consumer']
|
||||||
self.assertDictMatch(specs['Name3'], value3)
|
del value3['consumer']
|
||||||
|
expected1.update(dict(specs=value1))
|
||||||
|
expected2.update(dict(specs=value2))
|
||||||
|
expected3.update(dict(specs=value3))
|
||||||
|
self.assertIn(expected1, specs)
|
||||||
|
self.assertIn(expected2, specs)
|
||||||
|
self.assertIn(expected3, specs)
|
||||||
|
|
||||||
def test_qos_specs_get_by_name(self):
|
def test_qos_specs_get_by_name(self):
|
||||||
name = str(int(time.time()))
|
name = str(int(time.time()))
|
||||||
@@ -114,8 +121,11 @@ class QualityOfServiceSpecsTableTestCase(test.TestCase):
|
|||||||
foo='Foo', bar='Bar')
|
foo='Foo', bar='Bar')
|
||||||
specs_id = self._create_qos_specs(name, value)
|
specs_id = self._create_qos_specs(name, value)
|
||||||
specs = db.qos_specs_get_by_name(self.ctxt, name)
|
specs = db.qos_specs_get_by_name(self.ctxt, name)
|
||||||
value.update(dict(id=specs_id))
|
del value['consumer']
|
||||||
expected = {name: value}
|
expected = {'name': name,
|
||||||
|
'id': specs_id,
|
||||||
|
'consumer': 'front-end',
|
||||||
|
'specs': value}
|
||||||
self.assertDictMatch(specs, expected)
|
self.assertDictMatch(specs, expected)
|
||||||
|
|
||||||
def test_qos_specs_delete(self):
|
def test_qos_specs_delete(self):
|
||||||
@@ -200,5 +210,5 @@ class QualityOfServiceSpecsTableTestCase(test.TestCase):
|
|||||||
self.ctxt, 'Fake-UUID', value)
|
self.ctxt, 'Fake-UUID', value)
|
||||||
db.qos_specs_update(self.ctxt, specs_id, value)
|
db.qos_specs_update(self.ctxt, specs_id, value)
|
||||||
specs = db.qos_specs_get(self.ctxt, specs_id)
|
specs = db.qos_specs_get(self.ctxt, specs_id)
|
||||||
self.assertEqual(specs[name]['key2'], 'new_value2')
|
self.assertEqual(specs['specs']['key2'], 'new_value2')
|
||||||
self.assertEqual(specs[name]['key3'], 'value3')
|
self.assertEqual(specs['specs']['key3'], 'value3')
|
||||||
|
|||||||
@@ -66,17 +66,16 @@ class QoSSpecsTestCase(test.TestCase):
|
|||||||
'key3': 'value3'}
|
'key3': 'value3'}
|
||||||
ref = qos_specs.create(self.ctxt, 'FakeName', input)
|
ref = qos_specs.create(self.ctxt, 'FakeName', input)
|
||||||
specs = qos_specs.get_qos_specs(self.ctxt, ref['id'])
|
specs = qos_specs.get_qos_specs(self.ctxt, ref['id'])
|
||||||
input.update(dict(consumer='back-end'))
|
expected = (dict(consumer='back-end'))
|
||||||
input.update(dict(id=ref['id']))
|
expected.update(dict(id=ref['id']))
|
||||||
expected = {'FakeName': input}
|
expected.update(dict(name='FakeName'))
|
||||||
|
del input['consumer']
|
||||||
|
expected.update(dict(specs=input))
|
||||||
self.assertDictMatch(specs, expected)
|
self.assertDictMatch(specs, expected)
|
||||||
|
|
||||||
self.stubs.Set(db, 'qos_specs_create',
|
self.stubs.Set(db, 'qos_specs_create',
|
||||||
fake_db_qos_specs_create)
|
fake_db_qos_specs_create)
|
||||||
|
|
||||||
# Restore input back to original state
|
|
||||||
del input['id']
|
|
||||||
del input['consumer']
|
|
||||||
# qos specs must have unique name
|
# qos specs must have unique name
|
||||||
self.assertRaises(exception.QoSSpecsExists,
|
self.assertRaises(exception.QoSSpecsExists,
|
||||||
qos_specs.create, self.ctxt, 'DupQoSName', input)
|
qos_specs.create, self.ctxt, 'DupQoSName', input)
|
||||||
@@ -101,7 +100,7 @@ class QoSSpecsTestCase(test.TestCase):
|
|||||||
self.assertRaises(exception.InvalidQoSSpecs,
|
self.assertRaises(exception.InvalidQoSSpecs,
|
||||||
qos_specs.update, self.ctxt, 'fake_id', input)
|
qos_specs.update, self.ctxt, 'fake_id', input)
|
||||||
|
|
||||||
del input['consumer']
|
input['consumer'] = 'front-end'
|
||||||
# qos specs must exists
|
# qos specs must exists
|
||||||
self.assertRaises(exception.QoSSpecsNotFound,
|
self.assertRaises(exception.QoSSpecsNotFound,
|
||||||
qos_specs.update, self.ctxt, 'fake_id', input)
|
qos_specs.update, self.ctxt, 'fake_id', input)
|
||||||
@@ -111,8 +110,8 @@ class QoSSpecsTestCase(test.TestCase):
|
|||||||
{'key1': 'newvalue1',
|
{'key1': 'newvalue1',
|
||||||
'key2': 'value2'})
|
'key2': 'value2'})
|
||||||
specs = qos_specs.get_qos_specs(self.ctxt, specs_id)
|
specs = qos_specs.get_qos_specs(self.ctxt, specs_id)
|
||||||
self.assertEqual(specs['Name']['key1'], 'newvalue1')
|
self.assertEqual(specs['specs']['key1'], 'newvalue1')
|
||||||
self.assertEqual(specs['Name']['key2'], 'value2')
|
self.assertEqual(specs['specs']['key2'], 'value2')
|
||||||
|
|
||||||
self.stubs.Set(db, 'qos_specs_update', fake_db_update)
|
self.stubs.Set(db, 'qos_specs_update', fake_db_update)
|
||||||
self.assertRaises(exception.QoSSpecsUpdateFailed,
|
self.assertRaises(exception.QoSSpecsUpdateFailed,
|
||||||
@@ -155,10 +154,15 @@ class QoSSpecsTestCase(test.TestCase):
|
|||||||
|
|
||||||
self.stubs.Set(db, 'qos_specs_associations_get',
|
self.stubs.Set(db, 'qos_specs_associations_get',
|
||||||
fake_db_associate_get)
|
fake_db_associate_get)
|
||||||
expected = {'specs-id': {'type-1': 'id-1',
|
expected1 = {'association_type': 'volume_type',
|
||||||
'type-2': 'id-2'}}
|
'name': 'type-1',
|
||||||
|
'id': 'id-1'}
|
||||||
|
expected2 = {'association_type': 'volume_type',
|
||||||
|
'name': 'type-2',
|
||||||
|
'id': 'id-2'}
|
||||||
res = qos_specs.get_associations(self.ctxt, 'specs-id')
|
res = qos_specs.get_associations(self.ctxt, 'specs-id')
|
||||||
self.assertDictMatch(res, expected)
|
self.assertIn(expected1, res)
|
||||||
|
self.assertIn(expected2, res)
|
||||||
|
|
||||||
self.assertRaises(exception.CinderException,
|
self.assertRaises(exception.CinderException,
|
||||||
qos_specs.get_associations, self.ctxt,
|
qos_specs.get_associations, self.ctxt,
|
||||||
@@ -178,9 +182,9 @@ class QoSSpecsTestCase(test.TestCase):
|
|||||||
qos_specs.associate_qos_with_type(self.ctxt, specs_id,
|
qos_specs.associate_qos_with_type(self.ctxt, specs_id,
|
||||||
type_ref['id'])
|
type_ref['id'])
|
||||||
res = qos_specs.get_associations(self.ctxt, specs_id)
|
res = qos_specs.get_associations(self.ctxt, specs_id)
|
||||||
self.assertEquals(len(res[specs_id].keys()), 1)
|
self.assertEquals(len(res), 1)
|
||||||
self.assertIn('TypeName', res[specs_id].keys())
|
self.assertEquals('TypeName', res[0]['name'])
|
||||||
self.assertIn(type_ref['id'], res[specs_id].values())
|
self.assertEquals(type_ref['id'], res[0]['id'])
|
||||||
|
|
||||||
self.stubs.Set(db, 'qos_specs_associate',
|
self.stubs.Set(db, 'qos_specs_associate',
|
||||||
fake_db_associate)
|
fake_db_associate)
|
||||||
@@ -205,11 +209,11 @@ class QoSSpecsTestCase(test.TestCase):
|
|||||||
qos_specs.associate_qos_with_type(self.ctxt, specs_id,
|
qos_specs.associate_qos_with_type(self.ctxt, specs_id,
|
||||||
type_ref['id'])
|
type_ref['id'])
|
||||||
res = qos_specs.get_associations(self.ctxt, specs_id)
|
res = qos_specs.get_associations(self.ctxt, specs_id)
|
||||||
self.assertEquals(len(res[specs_id].keys()), 1)
|
self.assertEquals(len(res), 1)
|
||||||
|
|
||||||
qos_specs.disassociate_qos_specs(self.ctxt, specs_id, type_ref['id'])
|
qos_specs.disassociate_qos_specs(self.ctxt, specs_id, type_ref['id'])
|
||||||
res = qos_specs.get_associations(self.ctxt, specs_id)
|
res = qos_specs.get_associations(self.ctxt, specs_id)
|
||||||
self.assertEquals(len(res[specs_id].keys()), 0)
|
self.assertEquals(len(res), 0)
|
||||||
|
|
||||||
self.stubs.Set(db, 'qos_specs_disassociate',
|
self.stubs.Set(db, 'qos_specs_disassociate',
|
||||||
fake_db_disassociate)
|
fake_db_disassociate)
|
||||||
@@ -235,11 +239,11 @@ class QoSSpecsTestCase(test.TestCase):
|
|||||||
qos_specs.associate_qos_with_type(self.ctxt, specs_id,
|
qos_specs.associate_qos_with_type(self.ctxt, specs_id,
|
||||||
type2_ref['id'])
|
type2_ref['id'])
|
||||||
res = qos_specs.get_associations(self.ctxt, specs_id)
|
res = qos_specs.get_associations(self.ctxt, specs_id)
|
||||||
self.assertEquals(len(res[specs_id].keys()), 2)
|
self.assertEquals(len(res), 2)
|
||||||
|
|
||||||
qos_specs.disassociate_all(self.ctxt, specs_id)
|
qos_specs.disassociate_all(self.ctxt, specs_id)
|
||||||
res = qos_specs.get_associations(self.ctxt, specs_id)
|
res = qos_specs.get_associations(self.ctxt, specs_id)
|
||||||
self.assertEquals(len(res[specs_id].keys()), 0)
|
self.assertEquals(len(res), 0)
|
||||||
|
|
||||||
self.stubs.Set(db, 'qos_specs_disassociate_all',
|
self.stubs.Set(db, 'qos_specs_disassociate_all',
|
||||||
fake_db_disassociate_all)
|
fake_db_disassociate_all)
|
||||||
@@ -250,31 +254,41 @@ class QoSSpecsTestCase(test.TestCase):
|
|||||||
def test_get_all_specs(self):
|
def test_get_all_specs(self):
|
||||||
input = {'key1': 'value1',
|
input = {'key1': 'value1',
|
||||||
'key2': 'value2',
|
'key2': 'value2',
|
||||||
'key3': 'value3'}
|
'key3': 'value3',
|
||||||
|
'consumer': 'both'}
|
||||||
specs_id1 = self._create_qos_specs('Specs1', input)
|
specs_id1 = self._create_qos_specs('Specs1', input)
|
||||||
input.update({'key4': 'value4'})
|
input.update({'key4': 'value4'})
|
||||||
specs_id2 = self._create_qos_specs('Specs2', input)
|
specs_id2 = self._create_qos_specs('Specs2', input)
|
||||||
|
|
||||||
expected = {'Specs1': {'key1': 'value1',
|
expected1 = {
|
||||||
'id': specs_id1,
|
'id': specs_id1,
|
||||||
|
'name': 'Specs1',
|
||||||
|
'consumer': 'both',
|
||||||
|
'specs': {'key1': 'value1',
|
||||||
'key2': 'value2',
|
'key2': 'value2',
|
||||||
'key3': 'value3'},
|
'key3': 'value3'}}
|
||||||
'Specs2': {'key1': 'value1',
|
expected2 = {
|
||||||
'id': specs_id2,
|
'id': specs_id2,
|
||||||
|
'name': 'Specs2',
|
||||||
|
'consumer': 'both',
|
||||||
|
'specs': {'key1': 'value1',
|
||||||
'key2': 'value2',
|
'key2': 'value2',
|
||||||
'key3': 'value3',
|
'key3': 'value3',
|
||||||
'key4': 'value4'}}
|
'key4': 'value4'}}
|
||||||
res = qos_specs.get_all_specs(self.ctxt)
|
res = qos_specs.get_all_specs(self.ctxt)
|
||||||
self.assertDictMatch(expected, res)
|
self.assertEqual(len(res), 2)
|
||||||
|
self.assertIn(expected1, res)
|
||||||
|
self.assertIn(expected2, res)
|
||||||
|
|
||||||
def test_get_qos_specs(self):
|
def test_get_qos_specs(self):
|
||||||
one_time_value = str(int(time.time()))
|
one_time_value = str(int(time.time()))
|
||||||
input = {'key1': one_time_value,
|
input = {'key1': one_time_value,
|
||||||
'key2': 'value2',
|
'key2': 'value2',
|
||||||
'key3': 'value3'}
|
'key3': 'value3',
|
||||||
|
'consumer': 'both'}
|
||||||
id = self._create_qos_specs('Specs1', input)
|
id = self._create_qos_specs('Specs1', input)
|
||||||
specs = qos_specs.get_qos_specs(self.ctxt, id)
|
specs = qos_specs.get_qos_specs(self.ctxt, id)
|
||||||
self.assertEquals(specs['Specs1']['key1'], one_time_value)
|
self.assertEquals(specs['specs']['key1'], one_time_value)
|
||||||
|
|
||||||
self.assertRaises(exception.InvalidQoSSpecs,
|
self.assertRaises(exception.InvalidQoSSpecs,
|
||||||
qos_specs.get_qos_specs, self.ctxt, None)
|
qos_specs.get_qos_specs, self.ctxt, None)
|
||||||
@@ -283,11 +297,12 @@ class QoSSpecsTestCase(test.TestCase):
|
|||||||
one_time_value = str(int(time.time()))
|
one_time_value = str(int(time.time()))
|
||||||
input = {'key1': one_time_value,
|
input = {'key1': one_time_value,
|
||||||
'key2': 'value2',
|
'key2': 'value2',
|
||||||
'key3': 'value3'}
|
'key3': 'value3',
|
||||||
|
'consumer': 'back-end'}
|
||||||
id = self._create_qos_specs(one_time_value, input)
|
id = self._create_qos_specs(one_time_value, input)
|
||||||
specs = qos_specs.get_qos_specs_by_name(self.ctxt,
|
specs = qos_specs.get_qos_specs_by_name(self.ctxt,
|
||||||
one_time_value)
|
one_time_value)
|
||||||
self.assertEquals(specs[one_time_value]['key1'], one_time_value)
|
self.assertEquals(specs['specs']['key1'], one_time_value)
|
||||||
|
|
||||||
self.assertRaises(exception.InvalidQoSSpecs,
|
self.assertRaises(exception.InvalidQoSSpecs,
|
||||||
qos_specs.get_qos_specs_by_name, self.ctxt, None)
|
qos_specs.get_qos_specs_by_name, self.ctxt, None)
|
||||||
|
|||||||
@@ -147,11 +147,14 @@ def get_associations(context, specs_id):
|
|||||||
LOG.warn(msg)
|
LOG.warn(msg)
|
||||||
raise exception.CinderException(message=msg)
|
raise exception.CinderException(message=msg)
|
||||||
|
|
||||||
result = {}
|
result = []
|
||||||
for vol_type in associates:
|
for vol_type in associates:
|
||||||
result[vol_type['name']] = vol_type['id']
|
member = dict(association_type='volume_type')
|
||||||
|
member.update(dict(name=vol_type['name']))
|
||||||
|
member.update(dict(id=vol_type['id']))
|
||||||
|
result.append(member)
|
||||||
|
|
||||||
return {specs_id: result}
|
return result
|
||||||
|
|
||||||
|
|
||||||
def associate_qos_with_type(context, specs_id, type_id):
|
def associate_qos_with_type(context, specs_id, type_id):
|
||||||
|
|||||||
Reference in New Issue
Block a user