diff --git a/cinder/api/common.py b/cinder/api/common.py index 1efb6ae761c..82069d951ef 100644 --- a/cinder/api/common.py +++ b/cinder/api/common.py @@ -23,8 +23,6 @@ from oslo_log import log as logging from six.moves import urllib import webob -from cinder.api.openstack import wsgi -from cinder.api import xmlutil from cinder.common import constants from cinder import exception from cinder.i18n import _ @@ -59,9 +57,6 @@ CONF.register_opts(api_common_opts) LOG = logging.getLogger(__name__) -XML_NS_V1 = 'http://docs.openstack.org/api/openstack-block-storage/1.0/content' -XML_NS_V2 = 'http://docs.openstack.org/api/openstack-block-storage/2.0/content' - METADATA_TYPES = enum.Enum('METADATA_TYPES', 'user image') @@ -370,75 +365,3 @@ class ViewBuilder(object): url_parts[2] = prefix_parts[2] + url_parts[2] return urllib.parse.urlunsplit(url_parts).rstrip('/') - - -class MetadataDeserializer(wsgi.MetadataXMLDeserializer): - def deserialize(self, text): - dom = utils.safe_minidom_parse_string(text) - metadata_node = self.find_first_child_named(dom, "metadata") - metadata = self.extract_metadata(metadata_node) - return {'body': {'metadata': metadata}} - - -class MetaItemDeserializer(wsgi.MetadataXMLDeserializer): - def deserialize(self, text): - dom = utils.safe_minidom_parse_string(text) - metadata_item = self.extract_metadata(dom) - return {'body': {'meta': metadata_item}} - - -class MetadataXMLDeserializer(wsgi.XMLDeserializer): - - def extract_metadata(self, metadata_node): - """Marshal the metadata attribute of a parsed request.""" - if metadata_node is None: - return {} - metadata = {} - for meta_node in self.find_children_named(metadata_node, "meta"): - key = meta_node.getAttribute("key") - metadata[key] = self.extract_text(meta_node) - return metadata - - def _extract_metadata_container(self, datastring): - dom = utils.safe_minidom_parse_string(datastring) - metadata_node = self.find_first_child_named(dom, "metadata") - metadata = self.extract_metadata(metadata_node) - return {'body': {'metadata': metadata}} - - def create(self, datastring): - return self._extract_metadata_container(datastring) - - def update_all(self, datastring): - return self._extract_metadata_container(datastring) - - def update(self, datastring): - dom = utils.safe_minidom_parse_string(datastring) - metadata_item = self.extract_metadata(dom) - return {'body': {'meta': metadata_item}} - - -metadata_nsmap = {None: xmlutil.XMLNS_V11} - - -class MetaItemTemplate(xmlutil.TemplateBuilder): - def construct(self): - sel = xmlutil.Selector('meta', xmlutil.get_items, 0) - root = xmlutil.TemplateElement('meta', selector=sel) - root.set('key', 0) - root.text = 1 - return xmlutil.MasterTemplate(root, 1, nsmap=metadata_nsmap) - - -class MetadataTemplateElement(xmlutil.TemplateElement): - def will_render(self, datum): - return True - - -class MetadataTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = MetadataTemplateElement('metadata', selector='metadata') - elem = xmlutil.SubTemplateElement(root, 'meta', - selector=xmlutil.get_items) - elem.set('key', 0) - elem.text = 1 - return xmlutil.MasterTemplate(root, 1, nsmap=metadata_nsmap) diff --git a/cinder/api/contrib/admin_actions.py b/cinder/api/contrib/admin_actions.py index 0911d20ffb9..8cc1aa7f36a 100644 --- a/cinder/api/contrib/admin_actions.py +++ b/cinder/api/contrib/admin_actions.py @@ -334,7 +334,6 @@ class Admin_actions(extensions.ExtensionDescriptor): name = "AdminActions" alias = "os-admin-actions" - namespace = "http://docs.openstack.org/volume/ext/admin-actions/api/v1.1" updated = "2012-08-25T00:00:00+00:00" def get_controller_extensions(self): diff --git a/cinder/api/contrib/availability_zones.py b/cinder/api/contrib/availability_zones.py index 2f028110469..c3f7b3f8d57 100644 --- a/cinder/api/contrib/availability_zones.py +++ b/cinder/api/contrib/availability_zones.py @@ -16,29 +16,10 @@ from cinder.api import extensions from cinder.api.openstack import wsgi import cinder.api.views.availability_zones -from cinder.api import xmlutil import cinder.exception import cinder.volume.api -def make_availability_zone(elem): - elem.set('name', 'zoneName') - zoneStateElem = xmlutil.SubTemplateElement(elem, 'zoneState', - selector='zoneState') - zoneStateElem.set('available') - - -class ListTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('availabilityZones') - elem = xmlutil.SubTemplateElement(root, 'availabilityZone', - selector='availabilityZoneInfo') - make_availability_zone(elem) - alias = Availability_zones.alias - namespace = Availability_zones.namespace - return xmlutil.MasterTemplate(root, 1, nsmap={alias: namespace}) - - class Controller(wsgi.Controller): _view_builder_class = cinder.api.views.availability_zones.ViewBuilder @@ -47,7 +28,6 @@ class Controller(wsgi.Controller): super(Controller, self).__init__(*args, **kwargs) self.volume_api = cinder.volume.api.API() - @wsgi.serializers(xml=ListTemplate) def index(self, req): """Describe all known availability zones.""" azs = self.volume_api.list_availability_zones() @@ -59,8 +39,6 @@ class Availability_zones(extensions.ExtensionDescriptor): name = 'AvailabilityZones' alias = 'os-availability-zone' - namespace = ('http://docs.openstack.org/volume/ext/' - 'os-availability-zone/api/v1') updated = '2013-06-27T00:00:00+00:00' def get_resources(self): diff --git a/cinder/api/contrib/backups.py b/cinder/api/contrib/backups.py index c5d2d8ed492..90a6625332e 100644 --- a/cinder/api/contrib/backups.py +++ b/cinder/api/contrib/backups.py @@ -25,7 +25,6 @@ from cinder.api import common from cinder.api import extensions from cinder.api.openstack import wsgi from cinder.api.views import backups as backup_views -from cinder.api import xmlutil from cinder import backup as backupAPI from cinder import exception from cinder.i18n import _, _LI @@ -34,123 +33,6 @@ from cinder import utils LOG = logging.getLogger(__name__) -def make_backup(elem): - elem.set('id') - elem.set('status') - elem.set('size') - elem.set('container') - elem.set('parent_id') - elem.set('volume_id') - elem.set('object_count') - elem.set('availability_zone') - elem.set('created_at') - elem.set('name') - elem.set('description') - elem.set('fail_reason') - - -def make_backup_restore(elem): - elem.set('backup_id') - elem.set('volume_id') - elem.set('volume_name') - - -def make_backup_export_import_record(elem): - elem.set('backup_service') - elem.set('backup_url') - - -class BackupTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('backup', selector='backup') - make_backup(root) - alias = Backups.alias - namespace = Backups.namespace - return xmlutil.MasterTemplate(root, 1, nsmap={alias: namespace}) - - -class BackupsTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('backups') - elem = xmlutil.SubTemplateElement(root, 'backup', selector='backups') - make_backup(elem) - alias = Backups.alias - namespace = Backups.namespace - return xmlutil.MasterTemplate(root, 1, nsmap={alias: namespace}) - - -class BackupRestoreTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('restore', selector='restore') - make_backup_restore(root) - alias = Backups.alias - namespace = Backups.namespace - return xmlutil.MasterTemplate(root, 1, nsmap={alias: namespace}) - - -class BackupExportImportTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('backup-record', - selector='backup-record') - make_backup_export_import_record(root) - alias = Backups.alias - namespace = Backups.namespace - return xmlutil.MasterTemplate(root, 1, nsmap={alias: namespace}) - - -class CreateDeserializer(wsgi.MetadataXMLDeserializer): - def default(self, string): - dom = utils.safe_minidom_parse_string(string) - backup = self._extract_backup(dom) - return {'body': {'backup': backup}} - - def _extract_backup(self, node): - backup = {} - backup_node = self.find_first_child_named(node, 'backup') - - attributes = ['container', 'display_name', - 'display_description', 'volume_id', - 'parent_id'] - - for attr in attributes: - if backup_node.getAttribute(attr): - backup[attr] = backup_node.getAttribute(attr) - return backup - - -class RestoreDeserializer(wsgi.MetadataXMLDeserializer): - def default(self, string): - dom = utils.safe_minidom_parse_string(string) - restore = self._extract_restore(dom) - return {'body': {'restore': restore}} - - def _extract_restore(self, node): - restore = {} - restore_node = self.find_first_child_named(node, 'restore') - if restore_node.getAttribute('volume_id'): - restore['volume_id'] = restore_node.getAttribute('volume_id') - return restore - - -class BackupImportDeserializer(wsgi.MetadataXMLDeserializer): - def default(self, string): - dom = utils.safe_minidom_parse_string(string) - backup = self._extract_backup(dom) - retval = {'body': {'backup-record': backup}} - return retval - - def _extract_backup(self, node): - backup = {} - backup_node = self.find_first_child_named(node, 'backup-record') - - attributes = ['backup_service', 'backup_url'] - - for attr in attributes: - if backup_node.getAttribute(attr): - backup[attr] = backup_node.getAttribute(attr) - return backup - - class BackupsController(wsgi.Controller): """The Backups API controller for the OpenStack API.""" @@ -160,7 +42,6 @@ class BackupsController(wsgi.Controller): self.backup_api = backupAPI.API() super(BackupsController, self).__init__() - @wsgi.serializers(xml=BackupTemplate) def show(self, req, id): """Return data about the given backup.""" LOG.debug('show called for member %s', id) @@ -191,12 +72,10 @@ class BackupsController(wsgi.Controller): return webob.Response(status_int=202) - @wsgi.serializers(xml=BackupsTemplate) def index(self, req): """Returns a summary list of backups.""" return self._get_backups(req, is_detail=False) - @wsgi.serializers(xml=BackupsTemplate) def detail(self, req): """Returns a detailed list of backups.""" return self._get_backups(req, is_detail=True) @@ -242,8 +121,6 @@ class BackupsController(wsgi.Controller): # immediately # - maybe also do validation of swift container name @wsgi.response(202) - @wsgi.serializers(xml=BackupTemplate) - @wsgi.deserializers(xml=CreateDeserializer) def create(self, req, body): """Create a new backup.""" LOG.debug('Creating new backup %s', body) @@ -287,8 +164,6 @@ class BackupsController(wsgi.Controller): return retval @wsgi.response(202) - @wsgi.serializers(xml=BackupRestoreTemplate) - @wsgi.deserializers(xml=RestoreDeserializer) def restore(self, req, id, body): """Restore an existing backup to a volume.""" LOG.debug('Restoring backup %(backup_id)s (%(body)s)', @@ -331,7 +206,6 @@ class BackupsController(wsgi.Controller): return retval @wsgi.response(200) - @wsgi.serializers(xml=BackupExportImportTemplate) def export_record(self, req, id): """Export a backup.""" LOG.debug('export record called for member %s.', id) @@ -350,8 +224,6 @@ class BackupsController(wsgi.Controller): return retval @wsgi.response(201) - @wsgi.serializers(xml=BackupTemplate) - @wsgi.deserializers(xml=BackupImportDeserializer) def import_record(self, req, body): """Import a backup.""" LOG.debug('Importing record from %s.', body) @@ -389,7 +261,6 @@ class Backups(extensions.ExtensionDescriptor): name = 'Backups' alias = 'backups' - namespace = 'http://docs.openstack.org/volume/ext/backups/api/v1' updated = '2012-12-12T00:00:00+00:00' def get_resources(self): diff --git a/cinder/api/contrib/capabilities.py b/cinder/api/contrib/capabilities.py index b1796305cdd..d8430c6067d 100644 --- a/cinder/api/contrib/capabilities.py +++ b/cinder/api/contrib/capabilities.py @@ -65,7 +65,6 @@ class Capabilities(extensions.ExtensionDescriptor): name = "Capabilities" alias = "capabilities" - namespace = "http://docs.openstack.org/volume/ext/capabilities/api/v2" updated = "2015-08-31T00:00:00+00:00" def get_resources(self): diff --git a/cinder/api/contrib/cgsnapshots.py b/cinder/api/contrib/cgsnapshots.py index 752f5e4b198..e618fefe1a5 100644 --- a/cinder/api/contrib/cgsnapshots.py +++ b/cinder/api/contrib/cgsnapshots.py @@ -23,63 +23,13 @@ from cinder.api import common from cinder.api import extensions from cinder.api.openstack import wsgi from cinder.api.views import cgsnapshots as cgsnapshot_views -from cinder.api import xmlutil from cinder import consistencygroup as consistencygroupAPI from cinder import exception from cinder.i18n import _, _LI -from cinder import utils LOG = logging.getLogger(__name__) -def make_cgsnapshot(elem): - elem.set('id') - elem.set('consistencygroup_id') - elem.set('status') - elem.set('created_at') - elem.set('name') - elem.set('description') - - -class CgsnapshotTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('cgsnapshot', selector='cgsnapshot') - make_cgsnapshot(root) - alias = Cgsnapshots.alias - namespace = Cgsnapshots.namespace - return xmlutil.MasterTemplate(root, 1, nsmap={alias: namespace}) - - -class CgsnapshotsTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('cgsnapshots') - elem = xmlutil.SubTemplateElement(root, 'cgsnapshot', - selector='cgsnapshots') - make_cgsnapshot(elem) - alias = Cgsnapshots.alias - namespace = Cgsnapshots.namespace - return xmlutil.MasterTemplate(root, 1, nsmap={alias: namespace}) - - -class CreateDeserializer(wsgi.MetadataXMLDeserializer): - def default(self, string): - dom = utils.safe_minidom_parse_string(string) - cgsnapshot = self._extract_cgsnapshot(dom) - return {'body': {'cgsnapshot': cgsnapshot}} - - def _extract_cgsnapshot(self, node): - cgsnapshot = {} - cgsnapshot_node = self.find_first_child_named(node, 'cgsnapshot') - - attributes = ['name', - 'description'] - - for attr in attributes: - if cgsnapshot_node.getAttribute(attr): - cgsnapshot[attr] = cgsnapshot_node.getAttribute(attr) - return cgsnapshot - - class CgsnapshotsController(wsgi.Controller): """The cgsnapshots API controller for the OpenStack API.""" @@ -89,7 +39,6 @@ class CgsnapshotsController(wsgi.Controller): self.cgsnapshot_api = consistencygroupAPI.API() super(CgsnapshotsController, self).__init__() - @wsgi.serializers(xml=CgsnapshotTemplate) def show(self, req, id): """Return data about the given cgsnapshot.""" LOG.debug('show called for member %s', id) @@ -127,12 +76,10 @@ class CgsnapshotsController(wsgi.Controller): return webob.Response(status_int=202) - @wsgi.serializers(xml=CgsnapshotsTemplate) def index(self, req): """Returns a summary list of cgsnapshots.""" return self._get_cgsnapshots(req, is_detail=False) - @wsgi.serializers(xml=CgsnapshotsTemplate) def detail(self, req): """Returns a detailed list of cgsnapshots.""" return self._get_cgsnapshots(req, is_detail=True) @@ -150,8 +97,6 @@ class CgsnapshotsController(wsgi.Controller): return cgsnapshots @wsgi.response(202) - @wsgi.serializers(xml=CgsnapshotTemplate) - @wsgi.deserializers(xml=CreateDeserializer) def create(self, req, body): """Create a new cgsnapshot.""" LOG.debug('Creating new cgsnapshot %s', body) @@ -197,7 +142,6 @@ class Cgsnapshots(extensions.ExtensionDescriptor): name = 'Cgsnapshots' alias = 'cgsnapshots' - namespace = 'http://docs.openstack.org/volume/ext/cgsnapshots/api/v1' updated = '2014-08-18T00:00:00+00:00' def get_resources(self): diff --git a/cinder/api/contrib/consistencygroups.py b/cinder/api/contrib/consistencygroups.py index ac7f9439a3d..7c462784c47 100644 --- a/cinder/api/contrib/consistencygroups.py +++ b/cinder/api/contrib/consistencygroups.py @@ -24,108 +24,13 @@ from cinder.api import common from cinder.api import extensions from cinder.api.openstack import wsgi from cinder.api.views import consistencygroups as consistencygroup_views -from cinder.api import xmlutil from cinder import consistencygroup as consistencygroupAPI from cinder import exception from cinder.i18n import _, _LI -from cinder import utils LOG = logging.getLogger(__name__) -def make_consistencygroup(elem): - elem.set('id') - elem.set('status') - elem.set('availability_zone') - elem.set('created_at') - elem.set('name') - elem.set('description') - - -def make_consistencygroup_from_src(elem): - elem.set('id') - elem.set('status') - elem.set('created_at') - elem.set('name') - elem.set('description') - elem.set('cgsnapshot_id') - elem.set('source_cgid') - - -class ConsistencyGroupTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('consistencygroup', - selector='consistencygroup') - make_consistencygroup(root) - alias = Consistencygroups.alias - namespace = Consistencygroups.namespace - return xmlutil.MasterTemplate(root, 1, nsmap={alias: namespace}) - - -class ConsistencyGroupsTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('consistencygroups') - elem = xmlutil.SubTemplateElement(root, 'consistencygroup', - selector='consistencygroups') - make_consistencygroup(elem) - alias = Consistencygroups.alias - namespace = Consistencygroups.namespace - return xmlutil.MasterTemplate(root, 1, nsmap={alias: namespace}) - - -class ConsistencyGroupFromSrcTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('consistencygroup-from-src', - selector='consistencygroup-from-src') - make_consistencygroup_from_src(root) - alias = Consistencygroups.alias - namespace = Consistencygroups.namespace - return xmlutil.MasterTemplate(root, 1, nsmap={alias: namespace}) - - -class CreateDeserializer(wsgi.MetadataXMLDeserializer): - def default(self, string): - dom = utils.safe_minidom_parse_string(string) - consistencygroup = self._extract_consistencygroup(dom) - return {'body': {'consistencygroup': consistencygroup}} - - def _extract_consistencygroup(self, node): - consistencygroup = {} - consistencygroup_node = self.find_first_child_named( - node, - 'consistencygroup') - - attributes = ['name', - 'description'] - - for attr in attributes: - if consistencygroup_node.getAttribute(attr): - consistencygroup[attr] = consistencygroup_node.\ - getAttribute(attr) - return consistencygroup - - -class CreateFromSrcDeserializer(wsgi.MetadataXMLDeserializer): - def default(self, string): - dom = utils.safe_minidom_parse_string(string) - consistencygroup = self._extract_consistencygroup(dom) - retval = {'body': {'consistencygroup-from-src': consistencygroup}} - return retval - - def _extract_consistencygroup(self, node): - consistencygroup = {} - consistencygroup_node = self.find_first_child_named( - node, 'consistencygroup-from-src') - - attributes = ['cgsnapshot', 'source_cgid', 'name', 'description'] - - for attr in attributes: - if consistencygroup_node.getAttribute(attr): - consistencygroup[attr] = ( - consistencygroup_node.getAttribute(attr)) - return consistencygroup - - class ConsistencyGroupsController(wsgi.Controller): """The ConsistencyGroups API controller for the OpenStack API.""" @@ -135,7 +40,6 @@ class ConsistencyGroupsController(wsgi.Controller): self.consistencygroup_api = consistencygroupAPI.API() super(ConsistencyGroupsController, self).__init__() - @wsgi.serializers(xml=ConsistencyGroupTemplate) def show(self, req, id): """Return data about the given consistency group.""" LOG.debug('show called for member %s', id) @@ -182,12 +86,10 @@ class ConsistencyGroupsController(wsgi.Controller): return webob.Response(status_int=202) - @wsgi.serializers(xml=ConsistencyGroupsTemplate) def index(self, req): """Returns a summary list of consistency groups.""" return self._get_consistencygroups(req, is_detail=False) - @wsgi.serializers(xml=ConsistencyGroupsTemplate) def detail(self, req): """Returns a detailed list of consistency groups.""" return self._get_consistencygroups(req, is_detail=True) @@ -212,8 +114,6 @@ class ConsistencyGroupsController(wsgi.Controller): return consistencygroups @wsgi.response(202) - @wsgi.serializers(xml=ConsistencyGroupTemplate) - @wsgi.deserializers(xml=CreateDeserializer) def create(self, req, body): """Create a new consistency group.""" LOG.debug('Creating new consistency group %s', body) @@ -250,8 +150,6 @@ class ConsistencyGroupsController(wsgi.Controller): return retval @wsgi.response(202) - @wsgi.serializers(xml=ConsistencyGroupFromSrcTemplate) - @wsgi.deserializers(xml=CreateFromSrcDeserializer) def create_from_src(self, req, body): """Create a new consistency group from a source. @@ -307,7 +205,6 @@ class ConsistencyGroupsController(wsgi.Controller): retval = self._view_builder.summary(req, new_consistencygroup) return retval - @wsgi.serializers(xml=ConsistencyGroupTemplate) def update(self, req, id, body): """Update the consistency group. @@ -375,7 +272,6 @@ class Consistencygroups(extensions.ExtensionDescriptor): name = 'Consistencygroups' alias = 'consistencygroups' - namespace = 'http://docs.openstack.org/volume/ext/consistencygroups/api/v1' updated = '2014-08-18T00:00:00+00:00' def get_resources(self): diff --git a/cinder/api/contrib/extended_services.py b/cinder/api/contrib/extended_services.py index 97e95b9e6c9..92619ea7e94 100644 --- a/cinder/api/contrib/extended_services.py +++ b/cinder/api/contrib/extended_services.py @@ -20,6 +20,4 @@ class Extended_services(extensions.ExtensionDescriptor): name = "ExtendedServices" alias = "os-extended-services" - namespace = ("http://docs.openstack.org/volume/ext/" - "extended_services/api/v2") updated = "2014-01-10T00:00:00-00:00" diff --git a/cinder/api/contrib/extended_snapshot_attributes.py b/cinder/api/contrib/extended_snapshot_attributes.py index 8fbe1a6db62..226d0739adb 100644 --- a/cinder/api/contrib/extended_snapshot_attributes.py +++ b/cinder/api/contrib/extended_snapshot_attributes.py @@ -18,7 +18,6 @@ from oslo_log import log as logging from cinder.api import extensions from cinder.api.openstack import wsgi -from cinder.api import xmlutil LOG = logging.getLogger(__name__) @@ -39,7 +38,6 @@ class ExtendedSnapshotAttributesController(wsgi.Controller): context = req.environ['cinder.context'] if authorize(context): # Attach our slave template to the response object - resp_obj.attach(xml=ExtendedSnapshotAttributeTemplate()) snapshot = resp_obj.obj['snapshot'] self._extend_snapshot(req, snapshot) @@ -48,7 +46,6 @@ class ExtendedSnapshotAttributesController(wsgi.Controller): context = req.environ['cinder.context'] if authorize(context): # Attach our slave template to the response object - resp_obj.attach(xml=ExtendedSnapshotAttributesTemplate()) for snapshot in list(resp_obj.obj['snapshots']): self._extend_snapshot(req, snapshot) @@ -58,8 +55,6 @@ class Extended_snapshot_attributes(extensions.ExtensionDescriptor): name = "ExtendedSnapshotAttributes" alias = "os-extended-snapshot-attributes" - namespace = ("http://docs.openstack.org/volume/ext/" - "extended_snapshot_attributes/api/v1") updated = "2012-06-19T00:00:00+00:00" def get_controller_extensions(self): @@ -67,30 +62,3 @@ class Extended_snapshot_attributes(extensions.ExtensionDescriptor): extension = extensions.ControllerExtension(self, 'snapshots', controller) return [extension] - - -def make_snapshot(elem): - elem.set('{%s}project_id' % Extended_snapshot_attributes.namespace, - '%s:project_id' % Extended_snapshot_attributes.alias) - elem.set('{%s}progress' % Extended_snapshot_attributes.namespace, - '%s:progress' % Extended_snapshot_attributes.alias) - - -class ExtendedSnapshotAttributeTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('snapshot', selector='snapshot') - make_snapshot(root) - alias = Extended_snapshot_attributes.alias - namespace = Extended_snapshot_attributes.namespace - return xmlutil.SlaveTemplate(root, 1, nsmap={alias: namespace}) - - -class ExtendedSnapshotAttributesTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('snapshots') - elem = xmlutil.SubTemplateElement(root, 'snapshot', - selector='snapshots') - make_snapshot(elem) - alias = Extended_snapshot_attributes.alias - namespace = Extended_snapshot_attributes.namespace - return xmlutil.SlaveTemplate(root, 1, nsmap={alias: namespace}) diff --git a/cinder/api/contrib/hosts.py b/cinder/api/contrib/hosts.py index a09eff62464..9281d5966c7 100644 --- a/cinder/api/contrib/hosts.py +++ b/cinder/api/contrib/hosts.py @@ -15,8 +15,6 @@ """The hosts admin extension.""" -from xml.parsers import expat - from oslo_config import cfg from oslo_log import log as logging from oslo_utils import timeutils @@ -24,12 +22,10 @@ import webob.exc from cinder.api import extensions from cinder.api.openstack import wsgi -from cinder.api import xmlutil from cinder import db from cinder import exception from cinder.i18n import _, _LI from cinder import objects -from cinder import utils from cinder.volume import api as volume_api @@ -39,62 +35,6 @@ LOG = logging.getLogger(__name__) authorize = extensions.extension_authorizer('volume', 'hosts') -class HostIndexTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('hosts') - elem = xmlutil.SubTemplateElement(root, 'host', selector='hosts') - elem.set('service-status') - elem.set('service') - elem.set('zone') - elem.set('service-state') - elem.set('host_name') - elem.set('last-update') - - return xmlutil.MasterTemplate(root, 1) - - -class HostUpdateTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('host') - root.set('host') - root.set('status') - - return xmlutil.MasterTemplate(root, 1) - - -class HostActionTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('host') - root.set('host') - - return xmlutil.MasterTemplate(root, 1) - - -class HostShowTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('host') - elem = xmlutil.make_flat_dict('resource', selector='host', - subselector='resource') - root.append(elem) - - return xmlutil.MasterTemplate(root, 1) - - -class HostDeserializer(wsgi.XMLDeserializer): - def default(self, string): - try: - node = utils.safe_minidom_parse_string(string) - except expat.ExpatError: - msg = _("cannot understand XML") - raise exception.MalformedRequestBody(reason=msg) - - updates = {} - for child in node.childNodes[0].childNodes: - updates[child.tagName] = self.extract_text(child) - - return dict(body=updates) - - def _list_hosts(req, service=None): """Returns a summary list of hosts.""" curr_time = timeutils.utcnow(with_timezone=True) @@ -151,13 +91,10 @@ class HostController(wsgi.Controller): self.api = volume_api.HostAPI() super(HostController, self).__init__() - @wsgi.serializers(xml=HostIndexTemplate) def index(self, req): authorize(req.environ['cinder.context']) return {'hosts': _list_hosts(req)} - @wsgi.serializers(xml=HostUpdateTemplate) - @wsgi.deserializers(xml=HostDeserializer) @check_host def update(self, req, id, body): authorize(req.environ['cinder.context']) @@ -194,7 +131,6 @@ class HostController(wsgi.Controller): raise webob.exc.HTTPBadRequest(explanation=result) return {"host": host, "status": result} - @wsgi.serializers(xml=HostShowTemplate) def show(self, req, id): """Shows the volume usage info given by hosts. @@ -260,7 +196,6 @@ class Hosts(extensions.ExtensionDescriptor): name = "Hosts" alias = "os-hosts" - namespace = "http://docs.openstack.org/volume/ext/hosts/api/v1.1" updated = "2011-06-29T00:00:00+00:00" def get_resources(self): diff --git a/cinder/api/contrib/image_create.py b/cinder/api/contrib/image_create.py index 3358831143d..eb2358a3087 100644 --- a/cinder/api/contrib/image_create.py +++ b/cinder/api/contrib/image_create.py @@ -25,5 +25,4 @@ class Image_create(extensions.ExtensionDescriptor): name = "CreateVolumeExtension" alias = "os-image-create" - namespace = "http://docs.openstack.org/volume/ext/image-create/api/v1" updated = "2012-08-13T00:00:00+00:00" diff --git a/cinder/api/contrib/qos_specs_manage.py b/cinder/api/contrib/qos_specs_manage.py index d272bcb3d57..0c3d4f8f5da 100644 --- a/cinder/api/contrib/qos_specs_manage.py +++ b/cinder/api/contrib/qos_specs_manage.py @@ -24,9 +24,8 @@ from cinder.api import common 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.i18n import _, _LI +from cinder.i18n import _ from cinder import rpc from cinder import utils from cinder.volume import qos_specs @@ -37,62 +36,6 @@ LOG = logging.getLogger(__name__) authorize = extensions.extension_authorizer('volume', 'qos_specs_manage') -def make_qos_specs(elem): - elem.set('id') - elem.set('name') - elem.set('consumer') - elem.append(SpecsTemplate()) - - -def make_associations(elem): - elem.set('association_type') - elem.set('name') - elem.set('id') - - -class SpecsTemplate(xmlutil.TemplateBuilder): - def construct(self): - return xmlutil.MasterTemplate(xmlutil.make_flat_dict('specs'), 1) - - -class QoSSpecsTemplate(xmlutil.TemplateBuilder): - 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) - - -class QoSSpecsKeyDeserializer(wsgi.XMLDeserializer): - def _extract_keys(self, key_node): - keys = [] - for key in key_node.childNodes: - key_name = key.tagName - keys.append(key_name) - - return keys - - def default(self, string): - dom = utils.safe_minidom_parse_string(string) - key_node = self.find_first_child_named(dom, 'keys') - if not key_node: - LOG.info(_LI("Unable to parse XML input.")) - msg = _("Unable to parse XML request. " - "Please provide XML in correct format.") - raise webob.exc.HTTPBadRequest(explanation=msg) - return {'body': {'keys': self._extract_keys(key_node)}} - - -class AssociationsTemplate(xmlutil.TemplateBuilder): - 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) @@ -111,7 +54,6 @@ class QoSSpecsController(wsgi.Controller): method, payload) - @wsgi.serializers(xml=QoSSpecsTemplate) def index(self, req): """Returns the list of qos_specs.""" context = req.environ['cinder.context'] @@ -132,7 +74,6 @@ class QoSSpecsController(wsgi.Controller): sort_dirs=sort_dirs) return self._view_builder.summary_list(req, specs) - @wsgi.serializers(xml=QoSSpecsTemplate) def create(self, req, body=None): context = req.environ['cinder.context'] authorize(context) @@ -178,7 +119,6 @@ class QoSSpecsController(wsgi.Controller): return self._view_builder.detail(req, spec) - @wsgi.serializers(xml=QoSSpecsTemplate) def update(self, req, id, body=None): context = req.environ['cinder.context'] authorize(context) @@ -213,7 +153,6 @@ class QoSSpecsController(wsgi.Controller): return body - @wsgi.serializers(xml=QoSSpecsTemplate) def show(self, req, id): """Return a single qos spec item.""" context = req.environ['cinder.context'] @@ -263,7 +202,6 @@ class QoSSpecsController(wsgi.Controller): return webob.Response(status_int=202) - @wsgi.deserializers(xml=QoSSpecsKeyDeserializer) def delete_keys(self, req, id, body): """Deletes specified keys in qos specs.""" context = req.environ['cinder.context'] @@ -297,7 +235,6 @@ class QoSSpecsController(wsgi.Controller): return webob.Response(status_int=202) - @wsgi.serializers(xml=AssociationsTemplate) def associations(self, req, id): """List all associations of given qos specs.""" context = req.environ['cinder.context'] @@ -461,7 +398,6 @@ class Qos_specs_manage(extensions.ExtensionDescriptor): 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" def get_resources(self): diff --git a/cinder/api/contrib/quota_classes.py b/cinder/api/contrib/quota_classes.py index 086d2c36d09..a694d856cb7 100644 --- a/cinder/api/contrib/quota_classes.py +++ b/cinder/api/contrib/quota_classes.py @@ -17,7 +17,6 @@ import webob from cinder.api import extensions from cinder.api.openstack import wsgi -from cinder.api import xmlutil from cinder import db from cinder import exception from cinder.i18n import _ @@ -31,19 +30,6 @@ QUOTAS = quota.QUOTAS authorize = extensions.extension_authorizer('volume', 'quota_classes') -class QuotaClassTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('quota_class_set', - selector='quota_class_set') - root.set('id') - - for resource in QUOTAS.resources: - elem = xmlutil.SubTemplateElement(root, resource) - elem.text = resource - - return xmlutil.MasterTemplate(root, 1) - - class QuotaClassSetsController(wsgi.Controller): def _format_quota_set(self, quota_class, quota_set): @@ -53,7 +39,6 @@ class QuotaClassSetsController(wsgi.Controller): return dict(quota_class_set=quota_set) - @wsgi.serializers(xml=QuotaClassTemplate) def show(self, req, id): context = req.environ['cinder.context'] authorize(context) @@ -65,7 +50,6 @@ class QuotaClassSetsController(wsgi.Controller): return self._format_quota_set(id, QUOTAS.get_class_quotas(context, id)) - @wsgi.serializers(xml=QuotaClassTemplate) def update(self, req, id, body): context = req.environ['cinder.context'] authorize(context) @@ -97,8 +81,6 @@ class Quota_classes(extensions.ExtensionDescriptor): name = "QuotaClasses" alias = "os-quota-class-sets" - namespace = ("http://docs.openstack.org/volume/ext/" - "quota-classes-sets/api/v1.1") updated = "2012-03-12T00:00:00+00:00" def get_resources(self): diff --git a/cinder/api/contrib/quotas.py b/cinder/api/contrib/quotas.py index d4dcc66d0a9..5b458fb4d01 100644 --- a/cinder/api/contrib/quotas.py +++ b/cinder/api/contrib/quotas.py @@ -17,7 +17,6 @@ import webob from cinder.api import extensions from cinder.api.openstack import wsgi -from cinder.api import xmlutil from cinder import db from cinder.db.sqlalchemy import api as sqlalchemy_api from cinder import exception @@ -39,18 +38,6 @@ authorize_show = extensions.extension_authorizer('volume', 'quotas:show') authorize_delete = extensions.extension_authorizer('volume', 'quotas:delete') -class QuotaTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('quota_set', selector='quota_set') - root.set('id') - - for resource in QUOTAS.resources: - elem = xmlutil.SubTemplateElement(root, resource) - elem.text = resource - - return xmlutil.MasterTemplate(root, 1) - - class QuotaSetsController(wsgi.Controller): def _format_quota_set(self, project_id, quota_set): @@ -155,7 +142,6 @@ class QuotaSetsController(wsgi.Controller): return True return False - @wsgi.serializers(xml=QuotaTemplate) def show(self, req, id): """Show quota for a particular tenant @@ -197,7 +183,6 @@ class QuotaSetsController(wsgi.Controller): quotas = self._get_quotas(context, target_project_id, usage) return self._format_quota_set(target_project_id, quotas) - @wsgi.serializers(xml=QuotaTemplate) def update(self, req, id, body): """Update Quota for a particular tenant @@ -337,7 +322,6 @@ class QuotaSetsController(wsgi.Controller): return reservations - @wsgi.serializers(xml=QuotaTemplate) def defaults(self, req, id): context = req.environ['cinder.context'] authorize_show(context) @@ -345,7 +329,6 @@ class QuotaSetsController(wsgi.Controller): return self._format_quota_set(id, QUOTAS.get_defaults( context, project_id=id)) - @wsgi.serializers(xml=QuotaTemplate) def delete(self, req, id): """Delete Quota for a particular tenant. @@ -436,7 +419,6 @@ class Quotas(extensions.ExtensionDescriptor): name = "Quotas" alias = "os-quota-sets" - namespace = "http://docs.openstack.org/volume/ext/quotas-sets/api/v1.1" updated = "2011-08-08T00:00:00+00:00" def get_resources(self): diff --git a/cinder/api/contrib/scheduler_hints.py b/cinder/api/contrib/scheduler_hints.py index 4d01d51059f..858b3ade6f6 100644 --- a/cinder/api/contrib/scheduler_hints.py +++ b/cinder/api/contrib/scheduler_hints.py @@ -17,7 +17,6 @@ import webob.exc from cinder.api import extensions from cinder.api.openstack import wsgi -from cinder.api.v2 import volumes from cinder.i18n import _ LOG = logging.getLogger(__name__) @@ -53,7 +52,6 @@ class Scheduler_hints(extensions.ExtensionDescriptor): name = "SchedulerHints" alias = "OS-SCH-HNT" - namespace = volumes.SCHEDULER_HINTS_NAMESPACE updated = "2013-04-18T00:00:00+00:00" def get_controller_extensions(self): diff --git a/cinder/api/contrib/scheduler_stats.py b/cinder/api/contrib/scheduler_stats.py index 96d8076cf91..9f6e59d36de 100644 --- a/cinder/api/contrib/scheduler_stats.py +++ b/cinder/api/contrib/scheduler_stats.py @@ -56,7 +56,6 @@ class Scheduler_stats(extensions.ExtensionDescriptor): name = "Scheduler_stats" alias = "scheduler-stats" - namespace = "http://docs.openstack.org/volume/ext/scheduler-stats/api/v1" updated = "2014-09-07T00:00:00+00:00" def get_resources(self): diff --git a/cinder/api/contrib/services.py b/cinder/api/contrib/services.py index 36a99543961..fa531a08f8f 100644 --- a/cinder/api/contrib/services.py +++ b/cinder/api/contrib/services.py @@ -22,7 +22,6 @@ import webob.exc from cinder.api import extensions from cinder.api.openstack import wsgi -from cinder.api import xmlutil from cinder import exception from cinder.i18n import _ from cinder import objects @@ -36,51 +35,12 @@ LOG = logging.getLogger(__name__) authorize = extensions.extension_authorizer('volume', 'services') -class ServicesIndexTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('services') - elem = xmlutil.SubTemplateElement(root, 'service', selector='services') - elem.set('binary') - elem.set('host') - elem.set('zone') - elem.set('status') - elem.set('state') - elem.set('update_at') - elem.set('disabled_reason') - elem.set('replication_status') - elem.set('active_backend_id') - elem.set('frozen') - - return xmlutil.MasterTemplate(root, 1) - - -class ServicesUpdateTemplate(xmlutil.TemplateBuilder): - def construct(self): - # TODO(uni): template elements of 'host', 'service' and 'disabled' - # should be deprecated to make ServicesUpdateTemplate consistent - # with ServicesIndexTemplate. Still keeping it here for API - # compatibility sake. - root = xmlutil.TemplateElement('host') - root.set('host') - root.set('service') - root.set('disabled') - root.set('binary') - root.set('status') - root.set('disabled_reason') - root.set('replication_status') - root.set('active_backend_id') - root.set('frozen') - - return xmlutil.MasterTemplate(root, 1) - - class ServiceController(wsgi.Controller): def __init__(self, ext_mgr=None): self.ext_mgr = ext_mgr super(ServiceController, self).__init__() self.volume_api = volume.API() - @wsgi.serializers(xml=ServicesIndexTemplate) def index(self, req): """Return a list of all running services. @@ -154,7 +114,6 @@ class ServiceController(wsgi.Controller): def _failover(self, context, host, backend_id=None): return self.volume_api.failover_host(context, host, backend_id) - @wsgi.serializers(xml=ServicesUpdateTemplate) def update(self, req, id, body): """Enable/Disable scheduling for a service. @@ -236,7 +195,6 @@ class Services(extensions.ExtensionDescriptor): name = "Services" alias = "os-services" - namespace = "http://docs.openstack.org/volume/ext/services/api/v2" updated = "2012-10-28T00:00:00-00:00" def get_resources(self): diff --git a/cinder/api/contrib/snapshot_actions.py b/cinder/api/contrib/snapshot_actions.py index 6319c16e27f..6cc0f764f56 100644 --- a/cinder/api/contrib/snapshot_actions.py +++ b/cinder/api/contrib/snapshot_actions.py @@ -100,8 +100,6 @@ class Snapshot_actions(extensions.ExtensionDescriptor): name = "SnapshotActions" alias = "os-snapshot-actions" - namespace = \ - "http://docs.openstack.org/volume/ext/snapshot-actions/api/v1.1" updated = "2013-07-16T00:00:00+00:00" def get_controller_extensions(self): diff --git a/cinder/api/contrib/snapshot_manage.py b/cinder/api/contrib/snapshot_manage.py index bf1c280c446..e797dd27e6e 100644 --- a/cinder/api/contrib/snapshot_manage.py +++ b/cinder/api/contrib/snapshot_manage.py @@ -18,7 +18,6 @@ from webob import exc from cinder.api import extensions from cinder.api.openstack import wsgi -from cinder.api.v2 import snapshots from cinder.api.views import snapshots as snapshot_views from cinder import exception from cinder.i18n import _ @@ -39,7 +38,6 @@ class SnapshotManageController(wsgi.Controller): self.volume_api = cinder_volume.API() @wsgi.response(202) - @wsgi.serializers(xml=snapshots.SnapshotTemplate) def create(self, req, body): """Instruct Cinder to manage a storage snapshot object. @@ -138,8 +136,6 @@ class Snapshot_manage(extensions.ExtensionDescriptor): name = 'SnapshotManage' alias = 'os-snapshot-manage' - namespace = ('http://docs.openstack.org/volume/ext/' - 'os-snapshot-manage/api/v1') updated = '2014-12-31T00:00:00+00:00' def get_resources(self): diff --git a/cinder/api/contrib/snapshot_unmanage.py b/cinder/api/contrib/snapshot_unmanage.py index 5ddf96b1829..c9e2259df21 100644 --- a/cinder/api/contrib/snapshot_unmanage.py +++ b/cinder/api/contrib/snapshot_unmanage.py @@ -66,8 +66,6 @@ class Snapshot_unmanage(extensions.ExtensionDescriptor): name = "SnapshotUnmanage" alias = "os-snapshot-unmanage" - namespace = ('http://docs.openstack.org/snapshot/ext/snapshot-unmanage' - '/api/v1') updated = "2014-12-31T00:00:00+00:00" def get_controller_extensions(self): diff --git a/cinder/api/contrib/types_extra_specs.py b/cinder/api/contrib/types_extra_specs.py index cc169144edf..70b6083ee75 100644 --- a/cinder/api/contrib/types_extra_specs.py +++ b/cinder/api/contrib/types_extra_specs.py @@ -20,7 +20,6 @@ import webob from cinder.api import common from cinder.api import extensions from cinder.api.openstack import wsgi -from cinder.api import xmlutil from cinder import db from cinder import exception from cinder.i18n import _ @@ -30,26 +29,6 @@ from cinder.volume import volume_types authorize = extensions.extension_authorizer('volume', 'types_extra_specs') -class VolumeTypeExtraSpecsTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.make_flat_dict('extra_specs', selector='extra_specs') - return xmlutil.MasterTemplate(root, 1) - - -class VolumeTypeExtraSpecTemplate(xmlutil.TemplateBuilder): - def construct(self): - tagname = xmlutil.Selector('key') - - def extraspec_sel(obj, do_raise=False): - # Have to extract the key and value for later use... - key, value = list(obj.items())[0] - return dict(key=key, value=value) - - root = xmlutil.TemplateElement(tagname, selector=extraspec_sel) - root.text = 'value' - return xmlutil.MasterTemplate(root, 1) - - class VolumeTypeExtraSpecsController(wsgi.Controller): """The volume type extra specs API controller for the OpenStack API.""" @@ -66,7 +45,6 @@ class VolumeTypeExtraSpecsController(wsgi.Controller): except exception.VolumeTypeNotFound as ex: raise webob.exc.HTTPNotFound(explanation=ex.msg) - @wsgi.serializers(xml=VolumeTypeExtraSpecsTemplate) def index(self, req, type_id): """Returns the list of extra specs for a given volume type.""" context = req.environ['cinder.context'] @@ -85,7 +63,6 @@ class VolumeTypeExtraSpecsController(wsgi.Controller): self.validate_string_length(value, 'Value for key "%s"' % key, min_length=0, max_length=255) - @wsgi.serializers(xml=VolumeTypeExtraSpecsTemplate) def create(self, req, type_id, body=None): context = req.environ['cinder.context'] authorize(context) @@ -106,7 +83,6 @@ class VolumeTypeExtraSpecsController(wsgi.Controller): notifier_info) return body - @wsgi.serializers(xml=VolumeTypeExtraSpecTemplate) def update(self, req, type_id, id, body=None): context = req.environ['cinder.context'] authorize(context) @@ -133,7 +109,6 @@ class VolumeTypeExtraSpecsController(wsgi.Controller): notifier_info) return body - @wsgi.serializers(xml=VolumeTypeExtraSpecTemplate) def show(self, req, type_id, id): """Return a single extra spec item.""" context = req.environ['cinder.context'] @@ -178,7 +153,6 @@ class Types_extra_specs(extensions.ExtensionDescriptor): name = "TypesExtraSpecs" alias = "os-types-extra-specs" - namespace = "http://docs.openstack.org/volume/ext/types-extra-specs/api/v1" updated = "2011-08-24T00:00:00+00:00" def get_resources(self): diff --git a/cinder/api/contrib/types_manage.py b/cinder/api/contrib/types_manage.py index f90ea12ac7c..b22d239ad74 100644 --- a/cinder/api/contrib/types_manage.py +++ b/cinder/api/contrib/types_manage.py @@ -20,7 +20,6 @@ import webob from cinder.api import extensions from cinder.api.openstack import wsgi -from cinder.api.v1 import types from cinder.api.views import types as views_types from cinder import exception from cinder.i18n import _ @@ -48,7 +47,6 @@ class VolumeTypesManageController(wsgi.Controller): rpc.get_notifier('volumeType').info(context, method, payload) @wsgi.action("create") - @wsgi.serializers(xml=types.VolumeTypeTemplate) def _create(self, req, body): """Creates a new volume type.""" context = req.environ['cinder.context'] @@ -101,7 +99,6 @@ class VolumeTypesManageController(wsgi.Controller): return self._view_builder.show(req, vol_type) @wsgi.action("update") - @wsgi.serializers(xml=types.VolumeTypeTemplate) def _update(self, req, id, body): # Update description for a given volume type. context = req.environ['cinder.context'] @@ -192,7 +189,6 @@ class Types_manage(extensions.ExtensionDescriptor): name = "TypesManage" alias = "os-types-manage" - namespace = "http://docs.openstack.org/volume/ext/types-manage/api/v1" updated = "2011-08-24T00:00:00+00:00" def get_controller_extensions(self): diff --git a/cinder/api/contrib/used_limits.py b/cinder/api/contrib/used_limits.py index d32967a3e7b..2665ed21da4 100644 --- a/cinder/api/contrib/used_limits.py +++ b/cinder/api/contrib/used_limits.py @@ -51,7 +51,6 @@ class Used_limits(extensions.ExtensionDescriptor): name = "UsedLimits" alias = 'os-used-limits' - namespace = "http://docs.openstack.org/volume/ext/used-limits/api/v1.1" updated = "2013-10-03T00:00:00+00:00" def get_controller_extensions(self): diff --git a/cinder/api/contrib/volume_actions.py b/cinder/api/contrib/volume_actions.py index 9737a212d87..684791d4eed 100644 --- a/cinder/api/contrib/volume_actions.py +++ b/cinder/api/contrib/volume_actions.py @@ -24,7 +24,6 @@ import webob from cinder.api import extensions from cinder.api.openstack import api_version_request from cinder.api.openstack import wsgi -from cinder.api import xmlutil from cinder import exception from cinder.i18n import _ from cinder import utils @@ -40,50 +39,6 @@ def authorize(context, action_name): extensions.extension_authorizer('volume', action)(context) -class VolumeToImageSerializer(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('os-volume_upload_image', - selector='os-volume_upload_image') - root.set('id') - root.set('updated_at') - root.set('status') - root.set('display_description') - root.set('size') - root.set('volume_type') - root.set('image_id') - root.set('container_format') - root.set('disk_format') - root.set('image_name') - root.set('protected') - if CONF.glance_api_version == 2: - root.set('visibility') - else: - root.set('is_public') - return xmlutil.MasterTemplate(root, 1) - - -class VolumeToImageDeserializer(wsgi.XMLDeserializer): - """Deserializer to handle xml-formatted requests.""" - def default(self, string): - dom = utils.safe_minidom_parse_string(string) - action_node = dom.childNodes[0] - action_name = action_node.tagName - - action_data = {} - attributes = ["force", "image_name", "container_format", "disk_format", - "protected"] - if CONF.glance_api_version == 2: - attributes.append('visibility') - else: - attributes.append('is_public') - for attr in attributes: - if action_node.hasAttribute(attr): - action_data[attr] = action_node.getAttribute(attr) - if 'force' in action_data and action_data['force'] == 'True': - action_data['force'] = True - return {'body': {action_name: action_data}} - - class VolumeActionsController(wsgi.Controller): def __init__(self, *args, **kwargs): super(VolumeActionsController, self).__init__(*args, **kwargs) @@ -261,8 +216,6 @@ class VolumeActionsController(wsgi.Controller): @wsgi.response(202) @wsgi.action('os-volume_upload_image') - @wsgi.serializers(xml=VolumeToImageSerializer) - @wsgi.deserializers(xml=VolumeToImageDeserializer) def _volume_upload_image(self, req, id, body): """Uploads the specified volume to image service.""" context = req.environ['cinder.context'] @@ -423,7 +376,6 @@ class Volume_actions(extensions.ExtensionDescriptor): name = "VolumeActions" alias = "os-volume-actions" - namespace = "http://docs.openstack.org/volume/ext/volume-actions/api/v1.1" updated = "2012-05-31T00:00:00+00:00" def get_controller_extensions(self): diff --git a/cinder/api/contrib/volume_encryption_metadata.py b/cinder/api/contrib/volume_encryption_metadata.py index 6ce2100bbb6..66f18277a5f 100644 --- a/cinder/api/contrib/volume_encryption_metadata.py +++ b/cinder/api/contrib/volume_encryption_metadata.py @@ -17,30 +17,21 @@ from cinder.api import extensions from cinder.api.openstack import wsgi -from cinder.api import xmlutil from cinder import db authorize = extensions.extension_authorizer('volume', 'volume_encryption_metadata') -class VolumeEncryptionMetadataTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.make_flat_dict('encryption', selector='encryption') - return xmlutil.MasterTemplate(root, 1) - - class VolumeEncryptionMetadataController(wsgi.Controller): """The volume encryption metadata API extension.""" - @wsgi.serializers(xml=VolumeEncryptionMetadataTemplate) def index(self, req, volume_id): """Returns the encryption metadata for a given volume.""" context = req.environ['cinder.context'] authorize(context) return db.volume_encryption_metadata_get(context, volume_id) - @wsgi.serializers(xml=VolumeEncryptionMetadataTemplate) def show(self, req, volume_id, id): """Return a single encryption item.""" encryption_item = self.index(req, volume_id) @@ -55,8 +46,6 @@ class Volume_encryption_metadata(extensions.ExtensionDescriptor): name = "VolumeEncryptionMetadata" alias = "os-volume-encryption-metadata" - namespace = ("http://docs.openstack.org/volume/ext/" - "os-volume-encryption-metadata/api/v1") updated = "2013-07-10T00:00:00+00:00" def get_resources(self): diff --git a/cinder/api/contrib/volume_host_attribute.py b/cinder/api/contrib/volume_host_attribute.py index 2367a530f92..4d8a0e7001a 100644 --- a/cinder/api/contrib/volume_host_attribute.py +++ b/cinder/api/contrib/volume_host_attribute.py @@ -16,7 +16,6 @@ from oslo_log import log as logging from cinder.api import extensions from cinder.api.openstack import wsgi -from cinder.api import xmlutil LOG = logging.getLogger(__name__) @@ -34,7 +33,6 @@ class VolumeHostAttributeController(wsgi.Controller): def show(self, req, resp_obj, id): context = req.environ['cinder.context'] if authorize(context): - resp_obj.attach(xml=VolumeHostAttributeTemplate()) volume = resp_obj.obj['volume'] self._add_volume_host_attribute(req, volume) @@ -42,7 +40,6 @@ class VolumeHostAttributeController(wsgi.Controller): def detail(self, req, resp_obj): context = req.environ['cinder.context'] if authorize(context): - resp_obj.attach(xml=VolumeListHostAttributeTemplate()) for vol in list(resp_obj.obj['volumes']): self._add_volume_host_attribute(req, vol) @@ -52,35 +49,9 @@ class Volume_host_attribute(extensions.ExtensionDescriptor): name = "VolumeHostAttribute" alias = "os-vol-host-attr" - namespace = ("http://docs.openstack.org/volume/ext/" - "volume_host_attribute/api/v2") updated = "2011-11-03T00:00:00+00:00" def get_controller_extensions(self): controller = VolumeHostAttributeController() extension = extensions.ControllerExtension(self, 'volumes', controller) return [extension] - - -def make_volume(elem): - elem.set('{%s}host' % Volume_host_attribute.namespace, - '%s:host' % Volume_host_attribute.alias) - - -class VolumeHostAttributeTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('volume', selector='volume') - make_volume(root) - alias = Volume_host_attribute.alias - namespace = Volume_host_attribute.namespace - return xmlutil.SlaveTemplate(root, 1, nsmap={alias: namespace}) - - -class VolumeListHostAttributeTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('volumes') - elem = xmlutil.SubTemplateElement(root, 'volume', selector='volumes') - make_volume(elem) - alias = Volume_host_attribute.alias - namespace = Volume_host_attribute.namespace - return xmlutil.SlaveTemplate(root, 1, nsmap={alias: namespace}) diff --git a/cinder/api/contrib/volume_image_metadata.py b/cinder/api/contrib/volume_image_metadata.py index c1113d041f6..8f9c4145021 100644 --- a/cinder/api/contrib/volume_image_metadata.py +++ b/cinder/api/contrib/volume_image_metadata.py @@ -20,7 +20,6 @@ from oslo_log import log as logging from cinder.api import common from cinder.api import extensions from cinder.api.openstack import wsgi -from cinder.api import xmlutil from cinder import exception from cinder.i18n import _ from cinder import volume @@ -75,22 +74,18 @@ class VolumeImageMetadataController(wsgi.Controller): def show(self, req, resp_obj, id): context = req.environ['cinder.context'] if authorize(context): - resp_obj.attach(xml=VolumeImageMetadataTemplate()) self._add_image_metadata(context, [resp_obj.obj['volume']]) @wsgi.extends def detail(self, req, resp_obj): context = req.environ['cinder.context'] if authorize(context): - resp_obj.attach(xml=VolumesImageMetadataTemplate()) # Just get the image metadata of those volumes in response. volumes = list(resp_obj.obj.get('volumes', [])) if volumes: self._add_image_metadata(context, volumes) @wsgi.action("os-set_image_metadata") - @wsgi.serializers(xml=common.MetadataTemplate) - @wsgi.deserializers(xml=common.MetadataDeserializer) def create(self, req, id, body): context = req.environ['cinder.context'] if authorize(context): @@ -130,7 +125,6 @@ class VolumeImageMetadataController(wsgi.Controller): raise webob.exc.HTTPRequestEntityTooLarge(explanation=error.msg) @wsgi.action("os-show_image_metadata") - @wsgi.serializers(xml=common.MetadataTemplate) def index(self, req, id, body): context = req.environ['cinder.context'] return {'metadata': self._get_image_metadata(context, id)[1]} @@ -167,46 +161,9 @@ class Volume_image_metadata(extensions.ExtensionDescriptor): name = "VolumeImageMetadata" alias = "os-vol-image-meta" - namespace = ("http://docs.openstack.org/volume/ext/" - "volume_image_metadata/api/v1") updated = "2012-12-07T00:00:00+00:00" def get_controller_extensions(self): controller = VolumeImageMetadataController() extension = extensions.ControllerExtension(self, 'volumes', controller) return [extension] - - -class VolumeImageMetadataMetadataTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('volume_image_metadata', - selector='volume_image_metadata') - elem = xmlutil.SubTemplateElement(root, 'meta', - selector=xmlutil.get_items) - elem.set('key', 0) - elem.text = 1 - - return xmlutil.MasterTemplate(root, 1) - - -class VolumeImageMetadataTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('volume', selector='volume') - root.append(VolumeImageMetadataMetadataTemplate()) - - alias = Volume_image_metadata.alias - namespace = Volume_image_metadata.namespace - - return xmlutil.SlaveTemplate(root, 1, nsmap={alias: namespace}) - - -class VolumesImageMetadataTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('volumes') - elem = xmlutil.SubTemplateElement(root, 'volume', selector='volume') - elem.append(VolumeImageMetadataMetadataTemplate()) - - alias = Volume_image_metadata.alias - namespace = Volume_image_metadata.namespace - - return xmlutil.SlaveTemplate(root, 1, nsmap={alias: namespace}) diff --git a/cinder/api/contrib/volume_manage.py b/cinder/api/contrib/volume_manage.py index 136812b809b..bb5734c4dc4 100644 --- a/cinder/api/contrib/volume_manage.py +++ b/cinder/api/contrib/volume_manage.py @@ -19,7 +19,6 @@ from webob import exc from cinder.api import extensions from cinder.api.openstack import wsgi from cinder.api.v2.views import volumes as volume_views -from cinder.api.v2 import volumes from cinder import exception from cinder.i18n import _ from cinder import utils @@ -40,8 +39,6 @@ class VolumeManageController(wsgi.Controller): self.volume_api = cinder_volume.API() @wsgi.response(202) - @wsgi.serializers(xml=volumes.VolumeTemplate) - @wsgi.deserializers(xml=volumes.CreateDeserializer) def create(self, req, body): """Instruct Cinder to manage a storage object. @@ -155,8 +152,6 @@ class Volume_manage(extensions.ExtensionDescriptor): name = 'VolumeManage' alias = 'os-volume-manage' - namespace = ('http://docs.openstack.org/volume/ext/' - 'os-volume-manage/api/v1') updated = '2014-02-10T00:00:00+00:00' def get_resources(self): diff --git a/cinder/api/contrib/volume_mig_status_attribute.py b/cinder/api/contrib/volume_mig_status_attribute.py index 9e7b6c380a4..ce2e6d1fa4c 100644 --- a/cinder/api/contrib/volume_mig_status_attribute.py +++ b/cinder/api/contrib/volume_mig_status_attribute.py @@ -14,8 +14,6 @@ from cinder.api import extensions from cinder.api.openstack import wsgi -from cinder.api import xmlutil - authorize = extensions.soft_extension_authorizer('volume', 'volume_mig_status_attribute') @@ -33,14 +31,12 @@ class VolumeMigStatusAttributeController(wsgi.Controller): def show(self, req, resp_obj, id): context = req.environ['cinder.context'] if authorize(context): - resp_obj.attach(xml=VolumeMigStatusAttributeTemplate()) self._add_volume_mig_status_attribute(req, resp_obj.obj['volume']) @wsgi.extends def detail(self, req, resp_obj): context = req.environ['cinder.context'] if authorize(context): - resp_obj.attach(xml=VolumeListMigStatusAttributeTemplate()) for vol in list(resp_obj.obj['volumes']): self._add_volume_mig_status_attribute(req, vol) @@ -50,37 +46,9 @@ class Volume_mig_status_attribute(extensions.ExtensionDescriptor): name = "VolumeMigStatusAttribute" alias = "os-vol-mig-status-attr" - namespace = ("http://docs.openstack.org/volume/ext/" - "volume_mig_status_attribute/api/v1") updated = "2013-08-08T00:00:00+00:00" def get_controller_extensions(self): controller = VolumeMigStatusAttributeController() extension = extensions.ControllerExtension(self, 'volumes', controller) return [extension] - - -def make_volume(elem): - elem.set('{%s}migstat' % Volume_mig_status_attribute.namespace, - '%s:migstat' % Volume_mig_status_attribute.alias) - elem.set('{%s}name_id' % Volume_mig_status_attribute.namespace, - '%s:name_id' % Volume_mig_status_attribute.alias) - - -class VolumeMigStatusAttributeTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('volume', selector='volume') - make_volume(root) - alias = Volume_mig_status_attribute.alias - namespace = Volume_mig_status_attribute.namespace - return xmlutil.SlaveTemplate(root, 1, nsmap={alias: namespace}) - - -class VolumeListMigStatusAttributeTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('volumes') - elem = xmlutil.SubTemplateElement(root, 'volume', selector='volumes') - make_volume(elem) - alias = Volume_mig_status_attribute.alias - namespace = Volume_mig_status_attribute.namespace - return xmlutil.SlaveTemplate(root, 1, nsmap={alias: namespace}) diff --git a/cinder/api/contrib/volume_tenant_attribute.py b/cinder/api/contrib/volume_tenant_attribute.py index bb51b6057fe..263704abc40 100644 --- a/cinder/api/contrib/volume_tenant_attribute.py +++ b/cinder/api/contrib/volume_tenant_attribute.py @@ -14,7 +14,6 @@ from cinder.api import extensions from cinder.api.openstack import wsgi -from cinder.api import xmlutil authorize = extensions.soft_extension_authorizer('volume', @@ -31,7 +30,6 @@ class VolumeTenantAttributeController(wsgi.Controller): def show(self, req, resp_obj, id): context = req.environ['cinder.context'] if authorize(context): - resp_obj.attach(xml=VolumeTenantAttributeTemplate()) volume = resp_obj.obj['volume'] self._add_volume_tenant_attribute(req, volume) @@ -39,7 +37,6 @@ class VolumeTenantAttributeController(wsgi.Controller): def detail(self, req, resp_obj): context = req.environ['cinder.context'] if authorize(context): - resp_obj.attach(xml=VolumeListTenantAttributeTemplate()) for vol in list(resp_obj.obj['volumes']): self._add_volume_tenant_attribute(req, vol) @@ -49,35 +46,9 @@ class Volume_tenant_attribute(extensions.ExtensionDescriptor): name = "VolumeTenantAttribute" alias = "os-vol-tenant-attr" - namespace = ("http://docs.openstack.org/volume/ext/" - "volume_tenant_attribute/api/v2") updated = "2011-11-03T00:00:00+00:00" def get_controller_extensions(self): controller = VolumeTenantAttributeController() extension = extensions.ControllerExtension(self, 'volumes', controller) return [extension] - - -def make_volume(elem): - elem.set('{%s}tenant_id' % Volume_tenant_attribute.namespace, - '%s:tenant_id' % Volume_tenant_attribute.alias) - - -class VolumeTenantAttributeTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('volume', selector='volume') - make_volume(root) - alias = Volume_tenant_attribute.alias - namespace = Volume_tenant_attribute.namespace - return xmlutil.SlaveTemplate(root, 1, nsmap={alias: namespace}) - - -class VolumeListTenantAttributeTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('volumes') - elem = xmlutil.SubTemplateElement(root, 'volume', selector='volumes') - make_volume(elem) - alias = Volume_tenant_attribute.alias - namespace = Volume_tenant_attribute.namespace - return xmlutil.SlaveTemplate(root, 1, nsmap={alias: namespace}) diff --git a/cinder/api/contrib/volume_transfer.py b/cinder/api/contrib/volume_transfer.py index d5700ae08df..fc7745c3bf0 100644 --- a/cinder/api/contrib/volume_transfer.py +++ b/cinder/api/contrib/volume_transfer.py @@ -21,79 +21,13 @@ from cinder.api import common from cinder.api import extensions from cinder.api.openstack import wsgi from cinder.api.views import transfers as transfer_view -from cinder.api import xmlutil from cinder import exception from cinder.i18n import _, _LI from cinder import transfer as transferAPI -from cinder import utils LOG = logging.getLogger(__name__) -def make_transfer(elem): - elem.set('id') - elem.set('volume_id') - elem.set('created_at') - elem.set('name') - elem.set('auth_key') - - -class TransferTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('transfer', selector='transfer') - make_transfer(root) - alias = Volume_transfer.alias - namespace = Volume_transfer.namespace - return xmlutil.MasterTemplate(root, 1, nsmap={alias: namespace}) - - -class TransfersTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('transfers') - elem = xmlutil.SubTemplateElement(root, 'transfer', - selector='transfers') - make_transfer(elem) - alias = Volume_transfer.alias - namespace = Volume_transfer.namespace - return xmlutil.MasterTemplate(root, 1, nsmap={alias: namespace}) - - -class CreateDeserializer(wsgi.MetadataXMLDeserializer): - def default(self, string): - dom = utils.safe_minidom_parse_string(string) - transfer = self._extract_transfer(dom) - return {'body': {'transfer': transfer}} - - def _extract_transfer(self, node): - transfer = {} - transfer_node = self.find_first_child_named(node, 'transfer') - - attributes = ['volume_id', 'name'] - - for attr in attributes: - if transfer_node.getAttribute(attr): - transfer[attr] = transfer_node.getAttribute(attr) - return transfer - - -class AcceptDeserializer(wsgi.MetadataXMLDeserializer): - def default(self, string): - dom = utils.safe_minidom_parse_string(string) - transfer = self._extract_transfer(dom) - return {'body': {'accept': transfer}} - - def _extract_transfer(self, node): - transfer = {} - transfer_node = self.find_first_child_named(node, 'accept') - - attributes = ['auth_key'] - - for attr in attributes: - if transfer_node.getAttribute(attr): - transfer[attr] = transfer_node.getAttribute(attr) - return transfer - - class VolumeTransferController(wsgi.Controller): """The Volume Transfer API controller for the OpenStack API.""" @@ -103,7 +37,6 @@ class VolumeTransferController(wsgi.Controller): self.transfer_api = transferAPI.API() super(VolumeTransferController, self).__init__() - @wsgi.serializers(xml=TransferTemplate) def show(self, req, id): """Return data about active transfers.""" context = req.environ['cinder.context'] @@ -115,12 +48,10 @@ class VolumeTransferController(wsgi.Controller): return self._view_builder.detail(req, transfer) - @wsgi.serializers(xml=TransfersTemplate) def index(self, req): """Returns a summary list of transfers.""" return self._get_transfers(req, is_detail=False) - @wsgi.serializers(xml=TransfersTemplate) def detail(self, req): """Returns a detailed list of transfers.""" return self._get_transfers(req, is_detail=True) @@ -144,8 +75,6 @@ class VolumeTransferController(wsgi.Controller): return transfers @wsgi.response(202) - @wsgi.serializers(xml=TransferTemplate) - @wsgi.deserializers(xml=CreateDeserializer) def create(self, req, body): """Create a new volume transfer.""" LOG.debug('Creating new volume transfer %s', body) @@ -183,8 +112,6 @@ class VolumeTransferController(wsgi.Controller): return transfer @wsgi.response(202) - @wsgi.serializers(xml=TransferTemplate) - @wsgi.deserializers(xml=AcceptDeserializer) def accept(self, req, id, body): """Accept a new volume transfer.""" transfer_id = id @@ -235,8 +162,6 @@ class Volume_transfer(extensions.ExtensionDescriptor): name = "VolumeTransfer" alias = "os-volume-transfer" - namespace = "http://docs.openstack.org/volume/ext/volume-transfer/" + \ - "api/v1.1" updated = "2013-05-29T00:00:00+00:00" def get_resources(self): diff --git a/cinder/api/contrib/volume_type_access.py b/cinder/api/contrib/volume_type_access.py index 82a84d53c77..56937900919 100644 --- a/cinder/api/contrib/volume_type_access.py +++ b/cinder/api/contrib/volume_type_access.py @@ -19,7 +19,6 @@ import webob from cinder.api import extensions from cinder.api.openstack import wsgi -from cinder.api import xmlutil from cinder import exception from cinder.i18n import _ from cinder.volume import volume_types @@ -30,45 +29,6 @@ soft_authorize = extensions.soft_extension_authorizer('volume', authorize = extensions.extension_authorizer('volume', 'volume_type_access') -def make_volume_type(elem): - elem.set('{%s}is_public' % Volume_type_access.namespace, - '%s:is_public' % Volume_type_access.alias) - - -def make_volume_type_access(elem): - elem.set('volume_type_id') - elem.set('project_id') - - -class VolumeTypeTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('volume_type', selector='volume_type') - make_volume_type(root) - alias = Volume_type_access.alias - namespace = Volume_type_access.namespace - return xmlutil.SlaveTemplate(root, 1, nsmap={alias: namespace}) - - -class VolumeTypesTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('volume_types') - elem = xmlutil.SubTemplateElement( - root, 'volume_type', selector='volume_types') - make_volume_type(elem) - alias = Volume_type_access.alias - namespace = Volume_type_access.namespace - return xmlutil.SlaveTemplate(root, 1, nsmap={alias: namespace}) - - -class VolumeTypeAccessTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('volume_type_access') - elem = xmlutil.SubTemplateElement(root, 'access', - selector='volume_type_access') - make_volume_type_access(elem) - return xmlutil.MasterTemplate(root, 1) - - def _marshall_volume_type_access(vol_type): rval = [] for project_id in vol_type['projects']: @@ -84,7 +44,6 @@ class VolumeTypeAccessController(object): def __init__(self): super(VolumeTypeAccessController, self).__init__() - @wsgi.serializers(xml=VolumeTypeAccessTemplate) def index(self, req, type_id): context = req.environ['cinder.context'] authorize(context) @@ -123,8 +82,6 @@ class VolumeTypeActionController(wsgi.Controller): def show(self, req, resp_obj, id): context = req.environ['cinder.context'] if soft_authorize(context): - # Attach our slave template to the response object - resp_obj.attach(xml=VolumeTypeTemplate()) vol_type = req.cached_resource_by_id(id, name='types') self._extend_vol_type(resp_obj.obj['volume_type'], vol_type) @@ -132,8 +89,6 @@ class VolumeTypeActionController(wsgi.Controller): def index(self, req, resp_obj): context = req.environ['cinder.context'] if soft_authorize(context): - # Attach our slave template to the response object - resp_obj.attach(xml=VolumeTypesTemplate()) for vol_type_rval in list(resp_obj.obj['volume_types']): type_id = vol_type_rval['id'] vol_type = req.cached_resource_by_id(type_id, name='types') @@ -143,8 +98,6 @@ class VolumeTypeActionController(wsgi.Controller): def detail(self, req, resp_obj): context = req.environ['cinder.context'] if soft_authorize(context): - # Attach our slave template to the response object - resp_obj.attach(xml=VolumeTypesTemplate()) for vol_type_rval in list(resp_obj.obj['volume_types']): type_id = vol_type_rval['id'] vol_type = req.cached_resource_by_id(type_id, name='types') @@ -154,8 +107,6 @@ class VolumeTypeActionController(wsgi.Controller): def create(self, req, body, resp_obj): context = req.environ['cinder.context'] if soft_authorize(context): - # Attach our slave template to the response object - resp_obj.attach(xml=VolumeTypeTemplate()) type_id = resp_obj.obj['volume_type']['id'] vol_type = req.cached_resource_by_id(type_id, name='types') self._extend_vol_type(resp_obj.obj['volume_type'], vol_type) @@ -195,8 +146,6 @@ class Volume_type_access(extensions.ExtensionDescriptor): name = "VolumeTypeAccess" alias = "os-volume-type-access" - namespace = ("http://docs.openstack.org/volume/" - "ext/os-volume-type-access/api/v1") updated = "2014-06-26T00:00:00Z" def get_resources(self): diff --git a/cinder/api/contrib/volume_type_encryption.py b/cinder/api/contrib/volume_type_encryption.py index 7750aa090a5..9ae05ce5021 100644 --- a/cinder/api/contrib/volume_type_encryption.py +++ b/cinder/api/contrib/volume_type_encryption.py @@ -19,7 +19,6 @@ import webob from cinder.api import extensions from cinder.api.openstack import wsgi -from cinder.api import xmlutil from cinder import db from cinder import exception from cinder.i18n import _ @@ -33,12 +32,6 @@ authorize = extensions.extension_authorizer('volume', CONTROL_LOCATION = ['front-end', 'back-end'] -class VolumeTypeEncryptionTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.make_flat_dict('encryption', selector='encryption') - return xmlutil.MasterTemplate(root, 1) - - class VolumeTypeEncryptionController(wsgi.Controller): """The volume type encryption API controller for the OpenStack API.""" @@ -89,7 +82,6 @@ class VolumeTypeEncryptionController(wsgi.Controller): else: return False - @wsgi.serializers(xml=VolumeTypeEncryptionTemplate) def index(self, req, type_id): """Returns the encryption specs for a given volume type.""" context = req.environ['cinder.context'] @@ -97,7 +89,6 @@ class VolumeTypeEncryptionController(wsgi.Controller): self._check_type(context, type_id) return self._get_volume_type_encryption(context, type_id) - @wsgi.serializers(xml=VolumeTypeEncryptionTemplate) def create(self, req, type_id, body=None): """Create encryption specs for an existing volume type.""" context = req.environ['cinder.context'] @@ -125,7 +116,6 @@ class VolumeTypeEncryptionController(wsgi.Controller): notifier.info(context, 'volume_type_encryption.create', notifier_info) return body - @wsgi.serializers(xml=VolumeTypeEncryptionTemplate) def update(self, req, type_id, id, body=None): """Update encryption specs for a given volume type.""" context = req.environ['cinder.context'] @@ -153,7 +143,6 @@ class VolumeTypeEncryptionController(wsgi.Controller): return body - @wsgi.serializers(xml=VolumeTypeEncryptionTemplate) def show(self, req, type_id, id): """Return a single encryption item.""" context = req.environ['cinder.context'] @@ -190,8 +179,6 @@ class Volume_type_encryption(extensions.ExtensionDescriptor): name = "VolumeTypeEncryption" alias = "encryption" - namespace = ("http://docs.openstack.org/volume/ext/" - "volume-type-encryption/api/v1") updated = "2013-07-01T00:00:00+00:00" def get_resources(self): diff --git a/cinder/api/contrib/volume_unmanage.py b/cinder/api/contrib/volume_unmanage.py index 72b5c7fa1ca..0e156d76ef0 100644 --- a/cinder/api/contrib/volume_unmanage.py +++ b/cinder/api/contrib/volume_unmanage.py @@ -66,7 +66,6 @@ class Volume_unmanage(extensions.ExtensionDescriptor): name = "VolumeUnmanage" alias = "os-volume-unmanage" - namespace = "http://docs.openstack.org/volume/ext/volume-unmanage/api/v1.1" updated = "2012-05-31T00:00:00+00:00" def get_controller_extensions(self): diff --git a/cinder/api/extensions.py b/cinder/api/extensions.py index 20af44c0cf1..bf8cc96e937 100644 --- a/cinder/api/extensions.py +++ b/cinder/api/extensions.py @@ -24,7 +24,6 @@ import webob.exc import cinder.api.openstack from cinder.api.openstack import wsgi -from cinder.api import xmlutil from cinder import exception from cinder.i18n import _LE, _LI, _LW import cinder.policy @@ -49,12 +48,6 @@ class ExtensionDescriptor(object): # The alias for the extension, e.g., 'FOXNSOX' alias = None - # Description comes from the docstring for the class - - # The XML namespace for the extension, e.g., - # 'http://www.fox.in.socks/api/ext/pie/v1.0' - namespace = None - # The timestamp when the extension was last updated, e.g., # '2011-01-22T13:25:27-06:00' updated = None @@ -82,55 +75,6 @@ class ExtensionDescriptor(object): controller_exts = [] return controller_exts - @classmethod - def nsmap(cls): - """Synthesize a namespace map from extension.""" - - # Start with a base nsmap - nsmap = ext_nsmap.copy() - - # Add the namespace for the extension - nsmap[cls.alias] = cls.namespace - - return nsmap - - @classmethod - def xmlname(cls, name): - """Synthesize element and attribute names.""" - - return '{%s}%s' % (cls.namespace, name) - - -def make_ext(elem): - elem.set('name') - elem.set('namespace') - elem.set('alias') - elem.set('updated') - - desc = xmlutil.SubTemplateElement(elem, 'description') - desc.text = 'description' - - xmlutil.make_links(elem, 'links') - - -ext_nsmap = {None: xmlutil.XMLNS_COMMON_V10, 'atom': xmlutil.XMLNS_ATOM} - - -class ExtensionTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('extension', selector='extension') - make_ext(root) - return xmlutil.MasterTemplate(root, 1, nsmap=ext_nsmap) - - -class ExtensionsTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('extensions') - elem = xmlutil.SubTemplateElement(root, 'extension', - selector='extensions') - make_ext(elem) - return xmlutil.MasterTemplate(root, 1, nsmap=ext_nsmap) - class ExtensionsResource(wsgi.Resource): @@ -143,19 +87,16 @@ class ExtensionsResource(wsgi.Resource): ext_data['name'] = ext.name ext_data['alias'] = ext.alias ext_data['description'] = ext.__doc__ - ext_data['namespace'] = ext.namespace ext_data['updated'] = ext.updated ext_data['links'] = [] # TODO(dprince): implement extension links return ext_data - @wsgi.serializers(xml=ExtensionsTemplate) def index(self, req): extensions = [] for _alias, ext in self.extension_manager.extensions.items(): extensions.append(self._translate(ext)) return dict(extensions=extensions) - @wsgi.serializers(xml=ExtensionTemplate) def show(self, req, id): try: # NOTE(dprince): the extensions alias is used as the 'id' for show @@ -238,7 +179,6 @@ class ExtensionManager(object): LOG.debug('Ext alias: %s', extension.alias) LOG.debug('Ext description: %s', ' '.join(extension.__doc__.strip().split())) - LOG.debug('Ext namespace: %s', extension.namespace) LOG.debug('Ext updated: %s', extension.updated) except AttributeError: LOG.exception(_LE("Exception loading extension.")) diff --git a/cinder/api/openstack/__init__.py b/cinder/api/openstack/__init__.py index fabd12aaed3..1d7152b5b10 100644 --- a/cinder/api/openstack/__init__.py +++ b/cinder/api/openstack/__init__.py @@ -38,11 +38,11 @@ class APIMapper(routes.Mapper): def connect(self, *args, **kwargs): # NOTE(inhye): Default the format part of a route to only accept json - # and xml so it doesn't eat all characters after a '.' + # so it doesn't eat all characters after a '.' # in the url. kwargs.setdefault('requirements', {}) if not kwargs['requirements'].get('format'): - kwargs['requirements']['format'] = 'json|xml' + kwargs['requirements']['format'] = 'json' return routes.Mapper.connect(self, *args, **kwargs) diff --git a/cinder/api/openstack/wsgi.py b/cinder/api/openstack/wsgi.py index 67a54cb373f..c715271370c 100644 --- a/cinder/api/openstack/wsgi.py +++ b/cinder/api/openstack/wsgi.py @@ -18,12 +18,8 @@ import functools import inspect import math import time -from xml.dom import minidom -from xml.parsers import expat -from lxml import etree from oslo_log import log as logging -from oslo_log import versionutils from oslo_serialization import jsonutils from oslo_utils import encodeutils from oslo_utils import excutils @@ -41,26 +37,16 @@ from cinder import utils from cinder.wsgi import common as wsgi -XML_NS_V1 = 'http://docs.openstack.org/api/openstack-block-storage/1.0/content' -XML_NS_V2 = 'http://docs.openstack.org/api/openstack-block-storage/2.0/content' -XML_NS_ATOM = 'http://www.w3.org/2005/Atom' -XML_WARNING = False - LOG = logging.getLogger(__name__) SUPPORTED_CONTENT_TYPES = ( 'application/json', 'application/vnd.openstack.volume+json', - 'application/xml', - 'application/vnd.openstack.volume+xml', ) _MEDIA_TYPE_MAP = { 'application/vnd.openstack.volume+json': 'json', 'application/json': 'json', - 'application/vnd.openstack.volume+xml': 'xml', - 'application/xml': 'xml', - 'application/atom+xml': 'atom', } @@ -372,95 +358,6 @@ class JSONDeserializer(TextDeserializer): return {'body': self._from_json(datastring)} -class XMLDeserializer(TextDeserializer): - - def __init__(self, metadata=None): - """Initialize XMLDeserializer. - - :param metadata: information needed to deserialize xml into - a dictionary. - """ - super(XMLDeserializer, self).__init__() - self.metadata = metadata or {} - - def _from_xml(self, datastring): - plurals = set(self.metadata.get('plurals', {})) - - try: - node = utils.safe_minidom_parse_string(datastring).childNodes[0] - return {node.nodeName: self._from_xml_node(node, plurals)} - except expat.ExpatError: - msg = _("cannot understand XML") - raise exception.MalformedRequestBody(reason=msg) - - def _from_xml_node(self, node, listnames): - """Convert a minidom node to a simple Python type. - - :param listnames: list of XML node names whose subnodes should - be considered list items. - """ - if len(node.childNodes) == 1 and node.childNodes[0].nodeType == 3: - return node.childNodes[0].nodeValue - elif node.nodeName in listnames: - return [self._from_xml_node(n, listnames) for n in node.childNodes] - else: - result = dict() - for attr in node.attributes.keys(): - result[attr] = node.attributes[attr].nodeValue - for child in node.childNodes: - if child.nodeType != node.TEXT_NODE: - result[child.nodeName] = self._from_xml_node(child, - listnames) - return result - - def find_first_child_named_in_namespace(self, parent, namespace, name): - """Search a nodes children for the first child with a given name.""" - for node in parent.childNodes: - if (node.localName == name and - node.namespaceURI and - node.namespaceURI == namespace): - return node - return None - - def find_first_child_named(self, parent, name): - """Search a nodes children for the first child with a given name.""" - for node in parent.childNodes: - if node.nodeName == name: - return node - return None - - def find_children_named(self, parent, name): - """Return all of a nodes children who have the given name.""" - for node in parent.childNodes: - if node.nodeName == name: - yield node - - def extract_text(self, node): - """Get the text field contained by the given node.""" - text = [] - # Cannot assume entire text will be in a single child node because SAX - # parsers may split contiguous character data into multiple chunks - for child in node.childNodes: - if child.nodeType == child.TEXT_NODE: - text.append(child.nodeValue) - return ''.join(text) - - def default(self, datastring): - return {'body': self._from_xml(datastring)} - - -class MetadataXMLDeserializer(XMLDeserializer): - - def extract_metadata(self, metadata_node): - """Marshal the metadata attribute of a parsed request.""" - metadata = {} - if metadata_node is not None: - for meta_node in self.find_children_named(metadata_node, "meta"): - key = meta_node.getAttribute("key") - metadata[key] = self.extract_text(meta_node) - return metadata - - class DictSerializer(ActionDispatcher): """Default request body serialization.""" @@ -478,111 +375,6 @@ class JSONDictSerializer(DictSerializer): return jsonutils.dump_as_bytes(data) -class XMLDictSerializer(DictSerializer): - - def __init__(self, metadata=None, xmlns=None): - """Initialize XMLDictSerializer. - - :param metadata: information needed to deserialize xml into - a dictionary. - :param xmlns: XML namespace to include with serialized xml - """ - super(XMLDictSerializer, self).__init__() - self.metadata = metadata or {} - self.xmlns = xmlns - - def default(self, data): - # We expect data to contain a single key which is the XML root. - root_key = list(data.keys())[0] - doc = minidom.Document() - node = self._to_xml_node(doc, self.metadata, root_key, data[root_key]) - - return self.to_xml_string(node) - - def to_xml_string(self, node, has_atom=False): - self._add_xmlns(node, has_atom) - return node.toxml('UTF-8') - - # NOTE (ameade): the has_atom should be removed after all of the - # xml serializers and view builders have been updated to the current - # spec that required all responses include the xmlns:atom, the has_atom - # flag is to prevent current tests from breaking - def _add_xmlns(self, node, has_atom=False): - if self.xmlns is not None: - node.setAttribute('xmlns', self.xmlns) - if has_atom: - node.setAttribute('xmlns:atom', "http://www.w3.org/2005/Atom") - - def _to_xml_node(self, doc, metadata, nodename, data): - """Recursive method to convert data members to XML nodes.""" - result = doc.createElement(nodename) - - # Set the xml namespace if one is specified - # TODO(justinsb): We could also use prefixes on the keys - xmlns = metadata.get('xmlns', None) - if xmlns: - result.setAttribute('xmlns', xmlns) - - # TODO(bcwaldon): accomplish this without a type-check - if isinstance(data, list): - collections = metadata.get('list_collections', {}) - if nodename in collections: - metadata = collections[nodename] - for item in data: - node = doc.createElement(metadata['item_name']) - node.setAttribute(metadata['item_key'], str(item)) - result.appendChild(node) - return result - singular = metadata.get('plurals', {}).get(nodename, None) - if singular is None: - if nodename.endswith('s'): - singular = nodename[:-1] - else: - singular = 'item' - for item in data: - node = self._to_xml_node(doc, metadata, singular, item) - result.appendChild(node) - # TODO(bcwaldon): accomplish this without a type-check - elif isinstance(data, dict): - collections = metadata.get('dict_collections', {}) - if nodename in collections: - metadata = collections[nodename] - for k, v in sorted(data.items()): - node = doc.createElement(metadata['item_name']) - node.setAttribute(metadata['item_key'], str(k)) - text = doc.createTextNode(str(v)) - node.appendChild(text) - result.appendChild(node) - return result - attrs = metadata.get('attributes', {}).get(nodename, {}) - for k, v in sorted(data.items()): - if k in attrs: - result.setAttribute(k, str(v)) - else: - node = self._to_xml_node(doc, metadata, k, v) - result.appendChild(node) - else: - # Type is atom - node = doc.createTextNode(str(data)) - result.appendChild(node) - return result - - def _create_link_nodes(self, xml_doc, links): - link_nodes = [] - for link in links: - link_node = xml_doc.createElement('atom:link') - link_node.setAttribute('rel', link['rel']) - link_node.setAttribute('href', link['href']) - if 'type' in link: - link_node.setAttribute('type', link['type']) - link_nodes.append(link_node) - return link_nodes - - def _to_xml(self, root): - """Convert the xml object to an xml string.""" - return etree.tostring(root, encoding='UTF-8', xml_declaration=True) - - def serializers(**serializers): """Attaches serializers to a method. @@ -784,15 +576,6 @@ def action_peek_json(body): return list(decoded.keys())[0] -def action_peek_xml(body): - """Determine action to invoke.""" - - dom = utils.safe_minidom_parse_string(body) - action_node = dom.childNodes[0] - - return action_node.tagName - - class ResourceExceptionHandler(object): """Context manager to handle Resource exceptions. @@ -859,16 +642,13 @@ class Resource(wsgi.Application): self.controller = controller - default_deserializers = dict(xml=XMLDeserializer, - json=JSONDeserializer) + default_deserializers = dict(json=JSONDeserializer) default_deserializers.update(deserializers) self.default_deserializers = default_deserializers - self.default_serializers = dict(xml=XMLDictSerializer, - json=JSONDictSerializer) + self.default_serializers = dict(json=JSONDictSerializer) - self.action_peek = dict(xml=action_peek_xml, - json=action_peek_json) + self.action_peek = dict(json=action_peek_json) self.action_peek.update(action_peek or {}) # Copy over the actions dictionary @@ -1542,25 +1322,11 @@ class Fault(webob.exc.HTTPException): req.api_version_request.get_string()) self.wrapped_exc.headers['Vary'] = API_VERSION_REQUEST_HEADER - # 'code' is an attribute on the fault tag itself - metadata = {'attributes': {fault_name: 'code'}} - - xml_serializer = XMLDictSerializer(metadata, XML_NS_V2) - content_type = req.best_match_content_type() serializer = { - 'application/xml': xml_serializer, 'application/json': JSONDictSerializer(), }[content_type] - if content_type == 'application/xml': - global XML_WARNING - if not XML_WARNING: - msg = _('XML support has been deprecated and will be removed ' - 'in the N release.') - versionutils.report_deprecated_feature(LOG, msg) - XML_WARNING = True - body = serializer.serialize(fault_data) if isinstance(body, six.text_type): body = body.encode('utf-8') @@ -1606,7 +1372,6 @@ class OverLimitFault(webob.exc.HTTPException): def __call__(self, request): """Serializes the wrapped exception conforming to our error format.""" content_type = request.best_match_content_type() - metadata = {"attributes": {"overLimitFault": "code"}} def translate(msg): locale = request.best_match_language() @@ -1617,9 +1382,7 @@ class OverLimitFault(webob.exc.HTTPException): self.content['overLimitFault']['details'] = \ translate(self.content['overLimitFault']['details']) - xml_serializer = XMLDictSerializer(metadata, XML_NS_V2) serializer = { - 'application/xml': xml_serializer, 'application/json': JSONDictSerializer(), }[content_type] diff --git a/cinder/api/schemas/atom-link.rng b/cinder/api/schemas/atom-link.rng deleted file mode 100644 index edba5eee6c4..00000000000 --- a/cinder/api/schemas/atom-link.rng +++ /dev/null @@ -1,141 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - [^:]* - - - - - - .+/.+ - - - - - - [A-Za-z]{1,8}(-[A-Za-z0-9]{1,8})* - - - - - - - - - - - - xml:base - xml:lang - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/cinder/api/schemas/v1.1/extension.rng b/cinder/api/schemas/v1.1/extension.rng deleted file mode 100644 index b16d8c13006..00000000000 --- a/cinder/api/schemas/v1.1/extension.rng +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - diff --git a/cinder/api/schemas/v1.1/extensions.rng b/cinder/api/schemas/v1.1/extensions.rng deleted file mode 100644 index 8538eaf2dad..00000000000 --- a/cinder/api/schemas/v1.1/extensions.rng +++ /dev/null @@ -1,6 +0,0 @@ - - - - - diff --git a/cinder/api/schemas/v1.1/limits.rng b/cinder/api/schemas/v1.1/limits.rng deleted file mode 100644 index a66af4b9c47..00000000000 --- a/cinder/api/schemas/v1.1/limits.rng +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/cinder/api/schemas/v1.1/metadata.rng b/cinder/api/schemas/v1.1/metadata.rng deleted file mode 100644 index b2f5d702a2f..00000000000 --- a/cinder/api/schemas/v1.1/metadata.rng +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - diff --git a/cinder/api/schemas/v1.1/qos_association.rng b/cinder/api/schemas/v1.1/qos_association.rng deleted file mode 100644 index 20d975c01a8..00000000000 --- a/cinder/api/schemas/v1.1/qos_association.rng +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/cinder/api/schemas/v1.1/qos_associations.rng b/cinder/api/schemas/v1.1/qos_associations.rng deleted file mode 100644 index 3d218f88119..00000000000 --- a/cinder/api/schemas/v1.1/qos_associations.rng +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/cinder/api/schemas/v1.1/qos_spec.rng b/cinder/api/schemas/v1.1/qos_spec.rng deleted file mode 100644 index c82741fc36e..00000000000 --- a/cinder/api/schemas/v1.1/qos_spec.rng +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/cinder/api/schemas/v1.1/qos_specs.rng b/cinder/api/schemas/v1.1/qos_specs.rng deleted file mode 100644 index 974e7debc90..00000000000 --- a/cinder/api/schemas/v1.1/qos_specs.rng +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/cinder/api/urlmap.py b/cinder/api/urlmap.py index 1a3cc6055a8..ade7e1a6683 100644 --- a/cinder/api/urlmap.py +++ b/cinder/api/urlmap.py @@ -258,7 +258,7 @@ class URLMap(paste.urlmap.URLMap): # The MIME type for the response is determined in one of two ways: # 1) URL path suffix (eg /servers/detail.json) - # 2) Accept header (eg application/json;q=0.8, application/xml;q=0.2) + # 2) Accept header (eg application/json;q=0.8) # The API version is determined in one of three ways: # 1) URL path prefix (eg /v1.1/tenant/servers/detail) @@ -269,11 +269,6 @@ class URLMap(paste.urlmap.URLMap): mime_type, app, app_url = self._path_strategy(host, port, path_info) - # Accept application/atom+xml for the index query of each API - # version mount point as well as the root index - if (app_url and app_url + '/' == path_info) or path_info == '/': - supported_content_types.append('application/atom+xml') - if not app: app = self._content_type_strategy(host, port, environ) diff --git a/cinder/api/v1/limits.py b/cinder/api/v1/limits.py index f1143d7f646..20f432414e5 100644 --- a/cinder/api/v1/limits.py +++ b/cinder/api/v1/limits.py @@ -31,7 +31,6 @@ import webob.exc from cinder.api.openstack import wsgi from cinder.api.views import limits as limits_views -from cinder.api import xmlutil from cinder.i18n import _ from cinder import quota from cinder.wsgi import common as base_wsgi @@ -47,38 +46,9 @@ PER_HOUR = 60 * 60 PER_DAY = 60 * 60 * 24 -limits_nsmap = {None: xmlutil.XMLNS_COMMON_V10, 'atom': xmlutil.XMLNS_ATOM} - - -class LimitsTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('limits', selector='limits') - - rates = xmlutil.SubTemplateElement(root, 'rates') - rate = xmlutil.SubTemplateElement(rates, 'rate', selector='rate') - rate.set('uri', 'uri') - rate.set('regex', 'regex') - limit = xmlutil.SubTemplateElement(rate, 'limit', selector='limit') - limit.set('value', 'value') - limit.set('verb', 'verb') - limit.set('remaining', 'remaining') - limit.set('unit', 'unit') - limit.set('next-available', 'next-available') - - absolute = xmlutil.SubTemplateElement(root, 'absolute', - selector='absolute') - limit = xmlutil.SubTemplateElement(absolute, 'limit', - selector=xmlutil.get_items) - limit.set('name', 0) - limit.set('value', 1) - - return xmlutil.MasterTemplate(root, 1, nsmap=limits_nsmap) - - class LimitsController(wsgi.Controller): """Controller for accessing limits in the OpenStack API.""" - @wsgi.serializers(xml=LimitsTemplate) def index(self, req): """Return all global and rate limit information.""" context = req.environ['cinder.context'] diff --git a/cinder/api/v1/snapshot_metadata.py b/cinder/api/v1/snapshot_metadata.py index 18c2dd4a0c5..8bbf1f8c0be 100644 --- a/cinder/api/v1/snapshot_metadata.py +++ b/cinder/api/v1/snapshot_metadata.py @@ -16,7 +16,6 @@ import webob from webob import exc -from cinder.api import common from cinder.api.openstack import wsgi from cinder import exception from cinder.i18n import _ @@ -39,14 +38,11 @@ class Controller(wsgi.Controller): raise exc.HTTPNotFound(explanation=msg) return meta - @wsgi.serializers(xml=common.MetadataTemplate) def index(self, req, snapshot_id): """Returns the list of metadata for a given snapshot.""" context = req.environ['cinder.context'] return {'metadata': self._get_metadata(context, snapshot_id)} - @wsgi.serializers(xml=common.MetadataTemplate) - @wsgi.deserializers(xml=common.MetadataDeserializer) def create(self, req, snapshot_id, body): try: metadata = body['metadata'] @@ -63,8 +59,6 @@ class Controller(wsgi.Controller): return {'metadata': new_metadata} - @wsgi.serializers(xml=common.MetaItemTemplate) - @wsgi.deserializers(xml=common.MetaItemDeserializer) def update(self, req, snapshot_id, id, body): try: meta_item = body['meta'] @@ -88,8 +82,6 @@ class Controller(wsgi.Controller): return {'meta': meta_item} - @wsgi.serializers(xml=common.MetadataTemplate) - @wsgi.deserializers(xml=common.MetadataDeserializer) def update_all(self, req, snapshot_id, body): try: metadata = body['metadata'] @@ -128,7 +120,6 @@ class Controller(wsgi.Controller): except exception.InvalidVolumeMetadataSize as error: raise exc.HTTPRequestEntityTooLarge(explanation=error.msg) - @wsgi.serializers(xml=common.MetaItemTemplate) def show(self, req, snapshot_id, id): """Return a single metadata item.""" context = req.environ['cinder.context'] diff --git a/cinder/api/v1/snapshots.py b/cinder/api/v1/snapshots.py index 097f429c292..e7b63178f0a 100644 --- a/cinder/api/v1/snapshots.py +++ b/cinder/api/v1/snapshots.py @@ -22,7 +22,6 @@ from webob import exc from cinder.api import common from cinder.api.openstack import wsgi -from cinder.api import xmlutil from cinder import exception from cinder.i18n import _, _LI from cinder import utils @@ -61,33 +60,6 @@ def _translate_snapshot_summary_view(snapshot): return d -def make_snapshot(elem): - elem.set('id') - elem.set('status') - elem.set('size') - elem.set('created_at') - elem.set('display_name') - elem.set('display_description') - elem.set('volume_id') - elem.append(common.MetadataTemplate()) - - -class SnapshotTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('snapshot', selector='snapshot') - make_snapshot(root) - return xmlutil.MasterTemplate(root, 1) - - -class SnapshotsTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('snapshots') - elem = xmlutil.SubTemplateElement(root, 'snapshot', - selector='snapshots') - make_snapshot(elem) - return xmlutil.MasterTemplate(root, 1) - - class SnapshotsController(wsgi.Controller): """The Snapshots API controller for the OpenStack API.""" @@ -96,7 +68,6 @@ class SnapshotsController(wsgi.Controller): self.ext_mgr = ext_mgr super(SnapshotsController, self).__init__() - @wsgi.serializers(xml=SnapshotTemplate) def show(self, req, id): """Return data about the given snapshot.""" context = req.environ['cinder.context'] @@ -122,12 +93,10 @@ class SnapshotsController(wsgi.Controller): raise exc.HTTPNotFound() return webob.Response(status_int=202) - @wsgi.serializers(xml=SnapshotsTemplate) def index(self, req): """Returns a summary list of snapshots.""" return self._items(req, entity_maker=_translate_snapshot_summary_view) - @wsgi.serializers(xml=SnapshotsTemplate) def detail(self, req): """Returns a detailed list of snapshots.""" return self._items(req, entity_maker=_translate_snapshot_detail_view) @@ -153,7 +122,6 @@ class SnapshotsController(wsgi.Controller): res = [entity_maker(snapshot) for snapshot in limited_list] return {'snapshots': res} - @wsgi.serializers(xml=SnapshotTemplate) def create(self, req, body): """Creates a new snapshot.""" kwargs = {} @@ -204,7 +172,6 @@ class SnapshotsController(wsgi.Controller): return {'snapshot': retval} - @wsgi.serializers(xml=SnapshotTemplate) def update(self, req, id, body): """Update a snapshot.""" context = req.environ['cinder.context'] diff --git a/cinder/api/v1/types.py b/cinder/api/v1/types.py index b28cb017daf..fe207253bb7 100644 --- a/cinder/api/v1/types.py +++ b/cinder/api/v1/types.py @@ -19,40 +19,15 @@ from webob import exc from cinder.api.openstack import wsgi from cinder.api.views import types as views_types -from cinder.api import xmlutil from cinder import exception from cinder.volume import volume_types -def make_voltype(elem): - elem.set('id') - elem.set('name') - extra_specs = xmlutil.make_flat_dict('extra_specs', selector='extra_specs') - elem.append(extra_specs) - - -class VolumeTypeTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('volume_type', selector='volume_type') - make_voltype(root) - return xmlutil.MasterTemplate(root, 1) - - -class VolumeTypesTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('volume_types') - elem = xmlutil.SubTemplateElement(root, 'volume_type', - selector='volume_types') - make_voltype(elem) - return xmlutil.MasterTemplate(root, 1) - - class VolumeTypesController(wsgi.Controller): """The volume types API controller for the OpenStack API.""" _view_builder_class = views_types.ViewBuilder - @wsgi.serializers(xml=VolumeTypesTemplate) def index(self, req): """Returns the list of volume types.""" context = req.environ['cinder.context'] @@ -61,7 +36,6 @@ class VolumeTypesController(wsgi.Controller): req.cache_resource(vol_types, name='types') return self._view_builder.index(req, vol_types) - @wsgi.serializers(xml=VolumeTypeTemplate) def show(self, req, id): """Return a single volume type item.""" context = req.environ['cinder.context'] diff --git a/cinder/api/v1/volume_metadata.py b/cinder/api/v1/volume_metadata.py index b4f0bb3d5d4..c42f28f5a2b 100644 --- a/cinder/api/v1/volume_metadata.py +++ b/cinder/api/v1/volume_metadata.py @@ -16,7 +16,6 @@ import webob from webob import exc -from cinder.api import common from cinder.api.openstack import wsgi from cinder import exception from cinder.i18n import _ @@ -39,14 +38,11 @@ class Controller(wsgi.Controller): raise exc.HTTPNotFound(explanation=msg) return meta - @wsgi.serializers(xml=common.MetadataTemplate) def index(self, req, volume_id): """Returns the list of metadata for a given volume.""" context = req.environ['cinder.context'] return {'metadata': self._get_metadata(context, volume_id)} - @wsgi.serializers(xml=common.MetadataTemplate) - @wsgi.deserializers(xml=common.MetadataDeserializer) def create(self, req, volume_id, body): try: metadata = body['metadata'] @@ -63,8 +59,6 @@ class Controller(wsgi.Controller): return {'metadata': new_metadata} - @wsgi.serializers(xml=common.MetaItemTemplate) - @wsgi.deserializers(xml=common.MetaItemDeserializer) def update(self, req, volume_id, id, body): try: meta_item = body['meta'] @@ -88,8 +82,6 @@ class Controller(wsgi.Controller): return {'meta': meta_item} - @wsgi.serializers(xml=common.MetadataTemplate) - @wsgi.deserializers(xml=common.MetadataDeserializer) def update_all(self, req, volume_id, body): try: metadata = body['metadata'] @@ -128,7 +120,6 @@ class Controller(wsgi.Controller): except exception.InvalidVolumeMetadataSize as error: raise exc.HTTPRequestEntityTooLarge(explanation=error.msg) - @wsgi.serializers(xml=common.MetaItemTemplate) def show(self, req, volume_id, id): """Return a single metadata item.""" context = req.environ['cinder.context'] diff --git a/cinder/api/v1/volumes.py b/cinder/api/v1/volumes.py index 9a9de03d909..fc29fe5b070 100644 --- a/cinder/api/v1/volumes.py +++ b/cinder/api/v1/volumes.py @@ -24,7 +24,6 @@ from webob import exc from cinder.api import common from cinder.api.openstack import wsgi -from cinder.api import xmlutil from cinder import exception from cinder.i18n import _, _LI from cinder import utils @@ -126,97 +125,6 @@ def _translate_volume_summary_view(context, vol, image_id=None): return d -def make_attachment(elem): - elem.set('id') - elem.set('server_id') - elem.set('host_name') - elem.set('volume_id') - elem.set('device') - - -def make_volume(elem): - elem.set('id') - elem.set('status') - elem.set('size') - elem.set('availability_zone') - elem.set('created_at') - elem.set('display_name') - elem.set('bootable') - elem.set('display_description') - elem.set('volume_type') - elem.set('snapshot_id') - elem.set('source_volid') - elem.set('multiattach') - - attachments = xmlutil.SubTemplateElement(elem, 'attachments') - attachment = xmlutil.SubTemplateElement(attachments, 'attachment', - selector='attachments') - make_attachment(attachment) - - # Attach metadata node - elem.append(common.MetadataTemplate()) - - -volume_nsmap = {None: xmlutil.XMLNS_VOLUME_V1, 'atom': xmlutil.XMLNS_ATOM} - - -class VolumeTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('volume', selector='volume') - make_volume(root) - return xmlutil.MasterTemplate(root, 1, nsmap=volume_nsmap) - - -class VolumesTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('volumes') - elem = xmlutil.SubTemplateElement(root, 'volume', selector='volumes') - make_volume(elem) - return xmlutil.MasterTemplate(root, 1, nsmap=volume_nsmap) - - -class CommonDeserializer(wsgi.MetadataXMLDeserializer): - """Common deserializer to handle xml-formatted volume requests. - - Handles standard volume attributes as well as the optional metadata - attribute - """ - - metadata_deserializer = common.MetadataXMLDeserializer() - - def _extract_volume(self, node): - """Marshal the volume attribute of a parsed request.""" - volume = {} - volume_node = self.find_first_child_named(node, 'volume') - - attributes = ['display_name', 'display_description', 'size', - 'volume_type', 'availability_zone', 'imageRef', - 'snapshot_id', 'source_volid'] - for attr in attributes: - if volume_node.getAttribute(attr): - volume[attr] = volume_node.getAttribute(attr) - - metadata_node = self.find_first_child_named(volume_node, 'metadata') - if metadata_node is not None: - volume['metadata'] = self.extract_metadata(metadata_node) - - return volume - - -class CreateDeserializer(CommonDeserializer): - """Deserializer to handle xml-formatted create volume requests. - - Handles standard volume attributes as well as the optional metadata - attribute - """ - - def default(self, string): - """Deserialize an xml-formatted volume create request.""" - dom = utils.safe_minidom_parse_string(string) - volume = self._extract_volume(dom) - return {'body': {'volume': volume}} - - class VolumeController(wsgi.Controller): """The Volumes API controller for the OpenStack API.""" @@ -225,7 +133,6 @@ class VolumeController(wsgi.Controller): self.ext_mgr = ext_mgr super(VolumeController, self).__init__() - @wsgi.serializers(xml=VolumeTemplate) def show(self, req, id): """Return data about the given volume.""" context = req.environ['cinder.context'] @@ -253,12 +160,10 @@ class VolumeController(wsgi.Controller): raise exc.HTTPNotFound() return webob.Response(status_int=202) - @wsgi.serializers(xml=VolumesTemplate) def index(self, req): """Returns a summary list of volumes.""" return self._items(req, entity_maker=_translate_volume_summary_view) - @wsgi.serializers(xml=VolumesTemplate) def detail(self, req): """Returns a detailed list of volumes.""" return self._items(req, entity_maker=_translate_volume_detail_view) @@ -312,8 +217,6 @@ class VolumeController(wsgi.Controller): return image_uuid - @wsgi.serializers(xml=VolumeTemplate) - @wsgi.deserializers(xml=CreateDeserializer) def create(self, req, body): """Creates a new volume.""" if not self.is_valid_body(body, 'volume'): @@ -400,7 +303,6 @@ class VolumeController(wsgi.Controller): """Return volume search options allowed by non-admin.""" return ('display_name', 'status', 'metadata') - @wsgi.serializers(xml=VolumeTemplate) def update(self, req, id, body): """Update a volume.""" context = req.environ['cinder.context'] diff --git a/cinder/api/v2/limits.py b/cinder/api/v2/limits.py index f50376bfd48..2578acb55cc 100644 --- a/cinder/api/v2/limits.py +++ b/cinder/api/v2/limits.py @@ -31,7 +31,6 @@ import webob.exc from cinder.api.openstack import wsgi from cinder.api.views import limits as limits_views -from cinder.api import xmlutil from cinder.i18n import _ from cinder import quota from cinder.wsgi import common as base_wsgi @@ -47,38 +46,9 @@ PER_HOUR = 60 * 60 PER_DAY = 60 * 60 * 24 -limits_nsmap = {None: xmlutil.XMLNS_COMMON_V10, 'atom': xmlutil.XMLNS_ATOM} - - -class LimitsTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('limits', selector='limits') - - rates = xmlutil.SubTemplateElement(root, 'rates') - rate = xmlutil.SubTemplateElement(rates, 'rate', selector='rate') - rate.set('uri', 'uri') - rate.set('regex', 'regex') - limit = xmlutil.SubTemplateElement(rate, 'limit', selector='limit') - limit.set('value', 'value') - limit.set('verb', 'verb') - limit.set('remaining', 'remaining') - limit.set('unit', 'unit') - limit.set('next-available', 'next-available') - - absolute = xmlutil.SubTemplateElement(root, 'absolute', - selector='absolute') - limit = xmlutil.SubTemplateElement(absolute, 'limit', - selector=xmlutil.get_items) - limit.set('name', 0) - limit.set('value', 1) - - return xmlutil.MasterTemplate(root, 1, nsmap=limits_nsmap) - - class LimitsController(wsgi.Controller): """Controller for accessing limits in the OpenStack API.""" - @wsgi.serializers(xml=LimitsTemplate) def index(self, req): """Return all global and rate limit information.""" context = req.environ['cinder.context'] diff --git a/cinder/api/v2/snapshot_metadata.py b/cinder/api/v2/snapshot_metadata.py index fb6cab0f0ff..8d2e82ce7af 100644 --- a/cinder/api/v2/snapshot_metadata.py +++ b/cinder/api/v2/snapshot_metadata.py @@ -16,7 +16,6 @@ import webob from webob import exc -from cinder.api import common from cinder.api.openstack import wsgi from cinder import exception from cinder.i18n import _ @@ -39,14 +38,11 @@ class Controller(wsgi.Controller): raise exc.HTTPNotFound(explanation=msg) return meta - @wsgi.serializers(xml=common.MetadataTemplate) def index(self, req, snapshot_id): """Returns the list of metadata for a given snapshot.""" context = req.environ['cinder.context'] return {'metadata': self._get_metadata(context, snapshot_id)} - @wsgi.serializers(xml=common.MetadataTemplate) - @wsgi.deserializers(xml=common.MetadataDeserializer) def create(self, req, snapshot_id, body): self.assert_valid_body(body, 'metadata') context = req.environ['cinder.context'] @@ -59,8 +55,6 @@ class Controller(wsgi.Controller): return {'metadata': new_metadata} - @wsgi.serializers(xml=common.MetaItemTemplate) - @wsgi.deserializers(xml=common.MetaItemDeserializer) def update(self, req, snapshot_id, id, body): self.assert_valid_body(body, 'meta') meta_item = body['meta'] @@ -81,8 +75,6 @@ class Controller(wsgi.Controller): return {'meta': meta_item} - @wsgi.serializers(xml=common.MetadataTemplate) - @wsgi.deserializers(xml=common.MetadataDeserializer) def update_all(self, req, snapshot_id, body): self.assert_valid_body(body, 'metadata') context = req.environ['cinder.context'] @@ -118,7 +110,6 @@ class Controller(wsgi.Controller): except exception.InvalidVolumeMetadataSize as error: raise exc.HTTPRequestEntityTooLarge(explanation=error.msg) - @wsgi.serializers(xml=common.MetaItemTemplate) def show(self, req, snapshot_id, id): """Return a single metadata item.""" context = req.environ['cinder.context'] diff --git a/cinder/api/v2/snapshots.py b/cinder/api/v2/snapshots.py index 536b27854b7..0e149e04da1 100644 --- a/cinder/api/v2/snapshots.py +++ b/cinder/api/v2/snapshots.py @@ -24,7 +24,6 @@ from webob import exc from cinder.api import common from cinder.api.openstack import wsgi from cinder.api.views import snapshots as snapshot_views -from cinder.api import xmlutil from cinder import exception from cinder.i18n import _, _LI from cinder import utils @@ -35,33 +34,6 @@ from cinder.volume import utils as volume_utils LOG = logging.getLogger(__name__) -def make_snapshot(elem): - elem.set('id') - elem.set('status') - elem.set('size') - elem.set('created_at') - elem.set('name') - elem.set('description') - elem.set('volume_id') - elem.append(common.MetadataTemplate()) - - -class SnapshotTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('snapshot', selector='snapshot') - make_snapshot(root) - return xmlutil.MasterTemplate(root, 1) - - -class SnapshotsTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('snapshots') - elem = xmlutil.SubTemplateElement(root, 'snapshot', - selector='snapshots') - make_snapshot(elem) - return xmlutil.MasterTemplate(root, 1) - - class SnapshotsController(wsgi.Controller): """The Snapshots API controller for the OpenStack API.""" @@ -72,7 +44,6 @@ class SnapshotsController(wsgi.Controller): self.ext_mgr = ext_mgr super(SnapshotsController, self).__init__() - @wsgi.serializers(xml=SnapshotTemplate) def show(self, req, id): """Return data about the given snapshot.""" context = req.environ['cinder.context'] @@ -99,12 +70,10 @@ class SnapshotsController(wsgi.Controller): return webob.Response(status_int=202) - @wsgi.serializers(xml=SnapshotsTemplate) def index(self, req): """Returns a summary list of snapshots.""" return self._items(req, is_detail=False) - @wsgi.serializers(xml=SnapshotsTemplate) def detail(self, req): """Returns a detailed list of snapshots.""" return self._items(req, is_detail=True) @@ -145,7 +114,6 @@ class SnapshotsController(wsgi.Controller): return snapshots @wsgi.response(202) - @wsgi.serializers(xml=SnapshotTemplate) def create(self, req, body): """Creates a new snapshot.""" kwargs = {} @@ -200,7 +168,6 @@ class SnapshotsController(wsgi.Controller): return self._view_builder.detail(req, new_snapshot) - @wsgi.serializers(xml=SnapshotTemplate) def update(self, req, id, body): """Update a snapshot.""" context = req.environ['cinder.context'] diff --git a/cinder/api/v2/types.py b/cinder/api/v2/types.py index 8a334eba4fb..95bd71bdf11 100644 --- a/cinder/api/v2/types.py +++ b/cinder/api/v2/types.py @@ -21,51 +21,23 @@ from webob import exc from cinder.api import common from cinder.api.openstack import wsgi from cinder.api.v2.views import types as views_types -from cinder.api import xmlutil from cinder import exception from cinder.i18n import _ from cinder import utils from cinder.volume import volume_types -def make_voltype(elem): - elem.set('id') - elem.set('name') - elem.set('description') - elem.set('qos_specs_id') - extra_specs = xmlutil.make_flat_dict('extra_specs', selector='extra_specs') - elem.append(extra_specs) - - -class VolumeTypeTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('volume_type', selector='volume_type') - make_voltype(root) - return xmlutil.MasterTemplate(root, 1) - - -class VolumeTypesTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('volume_types') - elem = xmlutil.SubTemplateElement(root, 'volume_type', - selector='volume_types') - make_voltype(elem) - return xmlutil.MasterTemplate(root, 1) - - class VolumeTypesController(wsgi.Controller): """The volume types API controller for the OpenStack API.""" _view_builder_class = views_types.ViewBuilder - @wsgi.serializers(xml=VolumeTypesTemplate) def index(self, req): """Returns the list of volume types.""" limited_types = self._get_volume_types(req) req.cache_resource(limited_types, name='types') return self._view_builder.index(req, limited_types) - @wsgi.serializers(xml=VolumeTypeTemplate) def show(self, req, id): """Return a single volume type item.""" context = req.environ['cinder.context'] diff --git a/cinder/api/v2/volume_metadata.py b/cinder/api/v2/volume_metadata.py index f5f9649a30f..b7d39c1c80e 100644 --- a/cinder/api/v2/volume_metadata.py +++ b/cinder/api/v2/volume_metadata.py @@ -42,14 +42,11 @@ class Controller(wsgi.Controller): raise webob.exc.HTTPNotFound(explanation=error.msg) return (volume, meta) - @wsgi.serializers(xml=common.MetadataTemplate) def index(self, req, volume_id): """Returns the list of metadata for a given volume.""" context = req.environ['cinder.context'] return {'metadata': self._get_metadata(context, volume_id)} - @wsgi.serializers(xml=common.MetadataTemplate) - @wsgi.deserializers(xml=common.MetadataDeserializer) def create(self, req, volume_id, body): self.assert_valid_body(body, 'metadata') context = req.environ['cinder.context'] @@ -62,8 +59,6 @@ class Controller(wsgi.Controller): return {'metadata': new_metadata} - @wsgi.serializers(xml=common.MetaItemTemplate) - @wsgi.deserializers(xml=common.MetaItemDeserializer) def update(self, req, volume_id, id, body): self.assert_valid_body(body, 'meta') meta_item = body['meta'] @@ -84,8 +79,6 @@ class Controller(wsgi.Controller): return {'meta': meta_item} - @wsgi.serializers(xml=common.MetadataTemplate) - @wsgi.deserializers(xml=common.MetadataDeserializer) def update_all(self, req, volume_id, body): self.assert_valid_body(body, 'metadata') metadata = body['metadata'] @@ -122,7 +115,6 @@ class Controller(wsgi.Controller): except exception.InvalidVolumeMetadataSize as error: raise webob.exc.HTTPRequestEntityTooLarge(explanation=error.msg) - @wsgi.serializers(xml=common.MetaItemTemplate) def show(self, req, volume_id, id): """Return a single metadata item.""" context = req.environ['cinder.context'] diff --git a/cinder/api/v2/volumes.py b/cinder/api/v2/volumes.py index ad4a9158e27..1e591fa9880 100644 --- a/cinder/api/v2/volumes.py +++ b/cinder/api/v2/volumes.py @@ -25,7 +25,6 @@ from webob import exc from cinder.api import common from cinder.api.openstack import wsgi from cinder.api.v2.views import volumes as volume_views -from cinder.api import xmlutil from cinder import consistencygroup as consistencygroupAPI from cinder import exception from cinder.i18n import _, _LI @@ -38,122 +37,6 @@ from cinder.volume import volume_types CONF = cfg.CONF LOG = logging.getLogger(__name__) -SCHEDULER_HINTS_NAMESPACE =\ - "http://docs.openstack.org/block-service/ext/scheduler-hints/api/v2" - - -def make_attachment(elem): - elem.set('id') - elem.set('attachment_id') - elem.set('server_id') - elem.set('host_name') - elem.set('volume_id') - elem.set('device') - - -def make_volume(elem): - elem.set('id') - elem.set('status') - elem.set('size') - elem.set('availability_zone') - elem.set('created_at') - elem.set('name') - elem.set('bootable') - elem.set('description') - elem.set('volume_type') - elem.set('snapshot_id') - elem.set('source_volid') - elem.set('consistencygroup_id') - elem.set('multiattach') - - attachments = xmlutil.SubTemplateElement(elem, 'attachments') - attachment = xmlutil.SubTemplateElement(attachments, 'attachment', - selector='attachments') - make_attachment(attachment) - - # Attach metadata node - elem.append(common.MetadataTemplate()) - - -volume_nsmap = {None: xmlutil.XMLNS_VOLUME_V2, 'atom': xmlutil.XMLNS_ATOM} - - -class VolumeTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('volume', selector='volume') - make_volume(root) - return xmlutil.MasterTemplate(root, 1, nsmap=volume_nsmap) - - -class VolumesTemplate(xmlutil.TemplateBuilder): - def construct(self): - root = xmlutil.TemplateElement('volumes') - elem = xmlutil.SubTemplateElement(root, 'volume', selector='volumes') - make_volume(elem) - return xmlutil.MasterTemplate(root, 1, nsmap=volume_nsmap) - - -class CommonDeserializer(wsgi.MetadataXMLDeserializer): - """Common deserializer to handle xml-formatted volume requests. - - Handles standard volume attributes as well as the optional metadata - attribute - """ - - metadata_deserializer = common.MetadataXMLDeserializer() - - def _extract_scheduler_hints(self, volume_node): - """Marshal the scheduler hints attribute of a parsed request.""" - node =\ - self.find_first_child_named_in_namespace(volume_node, - SCHEDULER_HINTS_NAMESPACE, - "scheduler_hints") - if node: - scheduler_hints = {} - for child in self.extract_elements(node): - scheduler_hints.setdefault(child.nodeName, []) - value = self.extract_text(child).strip() - scheduler_hints[child.nodeName].append(value) - return scheduler_hints - else: - return None - - def _extract_volume(self, node): - """Marshal the volume attribute of a parsed request.""" - volume = {} - volume_node = self.find_first_child_named(node, 'volume') - - attributes = ['name', 'description', 'size', - 'volume_type', 'availability_zone', 'imageRef', - 'image_id', 'snapshot_id', 'source_volid', - 'consistencygroup_id'] - for attr in attributes: - if volume_node.getAttribute(attr): - volume[attr] = volume_node.getAttribute(attr) - - metadata_node = self.find_first_child_named(volume_node, 'metadata') - if metadata_node is not None: - volume['metadata'] = self.extract_metadata(metadata_node) - - scheduler_hints = self._extract_scheduler_hints(volume_node) - if scheduler_hints: - volume['scheduler_hints'] = scheduler_hints - - return volume - - -class CreateDeserializer(CommonDeserializer): - """Deserializer to handle xml-formatted create volume requests. - - Handles standard volume attributes as well as the optional metadata - attribute - """ - - def default(self, string): - """Deserialize an xml-formatted volume create request.""" - dom = utils.safe_minidom_parse_string(string) - volume = self._extract_volume(dom) - return {'body': {'volume': volume}} class VolumeController(wsgi.Controller): @@ -167,7 +50,6 @@ class VolumeController(wsgi.Controller): self.ext_mgr = ext_mgr super(VolumeController, self).__init__() - @wsgi.serializers(xml=VolumeTemplate) def show(self, req, id): """Return data about the given volume.""" context = req.environ['cinder.context'] @@ -197,12 +79,10 @@ class VolumeController(wsgi.Controller): raise exc.HTTPNotFound(explanation=error.msg) return webob.Response(status_int=202) - @wsgi.serializers(xml=VolumesTemplate) def index(self, req): """Returns a summary list of volumes.""" return self._get_volumes(req, is_detail=False) - @wsgi.serializers(xml=VolumesTemplate) def detail(self, req): """Returns a detailed list of volumes.""" return self._get_volumes(req, is_detail=True) @@ -292,8 +172,6 @@ class VolumeController(wsgi.Controller): raise exc.HTTPBadRequest(explanation=msg) @wsgi.response(202) - @wsgi.serializers(xml=VolumeTemplate) - @wsgi.deserializers(xml=CreateDeserializer) def create(self, req, body): """Creates a new volume.""" self.assert_valid_body(body, 'volume') @@ -415,7 +293,6 @@ class VolumeController(wsgi.Controller): """Return volume search options allowed by non-admin.""" return CONF.query_volume_filters - @wsgi.serializers(xml=VolumeTemplate) def update(self, req, id, body): """Update a volume.""" context = req.environ['cinder.context'] diff --git a/cinder/api/versions.py b/cinder/api/versions.py index 9cc10bde501..434916cd65d 100644 --- a/cinder/api/versions.py +++ b/cinder/api/versions.py @@ -16,9 +16,7 @@ import copy -import datetime -from lxml import etree from oslo_config import cfg from cinder.api import extensions @@ -26,7 +24,6 @@ from cinder.api import openstack from cinder.api.openstack import api_version_request from cinder.api.openstack import wsgi from cinder.api.views import versions as views_versions -from cinder.api import xmlutil CONF = cfg.CONF @@ -43,11 +40,6 @@ _MEDIA_TYPES = [{ "type": "application/vnd.openstack.volume+json;version=1", }, - {"base": - "application/xml", - "type": - "application/vnd.openstack.volume+xml;version=1", - }, ] _KNOWN_VERSIONS = { @@ -138,149 +130,5 @@ class VersionsController(wsgi.Controller): return builder.build_versions(known_versions) -class MediaTypesTemplateElement(xmlutil.TemplateElement): - - def will_render(self, datum): - return 'media-types' in datum - - -def make_version(elem): - elem.set('id') - elem.set('status') - elem.set('updated') - - mts = MediaTypesTemplateElement('media-types') - elem.append(mts) - - mt = xmlutil.SubTemplateElement(mts, 'media-type', selector='media-types') - mt.set('base') - mt.set('type') - - xmlutil.make_links(elem, 'links') - - -version_nsmap = {None: xmlutil.XMLNS_COMMON_V10, 'atom': xmlutil.XMLNS_ATOM} - - -class VersionTemplate(xmlutil.TemplateBuilder): - - def construct(self): - root = xmlutil.TemplateElement('version', selector='version') - make_version(root) - return xmlutil.MasterTemplate(root, 1, nsmap=version_nsmap) - - -class VersionsTemplate(xmlutil.TemplateBuilder): - - def construct(self): - root = xmlutil.TemplateElement('versions') - elem = xmlutil.SubTemplateElement(root, 'version', selector='versions') - make_version(elem) - return xmlutil.MasterTemplate(root, 1, nsmap=version_nsmap) - - -class ChoicesTemplate(xmlutil.TemplateBuilder): - - def construct(self): - root = xmlutil.TemplateElement('choices') - elem = xmlutil.SubTemplateElement(root, 'version', selector='choices') - make_version(elem) - return xmlutil.MasterTemplate(root, 1, nsmap=version_nsmap) - - -class AtomSerializer(wsgi.XMLDictSerializer): - - NSMAP = {None: xmlutil.XMLNS_ATOM} - - def __init__(self, metadata=None, xmlns=None): - self.metadata = metadata or {} - if not xmlns: - self.xmlns = wsgi.XML_NS_ATOM - else: - self.xmlns = xmlns - - def _get_most_recent_update(self, versions): - recent = None - for version in versions: - updated = datetime.datetime.strptime(version['updated'], - '%Y-%m-%dT%H:%M:%SZ') - if not recent: - recent = updated - elif updated > recent: - recent = updated - - return recent.strftime('%Y-%m-%dT%H:%M:%SZ') - - def _get_base_url(self, link_href): - # Make sure no trailing / - link_href = link_href.rstrip('/') - return link_href.rsplit('/', 1)[0] + '/' - - def _create_feed(self, versions, feed_title, feed_id): - feed = etree.Element('feed', nsmap=self.NSMAP) - title = etree.SubElement(feed, 'title') - title.set('type', 'text') - title.text = feed_title - - # Set this updated to the most recently updated version - recent = self._get_most_recent_update(versions) - etree.SubElement(feed, 'updated').text = recent - - etree.SubElement(feed, 'id').text = feed_id - - link = etree.SubElement(feed, 'link') - link.set('rel', 'self') - link.set('href', feed_id) - - author = etree.SubElement(feed, 'author') - etree.SubElement(author, 'name').text = 'Rackspace' - etree.SubElement(author, 'uri').text = 'http://www.rackspace.com/' - - for version in versions: - feed.append(self._create_version_entry(version)) - - return feed - - def _create_version_entry(self, version): - entry = etree.Element('entry') - etree.SubElement(entry, 'id').text = version['links'][0]['href'] - title = etree.SubElement(entry, 'title') - title.set('type', 'text') - title.text = 'Version %s' % version['id'] - etree.SubElement(entry, 'updated').text = version['updated'] - - for link in version['links']: - link_elem = etree.SubElement(entry, 'link') - link_elem.set('rel', link['rel']) - link_elem.set('href', link['href']) - if 'type' in link: - link_elem.set('type', link['type']) - - content = etree.SubElement(entry, 'content') - content.set('type', 'text') - content.text = 'Version %s %s (%s)' % (version['id'], - version['status'], - version['updated']) - return entry - - -class VersionsAtomSerializer(AtomSerializer): - - def default(self, data): - versions = data['versions'] - feed_id = self._get_base_url(versions[0]['links'][0]['href']) - feed = self._create_feed(versions, 'Available API Versions', feed_id) - return self._to_xml(feed) - - -class VersionAtomSerializer(AtomSerializer): - - def default(self, data): - version = data['version'] - feed_id = version['links'][0]['href'] - feed = self._create_feed([version], 'About This Version', feed_id) - return self._to_xml(feed) - - def create_resource(): return wsgi.Resource(VersionsController()) diff --git a/cinder/api/xmlutil.py b/cinder/api/xmlutil.py deleted file mode 100644 index 7fb851a0c30..00000000000 --- a/cinder/api/xmlutil.py +++ /dev/null @@ -1,968 +0,0 @@ -# Copyright 2011 OpenStack Foundation -# 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. - -import os.path -import re - -from lxml import etree -import six - -from cinder.i18n import _ -from cinder import utils - - -XMLNS_V10 = 'http://docs.rackspacecloud.com/servers/api/v1.0' -XMLNS_V11 = 'http://docs.openstack.org/compute/api/v1.1' -XMLNS_COMMON_V10 = 'http://docs.openstack.org/common/api/v1.0' -XMLNS_ATOM = 'http://www.w3.org/2005/Atom' -XMLNS_VOLUME_V1 = ('http://docs.openstack.org/api/openstack-block-storage/1.0/' - 'content') -XMLNS_VOLUME_V2 = ('http://docs.openstack.org/api/openstack-block-storage/2.0/' - 'content') - -_split_pattern = re.compile(r'([^:{]*{[^}]*}[^:]*|[^:]+)') - - -def validate_schema(xml, schema_name): - if isinstance(xml, str): - xml = etree.fromstring(xml) - base_path = 'cinder/api/schemas/v1.1/' - if schema_name in ('atom', 'atom-link'): - base_path = 'cinder/api/schemas/' - schema_path = os.path.join(utils.cinderdir(), - '%s%s.rng' % (base_path, schema_name)) - schema_doc = etree.parse(schema_path) - relaxng = etree.RelaxNG(schema_doc) - relaxng.assertValid(xml) - - -class Selector(object): - """Selects datum to operate on from an object.""" - - def __init__(self, *chain): - """Initialize the selector. - - Each argument is a subsequent index into the object. - """ - - self.chain = chain - - def __repr__(self): - """Return a representation of the selector.""" - - return "Selector" + repr(self.chain) - - def __call__(self, obj, do_raise=False): - """Select a datum to operate on. - - Selects the relevant datum within the object. - - :param obj: The object from which to select the object. - :param do_raise: If False (the default), return None if the - indexed datum does not exist. Otherwise, - raise a KeyError. - """ - - # Walk the selector list - for elem in self.chain: - # If it's callable, call it - if callable(elem): - obj = elem(obj) - else: - # Use indexing - try: - obj = obj[elem] - except (KeyError, IndexError): - # No sense going any further - if do_raise: - # Convert to a KeyError, for consistency - raise KeyError(elem) - return None - - # Return the finally-selected object - return obj - - -def get_items(obj): - """Get items in obj.""" - - return list(obj.items()) - - -class EmptyStringSelector(Selector): - """Returns the empty string if Selector would return None.""" - def __call__(self, obj, do_raise=False): - """Returns empty string if the selected value does not exist.""" - - try: - return super(EmptyStringSelector, self).__call__(obj, True) - except KeyError: - return "" - - -class ConstantSelector(object): - """Returns a constant.""" - - def __init__(self, value): - """Initialize the selector. - - :param value: The value to return. - """ - - self.value = value - - def __repr__(self): - """Return a representation of the selector.""" - - return repr(self.value) - - def __call__(self, _obj, _do_raise=False): - """Select a datum to operate on. - - Returns a constant value. Compatible with - Selector.__call__(). - """ - - return self.value - - -class TemplateElement(object): - """Represent an element in the template.""" - - def __init__(self, tag, attrib=None, selector=None, subselector=None, - **extra): - """Initialize an element. - - Initializes an element in the template. Keyword arguments - specify attributes to be set on the element; values must be - callables. See TemplateElement.set() for more information. - - :param tag: The name of the tag to create. - :param attrib: An optional dictionary of element attributes. - :param selector: An optional callable taking an object and - optional boolean do_raise indicator and - returning the object bound to the element. - :param subselector: An optional callable taking an object and - optional boolean do_raise indicator and - returning the object bound to the element. - This is used to further refine the datum - object returned by selector in the event - that it is a list of objects. - """ - - # Convert selector into a Selector - if selector is None: - selector = Selector() - elif not callable(selector): - selector = Selector(selector) - - # Convert subselector into a Selector - if subselector is not None and not callable(subselector): - subselector = Selector(subselector) - - self.tag = tag - self.selector = selector - self.subselector = subselector - self.attrib = {} - self._text = None - self._children = [] - self._childmap = {} - - # Run the incoming attributes through set() so that they - # become selectorized - if not attrib: - attrib = {} - attrib.update(extra) - for k, v in attrib.items(): - self.set(k, v) - - def __repr__(self): - """Return a representation of the template element.""" - - return ('<%s.%s %r at %#x>' % - (self.__class__.__module__, self.__class__.__name__, - self.tag, id(self))) - - def __len__(self): - """Return the number of child elements.""" - - return len(self._children) - - def __contains__(self, key): - """Determine whether a child node named by key exists.""" - - return key in self._childmap - - def __getitem__(self, idx): - """Retrieve a child node by index or name.""" - - if isinstance(idx, six.string_types): - # Allow access by node name - return self._childmap[idx] - else: - return self._children[idx] - - def append(self, elem): - """Append a child to the element.""" - - # Unwrap templates... - elem = elem.unwrap() - - # Avoid duplications - if elem.tag in self._childmap: - raise KeyError(elem.tag) - - self._children.append(elem) - self._childmap[elem.tag] = elem - - def extend(self, elems): - """Append children to the element.""" - - # Pre-evaluate the elements - elemmap = {} - elemlist = [] - for elem in elems: - # Unwrap templates... - elem = elem.unwrap() - - # Avoid duplications - if elem.tag in self._childmap or elem.tag in elemmap: - raise KeyError(elem.tag) - - elemmap[elem.tag] = elem - elemlist.append(elem) - - # Update the children - self._children.extend(elemlist) - self._childmap.update(elemmap) - - def insert(self, idx, elem): - """Insert a child element at the given index.""" - - # Unwrap templates... - elem = elem.unwrap() - - # Avoid duplications - if elem.tag in self._childmap: - raise KeyError(elem.tag) - - self._children.insert(idx, elem) - self._childmap[elem.tag] = elem - - def remove(self, elem): - """Remove a child element.""" - - # Unwrap templates... - elem = elem.unwrap() - - # Check if element exists - if elem.tag not in self._childmap or self._childmap[elem.tag] != elem: - raise ValueError(_('element is not a child')) - - self._children.remove(elem) - del self._childmap[elem.tag] - - def get(self, key): - """Get an attribute. - - Returns a callable which performs datum selection. - - :param key: The name of the attribute to get. - """ - - return self.attrib[key] - - def set(self, key, value=None): - """Set an attribute. - - :param key: The name of the attribute to set. - - :param value: A callable taking an object and optional boolean - do_raise indicator and returning the datum bound - to the attribute. If None, a Selector() will be - constructed from the key. If a string, a - Selector() will be constructed from the string. - """ - - # Convert value to a selector - if value is None: - value = Selector(key) - elif not callable(value): - value = Selector(value) - - self.attrib[key] = value - - def keys(self): - """Return the attribute names.""" - - return self.attrib.keys() - - def items(self): - """Return the attribute names and values.""" - - return self.attrib.items() - - def unwrap(self): - """Unwraps a template to return a template element.""" - - # We are a template element - return self - - def wrap(self): - """Wraps a template element to return a template.""" - - # Wrap in a basic Template - return Template(self) - - def apply(self, elem, obj): - """Apply text and attributes to an etree.Element. - - Applies the text and attribute instructions in the template - element to an etree.Element instance. - - :param elem: An etree.Element instance. - :param obj: The base object associated with this template - element. - """ - - # Start with the text... - if self.text is not None: - elem.text = six.text_type(self.text(obj)) - - # Now set up all the attributes... - for key, value in self.attrib.items(): - try: - elem.set(key, six.text_type(value(obj, True))) - except KeyError: - # Attribute has no value, so don't include it - pass - - def getAttrib(self, obj): - """Get attribute.""" - tmpattrib = {} - # Now set up all the attributes... - for key, value in self.attrib.items(): - try: - tmpattrib[key] = value(obj) - except KeyError: - # Attribute has no value, so don't include it - pass - return tmpattrib - - @staticmethod - def _splitTagName(name): - return _split_pattern.findall(name) - - def _render(self, parent, datum, patches, nsmap): - """Internal rendering. - - Renders the template node into an etree.Element object. - Returns the etree.Element object. - - :param parent: The parent etree.Element instance. - :param datum: The datum associated with this template element. - :param patches: A list of other template elements that must - also be applied. - :param nsmap: An optional namespace dictionary to be - associated with the etree.Element instance. - """ - - # Allocate a node - if callable(self.tag): - tagname = self.tag(datum) - else: - tagname = self.tag - - # If the datum is None - if datum is not None: - tmpattrib = self.getAttrib(datum) - else: - tmpattrib = {} - - tagnameList = self._splitTagName(tagname) - insertIndex = 0 - - # If parent is not none and has same tagname - if parent is not None: - for i in range(0, len(tagnameList)): - tmpInsertPos = parent.find(tagnameList[i]) - if tmpInsertPos is None: - break - elif parent.attrib != tmpattrib: - break - parent = tmpInsertPos - insertIndex = i + 1 - - if insertIndex >= len(tagnameList): - insertIndex = insertIndex - 1 - - # Create root elem - elem = etree.Element(tagnameList[insertIndex], nsmap=nsmap) - rootelem = elem - subelem = elem - - # Create subelem - for i in range((insertIndex + 1), len(tagnameList)): - subelem = etree.SubElement(elem, tagnameList[i]) - elem = subelem - - # If we have a parent, append the node to the parent - if parent is not None: - # If we can merge this element, then insert - if insertIndex > 0: - parent.insert(len(list(parent)), rootelem) - else: - parent.append(rootelem) - - # If the datum is None, do nothing else - if datum is None: - return rootelem - - # Apply this template element to the element - self.apply(subelem, datum) - - # Additionally, apply the patches - for patch in patches: - patch.apply(subelem, datum) - - # We have fully rendered the element; return it - return rootelem - - def render(self, parent, obj, patches=None, nsmap=None): - """Render an object. - - Renders an object against this template node. Returns a list - of two-item tuples, where the first item is an etree.Element - instance and the second item is the datum associated with that - instance. - - :param parent: The parent for the etree.Element instances. - :param obj: The object to render this template element - against. - :param patches: A list of other template elements to apply - when rendering this template element. - :param nsmap: An optional namespace dictionary to attach to - the etree.Element instances. - """ - - patches = patches or [] - # First, get the datum we're rendering - data = None if obj is None else self.selector(obj) - - # Check if we should render at all - if not self.will_render(data): - return [] - elif data is None: - return [(self._render(parent, None, patches, nsmap), None)] - - # Make the data into a list if it isn't already - if not isinstance(data, list): - data = [data] - elif parent is None: - raise ValueError(_('root element selecting a list')) - - # Render all the elements - elems = [] - for datum in data: - if self.subselector is not None: - datum = self.subselector(datum) - elems.append((self._render(parent, datum, patches, nsmap), datum)) - - # Return all the elements rendered, as well as the - # corresponding datum for the next step down the tree - return elems - - def will_render(self, datum): - """Hook method. - - An overridable hook method to determine whether this template - element will be rendered at all. By default, returns False - (inhibiting rendering) if the datum is None. - - :param datum: The datum associated with this template element. - """ - - # Don't render if datum is None - return datum is not None - - def _text_get(self): - """Template element text. - - Either None or a callable taking an object and optional - boolean do_raise indicator and returning the datum bound to - the text of the template element. - """ - - return self._text - - def _text_set(self, value): - # Convert value to a selector - if value is not None and not callable(value): - value = Selector(value) - - self._text = value - - def _text_del(self): - self._text = None - - text = property(_text_get, _text_set, _text_del) - - def tree(self): - """Return string representation of the template tree. - - Returns a representation of the template rooted at this - element as a string, suitable for inclusion in debug logs. - """ - - # Build the inner contents of the tag... - contents = [self.tag, '!selector=%r' % self.selector] - - # Add the text... - if self.text is not None: - contents.append('!text=%r' % self.text) - - # Add all the other attributes - for key, value in self.attrib.items(): - contents.append('%s=%r' % (key, value)) - - # If there are no children, return it as a closed tag - if len(self) == 0: - return '<%s/>' % ' '.join([str(i) for i in contents]) - - # OK, recurse to our children - children = [c.tree() for c in self] - - # Return the result - return ('<%s>%s' % - (' '.join(contents), ''.join(children), self.tag)) - - -def SubTemplateElement(parent, tag, attrib=None, selector=None, - subselector=None, **extra): - """Create a template element as a child of another. - - Corresponds to the etree.SubElement interface. Parameters are as - for TemplateElement, with the addition of the parent. - """ - - # Convert attributes - attrib = attrib or {} - attrib.update(extra) - - # Get a TemplateElement - elem = TemplateElement(tag, attrib=attrib, selector=selector, - subselector=subselector) - - # Append the parent safely - if parent is not None: - parent.append(elem) - - return elem - - -class Template(object): - """Represent a template.""" - - def __init__(self, root, nsmap=None): - """Initialize a template. - - :param root: The root element of the template. - :param nsmap: An optional namespace dictionary to be - associated with the root element of the - template. - """ - - self.root = root.unwrap() if root is not None else None - self.nsmap = nsmap or {} - self.serialize_options = dict(encoding='UTF-8', xml_declaration=True) - - def _serialize(self, parent, obj, siblings, nsmap=None): - """Internal serialization. - - Recursive routine to build a tree of etree.Element instances - from an object based on the template. Returns the first - etree.Element instance rendered, or None. - - :param parent: The parent etree.Element instance. Can be - None. - :param obj: The object to render. - :param siblings: The TemplateElement instances against which - to render the object. - :param nsmap: An optional namespace dictionary to be - associated with the etree.Element instance - rendered. - """ - - # First step, render the element - elems = siblings[0].render(parent, obj, siblings[1:], nsmap) - - # Now, traverse all child elements - seen = set() - for idx, sibling in enumerate(siblings): - for child in sibling: - # Have we handled this child already? - if child.tag in seen: - continue - seen.add(child.tag) - - # Determine the child's siblings - nieces = [child] - for sib in siblings[idx + 1:]: - if child.tag in sib: - nieces.append(sib[child.tag]) - - # Now call this function for all data elements recursively - for elem, datum in elems: - self._serialize(elem, datum, nieces) - - # Return the first element; at the top level, this will be the - # root element - if elems: - return elems[0][0] - - def serialize(self, obj, *args, **kwargs): - """Serialize an object. - - Serializes an object against the template. Returns a string - with the serialized XML. Positional and keyword arguments are - passed to etree.tostring(). - - :param obj: The object to serialize. - """ - - elem = self.make_tree(obj) - if elem is None: - return '' - - for k, v in self.serialize_options.items(): - kwargs.setdefault(k, v) - - # Serialize it into XML - return etree.tostring(elem, *args, **kwargs) - - def make_tree(self, obj): - """Create a tree. - - Serializes an object against the template. Returns an Element - node with appropriate children. - - :param obj: The object to serialize. - """ - - # If the template is empty, return the empty string - if self.root is None: - return None - - # Get the siblings and nsmap of the root element - siblings = self._siblings() - nsmap = self._nsmap() - - # Form the element tree - return self._serialize(None, obj, siblings, nsmap) - - def _siblings(self): - """Hook method for computing root siblings. - - An overridable hook method to return the siblings of the root - element. By default, this is the root element itself. - """ - - return [self.root] - - def _nsmap(self): - """Hook method for computing the namespace dictionary. - - An overridable hook method to return the namespace dictionary. - """ - - return self.nsmap.copy() - - def unwrap(self): - """Unwraps a template to return a template element.""" - - # Return the root element - return self.root - - def wrap(self): - """Wraps a template element to return a template.""" - - # We are a template - return self - - def apply(self, master): - """Hook method for determining slave applicability. - - An overridable hook method used to determine if this template - is applicable as a slave to a given master template. - - :param master: The master template to test. - """ - - return True - - def tree(self): - """Return string representation of the template tree. - - Returns a representation of the template as a string, suitable - for inclusion in debug logs. - """ - - return "%r: %s" % (self, self.root.tree()) - - -class MasterTemplate(Template): - """Represent a master template. - - Master templates are versioned derivatives of templates that - additionally allow slave templates to be attached. Slave - templates allow modification of the serialized result without - directly changing the master. - """ - - def __init__(self, root, version, nsmap=None): - """Initialize a master template. - - :param root: The root element of the template. - :param version: The version number of the template. - :param nsmap: An optional namespace dictionary to be - associated with the root element of the - template. - """ - - super(MasterTemplate, self).__init__(root, nsmap) - self.version = version - self.slaves = [] - - def __repr__(self): - """Return string representation of the template.""" - - return ("<%s.%s object version %s at %#x>" % - (self.__class__.__module__, self.__class__.__name__, - self.version, id(self))) - - def _siblings(self): - """Hook method for computing root siblings. - - An overridable hook method to return the siblings of the root - element. This is the root element plus the root elements of - all the slave templates. - """ - - return [self.root] + [slave.root for slave in self.slaves] - - def _nsmap(self): - """Hook method for computing the namespace dictionary. - - An overridable hook method to return the namespace dictionary. - The namespace dictionary is computed by taking the master - template's namespace dictionary and updating it from all the - slave templates. - """ - - nsmap = self.nsmap.copy() - for slave in self.slaves: - nsmap.update(slave._nsmap()) - return nsmap - - def attach(self, *slaves): - """Attach one or more slave templates. - - Attaches one or more slave templates to the master template. - Slave templates must have a root element with the same tag as - the master template. The slave template's apply() method will - be called to determine if the slave should be applied to this - master; if it returns False, that slave will be skipped. - (This allows filtering of slaves based on the version of the - master template.) - """ - - slave_list = [] - for slave in slaves: - slave = slave.wrap() - - # Make sure we have a tree match - if slave.root.tag != self.root.tag: - msg = (_("Template tree mismatch; adding slave %(slavetag)s " - "to master %(mastertag)s") % - {'slavetag': slave.root.tag, - 'mastertag': self.root.tag}) - raise ValueError(msg) - - # Make sure slave applies to this template - if not slave.apply(self): - continue - - slave_list.append(slave) - - # Add the slaves - self.slaves.extend(slave_list) - - def copy(self): - """Return a copy of this master template.""" - - # Return a copy of the MasterTemplate - tmp = self.__class__(self.root, self.version, self.nsmap) - tmp.slaves = self.slaves[:] - return tmp - - -class SlaveTemplate(Template): - """Represent a slave template. - - Slave templates are versioned derivatives of templates. Each - slave has a minimum version and optional maximum version of the - master template to which they can be attached. - """ - - def __init__(self, root, min_vers, max_vers=None, nsmap=None): - """Initialize a slave template. - - :param root: The root element of the template. - :param min_vers: The minimum permissible version of the master - template for this slave template to apply. - :param max_vers: An optional upper bound for the master - template version. - :param nsmap: An optional namespace dictionary to be - associated with the root element of the - template. - """ - - super(SlaveTemplate, self).__init__(root, nsmap) - self.min_vers = min_vers - self.max_vers = max_vers - - def __repr__(self): - """Return string representation of the template.""" - - return ("<%s.%s object versions %s-%s at %#x>" % - (self.__class__.__module__, self.__class__.__name__, - self.min_vers, self.max_vers, id(self))) - - def apply(self, master): - """Hook method for determining slave applicability. - - An overridable hook method used to determine if this template - is applicable as a slave to a given master template. This - version requires the master template to have a version number - between min_vers and max_vers. - - :param master: The master template to test. - """ - - # Does the master meet our minimum version requirement? - if master.version < self.min_vers: - return False - - # How about our maximum version requirement? - if self.max_vers is not None and master.version > self.max_vers: - return False - - return True - - -class TemplateBuilder(object): - """Template builder. - - This class exists to allow templates to be lazily built without - having to build them each time they are needed. It must be - subclassed, and the subclass must implement the construct() - method, which must return a Template (or subclass) instance. The - constructor will always return the template returned by - construct(), or, if it has a copy() method, a copy of that - template. - """ - - _tmpl = None - - def __new__(cls, copy=True): - """Construct and return a template. - - :param copy: If True (the default), a copy of the template - will be constructed and returned, if possible. - """ - - # Do we need to construct the template? - if cls._tmpl is None: - tmp = super(TemplateBuilder, cls).__new__(cls) - - # Construct the template - cls._tmpl = tmp.construct() - - # If the template has a copy attribute, return the result of - # calling it - if copy and hasattr(cls._tmpl, 'copy'): - return cls._tmpl.copy() - - # Return the template - return cls._tmpl - - def construct(self): - """Construct a template. - - Called to construct a template instance, which it must return. - Only called once. - """ - - raise NotImplementedError(_("subclasses must implement construct()!")) - - -def make_links(parent, selector=None): - """Attach an Atom element to the parent.""" - - elem = SubTemplateElement(parent, '{%s}link' % XMLNS_ATOM, - selector=selector) - elem.set('rel') - elem.set('type') - elem.set('href') - - # Just for completeness... - return elem - - -def make_flat_dict(name, selector=None, subselector=None, ns=None): - """Utility for simple XML templates. - - Simple templates are templates that traditionally used - XMLDictSerializer with no metadata. - - Returns a template element where the top-level element has the - given tag name, and where sub-elements have tag names derived - from the object's keys and text derived from the object's values. - - This only works for flat dictionary objects, not dictionaries - containing nested lists or dictionaries. - """ - - # Set up the names we need... - if ns is None: - elemname = name - tagname = Selector(0) - else: - elemname = '{%s}%s' % (ns, name) - tagname = lambda obj, do_raise=False: '{%s}%s' % (ns, obj[0]) - - if selector is None: - selector = name - - # Build the root element - root = TemplateElement(elemname, selector=selector, - subselector=subselector) - - # Build an element to represent all the keys and values - elem = SubTemplateElement(root, tagname, selector=get_items) - elem.text = 1 - - # Return the template - return root diff --git a/cinder/tests/functional/api/foxinsocks.py b/cinder/tests/functional/api/foxinsocks.py index f4711a38140..2eb570fdfec 100644 --- a/cinder/tests/functional/api/foxinsocks.py +++ b/cinder/tests/functional/api/foxinsocks.py @@ -46,7 +46,6 @@ class FoxInSocksFlavorGooseControllerExtension(wsgi.Controller): @wsgi.extends def show(self, req, resp_obj, id): # NOTE: This only handles JSON responses. - # You can use content type header to test for XML. resp_obj.obj['flavor']['googoose'] = req.GET.get('chewing') @@ -54,7 +53,6 @@ class FoxInSocksFlavorBandsControllerExtension(wsgi.Controller): @wsgi.extends def show(self, req, resp_obj, id): # NOTE: This only handles JSON responses. - # You can use content type header to test for XML. resp_obj.obj['big_bands'] = 'Pig Bands!' diff --git a/cinder/tests/functional/test_extensions.py b/cinder/tests/functional/test_extensions.py index 6772caf331a..f65555b0f9a 100644 --- a/cinder/tests/functional/test_extensions.py +++ b/cinder/tests/functional/test_extensions.py @@ -15,14 +15,12 @@ import iso8601 -from lxml import etree from oslo_config import cfg from oslo_serialization import jsonutils import webob from cinder.api import extensions from cinder.api.v1 import router -from cinder.api import xmlutil from cinder.tests.functional import functional_helpers @@ -75,8 +73,7 @@ class ExtensionControllerTest(ExtensionTestCase): (fox_ext, ) = [ x for x in data['extensions'] if x['alias'] == 'FOXNSOX'] self.assertEqual( - {'namespace': 'http://www.fox.in.socks/api/ext/pie/v1.0', - 'name': 'Fox In Socks', + {'name': 'Fox In Socks', 'updated': '2011-01-22T13:25:27-06:00', 'description': 'The Fox In Socks Extension.', 'alias': 'FOXNSOX', @@ -98,8 +95,7 @@ class ExtensionControllerTest(ExtensionTestCase): data = jsonutils.loads(response.body) self.assertEqual( - {"namespace": "http://www.fox.in.socks/api/ext/pie/v1.0", - "name": "Fox In Socks", + {"name": "Fox In Socks", "updated": "2011-01-22T13:25:27-06:00", "description": "The Fox In Socks Extension.", "alias": "FOXNSOX", @@ -111,55 +107,6 @@ class ExtensionControllerTest(ExtensionTestCase): response = request.get_response(app) self.assertEqual(404, response.status_int) - def test_list_extensions_xml(self): - app = router.APIRouter() - request = webob.Request.blank("/fake/extensions") - request.accept = "application/xml" - response = request.get_response(app) - self.assertEqual(200, response.status_int) - - root = etree.XML(response.body) - self.assertEqual(NS, root.tag.split('extensions')[0]) - - # Make sure we have all the extensions, extras extensions being OK. - exts = root.findall('{0}extension'.format(NS)) - self.assertGreaterEqual(len(exts), len(self.ext_list)) - - # Make sure that at least Fox in Sox is correct. - (fox_ext, ) = [x for x in exts if x.get('alias') == 'FOXNSOX'] - self.assertEqual('Fox In Socks', fox_ext.get('name')) - self.assertEqual( - 'http://www.fox.in.socks/api/ext/pie/v1.0', - fox_ext.get('namespace')) - self.assertEqual('2011-01-22T13:25:27-06:00', fox_ext.get('updated')) - self.assertEqual( - 'The Fox In Socks Extension.', - fox_ext.findtext('{0}description'.format(NS))) - - xmlutil.validate_schema(root, 'extensions') - - def test_get_extension_xml(self): - app = router.APIRouter() - request = webob.Request.blank("/fake/extensions/FOXNSOX") - request.accept = "application/xml" - response = request.get_response(app) - self.assertEqual(200, response.status_int) - xml = response.body - - root = etree.XML(xml) - self.assertEqual(NS, root.tag.split('extension')[0]) - self.assertEqual('FOXNSOX', root.get('alias')) - self.assertEqual('Fox In Socks', root.get('name')) - self.assertEqual( - 'http://www.fox.in.socks/api/ext/pie/v1.0', - root.get('namespace')) - self.assertEqual('2011-01-22T13:25:27-06:00', root.get('updated')) - self.assertEqual( - 'The Fox In Socks Extension.', - root.findtext('{0}description'.format(NS))) - - xmlutil.validate_schema(root, 'extension') - class StubExtensionManager(object): """Provides access to Tweedle Beetles.""" @@ -203,10 +150,6 @@ class ExtensionControllerIdFormatTest(ExtensionTestCase): response = request.get_response(app) return response.body - def test_id_with_xml_format(self): - result = self._bounce_id('foo.xml') - self.assertEqual(b'foo', result) - def test_id_with_json_format(self): result = self._bounce_id('foo.json') self.assertEqual(b'foo', result) diff --git a/cinder/tests/functional/test_xml.py b/cinder/tests/functional/test_xml.py deleted file mode 100644 index f2f9786e785..00000000000 --- a/cinder/tests/functional/test_xml.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright 2011 Justin Santa Barbara -# 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 lxml import etree - -from cinder.api import common -from cinder.tests.functional import functional_helpers - - -class XmlTests(functional_helpers._FunctionalTestBase): - """Some basic XML sanity checks.""" - - # FIXME(ja): does cinder need limits? - # def test_namespace_limits(self): - # headers = {} - # headers['Accept'] = 'application/xml' - - # response = self.api.api_request('/limits', headers=headers) - # data = response.read() - # LOG.debug("data: %s" % data) - # root = etree.XML(data) - # self.assertEqual(root.nsmap.get(None), xmlutil.XMLNS_COMMON_V10) - - def test_namespace_volumes(self): - headers = {} - headers['Accept'] = 'application/xml' - - response = self.api.api_request('/volumes', headers=headers, - stream=True) - data = response.raw - root = etree.parse(data).getroot() - self.assertEqual(common.XML_NS_V2, root.nsmap.get(None)) diff --git a/cinder/tests/unit/api/common.py b/cinder/tests/unit/api/common.py deleted file mode 100644 index c0ef6108158..00000000000 --- a/cinder/tests/unit/api/common.py +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright 2011 OpenStack Foundation -# 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. - - -def compare_links(actual, expected): - """Compare xml atom links.""" - - return compare_tree_to_dict(actual, expected, ('rel', 'href', 'type')) - - -def compare_media_types(actual, expected): - """Compare xml media types.""" - - return compare_tree_to_dict(actual, expected, ('base', 'type')) - - -def compare_tree_to_dict(actual, expected, keys): - """Compare parts of lxml.etree objects to dicts.""" - - for elem, data in zip(actual, expected): - for key in keys: - if elem.get(key) != data.get(key): - return False - return True diff --git a/cinder/tests/unit/api/contrib/test_availability_zones.py b/cinder/tests/unit/api/contrib/test_availability_zones.py index a4683991160..fd9359ce562 100644 --- a/cinder/tests/unit/api/contrib/test_availability_zones.py +++ b/cinder/tests/unit/api/contrib/test_availability_zones.py @@ -15,7 +15,6 @@ import datetime -from lxml import etree from oslo_utils import timeutils import cinder.api.contrib.availability_zones @@ -60,31 +59,3 @@ class ControllerTestCase(cinder.test.TestCase): ], } self.assertEqual(expected, actual) - - -class XMLSerializerTest(cinder.test.TestCase): - - def test_index_xml(self): - fixture = { - 'availabilityZoneInfo': [ - {'zoneName': 'ping', 'zoneState': {'available': True}}, - {'zoneName': 'pong', 'zoneState': {'available': False}}, - ], - } - - serializer = cinder.api.contrib.availability_zones.ListTemplate() - text = serializer.serialize(fixture) - tree = etree.fromstring(text) - - self.assertEqual('availabilityZones', tree.tag) - self.assertEqual(2, len(tree)) - - self.assertEqual('availabilityZone', tree[0].tag) - - self.assertEqual('ping', tree[0].get('name')) - self.assertEqual('zoneState', tree[0][0].tag) - self.assertEqual('True', tree[0][0].get('available')) - - self.assertEqual('pong', tree[1].get('name')) - self.assertEqual('zoneState', tree[1][0].tag) - self.assertEqual('False', tree[1][0].get('available')) diff --git a/cinder/tests/unit/api/contrib/test_backups.py b/cinder/tests/unit/api/contrib/test_backups.py index 9b926120968..233400ffc09 100644 --- a/cinder/tests/unit/api/contrib/test_backups.py +++ b/cinder/tests/unit/api/contrib/test_backups.py @@ -17,13 +17,10 @@ Tests for Backup code. """ -from xml.dom import minidom - import ddt import mock from oslo_serialization import jsonutils from oslo_utils import timeutils -import six import webob # needed for stubs to work @@ -141,25 +138,6 @@ class BackupsAPITestCase(test.TestCase): db.backup_destroy(context.get_admin_context(), backup_id) db.volume_destroy(context.get_admin_context(), volume_id) - def test_show_backup_xml_content_type(self): - volume_id = utils.create_volume(self.context, size=5, - status='creating')['id'] - backup_id = self._create_backup(volume_id) - req = webob.Request.blank('/v2/fake/backups/%s' % backup_id) - req.method = 'GET' - req.headers['Content-Type'] = 'application/xml' - req.headers['Accept'] = 'application/xml' - res = req.get_response(fakes.wsgi_app()) - self.assertEqual(200, res.status_int) - dom = minidom.parseString(res.body) - backup = dom.getElementsByTagName('backup') - name = backup.item(0).getAttribute('name') - container_name = backup.item(0).getAttribute('container') - self.assertEqual('volumebackups', container_name.strip()) - self.assertEqual('test_backup', name.strip()) - db.backup_destroy(context.get_admin_context(), backup_id) - db.volume_destroy(context.get_admin_context(), volume_id) - def test_show_backup_with_backup_NotFound(self): req = webob.Request.blank('/v2/fake/backups/9999') req.method = 'GET' @@ -198,35 +176,6 @@ class BackupsAPITestCase(test.TestCase): db.backup_destroy(context.get_admin_context(), backup_id2) db.backup_destroy(context.get_admin_context(), backup_id1) - def test_list_backups_xml(self): - backup_id1 = self._create_backup() - backup_id2 = self._create_backup() - backup_id3 = self._create_backup() - - req = webob.Request.blank('/v2/fake/backups') - req.method = 'GET' - req.headers['Content-Type'] = 'application/xml' - req.headers['Accept'] = 'application/xml' - res = req.get_response(fakes.wsgi_app()) - - self.assertEqual(200, res.status_int) - dom = minidom.parseString(res.body) - backup_list = dom.getElementsByTagName('backup') - - self.assertEqual(2, backup_list.item(0).attributes.length) - self.assertEqual(backup_id3, - backup_list.item(0).getAttribute('id')) - self.assertEqual(2, backup_list.item(1).attributes.length) - self.assertEqual(backup_id2, - backup_list.item(1).getAttribute('id')) - self.assertEqual(2, backup_list.item(2).attributes.length) - self.assertEqual(backup_id1, - backup_list.item(2).getAttribute('id')) - - db.backup_destroy(context.get_admin_context(), backup_id3) - db.backup_destroy(context.get_admin_context(), backup_id2) - db.backup_destroy(context.get_admin_context(), backup_id1) - def test_list_backups_with_limit(self): backup_id1 = self._create_backup() backup_id2 = self._create_backup() @@ -411,90 +360,6 @@ class BackupsAPITestCase(test.TestCase): db.backup_destroy(context.get_admin_context(), backup_id2) db.backup_destroy(context.get_admin_context(), backup_id1) - def test_list_backups_detail_xml(self): - backup_id1 = self._create_backup() - backup_id2 = self._create_backup() - backup_id3 = self._create_backup() - - req = webob.Request.blank('/v2/fake/backups/detail') - req.method = 'GET' - req.headers['Content-Type'] = 'application/xml' - req.headers['Accept'] = 'application/xml' - res = req.get_response(fakes.wsgi_app()) - - self.assertEqual(200, res.status_int) - dom = minidom.parseString(res.body) - backup_detail = dom.getElementsByTagName('backup') - - self.assertEqual(11, backup_detail.item(0).attributes.length) - self.assertEqual( - 'az1', backup_detail.item(0).getAttribute('availability_zone')) - self.assertEqual( - 'volumebackups', backup_detail.item(0).getAttribute('container')) - self.assertEqual( - 'this is a test backup', - backup_detail.item(0).getAttribute('description')) - self.assertEqual( - 'test_backup', backup_detail.item(0).getAttribute('name')) - self.assertEqual( - backup_id3, backup_detail.item(0).getAttribute('id')) - self.assertEqual( - 0, int(backup_detail.item(0).getAttribute('object_count'))) - self.assertEqual( - 0, int(backup_detail.item(0).getAttribute('size'))) - self.assertEqual( - fields.BackupStatus.CREATING, - backup_detail.item(0).getAttribute('status')) - self.assertEqual( - 1, int(backup_detail.item(0).getAttribute('volume_id'))) - - self.assertEqual(11, backup_detail.item(1).attributes.length) - self.assertEqual( - 'az1', backup_detail.item(1).getAttribute('availability_zone')) - self.assertEqual( - 'volumebackups', backup_detail.item(1).getAttribute('container')) - self.assertEqual( - 'this is a test backup', - backup_detail.item(1).getAttribute('description')) - self.assertEqual( - 'test_backup', backup_detail.item(1).getAttribute('name')) - self.assertEqual( - backup_id2, backup_detail.item(1).getAttribute('id')) - self.assertEqual( - 0, int(backup_detail.item(1).getAttribute('object_count'))) - self.assertEqual( - 0, int(backup_detail.item(1).getAttribute('size'))) - self.assertEqual( - fields.BackupStatus.CREATING, - backup_detail.item(1).getAttribute('status')) - self.assertEqual( - 1, int(backup_detail.item(1).getAttribute('volume_id'))) - - self.assertEqual(11, backup_detail.item(2).attributes.length) - self.assertEqual( - 'az1', backup_detail.item(2).getAttribute('availability_zone')) - self.assertEqual( - 'volumebackups', backup_detail.item(2).getAttribute('container')) - self.assertEqual( - 'this is a test backup', - backup_detail.item(2).getAttribute('description')) - self.assertEqual( - 'test_backup', backup_detail.item(2).getAttribute('name')) - self.assertEqual( - backup_id1, backup_detail.item(2).getAttribute('id')) - self.assertEqual( - 0, int(backup_detail.item(2).getAttribute('object_count'))) - self.assertEqual( - 0, int(backup_detail.item(2).getAttribute('size'))) - self.assertEqual(fields.BackupStatus.CREATING, - backup_detail.item(2).getAttribute('status')) - self.assertEqual( - 1, int(backup_detail.item(2).getAttribute('volume_id'))) - - db.backup_destroy(context.get_admin_context(), backup_id3) - db.backup_destroy(context.get_admin_context(), backup_id2) - db.backup_destroy(context.get_admin_context(), backup_id1) - def test_list_backups_detail_with_limit_and_sort_args(self): backup_id1 = self._create_backup() backup_id2 = self._create_backup() @@ -736,39 +601,6 @@ class BackupsAPITestCase(test.TestCase): self.assertEqual(400, res.status_int) self.assertIsNotNone(res_dict['badRequest']['message']) - @mock.patch('cinder.db.service_get_all_by_topic') - @mock.patch( - 'cinder.api.openstack.wsgi.Controller.validate_name_and_description') - def test_create_backup_xml(self, mock_validate, - _mock_service_get_all_by_topic): - _mock_service_get_all_by_topic.return_value = [ - {'availability_zone': 'fake_az', 'host': 'testhost', - 'disabled': 0, 'updated_at': timeutils.utcnow()}] - - volume_id = utils.create_volume(self.context, size=2)['id'] - - body = ('' % volume_id) - if isinstance(body, six.text_type): - body = body.encode('utf-8') - - req = webob.Request.blank('/v2/fake/backups') - req.body = body - req.method = 'POST' - req.headers['Content-Type'] = 'application/xml' - req.headers['Accept'] = 'application/xml' - res = req.get_response(fakes.wsgi_app()) - - self.assertEqual(202, res.status_int) - dom = minidom.parseString(res.body) - backup = dom.getElementsByTagName('backup') - self.assertTrue(backup.item(0).hasAttribute('id')) - self.assertTrue(_mock_service_get_all_by_topic.called) - self.assertTrue(mock_validate.called) - - db.volume_destroy(context.get_admin_context(), volume_id) - def test_create_backup_with_invalid_snapshot(self): volume_id = utils.create_volume(self.context, size=5, status='available')['id'] @@ -1311,37 +1143,6 @@ class BackupsAPITestCase(test.TestCase): self.assertEqual(volume_id, res_dict['restore']['volume_id']) self.assertEqual(volume_name, res_dict['restore']['volume_name']) - @mock.patch('cinder.backup.api.API._get_available_backup_service_host') - def test_restore_backup_volume_id_specified_xml( - self, _mock_get_backup_host): - _mock_get_backup_host.return_value = 'testhost' - volume_name = 'test1' - backup_id = self._create_backup(status=fields.BackupStatus.AVAILABLE) - volume_id = utils.create_volume(self.context, - size=2, - display_name=volume_name)['id'] - - body = '' % volume_id - if isinstance(body, six.text_type): - body = body.encode('utf-8') - - req = webob.Request.blank('/v2/fake/backups/%s/restore' % backup_id) - req.body = body - req.method = 'POST' - req.headers['Content-Type'] = 'application/xml' - req.headers['Accept'] = 'application/xml' - res = req.get_response(fakes.wsgi_app()) - - self.assertEqual(202, res.status_int) - dom = minidom.parseString(res.body) - restore = dom.getElementsByTagName('restore') - self.assertEqual(backup_id, - restore.item(0).getAttribute('backup_id')) - self.assertEqual(volume_id, restore.item(0).getAttribute('volume_id')) - - db.backup_destroy(context.get_admin_context(), backup_id) - db.volume_destroy(context.get_admin_context(), volume_id) - def test_restore_backup_with_no_body(self): # omit body from the request backup_id = self._create_backup(status=fields.BackupStatus.AVAILABLE) @@ -1774,36 +1575,6 @@ class BackupsAPITestCase(test.TestCase): res_dict['backup-record']['backup_url']) db.backup_destroy(context.get_admin_context(), backup_id) - @mock.patch('cinder.backup.api.API._get_available_backup_service_host') - @mock.patch('cinder.backup.rpcapi.BackupAPI.export_record') - def test_export_record_backup_id_specified_xml(self, - _mock_export_record_rpc, - _mock_get_backup_host): - backup_id = self._create_backup(status=fields.BackupStatus.AVAILABLE, - size=10) - ctx = context.RequestContext('admin', 'fake', is_admin=True) - backup_service = 'fake' - backup_url = 'fake' - _mock_export_record_rpc.return_value = \ - {'backup_service': backup_service, - 'backup_url': backup_url} - _mock_get_backup_host.return_value = 'testhost' - req = webob.Request.blank('/v2/fake/backups/%s/export_record' % - backup_id) - req.method = 'GET' - req.headers['Content-Type'] = 'application/xml' - req.headers['Accept'] = 'application/xml' - res = req.get_response(fakes.wsgi_app(fake_auth_context=ctx)) - self.assertEqual(200, res.status_int) - dom = minidom.parseString(res.body) - export = dom.getElementsByTagName('backup-record') - self.assertEqual(backup_service, - export.item(0).getAttribute('backup_service')) - self.assertEqual(backup_url, - export.item(0).getAttribute('backup_url')) - - # db.backup_destroy(context.get_admin_context(), backup_id) - def test_export_record_with_bad_backup_id(self): ctx = context.RequestContext('admin', 'fake', is_admin=True) @@ -1960,53 +1731,6 @@ class BackupsAPITestCase(test.TestCase): db.backup_destroy(context.get_admin_context(), backup_id) - @mock.patch('cinder.backup.api.API._list_backup_hosts') - @mock.patch('cinder.backup.rpcapi.BackupAPI.import_record') - def test_import_record_volume_id_specified_xml(self, - _mock_import_record_rpc, - _mock_list_services): - utils.replace_obj_loader(self, objects.Backup) - project_id = 'fake' - backup_service = 'fake' - ctx = context.RequestContext('admin', project_id, is_admin=True) - backup = objects.Backup(ctx, id='id', user_id='user_id', - project_id=project_id, - status=fields.BackupStatus.AVAILABLE) - backup_url = backup.encode_record() - _mock_import_record_rpc.return_value = None - _mock_list_services.return_value = [backup_service] - - if six.PY2: - backup_url = backup_url.encode('utf-8') - body = ('' - % {'backup_url': backup_url, - 'backup_service': backup_service}) - if isinstance(body, six.text_type): - body = body.encode('utf-8') - - req = webob.Request.blank('/v2/fake/backups/import_record') - req.body = body - req.method = 'POST' - req.headers['Content-Type'] = 'application/xml' - req.headers['Accept'] = 'application/xml' - res = req.get_response(fakes.wsgi_app(fake_auth_context=ctx)) - - # verify that request is successful - self.assertEqual(201, res.status_int) - - # Verify that entry in DB is as expected - db_backup = objects.Backup.get_by_id(ctx, 'id') - self.assertEqual(ctx.project_id, db_backup.project_id) - self.assertEqual(ctx.user_id, db_backup.user_id) - self.assertEqual(backup_api.IMPORT_VOLUME_ID, db_backup.volume_id) - self.assertEqual(fields.BackupStatus.CREATING, db_backup.status) - - # Verify the response - dom = minidom.parseString(res.body) - back = dom.getElementsByTagName('backup') - self.assertEqual(backup.id, back.item(0).attributes['id'].value) - @mock.patch('cinder.backup.api.API._list_backup_hosts') def test_import_record_with_no_backup_services(self, _mock_list_services): diff --git a/cinder/tests/unit/api/contrib/test_cgsnapshots.py b/cinder/tests/unit/api/contrib/test_cgsnapshots.py index 659c92594eb..b79b5f48d58 100644 --- a/cinder/tests/unit/api/contrib/test_cgsnapshots.py +++ b/cinder/tests/unit/api/contrib/test_cgsnapshots.py @@ -17,8 +17,6 @@ Tests for cgsnapshot code. """ -from xml.dom import minidom - import mock from oslo_serialization import jsonutils import webob @@ -71,30 +69,6 @@ class CgsnapshotsAPITestCase(test.TestCase): volume_id) consistencygroup.destroy() - def test_show_cgsnapshot_xml_content_type(self): - consistencygroup = utils.create_consistencygroup(self.context) - volume_id = utils.create_volume(self.context, - consistencygroup_id= - consistencygroup.id)['id'] - cgsnapshot = utils.create_cgsnapshot( - self.context, consistencygroup_id=consistencygroup.id) - req = webob.Request.blank('/v2/fake/cgsnapshots/%s' % - cgsnapshot.id) - req.method = 'GET' - req.headers['Content-Type'] = 'application/xml' - req.headers['Accept'] = 'application/xml' - res = req.get_response(fakes.wsgi_app()) - self.assertEqual(200, res.status_int) - dom = minidom.parseString(res.body) - - cgsnapshots = dom.getElementsByTagName('cgsnapshot') - name = cgsnapshots.item(0).getAttribute('name') - self.assertEqual("test_cgsnapshot", name.strip()) - cgsnapshot.destroy() - db.volume_destroy(context.get_admin_context(), - volume_id) - consistencygroup.destroy() - def test_show_cgsnapshot_with_cgsnapshot_NotFound(self): req = webob.Request.blank('/v2/fake/cgsnapshots/9999') req.method = 'GET' @@ -146,42 +120,6 @@ class CgsnapshotsAPITestCase(test.TestCase): volume_id) consistencygroup.destroy() - def test_list_cgsnapshots_xml(self): - consistencygroup = utils.create_consistencygroup(self.context) - volume_id = utils.create_volume(self.context, - consistencygroup_id= - consistencygroup.id)['id'] - cgsnapshot1 = utils.create_cgsnapshot( - self.context, consistencygroup_id=consistencygroup.id) - cgsnapshot2 = utils.create_cgsnapshot( - self.context, consistencygroup_id=consistencygroup.id) - cgsnapshot3 = utils.create_cgsnapshot( - self.context, consistencygroup_id=consistencygroup.id) - - req = webob.Request.blank('/v2/fake/cgsnapshots') - req.method = 'GET' - req.headers['Content-Type'] = 'application/xml' - req.headers['Accept'] = 'application/xml' - res = req.get_response(fakes.wsgi_app()) - - self.assertEqual(200, res.status_int) - dom = minidom.parseString(res.body) - cgsnapshot_list = dom.getElementsByTagName('cgsnapshot') - - self.assertEqual(cgsnapshot1.id, - cgsnapshot_list.item(0).getAttribute('id')) - self.assertEqual(cgsnapshot2.id, - cgsnapshot_list.item(1).getAttribute('id')) - self.assertEqual(cgsnapshot3.id, - cgsnapshot_list.item(2).getAttribute('id')) - - cgsnapshot3.destroy() - cgsnapshot2.destroy() - cgsnapshot1.destroy() - db.volume_destroy(context.get_admin_context(), - volume_id) - consistencygroup.destroy() - def test_list_cgsnapshots_detail_json(self): consistencygroup = utils.create_consistencygroup(self.context) volume_id = utils.create_volume(self.context, @@ -236,71 +174,6 @@ class CgsnapshotsAPITestCase(test.TestCase): volume_id) consistencygroup.destroy() - def test_list_cgsnapshots_detail_xml(self): - consistencygroup = utils.create_consistencygroup(self.context) - volume_id = utils.create_volume(self.context, - consistencygroup_id= - consistencygroup.id)['id'] - cgsnapshot1 = utils.create_cgsnapshot( - self.context, consistencygroup_id=consistencygroup.id) - cgsnapshot2 = utils.create_cgsnapshot( - self.context, consistencygroup_id=consistencygroup.id) - cgsnapshot3 = utils.create_cgsnapshot( - self.context, consistencygroup_id=consistencygroup.id) - - req = webob.Request.blank('/v2/fake/cgsnapshots/detail') - req.method = 'GET' - req.headers['Content-Type'] = 'application/xml' - req.headers['Accept'] = 'application/xml' - res = req.get_response(fakes.wsgi_app()) - - self.assertEqual(200, res.status_int) - dom = minidom.parseString(res.body) - cgsnapshot_detail = dom.getElementsByTagName('cgsnapshot') - - self.assertEqual( - 'this is a test cgsnapshot', - cgsnapshot_detail.item(0).getAttribute('description')) - self.assertEqual( - 'test_cgsnapshot', - cgsnapshot_detail.item(0).getAttribute('name')) - self.assertEqual( - cgsnapshot1.id, - cgsnapshot_detail.item(0).getAttribute('id')) - self.assertEqual( - 'creating', cgsnapshot_detail.item(0).getAttribute('status')) - - self.assertEqual( - 'this is a test cgsnapshot', - cgsnapshot_detail.item(1).getAttribute('description')) - self.assertEqual( - 'test_cgsnapshot', - cgsnapshot_detail.item(1).getAttribute('name')) - self.assertEqual( - cgsnapshot2.id, - cgsnapshot_detail.item(1).getAttribute('id')) - self.assertEqual( - 'creating', cgsnapshot_detail.item(1).getAttribute('status')) - - self.assertEqual( - 'this is a test cgsnapshot', - cgsnapshot_detail.item(2).getAttribute('description')) - self.assertEqual( - 'test_cgsnapshot', - cgsnapshot_detail.item(2).getAttribute('name')) - self.assertEqual( - cgsnapshot3.id, - cgsnapshot_detail.item(2).getAttribute('id')) - self.assertEqual( - 'creating', cgsnapshot_detail.item(2).getAttribute('status')) - - cgsnapshot3.destroy() - cgsnapshot2.destroy() - cgsnapshot1.destroy() - db.volume_destroy(context.get_admin_context(), - volume_id) - consistencygroup.destroy() - @mock.patch( 'cinder.api.openstack.wsgi.Controller.validate_name_and_description') def test_create_cgsnapshot_json(self, mock_validate): diff --git a/cinder/tests/unit/api/contrib/test_consistencygroups.py b/cinder/tests/unit/api/contrib/test_consistencygroups.py index 54c6cb73e3e..3bc9da20835 100644 --- a/cinder/tests/unit/api/contrib/test_consistencygroups.py +++ b/cinder/tests/unit/api/contrib/test_consistencygroups.py @@ -17,8 +17,6 @@ Tests for consistency group code. """ -from xml.dom import minidom - import ddt import mock from oslo_serialization import jsonutils @@ -94,21 +92,6 @@ class ConsistencyGroupsAPITestCase(test.TestCase): consistencygroup.destroy() - def test_show_consistencygroup_xml_content_type(self): - consistencygroup = self._create_consistencygroup() - req = webob.Request.blank('/v2/fake/consistencygroups/%s' % - consistencygroup.id) - req.method = 'GET' - req.headers['Content-Type'] = 'application/xml' - req.headers['Accept'] = 'application/xml' - res = req.get_response(fakes.wsgi_app()) - self.assertEqual(200, res.status_int) - dom = minidom.parseString(res.body) - consistencygroups = dom.getElementsByTagName('consistencygroup') - name = consistencygroups.item(0).getAttribute('name') - self.assertEqual("test_consistencygroup", name.strip()) - consistencygroup.destroy() - def test_show_consistencygroup_with_consistencygroup_NotFound(self): req = webob.Request.blank('/v2/fake/consistencygroups/9999') req.method = 'GET' @@ -172,32 +155,6 @@ class ConsistencyGroupsAPITestCase(test.TestCase): consistencygroup2.destroy() consistencygroup3.destroy() - def test_list_consistencygroups_xml(self): - consistencygroup1 = self._create_consistencygroup() - consistencygroup2 = self._create_consistencygroup() - consistencygroup3 = self._create_consistencygroup() - - req = webob.Request.blank('/v2/fake/consistencygroups') - req.method = 'GET' - req.headers['Content-Type'] = 'application/xml' - req.headers['Accept'] = 'application/xml' - res = req.get_response(fakes.wsgi_app()) - - self.assertEqual(200, res.status_int) - dom = minidom.parseString(res.body) - consistencygroup_list = dom.getElementsByTagName('consistencygroup') - - self.assertEqual(consistencygroup3.id, - consistencygroup_list.item(0).getAttribute('id')) - self.assertEqual(consistencygroup2.id, - consistencygroup_list.item(1).getAttribute('id')) - self.assertEqual(consistencygroup1.id, - consistencygroup_list.item(2).getAttribute('id')) - - consistencygroup3.destroy() - consistencygroup2.destroy() - consistencygroup1.destroy() - @ddt.data(False, True) def test_list_consistencygroups_with_limit(self, is_detail): consistencygroup1 = self._create_consistencygroup() @@ -395,73 +352,6 @@ class ConsistencyGroupsAPITestCase(test.TestCase): consistencygroup2.destroy() consistencygroup3.destroy() - def test_list_consistencygroups_detail_xml(self): - consistencygroup1 = self._create_consistencygroup() - consistencygroup2 = self._create_consistencygroup() - consistencygroup3 = self._create_consistencygroup() - - req = webob.Request.blank('/v2/fake/consistencygroups/detail') - req.method = 'GET' - req.headers['Content-Type'] = 'application/xml' - req.headers['Accept'] = 'application/xml' - res = req.get_response(fakes.wsgi_app()) - - self.assertEqual(200, res.status_int) - dom = minidom.parseString(res.body) - consistencygroup_detail = dom.getElementsByTagName('consistencygroup') - - self.assertEqual( - 'az1', - consistencygroup_detail.item(0).getAttribute('availability_zone')) - self.assertEqual( - 'this is a test consistency group', - consistencygroup_detail.item(0).getAttribute('description')) - self.assertEqual( - 'test_consistencygroup', - consistencygroup_detail.item(0).getAttribute('name')) - self.assertEqual( - consistencygroup3.id, - consistencygroup_detail.item(0).getAttribute('id')) - self.assertEqual( - 'creating', - consistencygroup_detail.item(0).getAttribute('status')) - - self.assertEqual( - 'az1', - consistencygroup_detail.item(1).getAttribute('availability_zone')) - self.assertEqual( - 'this is a test consistency group', - consistencygroup_detail.item(1).getAttribute('description')) - self.assertEqual( - 'test_consistencygroup', - consistencygroup_detail.item(1).getAttribute('name')) - self.assertEqual( - consistencygroup2.id, - consistencygroup_detail.item(1).getAttribute('id')) - self.assertEqual( - 'creating', - consistencygroup_detail.item(1).getAttribute('status')) - - self.assertEqual( - 'az1', - consistencygroup_detail.item(2).getAttribute('availability_zone')) - self.assertEqual( - 'this is a test consistency group', - consistencygroup_detail.item(2).getAttribute('description')) - self.assertEqual( - 'test_consistencygroup', - consistencygroup_detail.item(2).getAttribute('name')) - self.assertEqual( - consistencygroup1.id, - consistencygroup_detail.item(2).getAttribute('id')) - self.assertEqual( - 'creating', - consistencygroup_detail.item(2).getAttribute('status')) - - consistencygroup3.destroy() - consistencygroup2.destroy() - consistencygroup1.destroy() - @mock.patch( 'cinder.api.openstack.wsgi.Controller.validate_name_and_description') def test_create_consistencygroup_json(self, mock_validate): diff --git a/cinder/tests/unit/api/contrib/test_extended_snapshot_attributes.py b/cinder/tests/unit/api/contrib/test_extended_snapshot_attributes.py index 954c7dc858b..04721ef2ffe 100644 --- a/cinder/tests/unit/api/contrib/test_extended_snapshot_attributes.py +++ b/cinder/tests/unit/api/contrib/test_extended_snapshot_attributes.py @@ -14,12 +14,10 @@ # under the License. -from lxml import etree import mock from oslo_serialization import jsonutils import webob -from cinder.api.contrib import extended_snapshot_attributes from cinder import context from cinder import test from cinder.tests.unit.api import fakes @@ -107,15 +105,3 @@ class ExtendedSnapshotAttributesTest(test.TestCase): self.assertSnapshotAttributes(snapshot, project_id='fake', progress='0%') - - -class ExtendedSnapshotAttributesXmlTest(ExtendedSnapshotAttributesTest): - content_type = 'application/xml' - ext = extended_snapshot_attributes - prefix = '{%s}' % ext.Extended_snapshot_attributes.namespace - - def _get_snapshot(self, body): - return etree.XML(body) - - def _get_snapshots(self, body): - return etree.XML(body).getchildren() diff --git a/cinder/tests/unit/api/contrib/test_hosts.py b/cinder/tests/unit/api/contrib/test_hosts.py index f1e54d1a868..f482a172d17 100644 --- a/cinder/tests/unit/api/contrib/test_hosts.py +++ b/cinder/tests/unit/api/contrib/test_hosts.py @@ -16,7 +16,6 @@ import datetime from iso8601 import iso8601 -from lxml import etree from oslo_utils import timeutils import webob.exc @@ -161,51 +160,3 @@ class HostTestCase(test.TestCase): self.assertRaises(webob.exc.HTTPNotFound, self.controller.show, self.req, dest) - - -class HostSerializerTest(test.TestCase): - def setUp(self): - super(HostSerializerTest, self).setUp() - self.deserializer = os_hosts.HostDeserializer() - - def test_index_serializer(self): - serializer = os_hosts.HostIndexTemplate() - text = serializer.serialize({"hosts": LIST_RESPONSE}) - - tree = etree.fromstring(text) - - self.assertEqual('hosts', tree.tag) - self.assertEqual(len(LIST_RESPONSE), len(tree)) - for i in range(len(LIST_RESPONSE)): - self.assertEqual('host', tree[i].tag) - self.assertEqual(LIST_RESPONSE[i]['service-status'], - tree[i].get('service-status')) - self.assertEqual(LIST_RESPONSE[i]['service'], - tree[i].get('service')) - self.assertEqual(LIST_RESPONSE[i]['zone'], - tree[i].get('zone')) - self.assertEqual(LIST_RESPONSE[i]['service-state'], - tree[i].get('service-state')) - self.assertEqual(LIST_RESPONSE[i]['host_name'], - tree[i].get('host_name')) - self.assertEqual(str(LIST_RESPONSE[i]['last-update']), - tree[i].get('last-update')) - - def test_update_serializer_with_status(self): - exemplar = dict(host='test.host.1', status='enabled') - serializer = os_hosts.HostUpdateTemplate() - text = serializer.serialize(exemplar) - - tree = etree.fromstring(text) - - self.assertEqual('host', tree.tag) - for key, value in exemplar.items(): - self.assertEqual(value, tree.get(key)) - - def test_update_deserializer(self): - exemplar = dict(status='enabled', foo='bar') - intext = ("\n" - 'enabledbar') - result = self.deserializer.deserialize(intext) - - self.assertEqual(dict(body=exemplar), result) diff --git a/cinder/tests/unit/api/contrib/test_qos_specs_manage.py b/cinder/tests/unit/api/contrib/test_qos_specs_manage.py index e8405acbf65..35cd066864c 100644 --- a/cinder/tests/unit/api/contrib/test_qos_specs_manage.py +++ b/cinder/tests/unit/api/contrib/test_qos_specs_manage.py @@ -14,14 +14,10 @@ # License for the specific language governing permissions and limitations # under the License. -from xml.dom import minidom - -from lxml import etree import mock import webob from cinder.api.contrib import qos_specs_manage -from cinder.api import xmlutil from cinder import context from cinder import db from cinder import exception @@ -186,28 +182,6 @@ class QoSSpecManageApiTest(test.TestCase): expected_names = ['qos_specs_1', 'qos_specs_2', 'qos_specs_3'] self.assertEqual(set(expected_names), names) - @mock.patch('cinder.volume.qos_specs.get_all_specs', - side_effect=return_qos_specs_get_all) - def test_index_xml_response(self, mock_get_all_specs): - req = fakes.HTTPRequest.blank('/v2/fake/qos-specs') - res = self.controller.index(req) - req.method = 'GET' - req.headers['Content-Type'] = 'application/xml' - req.headers['Accept'] = 'application/xml' - res = req.get_response(fakes.wsgi_app()) - - self.assertEqual(200, res.status_int) - dom = minidom.parseString(res.body) - qos_specs_response = dom.getElementsByTagName('qos_spec') - - names = set() - for qos_spec in qos_specs_response: - name = qos_spec.getAttribute('name') - names.add(name) - - expected_names = ['qos_specs_1', 'qos_specs_2', 'qos_specs_3'] - self.assertEqual(set(expected_names), names) - def test_index_with_limit(self): url = '/v2/%s/qos-specs?limit=2' % fake.project_id req = fakes.HTTPRequest.blank(url, use_admin_context=True) @@ -532,29 +506,6 @@ class QoSSpecManageApiTest(test.TestCase): self.assertEqual('1', res_dict['qos_specs']['id']) self.assertEqual('qos_specs_1', res_dict['qos_specs']['name']) - @mock.patch('cinder.volume.qos_specs.get_qos_specs', - side_effect=return_qos_specs_get_qos_specs) - def test_show_xml_response(self, mock_get_qos_specs): - req = fakes.HTTPRequest.blank('/v2/fake/qos-specs/1') - res = self.controller.show(req, '1') - req.method = 'GET' - req.headers['Content-Type'] = 'application/xml' - req.headers['Accept'] = 'application/xml' - res = req.get_response(fakes.wsgi_app()) - - self.assertEqual(200, res.status_int) - dom = minidom.parseString(res.body) - qos_spec_response = dom.getElementsByTagName('qos_spec') - qos_spec = qos_spec_response.item(0) - - id = qos_spec.getAttribute('id') - name = qos_spec.getAttribute('name') - consumer = qos_spec.getAttribute('consumer') - - self.assertEqual(u'1', id) - self.assertEqual('qos_specs_1', name) - self.assertEqual('back-end', consumer) - @mock.patch('cinder.volume.qos_specs.get_associations', side_effect=return_get_qos_associations) def test_get_associations(self, mock_get_assciations): @@ -567,29 +518,6 @@ class QoSSpecManageApiTest(test.TestCase): self.assertEqual('FakeVolTypeID', res['qos_associations'][0]['id']) - @mock.patch('cinder.volume.qos_specs.get_associations', - side_effect=return_get_qos_associations) - def test_get_associations_xml_response(self, mock_get_assciations): - req = fakes.HTTPRequest.blank('/v2/fake/qos-specs/1/associations') - res = self.controller.associations(req, '1') - req.method = 'GET' - req.headers['Content-Type'] = 'application/xml' - req.headers['Accept'] = 'application/xml' - res = req.get_response(fakes.wsgi_app()) - - self.assertEqual(200, res.status_int) - dom = minidom.parseString(res.body) - associations_response = dom.getElementsByTagName('associations') - association = associations_response.item(0) - - id = association.getAttribute('id') - name = association.getAttribute('name') - association_type = association.getAttribute('association_type') - - self.assertEqual('FakeVolTypeID', id) - self.assertEqual('FakeVolTypeName', name) - self.assertEqual('volume_type', association_type) - @mock.patch('cinder.volume.qos_specs.get_associations', side_effect=return_get_qos_associations) def test_get_associations_not_found(self, mock_get_assciations): @@ -731,108 +659,3 @@ class QoSSpecManageApiTest(test.TestCase): '/v2/fake/qos-specs/222/disassociate_all') self.assertRaises(webob.exc.HTTPInternalServerError, self.controller.disassociate_all, req, '222') - - -class TestQoSSpecsTemplate(test.TestCase): - def setUp(self): - super(TestQoSSpecsTemplate, self).setUp() - self.serializer = qos_specs_manage.QoSSpecsTemplate() - - def test_qos_specs_serializer(self): - fixture = { - "qos_specs": [ - { - "specs": { - "key1": "v1", - "key2": "v2", - }, - "consumer": "back-end", - "name": "qos-2", - "id": "61e7b72f-ef15-46d9-b00e-b80f699999d0" - }, - { - "specs": {"total_iops_sec": "200"}, - "consumer": "front-end", - "name": "qos-1", - "id": "e44bba5e-b629-4b96-9aa3-0404753a619b" - } - ] - } - - output = self.serializer.serialize(fixture) - root = etree.XML(output) - xmlutil.validate_schema(root, 'qos_specs') - qos_elems = root.findall("qos_spec") - self.assertEqual(2, len(qos_elems)) - for i, qos_elem in enumerate(qos_elems): - qos_dict = fixture['qos_specs'][i] - - # check qos_spec attributes - for key in ['name', 'id', 'consumer']: - self.assertEqual(str(qos_dict[key]), qos_elem.get(key)) - - # check specs - specs = qos_elem.find("specs") - new_dict = {} - for element in specs.iter(tag=etree.Element): - # skip root element for specs - if element.tag == "specs": - continue - new_dict.update({element.tag: element.text}) - - self.assertDictMatch(qos_dict['specs'], new_dict) - - -class TestAssociationsTemplate(test.TestCase): - def setUp(self): - super(TestAssociationsTemplate, self).setUp() - self.serializer = qos_specs_manage.AssociationsTemplate() - - def test_qos_associations_serializer(self): - fixture = { - "qos_associations": [ - { - "association_type": "volume_type", - "name": "type-4", - "id": "14d54d29-51a4-4046-9f6f-cf9800323563" - }, - { - "association_type": "volume_type", - "name": "type-2", - "id": "3689ce83-308d-4ba1-8faf-7f1be04a282b"} - ] - } - - output = self.serializer.serialize(fixture) - root = etree.XML(output) - xmlutil.validate_schema(root, 'qos_associations') - association_elems = root.findall("associations") - self.assertEqual(2, len(association_elems)) - for i, association_elem in enumerate(association_elems): - association_dict = fixture['qos_associations'][i] - - # check qos_spec attributes - for key in ['name', 'id', 'association_type']: - self.assertEqual(str(association_dict[key]), - association_elem.get(key)) - - -class TestQoSSpecsKeyDeserializer(test.TestCase): - def setUp(self): - super(TestQoSSpecsKeyDeserializer, self).setUp() - self.deserializer = qos_specs_manage.QoSSpecsKeyDeserializer() - - def test_keys(self): - self_request = """ -""" - request = self.deserializer.deserialize(self_request) - expected = { - "keys": ["xyz", "abc"] - } - self.assertEqual(expected, request['body']) - - def test_bad_format(self): - self_request = """ -""" - self.assertRaises(webob.exc.HTTPBadRequest, - self.deserializer.deserialize, self_request) diff --git a/cinder/tests/unit/api/contrib/test_quotas.py b/cinder/tests/unit/api/contrib/test_quotas.py index 84880929bec..11f6f9fa05b 100644 --- a/cinder/tests/unit/api/contrib/test_quotas.py +++ b/cinder/tests/unit/api/contrib/test_quotas.py @@ -21,8 +21,6 @@ Tests for cinder.api.contrib.quotas.py import mock -from lxml import etree - import uuid import webob.exc @@ -1039,23 +1037,3 @@ class QuotaSetsControllerNestedQuotasTest(QuotaSetsControllerTestBase): quota_limit['volumes'] = 5 self.controller.update(self.req, self.B.id, body) self._assert_quota_show(self.A.id, res, allocated=6, in_use=1, limit=7) - - -class QuotaSerializerTest(test.TestCase): - - def setUp(self): - super(QuotaSerializerTest, self).setUp() - self.req = mock.Mock() - self.req.environ = {'cinder.context': context.get_admin_context()} - - def test_update_serializer(self): - serializer = quotas.QuotaTemplate() - quota_set = make_body(root=False) - text = serializer.serialize({'quota_set': quota_set}) - tree = etree.fromstring(text) - self.assertEqual('quota_set', tree.tag) - self.assertEqual(quota_set['id'], tree.get('id')) - body = make_body(root=False, tenant_id=None) - for node in tree: - self.assertIn(node.tag, body) - self.assertEqual(str(body[node.tag]), node.text) diff --git a/cinder/tests/unit/api/contrib/test_quotas_classes.py b/cinder/tests/unit/api/contrib/test_quotas_classes.py index 3792bac7001..9b570f37e0f 100644 --- a/cinder/tests/unit/api/contrib/test_quotas_classes.py +++ b/cinder/tests/unit/api/contrib/test_quotas_classes.py @@ -20,7 +20,6 @@ Tests for cinder.api.contrib.quota_classes.py import mock -from lxml import etree import webob.exc @@ -152,23 +151,3 @@ class QuotaClassSetsControllerTest(test.TestCase): request_body=body, tenant_id=None), result) - - -class QuotaClassesSerializerTest(test.TestCase): - - def setUp(self): - super(QuotaClassesSerializerTest, self).setUp() - self.req = mock.Mock() - self.req.environ = {'cinder.context': context.get_admin_context()} - - def test_update_serializer(self): - serializer = quota_classes.QuotaClassTemplate() - quota_class_set = make_body(root=False) - text = serializer.serialize({'quota_class_set': quota_class_set}) - tree = etree.fromstring(text) - self.assertEqual('quota_class_set', tree.tag) - self.assertEqual(tree.get('id'), quota_class_set['id']) - body = make_body(root=False, tenant_id=None) - for node in tree: - self.assertIn(node.tag, body) - self.assertEqual(str(body[node.tag]), node.text) diff --git a/cinder/tests/unit/api/contrib/test_types_extra_specs.py b/cinder/tests/unit/api/contrib/test_types_extra_specs.py index e62fa557211..578fd023615 100644 --- a/cinder/tests/unit/api/contrib/test_types_extra_specs.py +++ b/cinder/tests/unit/api/contrib/test_types_extra_specs.py @@ -15,7 +15,6 @@ # License for the specific language governing permissions and limitations # under the License. -from lxml import etree import mock import webob @@ -266,35 +265,3 @@ class VolumeTypesExtraSpecsTest(test.TestCase): def test_create_invalid_too_many_key(self): body = {"key1": "value1", "ke/y2": "value2", "key3": "value3"} self._extra_specs_create_bad_body(body=body) - - -class VolumeTypeExtraSpecsSerializerTest(test.TestCase): - def test_index_create_serializer(self): - serializer = types_extra_specs.VolumeTypeExtraSpecsTemplate() - - # Just getting some input data - extra_specs = stub_volume_type_extra_specs() - text = serializer.serialize(dict(extra_specs=extra_specs)) - - tree = etree.fromstring(text) - - self.assertEqual('extra_specs', tree.tag) - self.assertEqual(len(extra_specs), len(tree)) - seen = set(extra_specs.keys()) - for child in tree: - self.assertIn(child.tag, seen) - self.assertEqual(extra_specs[child.tag], child.text) - seen.remove(child.tag) - self.assertEqual(0, len(seen)) - - def test_update_show_serializer(self): - serializer = types_extra_specs.VolumeTypeExtraSpecTemplate() - - exemplar = dict(key1='value1') - text = serializer.serialize(exemplar) - - tree = etree.fromstring(text) - - self.assertEqual('key1', tree.tag) - self.assertEqual('value1', tree.text) - self.assertEqual(0, len(tree)) diff --git a/cinder/tests/unit/api/contrib/test_volume_host_attribute.py b/cinder/tests/unit/api/contrib/test_volume_host_attribute.py index dcc136f0679..f7b2e4c770e 100644 --- a/cinder/tests/unit/api/contrib/test_volume_host_attribute.py +++ b/cinder/tests/unit/api/contrib/test_volume_host_attribute.py @@ -14,7 +14,6 @@ import uuid -from lxml import etree from oslo_serialization import jsonutils from oslo_utils import timeutils import webob @@ -119,27 +118,3 @@ class VolumeHostAttributeTest(test.TestCase): res = req.get_response(app()) vol = jsonutils.loads(res.body)['volumes'] self.assertNotIn('os-vol-host-attr:host', vol[0]) - - def test_get_volume_xml(self): - ctx = context.RequestContext('admin', 'fake', True) - req = webob.Request.blank('/v2/fake/volumes/%s' % self.UUID) - req.method = 'GET' - req.accept = 'application/xml' - req.environ['cinder.context'] = ctx - res = req.get_response(app()) - vol = etree.XML(res.body) - host_key = ('{http://docs.openstack.org/volume/ext/' - 'volume_host_attribute/api/v2}host') - self.assertEqual('host001', vol.get(host_key)) - - def test_list_volumes_detail_xml(self): - ctx = context.RequestContext('admin', 'fake', True) - req = webob.Request.blank('/v2/fake/volumes/detail') - req.method = 'GET' - req.accept = 'application/xml' - req.environ['cinder.context'] = ctx - res = req.get_response(app()) - vol = list(etree.XML(res.body))[0] - host_key = ('{http://docs.openstack.org/volume/ext/' - 'volume_host_attribute/api/v2}host') - self.assertEqual('host001', vol.get(host_key)) diff --git a/cinder/tests/unit/api/contrib/test_volume_image_metadata.py b/cinder/tests/unit/api/contrib/test_volume_image_metadata.py index da87847f64b..2a117d68fa7 100644 --- a/cinder/tests/unit/api/contrib/test_volume_image_metadata.py +++ b/cinder/tests/unit/api/contrib/test_volume_image_metadata.py @@ -13,15 +13,12 @@ # under the License. import uuid -from xml.dom import minidom from oslo_serialization import jsonutils from oslo_utils import timeutils import webob -from cinder.api import common from cinder.api.contrib import volume_image_metadata -from cinder.api.openstack import wsgi from cinder import context from cinder import db from cinder import exception @@ -330,34 +327,3 @@ class VolumeImageMetadataTest(test.TestCase): self.assertEqual(200, res.status_int) self.assertEqual(fake_image_metadata, jsonutils.loads(res.body)["metadata"]) - - -class ImageMetadataXMLDeserializer(common.MetadataXMLDeserializer): - metadata_node_name = "volume_image_metadata" - - -class VolumeImageMetadataXMLTest(VolumeImageMetadataTest): - content_type = 'application/xml' - - def _get_image_metadata(self, body): - deserializer = wsgi.XMLDeserializer() - volume = deserializer.find_first_child_named( - minidom.parseString(body), 'volume') - image_metadata = deserializer.find_first_child_named( - volume, 'volume_image_metadata') - return wsgi.MetadataXMLDeserializer().extract_metadata(image_metadata) - - def _get_image_metadata_list(self, body): - deserializer = wsgi.XMLDeserializer() - volumes = deserializer.find_first_child_named( - minidom.parseString(body), 'volumes') - volume_list = deserializer.find_children_named(volumes, 'volume') - image_metadata_list = [ - deserializer.find_first_child_named( - volume, 'volume_image_metadata' - ) - for volume in volume_list] - - metadata_deserializer = wsgi.MetadataXMLDeserializer() - return [metadata_deserializer.extract_metadata(image_metadata) - for image_metadata in image_metadata_list] diff --git a/cinder/tests/unit/api/contrib/test_volume_migration_status_attribute.py b/cinder/tests/unit/api/contrib/test_volume_migration_status_attribute.py index f7bb6937668..872934d7681 100644 --- a/cinder/tests/unit/api/contrib/test_volume_migration_status_attribute.py +++ b/cinder/tests/unit/api/contrib/test_volume_migration_status_attribute.py @@ -14,7 +14,6 @@ import uuid -from lxml import etree from oslo_serialization import jsonutils from oslo_utils import timeutils import webob @@ -121,33 +120,3 @@ class VolumeMigStatusAttributeTest(test.TestCase): vol = jsonutils.loads(res.body)['volumes'] self.assertNotIn('os-vol-mig-status-attr:migstat', vol[0]) self.assertNotIn('os-vol-mig-status-attr:name_id', vol[0]) - - def test_get_volume_xml(self): - ctx = context.RequestContext('admin', 'fake', True) - req = webob.Request.blank('/v2/fake/volumes/%s' % self.UUID) - req.method = 'GET' - req.accept = 'application/xml' - req.environ['cinder.context'] = ctx - res = req.get_response(app()) - vol = etree.XML(res.body) - mig_key = ('{http://docs.openstack.org/volume/ext/' - 'volume_mig_status_attribute/api/v1}migstat') - self.assertEqual('migrating', vol.get(mig_key)) - mig_key = ('{http://docs.openstack.org/volume/ext/' - 'volume_mig_status_attribute/api/v1}name_id') - self.assertEqual('fake2', vol.get(mig_key)) - - def test_list_volumes_detail_xml(self): - ctx = context.RequestContext('admin', 'fake', True) - req = webob.Request.blank('/v2/fake/volumes/detail') - req.method = 'GET' - req.accept = 'application/xml' - req.environ['cinder.context'] = ctx - res = req.get_response(app()) - vol = list(etree.XML(res.body))[0] - mig_key = ('{http://docs.openstack.org/volume/ext/' - 'volume_mig_status_attribute/api/v1}migstat') - self.assertEqual('migrating', vol.get(mig_key)) - mig_key = ('{http://docs.openstack.org/volume/ext/' - 'volume_mig_status_attribute/api/v1}name_id') - self.assertEqual('fake2', vol.get(mig_key)) diff --git a/cinder/tests/unit/api/contrib/test_volume_tenant_attribute.py b/cinder/tests/unit/api/contrib/test_volume_tenant_attribute.py index 1fc4fe40a7f..8c57ae33a8a 100644 --- a/cinder/tests/unit/api/contrib/test_volume_tenant_attribute.py +++ b/cinder/tests/unit/api/contrib/test_volume_tenant_attribute.py @@ -14,7 +14,6 @@ import uuid -from lxml import etree from oslo_serialization import jsonutils import webob @@ -102,27 +101,3 @@ class VolumeTenantAttributeTest(test.TestCase): res = req.get_response(app()) vol = jsonutils.loads(res.body)['volumes'] self.assertNotIn('os-vol-tenant-attr:tenant_id', vol[0]) - - def test_get_volume_xml(self): - ctx = context.RequestContext('admin', 'fake', True) - req = webob.Request.blank('/v2/fake/volumes/%s' % self.UUID) - req.method = 'GET' - req.accept = 'application/xml' - req.environ['cinder.context'] = ctx - res = req.get_response(app()) - vol = etree.XML(res.body) - tenant_key = ('{http://docs.openstack.org/volume/ext/' - 'volume_tenant_attribute/api/v2}tenant_id') - self.assertEqual(PROJECT_ID, vol.get(tenant_key)) - - def test_list_volumes_detail_xml(self): - ctx = context.RequestContext('admin', 'fake', True) - req = webob.Request.blank('/v2/fake/volumes/detail') - req.method = 'GET' - req.accept = 'application/xml' - req.environ['cinder.context'] = ctx - res = req.get_response(app()) - vol = list(etree.XML(res.body))[0] - tenant_key = ('{http://docs.openstack.org/volume/ext/' - 'volume_tenant_attribute/api/v2}tenant_id') - self.assertEqual(PROJECT_ID, vol.get(tenant_key)) diff --git a/cinder/tests/unit/api/contrib/test_volume_transfer.py b/cinder/tests/unit/api/contrib/test_volume_transfer.py index 685905e93d0..e6b9923b85c 100644 --- a/cinder/tests/unit/api/contrib/test_volume_transfer.py +++ b/cinder/tests/unit/api/contrib/test_volume_transfer.py @@ -18,10 +18,8 @@ Tests for volume transfer code. """ import mock -from xml.dom import minidom from oslo_serialization import jsonutils -import six import webob from cinder.api.contrib import volume_transfer @@ -84,24 +82,6 @@ class VolumeTransferAPITestCase(test.TestCase): db.transfer_destroy(context.get_admin_context(), transfer['id']) db.volume_destroy(context.get_admin_context(), volume_id) - def test_show_transfer_xml_content_type(self): - volume_id = self._create_volume(size=5) - transfer = self._create_transfer(volume_id) - req = webob.Request.blank('/v2/fake/os-volume-transfer/%s' % - transfer['id']) - req.method = 'GET' - req.headers['Content-Type'] = 'application/xml' - req.headers['Accept'] = 'application/xml' - res = req.get_response(fakes.wsgi_app()) - self.assertEqual(200, res.status_int) - dom = minidom.parseString(res.body) - transfer_xml = dom.getElementsByTagName('transfer') - name = transfer_xml.item(0).getAttribute('name') - self.assertEqual('test_transfer', name.strip()) - - db.transfer_destroy(context.get_admin_context(), transfer['id']) - db.volume_destroy(context.get_admin_context(), volume_id) - def test_show_transfer_with_transfer_NotFound(self): req = webob.Request.blank('/v2/fake/os-volume-transfer/1234') req.method = 'GET' @@ -138,33 +118,6 @@ class VolumeTransferAPITestCase(test.TestCase): db.volume_destroy(context.get_admin_context(), volume_id_1) db.volume_destroy(context.get_admin_context(), volume_id_2) - def test_list_transfers_xml(self): - volume_id_1 = self._create_volume(size=5) - volume_id_2 = self._create_volume(size=5) - transfer1 = self._create_transfer(volume_id_1) - transfer2 = self._create_transfer(volume_id_2) - - req = webob.Request.blank('/v2/fake/os-volume-transfer') - req.method = 'GET' - req.headers['Content-Type'] = 'application/xml' - req.headers['Accept'] = 'application/xml' - res = req.get_response(fakes.wsgi_app()) - - self.assertEqual(200, res.status_int) - dom = minidom.parseString(res.body) - transfer_list = dom.getElementsByTagName('transfer') - self.assertEqual(3, transfer_list.item(0).attributes.length) - self.assertEqual(transfer1['id'], - transfer_list.item(0).getAttribute('id')) - self.assertEqual(3, transfer_list.item(1).attributes.length) - self.assertEqual(transfer2['id'], - transfer_list.item(1).getAttribute('id')) - - db.transfer_destroy(context.get_admin_context(), transfer2['id']) - db.transfer_destroy(context.get_admin_context(), transfer1['id']) - db.volume_destroy(context.get_admin_context(), volume_id_2) - db.volume_destroy(context.get_admin_context(), volume_id_1) - def test_list_transfers_detail_json(self): volume_id_1 = self._create_volume(size=5) volume_id_2 = self._create_volume(size=5) @@ -196,43 +149,6 @@ class VolumeTransferAPITestCase(test.TestCase): db.volume_destroy(context.get_admin_context(), volume_id_2) db.volume_destroy(context.get_admin_context(), volume_id_1) - def test_list_transfers_detail_xml(self): - volume_id_1 = self._create_volume(size=5) - volume_id_2 = self._create_volume(size=5) - transfer1 = self._create_transfer(volume_id_1) - transfer2 = self._create_transfer(volume_id_2) - - req = webob.Request.blank('/v2/fake/os-volume-transfer/detail') - req.method = 'GET' - req.headers['Content-Type'] = 'application/xml' - req.headers['Accept'] = 'application/xml' - res = req.get_response(fakes.wsgi_app()) - - self.assertEqual(200, res.status_int) - dom = minidom.parseString(res.body) - transfer_detail = dom.getElementsByTagName('transfer') - - self.assertEqual(4, transfer_detail.item(0).attributes.length) - self.assertEqual( - 'test_transfer', transfer_detail.item(0).getAttribute('name')) - self.assertEqual( - transfer1['id'], transfer_detail.item(0).getAttribute('id')) - self.assertEqual(volume_id_1, - transfer_detail.item(0).getAttribute('volume_id')) - - self.assertEqual(4, transfer_detail.item(1).attributes.length) - self.assertEqual( - 'test_transfer', transfer_detail.item(1).getAttribute('name')) - self.assertEqual( - transfer2['id'], transfer_detail.item(1).getAttribute('id')) - self.assertEqual( - volume_id_2, transfer_detail.item(1).getAttribute('volume_id')) - - db.transfer_destroy(context.get_admin_context(), transfer2['id']) - db.transfer_destroy(context.get_admin_context(), transfer1['id']) - db.volume_destroy(context.get_admin_context(), volume_id_2) - db.volume_destroy(context.get_admin_context(), volume_id_1) - def test_list_transfers_with_all_tenants(self): volume_id_1 = self._create_volume(size=5) volume_id_2 = self._create_volume(size=5, project_id='fake1') @@ -280,35 +196,6 @@ class VolumeTransferAPITestCase(test.TestCase): db.volume_destroy(context.get_admin_context(), volume_id) - @mock.patch( - 'cinder.api.openstack.wsgi.Controller.validate_string_length') - def test_create_transfer_xml(self, mock_validate): - volume_size = 2 - volume_id = self._create_volume(status='available', size=volume_size) - - body = '' % volume_id - if isinstance(body, six.text_type): - body = body.encode('utf-8') - - req = webob.Request.blank('/v2/fake/os-volume-transfer') - req.body = body - req.method = 'POST' - req.headers['Content-Type'] = 'application/xml' - req.headers['Accept'] = 'application/xml' - res = req.get_response(fakes.wsgi_app()) - - self.assertEqual(202, res.status_int) - dom = minidom.parseString(res.body) - transfer = dom.getElementsByTagName('transfer') - self.assertTrue(transfer.item(0).hasAttribute('id')) - self.assertTrue(transfer.item(0).hasAttribute('auth_key')) - self.assertTrue(transfer.item(0).hasAttribute('created_at')) - self.assertEqual('transfer-001', transfer.item(0).getAttribute('name')) - self.assertTrue(transfer.item(0).hasAttribute('volume_id')) - self.assertTrue(mock_validate.called) - - db.volume_destroy(context.get_admin_context(), volume_id) - def test_create_transfer_with_no_body(self): req = webob.Request.blank('/v2/fake/os-volume-transfer') req.body = jsonutils.dump_as_bytes(None) @@ -433,34 +320,6 @@ class VolumeTransferAPITestCase(test.TestCase): # cleanup svc.stop() - def test_accept_transfer_volume_id_specified_xml(self): - volume_id = self._create_volume(size=5) - transfer = self._create_transfer(volume_id) - svc = self.start_service('volume', host='fake_host') - - body = '' % transfer['auth_key'] - if isinstance(body, six.text_type): - body = body.encode('utf-8') - - req = webob.Request.blank('/v2/fake/os-volume-transfer/%s/accept' % - transfer['id']) - req.body = body - req.method = 'POST' - req.headers['Content-Type'] = 'application/xml' - req.headers['Accept'] = 'application/xml' - res = req.get_response(fakes.wsgi_app()) - - self.assertEqual(202, res.status_int) - dom = minidom.parseString(res.body) - accept = dom.getElementsByTagName('transfer') - self.assertEqual(transfer['id'], - accept.item(0).getAttribute('id')) - self.assertEqual(volume_id, accept.item(0).getAttribute('volume_id')) - - db.volume_destroy(context.get_admin_context(), volume_id) - # cleanup - svc.stop() - def test_accept_transfer_with_no_body(self): volume_id = self._create_volume(size=5) transfer = self._create_transfer(volume_id) diff --git a/cinder/tests/unit/api/contrib/test_volume_type_encryption.py b/cinder/tests/unit/api/contrib/test_volume_type_encryption.py index 27144499e5e..1dba18e6731 100644 --- a/cinder/tests/unit/api/contrib/test_volume_type_encryption.py +++ b/cinder/tests/unit/api/contrib/test_volume_type_encryption.py @@ -205,25 +205,6 @@ class VolumeTypeEncryptionTest(test.TestCase): self._create('fake_cipher', 'front-end', 128, 'fake_encryptor') self.assertTrue(mock_validate_integer.called) - def test_create_xml(self): - volume_type = self._default_volume_type - db.volume_type_create(context.get_admin_context(), volume_type) - - ctxt = context.RequestContext('fake', 'fake', is_admin=True) - - req = webob.Request.blank('/v2/fake/types/%s/encryption' - % volume_type['id']) - req.method = 'POST' - req.body = (b'') - req.headers['Content-Type'] = 'application/xml' - req.headers['Accept'] = 'application/xml' - res = req.get_response(fakes.wsgi_app(fake_auth_context=ctxt)) - - self.assertEqual(200, res.status_int) - - db.volume_type_destroy(context.get_admin_context(), volume_type['id']) - def test_create_invalid_volume_type(self): volume_type = self._default_volume_type body = {"encryption": stub_volume_type_encryption()} diff --git a/cinder/tests/unit/api/middleware/test_faults.py b/cinder/tests/unit/api/middleware/test_faults.py index eae64e564e7..da130e2bb84 100644 --- a/cinder/tests/unit/api/middleware/test_faults.py +++ b/cinder/tests/unit/api/middleware/test_faults.py @@ -12,33 +12,15 @@ # 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 xml.dom import minidom - -import mock from oslo_i18n import fixture as i18n_fixture from oslo_serialization import jsonutils -import six import webob.dec -from cinder.api import common from cinder.api.openstack import wsgi -from cinder.i18n import _ from cinder import test -class TestCase(test.TestCase): - def _prepare_xml(self, xml_string): - """Remove characters from string which hinder XML equality testing.""" - if six.PY3 and isinstance(xml_string, bytes): - xml_string = xml_string.decode('utf-8') - xml_string = xml_string.replace(" ", "") - xml_string = xml_string.replace("\n", "") - xml_string = xml_string.replace("\t", "") - return xml_string - - -class TestFaults(TestCase): +class TestFaults(test.TestCase): """Tests covering `cinder.api.openstack.faults:Fault` class.""" def setUp(self): @@ -92,219 +74,7 @@ class TestFaults(TestCase): self.assertEqual("application/json", response.content_type) self.assertEqual(expected, actual) - def test_raise(self): - """Ensure the ability to raise :class:`Fault` in WSGI-ified methods.""" - @webob.dec.wsgify - def raiser(req): - raise wsgi.Fault(webob.exc.HTTPNotFound(explanation='whut?')) - - req = webob.Request.blank('/.xml') - resp = req.get_response(raiser) - self.assertEqual("application/xml", resp.content_type) - self.assertEqual(404, resp.status_int) - self.assertIn(b'whut?', resp.body) - - def test_raise_403(self): - """Ensure the ability to raise :class:`Fault` in WSGI-ified methods.""" - @webob.dec.wsgify - def raiser(req): - raise wsgi.Fault(webob.exc.HTTPForbidden(explanation='whut?')) - - req = webob.Request.blank('/.xml') - resp = req.get_response(raiser) - self.assertEqual("application/xml", resp.content_type) - self.assertEqual(403, resp.status_int) - self.assertNotIn('resizeNotAllowed', resp.body) - self.assertIn(b'forbidden', resp.body) - - @mock.patch('cinder.api.openstack.wsgi.i18n.translate') - def test_raise_http_with_localized_explanation(self, mock_translate): - params = ('blah', ) - expl = _("String with params: %s") % params - - def _mock_translation(msg, locale): - return "Mensaje traducido" - - mock_translate.side_effect = _mock_translation - - @webob.dec.wsgify - def raiser(req): - raise wsgi.Fault(webob.exc.HTTPNotFound(explanation=expl)) - - req = webob.Request.blank('/.xml') - resp = req.get_response(raiser) - self.assertEqual("application/xml", resp.content_type) - self.assertEqual(404, resp.status_int) - self.assertIn(b"Mensaje traducido", resp.body) - self.stubs.UnsetAll() - def test_fault_has_status_int(self): """Ensure the status_int is set correctly on faults.""" fault = wsgi.Fault(webob.exc.HTTPBadRequest(explanation='what?')) self.assertEqual(400, fault.status_int) - - def test_xml_serializer(self): - """Ensure that a v2 request responds with a v2 xmlns.""" - request = webob.Request.blank('/v2', - headers={"Accept": "application/xml"}) - - fault = wsgi.Fault(webob.exc.HTTPBadRequest(explanation='scram')) - response = request.get_response(fault) - - self.assertIn(common.XML_NS_V2, response.body.decode()) - self.assertEqual("application/xml", response.content_type) - self.assertEqual(400, response.status_int) - - -class FaultsXMLSerializationTestV11(TestCase): - """Tests covering `cinder.api.openstack.faults:Fault` class.""" - - def test_400_fault(self): - metadata = {'attributes': {"badRequest": 'code'}} - serializer = wsgi.XMLDictSerializer(metadata=metadata, - xmlns=common.XML_NS_V1) - - fixture = { - "badRequest": { - "message": "scram", - "code": 400, - }, - } - - output = serializer.serialize(fixture) - actual = minidom.parseString(self._prepare_xml(output)) - - expected = minidom.parseString(self._prepare_xml(""" - - scram - - """) % common.XML_NS_V1) - - self.assertEqual(expected.toxml(), actual.toxml()) - - def test_413_fault(self): - metadata = {'attributes': {"overLimit": 'code'}} - serializer = wsgi.XMLDictSerializer(metadata=metadata, - xmlns=common.XML_NS_V1) - - fixture = { - "overLimit": { - "message": "sorry", - "code": 413, - "retryAfter": 4, - }, - } - - output = serializer.serialize(fixture) - if six.PY3: - output = output.decode('utf-8') - actual = minidom.parseString(self._prepare_xml(output)) - - expected = minidom.parseString(self._prepare_xml(""" - - sorry - 4 - - """) % common.XML_NS_V1) - - self.assertEqual(expected.toxml(), actual.toxml()) - - def test_404_fault(self): - metadata = {'attributes': {"itemNotFound": 'code'}} - serializer = wsgi.XMLDictSerializer(metadata=metadata, - xmlns=common.XML_NS_V1) - - fixture = { - "itemNotFound": { - "message": "sorry", - "code": 404, - }, - } - - output = serializer.serialize(fixture) - if six.PY3: - output = output.decode('utf-8') - actual = minidom.parseString(self._prepare_xml(output)) - - expected = minidom.parseString(self._prepare_xml(""" - - sorry - - """) % common.XML_NS_V1) - - self.assertEqual(expected.toxml(), actual.toxml()) - - -class FaultsXMLSerializationTestV2(TestCase): - """Tests covering `cinder.api.openstack.faults:Fault` class.""" - - def test_400_fault(self): - metadata = {'attributes': {"badRequest": 'code'}} - serializer = wsgi.XMLDictSerializer(metadata=metadata, - xmlns=common.XML_NS_V2) - - fixture = { - "badRequest": { - "message": "scram", - "code": 400, - }, - } - - output = serializer.serialize(fixture) - actual = minidom.parseString(self._prepare_xml(output)) - - expected = minidom.parseString(self._prepare_xml(""" - - scram - - """) % common.XML_NS_V2) - - self.assertEqual(expected.toxml(), actual.toxml()) - - def test_413_fault(self): - metadata = {'attributes': {"overLimit": 'code'}} - serializer = wsgi.XMLDictSerializer(metadata=metadata, - xmlns=common.XML_NS_V2) - - fixture = { - "overLimit": { - "message": "sorry", - "code": 413, - "retryAfter": 4, - }, - } - - output = serializer.serialize(fixture) - actual = minidom.parseString(self._prepare_xml(output)) - - expected = minidom.parseString(self._prepare_xml(""" - - sorry - 4 - - """) % common.XML_NS_V2) - - self.assertEqual(expected.toxml(), actual.toxml()) - - def test_404_fault(self): - metadata = {'attributes': {"itemNotFound": 'code'}} - serializer = wsgi.XMLDictSerializer(metadata=metadata, - xmlns=common.XML_NS_V2) - - fixture = { - "itemNotFound": { - "message": "sorry", - "code": 404, - }, - } - - output = serializer.serialize(fixture) - actual = minidom.parseString(self._prepare_xml(output)) - - expected = minidom.parseString(self._prepare_xml(""" - - sorry - - """) % common.XML_NS_V2) - - self.assertEqual(expected.toxml(), actual.toxml()) diff --git a/cinder/tests/unit/api/openstack/test_wsgi.py b/cinder/tests/unit/api/openstack/test_wsgi.py index a4ef22949c1..3c50272edaf 100644 --- a/cinder/tests/unit/api/openstack/test_wsgi.py +++ b/cinder/tests/unit/api/openstack/test_wsgi.py @@ -40,9 +40,7 @@ class RequestTest(test.TestCase): self.assertEqual("application/json", result) def test_content_type_from_accept(self): - for content_type in ('application/xml', - 'application/vnd.openstack.volume+xml', - 'application/json', + for content_type in ('application/json', 'application/vnd.openstack.volume+json'): request = wsgi.Request.blank('/tests/123') request.headers["Accept"] = content_type @@ -51,21 +49,11 @@ class RequestTest(test.TestCase): def test_content_type_from_accept_best(self): request = wsgi.Request.blank('/tests/123') - request.headers["Accept"] = "application/xml, application/json" + request.headers["Accept"] = "application/json" result = request.best_match_content_type() self.assertEqual("application/json", result) - request = wsgi.Request.blank('/tests/123') - request.headers["Accept"] = ("application/json; q=0.3, " - "application/xml; q=0.9") - result = request.best_match_content_type() - self.assertEqual("application/xml", result) - def test_content_type_from_query_extension(self): - request = wsgi.Request.blank('/tests/123.xml') - result = request.best_match_content_type() - self.assertEqual("application/xml", result) - request = wsgi.Request.blank('/tests/123.json') result = request.best_match_content_type() self.assertEqual("application/json", result) @@ -74,12 +62,6 @@ class RequestTest(test.TestCase): result = request.best_match_content_type() self.assertEqual("application/json", result) - def test_content_type_accept_and_query_extension(self): - request = wsgi.Request.blank('/tests/123.xml') - request.headers["Accept"] = "application/json" - result = request.best_match_content_type() - self.assertEqual("application/xml", result) - def test_content_type_accept_default(self): request = wsgi.Request.blank('/tests/123.unsupported') request.headers["Accept"] = "application/unsupported1" @@ -203,16 +185,6 @@ class DictSerializerTest(test.TestCase): self.assertEqual('', serializer.serialize({}, 'update')) -class XMLDictSerializerTest(test.TestCase): - def test_xml(self): - input_dict = dict(servers=dict(a=(2, 3))) - expected_xml = b'(2,3)' - serializer = wsgi.XMLDictSerializer(xmlns="asdf") - result = serializer.serialize(input_dict) - result = result.replace(b'\n', b'').replace(b' ', b'') - self.assertEqual(expected_xml, result) - - class JSONDictSerializerTest(test.TestCase): def test_json(self): input_dict = dict(servers=dict(a=(2, 3))) @@ -252,62 +224,6 @@ class JSONDeserializerTest(test.TestCase): self.assertEqual(as_dict, deserializer.deserialize(data)) -class XMLDeserializerTest(test.TestCase): - def test_xml(self): - xml = """ - - 123 - 1 - 1 - - """.strip() - as_dict = { - 'body': { - 'a': { - 'a1': '1', - 'a2': '2', - 'bs': ['1', '2', '3', {'c': {'c1': '1'}}], - 'd': {'e': '1'}, - 'f': '1', - }, - }, - } - metadata = {'plurals': {'bs': 'b', 'ts': 't'}} - deserializer = wsgi.XMLDeserializer(metadata=metadata) - self.assertEqual(as_dict, deserializer.deserialize(xml)) - - def test_xml_empty(self): - xml = """""" - as_dict = {"body": {"a": {}}} - deserializer = wsgi.XMLDeserializer() - self.assertEqual(as_dict, deserializer.deserialize(xml)) - - -class MetadataXMLDeserializerTest(test.TestCase): - def test_xml_meta_parsing_special_character(self): - """Test XML meta parsing with special characters. - - Test that when a SaxParser splits a string containing special - characters into multiple childNodes there are no issues extracting - the text. - """ - meta_xml_str = """ - - value&3 - value2 - value1 - - """.strip() - meta_expected = {'key1': 'value1', - 'key2': 'value2', - 'key3': 'value&3'} - meta_deserializer = wsgi.MetadataXMLDeserializer() - document = wsgi.utils.safe_minidom_parse_string(meta_xml_str) - root_node = document.childNodes[0] - meta_extracted = meta_deserializer.extract_metadata(root_node) - self.assertEqual(meta_expected, meta_extracted) - - class ResourceTest(test.TestCase): def test_resource_call(self): class Controller(object): @@ -365,18 +281,6 @@ class ResourceTest(test.TestCase): '{"fooAction": true}') self.assertEqual(controller._action_foo, method) - def test_get_method_action_xml(self): - class Controller(wsgi.Controller): - @wsgi.action('fooAction') - def _action_foo(self, req, id, body): - return body - - controller = Controller() - resource = wsgi.Resource(controller) - method, _extensions = resource.get_method( - None, 'action', 'application/xml', 'true') - self.assertEqual(controller._action_foo, method) - def test_get_method_action_bad_body(self): class Controller(wsgi.Controller): @wsgi.action('fooAction') @@ -400,18 +304,6 @@ class ResourceTest(test.TestCase): None, 'action', 'application/json', '{"barAction": true}') - def test_get_method_action_method(self): - class Controller(object): - def action(self, req, pants=None): - return pants - - controller = Controller() - resource = wsgi.Resource(controller) - method, _extensions = resource.get_method(None, 'action', - 'application/xml', - 'true" - b"Value1" - b"Value2Value3" - b"") - result = serializer.serialize(obj) - result = result.replace(b'\n', b'').replace(b' ', b'') - self.assertEqual(expected_xml, result) - - -class MasterTemplateBuilder(xmlutil.TemplateBuilder): - def construct(self): - elem = xmlutil.TemplateElement('test') - return xmlutil.MasterTemplate(elem, 1) - - -class SlaveTemplateBuilder(xmlutil.TemplateBuilder): - def construct(self): - elem = xmlutil.TemplateElement('test') - return xmlutil.SlaveTemplate(elem, 1) - - -class TemplateBuilderTest(test.TestCase): - def test_master_template_builder(self): - # Make sure the template hasn't been built yet - self.assertIsNone(MasterTemplateBuilder._tmpl) - - # Now, construct the template - tmpl1 = MasterTemplateBuilder() - - # Make sure that there is a template cached... - self.assertIsNotNone(MasterTemplateBuilder._tmpl) - - # Make sure it wasn't what was returned... - self.assertNotEqual(MasterTemplateBuilder._tmpl, tmpl1) - - # Make sure it doesn't get rebuilt - cached = MasterTemplateBuilder._tmpl - tmpl2 = MasterTemplateBuilder() - self.assertEqual(MasterTemplateBuilder._tmpl, cached) - - # Make sure we're always getting fresh copies - self.assertNotEqual(tmpl1, tmpl2) - - # Make sure we can override the copying behavior - tmpl3 = MasterTemplateBuilder(False) - self.assertEqual(MasterTemplateBuilder._tmpl, tmpl3) - - def test_slave_template_builder(self): - # Make sure the template hasn't been built yet - self.assertIsNone(SlaveTemplateBuilder._tmpl) - - # Now, construct the template - tmpl1 = SlaveTemplateBuilder() - - # Make sure there is a template cached... - self.assertIsNotNone(SlaveTemplateBuilder._tmpl) - - # Make sure it was what was returned... - self.assertEqual(SlaveTemplateBuilder._tmpl, tmpl1) - - # Make sure it doesn't get rebuilt - tmpl2 = SlaveTemplateBuilder() - self.assertEqual(SlaveTemplateBuilder._tmpl, tmpl1) - - # Make sure we're always getting the cached copy - self.assertEqual(tmpl1, tmpl2) - - -class MiscellaneousXMLUtilTests(test.TestCase): - def test_make_flat_dict(self): - expected_xml = (b"\n" - b'foo') - root = xmlutil.make_flat_dict('wrapper') - tmpl = xmlutil.MasterTemplate(root, 1) - result = tmpl.serialize(dict(wrapper=dict(a='foo'))) - self.assertEqual(expected_xml, result) diff --git a/cinder/tests/unit/api/v1/test_limits.py b/cinder/tests/unit/api/v1/test_limits.py index 1795293623e..023486c659e 100644 --- a/cinder/tests/unit/api/v1/test_limits.py +++ b/cinder/tests/unit/api/v1/test_limits.py @@ -17,9 +17,6 @@ Tests dealing with HTTP rate-limiting. """ -from xml.dom import minidom - -from lxml import etree from oslo_serialization import jsonutils import six from six.moves import http_client @@ -28,7 +25,6 @@ import webob from cinder.api.v1 import limits from cinder.api import views -from cinder.api import xmlutil import cinder.context from cinder import test from cinder.tests.unit import fake_constants as fake @@ -276,26 +272,6 @@ class LimitMiddlewareTest(BaseLimitTestSuite): value = body["overLimitFault"]["details"].strip() self.assertEqual(expected, value) - def test_limited_request_xml(self): - """Test a rate-limited (413) response as XML.""" - request = webob.Request.blank("/") - response = request.get_response(self.app) - self.assertEqual(200, response.status_int) - - request = webob.Request.blank("/") - request.accept = "application/xml" - response = request.get_response(self.app) - self.assertEqual(413, response.status_int) - - root = minidom.parseString(response.body).childNodes[0] - expected = "Only 1 GET request(s) can be made to * every minute." - - details = root.getElementsByTagName("details") - self.assertEqual(1, details.length) - - value = details.item(0).firstChild.data.strip() - self.assertEqual(expected, value) - class LimitTest(BaseLimitTestSuite): """Tests for the `limits.Limit` class.""" @@ -820,89 +796,3 @@ class LimitsViewBuilderTest(test.TestCase): rate_limits = [] output = self.view_builder.build(rate_limits, abs_limits) self.assertDictMatch(expected_limits, output) - - -class LimitsXMLSerializationTest(test.TestCase): - def test_xml_declaration(self): - serializer = limits.LimitsTemplate() - - fixture = {"limits": { - "rate": [], - "absolute": {}}} - - output = serializer.serialize(fixture) - has_dec = output.startswith(b"") - self.assertTrue(has_dec) - - def test_index(self): - serializer = limits.LimitsTemplate() - fixture = { - "limits": { - "rate": [{ - "uri": "*", - "regex": ".*", - "limit": [{ - "value": 10, - "verb": "POST", - "remaining": 2, - "unit": "MINUTE", - "next-available": "2011-12-15T22:42:45Z"}]}, - {"uri": "*/servers", - "regex": "^/servers", - "limit": [{ - "value": 50, - "verb": "POST", - "remaining": 10, - "unit": "DAY", - "next-available": "2011-12-15T22:42:45Z"}]}], - "absolute": {"maxServerMeta": 1, - "maxImageMeta": 1, - "maxPersonality": 5, - "maxPersonalitySize": 10240}}} - - output = serializer.serialize(fixture) - root = etree.XML(output) - xmlutil.validate_schema(root, 'limits') - - # verify absolute limits - absolutes = root.xpath('ns:absolute/ns:limit', namespaces=NS) - self.assertEqual(4, len(absolutes)) - for limit in absolutes: - name = limit.get('name') - value = limit.get('value') - self.assertEqual(str(fixture['limits']['absolute'][name]), value) - - # verify rate limits - rates = root.xpath('ns:rates/ns:rate', namespaces=NS) - self.assertEqual(2, len(rates)) - for i, rate in enumerate(rates): - for key in ['uri', 'regex']: - self.assertEqual(str(fixture['limits']['rate'][i][key]), - rate.get(key)) - rate_limits = rate.xpath('ns:limit', namespaces=NS) - self.assertEqual(1, len(rate_limits)) - for j, limit in enumerate(rate_limits): - for key in ['verb', 'value', 'remaining', 'unit', - 'next-available']: - self.assertEqual( - str(fixture['limits']['rate'][i]['limit'][j][key]), - limit.get(key)) - - def test_index_no_limits(self): - serializer = limits.LimitsTemplate() - - fixture = {"limits": { - "rate": [], - "absolute": {}}} - - output = serializer.serialize(fixture) - root = etree.XML(output) - xmlutil.validate_schema(root, 'limits') - - # verify absolute limits - absolutes = root.xpath('ns:absolute/ns:limit', namespaces=NS) - self.assertEqual(0, len(absolutes)) - - # verify rate limits - rates = root.xpath('ns:rates/ns:rate', namespaces=NS) - self.assertEqual(0, len(rates)) diff --git a/cinder/tests/unit/api/v1/test_snapshots.py b/cinder/tests/unit/api/v1/test_snapshots.py index 48e1396ae43..879ea846b79 100644 --- a/cinder/tests/unit/api/v1/test_snapshots.py +++ b/cinder/tests/unit/api/v1/test_snapshots.py @@ -13,9 +13,7 @@ # License for the specific language governing permissions and limitations # under the License. -from lxml import etree import mock -from oslo_utils import timeutils import webob from cinder.api.v1 import snapshots @@ -379,56 +377,6 @@ class SnapshotApiTest(test.TestCase): self.assertEqual(1, len(res['snapshots'])) -class SnapshotSerializerTest(test.TestCase): - def _verify_snapshot(self, snap, tree): - self.assertEqual('snapshot', tree.tag) - - for attr in ('id', 'status', 'size', 'created_at', - 'display_name', 'display_description', 'volume_id'): - self.assertEqual(str(snap[attr]), tree.get(attr)) - - def test_snapshot_show_create_serializer(self): - serializer = snapshots.SnapshotTemplate() - raw_snapshot = dict( - id='snap_id', - status='snap_status', - size=1024, - created_at=timeutils.utcnow(), - display_name='snap_name', - display_description='snap_desc', - volume_id='vol_id', ) - text = serializer.serialize(dict(snapshot=raw_snapshot)) - - tree = etree.fromstring(text) - - self._verify_snapshot(raw_snapshot, tree) - - def test_snapshot_index_detail_serializer(self): - serializer = snapshots.SnapshotsTemplate() - raw_snapshots = [dict(id='snap1_id', - status='snap1_status', - size=1024, - created_at=timeutils.utcnow(), - display_name='snap1_name', - display_description='snap1_desc', - volume_id='vol1_id', ), - dict(id='snap2_id', - status='snap2_status', - size=1024, - created_at=timeutils.utcnow(), - display_name='snap2_name', - display_description='snap2_desc', - volume_id='vol2_id', )] - text = serializer.serialize(dict(snapshots=raw_snapshots)) - - tree = etree.fromstring(text) - - self.assertEqual('snapshots', tree.tag) - self.assertEqual(len(raw_snapshots), len(tree)) - for idx, child in enumerate(tree): - self._verify_snapshot(raw_snapshots[idx], child) - - class SnapshotsUnprocessableEntityTestCase(test.TestCase): """Tests of places we throw 422 Unprocessable Entity.""" diff --git a/cinder/tests/unit/api/v1/test_types.py b/cinder/tests/unit/api/v1/test_types.py index 8a81f220cb3..e897dff6bfd 100644 --- a/cinder/tests/unit/api/v1/test_types.py +++ b/cinder/tests/unit/api/v1/test_types.py @@ -15,7 +15,6 @@ import uuid -from lxml import etree from oslo_utils import timeutils import webob @@ -166,45 +165,3 @@ class VolumeTypesApiTest(test.TestCase): description=None) self.assertDictMatch(expected_volume_type, output['volume_types'][i]) - - -class VolumeTypesSerializerTest(test.TestCase): - def _verify_volume_type(self, vtype, tree): - self.assertEqual('volume_type', tree.tag) - self.assertEqual(vtype['name'], tree.get('name')) - self.assertEqual(vtype['id'], tree.get('id')) - self.assertEqual(1, len(tree)) - extra_specs = tree[0] - self.assertEqual('extra_specs', extra_specs.tag) - seen = set(vtype['extra_specs'].keys()) - for child in extra_specs: - self.assertIn(child.tag, seen) - self.assertEqual(vtype['extra_specs'][child.tag], child.text) - seen.remove(child.tag) - self.assertEqual(0, len(seen)) - - def test_index_serializer(self): - serializer = types.VolumeTypesTemplate() - - # Just getting some input data - vtypes = return_volume_types_get_all_types(None) - text = serializer.serialize({'volume_types': list(vtypes.values())}) - - tree = etree.fromstring(text) - - self.assertEqual('volume_types', tree.tag) - self.assertEqual(len(vtypes), len(tree)) - for child in tree: - name = child.get('name') - self.assertIn(name, vtypes) - self._verify_volume_type(vtypes[name], child) - - def test_voltype_serializer(self): - serializer = types.VolumeTypeTemplate() - - vtype = stub_volume_type(fake.volume_type_id) - text = serializer.serialize(dict(volume_type=vtype)) - - tree = etree.fromstring(text) - - self._verify_volume_type(vtype, tree) diff --git a/cinder/tests/unit/api/v1/test_volumes.py b/cinder/tests/unit/api/v1/test_volumes.py index cd907817db0..9ef7fc3988a 100644 --- a/cinder/tests/unit/api/v1/test_volumes.py +++ b/cinder/tests/unit/api/v1/test_volumes.py @@ -16,10 +16,8 @@ import datetime import iso8601 -from lxml import etree import mock from oslo_config import cfg -from oslo_utils import timeutils import webob from cinder.api import extensions @@ -861,285 +859,6 @@ class VolumeApiTest(test.TestCase): marker=None) -class VolumeSerializerTest(test.TestCase): - def _verify_volume_attachment(self, attach, tree): - for attr in ('id', 'volume_id', 'server_id', 'device'): - self.assertEqual(str(attach[attr]), tree.get(attr)) - - def _verify_volume(self, vol, tree): - self.assertEqual(NS + 'volume', tree.tag) - - for attr in ('id', 'status', 'size', 'availability_zone', 'created_at', - 'display_name', 'display_description', 'volume_type', - 'bootable', 'snapshot_id'): - self.assertEqual(str(vol[attr]), tree.get(attr)) - - for child in tree: - self.assertIn(child.tag, (NS + 'attachments', NS + 'metadata')) - if child.tag == 'attachments': - self.assertEqual(1, len(child)) - self.assertEqual('attachment', child[0].tag) - self._verify_volume_attachment(vol['attachments'][0], child[0]) - elif child.tag == 'metadata': - not_seen = set(vol['metadata'].keys()) - for gr_child in child: - self.assertIn(gr_child.get("key"), not_seen) - self.assertEqual(str(vol['metadata'][gr_child.get("key")]), - gr_child.text) - not_seen.remove(gr_child.get('key')) - self.assertEqual(0, len(not_seen)) - - def test_volume_show_create_serializer(self): - serializer = volumes.VolumeTemplate() - raw_volume = dict( - id=fake.volume_id, - status='vol_status', - size=1024, - availability_zone='vol_availability', - bootable='false', - created_at=timeutils.utcnow(), - attachments=[dict(id=fake.volume_id, - volume_id=fake.volume_id, - server_id=fake.instance_id, - device='/foo')], - display_name='vol_name', - display_description='vol_desc', - volume_type=fake.volume_type_id, - snapshot_id=fake.snapshot_id, - source_volid=fake.volume2_id, - metadata=dict(foo='bar', - baz='quux', ), ) - text = serializer.serialize(dict(volume=raw_volume)) - - tree = etree.fromstring(text) - - self._verify_volume(raw_volume, tree) - - def test_volume_index_detail_serializer(self): - serializer = volumes.VolumesTemplate() - raw_volumes = [dict(id=fake.volume_id, - status='vol1_status', - size=1024, - availability_zone='vol1_availability', - bootable='true', - created_at=timeutils.utcnow(), - attachments=[dict(id=fake.attachment_id, - volume_id=fake.volume_id, - server_id=fake.instance_id, - device='/foo1')], - display_name='vol1_name', - display_description='vol1_desc', - volume_type=fake.volume_type_id, - snapshot_id=fake.snapshot_id, - source_volid=None, - metadata=dict(foo='vol1_foo', - bar='vol1_bar', ), ), - dict(id=fake.volume2_id, - status='vol2_status', - size=1024, - availability_zone='vol2_availability', - bootable='true', - created_at=timeutils.utcnow(), - attachments=[dict(id=fake.attachment2_id, - volume_id=fake.volume2_id, - server_id=fake.instance_id, - device='/foo2')], - display_name='vol2_name', - display_description='vol2_desc', - volume_type=fake.volume_type2_id, - snapshot_id=fake.snapshot2_id, - source_volid=None, - metadata=dict(foo='vol2_foo', - bar='vol2_bar', ), )] - text = serializer.serialize(dict(volumes=raw_volumes)) - - tree = etree.fromstring(text) - - self.assertEqual(NS + 'volumes', tree.tag) - self.assertEqual(len(raw_volumes), len(tree)) - for idx, child in enumerate(tree): - self._verify_volume(raw_volumes[idx], child) - - -class TestVolumeCreateRequestXMLDeserializer(test.TestCase): - - def setUp(self): - super(TestVolumeCreateRequestXMLDeserializer, self).setUp() - self.deserializer = volumes.CreateDeserializer() - - def test_minimal_volume(self): - self_request = """ -""" - request = self.deserializer.deserialize(self_request) - expected = {"volume": {"size": "1", }, } - self.assertEqual(expected, request['body']) - - def test_display_name(self): - self_request = """ -""" - request = self.deserializer.deserialize(self_request) - expected = { - "volume": { - "size": "1", - "display_name": "Volume-xml", - }, - } - self.assertEqual(expected, request['body']) - - def test_display_description(self): - self_request = """ -""" - request = self.deserializer.deserialize(self_request) - expected = { - "volume": { - "size": "1", - "display_name": "Volume-xml", - "display_description": "description", - }, - } - self.assertEqual(expected, request['body']) - - def test_volume_type(self): - self_request = """ -""" - request = self.deserializer.deserialize(self_request) - expected = { - "volume": { - "size": "1", - "display_name": "Volume-xml", - "display_description": "description", - "volume_type": "289da7f8-6440-407c-9fb4-7db01ec49164", - }, - } - self.assertEqual(expected, request['body']) - - def test_availability_zone(self): - self_request = """ -""" - request = self.deserializer.deserialize(self_request) - expected = { - "volume": { - "size": "1", - "display_name": "Volume-xml", - "display_description": "description", - "volume_type": "289da7f8-6440-407c-9fb4-7db01ec49164", - "availability_zone": "us-east1", - }, - } - self.assertEqual(expected, request['body']) - - def test_metadata(self): - self_request = """ - - work""" - request = self.deserializer.deserialize(self_request) - expected = { - "volume": { - "display_name": "Volume-xml", - "size": "1", - "metadata": { - "Type": "work", - }, - }, - } - self.assertEqual(expected, request['body']) - - def test_full_volume(self): - self_request = """ - - work""" - request = self.deserializer.deserialize(self_request) - expected = { - "volume": { - "size": "1", - "display_name": "Volume-xml", - "display_description": "description", - "volume_type": "289da7f8-6440-407c-9fb4-7db01ec49164", - "availability_zone": "us-east1", - "metadata": { - "Type": "work", - }, - }, - } - self.assertEqual(expected, request['body']) - - def test_imageref(self): - self_request = """ -""" - request = self.deserializer.deserialize(self_request) - expected = { - "volume": { - "size": "1", - "display_name": "Volume-xml", - "display_description": "description", - "imageRef": "4a90189d-d702-4c7c-87fc-6608c554d737", - }, - } - self.assertEqual(expected, request['body']) - - def test_snapshot_id(self): - self_request = """ -""" - request = self.deserializer.deserialize(self_request) - expected = { - "volume": { - "size": "1", - "display_name": "Volume-xml", - "display_description": "description", - "snapshot_id": "4a90189d-d702-4c7c-87fc-6608c554d737", - }, - } - self.assertEqual(expected, request['body']) - - def test_source_volid(self): - self_request = """ -""" - request = self.deserializer.deserialize(self_request) - expected = { - "volume": { - "size": "1", - "display_name": "Volume-xml", - "display_description": "description", - "source_volid": "4a90189d-d702-4c7c-87fc-6608c554d737", - }, - } - self.assertEqual(expected, request['body']) - - class VolumesUnprocessableEntityTestCase(test.TestCase): """Tests of places we throw 422 Unprocessable Entity from.""" diff --git a/cinder/tests/unit/api/v2/test_limits.py b/cinder/tests/unit/api/v2/test_limits.py index 5a62e69af85..292bde74075 100644 --- a/cinder/tests/unit/api/v2/test_limits.py +++ b/cinder/tests/unit/api/v2/test_limits.py @@ -17,9 +17,6 @@ Tests dealing with HTTP rate-limiting. """ -from xml.dom import minidom - -from lxml import etree from oslo_serialization import jsonutils import six from six.moves import http_client @@ -28,7 +25,6 @@ import webob from cinder.api.v2 import limits from cinder.api import views -from cinder.api import xmlutil import cinder.context from cinder import test @@ -277,26 +273,6 @@ class LimitMiddlewareTest(BaseLimitTestSuite): value = body["overLimitFault"]["details"].strip() self.assertEqual(expected, value) - def test_limited_request_xml(self): - """Test a rate-limited (413) response as XML.""" - request = webob.Request.blank("/") - response = request.get_response(self.app) - self.assertEqual(200, response.status_int) - - request = webob.Request.blank("/") - request.accept = "application/xml" - response = request.get_response(self.app) - self.assertEqual(413, response.status_int) - - root = minidom.parseString(response.body).childNodes[0] - expected = "Only 1 GET request(s) can be made to * every minute." - - details = root.getElementsByTagName("details") - self.assertEqual(1, details.length) - - value = details.item(0).firstChild.data.strip() - self.assertEqual(expected, value) - class LimitTest(BaseLimitTestSuite): @@ -826,85 +802,3 @@ class LimitsViewBuilderTest(test.TestCase): rate_limits = [] output = self.view_builder.build(rate_limits, abs_limits) self.assertDictMatch(expected_limits, output) - - -class LimitsXMLSerializationTest(test.TestCase): - def test_xml_declaration(self): - serializer = limits.LimitsTemplate() - - fixture = {"limits": { - "rate": [], - "absolute": {}}} - - output = serializer.serialize(fixture) - has_dec = output.startswith(b"") - self.assertTrue(has_dec) - - def test_index(self): - tdate = "2011-12-15T22:42:45Z" - serializer = limits.LimitsTemplate() - fixture = {"limits": {"rate": [{"uri": "*", - "regex": ".*", - "limit": [{"value": 10, - "verb": "POST", - "remaining": 2, - "unit": "MINUTE", - "next-available": tdate}]}, - {"uri": "*/servers", - "regex": "^/servers", - "limit": [{"value": 50, - "verb": "POST", - "remaining": 10, - "unit": "DAY", - "next-available": tdate}]}], - "absolute": {"maxServerMeta": 1, - "maxImageMeta": 1, - "maxPersonality": 5, - "maxPersonalitySize": 10240}}} - - output = serializer.serialize(fixture) - root = etree.XML(output) - xmlutil.validate_schema(root, 'limits') - - # verify absolute limits - absolutes = root.xpath('ns:absolute/ns:limit', namespaces=NS) - self.assertEqual(4, len(absolutes)) - for limit in absolutes: - name = limit.get('name') - value = limit.get('value') - self.assertEqual(str(fixture['limits']['absolute'][name]), value) - - # verify rate limits - rates = root.xpath('ns:rates/ns:rate', namespaces=NS) - self.assertEqual(2, len(rates)) - for i, rate in enumerate(rates): - for key in ['uri', 'regex']: - self.assertEqual(str(fixture['limits']['rate'][i][key]), - rate.get(key)) - rate_limits = rate.xpath('ns:limit', namespaces=NS) - self.assertEqual(1, len(rate_limits)) - for j, limit in enumerate(rate_limits): - for key in ['verb', 'value', 'remaining', 'unit', - 'next-available']: - self.assertEqual( - str(fixture['limits']['rate'][i]['limit'][j][key]), - limit.get(key)) - - def test_index_no_limits(self): - serializer = limits.LimitsTemplate() - - fixture = {"limits": { - "rate": [], - "absolute": {}}} - - output = serializer.serialize(fixture) - root = etree.XML(output) - xmlutil.validate_schema(root, 'limits') - - # verify absolute limits - absolutes = root.xpath('ns:absolute/ns:limit', namespaces=NS) - self.assertEqual(0, len(absolutes)) - - # verify rate limits - rates = root.xpath('ns:rates/ns:rate', namespaces=NS) - self.assertEqual(0, len(rates)) diff --git a/cinder/tests/unit/api/v2/test_snapshots.py b/cinder/tests/unit/api/v2/test_snapshots.py index 0fb896eebdd..9fbc49077fa 100644 --- a/cinder/tests/unit/api/v2/test_snapshots.py +++ b/cinder/tests/unit/api/v2/test_snapshots.py @@ -13,10 +13,8 @@ # License for the specific language governing permissions and limitations # under the License. -from lxml import etree import mock from oslo_config import cfg -from oslo_utils import timeutils from six.moves.urllib import parse as urllib import webob @@ -582,61 +580,3 @@ class SnapshotApiTest(test.TestCase): def test_create_malformed_entity(self): body = {'snapshot': 'string'} self._create_snapshot_bad_body(body=body) - - -class SnapshotSerializerTest(test.TestCase): - def _verify_snapshot(self, snap, tree): - self.assertEqual('snapshot', tree.tag) - - for attr in ('id', 'status', 'size', 'created_at', - 'name', 'description', 'volume_id'): - self.assertEqual(str(snap[attr]), tree.get(attr)) - - def test_snapshot_show_create_serializer(self): - serializer = snapshots.SnapshotTemplate() - raw_snapshot = dict( - id='snap_id', - status='snap_status', - size=1024, - created_at=timeutils.utcnow(), - name='snap_name', - description='snap_desc', - display_description='snap_desc', - volume_id='vol_id', - ) - text = serializer.serialize(dict(snapshot=raw_snapshot)) - - tree = etree.fromstring(text) - - self._verify_snapshot(raw_snapshot, tree) - - def test_snapshot_index_detail_serializer(self): - serializer = snapshots.SnapshotsTemplate() - raw_snapshots = [ - dict( - id='snap1_id', - status='snap1_status', - size=1024, - created_at=timeutils.utcnow(), - name='snap1_name', - description='snap1_desc', - volume_id='vol1_id', - ), - dict( - id='snap2_id', - status='snap2_status', - size=1024, - created_at=timeutils.utcnow(), - name='snap2_name', - description='snap2_desc', - volume_id='vol2_id', - ) - ] - text = serializer.serialize(dict(snapshots=raw_snapshots)) - - tree = etree.fromstring(text) - - self.assertEqual('snapshots', tree.tag) - self.assertEqual(len(raw_snapshots), len(tree)) - for idx, child in enumerate(tree): - self._verify_snapshot(raw_snapshots[idx], child) diff --git a/cinder/tests/unit/api/v2/test_types.py b/cinder/tests/unit/api/v2/test_types.py index f5894f3e3c4..a93717a1db7 100644 --- a/cinder/tests/unit/api/v2/test_types.py +++ b/cinder/tests/unit/api/v2/test_types.py @@ -15,7 +15,6 @@ import uuid -from lxml import etree import mock from oslo_utils import timeutils import six @@ -506,46 +505,3 @@ class VolumeTypesApiTest(test.TestCase): ) self.assertDictMatch(expected_volume_type, output['volume_types'][i]) - - -class VolumeTypesSerializerTest(test.TestCase): - def _verify_volume_type(self, vtype, tree): - self.assertEqual('volume_type', tree.tag) - self.assertEqual(vtype['name'], tree.get('name')) - self.assertEqual(vtype['description'], tree.get('description')) - self.assertEqual(str(vtype['id']), tree.get('id')) - self.assertEqual(1, len(tree)) - extra_specs = tree[0] - self.assertEqual('extra_specs', extra_specs.tag) - seen = set(vtype['extra_specs'].keys()) - for child in extra_specs: - self.assertIn(child.tag, seen) - self.assertEqual(vtype['extra_specs'][child.tag], child.text) - seen.remove(child.tag) - self.assertEqual(0, len(seen)) - - def test_index_serializer(self): - serializer = types.VolumeTypesTemplate() - - # Just getting some input data - vtypes = return_volume_types_get_all_types(None) - text = serializer.serialize({'volume_types': list(vtypes.values())}) - - tree = etree.fromstring(text) - - self.assertEqual('volume_types', tree.tag) - self.assertEqual(len(vtypes), len(tree)) - for child in tree: - name = child.get('name') - self.assertIn(name, vtypes) - self._verify_volume_type(vtypes[name], child) - - def test_voltype_serializer(self): - serializer = types.VolumeTypeTemplate() - - vtype = stub_volume_type(1) - text = serializer.serialize(dict(volume_type=vtype)) - - tree = etree.fromstring(text) - - self._verify_volume_type(vtype, tree) diff --git a/cinder/tests/unit/api/v2/test_volumes.py b/cinder/tests/unit/api/v2/test_volumes.py index 1234d4922b1..9589814a6aa 100644 --- a/cinder/tests/unit/api/v2/test_volumes.py +++ b/cinder/tests/unit/api/v2/test_volumes.py @@ -17,10 +17,8 @@ import datetime import iso8601 -from lxml import etree import mock from oslo_config import cfg -from oslo_utils import timeutils import six from six.moves import range from six.moves import urllib @@ -1592,300 +1590,3 @@ class VolumeApiTest(test.TestCase): self.override_config('query_volume_filters', filter_list) self.assertEqual(filter_list, self.controller._get_volume_filter_options()) - - -class VolumeSerializerTest(test.TestCase): - def _verify_volume_attachment(self, attach, tree): - for attr in ('id', 'volume_id', 'server_id', 'device'): - self.assertEqual(str(attach[attr]), tree.get(attr)) - - def _verify_volume(self, vol, tree): - self.assertEqual(NS + 'volume', tree.tag) - - for attr in ('id', 'status', 'size', 'availability_zone', 'created_at', - 'name', 'description', 'volume_type', 'bootable', - 'snapshot_id', 'source_volid'): - self.assertEqual(str(vol[attr]), tree.get(attr)) - - for child in tree: - self.assertIn(child.tag, (NS + 'attachments', NS + 'metadata')) - if child.tag == 'attachments': - self.assertEqual(1, len(child)) - self.assertEqual('attachment', child[0].tag) - self._verify_volume_attachment(vol['attachments'][0], child[0]) - elif child.tag == 'metadata': - not_seen = set(vol['metadata'].keys()) - for gr_child in child: - self.assertIn(gr_child.get("key"), not_seen) - self.assertEqual(str(vol['metadata'][gr_child.get("key")]), - gr_child.text) - not_seen.remove(gr_child.get('key')) - self.assertEqual(0, len(not_seen)) - - def test_volume_show_create_serializer(self): - serializer = volumes.VolumeTemplate() - raw_volume = dict( - id='vol_id', - status='vol_status', - size=1024, - availability_zone='vol_availability', - bootable=False, - created_at=timeutils.utcnow(), - attachments=[ - dict( - id='vol_id', - volume_id='vol_id', - server_id='instance_uuid', - device='/foo' - ) - ], - name='vol_name', - description='vol_desc', - volume_type='vol_type', - snapshot_id='snap_id', - source_volid='source_volid', - metadata=dict( - foo='bar', - baz='quux', - ), - ) - text = serializer.serialize(dict(volume=raw_volume)) - - tree = etree.fromstring(text) - - self._verify_volume(raw_volume, tree) - - def test_volume_index_detail_serializer(self): - serializer = volumes.VolumesTemplate() - raw_volumes = [ - dict( - id='vol1_id', - status='vol1_status', - size=1024, - availability_zone='vol1_availability', - bootable=True, - created_at=timeutils.utcnow(), - attachments=[ - dict( - id='vol1_id', - volume_id='vol1_id', - server_id='instance_uuid', - device='/foo1' - ) - ], - name='vol1_name', - description='vol1_desc', - volume_type='vol1_type', - snapshot_id='snap1_id', - source_volid=None, - metadata=dict(foo='vol1_foo', - bar='vol1_bar', ), ), - dict( - id='vol2_id', - status='vol2_status', - size=1024, - availability_zone='vol2_availability', - bootable=False, - created_at=timeutils.utcnow(), - attachments=[dict(id='vol2_id', - volume_id='vol2_id', - server_id='instance_uuid', - device='/foo2')], - name='vol2_name', - description='vol2_desc', - volume_type='vol2_type', - snapshot_id='snap2_id', - source_volid=None, - metadata=dict(foo='vol2_foo', - bar='vol2_bar', ), )] - text = serializer.serialize(dict(volumes=raw_volumes)) - - tree = etree.fromstring(text) - - self.assertEqual(NS + 'volumes', tree.tag) - self.assertEqual(len(raw_volumes), len(tree)) - for idx, child in enumerate(tree): - self._verify_volume(raw_volumes[idx], child) - - -class TestVolumeCreateRequestXMLDeserializer(test.TestCase): - - def setUp(self): - super(TestVolumeCreateRequestXMLDeserializer, self).setUp() - self.deserializer = volumes.CreateDeserializer() - - def test_minimal_volume(self): - self_request = """ -""" - request = self.deserializer.deserialize(self_request) - expected = { - "volume": { - "size": "1", - }, - } - self.assertEqual(expected, request['body']) - - def test_name(self): - self_request = """ -""" - request = self.deserializer.deserialize(self_request) - expected = { - "volume": { - "size": "1", - "name": "Volume-xml", - }, - } - self.assertEqual(expected, request['body']) - - def test_description(self): - self_request = """ -""" - request = self.deserializer.deserialize(self_request) - expected = { - "volume": { - "size": "1", - "name": "Volume-xml", - "description": "description", - }, - } - self.assertEqual(expected, request['body']) - - def test_volume_type(self): - self_request = """ -""" - request = self.deserializer.deserialize(self_request) - expected = { - "volume": { - "size": "1", - "name": "Volume-xml", - "description": "description", - "volume_type": "289da7f8-6440-407c-9fb4-7db01ec49164", - }, - } - self.assertEqual(expected, request['body']) - - def test_availability_zone(self): - self_request = """ -""" - request = self.deserializer.deserialize(self_request) - expected = { - "volume": { - "size": "1", - "name": "Volume-xml", - "description": "description", - "volume_type": "289da7f8-6440-407c-9fb4-7db01ec49164", - "availability_zone": "us-east1", - }, - } - self.assertEqual(expected, request['body']) - - def test_metadata(self): - self_request = """ - - work""" - request = self.deserializer.deserialize(self_request) - expected = { - "volume": { - "name": "Volume-xml", - "size": "1", - "metadata": { - "Type": "work", - }, - }, - } - self.assertEqual(expected, request['body']) - - def test_full_volume(self): - self_request = """ - - work""" - request = self.deserializer.deserialize(self_request) - expected = { - "volume": { - "size": "1", - "name": "Volume-xml", - "description": "description", - "volume_type": "289da7f8-6440-407c-9fb4-7db01ec49164", - "availability_zone": "us-east1", - "metadata": { - "Type": "work", - }, - }, - } - self.assertEqual(expected, request['body']) - - def test_imageref(self): - self_request = """ -""" - request = self.deserializer.deserialize(self_request) - expected = { - "volume": { - "size": "1", - "name": "Volume-xml", - "description": "description", - "imageRef": "4a90189d-d702-4c7c-87fc-6608c554d737", - }, - } - self.assertEqual(expected, request['body']) - - def test_snapshot_id(self): - self_request = """ -""" - request = self.deserializer.deserialize(self_request) - expected = { - "volume": { - "size": "1", - "name": "Volume-xml", - "description": "description", - "snapshot_id": "4a90189d-d702-4c7c-87fc-6608c554d737", - }, - } - self.assertEqual(expected, request['body']) - - def test_source_volid(self): - self_request = """ -""" - request = self.deserializer.deserialize(self_request) - expected = { - "volume": { - "size": "1", - "name": "Volume-xml", - "description": "description", - "source_volid": "4a90189d-d702-4c7c-87fc-6608c554d737", - }, - } - self.assertEqual(expected, request['body']) diff --git a/cinder/tests/unit/api/views/test_versions.py b/cinder/tests/unit/api/views/test_versions.py index b21fdd2e245..0646419a330 100644 --- a/cinder/tests/unit/api/views/test_versions.py +++ b/cinder/tests/unit/api/views/test_versions.py @@ -48,10 +48,6 @@ FAKE_VERSIONS = { { "base": "application/json", "type": "application/vnd.openstack.share+json;version=1", - }, - { - "base": "application/xml", - "type": "application/vnd.openstack.share+xml;version=1", } ], }, diff --git a/cinder/tests/unit/test_api_urlmap.py b/cinder/tests/unit/test_api_urlmap.py index 57b6b504101..f4ae0383570 100644 --- a/cinder/tests/unit/test_api_urlmap.py +++ b/cinder/tests/unit/test_api_urlmap.py @@ -57,7 +57,7 @@ class TestAccept(test.TestCase): accept = urlmap.Accept(arg) self.assertEqual(('application/json', {'q': '0.7'}), accept.best_match(['application/json', - 'application/xml', 'text/html'])) + 'text/html'])) def test_match_mask_one_asterisk(self): arg = 'text/*; q=0.7' @@ -77,14 +77,14 @@ class TestAccept(test.TestCase): self.assertEqual((None, {}), accept.best_match(['text/html'])) def test_content_type_params(self): - arg = "application/xml; q=0.1, application/json; q=0.2," \ + arg = "application/json; q=0.2," \ " text/html; q=0.3" accept = urlmap.Accept(arg) self.assertEqual({'q': '0.2'}, accept.content_type_params('application/json')) def test_content_type_params_wrong_content_type(self): - arg = 'application/xml; q=0.1, text/html; q=0.1' + arg = 'text/html; q=0.1' accept = urlmap.Accept(arg) self.assertEqual({}, accept.content_type_params('application/json')) @@ -142,16 +142,6 @@ class TestURLMap(test.TestCase): def setUp(self): super(TestURLMap, self).setUp() self.urlmap = urlmap.URLMap() - self.input_environ = {'HTTP_ACCEPT': "application/json;" - "version=9.0", 'REQUEST_METHOD': "GET", - 'CONTENT_TYPE': 'application/xml', - 'SCRIPT_NAME': '/scriptname', - 'PATH_INFO': "/resource.xml"} - self.environ = {'HTTP_ACCEPT': "application/json;" - "version=9.0", 'REQUEST_METHOD': "GET", - 'CONTENT_TYPE': 'application/xml', - 'SCRIPT_NAME': '/scriptname/app_url', - 'PATH_INFO': "/resource.xml"} def test_match_with_applications(self): self.urlmap[('http://10.20.30.40:50', '/path/somepath')] = 'app' @@ -178,61 +168,11 @@ class TestURLMap(test.TestCase): self.urlmap._match('http://20.30.40.50', '60', '/path/somepath/elsepath')) - def test_set_script_name(self): - app = self.mox.CreateMockAnything() - start_response = self.mox.CreateMockAnything() - app.__call__(self.environ, start_response).AndReturn('value') - self.mox.ReplayAll() - wrap = self.urlmap._set_script_name(app, '/app_url') - self.assertEqual('value', wrap(self.input_environ, start_response)) - - def test_munge_path(self): - app = self.mox.CreateMockAnything() - start_response = self.mox.CreateMockAnything() - app.__call__(self.environ, start_response).AndReturn('value') - self.mox.ReplayAll() - wrap = self.urlmap._munge_path(app, '/app_url/resource.xml', - '/app_url') - self.assertEqual('value', wrap(self.input_environ, start_response)) - - def test_content_type_strategy_without_version(self): - self.assertIsNone(self.urlmap._content_type_strategy('host', 20, - self.environ)) - - def test_content_type_strategy_with_version(self): - environ = {'HTTP_ACCEPT': "application/vnd.openstack.melange+xml;" - "version=9.0", 'REQUEST_METHOD': "GET", - 'PATH_INFO': "/resource.xml", - 'CONTENT_TYPE': 'application/xml; version=2.0'} - self.urlmap[('http://10.20.30.40:50', '/v2.0')] = 'app' - self.mox.StubOutWithMock(self.urlmap, '_set_script_name') - self.urlmap._set_script_name('app', '/v2.0').AndReturn('value') - self.mox.ReplayAll() - self.assertEqual('value', - self.urlmap._content_type_strategy( - 'http://10.20.30.40', '50', environ)) - def test_path_strategy_wrong_path_info(self): self.assertEqual((None, None, None), self.urlmap._path_strategy('http://10.20.30.40', '50', '/resource')) - def test_path_strategy_mime_type_only(self): - self.assertEqual(('application/xml', None, None), - self.urlmap._path_strategy('http://10.20.30.40', '50', - '/resource.xml')) - - def test_path_strategy(self): - self.urlmap[('http://10.20.30.40:50', '/path/elsepath/')] = 'app' - self.mox.StubOutWithMock(self.urlmap, '_munge_path') - self.urlmap._munge_path('app', '/path/elsepath/resource.xml', - '/path/elsepath').AndReturn('value') - self.mox.ReplayAll() - self.assertEqual( - ('application/xml', 'value', '/path/elsepath'), - self.urlmap._path_strategy('http://10.20.30.40', '50', - '/path/elsepath/resource.xml')) - def test_path_strategy_wrong_mime_type(self): self.urlmap[('http://10.20.30.40:50', '/path/elsepath/')] = 'app' self.mox.StubOutWithMock(self.urlmap, '_munge_path') @@ -243,29 +183,3 @@ class TestURLMap(test.TestCase): (None, 'value', '/path/elsepath'), self.urlmap._path_strategy('http://10.20.30.40', '50', '/path/elsepath/resource.abc')) - - def test_accept_strategy_version_not_in_params(self): - environ = {'HTTP_ACCEPT': "application/xml; q=0.1, application/json; " - "q=0.2", 'REQUEST_METHOD': "GET", - 'PATH_INFO': "/resource.xml", - 'CONTENT_TYPE': 'application/xml; version=2.0'} - self.assertEqual(('application/xml', None), - self.urlmap._accept_strategy('http://10.20.30.40', - '50', - environ, - ['application/xml'])) - - def test_accept_strategy_version(self): - environ = {'HTTP_ACCEPT': "application/xml; q=0.1; version=1.0," - "application/json; q=0.2; version=2.0", - 'REQUEST_METHOD': "GET", 'PATH_INFO': "/resource.xml", - 'CONTENT_TYPE': 'application/xml; version=2.0'} - self.urlmap[('http://10.20.30.40:50', '/v1.0')] = 'app' - self.mox.StubOutWithMock(self.urlmap, '_set_script_name') - self.urlmap._set_script_name('app', '/v1.0').AndReturn('value') - self.mox.ReplayAll() - self.assertEqual(('application/xml', 'value'), - self.urlmap._accept_strategy('http://10.20.30.40', - '50', - environ, - ['application/xml'])) diff --git a/cinder/utils.py b/cinder/utils.py index 54dda984712..5c1f17bf333 100644 --- a/cinder/utils.py +++ b/cinder/utils.py @@ -160,11 +160,6 @@ def check_ssh_injection(cmd_list): raise exception.SSHInjectionThreat(command=cmd_list) -def cinderdir(): - import cinder - return os.path.abspath(cinder.__file__).split('cinder/__init__.py')[0] - - def last_completed_audit_period(unit=None): """This method gives you the most recently *completed* audit period. diff --git a/releasenotes/notes/remove-xml-api-392b41f387e60eb1.yaml b/releasenotes/notes/remove-xml-api-392b41f387e60eb1.yaml new file mode 100644 index 00000000000..f04f41c6ebd --- /dev/null +++ b/releasenotes/notes/remove-xml-api-392b41f387e60eb1.yaml @@ -0,0 +1,5 @@ +--- +upgrade: + - The XML API has been removed in Newton release. + Cinder supports only JSON API request/response format now. +