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:
		
							
								
								
									
										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.
 | 
			
		||||
		Reference in New Issue
	
	Block a user