diff --git a/contrib/tempest/tempest/api/share/test_extensions.py b/contrib/tempest/tempest/api/share/test_extensions.py
index c6d1712d5d..4520755ea3 100644
--- a/contrib/tempest/tempest/api/share/test_extensions.py
+++ b/contrib/tempest/tempest/api/share/test_extensions.py
@@ -27,5 +27,5 @@ class ExtensionsTest(base.BaseSharesTest):
# verify response
self.assertIn(int(resp["status"]), self.HTTP_SUCCESS)
- keys = ["alias", "updated", "namespace", "name", "description"]
+ keys = ["alias", "updated", "name", "description"]
[self.assertIn(key, ext.keys()) for ext in extensions for key in keys]
diff --git a/manila/api/common.py b/manila/api/common.py
index c3146bd281..bff254481e 100644
--- a/manila/api/common.py
+++ b/manila/api/common.py
@@ -22,10 +22,7 @@ import six
from six.moves.urllib import parse
import webob
-from manila.api.openstack import wsgi
-from manila.api import xmlutil
from manila.i18n import _
-from manila import utils
api_common_opts = [
cfg.IntOpt(
@@ -41,7 +38,6 @@ api_common_opts = [
CONF = cfg.CONF
CONF.register_opts(api_common_opts)
LOG = log.getLogger(__name__)
-XML_NS_V1 = 'http://docs.openstack.org/volume/api/v1'
# Regex that matches alphanumeric characters, periods, hypens,
@@ -267,78 +263,6 @@ class ViewBuilder(object):
return parse.urlunsplit(url_parts)
-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)
-
-
def remove_invalid_options(context, search_options, allowed_search_options):
"""Remove search options that are not valid for non-admin API/context."""
if context.is_admin:
diff --git a/manila/api/contrib/admin_actions.py b/manila/api/contrib/admin_actions.py
index dd9f0d20f3..d42764b4e9 100644
--- a/manila/api/contrib/admin_actions.py
+++ b/manila/api/contrib/admin_actions.py
@@ -131,7 +131,6 @@ class Admin_actions(extensions.ExtensionDescriptor):
name = "AdminActions"
alias = "os-admin-actions"
- namespace = "http://docs.openstack.org/share/ext/admin-actions/api/v1.1"
updated = "2012-08-25T00:00:00+00:00"
def get_controller_extensions(self):
diff --git a/manila/api/contrib/extended_quotas.py b/manila/api/contrib/extended_quotas.py
index 82efeeeac6..b2c5e50f53 100644
--- a/manila/api/contrib/extended_quotas.py
+++ b/manila/api/contrib/extended_quotas.py
@@ -25,6 +25,4 @@ class Extended_quotas(extensions.ExtensionDescriptor):
name = "ExtendedQuotas"
alias = "os-extended-quotas"
- namespace = ("http://docs.openstack.org/compute/ext/extended_quotas"
- "/api/v1.1")
updated = "2013-06-09T00:00:00+00:00"
diff --git a/manila/api/contrib/quota_classes.py b/manila/api/contrib/quota_classes.py
index 9dd256782c..05a4342dab 100644
--- a/manila/api/contrib/quota_classes.py
+++ b/manila/api/contrib/quota_classes.py
@@ -16,32 +16,14 @@
import webob
from manila.api import extensions
-from manila.api.openstack import wsgi
-from manila.api import xmlutil
from manila import db
from manila import exception
from manila import quota
-
QUOTAS = quota.QUOTAS
-
-
authorize = extensions.extension_authorizer('share', '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(object):
def _format_quota_set(self, quota_class, quota_set):
@@ -54,7 +36,6 @@ class QuotaClassSetsController(object):
return dict(quota_class_set=result)
- @wsgi.serializers(xml=QuotaClassTemplate)
def show(self, req, id):
context = req.environ['manila.context']
authorize(context)
@@ -66,7 +47,6 @@ class QuotaClassSetsController(object):
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['manila.context']
authorize(context)
@@ -89,8 +69,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/manila/api/contrib/quotas.py b/manila/api/contrib/quotas.py
index 594fa55b3f..4c27f90c49 100644
--- a/manila/api/contrib/quotas.py
+++ b/manila/api/contrib/quotas.py
@@ -19,8 +19,6 @@ from six.moves.urllib import parse
import webob
from manila.api import extensions
-from manila.api.openstack import wsgi
-from manila.api import xmlutil
from manila import db
from manila.db.sqlalchemy import api as sqlalchemy_api
from manila import exception
@@ -38,18 +36,6 @@ authorize_show = extensions.extension_authorizer('compute', 'quotas:show')
authorize_delete = extensions.extension_authorizer('compute', '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(object):
def __init__(self, ext_mgr):
@@ -90,7 +76,6 @@ class QuotaSetsController(object):
else:
return dict((k, v['limit']) for k, v in values.items())
- @wsgi.serializers(xml=QuotaTemplate)
def show(self, req, id):
context = req.environ['manila.context']
authorize_show(context)
@@ -105,7 +90,6 @@ class QuotaSetsController(object):
except exception.NotAuthorized:
raise webob.exc.HTTPForbidden()
- @wsgi.serializers(xml=QuotaTemplate)
def update(self, req, id, body):
context = req.environ['manila.context']
authorize_update(context)
@@ -209,7 +193,6 @@ class QuotaSetsController(object):
raise webob.exc.HTTPForbidden()
return {'quota_set': self._get_quotas(context, id, user_id=user_id)}
- @wsgi.serializers(xml=QuotaTemplate)
def defaults(self, req, id):
context = req.environ['manila.context']
authorize_show(context)
@@ -241,7 +224,6 @@ class Quotas(extensions.ExtensionDescriptor):
name = "Quotas"
alias = "os-quota-sets"
- namespace = "http://docs.openstack.org/compute/ext/quotas-sets/api/v1.1"
updated = "2011-08-08T00:00:00+00:00"
def get_resources(self):
diff --git a/manila/api/contrib/services.py b/manila/api/contrib/services.py
index a28f9a416a..4df0980054 100644
--- a/manila/api/contrib/services.py
+++ b/manila/api/contrib/services.py
@@ -17,8 +17,6 @@ from oslo_log import log
import webob.exc
from manila.api import extensions
-from manila.api.openstack import wsgi
-from manila.api import xmlutil
from manila import db
from manila import exception
from manila import utils
@@ -27,33 +25,7 @@ LOG = log.getLogger(__name__)
authorize = extensions.extension_authorizer('share', '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')
-
- return xmlutil.MasterTemplate(root, 1)
-
-
-class ServicesUpdateTemplate(xmlutil.TemplateBuilder):
- def construct(self):
- root = xmlutil.TemplateElement('host')
- root.set('host')
- root.set('disabled')
- root.set('binary')
- root.set('status')
-
- return xmlutil.MasterTemplate(root, 1)
-
-
class ServiceController(object):
- @wsgi.serializers(xml=ServicesIndexTemplate)
def index(self, req):
"""Return a list of all running services."""
context = req.environ['manila.context']
@@ -90,7 +62,6 @@ class ServiceController(object):
return {'services': services}
- @wsgi.serializers(xml=ServicesUpdateTemplate)
def update(self, req, id, body):
"""Enable/Disable scheduling for a service."""
context = req.environ['manila.context']
@@ -126,7 +97,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/manila/api/contrib/share_actions.py b/manila/api/contrib/share_actions.py
index d31eaa0fd7..a625612087 100644
--- a/manila/api/contrib/share_actions.py
+++ b/manila/api/contrib/share_actions.py
@@ -19,7 +19,6 @@ import webob
from manila.api import extensions
from manila.api.openstack import wsgi
-from manila.api import xmlutil
from manila import exception
from manila.i18n import _
from manila import share
@@ -28,40 +27,6 @@ from manila import share
authorize = extensions.extension_authorizer('share', 'services')
-class ShareAccessTemplate(xmlutil.TemplateBuilder):
- """XML Template for share access management methods."""
-
- def construct(self):
- root = xmlutil.TemplateElement('access',
- selector='access')
- root.set("share_id")
- root.set("deleted")
- root.set("created_at")
- root.set("updated_at")
- root.set("access_type")
- root.set("access_to")
- root.set("state")
- root.set("deleted_at")
- root.set("id")
-
- return xmlutil.MasterTemplate(root, 1)
-
-
-class ShareAccessListTemplate(xmlutil.TemplateBuilder):
- """XML Template for share access list."""
-
- def construct(self):
- root = xmlutil.TemplateElement('access_list')
- elem = xmlutil.SubTemplateElement(root, 'share',
- selector='access_list')
- elem.set("state")
- elem.set("id")
- elem.set("access_type")
- elem.set("access_to")
-
- return xmlutil.MasterTemplate(root, 1)
-
-
class ShareActionsController(wsgi.Controller):
def __init__(self, *args, **kwargs):
super(ShareActionsController, self).__init__(*args, **kwargs)
@@ -118,7 +83,6 @@ class ShareActionsController(wsgi.Controller):
raise webob.exc.HTTPBadRequest(explanation=exc_str)
@wsgi.action('os-allow_access')
- @wsgi.serializers(xml=ShareAccessTemplate)
def _allow_access(self, req, id, body):
"""Add share access rule."""
context = req.environ['manila.context']
@@ -146,7 +110,6 @@ class ShareActionsController(wsgi.Controller):
return {'access': access}
@wsgi.action('os-deny_access')
- @wsgi.serializers(xml=ShareAccessTemplate)
def _deny_access(self, req, id, body):
"""Remove access rule."""
context = req.environ['manila.context']
@@ -164,7 +127,6 @@ class ShareActionsController(wsgi.Controller):
return webob.Response(status_int=202)
@wsgi.action('os-access_list')
- @wsgi.serializers(xml=ShareAccessListTemplate)
def _access_list(self, req, id, body):
"""list access rules."""
context = req.environ['manila.context']
@@ -183,7 +145,6 @@ class Share_actions(extensions.ExtensionDescriptor):
name = 'ShareActions'
alias = 'share-actions'
- namespace = ''
updated = '2012-08-14T00:00:00+00:00'
def get_controller_extensions(self):
diff --git a/manila/api/contrib/share_manage.py b/manila/api/contrib/share_manage.py
index 61aef4dd74..ebe3559ad5 100644
--- a/manila/api/contrib/share_manage.py
+++ b/manila/api/contrib/share_manage.py
@@ -120,8 +120,6 @@ class Share_manage(extensions.ExtensionDescriptor):
name = 'ShareManage'
alias = 'os-share-manage'
- namespace = ('http://docs.openstack.org/share/ext/'
- 'os-share-manage/api/v1')
updated = '2015-02-17T00:00:00+00:00'
def get_resources(self):
diff --git a/manila/api/contrib/share_type_access.py b/manila/api/contrib/share_type_access.py
index 20e302b06f..2e54b98e1b 100644
--- a/manila/api/contrib/share_type_access.py
+++ b/manila/api/contrib/share_type_access.py
@@ -20,7 +20,6 @@ import webob
from manila.api import extensions
from manila.api.openstack import wsgi
-from manila.api import xmlutil
from manila import exception
from manila.i18n import _
from manila.share import share_types
@@ -31,45 +30,6 @@ soft_authorize = extensions.soft_extension_authorizer('share',
authorize = extensions.extension_authorizer('share', 'share_type_access')
-def make_share_type(elem):
- elem.set('{%s}is_public' % Share_type_access.namespace,
- '%s:is_public' % Share_type_access.alias)
-
-
-def make_share_type_access(elem):
- elem.set('share_type_id')
- elem.set('project_id')
-
-
-class ShareTypeTemplate(xmlutil.TemplateBuilder):
- def construct(self):
- root = xmlutil.TemplateElement('share_type', selector='share_type')
- make_share_type(root)
- alias = Share_type_access.alias
- namespace = Share_type_access.namespace
- return xmlutil.SlaveTemplate(root, 1, nsmap={alias: namespace})
-
-
-class ShareTypesTemplate(xmlutil.TemplateBuilder):
- def construct(self):
- root = xmlutil.TemplateElement('share_types')
- elem = xmlutil.SubTemplateElement(
- root, 'share_type', selector='share_types')
- make_share_type(elem)
- alias = Share_type_access.alias
- namespace = Share_type_access.namespace
- return xmlutil.SlaveTemplate(root, 1, nsmap={alias: namespace})
-
-
-class ShareTypeAccessTemplate(xmlutil.TemplateBuilder):
- def construct(self):
- root = xmlutil.TemplateElement('share_type_access')
- elem = xmlutil.SubTemplateElement(root, 'access',
- selector='share_type_access')
- make_share_type_access(elem)
- return xmlutil.MasterTemplate(root, 1)
-
-
def _marshall_share_type_access(share_type):
rval = []
for project_id in share_type['projects']:
@@ -82,7 +42,6 @@ def _marshall_share_type_access(share_type):
class ShareTypeAccessController(object):
"""The share type access API controller for the OpenStack API."""
- @wsgi.serializers(xml=ShareTypeAccessTemplate)
def index(self, req, type_id):
context = req.environ['manila.context']
authorize(context)
@@ -123,8 +82,6 @@ class ShareTypeActionController(wsgi.Controller):
def show(self, req, resp_obj, id):
context = req.environ['manila.context']
if soft_authorize(context):
- # Attach our slave template to the response object
- resp_obj.attach(xml=ShareTypeTemplate())
share_type = req.get_db_share_type(id)
self._extend_share_type(resp_obj.obj['share_type'], share_type)
@@ -132,8 +89,6 @@ class ShareTypeActionController(wsgi.Controller):
def index(self, req, resp_obj):
context = req.environ['manila.context']
if soft_authorize(context):
- # Attach our slave template to the response object
- resp_obj.attach(xml=ShareTypesTemplate())
for share_type_rval in list(resp_obj.obj['share_types']):
type_id = share_type_rval['id']
share_type = req.get_db_share_type(type_id)
@@ -143,8 +98,6 @@ class ShareTypeActionController(wsgi.Controller):
def create(self, req, body, resp_obj):
context = req.environ['manila.context']
if soft_authorize(context):
- # Attach our slave template to the response object
- resp_obj.attach(xml=ShareTypeTemplate())
type_id = resp_obj.obj['share_type']['id']
share_type = req.get_db_share_type(type_id)
self._extend_share_type(resp_obj.obj['share_type'], share_type)
@@ -193,8 +146,6 @@ class Share_type_access(extensions.ExtensionDescriptor):
name = "ShareTypeAccess"
alias = "os-share-type-access"
- namespace = ("http://docs.openstack.org/share/"
- "ext/os-share-type-access/api/v1")
updated = "2015-03-02T00:00:00Z"
def get_resources(self):
diff --git a/manila/api/contrib/share_unmanage.py b/manila/api/contrib/share_unmanage.py
index 98e3d61fa2..420271d81b 100644
--- a/manila/api/contrib/share_unmanage.py
+++ b/manila/api/contrib/share_unmanage.py
@@ -78,8 +78,6 @@ class Share_unmanage(extensions.ExtensionDescriptor):
name = 'ShareUnmanage'
alias = 'os-share-unmanage'
- namespace = ('http://docs.openstack.org/share/ext/'
- 'os-share-unmanage/api/v1')
updated = '2015-02-17T00:00:00+00:00'
def get_resources(self):
diff --git a/manila/api/contrib/types_extra_specs.py b/manila/api/contrib/types_extra_specs.py
index 87452479a8..3fafc9104c 100644
--- a/manila/api/contrib/types_extra_specs.py
+++ b/manila/api/contrib/types_extra_specs.py
@@ -162,7 +162,6 @@ class Types_extra_specs(extensions.ExtensionDescriptor):
name = "TypesExtraSpecs"
alias = "os-types-extra-specs"
- namespace = "http://docs.openstack.org/share/ext/types-extra-specs/api/v1"
updated = "2011-08-24T00:00:00+00:00"
def get_resources(self):
diff --git a/manila/api/contrib/types_manage.py b/manila/api/contrib/types_manage.py
index 973a6f052e..7d2054f09c 100644
--- a/manila/api/contrib/types_manage.py
+++ b/manila/api/contrib/types_manage.py
@@ -124,7 +124,6 @@ class Types_manage(extensions.ExtensionDescriptor):
name = "TypesManage"
alias = "os-types-manage"
- namespace = "http://docs.openstack.org/share/ext/types-manage/api/v1"
updated = "2011-08-24T00:00:00+00:00"
def get_controller_extensions(self):
diff --git a/manila/api/contrib/used_limits.py b/manila/api/contrib/used_limits.py
index dbdad642b1..b1b0a75a57 100644
--- a/manila/api/contrib/used_limits.py
+++ b/manila/api/contrib/used_limits.py
@@ -55,7 +55,6 @@ class Used_limits(extensions.ExtensionDescriptor):
name = "UsedLimits"
alias = 'os-used-limits'
- namespace = "http://docs.openstack.org/share/ext/used-limits/api/v1.0"
updated = "2014-03-27T00:00:00+00:00"
def get_controller_extensions(self):
diff --git a/manila/api/contrib/user_quotas.py b/manila/api/contrib/user_quotas.py
index 2119fbee0f..224e125539 100644
--- a/manila/api/contrib/user_quotas.py
+++ b/manila/api/contrib/user_quotas.py
@@ -22,6 +22,4 @@ class User_quotas(extensions.ExtensionDescriptor):
name = "UserQuotas"
alias = "os-user-quotas"
- namespace = ("http://docs.openstack.org/compute/ext/user_quotas"
- "/api/v1.1")
updated = "2013-07-18T00:00:00+00:00"
diff --git a/manila/api/extensions.py b/manila/api/extensions.py
index 1853f7bd1f..62f85a7657 100644
--- a/manila/api/extensions.py
+++ b/manila/api/extensions.py
@@ -25,7 +25,6 @@ import webob.exc
import manila.api.openstack
from manila.api.openstack import wsgi
-from manila.api import xmlutil
from manila import exception
from manila.i18n import _LE
from manila.i18n import _LI
@@ -52,10 +51,6 @@ class ExtensionDescriptor(object):
# 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
@@ -83,55 +78,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):
@@ -144,19 +90,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 six.iteritems(self.extension_manager.extensions):
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
@@ -240,7 +183,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 as ex:
LOG.exception(_LE("Exception loading extension: %s"),
diff --git a/manila/api/openstack/wsgi.py b/manila/api/openstack/wsgi.py
index 01c9ad319f..be88a902cb 100644
--- a/manila/api/openstack/wsgi.py
+++ b/manila/api/openstack/wsgi.py
@@ -28,37 +28,14 @@ from manila.i18n import _LI
from manila import utils
from manila import wsgi
-from lxml import etree
-from xml.dom import minidom
-from xml.parsers import expat
-
-
-XMLNS_V1 = 'http://docs.openstack.org/volume/api/v1'
-XMLNS_ATOM = 'http://www.w3.org/2005/Atom'
-
LOG = log.getLogger(__name__)
-# The vendor content types should serialize identically to the non-vendor
-# content types. So to avoid littering the code with both options, we
-# map the vendor to the other when looking up the type
-_CONTENT_TYPE_MAP = {
- 'application/vnd.openstack.volume+json': 'application/json',
- 'application/vnd.openstack.volume+xml': 'application/xml',
-}
-
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',
}
@@ -252,95 +229,6 @@ class JSONDeserializer(TextDeserializer):
return {'body': self._from_json(datastring)}
-class XMLDeserializer(TextDeserializer):
-
- def __init__(self, metadata=None):
- """
- :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(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"""
- if len(node.childNodes) == 1:
- child = node.childNodes[0]
- if child.nodeType == child.TEXT_NODE:
- return child.nodeValue
- return ""
-
- def find_attribute_or_element(self, parent, name):
- """Get an attribute value; fallback to an element if not found"""
- if parent.hasAttribute(name):
- return parent.getAttribute(name)
-
- node = self.find_first_child_named(parent, name)
- if node:
- return self.extract_text(node)
-
- return None
-
- 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"""
@@ -358,110 +246,6 @@ class JSONDictSerializer(DictSerializer):
return jsonutils.dumps(data)
-class XMLDictSerializer(DictSerializer):
-
- def __init__(self, metadata=None, xmlns=None):
- """
- :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 = 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 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 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.
@@ -660,15 +444,6 @@ def action_peek_json(body):
return 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.
@@ -731,16 +506,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
@@ -1186,11 +958,8 @@ class Fault(webob.exc.HTTPException):
# 'code' is an attribute on the fault tag itself
metadata = {'attributes': {fault_name: 'code'}}
- xml_serializer = XMLDictSerializer(metadata, XMLNS_V1)
-
content_type = req.best_match_content_type()
serializer = {
- 'application/xml': xml_serializer,
'application/json': JSONDictSerializer(),
}[content_type]
@@ -1245,9 +1014,7 @@ class OverLimitFault(webob.exc.HTTPException):
content_type = request.best_match_content_type()
metadata = {"attributes": {"overLimitFault": "code"}}
- xml_serializer = XMLDictSerializer(metadata, XMLNS_V1)
serializer = {
- 'application/xml': xml_serializer,
'application/json': JSONDictSerializer(),
}[content_type]
diff --git a/manila/api/schemas/atom-link.rng b/manila/api/schemas/atom-link.rng
deleted file mode 100644
index edba5eee6c..0000000000
--- a/manila/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/manila/api/schemas/v1.1/extension.rng b/manila/api/schemas/v1.1/extension.rng
deleted file mode 100644
index b16d8c1300..0000000000
--- a/manila/api/schemas/v1.1/extension.rng
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/manila/api/schemas/v1.1/extensions.rng b/manila/api/schemas/v1.1/extensions.rng
deleted file mode 100644
index 8538eaf2da..0000000000
--- a/manila/api/schemas/v1.1/extensions.rng
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
diff --git a/manila/api/schemas/v1.1/limits.rng b/manila/api/schemas/v1.1/limits.rng
deleted file mode 100644
index a66af4b9c4..0000000000
--- a/manila/api/schemas/v1.1/limits.rng
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/manila/api/schemas/v1.1/metadata.rng b/manila/api/schemas/v1.1/metadata.rng
deleted file mode 100644
index b2f5d702a2..0000000000
--- a/manila/api/schemas/v1.1/metadata.rng
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/manila/api/urlmap.py b/manila/api/urlmap.py
index 3a22324daf..09493db064 100644
--- a/manila/api/urlmap.py
+++ b/manila/api/urlmap.py
@@ -253,24 +253,16 @@ class URLMap(paste.urlmap.URLMap):
path_info = environ['PATH_INFO']
path_info = self.normalize_url(path_info, False)[1]
- # 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)
-
# The API version is determined in one of three ways:
# 1) URL path prefix (eg /v1.1/tenant/servers/detail)
# 2) Content-Type header (eg application/json;version=1.1)
# 3) Accept header (eg application/json;q=0.8;version=1.1)
+ # Manila supports only application/json as MIME type for the responses.
supported_content_types = list(wsgi.SUPPORTED_CONTENT_TYPES)
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/manila/api/v1/limits.py b/manila/api/v1/limits.py
index 6c3c59f920..fae0dfcd1d 100644
--- a/manila/api/v1/limits.py
+++ b/manila/api/v1/limits.py
@@ -31,7 +31,6 @@ import webob.exc
from manila.api.openstack import wsgi
from manila.api.views import limits as limits_views
-from manila.api import xmlutil
from manila.i18n import _
from manila import quota
from manila import wsgi as base_wsgi
@@ -46,38 +45,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(object):
"""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['manila.context']
diff --git a/manila/api/v1/security_service.py b/manila/api/v1/security_service.py
index 4c3ad5924d..6871b6f033 100644
--- a/manila/api/v1/security_service.py
+++ b/manila/api/v1/security_service.py
@@ -23,7 +23,6 @@ from webob import exc
from manila.api import common
from manila.api.openstack import wsgi
from manila.api.views import security_service as security_service_views
-from manila.api import xmlutil
from manila.common import constants
from manila import db
from manila import exception
@@ -36,36 +35,11 @@ RESOURCE_NAME = 'security_service'
LOG = log.getLogger(__name__)
-def make_security_service(elem):
- attrs = ['id', 'name', 'description', 'type', 'server', 'domain', 'user',
- 'password', 'dns_ip', 'status', 'updated_at', 'created_at']
- for attr in attrs:
- elem.set(attr)
-
-
-class SecurityServiceTemplate(xmlutil.TemplateBuilder):
- def construct(self):
- root = xmlutil.TemplateElement('security_service',
- selector='security_service')
- make_security_service(root)
- return xmlutil.MasterTemplate(root, 1)
-
-
-class SecurityServicesTemplate(xmlutil.TemplateBuilder):
- def construct(self):
- root = xmlutil.TemplateElement('security_services')
- elem = xmlutil.SubTemplateElement(root, 'security_service',
- selector='security_services')
- make_security_service(elem)
- return xmlutil.MasterTemplate(root, 1)
-
-
class SecurityServiceController(wsgi.Controller):
"""The Shares API controller for the OpenStack API."""
_view_builder_class = security_service_views.ViewBuilder
- @wsgi.serializers(xml=SecurityServiceTemplate)
def show(self, req, id):
"""Return data about the given security service."""
context = req.environ['manila.context']
@@ -102,14 +76,12 @@ class SecurityServiceController(wsgi.Controller):
return webob.Response(status_int=202)
- @wsgi.serializers(xml=SecurityServicesTemplate)
def index(self, req):
"""Returns a summary list of security services."""
policy.check_policy(req.environ['manila.context'], RESOURCE_NAME,
'index')
return self._get_security_services(req, is_detail=False)
- @wsgi.serializers(xml=SecurityServicesTemplate)
def detail(self, req):
"""Returns a detailed list of security services."""
policy.check_policy(req.environ['manila.context'], RESOURCE_NAME,
@@ -181,7 +153,6 @@ class SecurityServiceController(wsgi.Controller):
return True
return False
- @wsgi.serializers(xml=SecurityServiceTemplate)
def update(self, req, id, body):
"""Update a security service."""
context = req.environ['manila.context']
@@ -221,7 +192,6 @@ class SecurityServiceController(wsgi.Controller):
security_service = db.security_service_update(context, id, update_dict)
return self._view_builder.detail(req, security_service)
- @wsgi.serializers(xml=SecurityServiceTemplate)
def create(self, req, body):
"""Creates a new security service."""
context = req.environ['manila.context']
diff --git a/manila/api/v1/share_metadata.py b/manila/api/v1/share_metadata.py
index 7d212dd4c5..971c1b2be2 100644
--- a/manila/api/v1/share_metadata.py
+++ b/manila/api/v1/share_metadata.py
@@ -16,7 +16,6 @@
import webob
from webob import exc
-from manila.api import common
from manila.api.openstack import wsgi
from manila import exception
from manila.i18n import _
@@ -39,14 +38,11 @@ class ShareMetadataController(object):
raise exc.HTTPNotFound(explanation=msg)
return meta
- @wsgi.serializers(xml=common.MetadataTemplate)
def index(self, req, share_id):
"""Returns the list of metadata for a given share."""
context = req.environ['manila.context']
return {'metadata': self._get_metadata(context, share_id)}
- @wsgi.serializers(xml=common.MetadataTemplate)
- @wsgi.deserializers(xml=common.MetadataDeserializer)
def create(self, req, share_id, body):
try:
metadata = body['metadata']
@@ -63,8 +59,6 @@ class ShareMetadataController(object):
return {'metadata': new_metadata}
- @wsgi.serializers(xml=common.MetaItemTemplate)
- @wsgi.deserializers(xml=common.MetaItemDeserializer)
def update(self, req, share_id, id, body):
try:
meta_item = body['meta']
@@ -88,8 +82,6 @@ class ShareMetadataController(object):
return {'meta': meta_item}
- @wsgi.serializers(xml=common.MetadataTemplate)
- @wsgi.deserializers(xml=common.MetadataDeserializer)
def update_all(self, req, share_id, body):
try:
metadata = body['metadata']
@@ -125,7 +117,6 @@ class ShareMetadataController(object):
except exception.InvalidShareMetadataSize as error:
raise exc.HTTPBadRequest(explanation=error.msg)
- @wsgi.serializers(xml=common.MetaItemTemplate)
def show(self, req, share_id, id):
"""Return a single metadata item."""
context = req.environ['manila.context']
diff --git a/manila/api/v1/share_networks.py b/manila/api/v1/share_networks.py
index e2a9d7f9ca..6459986666 100644
--- a/manila/api/v1/share_networks.py
+++ b/manila/api/v1/share_networks.py
@@ -25,7 +25,6 @@ from webob import exc
from manila.api import common
from manila.api.openstack import wsgi
from manila.api.views import share_networks as share_networks_views
-from manila.api import xmlutil
from manila.db import api as db_api
from manila import exception
from manila.i18n import _
@@ -39,43 +38,6 @@ RESOURCE_NAME = 'share_network'
RESOURCES_NAME = 'share_networks'
LOG = log.getLogger(__name__)
QUOTAS = quota.QUOTAS
-SHARE_NETWORK_ATTRS = (
- 'id',
- 'project_id',
- 'user_id',
- 'created_at',
- 'updated_at',
- 'nova_net_id',
- 'neutron_net_id',
- 'neutron_subnet_id',
- 'network_type',
- 'segmentation_id',
- 'cidr',
- 'ip_version',
- 'name',
- 'description',
-)
-
-
-def _make_share_network(elem):
- for attr in SHARE_NETWORK_ATTRS:
- elem.set(attr)
-
-
-class ShareNetworkTemplate(xmlutil.TemplateBuilder):
- def construct(self):
- root = xmlutil.TemplateElement(RESOURCE_NAME, selector=RESOURCE_NAME)
- _make_share_network(root)
- return xmlutil.MasterTemplate(root, 1)
-
-
-class ShareNetworksTemplate(xmlutil.TemplateBuilder):
- def construct(self):
- root = xmlutil.TemplateElement(RESOURCES_NAME)
- elem = xmlutil.SubTemplateElement(root, RESOURCE_NAME,
- selector=RESOURCES_NAME)
- _make_share_network(elem)
- return xmlutil.MasterTemplate(root, 1)
class ShareNetworkController(wsgi.Controller):
@@ -87,7 +49,6 @@ class ShareNetworkController(wsgi.Controller):
super(ShareNetworkController, self).__init__()
self.share_rpcapi = share_rpcapi.ShareAPI()
- @wsgi.serializers(xml=ShareNetworkTemplate)
def show(self, req, id):
"""Return data about the requested network info."""
context = req.environ['manila.context']
@@ -132,7 +93,6 @@ class ShareNetworkController(wsgi.Controller):
project_id=share_network['project_id'])
return webob.Response(status_int=202)
- @wsgi.serializers(xml=ShareNetworksTemplate)
def _get_share_networks(self, req, is_detail=True):
"""Returns a list of share networks."""
context = req.environ['manila.context']
@@ -200,14 +160,12 @@ class ShareNetworkController(wsgi.Controller):
limited_list = common.limited(networks, req)
return self._view_builder.build_share_networks(limited_list, is_detail)
- @wsgi.serializers(xml=ShareNetworksTemplate)
def index(self, req):
"""Returns a summary list of share networks."""
policy.check_policy(req.environ['manila.context'], RESOURCE_NAME,
'index')
return self._get_share_networks(req, is_detail=False)
- @wsgi.serializers(xml=ShareNetworksTemplate)
def detail(self, req):
"""Returns a detailed list of share networks."""
policy.check_policy(req.environ['manila.context'], RESOURCE_NAME,
@@ -231,7 +189,6 @@ class ShareNetworkController(wsgi.Controller):
"exclusive. Only one of these are allowed at a time.")
raise exc.HTTPBadRequest(explanation=msg)
- @wsgi.serializers(xml=ShareNetworkTemplate)
def update(self, req, id, body):
"""Update specified share network."""
context = req.environ['manila.context']
@@ -267,7 +224,6 @@ class ShareNetworkController(wsgi.Controller):
return self._view_builder.build_share_network(share_network)
- @wsgi.serializers(xml=ShareNetworkTemplate)
def create(self, req, body):
"""Creates a new share network."""
context = req.environ['manila.context']
@@ -309,7 +265,6 @@ class ShareNetworkController(wsgi.Controller):
QUOTAS.commit(context, reservations)
return self._view_builder.build_share_network(share_network)
- @wsgi.serializers(xml=ShareNetworkTemplate)
def action(self, req, id, body):
_actions = {
'add_security_service': self._add_security_service,
diff --git a/manila/api/v1/share_servers.py b/manila/api/v1/share_servers.py
index 2c98fafba5..352c156728 100644
--- a/manila/api/v1/share_servers.py
+++ b/manila/api/v1/share_servers.py
@@ -20,7 +20,6 @@ from webob import exc
from manila.api.openstack import wsgi
from manila.api.views import share_servers as share_servers_views
-from manila.api import xmlutil
from manila.common import constants
from manila.db import api as db_api
from manila import exception
@@ -31,37 +30,6 @@ from manila import share
RESOURCE_NAME = 'share_server'
RESOURCES_NAME = 'share_servers'
LOG = log.getLogger(__name__)
-SHARE_SERVER_ATTRS = (
- 'id',
- 'project_id',
- 'updated_at',
- 'status',
- 'host',
- 'share_network_name',
-)
-
-
-def _make_share_server(elem, details=False):
- for attr in SHARE_SERVER_ATTRS:
- elem.set(attr)
- if details:
- elem.set('backend_details')
-
-
-class ShareServerTemplate(xmlutil.TemplateBuilder):
- def construct(self):
- root = xmlutil.TemplateElement(RESOURCE_NAME, selector=RESOURCE_NAME)
- _make_share_server(root, details=True)
- return xmlutil.MasterTemplate(root, 1)
-
-
-class ShareServersTemplate(xmlutil.TemplateBuilder):
- def construct(self):
- root = xmlutil.TemplateElement(RESOURCES_NAME)
- elem = xmlutil.SubTemplateElement(root, RESOURCE_NAME,
- selector=RESOURCES_NAME)
- _make_share_server(elem)
- return xmlutil.MasterTemplate(root, 1)
class ShareServerController(wsgi.Controller):
@@ -72,7 +40,6 @@ class ShareServerController(wsgi.Controller):
self._view_builder_class = share_servers_views.ViewBuilder
super(ShareServerController, self).__init__()
- @wsgi.serializers(xml=ShareServersTemplate)
def index(self, req):
"""Returns a list of share servers."""
@@ -98,7 +65,6 @@ class ShareServerController(wsgi.Controller):
s.share_network['id']])]
return self._view_builder.build_share_servers(share_servers)
- @wsgi.serializers(xml=ShareServerTemplate)
def show(self, req, id):
"""Return data about the requested share server."""
context = req.environ['manila.context']
diff --git a/manila/api/v1/share_snapshots.py b/manila/api/v1/share_snapshots.py
index 0feb6bc455..10db81493b 100644
--- a/manila/api/v1/share_snapshots.py
+++ b/manila/api/v1/share_snapshots.py
@@ -23,7 +23,6 @@ from webob import exc
from manila.api import common
from manila.api.openstack import wsgi
from manila.api.views import share_snapshots as snapshot_views
-from manila.api import xmlutil
from manila import exception
from manila.i18n import _LI
from manila import share
@@ -31,30 +30,6 @@ from manila import share
LOG = log.getLogger(__name__)
-def make_snapshot(elem):
- attrs = ['id', 'size', 'status', 'name', 'description', 'share_proto',
- 'links', 'share_id', 'created_at', 'share_size']
- for attr in attrs:
- elem.set(attr)
-
-
-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 ShareSnapshotsController(wsgi.Controller):
"""The Share Snapshots API controller for the OpenStack API."""
@@ -64,7 +39,6 @@ class ShareSnapshotsController(wsgi.Controller):
super(ShareSnapshotsController, self).__init__()
self.share_api = share.API()
- @wsgi.serializers(xml=SnapshotTemplate)
def show(self, req, id):
"""Return data about the given snapshot."""
context = req.environ['manila.context']
@@ -89,12 +63,10 @@ class ShareSnapshotsController(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._get_snapshots(req, is_detail=False)
- @wsgi.serializers(xml=SnapshotsTemplate)
def detail(self, req):
"""Returns a detailed list of snapshots."""
return self._get_snapshots(req, is_detail=True)
@@ -138,7 +110,6 @@ class ShareSnapshotsController(wsgi.Controller):
"""Return share search options allowed by non-admin."""
return ('display_name', 'name', 'status', 'share_id', 'size')
- @wsgi.serializers(xml=SnapshotTemplate)
def update(self, req, id, body):
"""Update a snapshot."""
context = req.environ['manila.context']
@@ -167,7 +138,6 @@ class ShareSnapshotsController(wsgi.Controller):
return self._view_builder.detail(req, snapshot)
@wsgi.response(202)
- @wsgi.serializers(xml=SnapshotTemplate)
def create(self, req, body):
"""Creates a new snapshot."""
context = req.environ['manila.context']
@@ -204,18 +174,3 @@ class ShareSnapshotsController(wsgi.Controller):
def create_resource():
return wsgi.Resource(ShareSnapshotsController())
-
-#
-# class Share_snapshots(extensions.ExtensionDescriptor):
-# """Enable share snapshtos API."""
-# name = 'ShareSnapshots'
-# alias = 'snapshots'
-# namespace = ''
-# updated = '2013-03-01T00:00:00+00:00'
-#
-# def get_resources(self):
-# controller = ShareSnapshotsController()
-# resource = extensions.ResourceExtension(
-# 'snapshots', controller,
-# collection_actions={'detail': 'GET'})
-# return [resource]
diff --git a/manila/api/v1/shares.py b/manila/api/v1/shares.py
index 028222e8ea..7e8076555f 100644
--- a/manila/api/v1/shares.py
+++ b/manila/api/v1/shares.py
@@ -26,7 +26,6 @@ from webob import exc
from manila.api import common
from manila.api.openstack import wsgi
from manila.api.views import shares as share_views
-from manila.api import xmlutil
from manila import exception
from manila.i18n import _
from manila.i18n import _LI
@@ -36,32 +35,6 @@ from manila.share import share_types
LOG = log.getLogger(__name__)
-def make_share(elem):
- # NOTE(u_glide):
- # export_location is backward-compatibility attribute, which contains first
- # export location from export_locations list.
- attrs = ['id', 'size', 'availability_zone', 'status', 'name',
- 'description', 'share_proto', 'export_location', 'links',
- 'snapshot_id', 'created_at', 'metadata', 'export_locations']
- for attr in attrs:
- elem.set(attr)
-
-
-class ShareTemplate(xmlutil.TemplateBuilder):
- def construct(self):
- root = xmlutil.TemplateElement('share', selector='share')
- make_share(root)
- return xmlutil.MasterTemplate(root, 1)
-
-
-class SharesTemplate(xmlutil.TemplateBuilder):
- def construct(self):
- root = xmlutil.TemplateElement('shares')
- elem = xmlutil.SubTemplateElement(root, 'share', selector='shares')
- make_share(elem)
- return xmlutil.MasterTemplate(root, 1)
-
-
class ShareController(wsgi.Controller):
"""The Shares API controller for the OpenStack API."""
@@ -71,7 +44,6 @@ class ShareController(wsgi.Controller):
super(ShareController, self).__init__()
self.share_api = share.API()
- @wsgi.serializers(xml=ShareTemplate)
def show(self, req, id):
"""Return data about the given share."""
context = req.environ['manila.context']
@@ -99,12 +71,10 @@ class ShareController(wsgi.Controller):
return webob.Response(status_int=202)
- @wsgi.serializers(xml=SharesTemplate)
def index(self, req):
"""Returns a summary list of shares."""
return self._get_shares(req, is_detail=False)
- @wsgi.serializers(xml=SharesTemplate)
def detail(self, req):
"""Returns a detailed list of shares."""
return self._get_shares(req, is_detail=True)
@@ -164,7 +134,6 @@ class ShareController(wsgi.Controller):
'is_public', 'metadata', 'extra_specs', 'sort_key', 'sort_dir',
)
- @wsgi.serializers(xml=ShareTemplate)
def update(self, req, id, body):
"""Update a share."""
context = req.environ['manila.context']
@@ -192,7 +161,6 @@ class ShareController(wsgi.Controller):
share.update(update_dict)
return self._view_builder.detail(req, share)
- @wsgi.serializers(xml=ShareTemplate)
def create(self, req, body):
"""Creates a new share."""
context = req.environ['manila.context']
diff --git a/manila/api/versions.py b/manila/api/versions.py
index 5d8744047a..545e2802d8 100644
--- a/manila/api/versions.py
+++ b/manila/api/versions.py
@@ -13,14 +13,10 @@
# License for the specific language governing permissions and limitations
# under the License.
-import datetime
-
-from lxml import etree
from oslo_config import cfg
from manila.api.openstack import wsgi
from manila.api.views import versions as views_versions
-from manila.api import xmlutil
CONF = cfg.CONF
@@ -46,13 +42,8 @@ _KNOWN_VERSIONS = {
},
],
"media-types": [
- {
- "base": "application/xml",
- "type": "application/vnd.openstack.volume+xml;version=1",
- },
{
"base": "application/json",
- "type": "application/vnd.openstack.volume+json;version=1",
}
],
},
@@ -76,13 +67,8 @@ _KNOWN_VERSIONS = {
},
],
"media-types": [
- {
- "base": "application/xml",
- "type": "application/vnd.openstack.volume+xml;version=1",
- },
{
"base": "application/json",
- "type": "application/vnd.openstack.volume+json;version=1",
}
],
}
@@ -101,157 +87,16 @@ def get_supported_versions():
return 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.XMLNS_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)
-
-
class Versions(wsgi.Resource):
def __init__(self):
super(Versions, self).__init__(None)
- @wsgi.serializers(xml=VersionsTemplate,
- atom=VersionsAtomSerializer)
def index(self, req):
"""Return all versions."""
builder = views_versions.get_view_builder(req)
return builder.build_versions(get_supported_versions())
- @wsgi.serializers(xml=ChoicesTemplate)
@wsgi.response(300)
def multi(self, req):
"""Return multiple choices."""
@@ -270,8 +115,6 @@ class Versions(wsgi.Resource):
class ShareVersionV1(object):
- @wsgi.serializers(xml=VersionTemplate,
- atom=VersionAtomSerializer)
def show(self, req):
builder = views_versions.get_view_builder(req)
return builder.build_version(_KNOWN_VERSIONS['v1.0'])
diff --git a/manila/api/xmlutil.py b/manila/api/xmlutil.py
deleted file mode 100644
index 2cc89d84aa..0000000000
--- a/manila/api/xmlutil.py
+++ /dev/null
@@ -1,913 +0,0 @@
-# Copyright 2011 OpenStack LLC.
-# 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
-
-from lxml import etree
-import six
-
-from manila.i18n import _
-from manila 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/volume/api/v1'
-XMLNS_VOLUME_V2 = ('http://docs.openstack.org/api/openstack-volume/2.0/'
- 'content')
-XMLNS_SHARE_V1 = ''
-
-
-def validate_schema(xml, schema_name):
- if isinstance(xml, str):
- xml = etree.fromstring(xml)
- base_path = 'manila/api/schemas/v1.1/'
- if schema_name in ('atom', 'atom-link'):
- base_path = 'manila/api/schemas/'
- schema_path = os.path.join(utils.maniladir(),
- '%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 _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
- elem = etree.Element(tagname, nsmap=nsmap)
-
- # If we have a parent, append the node to the parent
- if parent is not None:
- parent.append(elem)
-
- # If the datum is None, do nothing else
- if datum is None:
- return elem
-
- # Apply this template element to the element
- self.apply(elem, datum)
-
- # Additionally, apply the patches
- for patch in patches:
- patch.apply(elem, datum)
-
- # We have fully rendered the element; return it
- return elem
-
- def render(self, parent, obj, patches=[], 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.
- """
-
- # 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%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, recurse to 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 we recurse for every data element
- 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:
- slavetag = slave.root.tag
- mastertag = self.root.tag
- msg = _("Template tree mismatch; adding slave %(slavetag)s "
- "to master %(mastertag)s") % {
- "slavetag": slavetag,
- "mastertag": mastertag
- }
- 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.
-
- Utility for simple XML 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/manila/tests/api/middleware/test_faults.py b/manila/tests/api/middleware/test_faults.py
index ba75bc44b7..db80295efd 100644
--- a/manila/tests/api/middleware/test_faults.py
+++ b/manila/tests/api/middleware/test_faults.py
@@ -13,14 +13,11 @@
# License for the specific language governing permissions and limitations
# under the License.
-from xml.dom import minidom
-
from oslo_serialization import jsonutils
import webob
import webob.dec
import webob.exc
-from manila.api import common
from manila.api.openstack import wsgi
from manila import test
@@ -88,9 +85,9 @@ class TestFaults(test.TestCase):
def raiser(req):
raise wsgi.Fault(webob.exc.HTTPNotFound(explanation='whut?'))
- req = webob.Request.blank('/.xml')
+ req = webob.Request.blank('/.json')
resp = req.get_response(raiser)
- self.assertEqual(resp.content_type, "application/xml")
+ self.assertEqual(resp.content_type, "application/json")
self.assertEqual(resp.status_int, 404)
self.assertTrue('whut?' in resp.body)
@@ -100,9 +97,9 @@ class TestFaults(test.TestCase):
def raiser(req):
raise wsgi.Fault(webob.exc.HTTPForbidden(explanation='whut?'))
- req = webob.Request.blank('/.xml')
+ req = webob.Request.blank('/.json')
resp = req.get_response(raiser)
- self.assertEqual(resp.content_type, "application/xml")
+ self.assertEqual(resp.content_type, "application/json")
self.assertEqual(resp.status_int, 403)
self.assertTrue('resizeNotAllowed' not in resp.body)
self.assertTrue('forbidden' in resp.body)
@@ -111,104 +108,3 @@ class TestFaults(test.TestCase):
"""Ensure the status_int is set correctly on faults."""
fault = wsgi.Fault(webob.exc.HTTPBadRequest(explanation='what?'))
self.assertEqual(fault.status_int, 400)
-
- def test_xml_serializer(self):
- """Ensure that a v1.1 request responds with a v1 xmlns."""
- request = webob.Request.blank('/v1',
- headers={"Accept": "application/xml"})
-
- fault = wsgi.Fault(webob.exc.HTTPBadRequest(explanation='scram'))
- response = request.get_response(fault)
-
- self.assertTrue(common.XML_NS_V1 in response.body)
- self.assertEqual(response.content_type, "application/xml")
- self.assertEqual(response.status_int, 400)
-
-
-class FaultsXMLSerializationTestV11(test.TestCase):
- """Tests covering `manila.api.openstack.faults:Fault` class."""
-
- def _prepare_xml(self, xml_string):
- xml_string = xml_string.replace(" ", "")
- xml_string = xml_string.replace("\n", "")
- xml_string = xml_string.replace("\t", "")
- return xml_string
-
- 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)
- result = minidom.parseString(self._prepare_xml(output))
-
- # result has 1 child - overLimit
- self.assertEqual(result.firstChild, result.lastChild)
- self.assertEqual(result.firstChild.tagName, 'overLimit')
-
- # overLimit has attrs code = '413' and xmlns = common.XML_NS_V1
- self.assertEqual(result.firstChild.getAttribute('code'), '413')
- self.assertEqual(result.firstChild.getAttribute('xmlns'),
- common.XML_NS_V1)
-
- # overLimit has childs message = 'sorry' and retryAfter = '4'
- message = result.firstChild.getElementsByTagName('message')
- retry_after = result.firstChild.getElementsByTagName('retryAfter')
- self.assertEqual(len(message), 1)
- self.assertEqual(len(retry_after), 1)
- self.assertEqual(message[0].toxml(), 'sorry')
- self.assertEqual(retry_after[0].toxml(), '4')
-
- 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)
- actual = minidom.parseString(self._prepare_xml(output))
-
- expected = minidom.parseString(self._prepare_xml("""
-
- sorry
-
- """) % common.XML_NS_V1)
-
- self.assertEqual(expected.toxml(), actual.toxml())
diff --git a/manila/tests/api/openstack/test_wsgi.py b/manila/tests/api/openstack/test_wsgi.py
index d35d877172..788defb8cd 100644
--- a/manila/tests/api/openstack/test_wsgi.py
+++ b/manila/tests/api/openstack/test_wsgi.py
@@ -29,14 +29,13 @@ class RequestTest(test.TestCase):
self.assertEqual(result, "application/json")
def test_content_type_from_accept(self):
- for content_type in ('application/xml',
- 'application/vnd.openstack.volume+xml',
- 'application/json',
- 'application/vnd.openstack.volume+json'):
- request = wsgi.Request.blank('/tests/123')
- request.headers["Accept"] = content_type
- result = request.best_match_content_type()
- self.assertEqual(result, content_type)
+ content_type = 'application/json'
+ request = wsgi.Request.blank('/tests/123')
+ request.headers["Accept"] = content_type
+
+ result = request.best_match_content_type()
+
+ self.assertEqual(result, content_type)
def test_content_type_from_accept_best(self):
request = wsgi.Request.blank('/tests/123')
@@ -48,13 +47,9 @@ class RequestTest(test.TestCase):
request.headers["Accept"] = ("application/json; q=0.3, "
"application/xml; q=0.9")
result = request.best_match_content_type()
- self.assertEqual(result, "application/xml")
+ self.assertEqual(result, "application/json")
def test_content_type_from_query_extension(self):
- request = wsgi.Request.blank('/tests/123.xml')
- result = request.best_match_content_type()
- self.assertEqual(result, "application/xml")
-
request = wsgi.Request.blank('/tests/123.json')
result = request.best_match_content_type()
self.assertEqual(result, "application/json")
@@ -63,12 +58,6 @@ class RequestTest(test.TestCase):
result = request.best_match_content_type()
self.assertEqual(result, "application/json")
- 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(result, "application/xml")
-
def test_content_type_accept_default(self):
request = wsgi.Request.blank('/tests/123.unsupported')
request.headers["Accept"] = "application/unsupported1"
@@ -162,16 +151,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 = '(2,3)'
- serializer = wsgi.XMLDictSerializer(xmlns="asdf")
- result = serializer.serialize(input_dict)
- result = result.replace('\n', '').replace(' ', '')
- self.assertEqual(result, expected_xml)
-
-
class JSONDictSerializerTest(test.TestCase):
def test_json(self):
input_dict = dict(servers=dict(a=(2, 3)))
@@ -211,37 +190,6 @@ class JSONDeserializerTest(test.TestCase):
self.assertEqual(deserializer.deserialize(data), as_dict)
-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(deserializer.deserialize(xml), as_dict)
-
- def test_xml_empty(self):
- xml = """"""
- as_dict = {"body": {"a": {}}}
- deserializer = wsgi.XMLDeserializer()
- self.assertEqual(deserializer.deserialize(xml), as_dict)
-
-
class ResourceTest(test.TestCase):
def test_resource_call(self):
class Controller(object):
@@ -299,19 +247,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')
@@ -467,20 +402,15 @@ class ResourceTest(test.TestCase):
def deserialize(self, body):
return 'json'
- class XMLDeserializer(object):
- def deserialize(self, body):
- return 'xml'
-
class Controller(object):
- @wsgi.deserializers(xml=XMLDeserializer)
def index(self, req, pants=None):
return pants
controller = Controller()
resource = wsgi.Resource(controller, json=JSONDeserializer)
- obj = resource.deserialize(controller.index, 'application/xml', 'foo')
- self.assertEqual(obj, 'xml')
+ obj = resource.deserialize(controller.index, 'application/json', 'foo')
+ self.assertEqual(obj, 'json')
def test_register_actions(self):
class Controller(object):
diff --git a/manila/tests/api/test_extensions.py b/manila/tests/api/test_extensions.py
index e1acf4b793..c478f772b0 100644
--- a/manila/tests/api/test_extensions.py
+++ b/manila/tests/api/test_extensions.py
@@ -16,7 +16,6 @@
import ddt
import iso8601
-from lxml import etree
import mock
from oslo_config import cfg
from oslo_serialization import jsonutils
@@ -24,7 +23,6 @@ import webob
from manila.api import extensions
from manila.api.v1 import router
-from manila.api import xmlutil
from manila import policy
from manila import test
@@ -70,8 +68,7 @@ class ExtensionControllerTest(ExtensionTestCase):
(fox_ext, ) = [
x for x in data['extensions'] if x['alias'] == 'FOXNSOX']
self.assertEqual(
- fox_ext, {'namespace': 'http://www.fox.in.socks/api/ext/pie/v1.0',
- 'name': 'Fox In Socks',
+ fox_ext, {'name': 'Fox In Socks',
'updated': '2011-01-22T13:25:27-06:00',
'description': 'The Fox In Socks Extension.',
'alias': 'FOXNSOX',
@@ -93,8 +90,7 @@ class ExtensionControllerTest(ExtensionTestCase):
data = jsonutils.loads(response.body)
self.assertEqual(
data['extension'],
- {"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",
@@ -106,55 +102,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(root.tag.split('extensions')[0], NS)
-
- # Make sure we have all the extensions, extras extensions being OK.
- exts = root.findall('{0}extension'.format(NS))
- self.assertTrue(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_ext.get('name'), 'Fox In Socks')
- self.assertEqual(
- fox_ext.get('namespace'),
- 'http://www.fox.in.socks/api/ext/pie/v1.0')
- self.assertEqual(fox_ext.get('updated'), '2011-01-22T13:25:27-06:00')
- self.assertEqual(
- fox_ext.findtext('{0}description'.format(NS)),
- 'The Fox In Socks Extension.')
-
- 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(root.tag.split('extension')[0], NS)
- self.assertEqual(root.get('alias'), 'FOXNSOX')
- self.assertEqual(root.get('name'), 'Fox In Socks')
- self.assertEqual(
- root.get('namespace'),
- 'http://www.fox.in.socks/api/ext/pie/v1.0')
- self.assertEqual(root.get('updated'), '2011-01-22T13:25:27-06:00')
- self.assertEqual(
- root.findtext('{0}description'.format(NS)),
- 'The Fox In Socks Extension.')
-
- xmlutil.validate_schema(root, 'extension')
-
@ddt.ddt
class ExtensionAuthorizeTestCase(test.TestCase):
diff --git a/manila/tests/api/test_xmlutil.py b/manila/tests/api/test_xmlutil.py
deleted file mode 100644
index 11eca1496c..0000000000
--- a/manila/tests/api/test_xmlutil.py
+++ /dev/null
@@ -1,714 +0,0 @@
-# Copyright 2011 OpenStack LLC.
-# 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 xml.dom import minidom
-
-from lxml import etree
-
-from manila.api import xmlutil
-from manila import test
-
-
-class SelectorTest(test.TestCase):
- obj_for_test = {'test': {'name': 'test',
- 'values': [1, 2, 3],
- 'attrs': {'foo': 1,
- 'bar': 2,
- 'baz': 3, }, }, }
-
- def test_empty_selector(self):
- sel = xmlutil.Selector()
- self.assertEqual(len(sel.chain), 0)
- self.assertEqual(sel(self.obj_for_test), self.obj_for_test)
-
- def test_dict_selector(self):
- sel = xmlutil.Selector('test')
- self.assertEqual(len(sel.chain), 1)
- self.assertEqual(sel.chain[0], 'test')
- self.assertEqual(sel(self.obj_for_test),
- self.obj_for_test['test'])
-
- def test_datum_selector(self):
- sel = xmlutil.Selector('test', 'name')
- self.assertEqual(len(sel.chain), 2)
- self.assertEqual(sel.chain[0], 'test')
- self.assertEqual(sel.chain[1], 'name')
- self.assertEqual(sel(self.obj_for_test), 'test')
-
- def test_list_selector(self):
- sel = xmlutil.Selector('test', 'values', 0)
- self.assertEqual(len(sel.chain), 3)
- self.assertEqual(sel.chain[0], 'test')
- self.assertEqual(sel.chain[1], 'values')
- self.assertEqual(sel.chain[2], 0)
- self.assertEqual(sel(self.obj_for_test), 1)
-
- def test_items_selector(self):
- sel = xmlutil.Selector('test', 'attrs', xmlutil.get_items)
- self.assertEqual(len(sel.chain), 3)
- self.assertEqual(sel.chain[2], xmlutil.get_items)
- for key, val in sel(self.obj_for_test):
- self.assertEqual(self.obj_for_test['test']['attrs'][key], val)
-
- def test_missing_key_selector(self):
- sel = xmlutil.Selector('test2', 'attrs')
- self.assertEqual(sel(self.obj_for_test), None)
- self.assertRaises(KeyError, sel, self.obj_for_test, True)
-
- def test_constant_selector(self):
- sel = xmlutil.ConstantSelector('Foobar')
- self.assertEqual(sel.value, 'Foobar')
- self.assertEqual(sel(self.obj_for_test), 'Foobar')
-
-
-class TemplateElementTest(test.TestCase):
- def test_element_initial_attributes(self):
- # Create a template element with some attributes
- elem = xmlutil.TemplateElement('test', attrib=dict(a=1, b=2, c=3),
- c=4, d=5, e=6)
-
- # Verify all the attributes are as expected
- expected = dict(a=1, b=2, c=4, d=5, e=6)
- for k, v in expected.items():
- self.assertEqual(elem.attrib[k].chain[0], v)
-
- def test_element_get_attributes(self):
- expected = dict(a=1, b=2, c=3)
-
- # Create a template element with some attributes
- elem = xmlutil.TemplateElement('test', attrib=expected)
-
- # Verify that get() retrieves the attributes
- for k, v in expected.items():
- self.assertEqual(elem.get(k).chain[0], v)
-
- def test_element_set_attributes(self):
- attrs = dict(a=None, b='foo', c=xmlutil.Selector('foo', 'bar'))
-
- # Create a bare template element with no attributes
- elem = xmlutil.TemplateElement('test')
-
- # Set the attribute values
- for k, v in attrs.items():
- elem.set(k, v)
-
- # Now verify what got set
- self.assertEqual(len(elem.attrib['a'].chain), 1)
- self.assertEqual(elem.attrib['a'].chain[0], 'a')
- self.assertEqual(len(elem.attrib['b'].chain), 1)
- self.assertEqual(elem.attrib['b'].chain[0], 'foo')
- self.assertEqual(elem.attrib['c'], attrs['c'])
-
- def test_element_attribute_keys(self):
- attrs = dict(a=1, b=2, c=3, d=4)
- expected = set(attrs.keys())
-
- # Create a template element with some attributes
- elem = xmlutil.TemplateElement('test', attrib=attrs)
-
- # Now verify keys
- self.assertEqual(set(elem.keys()), expected)
-
- def test_element_attribute_items(self):
- expected = dict(a=xmlutil.Selector(1),
- b=xmlutil.Selector(2),
- c=xmlutil.Selector(3))
- keys = set(expected.keys())
-
- # Create a template element with some attributes
- elem = xmlutil.TemplateElement('test', attrib=expected)
-
- # Now verify items
- for k, v in elem.items():
- self.assertEqual(expected[k], v)
- keys.remove(k)
-
- # Did we visit all keys?
- self.assertEqual(len(keys), 0)
-
- def test_element_selector_none(self):
- # Create a template element with no selector
- elem = xmlutil.TemplateElement('test')
-
- self.assertEqual(len(elem.selector.chain), 0)
-
- def test_element_selector_string(self):
- # Create a template element with a string selector
- elem = xmlutil.TemplateElement('test', selector='test')
-
- self.assertEqual(len(elem.selector.chain), 1)
- self.assertEqual(elem.selector.chain[0], 'test')
-
- def test_element_selector(self):
- sel = xmlutil.Selector('a', 'b')
-
- # Create a template element with an explicit selector
- elem = xmlutil.TemplateElement('test', selector=sel)
-
- self.assertEqual(elem.selector, sel)
-
- def test_element_subselector_none(self):
- # Create a template element with no subselector
- elem = xmlutil.TemplateElement('test')
-
- self.assertEqual(elem.subselector, None)
-
- def test_element_subselector_string(self):
- # Create a template element with a string subselector
- elem = xmlutil.TemplateElement('test', subselector='test')
-
- self.assertEqual(len(elem.subselector.chain), 1)
- self.assertEqual(elem.subselector.chain[0], 'test')
-
- def test_element_subselector(self):
- sel = xmlutil.Selector('a', 'b')
-
- # Create a template element with an explicit subselector
- elem = xmlutil.TemplateElement('test', subselector=sel)
-
- self.assertEqual(elem.subselector, sel)
-
- def test_element_append_child(self):
- # Create an element
- elem = xmlutil.TemplateElement('test')
-
- # Make sure the element starts off empty
- self.assertEqual(len(elem), 0)
-
- # Create a child element
- child = xmlutil.TemplateElement('child')
-
- # Append the child to the parent
- elem.append(child)
-
- # Verify that the child was added
- self.assertEqual(len(elem), 1)
- self.assertEqual(elem[0], child)
- self.assertEqual('child' in elem, True)
- self.assertEqual(elem['child'], child)
-
- # Ensure that multiple children of the same name are rejected
- child2 = xmlutil.TemplateElement('child')
- self.assertRaises(KeyError, elem.append, child2)
-
- def test_element_extend_children(self):
- # Create an element
- elem = xmlutil.TemplateElement('test')
-
- # Make sure the element starts off empty
- self.assertEqual(len(elem), 0)
-
- # Create a few children
- children = [xmlutil.TemplateElement('child1'),
- xmlutil.TemplateElement('child2'),
- xmlutil.TemplateElement('child3'), ]
-
- # Extend the parent by those children
- elem.extend(children)
-
- # Verify that the children were added
- self.assertEqual(len(elem), 3)
- for idx in range(len(elem)):
- self.assertEqual(children[idx], elem[idx])
- self.assertEqual(children[idx].tag in elem, True)
- self.assertEqual(elem[children[idx].tag], children[idx])
-
- # Ensure that multiple children of the same name are rejected
- children2 = [xmlutil.TemplateElement('child4'),
- xmlutil.TemplateElement('child1'), ]
- self.assertRaises(KeyError, elem.extend, children2)
-
- # Also ensure that child4 was not added
- self.assertEqual(len(elem), 3)
- self.assertEqual(elem[-1].tag, 'child3')
-
- def test_element_insert_child(self):
- # Create an element
- elem = xmlutil.TemplateElement('test')
-
- # Make sure the element starts off empty
- self.assertEqual(len(elem), 0)
-
- # Create a few children
- children = [xmlutil.TemplateElement('child1'),
- xmlutil.TemplateElement('child2'),
- xmlutil.TemplateElement('child3'), ]
-
- # Extend the parent by those children
- elem.extend(children)
-
- # Create a child to insert
- child = xmlutil.TemplateElement('child4')
-
- # Insert it
- elem.insert(1, child)
-
- # Ensure the child was inserted in the right place
- self.assertEqual(len(elem), 4)
- children.insert(1, child)
- for idx in range(len(elem)):
- self.assertEqual(children[idx], elem[idx])
- self.assertEqual(children[idx].tag in elem, True)
- self.assertEqual(elem[children[idx].tag], children[idx])
-
- # Ensure that multiple children of the same name are rejected
- child2 = xmlutil.TemplateElement('child2')
- self.assertRaises(KeyError, elem.insert, 2, child2)
-
- def test_element_remove_child(self):
- # Create an element
- elem = xmlutil.TemplateElement('test')
-
- # Make sure the element starts off empty
- self.assertEqual(len(elem), 0)
-
- # Create a few children
- children = [xmlutil.TemplateElement('child1'),
- xmlutil.TemplateElement('child2'),
- xmlutil.TemplateElement('child3'), ]
-
- # Extend the parent by those children
- elem.extend(children)
-
- # Create a test child to remove
- child = xmlutil.TemplateElement('child2')
-
- # Try to remove it
- self.assertRaises(ValueError, elem.remove, child)
-
- # Ensure that no child was removed
- self.assertEqual(len(elem), 3)
-
- # Now remove a legitimate child
- elem.remove(children[1])
-
- # Ensure that the child was removed
- self.assertEqual(len(elem), 2)
- self.assertEqual(elem[0], children[0])
- self.assertEqual(elem[1], children[2])
- self.assertEqual('child2' in elem, False)
-
- # Ensure the child cannot be retrieved by name
- def get_key(elem, key):
- return elem[key]
- self.assertRaises(KeyError, get_key, elem, 'child2')
-
- def test_element_text(self):
- # Create an element
- elem = xmlutil.TemplateElement('test')
-
- # Ensure that it has no text
- self.assertEqual(elem.text, None)
-
- # Try setting it to a string and ensure it becomes a selector
- elem.text = 'test'
- self.assertEqual(hasattr(elem.text, 'chain'), True)
- self.assertEqual(len(elem.text.chain), 1)
- self.assertEqual(elem.text.chain[0], 'test')
-
- # Try resetting the text to None
- elem.text = None
- self.assertEqual(elem.text, None)
-
- # Now make up a selector and try setting the text to that
- sel = xmlutil.Selector()
- elem.text = sel
- self.assertEqual(elem.text, sel)
-
- # Finally, try deleting the text and see what happens
- del elem.text
- self.assertEqual(elem.text, None)
-
- def test_apply_attrs(self):
- # Create a template element
- attrs = dict(attr1=xmlutil.ConstantSelector(1),
- attr2=xmlutil.ConstantSelector(2))
- tmpl_elem = xmlutil.TemplateElement('test', attrib=attrs)
-
- # Create an etree element
- elem = etree.Element('test')
-
- # Apply the template to the element
- tmpl_elem.apply(elem, None)
-
- # Now, verify the correct attributes were set
- for k, v in elem.items():
- self.assertEqual(str(attrs[k].value), v)
-
- def test_apply_text(self):
- # Create a template element
- tmpl_elem = xmlutil.TemplateElement('test')
- tmpl_elem.text = xmlutil.ConstantSelector(1)
-
- # Create an etree element
- elem = etree.Element('test')
-
- # Apply the template to the element
- tmpl_elem.apply(elem, None)
-
- # Now, verify the text was set
- self.assertEqual(str(tmpl_elem.text.value), elem.text)
-
- def test__render(self):
- attrs = dict(attr1=xmlutil.ConstantSelector(1),
- attr2=xmlutil.ConstantSelector(2),
- attr3=xmlutil.ConstantSelector(3))
-
- # Create a master template element
- master_elem = xmlutil.TemplateElement('test', attr1=attrs['attr1'])
-
- # Create a couple of slave template element
- slave_elems = [xmlutil.TemplateElement('test', attr2=attrs['attr2']),
- xmlutil.TemplateElement('test', attr3=attrs['attr3']), ]
-
- # Try the render
- elem = master_elem._render(None, None, slave_elems, None)
-
- # Verify the particulars of the render
- self.assertEqual(elem.tag, 'test')
- self.assertEqual(len(elem.nsmap), 0)
- for k, v in elem.items():
- self.assertEqual(str(attrs[k].value), v)
-
- # Create a parent for the element to be rendered
- parent = etree.Element('parent')
-
- # Try the render again...
- elem = master_elem._render(parent, None, slave_elems, dict(a='foo'))
-
- # Verify the particulars of the render
- self.assertEqual(len(parent), 1)
- self.assertEqual(parent[0], elem)
- self.assertEqual(len(elem.nsmap), 1)
- self.assertEqual(elem.nsmap['a'], 'foo')
-
- def test_render(self):
- # Create a template element
- tmpl_elem = xmlutil.TemplateElement('test')
- tmpl_elem.text = xmlutil.Selector()
-
- # Create the object we're going to render
- obj = ['elem1', 'elem2', 'elem3', 'elem4']
-
- # Try a render with no object
- elems = tmpl_elem.render(None, None)
- self.assertEqual(len(elems), 0)
-
- # Try a render with one object
- elems = tmpl_elem.render(None, 'foo')
- self.assertEqual(len(elems), 1)
- self.assertEqual(elems[0][0].text, 'foo')
- self.assertEqual(elems[0][1], 'foo')
-
- # Now, try rendering an object with multiple entries
- parent = etree.Element('parent')
- elems = tmpl_elem.render(parent, obj)
- self.assertEqual(len(elems), 4)
-
- # Check the results
- for idx in range(len(obj)):
- self.assertEqual(elems[idx][0].text, obj[idx])
- self.assertEqual(elems[idx][1], obj[idx])
-
- def test_subelement(self):
- # Try the SubTemplateElement constructor
- parent = xmlutil.SubTemplateElement(None, 'parent')
- self.assertEqual(parent.tag, 'parent')
- self.assertEqual(len(parent), 0)
-
- # Now try it with a parent element
- child = xmlutil.SubTemplateElement(parent, 'child')
- self.assertEqual(child.tag, 'child')
- self.assertEqual(len(parent), 1)
- self.assertEqual(parent[0], child)
-
- def test_wrap(self):
- # These are strange methods, but they make things easier
- elem = xmlutil.TemplateElement('test')
- self.assertEqual(elem.unwrap(), elem)
- self.assertEqual(elem.wrap().root, elem)
-
- def test_dyntag(self):
- obj = ['a', 'b', 'c']
-
- # Create a template element with a dynamic tag
- tmpl_elem = xmlutil.TemplateElement(xmlutil.Selector())
-
- # Try the render
- parent = etree.Element('parent')
- elems = tmpl_elem.render(parent, obj)
-
- # Verify the particulars of the render
- self.assertEqual(len(elems), len(obj))
- for idx in range(len(obj)):
- self.assertEqual(elems[idx][0].tag, obj[idx])
-
-
-class TemplateTest(test.TestCase):
- def test_wrap(self):
- # These are strange methods, but they make things easier
- elem = xmlutil.TemplateElement('test')
- tmpl = xmlutil.Template(elem)
- self.assertEqual(tmpl.unwrap(), elem)
- self.assertEqual(tmpl.wrap(), tmpl)
-
- def test__siblings(self):
- # Set up a basic template
- elem = xmlutil.TemplateElement('test')
- tmpl = xmlutil.Template(elem)
-
- # Check that we get the right siblings
- siblings = tmpl._siblings()
- self.assertEqual(len(siblings), 1)
- self.assertEqual(siblings[0], elem)
-
- def test__nsmap(self):
- # Set up a basic template
- elem = xmlutil.TemplateElement('test')
- tmpl = xmlutil.Template(elem, nsmap=dict(a="foo"))
-
- # Check out that we get the right namespace dictionary
- nsmap = tmpl._nsmap()
- self.assertNotEqual(id(nsmap), id(tmpl.nsmap))
- self.assertEqual(len(nsmap), 1)
- self.assertEqual(nsmap['a'], 'foo')
-
- def test_master_attach(self):
- # Set up a master template
- elem = xmlutil.TemplateElement('test')
- tmpl = xmlutil.MasterTemplate(elem, 1)
-
- # Make sure it has a root but no slaves
- self.assertEqual(tmpl.root, elem)
- self.assertEqual(len(tmpl.slaves), 0)
-
- # Try to attach an invalid slave
- bad_elem = xmlutil.TemplateElement('test2')
- self.assertRaises(ValueError, tmpl.attach, bad_elem)
- self.assertEqual(len(tmpl.slaves), 0)
-
- # Try to attach an invalid and a valid slave
- good_elem = xmlutil.TemplateElement('test')
- self.assertRaises(ValueError, tmpl.attach, good_elem, bad_elem)
- self.assertEqual(len(tmpl.slaves), 0)
-
- # Try to attach an inapplicable template
- class InapplicableTemplate(xmlutil.Template):
- def apply(self, master):
- return False
- inapp_tmpl = InapplicableTemplate(good_elem)
- tmpl.attach(inapp_tmpl)
- self.assertEqual(len(tmpl.slaves), 0)
-
- # Now try attaching an applicable template
- tmpl.attach(good_elem)
- self.assertEqual(len(tmpl.slaves), 1)
- self.assertEqual(tmpl.slaves[0].root, good_elem)
-
- def test_master_copy(self):
- # Construct a master template
- elem = xmlutil.TemplateElement('test')
- tmpl = xmlutil.MasterTemplate(elem, 1, nsmap=dict(a='foo'))
-
- # Give it a slave
- slave = xmlutil.TemplateElement('test')
- tmpl.attach(slave)
-
- # Construct a copy
- copy = tmpl.copy()
-
- # Check to see if we actually managed a copy
- self.assertNotEqual(tmpl, copy)
- self.assertEqual(tmpl.root, copy.root)
- self.assertEqual(tmpl.version, copy.version)
- self.assertEqual(id(tmpl.nsmap), id(copy.nsmap))
- self.assertNotEqual(id(tmpl.slaves), id(copy.slaves))
- self.assertEqual(len(tmpl.slaves), len(copy.slaves))
- self.assertEqual(tmpl.slaves[0], copy.slaves[0])
-
- def test_slave_apply(self):
- # Construct a master template
- elem = xmlutil.TemplateElement('test')
- master = xmlutil.MasterTemplate(elem, 3)
-
- # Construct a slave template with applicable minimum version
- slave = xmlutil.SlaveTemplate(elem, 2)
- self.assertEqual(slave.apply(master), True)
-
- # Construct a slave template with equal minimum version
- slave = xmlutil.SlaveTemplate(elem, 3)
- self.assertEqual(slave.apply(master), True)
-
- # Construct a slave template with inapplicable minimum version
- slave = xmlutil.SlaveTemplate(elem, 4)
- self.assertEqual(slave.apply(master), False)
-
- # Construct a slave template with applicable version range
- slave = xmlutil.SlaveTemplate(elem, 2, 4)
- self.assertEqual(slave.apply(master), True)
-
- # Construct a slave template with low version range
- slave = xmlutil.SlaveTemplate(elem, 1, 2)
- self.assertEqual(slave.apply(master), False)
-
- # Construct a slave template with high version range
- slave = xmlutil.SlaveTemplate(elem, 4, 5)
- self.assertEqual(slave.apply(master), False)
-
- # Construct a slave template with matching version range
- slave = xmlutil.SlaveTemplate(elem, 3, 3)
- self.assertEqual(slave.apply(master), True)
-
- def test__serialize(self):
- # Our test object to serialize
- obj = {'test': {'name': 'foobar',
- 'values': [1, 2, 3, 4],
- 'attrs': {'a': 1,
- 'b': 2,
- 'c': 3,
- 'd': 4, },
- 'image': {'name': 'image_foobar', 'id': 42, }, }, }
-
- # Set up our master template
- root = xmlutil.TemplateElement('test', selector='test',
- name='name')
- value = xmlutil.SubTemplateElement(root, 'value', selector='values')
- value.text = xmlutil.Selector()
- attrs = xmlutil.SubTemplateElement(root, 'attrs', selector='attrs')
- xmlutil.SubTemplateElement(attrs, 'attr', selector=xmlutil.get_items,
- key=0, value=1)
- master = xmlutil.MasterTemplate(root, 1, nsmap=dict(f='foo'))
-
- # Set up our slave template
- root_slave = xmlutil.TemplateElement('test', selector='test')
- image = xmlutil.SubTemplateElement(root_slave, 'image',
- selector='image', id='id')
- image.text = xmlutil.Selector('name')
- slave = xmlutil.SlaveTemplate(root_slave, 1, nsmap=dict(b='bar'))
-
- # Attach the slave to the master...
- master.attach(slave)
-
- # Try serializing our object
- siblings = master._siblings()
- nsmap = master._nsmap()
- result = master._serialize(None, obj, siblings, nsmap)
-
- # Now we get to manually walk the element tree...
- self.assertEqual(result.tag, 'test')
- self.assertEqual(len(result.nsmap), 2)
- self.assertEqual(result.nsmap['f'], 'foo')
- self.assertEqual(result.nsmap['b'], 'bar')
- self.assertEqual(result.get('name'), obj['test']['name'])
- for idx, val in enumerate(obj['test']['values']):
- self.assertEqual(result[idx].tag, 'value')
- self.assertEqual(result[idx].text, str(val))
- idx += 1
- self.assertEqual(result[idx].tag, 'attrs')
- for attr in result[idx]:
- self.assertEqual(attr.tag, 'attr')
- self.assertEqual(attr.get('value'),
- str(obj['test']['attrs'][attr.get('key')]))
- idx += 1
- self.assertEqual(result[idx].tag, 'image')
- self.assertEqual(result[idx].get('id'),
- str(obj['test']['image']['id']))
- self.assertEqual(result[idx].text, obj['test']['image']['name'])
-
-
-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.assertEqual(MasterTemplateBuilder._tmpl, None)
-
- # Now, construct the template
- tmpl1 = MasterTemplateBuilder()
-
- # Make sure that there is a template cached...
- self.assertNotEqual(MasterTemplateBuilder._tmpl, None)
-
- # 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.assertEqual(SlaveTemplateBuilder._tmpl, None)
-
- # Now, construct the template
- tmpl1 = SlaveTemplateBuilder()
-
- # Make sure there is a template cached...
- self.assertNotEqual(SlaveTemplateBuilder._tmpl, None)
-
- # 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 = minidom.parseString(
- ""
- "foobar"
- )
- root = xmlutil.make_flat_dict('wrapper')
- tmpl = xmlutil.MasterTemplate(root, 1)
- result = tmpl.serialize(dict(wrapper=dict(a='foo', b='bar')))
- actual = minidom.parseString(result)
-
- self.assertEqual(expected.firstChild.tagName,
- actual.firstChild.tagName)
- expected_child_a = expected.firstChild.getElementsByTagName('a')
- expected_child_b = expected.firstChild.getElementsByTagName('b')
- actual_child_a = actual.firstChild.getElementsByTagName('a')
- actual_child_b = actual.firstChild.getElementsByTagName('b')
- self.assertEqual(len(expected_child_a), 1)
- self.assertEqual(len(expected_child_b), 1)
- self.assertEqual(len(actual_child_a), 1)
- self.assertEqual(len(actual_child_b), 1)
- self.assertEqual(expected_child_a[0].toxml(),
- actual_child_a[0].toxml())
- self.assertEqual(expected_child_b[0].toxml(),
- actual_child_b[0].toxml())
diff --git a/manila/tests/api/v1/test_limits.py b/manila/tests/api/v1/test_limits.py
index 5f7df06554..f8354b81c3 100644
--- a/manila/tests/api/v1/test_limits.py
+++ b/manila/tests/api/v1/test_limits.py
@@ -18,9 +18,7 @@ Tests dealing with HTTP rate-limiting.
"""
import httplib
-from xml.dom import minidom
-from lxml import etree
from oslo_serialization import jsonutils
import six
from six import moves
@@ -28,7 +26,6 @@ import webob
from manila.api.v1 import limits
from manila.api import views
-from manila.api import xmlutil
import manila.context
from manila import test
@@ -279,26 +276,6 @@ class LimitMiddlewareTest(BaseLimitTestSuite):
value = body["overLimitFault"]["details"].strip()
self.assertEqual(value, expected)
- 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(response.status_int, 413)
-
- 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(details.length, 1)
-
- value = details.item(0).firstChild.data.strip()
- self.assertEqual(value, expected)
-
class LimitTest(BaseLimitTestSuite):
"""Tests for the `limits.Limit` class."""
@@ -802,89 +779,3 @@ class LimitsViewBuilderTest(test.TestCase):
rate_limits = []
output = self.view_builder.build(rate_limits, abs_limits)
self.assertDictMatch(output, expected_limits)
-
-
-class LimitsXMLSerializationTest(test.TestCase):
- def test_xml_declaration(self):
- serializer = limits.LimitsTemplate()
-
- fixture = {"limits": {
- "rate": [],
- "absolute": {}}}
-
- output = serializer.serialize(fixture)
- has_dec = output.startswith("")
- 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(len(absolutes), 4)
- for limit in absolutes:
- name = limit.get('name')
- value = limit.get('value')
- self.assertEqual(value, str(fixture['limits']['absolute'][name]))
-
- # verify rate limits
- rates = root.xpath('ns:rates/ns:rate', namespaces=NS)
- self.assertEqual(len(rates), 2)
- for i, rate in enumerate(rates):
- for key in ['uri', 'regex']:
- self.assertEqual(rate.get(key),
- str(fixture['limits']['rate'][i][key]))
- rate_limits = rate.xpath('ns:limit', namespaces=NS)
- self.assertEqual(len(rate_limits), 1)
- for j, limit in enumerate(rate_limits):
- for key in ['verb', 'value', 'remaining', 'unit',
- 'next-available']:
- self.assertEqual(
- limit.get(key),
- str(fixture['limits']['rate'][i]['limit'][j][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(len(absolutes), 0)
-
- # verify rate limits
- rates = root.xpath('ns:rates/ns:rate', namespaces=NS)
- self.assertEqual(len(rates), 0)
diff --git a/manila/tests/test_utils.py b/manila/tests/test_utils.py
index a3d1a1bf8b..106ec41b6e 100644
--- a/manila/tests/test_utils.py
+++ b/manila/tests/test_utils.py
@@ -284,36 +284,6 @@ class GenericUtilsTestCase(test.TestCase):
self.assertFalse(result)
timeutils.utcnow.assert_called_once_with()
- def test_safe_parse_xml(self):
-
- normal_body = (''
- 'heythere')
-
- def killer_body():
- return (("""
-
- ]>
-
-
- %(d)s
-
- """) % {
- 'a': 'A' * 10,
- 'b': '&a;' * 10,
- 'c': '&b;' * 10,
- 'd': '&c;' * 9999,
- }).strip()
-
- dom = utils.safe_minidom_parse_string(normal_body)
- # Some versions of minidom inject extra newlines so we ignore them
- result = str(dom.toxml()).replace('\n', '')
- self.assertEqual(normal_body, result)
-
- self.assertRaises(ValueError,
- utils.safe_minidom_parse_string,
- killer_body())
-
def test_is_ipv6_configured0(self):
fake_fd = mock.Mock()
fake_fd.read.return_value = 'test'
diff --git a/manila/utils.py b/manila/utils.py
index 764b86b81e..53a98c178e 100644
--- a/manila/utils.py
+++ b/manila/utils.py
@@ -26,10 +26,6 @@ import shutil
import socket
import sys
import tempfile
-from xml.dom import minidom
-from xml.parsers import expat
-from xml import sax
-from xml.sax import expatreader
from eventlet import pools
import netaddr
@@ -191,46 +187,6 @@ class LazyPluggable(object):
return getattr(backend, key)
-class ProtectedExpatParser(expatreader.ExpatParser):
- """An expat parser which disables DTD's and entities by default."""
-
- def __init__(self, forbid_dtd=True, forbid_entities=True,
- *args, **kwargs):
- # Python 2.x old style class
- expatreader.ExpatParser.__init__(self, *args, **kwargs)
- self.forbid_dtd = forbid_dtd
- self.forbid_entities = forbid_entities
-
- def start_doctype_decl(self, name, sysid, pubid, has_internal_subset):
- raise ValueError("Inline DTD forbidden")
-
- def entity_decl(self, entityName, is_parameter_entity, value, base,
- systemId, publicId, notationName):
- raise ValueError(" forbidden")
-
- def unparsed_entity_decl(self, name, base, sysid, pubid, notation_name):
- # expat 1.2
- raise ValueError(" forbidden")
-
- def reset(self):
- expatreader.ExpatParser.reset(self)
- if self.forbid_dtd:
- self._parser.StartDoctypeDeclHandler = self.start_doctype_decl
- if self.forbid_entities:
- self._parser.EntityDeclHandler = self.entity_decl
- self._parser.UnparsedEntityDeclHandler = self.unparsed_entity_decl
-
-
-def safe_minidom_parse_string(xml_string):
- """Parse an XML string using minidom safely.
-
- """
- try:
- return minidom.parseString(xml_string, parser=ProtectedExpatParser())
- except sax.SAXParseException:
- raise expat.ExpatError()
-
-
def delete_if_exists(pathname):
"""Delete a file, but ignore file not found error."""