Remove XML support
As XML support has been removed from neutron, there is no need to keep it in client. Dropped XML serializer and deserializer and deprecated "request-format" CLI option, making JSON the default and the only supported request format. DocImpact Change-Id: I88b0fdd65a649694252d5ff43a174e75026df5b1 Closes-Bug: #1380787
This commit is contained in:
parent
88010add39
commit
54a4aea969
100
neutron_test.sh
100
neutron_test.sh
@ -28,12 +28,10 @@ fi
|
||||
echo "NOTE: User should be admin in order to perform all operations."
|
||||
sleep 3
|
||||
|
||||
FORMAT=" --request-format json"
|
||||
|
||||
# test the CRUD of network
|
||||
network=$net_name
|
||||
neutron net-create $FORMAT $NOAUTH $network || die "fail to create network $network"
|
||||
temp=`neutron net-list $FORMAT -- --name $network --fields id | wc -l`
|
||||
neutron net-create $NOAUTH $network || die "fail to create network $network"
|
||||
temp=`neutron net-list -- --name $network --fields id | wc -l`
|
||||
echo $temp
|
||||
if [ $temp -ne 5 ]; then
|
||||
die "networks with name $network is not unique or found"
|
||||
@ -41,66 +39,66 @@ fi
|
||||
network_id=`neutron net-list -- --name $network --fields id | tail -n 2 | head -n 1 | cut -d' ' -f 2`
|
||||
echo "ID of network with name $network is $network_id"
|
||||
|
||||
neutron net-show $FORMAT $network || die "fail to show network $network"
|
||||
neutron net-show $FORMAT $network_id || die "fail to show network $network_id"
|
||||
neutron net-show $network || die "fail to show network $network"
|
||||
neutron net-show $network_id || die "fail to show network $network_id"
|
||||
|
||||
neutron net-update $FORMAT $network --admin_state_up False || die "fail to update network $network"
|
||||
neutron net-update $FORMAT $network_id --admin_state_up True || die "fail to update network $network_id"
|
||||
neutron net-update $network --admin_state_up False || die "fail to update network $network"
|
||||
neutron net-update $network_id --admin_state_up True || die "fail to update network $network_id"
|
||||
|
||||
neutron net-list $FORMAT -c id -- --id fakeid || die "fail to list networks with column selection on empty list"
|
||||
neutron net-list -c id -- --id fakeid || die "fail to list networks with column selection on empty list"
|
||||
|
||||
# test the CRUD of subnet
|
||||
subnet=$subnet_name
|
||||
cidr=10.0.1.0/24
|
||||
neutron subnet-create $FORMAT $NOAUTH $network $cidr --name $subnet || die "fail to create subnet $subnet"
|
||||
tempsubnet=`neutron subnet-list $FORMAT -- --name $subnet --fields id | wc -l`
|
||||
neutron subnet-create $NOAUTH $network $cidr --name $subnet || die "fail to create subnet $subnet"
|
||||
tempsubnet=`neutron subnet-list -- --name $subnet --fields id | wc -l`
|
||||
echo $tempsubnet
|
||||
if [ $tempsubnet -ne 5 ]; then
|
||||
die "subnets with name $subnet is not unique or found"
|
||||
fi
|
||||
subnet_id=`neutron subnet-list $FORMAT -- --name $subnet --fields id | tail -n 2 | head -n 1 | cut -d' ' -f 2`
|
||||
subnet_id=`neutron subnet-list -- --name $subnet --fields id | tail -n 2 | head -n 1 | cut -d' ' -f 2`
|
||||
echo "ID of subnet with name $subnet is $subnet_id"
|
||||
neutron subnet-show $FORMAT $subnet || die "fail to show subnet $subnet"
|
||||
neutron subnet-show $FORMAT $subnet_id || die "fail to show subnet $subnet_id"
|
||||
neutron subnet-show $subnet || die "fail to show subnet $subnet"
|
||||
neutron subnet-show $subnet_id || die "fail to show subnet $subnet_id"
|
||||
|
||||
neutron subnet-update $FORMAT $subnet --dns_nameservers list=true 1.1.1.11 1.1.1.12 || die "fail to update subnet $subnet"
|
||||
neutron subnet-update $FORMAT $subnet_id --dns_nameservers list=true 2.2.2.21 2.2.2.22 || die "fail to update subnet $subnet_id"
|
||||
neutron subnet-update $subnet --dns_nameservers list=true 1.1.1.11 1.1.1.12 || die "fail to update subnet $subnet"
|
||||
neutron subnet-update $subnet_id --dns_nameservers list=true 2.2.2.21 2.2.2.22 || die "fail to update subnet $subnet_id"
|
||||
|
||||
# test the crud of ports
|
||||
port=$port_name
|
||||
neutron port-create $FORMAT $NOAUTH $network --name $port || die "fail to create port $port"
|
||||
tempport=`neutron port-list $FORMAT -- --name $port --fields id | wc -l`
|
||||
neutron port-create $NOAUTH $network --name $port || die "fail to create port $port"
|
||||
tempport=`neutron port-list -- --name $port --fields id | wc -l`
|
||||
echo $tempport
|
||||
if [ $tempport -ne 5 ]; then
|
||||
die "ports with name $port is not unique or found"
|
||||
fi
|
||||
port_id=`neutron port-list $FORMAT -- --name $port --fields id | tail -n 2 | head -n 1 | cut -d' ' -f 2`
|
||||
port_id=`neutron port-list -- --name $port --fields id | tail -n 2 | head -n 1 | cut -d' ' -f 2`
|
||||
echo "ID of port with name $port is $port_id"
|
||||
neutron port-show $FORMAT $port || die "fail to show port $port"
|
||||
neutron port-show $FORMAT $port_id || die "fail to show port $port_id"
|
||||
neutron port-update $FORMAT $port --device_id deviceid1 || die "fail to update port $port"
|
||||
neutron port-update $FORMAT $port_id --device_id deviceid2 || die "fail to update port $port_id"
|
||||
neutron port-update $FORMAT $port_id --allowed-address-pair ip_address=1.1.1.11,mac_address=10:00:00:00:00:00 --allowed-address-pair ip_address=1.1.1.12,mac_address=10:00:00:00:00:01 || die "fail to update port $port_id --allowed-address-pair"
|
||||
neutron port-show $FORMAT $port || die "fail to show port $port"
|
||||
neutron port-show $FORMAT $port_id || die "fail to show port $port_id"
|
||||
neutron port-update $FORMAT $port_id --no-allowed-address-pairs || die "fail to update port $port_id --no-allowed-address-pairs"
|
||||
neutron port-show $FORMAT $port || die "fail to show port $port"
|
||||
neutron port-show $FORMAT $port_id || die "fail to show port $port_id"
|
||||
neutron port-show $port || die "fail to show port $port"
|
||||
neutron port-show $port_id || die "fail to show port $port_id"
|
||||
neutron port-update $port --device_id deviceid1 || die "fail to update port $port"
|
||||
neutron port-update $port_id --device_id deviceid2 || die "fail to update port $port_id"
|
||||
neutron port-update $port_id --allowed-address-pair ip_address=1.1.1.11,mac_address=10:00:00:00:00:00 --allowed-address-pair ip_address=1.1.1.12,mac_address=10:00:00:00:00:01 || die "fail to update port $port_id --allowed-address-pair"
|
||||
neutron port-show $port || die "fail to show port $port"
|
||||
neutron port-show $port_id || die "fail to show port $port_id"
|
||||
neutron port-update $port_id --no-allowed-address-pairs || die "fail to update port $port_id --no-allowed-address-pairs"
|
||||
neutron port-show $port || die "fail to show port $port"
|
||||
neutron port-show $port_id || die "fail to show port $port_id"
|
||||
neutron port-delete $port_id
|
||||
|
||||
# test the create port with allowed-address-pairs
|
||||
port=$port_name
|
||||
neutron port-create $FORMAT $NOAUTH $network --name $port -- --allowed-address-pairs type=dict list=true ip_address=1.1.1.11,mac_address=10:00:00:00:00:00 ip_address=1.1.1.12,mac_address=10:00:00:00:00:01 || die "fail to create port $port"
|
||||
tempport=`neutron port-list $FORMAT -- --name $port --fields id | wc -l`
|
||||
neutron port-create $NOAUTH $network --name $port -- --allowed-address-pairs type=dict list=true ip_address=1.1.1.11,mac_address=10:00:00:00:00:00 ip_address=1.1.1.12,mac_address=10:00:00:00:00:01 || die "fail to create port $port"
|
||||
tempport=`neutron port-list -- --name $port --fields id | wc -l`
|
||||
echo $tempport
|
||||
if [ $tempport -ne 5 ]; then
|
||||
die "ports with name $port is not unique or found"
|
||||
fi
|
||||
port_id=`neutron port-list $FORMAT -- --name $port --fields id | tail -n 2 | head -n 1 | cut -d' ' -f 2`
|
||||
port_id=`neutron port-list -- --name $port --fields id | tail -n 2 | head -n 1 | cut -d' ' -f 2`
|
||||
echo "ID of port with name $port is $port_id"
|
||||
neutron port-show $FORMAT $port || die "fail to show port $port"
|
||||
neutron port-show $FORMAT $port_id || die "fail to show port $port_id"
|
||||
neutron port-update $FORMAT $port_id --no-allowed-address-pairs || die "fail to update port $port_id --no-allowed-address-pairs"
|
||||
neutron port-show $port || die "fail to show port $port"
|
||||
neutron port-show $port_id || die "fail to show port $port_id"
|
||||
neutron port-update $port_id --no-allowed-address-pairs || die "fail to update port $port_id --no-allowed-address-pairs"
|
||||
neutron port-show $port_id
|
||||
|
||||
# test quota commands RUD
|
||||
@ -108,58 +106,58 @@ DEFAULT_NETWORKS=10
|
||||
DEFAULT_PORTS=50
|
||||
tenant_id=tenant_a
|
||||
tenant_id_b=tenant_b
|
||||
neutron quota-update $FORMAT --tenant_id $tenant_id --network 30 || die "fail to update quota for tenant $tenant_id"
|
||||
neutron quota-update $FORMAT --tenant_id $tenant_id_b --network 20 || die "fail to update quota for tenant $tenant_id"
|
||||
networks=`neutron quota-list $FORMAT -c network -c tenant_id | grep $tenant_id | awk '{print $2}'`
|
||||
neutron quota-update --tenant_id $tenant_id --network 30 || die "fail to update quota for tenant $tenant_id"
|
||||
neutron quota-update --tenant_id $tenant_id_b --network 20 || die "fail to update quota for tenant $tenant_id"
|
||||
networks=`neutron quota-list -c network -c tenant_id | grep $tenant_id | awk '{print $2}'`
|
||||
if [ $networks -ne 30 ]; then
|
||||
die "networks quota should be 30"
|
||||
fi
|
||||
networks=`neutron quota-list $FORMAT -c network -c tenant_id | grep $tenant_id_b | awk '{print $2}'`
|
||||
networks=`neutron quota-list -c network -c tenant_id | grep $tenant_id_b | awk '{print $2}'`
|
||||
if [ $networks -ne 20 ]; then
|
||||
die "networks quota should be 20"
|
||||
fi
|
||||
networks=`neutron quota-show $FORMAT --tenant_id $tenant_id | grep network | awk -F'|' '{print $3}'`
|
||||
networks=`neutron quota-show --tenant_id $tenant_id | grep network | awk -F'|' '{print $3}'`
|
||||
if [ $networks -ne 30 ]; then
|
||||
die "networks quota should be 30"
|
||||
fi
|
||||
neutron quota-delete $FORMAT --tenant_id $tenant_id || die "fail to delete quota for tenant $tenant_id"
|
||||
networks=`neutron quota-show $FORMAT --tenant_id $tenant_id | grep network | awk -F'|' '{print $3}'`
|
||||
neutron quota-delete --tenant_id $tenant_id || die "fail to delete quota for tenant $tenant_id"
|
||||
networks=`neutron quota-show --tenant_id $tenant_id | grep network | awk -F'|' '{print $3}'`
|
||||
if [ $networks -ne $DEFAULT_NETWORKS ]; then
|
||||
die "networks quota should be $DEFAULT_NETWORKS"
|
||||
fi
|
||||
# update self
|
||||
if [ "t$NOAUTH" = "t" ]; then
|
||||
# with auth
|
||||
neutron quota-update $FORMAT --port 99 || die "fail to update quota for self"
|
||||
ports=`neutron quota-show $FORMAT | grep port | awk -F'|' '{print $3}'`
|
||||
neutron quota-update --port 99 || die "fail to update quota for self"
|
||||
ports=`neutron quota-show | grep port | awk -F'|' '{print $3}'`
|
||||
if [ $ports -ne 99 ]; then
|
||||
die "ports quota should be 99"
|
||||
fi
|
||||
|
||||
ports=`neutron quota-list $FORMAT -c port | grep 99 | awk '{print $2}'`
|
||||
ports=`neutron quota-list -c port | grep 99 | awk '{print $2}'`
|
||||
if [ $ports -ne 99 ]; then
|
||||
die "ports quota should be 99"
|
||||
fi
|
||||
neutron quota-delete $FORMAT || die "fail to delete quota for tenant self"
|
||||
ports=`neutron quota-show $FORMAT | grep port | awk -F'|' '{print $3}'`
|
||||
neutron quota-delete || die "fail to delete quota for tenant self"
|
||||
ports=`neutron quota-show | grep port | awk -F'|' '{print $3}'`
|
||||
if [ $ports -ne $DEFAULT_PORTS ]; then
|
||||
die "ports quota should be $DEFAULT_PORTS"
|
||||
fi
|
||||
else
|
||||
# without auth
|
||||
neutron quota-update $FORMAT --port 100
|
||||
neutron quota-update --port 100
|
||||
if [ $? -eq 0 ]; then
|
||||
die "without valid context on server, quota update command should fail."
|
||||
fi
|
||||
neutron quota-show $FORMAT
|
||||
neutron quota-show
|
||||
if [ $? -eq 0 ]; then
|
||||
die "without valid context on server, quota show command should fail."
|
||||
fi
|
||||
neutron quota-delete $FORMAT
|
||||
neutron quota-delete
|
||||
if [ $? -eq 0 ]; then
|
||||
die "without valid context on server, quota delete command should fail."
|
||||
fi
|
||||
neutron quota-list $FORMAT || die "fail to update quota for self"
|
||||
neutron quota-list || die "fail to update quota for self"
|
||||
fi
|
||||
|
||||
cleanup
|
||||
|
@ -14,18 +14,6 @@
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
EXT_NS = '_extension_ns'
|
||||
XML_NS_V20 = 'http://openstack.org/quantum/api/v2.0'
|
||||
XSI_NAMESPACE = "http://www.w3.org/2001/XMLSchema-instance"
|
||||
XSI_ATTR = "xsi:nil"
|
||||
XSI_NIL_ATTR = "xmlns:xsi"
|
||||
TYPE_XMLNS = "xmlns:quantum"
|
||||
TYPE_ATTR = "quantum:type"
|
||||
VIRTUAL_ROOT_KEY = "_v_root"
|
||||
ATOM_NAMESPACE = "http://www.w3.org/2005/Atom"
|
||||
ATOM_XMLNS = "xmlns:atom"
|
||||
ATOM_LINK_NOTATION = "{%s}link" % ATOM_NAMESPACE
|
||||
|
||||
TYPE_BOOL = "bool"
|
||||
TYPE_INT = "int"
|
||||
TYPE_LONG = "long"
|
||||
|
@ -14,13 +14,10 @@
|
||||
# under the License.
|
||||
|
||||
import logging
|
||||
from xml.etree import ElementTree as etree
|
||||
from xml.parsers import expat
|
||||
|
||||
from oslo_serialization import jsonutils
|
||||
import six
|
||||
|
||||
from neutronclient.common import constants
|
||||
from neutronclient.common import exceptions as exception
|
||||
from neutronclient.i18n import _
|
||||
|
||||
@ -62,148 +59,6 @@ class JSONDictSerializer(DictSerializer):
|
||||
return jsonutils.dumps(data, default=sanitizer)
|
||||
|
||||
|
||||
class XMLDictSerializer(DictSerializer):
|
||||
|
||||
def __init__(self, metadata=None, xmlns=None):
|
||||
"""XMLDictSerializer constructor.
|
||||
|
||||
: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 {}
|
||||
if not xmlns:
|
||||
xmlns = self.metadata.get('xmlns')
|
||||
if not xmlns:
|
||||
xmlns = constants.XML_NS_V20
|
||||
self.xmlns = xmlns
|
||||
|
||||
def default(self, data):
|
||||
"""Default serializer of XMLDictSerializer.
|
||||
|
||||
:param data: expect data to contain a single key as XML root, or
|
||||
contain another '*_links' key as atom links. Other
|
||||
case will use 'VIRTUAL_ROOT_KEY' as XML root.
|
||||
"""
|
||||
try:
|
||||
links = None
|
||||
has_atom = False
|
||||
if data is None:
|
||||
root_key = constants.VIRTUAL_ROOT_KEY
|
||||
root_value = None
|
||||
else:
|
||||
link_keys = [k for k in six.iterkeys(data) or []
|
||||
if k.endswith('_links')]
|
||||
if link_keys:
|
||||
links = data.pop(link_keys[0], None)
|
||||
has_atom = True
|
||||
root_key = (len(data) == 1 and
|
||||
list(data.keys())[0] or constants.VIRTUAL_ROOT_KEY)
|
||||
root_value = data.get(root_key, data)
|
||||
doc = etree.Element("_temp_root")
|
||||
used_prefixes = []
|
||||
self._to_xml_node(doc, self.metadata, root_key,
|
||||
root_value, used_prefixes)
|
||||
if links:
|
||||
self._create_link_nodes(list(doc)[0], links)
|
||||
return self.to_xml_string(list(doc)[0], used_prefixes, has_atom)
|
||||
except AttributeError as e:
|
||||
LOG.exception(str(e))
|
||||
return ''
|
||||
|
||||
def __call__(self, data):
|
||||
# Provides a migration path to a cleaner WSGI layer, this
|
||||
# "default" stuff and extreme extensibility isn't being used
|
||||
# like originally intended
|
||||
return self.default(data)
|
||||
|
||||
def to_xml_string(self, node, used_prefixes, has_atom=False):
|
||||
self._add_xmlns(node, used_prefixes, has_atom)
|
||||
return etree.tostring(node, encoding='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, used_prefixes, has_atom=False):
|
||||
node.set('xmlns', self.xmlns)
|
||||
node.set(constants.TYPE_XMLNS, self.xmlns)
|
||||
if has_atom:
|
||||
node.set(constants.ATOM_XMLNS, constants.ATOM_NAMESPACE)
|
||||
node.set(constants.XSI_NIL_ATTR, constants.XSI_NAMESPACE)
|
||||
ext_ns = self.metadata.get(constants.EXT_NS, {})
|
||||
for prefix in used_prefixes:
|
||||
if prefix in ext_ns:
|
||||
node.set('xmlns:' + prefix, ext_ns[prefix])
|
||||
|
||||
def _to_xml_node(self, parent, metadata, nodename, data, used_prefixes):
|
||||
"""Recursive method to convert data members to XML nodes."""
|
||||
result = etree.SubElement(parent, nodename)
|
||||
if ":" in nodename:
|
||||
used_prefixes.append(nodename.split(":", 1)[0])
|
||||
# TODO(bcwaldon): accomplish this without a type-check
|
||||
if isinstance(data, list):
|
||||
if not data:
|
||||
result.set(
|
||||
constants.TYPE_ATTR,
|
||||
constants.TYPE_LIST)
|
||||
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:
|
||||
self._to_xml_node(result, metadata, singular, item,
|
||||
used_prefixes)
|
||||
# TODO(bcwaldon): accomplish this without a type-check
|
||||
elif isinstance(data, dict):
|
||||
if not data:
|
||||
result.set(
|
||||
constants.TYPE_ATTR,
|
||||
constants.TYPE_DICT)
|
||||
return result
|
||||
attrs = metadata.get('attributes', {}).get(nodename, {})
|
||||
for k, v in sorted(data.items()):
|
||||
if k in attrs:
|
||||
result.set(k, str(v))
|
||||
else:
|
||||
self._to_xml_node(result, metadata, k, v,
|
||||
used_prefixes)
|
||||
elif data is None:
|
||||
result.set(constants.XSI_ATTR, 'true')
|
||||
else:
|
||||
if isinstance(data, bool):
|
||||
result.set(
|
||||
constants.TYPE_ATTR,
|
||||
constants.TYPE_BOOL)
|
||||
elif isinstance(data, int):
|
||||
result.set(
|
||||
constants.TYPE_ATTR,
|
||||
constants.TYPE_INT)
|
||||
elif isinstance(data, long):
|
||||
result.set(
|
||||
constants.TYPE_ATTR,
|
||||
constants.TYPE_LONG)
|
||||
elif isinstance(data, float):
|
||||
result.set(
|
||||
constants.TYPE_ATTR,
|
||||
constants.TYPE_FLOAT)
|
||||
LOG.debug("Data %(data)s type is %(type)s",
|
||||
{'data': data,
|
||||
'type': type(data)})
|
||||
result.text = six.text_type(data)
|
||||
return result
|
||||
|
||||
def _create_link_nodes(self, xml_doc, links):
|
||||
for link in links:
|
||||
link_node = etree.SubElement(xml_doc, 'atom:link')
|
||||
link_node.set('rel', link['rel'])
|
||||
link_node.set('href', link['href'])
|
||||
|
||||
|
||||
class TextDeserializer(ActionDispatcher):
|
||||
"""Default request body deserialization."""
|
||||
|
||||
@ -227,140 +82,11 @@ class JSONDeserializer(TextDeserializer):
|
||||
return {'body': self._from_json(datastring)}
|
||||
|
||||
|
||||
class XMLDeserializer(TextDeserializer):
|
||||
|
||||
def __init__(self, metadata=None):
|
||||
"""XMLDeserializer constructor.
|
||||
|
||||
:param metadata: information needed to deserialize XML into
|
||||
a dictionary.
|
||||
"""
|
||||
super(XMLDeserializer, self).__init__()
|
||||
self.metadata = metadata or {}
|
||||
xmlns = self.metadata.get('xmlns')
|
||||
if not xmlns:
|
||||
xmlns = constants.XML_NS_V20
|
||||
self.xmlns = xmlns
|
||||
|
||||
def _get_key(self, tag):
|
||||
tags = tag.split("}", 1)
|
||||
if len(tags) == 2:
|
||||
ns = tags[0][1:]
|
||||
bare_tag = tags[1]
|
||||
ext_ns = self.metadata.get(constants.EXT_NS, {})
|
||||
if ns == self.xmlns:
|
||||
return bare_tag
|
||||
for prefix, _ns in ext_ns.items():
|
||||
if ns == _ns:
|
||||
return prefix + ":" + bare_tag
|
||||
else:
|
||||
return tag
|
||||
|
||||
def _get_links(self, root_tag, node):
|
||||
link_nodes = node.findall(constants.ATOM_LINK_NOTATION)
|
||||
root_tag = self._get_key(node.tag)
|
||||
link_key = "%s_links" % root_tag
|
||||
link_list = []
|
||||
for link in link_nodes:
|
||||
link_list.append({'rel': link.get('rel'),
|
||||
'href': link.get('href')})
|
||||
# Remove link node in order to avoid link node being
|
||||
# processed as an item in _from_xml_node
|
||||
node.remove(link)
|
||||
return link_list and {link_key: link_list} or {}
|
||||
|
||||
def _from_xml(self, datastring):
|
||||
if datastring is None:
|
||||
return None
|
||||
plurals = set(self.metadata.get('plurals', {}))
|
||||
try:
|
||||
node = etree.fromstring(datastring)
|
||||
root_tag = self._get_key(node.tag)
|
||||
links = self._get_links(root_tag, node)
|
||||
result = self._from_xml_node(node, plurals)
|
||||
# There is no case where root_tag = constants.VIRTUAL_ROOT_KEY
|
||||
# and links is not None because of the way data are serialized
|
||||
if root_tag == constants.VIRTUAL_ROOT_KEY:
|
||||
return result
|
||||
return dict({root_tag: result}, **links)
|
||||
except Exception as e:
|
||||
parseError = False
|
||||
# Python2.7
|
||||
if (hasattr(etree, 'ParseError') and
|
||||
isinstance(e, getattr(etree, 'ParseError'))):
|
||||
parseError = True
|
||||
# Python2.6
|
||||
elif isinstance(e, expat.ExpatError):
|
||||
parseError = True
|
||||
if parseError:
|
||||
msg = _("Cannot understand XML")
|
||||
raise exception.MalformedResponseBody(reason=msg)
|
||||
else:
|
||||
raise
|
||||
|
||||
def _from_xml_node(self, node, listnames):
|
||||
"""Convert a minidom node to a simple Python type.
|
||||
|
||||
:param node: minidom node name
|
||||
:param listnames: list of XML node names whose subnodes should
|
||||
be considered list items.
|
||||
|
||||
"""
|
||||
attrNil = node.get(str(etree.QName(constants.XSI_NAMESPACE, "nil")))
|
||||
attrType = node.get(str(etree.QName(
|
||||
self.metadata.get('xmlns'), "type")))
|
||||
if (attrNil and attrNil.lower() == 'true'):
|
||||
return None
|
||||
elif not len(node) and not node.text:
|
||||
if (attrType and attrType == constants.TYPE_DICT):
|
||||
return {}
|
||||
elif (attrType and attrType == constants.TYPE_LIST):
|
||||
return []
|
||||
else:
|
||||
return ''
|
||||
elif (len(node) == 0 and node.text):
|
||||
converters = {constants.TYPE_BOOL:
|
||||
lambda x: x.lower() == 'true',
|
||||
constants.TYPE_INT:
|
||||
lambda x: int(x),
|
||||
constants.TYPE_LONG:
|
||||
lambda x: long(x),
|
||||
constants.TYPE_FLOAT:
|
||||
lambda x: float(x)}
|
||||
if attrType and attrType in converters:
|
||||
return converters[attrType](node.text)
|
||||
else:
|
||||
return node.text
|
||||
elif self._get_key(node.tag) in listnames:
|
||||
return [self._from_xml_node(n, listnames) for n in node]
|
||||
else:
|
||||
result = dict()
|
||||
for attr in node.keys():
|
||||
if (attr == 'xmlns' or
|
||||
attr.startswith('xmlns:') or
|
||||
attr == constants.XSI_ATTR or
|
||||
attr == constants.TYPE_ATTR):
|
||||
continue
|
||||
result[self._get_key(attr)] = node.get(attr)
|
||||
children = list(node)
|
||||
for child in children:
|
||||
result[self._get_key(child.tag)] = self._from_xml_node(
|
||||
child, listnames)
|
||||
return result
|
||||
|
||||
def default(self, datastring):
|
||||
return {'body': self._from_xml(datastring)}
|
||||
|
||||
def __call__(self, datastring):
|
||||
# Adding a migration path to allow us to remove unncessary classes
|
||||
return self.default(datastring)
|
||||
|
||||
|
||||
# NOTE(maru): this class is duplicated from neutron.wsgi
|
||||
class Serializer(object):
|
||||
"""Serializes and deserializes dictionaries to certain MIME types."""
|
||||
|
||||
def __init__(self, metadata=None, default_xmlns=None):
|
||||
def __init__(self, metadata=None):
|
||||
"""Create a serializer based on the given WSGI environment.
|
||||
|
||||
'metadata' is an optional dict mapping MIME types to information
|
||||
@ -368,12 +94,10 @@ class Serializer(object):
|
||||
|
||||
"""
|
||||
self.metadata = metadata or {}
|
||||
self.default_xmlns = default_xmlns
|
||||
|
||||
def _get_serialize_handler(self, content_type):
|
||||
handlers = {
|
||||
'application/json': JSONDictSerializer(),
|
||||
'application/xml': XMLDictSerializer(self.metadata),
|
||||
}
|
||||
|
||||
try:
|
||||
@ -381,22 +105,21 @@ class Serializer(object):
|
||||
except Exception:
|
||||
raise exception.InvalidContentType(content_type=content_type)
|
||||
|
||||
def serialize(self, data, content_type):
|
||||
def serialize(self, data):
|
||||
"""Serialize a dictionary into the specified content type."""
|
||||
return self._get_serialize_handler(content_type).serialize(data)
|
||||
return self._get_serialize_handler("application/json").serialize(data)
|
||||
|
||||
def deserialize(self, datastring, content_type):
|
||||
def deserialize(self, datastring):
|
||||
"""Deserialize a string to a dictionary.
|
||||
|
||||
The string must be in the format of a supported MIME type.
|
||||
"""
|
||||
return self.get_deserialize_handler(content_type).deserialize(
|
||||
return self.get_deserialize_handler("application/json").deserialize(
|
||||
datastring)
|
||||
|
||||
def get_deserialize_handler(self, content_type):
|
||||
handlers = {
|
||||
'application/json': JSONDeserializer(),
|
||||
'application/xml': XMLDeserializer(self.metadata),
|
||||
}
|
||||
|
||||
try:
|
||||
|
@ -426,12 +426,12 @@ class NeutronCommand(command.OpenStackCommand):
|
||||
parser = super(NeutronCommand, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'--request-format',
|
||||
help=_('The XML or JSON request format.'),
|
||||
help=_('DEPRECATED! Only JSON request format is supported.'),
|
||||
default='json',
|
||||
choices=['json', 'xml', ], )
|
||||
choices=['json', ], )
|
||||
parser.add_argument(
|
||||
'--request_format',
|
||||
choices=['json', 'xml', ],
|
||||
choices=['json', ],
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
return parser
|
||||
@ -486,7 +486,6 @@ class CreateCommand(NeutronCommand, show.ShowOne):
|
||||
self.log.debug('get_data(%s)' % parsed_args)
|
||||
self.set_extra_attrs(parsed_args)
|
||||
neutron_client = self.get_client()
|
||||
neutron_client.format = parsed_args.request_format
|
||||
_extra_values = parse_args_to_dict(self.values_specs)
|
||||
_merge_args(self, parsed_args, _extra_values,
|
||||
self.values_specs)
|
||||
@ -531,7 +530,6 @@ class UpdateCommand(NeutronCommand):
|
||||
self.log.debug('run(%s)', parsed_args)
|
||||
self.set_extra_attrs(parsed_args)
|
||||
neutron_client = self.get_client()
|
||||
neutron_client.format = parsed_args.request_format
|
||||
_extra_values = parse_args_to_dict(self.values_specs)
|
||||
_merge_args(self, parsed_args, _extra_values,
|
||||
self.values_specs)
|
||||
@ -587,7 +585,6 @@ class DeleteCommand(NeutronCommand):
|
||||
self.log.debug('run(%s)', parsed_args)
|
||||
self.set_extra_attrs(parsed_args)
|
||||
neutron_client = self.get_client()
|
||||
neutron_client.format = parsed_args.request_format
|
||||
obj_deleter = getattr(neutron_client,
|
||||
"delete_%s" % self.cmd_resource)
|
||||
if self.allow_names:
|
||||
@ -654,7 +651,6 @@ class ListCommand(NeutronCommand, lister.Lister):
|
||||
def retrieve_list(self, parsed_args):
|
||||
"""Retrieve a list of resources from Neutron server."""
|
||||
neutron_client = self.get_client()
|
||||
neutron_client.format = parsed_args.request_format
|
||||
_extra_values = parse_args_to_dict(self.values_specs)
|
||||
_merge_args(self, parsed_args, _extra_values,
|
||||
self.values_specs)
|
||||
@ -742,7 +738,6 @@ class ShowCommand(NeutronCommand, show.ShowOne):
|
||||
self.log.debug('get_data(%s)', parsed_args)
|
||||
self.set_extra_attrs(parsed_args)
|
||||
neutron_client = self.get_client()
|
||||
neutron_client.format = parsed_args.request_format
|
||||
|
||||
params = {}
|
||||
if parsed_args.show_details:
|
||||
|
@ -41,7 +41,6 @@ class AddNetworkToDhcpAgent(neutronV20.NeutronCommand):
|
||||
def run(self, parsed_args):
|
||||
self.log.debug('run(%s)' % parsed_args)
|
||||
neutron_client = self.get_client()
|
||||
neutron_client.format = parsed_args.request_format
|
||||
_net_id = neutronV20.find_resourceid_by_name_or_id(
|
||||
neutron_client, 'network', parsed_args.network)
|
||||
neutron_client.add_network_to_dhcp_agent(parsed_args.dhcp_agent,
|
||||
@ -66,7 +65,6 @@ class RemoveNetworkFromDhcpAgent(neutronV20.NeutronCommand):
|
||||
def run(self, parsed_args):
|
||||
self.log.debug('run(%s)' % parsed_args)
|
||||
neutron_client = self.get_client()
|
||||
neutron_client.format = parsed_args.request_format
|
||||
_net_id = neutronV20.find_resourceid_by_name_or_id(
|
||||
neutron_client, 'network', parsed_args.network)
|
||||
neutron_client.remove_network_from_dhcp_agent(
|
||||
@ -139,7 +137,6 @@ class AddRouterToL3Agent(neutronV20.NeutronCommand):
|
||||
def run(self, parsed_args):
|
||||
self.log.debug('run(%s)' % parsed_args)
|
||||
neutron_client = self.get_client()
|
||||
neutron_client.format = parsed_args.request_format
|
||||
_id = neutronV20.find_resourceid_by_name_or_id(
|
||||
neutron_client, 'router', parsed_args.router)
|
||||
neutron_client.add_router_to_l3_agent(parsed_args.l3_agent,
|
||||
@ -164,7 +161,6 @@ class RemoveRouterFromL3Agent(neutronV20.NeutronCommand):
|
||||
def run(self, parsed_args):
|
||||
self.log.debug('run(%s)' % parsed_args)
|
||||
neutron_client = self.get_client()
|
||||
neutron_client.format = parsed_args.request_format
|
||||
_id = neutronV20.find_resourceid_by_name_or_id(
|
||||
neutron_client, 'router', parsed_args.router)
|
||||
neutron_client.remove_router_from_l3_agent(
|
||||
|
@ -120,7 +120,6 @@ class AssociateFlavor(neutronV20.NeutronCommand):
|
||||
|
||||
def run(self, parsed_args):
|
||||
neutron_client = self.get_client()
|
||||
neutron_client.format = parsed_args.request_format
|
||||
flavor_id = neutronV20.find_resourceid_by_name_or_id(
|
||||
neutron_client, 'flavor', parsed_args.flavor)
|
||||
service_profile_id = neutronV20.find_resourceid_by_id(
|
||||
@ -154,7 +153,6 @@ class DisassociateFlavor(neutronV20.NeutronCommand):
|
||||
|
||||
def run(self, parsed_args):
|
||||
neutron_client = self.get_client()
|
||||
neutron_client.format = parsed_args.request_format
|
||||
flavor_id = neutronV20.find_resourceid_by_name_or_id(
|
||||
neutron_client, 'flavor', parsed_args.flavor)
|
||||
service_profile_id = neutronV20.find_resourceid_by_id(
|
||||
|
@ -114,7 +114,6 @@ class AssociateFloatingIP(neutronV20.NeutronCommand):
|
||||
def run(self, parsed_args):
|
||||
self.log.debug('run(%s)' % parsed_args)
|
||||
neutron_client = self.get_client()
|
||||
neutron_client.format = parsed_args.request_format
|
||||
update_dict = {}
|
||||
neutronV20.update_dict(parsed_args, update_dict,
|
||||
['port_id', 'fixed_ip_address'])
|
||||
@ -141,7 +140,6 @@ class DisassociateFloatingIP(neutronV20.NeutronCommand):
|
||||
def run(self, parsed_args):
|
||||
self.log.debug('run(%s)' % parsed_args)
|
||||
neutron_client = self.get_client()
|
||||
neutron_client.format = parsed_args.request_format
|
||||
neutron_client.update_floatingip(parsed_args.floatingip_id,
|
||||
{'floatingip': {'port_id': None}})
|
||||
print(_('Disassociated floating IP %s') % parsed_args.floatingip_id,
|
||||
|
@ -170,7 +170,6 @@ class FirewallPolicyInsertRule(neutronv20.UpdateCommand):
|
||||
|
||||
def run(self, parsed_args):
|
||||
neutron_client = self.get_client()
|
||||
neutron_client.format = parsed_args.request_format
|
||||
body = self.args2body(parsed_args)
|
||||
_id = neutronv20.find_resourceid_by_name_or_id(neutron_client,
|
||||
self.resource,
|
||||
@ -209,7 +208,6 @@ class FirewallPolicyRemoveRule(neutronv20.UpdateCommand):
|
||||
|
||||
def run(self, parsed_args):
|
||||
neutron_client = self.get_client()
|
||||
neutron_client.format = parsed_args.request_format
|
||||
body = self.args2body(parsed_args)
|
||||
_id = neutronv20.find_resourceid_by_name_or_id(neutron_client,
|
||||
self.resource,
|
||||
|
@ -126,7 +126,6 @@ class AssociateHealthMonitor(neutronV20.NeutronCommand):
|
||||
|
||||
def run(self, parsed_args):
|
||||
neutron_client = self.get_client()
|
||||
neutron_client.format = parsed_args.request_format
|
||||
body = {'health_monitor': {'id': parsed_args.health_monitor_id}}
|
||||
pool_id = neutronV20.find_resourceid_by_name_or_id(
|
||||
neutron_client, 'pool', parsed_args.pool_id)
|
||||
@ -153,7 +152,6 @@ class DisassociateHealthMonitor(neutronV20.NeutronCommand):
|
||||
|
||||
def run(self, parsed_args):
|
||||
neutron_client = self.get_client()
|
||||
neutron_client.format = parsed_args.request_format
|
||||
pool_id = neutronV20.find_resourceid_by_name_or_id(
|
||||
neutron_client, 'pool', parsed_args.pool_id)
|
||||
neutron_client.disassociate_health_monitor(pool_id,
|
||||
|
@ -110,7 +110,6 @@ class RetrievePoolStats(neutronV20.ShowCommand):
|
||||
def get_data(self, parsed_args):
|
||||
self.log.debug('run(%s)' % parsed_args)
|
||||
neutron_client = self.get_client()
|
||||
neutron_client.format = parsed_args.request_format
|
||||
pool_id = neutronV20.find_resourceid_by_name_or_id(
|
||||
self.get_client(), 'pool', parsed_args.id)
|
||||
params = {}
|
||||
|
@ -101,7 +101,6 @@ class CreateMeteringLabelRule(neutronv20.CreateCommand):
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
neutron_client = self.get_client()
|
||||
neutron_client.format = parsed_args.request_format
|
||||
label_id = neutronv20.find_resourceid_by_name_or_id(
|
||||
neutron_client, 'metering_label', parsed_args.label_id)
|
||||
|
||||
|
@ -237,7 +237,6 @@ class ConnectNetworkGateway(NetworkGatewayInterfaceCommand):
|
||||
def run(self, parsed_args):
|
||||
self.log.debug('run(%s)' % parsed_args)
|
||||
neutron_client = self.get_client()
|
||||
neutron_client.format = parsed_args.request_format
|
||||
(gateway_id, network_id) = self.retrieve_ids(neutron_client,
|
||||
parsed_args)
|
||||
neutron_client.connect_network_gateway(
|
||||
@ -256,7 +255,6 @@ class DisconnectNetworkGateway(NetworkGatewayInterfaceCommand):
|
||||
def run(self, parsed_args):
|
||||
self.log.debug('run(%s)' % parsed_args)
|
||||
neutron_client = self.get_client()
|
||||
neutron_client.format = parsed_args.request_format
|
||||
(gateway_id, network_id) = self.retrieve_ids(neutron_client,
|
||||
parsed_args)
|
||||
neutron_client.disconnect_network_gateway(
|
||||
|
@ -113,7 +113,6 @@ class ListRouterPort(neutronV20.ListCommand):
|
||||
|
||||
def get_data(self, parsed_args):
|
||||
neutron_client = self.get_client()
|
||||
neutron_client.format = parsed_args.request_format
|
||||
_id = neutronV20.find_resourceid_by_name_or_id(
|
||||
neutron_client, 'router', parsed_args.id)
|
||||
self.values_specs.append('--device_id=%s' % _id)
|
||||
|
@ -53,7 +53,6 @@ class DeleteQuota(neutronV20.NeutronCommand):
|
||||
def run(self, parsed_args):
|
||||
self.log.debug('run(%s)' % parsed_args)
|
||||
neutron_client = self.get_client()
|
||||
neutron_client.format = parsed_args.request_format
|
||||
tenant_id = get_tenant_id(parsed_args.tenant_id,
|
||||
neutron_client)
|
||||
obj_deleter = getattr(neutron_client,
|
||||
@ -81,7 +80,6 @@ class ListQuota(neutronV20.NeutronCommand, lister.Lister):
|
||||
neutron_client = self.get_client()
|
||||
search_opts = {}
|
||||
self.log.debug('search options: %s', search_opts)
|
||||
neutron_client.format = parsed_args.request_format
|
||||
obj_lister = getattr(neutron_client,
|
||||
"list_%ss" % self.resource)
|
||||
data = obj_lister(**search_opts)
|
||||
@ -114,7 +112,6 @@ class ShowQuota(neutronV20.NeutronCommand, show.ShowOne):
|
||||
def get_data(self, parsed_args):
|
||||
self.log.debug('get_data(%s)', parsed_args)
|
||||
neutron_client = self.get_client()
|
||||
neutron_client.format = parsed_args.request_format
|
||||
tenant_id = get_tenant_id(parsed_args.tenant_id,
|
||||
neutron_client)
|
||||
params = {}
|
||||
@ -212,7 +209,6 @@ class UpdateQuota(neutronV20.NeutronCommand, show.ShowOne):
|
||||
def get_data(self, parsed_args):
|
||||
self.log.debug('run(%s)', parsed_args)
|
||||
neutron_client = self.get_client()
|
||||
neutron_client.format = parsed_args.request_format
|
||||
_extra_values = neutronV20.parse_args_to_dict(self.values_specs)
|
||||
neutronV20._merge_args(self, parsed_args, _extra_values,
|
||||
self.values_specs)
|
||||
|
@ -67,7 +67,6 @@ class CreateRBACPolicy(neutronV20.CreateCommand):
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
neutron_client = self.get_client()
|
||||
neutron_client.format = parsed_args.request_format
|
||||
_object_id = get_rbac_object_id(neutron_client, parsed_args.type,
|
||||
parsed_args.name)
|
||||
body = {
|
||||
|
@ -160,7 +160,6 @@ class RouterInterfaceCommand(neutronV20.NeutronCommand):
|
||||
def run(self, parsed_args):
|
||||
self.log.debug('run(%s)' % parsed_args)
|
||||
neutron_client = self.get_client()
|
||||
neutron_client.format = parsed_args.request_format
|
||||
|
||||
if '=' in parsed_args.interface:
|
||||
resource, value = parsed_args.interface.split('=', 1)
|
||||
@ -232,7 +231,6 @@ class SetGatewayRouter(neutronV20.NeutronCommand):
|
||||
def run(self, parsed_args):
|
||||
self.log.debug('run(%s)' % parsed_args)
|
||||
neutron_client = self.get_client()
|
||||
neutron_client.format = parsed_args.request_format
|
||||
_router_id = neutronV20.find_resourceid_by_name_or_id(
|
||||
neutron_client, self.resource, parsed_args.router)
|
||||
_ext_net_id = neutronV20.find_resourceid_by_name_or_id(
|
||||
@ -272,7 +270,6 @@ class RemoveGatewayRouter(neutronV20.NeutronCommand):
|
||||
def run(self, parsed_args):
|
||||
self.log.debug('run(%s)' % parsed_args)
|
||||
neutron_client = self.get_client()
|
||||
neutron_client.format = parsed_args.request_format
|
||||
_router_id = neutronV20.find_resourceid_by_name_or_id(
|
||||
neutron_client, self.resource, parsed_args.router)
|
||||
neutron_client.remove_gateway_router(_router_id)
|
||||
|
@ -161,7 +161,3 @@ class CLITestV20FirewallJSON(test_cli20.CLITestV20Base):
|
||||
my_id = 'my-id'
|
||||
args = [my_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args)
|
||||
|
||||
|
||||
class CLITestV20FirewallXML(CLITestV20FirewallJSON):
|
||||
format = 'xml'
|
||||
|
@ -182,7 +182,6 @@ class CLITestV20FirewallPolicyJSON(test_cli20.CLITestV20Base):
|
||||
headers=mox.ContainsKeyValue(
|
||||
'X-Auth-Token',
|
||||
test_cli20.TOKEN)).AndReturn((test_cli20.MyResp(204), None))
|
||||
args.extend(['--request-format', self.format])
|
||||
self.mox.ReplayAll()
|
||||
cmd_parser = cmd.get_parser(resource + "_insert_rule")
|
||||
shell.run_command(cmd, cmd_parser, args)
|
||||
@ -213,13 +212,8 @@ class CLITestV20FirewallPolicyJSON(test_cli20.CLITestV20Base):
|
||||
headers=mox.ContainsKeyValue(
|
||||
'X-Auth-Token',
|
||||
test_cli20.TOKEN)).AndReturn((test_cli20.MyResp(204), None))
|
||||
args.extend(['--request-format', self.format])
|
||||
self.mox.ReplayAll()
|
||||
cmd_parser = cmd.get_parser(resource + "_remove_rule")
|
||||
shell.run_command(cmd, cmd_parser, args)
|
||||
self.mox.VerifyAll()
|
||||
self.mox.UnsetStubs()
|
||||
|
||||
|
||||
class CLITestV20FirewallPolicyXML(CLITestV20FirewallPolicyJSON):
|
||||
format = 'xml'
|
||||
|
@ -178,7 +178,3 @@ class CLITestV20FirewallRuleJSON(test_cli20.CLITestV20Base):
|
||||
my_id = 'myid1'
|
||||
args = [my_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args)
|
||||
|
||||
|
||||
class CLITestV20FirewallRuleXML(CLITestV20FirewallRuleJSON):
|
||||
format = 'xml'
|
||||
|
@ -201,7 +201,3 @@ class CLITestV20LbHealthmonitorJSON(test_cli20.CLITestV20Base):
|
||||
cmd.run(parsed_args)
|
||||
self.mox.VerifyAll()
|
||||
self.mox.UnsetStubs()
|
||||
|
||||
|
||||
class CLITestV20LbHealthmonitorXML(CLITestV20LbHealthmonitorJSON):
|
||||
format = 'xml'
|
||||
|
@ -117,7 +117,3 @@ class CLITestV20LbMemberJSON(test_cli20.CLITestV20Base):
|
||||
my_id = 'my-id'
|
||||
args = [my_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args)
|
||||
|
||||
|
||||
class CLITestV20LbMemberXML(CLITestV20LbMemberJSON):
|
||||
format = 'xml'
|
||||
|
@ -164,7 +164,3 @@ class CLITestV20LbPoolJSON(test_cli20.CLITestV20Base):
|
||||
_str = self.fake_stdout.make_string()
|
||||
self.assertIn('bytes_in', _str)
|
||||
self.assertIn('bytes_out', _str)
|
||||
|
||||
|
||||
class CLITestV20LbPoolXML(CLITestV20LbPoolJSON):
|
||||
format = 'xml'
|
||||
|
@ -205,7 +205,3 @@ class CLITestV20LbVipJSON(test_cli20.CLITestV20Base):
|
||||
my_id = 'my-id'
|
||||
args = [my_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args)
|
||||
|
||||
|
||||
class CLITestV20LbVipXML(CLITestV20LbVipJSON):
|
||||
format = 'xml'
|
||||
|
@ -148,7 +148,3 @@ class CLITestV20LbHealthMonitorJSON(test_cli20.CLITestV20Base):
|
||||
args = [my_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args,
|
||||
cmd_resource=cmd_resource)
|
||||
|
||||
|
||||
class CLITestV20LbHealthMonitorXML(CLITestV20LbHealthMonitorJSON):
|
||||
format = 'xml'
|
||||
|
@ -134,7 +134,3 @@ class CLITestV20LbListenerJSON(test_cli20.CLITestV20Base):
|
||||
args = [my_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args,
|
||||
cmd_resource=cmd_resource)
|
||||
|
||||
|
||||
class CLITestV20LbListenerXML(CLITestV20LbListenerJSON):
|
||||
format = 'xml'
|
||||
|
@ -130,7 +130,3 @@ class CLITestV20LbLoadBalancerJSON(test_cli20.CLITestV20Base):
|
||||
args = [my_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args,
|
||||
cmd_resource=cmd_resource)
|
||||
|
||||
|
||||
class CLITestV20LbLoadBalancerXML(CLITestV20LbLoadBalancerJSON):
|
||||
format = 'xml'
|
||||
|
@ -155,7 +155,3 @@ class CLITestV20LbMemberJSON(test_cli20.CLITestV20Base):
|
||||
self._test_delete_resource(resource, cmd, my_id, args,
|
||||
cmd_resource=cmd_resource,
|
||||
parent_id=pool_id)
|
||||
|
||||
|
||||
class CLITestV20LbMemberXML(CLITestV20LbMemberJSON):
|
||||
format = 'xml'
|
||||
|
@ -137,7 +137,3 @@ class CLITestV20LbPoolJSON(test_cli20.CLITestV20Base):
|
||||
args = [my_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args,
|
||||
cmd_resource=cmd_resource)
|
||||
|
||||
|
||||
class CLITestV20LbPoolXML(CLITestV20LbPoolJSON):
|
||||
format = 'xml'
|
||||
|
@ -190,10 +190,7 @@ class CLITestV20Base(base.BaseTestCase):
|
||||
client.Client.EXTED_PLURALS.update(constants.PLURALS)
|
||||
if plurals is not None:
|
||||
client.Client.EXTED_PLURALS.update(plurals)
|
||||
self.metadata = {'plurals': client.Client.EXTED_PLURALS,
|
||||
'xmlns': constants.XML_NS_V20,
|
||||
constants.EXT_NS: {'prefix':
|
||||
'http://xxxx.yy.com'}}
|
||||
self.metadata = {'plurals': client.Client.EXTED_PLURALS}
|
||||
self.mox = mox.Mox()
|
||||
self.endurl = ENDURL
|
||||
self.fake_stdout = FakeStdout()
|
||||
@ -208,6 +205,7 @@ class CLITestV20Base(base.BaseTestCase):
|
||||
'neutronclient.v2_0.client.Client.get_attr_metadata',
|
||||
self._get_attr_metadata))
|
||||
self.client = client.Client(token=TOKEN, endpoint_url=self.endurl)
|
||||
self.client.format = self.format
|
||||
|
||||
def register_non_admin_status_resource(self, resource_name):
|
||||
# TODO(amotoki):
|
||||
@ -254,7 +252,6 @@ class CLITestV20Base(base.BaseTestCase):
|
||||
{self.id_field: myid}, }
|
||||
if name:
|
||||
ress[resource].update({'name': name})
|
||||
self.client.format = self.format
|
||||
resstr = self.client.serialize(ress)
|
||||
# url method body
|
||||
resource_plural = neutronV2_0._get_resource_plural(cmd_resource,
|
||||
@ -262,19 +259,14 @@ class CLITestV20Base(base.BaseTestCase):
|
||||
path = getattr(self.client, resource_plural + "_path")
|
||||
if parent_id:
|
||||
path = path % parent_id
|
||||
# Work around for LP #1217791. XML deserializer called from
|
||||
# MyComparator does not decodes XML string correctly.
|
||||
if self.format == 'json':
|
||||
mox_body = MyComparator(body, self.client)
|
||||
else:
|
||||
mox_body = self.client.serialize(body)
|
||||
|
||||
if not no_api_call:
|
||||
self.client.httpclient.request(
|
||||
end_url(path, format=self.format), 'POST',
|
||||
body=mox_body,
|
||||
headers=mox.ContainsKeyValue(
|
||||
'X-Auth-Token', TOKEN)).AndReturn((MyResp(200), resstr))
|
||||
args.extend(['--request-format', self.format])
|
||||
self.mox.ReplayAll()
|
||||
cmd_parser = cmd.get_parser('create_' + resource)
|
||||
if expected_exception:
|
||||
@ -295,7 +287,6 @@ class CLITestV20Base(base.BaseTestCase):
|
||||
self.mox.StubOutWithMock(cmd, "get_client")
|
||||
self.mox.StubOutWithMock(self.client.httpclient, "request")
|
||||
cmd.get_client().MultipleTimes().AndReturn(self.client)
|
||||
self.client.format = self.format
|
||||
if not cmd_resources:
|
||||
cmd_resources = resources
|
||||
|
||||
@ -309,7 +300,6 @@ class CLITestV20Base(base.BaseTestCase):
|
||||
body=None,
|
||||
headers=mox.ContainsKeyValue(
|
||||
'X-Auth-Token', TOKEN)).AndReturn((MyResp(200), resstr))
|
||||
args = tuple(args) + ('--request-format', self.format)
|
||||
self.mox.ReplayAll()
|
||||
cmd_parser = cmd.get_parser("list_" + cmd_resources)
|
||||
shell.run_command(cmd, cmd_parser, args)
|
||||
@ -332,13 +322,11 @@ class CLITestV20Base(base.BaseTestCase):
|
||||
else:
|
||||
contents = response_contents
|
||||
reses = {resources: contents}
|
||||
self.client.format = self.format
|
||||
resstr = self.client.serialize(reses)
|
||||
# url method body
|
||||
args = base_args if base_args is not None else []
|
||||
if detail:
|
||||
args.append('-D')
|
||||
args.extend(['--request-format', self.format])
|
||||
if fields_1:
|
||||
for field in fields_1:
|
||||
args.append('--fields')
|
||||
@ -438,7 +426,6 @@ class CLITestV20Base(base.BaseTestCase):
|
||||
'rel': 'next'}]}
|
||||
reses2 = {resources: [{'id': 'myid3', },
|
||||
{'id': 'myid4', }]}
|
||||
self.client.format = self.format
|
||||
resstr1 = self.client.serialize(reses1)
|
||||
resstr2 = self.client.serialize(reses2)
|
||||
self.client.httpclient.request(
|
||||
@ -455,7 +442,6 @@ class CLITestV20Base(base.BaseTestCase):
|
||||
self.mox.ReplayAll()
|
||||
cmd_parser = cmd.get_parser("list_" + cmd_resources)
|
||||
args = base_args if base_args is not None else []
|
||||
args.extend(['--request-format', self.format])
|
||||
shell.run_command(cmd, cmd_parser, args)
|
||||
self.mox.VerifyAll()
|
||||
self.mox.UnsetStubs()
|
||||
@ -474,13 +460,8 @@ class CLITestV20Base(base.BaseTestCase):
|
||||
path = path % (parent_id, myid)
|
||||
else:
|
||||
path = path % myid
|
||||
self.client.format = self.format
|
||||
# Work around for LP #1217791. XML deserializer called from
|
||||
# MyComparator does not decodes XML string correctly.
|
||||
if self.format == 'json':
|
||||
mox_body = MyComparator(body, self.client)
|
||||
else:
|
||||
mox_body = self.client.serialize(body)
|
||||
|
||||
self.client.httpclient.request(
|
||||
MyUrlComparator(end_url(path, format=self.format),
|
||||
self.client),
|
||||
@ -488,7 +469,6 @@ class CLITestV20Base(base.BaseTestCase):
|
||||
body=mox_body,
|
||||
headers=mox.ContainsKeyValue(
|
||||
'X-Auth-Token', TOKEN)).AndReturn((MyResp(204), None))
|
||||
args.extend(['--request-format', self.format])
|
||||
self.mox.ReplayAll()
|
||||
cmd_parser = cmd.get_parser("update_" + cmd_resource)
|
||||
shell.run_command(cmd, cmd_parser, args)
|
||||
@ -509,7 +489,6 @@ class CLITestV20Base(base.BaseTestCase):
|
||||
expected_res = {resource:
|
||||
{self.id_field: myid,
|
||||
'name': 'myname', }, }
|
||||
self.client.format = self.format
|
||||
resstr = self.client.serialize(expected_res)
|
||||
path = getattr(self.client, cmd_resource + "_path")
|
||||
if parent_id:
|
||||
@ -521,7 +500,6 @@ class CLITestV20Base(base.BaseTestCase):
|
||||
body=None,
|
||||
headers=mox.ContainsKeyValue(
|
||||
'X-Auth-Token', TOKEN)).AndReturn((MyResp(200), resstr))
|
||||
args.extend(['--request-format', self.format])
|
||||
self.mox.ReplayAll()
|
||||
cmd_parser = cmd.get_parser("show_" + cmd_resource)
|
||||
shell.run_command(cmd, cmd_parser, args)
|
||||
@ -548,7 +526,6 @@ class CLITestV20Base(base.BaseTestCase):
|
||||
body=None,
|
||||
headers=mox.ContainsKeyValue(
|
||||
'X-Auth-Token', TOKEN)).AndReturn((MyResp(204), None))
|
||||
args.extend(['--request-format', self.format])
|
||||
self.mox.ReplayAll()
|
||||
cmd_parser = cmd.get_parser("delete_" + cmd_resource)
|
||||
shell.run_command(cmd, cmd_parser, args)
|
||||
@ -571,7 +548,6 @@ class CLITestV20Base(base.BaseTestCase):
|
||||
body=MyComparator(body, self.client),
|
||||
headers=mox.ContainsKeyValue(
|
||||
'X-Auth-Token', TOKEN)).AndReturn((MyResp(204), retval))
|
||||
args.extend(['--request-format', self.format])
|
||||
self.mox.ReplayAll()
|
||||
cmd_parser = cmd.get_parser("delete_" + cmd_resource)
|
||||
shell.run_command(cmd, cmd_parser, args)
|
||||
@ -583,7 +559,6 @@ class CLITestV20Base(base.BaseTestCase):
|
||||
|
||||
class ClientV2TestJson(CLITestV20Base):
|
||||
def test_do_request_unicode(self):
|
||||
self.client.format = self.format
|
||||
self.mox.StubOutWithMock(self.client.httpclient, "request")
|
||||
unicode_text = u'\u7f51\u7edc'
|
||||
# url with unicode
|
||||
@ -616,7 +591,6 @@ class ClientV2TestJson(CLITestV20Base):
|
||||
self.assertEqual(body, res_body)
|
||||
|
||||
def test_do_request_error_without_response_body(self):
|
||||
self.client.format = self.format
|
||||
self.mox.StubOutWithMock(self.client.httpclient, "request")
|
||||
params = {'test': 'value'}
|
||||
expect_query = six.moves.urllib.parse.urlencode(params)
|
||||
@ -649,10 +623,6 @@ class ClientV2TestJson(CLITestV20Base):
|
||||
self.fail('Expected exception NOT raised')
|
||||
|
||||
|
||||
class ClientV2UnicodeTestXML(ClientV2TestJson):
|
||||
format = 'xml'
|
||||
|
||||
|
||||
class CLITestV20ExceptionHandler(CLITestV20Base):
|
||||
|
||||
def _test_exception_handler_v20(
|
||||
|
@ -206,7 +206,3 @@ class CLITestV20LBaaSV2AgentScheduler(test_cli20.CLITestV20Base):
|
||||
contents = {self.id_field: 'myid1', 'alive': True}
|
||||
self._test_list_resources(resources, cmd, base_args=[lb_id],
|
||||
path=path, response_contents=contents)
|
||||
|
||||
|
||||
class CLITestV20LBaaSAgentSchedulerXML(CLITestV20LBaaSAgentScheduler):
|
||||
format = 'xml'
|
||||
|
@ -177,7 +177,3 @@ class CLITestV20FloatingIpsJSON(test_cli20.CLITestV20Base):
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
args, {"port_id": "portid"}
|
||||
)
|
||||
|
||||
|
||||
class CLITestV20FloatingIpsXML(CLITestV20FloatingIpsJSON):
|
||||
format = 'xml'
|
||||
|
@ -97,7 +97,3 @@ class CLITestV20MeteringJSON(test_cli20.CLITestV20Base):
|
||||
args = ['--fields', 'id', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id,
|
||||
args, ['id'])
|
||||
|
||||
|
||||
class CLITestV20MeteringXML(CLITestV20MeteringJSON):
|
||||
format = 'xml'
|
||||
|
@ -600,7 +600,3 @@ class CLITestV20NetworkJSON(test_cli20.CLITestV20Base):
|
||||
'X-Auth-Token', test_cli20.TOKEN)).AndReturn(response)
|
||||
|
||||
self._test_extend_list(mox_calls)
|
||||
|
||||
|
||||
class CLITestV20NetworkXML(CLITestV20NetworkJSON):
|
||||
format = 'xml'
|
||||
|
@ -261,7 +261,3 @@ class CLITestV20NetworkGatewayJSON(test_cli20.CLITestV20Base):
|
||||
args = ['--fields', 'id', '--fields', 'name', self.test_id]
|
||||
self._test_show_resource(self.dev_resource, cmd, self.test_id, args,
|
||||
['id', 'name'])
|
||||
|
||||
|
||||
class CLITestV20NetworkGatewayXML(CLITestV20NetworkGatewayJSON):
|
||||
format = 'xml'
|
||||
|
@ -83,7 +83,3 @@ class CLITestV20QosQueueJSON(test_cli20.CLITestV20Base):
|
||||
myid = 'myid'
|
||||
args = [myid]
|
||||
self._test_delete_resource(resource, cmd, myid, args)
|
||||
|
||||
|
||||
class CLITestV20QosQueueXML(CLITestV20QosQueueJSON):
|
||||
format = 'xml'
|
||||
|
@ -53,7 +53,3 @@ class CLITestV20NetPartitionJSON(test_cli20.CLITestV20Base):
|
||||
myid = 'myid'
|
||||
args = [myid]
|
||||
self._test_delete_resource(self.resource, cmd, myid, args)
|
||||
|
||||
|
||||
class CLITestV20NetPartitionXML(CLITestV20NetPartitionJSON):
|
||||
format = 'xml'
|
||||
|
@ -731,7 +731,3 @@ class CLITestV20PortJSON(test_cli20.CLITestV20Base):
|
||||
myid = 'myid'
|
||||
args = [myid]
|
||||
self._test_delete_resource(resource, cmd, myid, args)
|
||||
|
||||
|
||||
class CLITestV20PortXML(CLITestV20PortJSON):
|
||||
format = 'xml'
|
||||
|
@ -382,7 +382,3 @@ class CLITestV20RouterJSON(test_cli20.CLITestV20Base):
|
||||
self._test_update_resource(resource, cmd, 'externalid',
|
||||
args, {"external_gateway_info": {}}
|
||||
)
|
||||
|
||||
|
||||
class CLITestV20RouterXML(CLITestV20RouterJSON):
|
||||
format = 'xml'
|
||||
|
@ -609,7 +609,3 @@ class CLITestV20SecurityGroupsJSON(test_cli20.CLITestV20Base):
|
||||
]
|
||||
expected = '\n'.join(sorted(expected_data))
|
||||
self.assertEqual(expected, securitygroup._format_sg_rules(sg))
|
||||
|
||||
|
||||
class CLITestV20SecurityGroupsXML(CLITestV20SecurityGroupsJSON):
|
||||
format = 'xml'
|
||||
|
@ -53,7 +53,3 @@ class CLITestV20ServiceProvidersJSON(test_cli20.CLITestV20Base):
|
||||
cmd = servicetype.ListServiceProvider(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_list_resources(resources, cmd, page_size=1000)
|
||||
|
||||
|
||||
class CLITestV20ServiceProvidersXML(CLITestV20ServiceProvidersJSON):
|
||||
format = 'xml'
|
||||
|
@ -574,12 +574,6 @@ class CLITestV20SubnetJSON(test_cli20.CLITestV20Base):
|
||||
cmd = subnet.ListSubnet(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, tags=['a', 'b'])
|
||||
|
||||
def test_list_subnets_known_option_after_unknown(self):
|
||||
"""List subnets: -- --tags a b --request-format xml."""
|
||||
resources = "subnets"
|
||||
cmd = subnet.ListSubnet(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, tags=['a', 'b'])
|
||||
|
||||
def test_list_subnets_detail_tags(self):
|
||||
"""List subnets: -D -- --tags a b."""
|
||||
resources = "subnets"
|
||||
@ -624,36 +618,13 @@ class CLITestV20SubnetJSON(test_cli20.CLITestV20Base):
|
||||
{'name': 'myname', 'tags': ['a', 'b'], }
|
||||
)
|
||||
|
||||
def test_update_subnet_known_option_before_id(self):
|
||||
"""Update subnet: --request-format json myid --name myname."""
|
||||
# --request-format xml is known option
|
||||
resource = 'subnet'
|
||||
cmd = subnet.UpdateSubnet(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['--request-format', 'json',
|
||||
'myid', '--name', 'myname'],
|
||||
{'name': 'myname', }
|
||||
)
|
||||
|
||||
def test_update_subnet_known_option_after_id(self):
|
||||
"""Update subnet: myid --name myname --request-format json."""
|
||||
# --request-format xml is known option
|
||||
resource = 'subnet'
|
||||
cmd = subnet.UpdateSubnet(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['myid', '--name', 'myname',
|
||||
'--request-format', 'json'],
|
||||
{'name': 'myname', }
|
||||
)
|
||||
|
||||
def test_update_subnet_allocation_pools(self):
|
||||
"""Update subnet: myid --name myname --tags a b."""
|
||||
resource = 'subnet'
|
||||
cmd = subnet.UpdateSubnet(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['myid', '--allocation-pool',
|
||||
'start=1.2.0.2,end=1.2.0.127',
|
||||
'--request-format', 'json'],
|
||||
'start=1.2.0.2,end=1.2.0.127'],
|
||||
{'allocation_pools': [{'start': '1.2.0.2',
|
||||
'end': '1.2.0.127'}]}
|
||||
)
|
||||
@ -687,7 +658,3 @@ class CLITestV20SubnetJSON(test_cli20.CLITestV20Base):
|
||||
myid = 'myid'
|
||||
args = [myid]
|
||||
self._test_delete_resource(resource, cmd, myid, args)
|
||||
|
||||
|
||||
class CLITestV20SubnetXML(CLITestV20SubnetJSON):
|
||||
format = 'xml'
|
||||
|
@ -59,17 +59,17 @@ class TestHTTPClientMixin(object):
|
||||
self._test_headers(headers, body=BODY)
|
||||
|
||||
def test_headers_without_body_with_content_type(self):
|
||||
headers = {'Accept': 'application/xml'}
|
||||
self._test_headers(headers, content_type='application/xml')
|
||||
headers = {'Accept': 'application/json'}
|
||||
self._test_headers(headers, content_type='application/json')
|
||||
|
||||
def test_headers_with_body_with_content_type(self):
|
||||
headers = {'Accept': 'application/xml',
|
||||
'Content-Type': 'application/xml'}
|
||||
self._test_headers(headers, body=BODY, content_type='application/xml')
|
||||
headers = {'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'}
|
||||
self._test_headers(headers, body=BODY, content_type='application/json')
|
||||
|
||||
def test_headers_defined_in_headers(self):
|
||||
headers = {'Accept': 'application/xml',
|
||||
'Content-Type': 'application/xml'}
|
||||
headers = {'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'}
|
||||
self._test_headers(headers, body=BODY, headers=headers)
|
||||
|
||||
|
||||
|
@ -207,7 +207,3 @@ class CLITestV20VpnIkePolicyJSON(test_cli20.CLITestV20Base):
|
||||
my_id = 'my-id'
|
||||
args = [my_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args)
|
||||
|
||||
|
||||
class CLITestV20VpnIkePolicyXML(CLITestV20VpnIkePolicyJSON):
|
||||
format = 'xml'
|
||||
|
@ -204,7 +204,3 @@ class CLITestV20VpnIpsecPolicyJSON(test_cli20.CLITestV20Base):
|
||||
my_id = 'my-id'
|
||||
args = [my_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args)
|
||||
|
||||
|
||||
class CLITestV20VpnIpsecPolicyXML(CLITestV20VpnIpsecPolicyJSON):
|
||||
format = 'xml'
|
||||
|
@ -24,7 +24,6 @@ import requests
|
||||
import six.moves.urllib.parse as urlparse
|
||||
|
||||
from neutronclient import client
|
||||
from neutronclient.common import constants
|
||||
from neutronclient.common import exceptions
|
||||
from neutronclient.common import extension as client_extension
|
||||
from neutronclient.common import serializer
|
||||
@ -195,9 +194,7 @@ class ClientBase(object):
|
||||
if body:
|
||||
body = self.serialize(body)
|
||||
|
||||
resp, replybody = self.httpclient.do_request(
|
||||
action, method, body=body,
|
||||
content_type=self.content_type())
|
||||
resp, replybody = self.httpclient.do_request(action, method, body=body)
|
||||
|
||||
status_code = resp.status_code
|
||||
if status_code in (requests.codes.ok,
|
||||
@ -214,7 +211,7 @@ class ClientBase(object):
|
||||
return self.httpclient.get_auth_info()
|
||||
|
||||
def serialize(self, data):
|
||||
"""Serializes a dictionary into either XML or JSON.
|
||||
"""Serializes a dictionary into JSON.
|
||||
|
||||
A dictionary with a single key can be passed and it can contain any
|
||||
structure.
|
||||
@ -222,39 +219,17 @@ class ClientBase(object):
|
||||
if data is None:
|
||||
return None
|
||||
elif type(data) is dict:
|
||||
return serializer.Serializer(
|
||||
self.get_attr_metadata()).serialize(data, self.content_type())
|
||||
return serializer.Serializer().serialize(data)
|
||||
else:
|
||||
raise Exception(_("Unable to serialize object of type = '%s'") %
|
||||
type(data))
|
||||
|
||||
def deserialize(self, data, status_code):
|
||||
"""Deserializes an XML or JSON string into a dictionary."""
|
||||
"""Deserializes a JSON string into a dictionary."""
|
||||
if status_code == 204:
|
||||
return data
|
||||
return serializer.Serializer(self.get_attr_metadata()).deserialize(
|
||||
data, self.content_type())['body']
|
||||
|
||||
def get_attr_metadata(self):
|
||||
if self.format == 'json':
|
||||
return {}
|
||||
old_request_format = self.format
|
||||
self.format = 'json'
|
||||
exts = self.list_extensions()['extensions']
|
||||
self.format = old_request_format
|
||||
ns = dict([(ext['alias'], ext['namespace']) for ext in exts])
|
||||
self.EXTED_PLURALS.update(constants.PLURALS)
|
||||
return {'plurals': self.EXTED_PLURALS,
|
||||
'xmlns': constants.XML_NS_V20,
|
||||
constants.EXT_NS: ns}
|
||||
|
||||
def content_type(self, _format=None):
|
||||
"""Returns the mime-type for either 'xml' or 'json'.
|
||||
|
||||
Defaults to the currently set format.
|
||||
"""
|
||||
_format = _format or self.format
|
||||
return "application/%s" % (_format)
|
||||
return serializer.Serializer().deserialize(
|
||||
data)['body']
|
||||
|
||||
def retry_request(self, method, action, body=None,
|
||||
headers=None, params=None):
|
||||
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
upgrade:
|
||||
- XML request format support has been removed.
|
||||
deprecations:
|
||||
- request-format option is deprecated.
|
Loading…
Reference in New Issue
Block a user