From: Victor Stinner <vstinner@redhat.com>
Date: Tue, 9 Jun 2015 13:37:02 +0000 (+0200)
Subject: Replace urllib and urllib2 with six.moves.urllib
X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=d08c7ffe52e3ee211e425c363200998704726e58;p=openstack-build%2Fcinder-build.git

Replace urllib and urllib2 with six.moves.urllib

The Python 2 urllib and urllib2 modules changed a lot in Python 3. On
Python 3, the urllib functions are now grouped into submodules of
urllib: urllib.parse, urllib.error, etc. The urllib2 has been removed.
Replace urllib and urllib2 with six.moves.urllib to make the Cinder code
compatible with Python 2 and Python 3.

The new code now looks like Python 3 code (ex: "urllib.parse.urlsplit"),
but it also works on Python 2.

Replace also "import six.moves.urllib.parse as urlparse" with "from
six.moves import urllib" to uniformize the code:
"urlparse.urlsplit(href)" becomes "urllib.parse.urlsplit(href)".

This patch was generated by the urllib operation of the sixer tool version 0.4:
https://pypi.python.org/pypi/sixer

Manual changes:

* Add a try/except ImportError to get the parse_http_list function
  in cinder/api/urlmap.py
* Import the socket module instead of using urllib2.socket
  in cinder/volume/drivers/huawei/rest_common.py
* test_nimble.py: replace NIMBLE_URLLIB2 value with
  'six.moves.urllib.request'
* Remove "from six.moves.urllib import parse as urlparse", it was
  replaced with urllib.parse from six.moves.
* Reformat to respect the 80 columns constraint

Change-Id: Ibd1e7bc83bbbd93a3634207fb277d25ef1b8a086
---

diff --git a/cinder/api/common.py b/cinder/api/common.py
index 758df61bd..f3483f095 100644
--- a/cinder/api/common.py
+++ b/cinder/api/common.py
@@ -16,11 +16,10 @@
 
 import os
 import re
-import urllib
 
 from oslo_config import cfg
 from oslo_log import log as logging
-import six.moves.urllib.parse as urlparse
+from six.moves import urllib
 import webob
 
 from cinder.api.openstack import wsgi
@@ -225,7 +224,7 @@ def remove_version_from_href(href):
     Returns: 'http://www.cinder.com'
 
     """
-    parsed_url = urlparse.urlsplit(href)
+    parsed_url = urllib.parse.urlsplit(href)
     url_parts = parsed_url.path.split('/', 2)
 
     # NOTE: this should match vX.X or vX
@@ -242,7 +241,7 @@ def remove_version_from_href(href):
 
     parsed_url = list(parsed_url)
     parsed_url[2] = new_path
-    return urlparse.urlunsplit(parsed_url)
+    return urllib.parse.urlunsplit(parsed_url)
 
 
 class ViewBuilder(object):
@@ -265,7 +264,7 @@ class ViewBuilder(object):
         url = os.path.join(prefix,
                            request.environ["cinder.context"].project_id,
                            collection_name)
-        return "%s?%s" % (url, urllib.urlencode(params))
+        return "%s?%s" % (url, urllib.parse.urlencode(params))
 
     def _get_href_link(self, request, identifier):
         """Return an href string pointing to this object."""
@@ -350,12 +349,12 @@ class ViewBuilder(object):
     def _update_link_prefix(self, orig_url, prefix):
         if not prefix:
             return orig_url
-        url_parts = list(urlparse.urlsplit(orig_url))
-        prefix_parts = list(urlparse.urlsplit(prefix))
+        url_parts = list(urllib.parse.urlsplit(orig_url))
+        prefix_parts = list(urllib.parse.urlsplit(prefix))
         url_parts[0:2] = prefix_parts[0:2]
         url_parts[2] = prefix_parts[2] + url_parts[2]
 
-        return urlparse.urlunsplit(url_parts).rstrip('/')
+        return urllib.parse.urlunsplit(url_parts).rstrip('/')
 
 
 class MetadataDeserializer(wsgi.MetadataXMLDeserializer):
diff --git a/cinder/api/urlmap.py b/cinder/api/urlmap.py
index 7b7971767..0fdf41161 100644
--- a/cinder/api/urlmap.py
+++ b/cinder/api/urlmap.py
@@ -14,10 +14,13 @@
 #    under the License.
 
 import re
-import urllib2
 
 from oslo_log import log as logging
 import paste.urlmap
+try:
+    from urllib.request import parse_http_list   # pylint: disable=E0611
+except ImportError:
+    from urllib2 import parse_http_list   # Python 2
 
 from cinder.api.openstack import wsgi
 
@@ -64,7 +67,7 @@ def parse_list_header(value):
     :return: :class:`list`
     """
     result = []
-    for item in urllib2.parse_http_list(value):
+    for item in parse_http_list(value):
         if item[:1] == item[-1:] == '"':
             item = unquote_header_value(item[1:-1])
         result.append(item)
diff --git a/cinder/image/glance.py b/cinder/image/glance.py
index ecc3314c6..42de65d77 100644
--- a/cinder/image/glance.py
+++ b/cinder/image/glance.py
@@ -31,7 +31,7 @@ from oslo_config import cfg
 from oslo_log import log as logging
 from oslo_serialization import jsonutils
 from oslo_utils import timeutils
-import six.moves.urllib.parse as urlparse
+from six.moves import urllib
 
 from cinder import exception
 from cinder.i18n import _LE, _LW
@@ -67,7 +67,7 @@ def _parse_image_ref(image_href):
     :raises ValueError
 
     """
-    url = urlparse.urlparse(image_href)
+    url = urllib.parse.urlparse(image_href)
     netloc = url.netloc
     image_id = url.path.split('/')[-1]
     use_ssl = (url.scheme == 'https')
@@ -106,7 +106,7 @@ def get_api_servers():
     for api_server in CONF.glance_api_servers:
         if '//' not in api_server:
             api_server = 'http://' + api_server
-        url = urlparse.urlparse(api_server)
+        url = urllib.parse.urlparse(api_server)
         netloc = url.netloc
         use_ssl = (url.scheme == 'https')
         api_servers.append((netloc, use_ssl))
@@ -273,7 +273,7 @@ class GlanceImageService(object):
             for url in urls:
                 if url is None:
                     continue
-                parsed_url = urlparse.urlparse(url)
+                parsed_url = urllib.parse.urlparse(url)
                 if parsed_url.scheme == "file":
                     # a system call to cp could have significant performance
                     # advantages, however we do not have the path to files at
diff --git a/cinder/openstack/common/policy.py b/cinder/openstack/common/policy.py
index 871e7c226..47517fa4f 100644
--- a/cinder/openstack/common/policy.py
+++ b/cinder/openstack/common/policy.py
@@ -98,7 +98,7 @@ import re
 from oslo_config import cfg
 from oslo_serialization import jsonutils
 import six
-import six.moves.urllib.parse as urlparse
+from six.moves import urllib
 import six.moves.urllib.request as urlrequest
 
 from cinder.openstack.common import fileutils
@@ -924,7 +924,7 @@ class HttpCheck(Check):
 
         data = {'target': jsonutils.dumps(temp_target),
                 'credentials': jsonutils.dumps(creds)}
-        post_data = urlparse.urlencode(data)
+        post_data = urllib.parse.urlencode(data)
         f = urlrequest.urlopen(url, post_data)
         return f.read() == "True"
 
diff --git a/cinder/tests/unit/api/v2/test_volumes.py b/cinder/tests/unit/api/v2/test_volumes.py
index 8f7cfc48d..941300667 100644
--- a/cinder/tests/unit/api/v2/test_volumes.py
+++ b/cinder/tests/unit/api/v2/test_volumes.py
@@ -21,7 +21,7 @@ import mock
 from oslo_config import cfg
 from oslo_utils import timeutils
 import six
-import six.moves.urllib.parse as urlparse
+from six.moves import urllib
 import webob
 
 from cinder.api import extensions
@@ -932,9 +932,9 @@ class VolumeApiTest(test.TestCase):
         # need to manually insert the limit and sort information.
         links = res_dict['volumes_links']
         self.assertEqual(links[0]['rel'], 'next')
-        href_parts = urlparse.urlparse(links[0]['href'])
+        href_parts = urllib.parse.urlparse(links[0]['href'])
         self.assertEqual('/v2/fakeproject/volumes', href_parts.path)
-        params = urlparse.parse_qs(href_parts.query)
+        params = urllib.parse.parse_qs(href_parts.query)
         self.assertEqual(str(volumes[0]['id']), params['marker'][0])
         self.assertEqual('1', params['limit'][0])
         self.assertEqual('foo', params['name'][0])
@@ -1025,9 +1025,9 @@ class VolumeApiTest(test.TestCase):
         # Ensure that the next link is correctly formatted
         links = res_dict['volumes_links']
         self.assertEqual(links[0]['rel'], 'next')
-        href_parts = urlparse.urlparse(links[0]['href'])
+        href_parts = urllib.parse.urlparse(links[0]['href'])
         self.assertEqual('/v2/fakeproject/volumes/detail', href_parts.path)
-        params = urlparse.parse_qs(href_parts.query)
+        params = urllib.parse.parse_qs(href_parts.query)
         self.assertTrue('marker' in params)
         self.assertEqual('1', params['limit'][0])
 
@@ -1105,7 +1105,7 @@ class VolumeApiTest(test.TestCase):
         def _verify_links(links, url_key):
             '''Verify next link and url.'''
             self.assertEqual(links[0]['rel'], 'next')
-            href_parts = urlparse.urlparse(links[0]['href'])
+            href_parts = urllib.parse.urlparse(links[0]['href'])
             self.assertEqual('/v2/fakeproject/%s' % key, href_parts.path)
 
         # Verify both the index and detail queries
diff --git a/cinder/tests/unit/integrated/api/client.py b/cinder/tests/unit/integrated/api/client.py
index 4ed2b9570..3010a0bce 100644
--- a/cinder/tests/unit/integrated/api/client.py
+++ b/cinder/tests/unit/integrated/api/client.py
@@ -16,7 +16,7 @@ from oslo_log import log as logging
 from oslo_serialization import jsonutils
 from oslo_utils import netutils
 import requests
-import six.moves.urllib.parse as urlparse
+from six.moves import urllib
 
 from cinder.i18n import _, _LI
 
@@ -83,7 +83,7 @@ class TestOpenStackClient(object):
         _headers = {'Content-Type': 'application/json'}
         _headers.update(headers or {})
 
-        parsed_url = urlparse.urlparse(url)
+        parsed_url = urllib.parse.urlparse(url)
         port = parsed_url.port
         hostname = parsed_url.hostname
         scheme = parsed_url.scheme
diff --git a/cinder/tests/unit/test_netapp_eseries_iscsi.py b/cinder/tests/unit/test_netapp_eseries_iscsi.py
index a1ebf45c8..4c55077dc 100644
--- a/cinder/tests/unit/test_netapp_eseries_iscsi.py
+++ b/cinder/tests/unit/test_netapp_eseries_iscsi.py
@@ -25,7 +25,7 @@ import re
 import mock
 from oslo_log import log as logging
 import requests
-import six.moves.urllib.parse as urlparse
+from six.moves import urllib
 
 from cinder import exception
 from cinder import test
@@ -877,7 +877,7 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
         driver = common.NetAppDriver(configuration=configuration)
         driver._check_mode_get_or_register_storage_system = mock.Mock()
         driver.do_setup(context='context')
-        url = urlparse.urlparse(driver._client._endpoint)
+        url = urllib.parse.urlparse(driver._client._endpoint)
         port = url.port
         scheme = url.scheme
         self.assertEqual(8080, port)
@@ -889,7 +889,7 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
         driver = common.NetAppDriver(configuration=configuration)
         driver._check_mode_get_or_register_storage_system = mock.Mock()
         driver.do_setup(context='context')
-        url = urlparse.urlparse(driver._client._endpoint)
+        url = urllib.parse.urlparse(driver._client._endpoint)
         port = url.port
         scheme = url.scheme
         self.assertEqual(8080, port)
@@ -901,7 +901,7 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
         driver = common.NetAppDriver(configuration=configuration)
         driver._check_mode_get_or_register_storage_system = mock.Mock()
         driver.do_setup(context='context')
-        url = urlparse.urlparse(driver._client._endpoint)
+        url = urllib.parse.urlparse(driver._client._endpoint)
         port = url.port
         scheme = url.scheme
         self.assertEqual(8443, port)
@@ -913,7 +913,7 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
         driver = common.NetAppDriver(configuration=configuration)
         driver._check_mode_get_or_register_storage_system = mock.Mock()
         driver.do_setup(context='context')
-        url = urlparse.urlparse(driver._client._endpoint)
+        url = urllib.parse.urlparse(driver._client._endpoint)
         port = url.port
         scheme = url.scheme
         self.assertEqual(81, port)
@@ -926,7 +926,7 @@ class NetAppEseriesISCSIDriverTestCase(test.TestCase):
         driver = common.NetAppDriver(configuration=configuration)
         driver._check_mode_get_or_register_storage_system = mock.Mock()
         driver.do_setup(context='context')
-        url = urlparse.urlparse(driver._client._endpoint)
+        url = urllib.parse.urlparse(driver._client._endpoint)
         port = url.port
         scheme = url.scheme
         self.assertEqual(446, port)
diff --git a/cinder/tests/unit/test_nimble.py b/cinder/tests/unit/test_nimble.py
index ba3592337..e229a6e20 100644
--- a/cinder/tests/unit/test_nimble.py
+++ b/cinder/tests/unit/test_nimble.py
@@ -24,7 +24,7 @@ from cinder.volume.drivers import nimble
 
 CONF = cfg.CONF
 NIMBLE_CLIENT = 'cinder.volume.drivers.nimble.client'
-NIMBLE_URLLIB2 = 'cinder.volume.drivers.nimble.urllib2'
+NIMBLE_URLLIB2 = 'six.moves.urllib.request'
 NIMBLE_RANDOM = 'cinder.volume.drivers.nimble.random'
 LOG = logging.getLogger(__name__)
 
diff --git a/cinder/tests/unit/test_wsgi.py b/cinder/tests/unit/test_wsgi.py
index a304abdcf..c72dac282 100644
--- a/cinder/tests/unit/test_wsgi.py
+++ b/cinder/tests/unit/test_wsgi.py
@@ -22,11 +22,11 @@ import socket
 import ssl
 import tempfile
 import time
-import urllib2
 
 import mock
 from oslo_config import cfg
 from oslo_i18n import fixture as i18n_fixture
+from six.moves import urllib
 import testtools
 import webob
 import webob.dec
@@ -48,12 +48,13 @@ def open_no_proxy(*args, **kwargs):
     # introduced in python 2.7.9 under PEP-0476
     # https://github.com/python/peps/blob/master/pep-0476.txt
     if hasattr(ssl, "_create_unverified_context"):
-        opener = urllib2.build_opener(
-            urllib2.ProxyHandler({}),
-            urllib2.HTTPSHandler(context=ssl._create_unverified_context())
+        context = ssl._create_unverified_context()
+        opener = urllib.request.build_opener(
+            urllib.request.ProxyHandler({}),
+            urllib.request.HTTPSHandler(context=context)
         )
     else:
-        opener = urllib2.build_opener(urllib2.ProxyHandler({}))
+        opener = urllib.request.build_opener(urllib.request.ProxyHandler({}))
     return opener.open(*args, **kwargs)
 
 
diff --git a/cinder/volume/drivers/cloudbyte/cloudbyte.py b/cinder/volume/drivers/cloudbyte/cloudbyte.py
index 7bd5f79e0..310e91b36 100644
--- a/cinder/volume/drivers/cloudbyte/cloudbyte.py
+++ b/cinder/volume/drivers/cloudbyte/cloudbyte.py
@@ -15,12 +15,12 @@
 
 import httplib
 import json
-import urllib
 import uuid
 
 from oslo_log import log as logging
 from oslo_utils import units
 import six
+from six.moves import urllib
 
 from cinder import exception
 from cinder.i18n import _, _LE, _LI
@@ -69,7 +69,7 @@ class CloudByteISCSIDriver(san.SanISCSIDriver):
             if value is not None:
                 sanitized_params[key] = six.text_type(value)
 
-        sanitized_params = urllib.urlencode(sanitized_params)
+        sanitized_params = urllib.parse.urlencode(sanitized_params)
         url = ('/client/api?%s' % sanitized_params)
 
         LOG.debug("CloudByte URL to be executed: [%s].", url)
@@ -77,7 +77,7 @@ class CloudByteISCSIDriver(san.SanISCSIDriver):
         # Add the apikey
         api = {}
         api['apiKey'] = apikey
-        url = url + '&' + urllib.urlencode(api)
+        url = url + '&' + urllib.parse.urlencode(api)
 
         return url
 
diff --git a/cinder/volume/drivers/emc/emc_vmax_https.py b/cinder/volume/drivers/emc/emc_vmax_https.py
index ea08ebfc0..309ca2670 100644
--- a/cinder/volume/drivers/emc/emc_vmax_https.py
+++ b/cinder/volume/drivers/emc/emc_vmax_https.py
@@ -20,12 +20,12 @@ import socket
 import ssl
 import string
 import struct
-import urllib
 
 from eventlet import patcher
 import OpenSSL
 from oslo_log import log as logging
 import six
+from six.moves import urllib
 
 from cinder.i18n import _, _LI
 
@@ -312,7 +312,7 @@ def wbem_request(url, data, creds, headers=None, debug=0, x509=None,
             if isinstance(hdr, unicode):
                 hdr = hdr.encode('utf-8')
             s = map(lambda x: string.strip(x), string.split(hdr, ":", 1))
-            h.putheader(urllib.quote(s[0]), urllib.quote(s[1]))
+            h.putheader(urllib.parse.quote(s[0]), urllib.parse.quote(s[1]))
 
         try:
             h.endheaders()
diff --git a/cinder/volume/drivers/emc/xtremio.py b/cinder/volume/drivers/emc/xtremio.py
index 38f4462ef..4a7d7be55 100644
--- a/cinder/volume/drivers/emc/xtremio.py
+++ b/cinder/volume/drivers/emc/xtremio.py
@@ -29,13 +29,12 @@ import json
 import math
 import random
 import string
-import urllib
-import urllib2
 
 from oslo_config import cfg
 from oslo_log import log as logging
 from oslo_utils import units
 import six
+from six.moves import urllib
 
 from cinder import exception
 from cinder.i18n import _, _LE, _LI, _LW
@@ -78,19 +77,18 @@ class XtremIOClient(object):
         if request_typ in ('GET', 'DELETE'):
             data.update(url_data)
             self.update_url(data, self.cluster_id)
-            url = '%(url)s?%(query)s' % {'query': urllib.urlencode(data,
-                                                                   doseq=True),
-                                         'url': url}
-            request = urllib2.Request(url)
+            query = urllib.parse.urlencode(data, doseq=True)
+            url = '%(url)s?%(query)s' % {'query': query, 'url': url}
+            request = urllib.request.Request(url)
         else:
             if url_data:
                 url = ('%(url)s?%(query)s' %
-                       {'query': urllib.urlencode(url_data, doseq=True),
+                       {'query': urllib.parse.urlencode(url_data, doseq=True),
                         'url': url})
 
             self.update_data(data, self.cluster_id)
             LOG.debug('data: %s', data)
-            request = urllib2.Request(url, json.dumps(data))
+            request = urllib.request.Request(url, json.dumps(data))
             LOG.debug('%(type)s %(url)s', {'type': request_typ, 'url': url})
 
         def get_request_type():
@@ -101,8 +99,8 @@ class XtremIOClient(object):
 
     def _send_request(self, object_type, key, request):
         try:
-            response = urllib2.urlopen(request)
-        except (urllib2.HTTPError, ) as exc:
+            response = urllib.request.urlopen(request)
+        except (urllib.error.HTTPError, ) as exc:
             if exc.code == 400 and hasattr(exc, 'read'):
                 error = json.load(exc)
                 err_msg = error['message']
diff --git a/cinder/volume/drivers/huawei/rest_common.py b/cinder/volume/drivers/huawei/rest_common.py
index c12ee2249..6b3482344 100644
--- a/cinder/volume/drivers/huawei/rest_common.py
+++ b/cinder/volume/drivers/huawei/rest_common.py
@@ -17,8 +17,8 @@
 import base64
 import cookielib
 import json
+import socket
 import time
-import urllib2
 import uuid
 from xml.etree import ElementTree as ET
 
@@ -26,6 +26,7 @@ from oslo_log import log as logging
 from oslo_utils import excutils
 from oslo_utils import units
 import six
+from six.moves import urllib
 
 from cinder import context
 from cinder import exception
@@ -65,15 +66,16 @@ class RestCommon(object):
         Convert response into Python Object and return it.
         """
 
-        opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cookie))
-        urllib2.install_opener(opener)
+        handler = urllib.request.HTTPCookieProcessor(self.cookie)
+        opener = urllib.request.build_opener(handler)
+        urllib.request.install_opener(opener)
 
         try:
-            urllib2.socket.setdefaulttimeout(720)
-            req = urllib2.Request(url, data, self.headers)
+            socket.setdefaulttimeout(720)
+            req = urllib.request.Request(url, data, self.headers)
             if method:
                 req.get_method = lambda: method
-            res = urllib2.urlopen(req).read().decode("utf-8")
+            res = urllib.request.urlopen(req).read().decode("utf-8")
 
             if "xx/sessions" not in url:
                 LOG.info(_LI('\n\n\n\nRequest URL: %(url)s\n\n'
diff --git a/cinder/volume/drivers/netapp/dataontap/client/api.py b/cinder/volume/drivers/netapp/dataontap/client/api.py
index f86caddfc..7391f8a60 100644
--- a/cinder/volume/drivers/netapp/dataontap/client/api.py
+++ b/cinder/volume/drivers/netapp/dataontap/client/api.py
@@ -21,11 +21,11 @@ Contains classes required to issue API calls to Data ONTAP and OnCommand DFM.
 """
 
 import copy
-import urllib2
 
 from lxml import etree
 from oslo_log import log as logging
 import six
+from six.moves import urllib
 
 from cinder import exception
 from cinder.i18n import _
@@ -206,7 +206,7 @@ class NaServer(object):
                 response = self._opener.open(request, timeout=self._timeout)
             else:
                 response = self._opener.open(request)
-        except urllib2.HTTPError as e:
+        except urllib.error.HTTPError as e:
             raise NaApiError(e.code, e.msg)
         except Exception as e:
             raise NaApiError('Unexpected error', e)
@@ -245,7 +245,7 @@ class NaServer(object):
             self._enable_tunnel_request(netapp_elem)
         netapp_elem.add_child_elem(na_element)
         request_d = netapp_elem.to_string()
-        request = urllib2.Request(
+        request = urllib.request.Request(
             self._get_url(), data=request_d,
             headers={'Content-Type': 'text/xml', 'charset': 'utf-8'})
         return request
@@ -292,14 +292,14 @@ class NaServer(object):
             auth_handler = self._create_basic_auth_handler()
         else:
             auth_handler = self._create_certificate_auth_handler()
-        opener = urllib2.build_opener(auth_handler)
+        opener = urllib.request.build_opener(auth_handler)
         self._opener = opener
 
     def _create_basic_auth_handler(self):
-        password_man = urllib2.HTTPPasswordMgrWithDefaultRealm()
+        password_man = urllib.request.HTTPPasswordMgrWithDefaultRealm()
         password_man.add_password(None, self._get_url(), self._username,
                                   self._password)
-        auth_handler = urllib2.HTTPBasicAuthHandler(password_man)
+        auth_handler = urllib.request.HTTPBasicAuthHandler(password_man)
         return auth_handler
 
     def _create_certificate_auth_handler(self):
diff --git a/cinder/volume/drivers/netapp/dataontap/nfs_base.py b/cinder/volume/drivers/netapp/dataontap/nfs_base.py
index 375118192..51debdae1 100644
--- a/cinder/volume/drivers/netapp/dataontap/nfs_base.py
+++ b/cinder/volume/drivers/netapp/dataontap/nfs_base.py
@@ -33,7 +33,7 @@ from oslo_config import cfg
 from oslo_log import log as logging
 from oslo_utils import units
 import six
-import six.moves.urllib.parse as urlparse
+from six.moves import urllib
 
 from cinder import exception
 from cinder.i18n import _, _LE, _LI, _LW
@@ -675,7 +675,7 @@ class NetAppNfsDriver(nfs.NfsDriver):
         mount_point = location['metadata'].get('mount_point')
         if not share_location or not mount_point:
             return url
-        url_parse = urlparse.urlparse(url)
+        url_parse = urllib.parse.urlparse(url)
         abs_path = os.path.join(url_parse.netloc, url_parse.path)
         rel_path = os.path.relpath(abs_path, mount_point)
         direct_url = "%s/%s" % (share_location, rel_path)
diff --git a/cinder/volume/drivers/netapp/eseries/client.py b/cinder/volume/drivers/netapp/eseries/client.py
index 87812df5e..036d48434 100644
--- a/cinder/volume/drivers/netapp/eseries/client.py
+++ b/cinder/volume/drivers/netapp/eseries/client.py
@@ -23,7 +23,7 @@ import json
 
 from oslo_log import log as logging
 import requests
-import six.moves.urllib.parse as urlparse
+from six.moves import urllib
 
 from cinder import exception
 from cinder.i18n import _, _LE
@@ -56,8 +56,8 @@ class WebserviceClient(object):
     def _create_endpoint(self, scheme, host, port, service_path):
         """Creates end point url for the service."""
         netloc = '%s:%s' % (host, port)
-        self._endpoint = urlparse.urlunparse((scheme, netloc, service_path,
-                                              None, None, None))
+        self._endpoint = urllib.parse.urlunparse((scheme, netloc, service_path,
+                                                 None, None, None))
 
     def _init_connection(self):
         """Do client specific set up for session and connection pooling."""
@@ -116,7 +116,7 @@ class RestClient(WebserviceClient):
         path = path.format(**kwargs)
         if not self._endpoint.endswith('/'):
             self._endpoint = '%s/' % self._endpoint
-        return urlparse.urljoin(self._endpoint, path.lstrip('/'))
+        return urllib.parse.urljoin(self._endpoint, path.lstrip('/'))
 
     def _invoke(self, method, path, data=None, use_system=True,
                 timeout=None, verify=False, **kwargs):
diff --git a/cinder/volume/drivers/nimble.py b/cinder/volume/drivers/nimble.py
index d97ccaf0f..99ff7b5c1 100644
--- a/cinder/volume/drivers/nimble.py
+++ b/cinder/volume/drivers/nimble.py
@@ -23,11 +23,11 @@ import random
 import re
 import six
 import string
-import urllib2
 
 from oslo_config import cfg
 from oslo_log import log as logging
 from oslo_utils import units
+from six.moves import urllib
 from suds import client
 
 from cinder import exception
@@ -425,7 +425,7 @@ class NimbleAPIExecutor(object):
         self.login()
 
     def _create_err_code_to_str_mapper(self, wsdl_url):
-        f = urllib2.urlopen(wsdl_url)
+        f = urllib.request.urlopen(wsdl_url)
         wsdl_file = f.read()
         err_enums = re.findall(
             r'<simpleType name="SmErrorType">(.*?)</simpleType>',
diff --git a/cinder/volume/drivers/rbd.py b/cinder/volume/drivers/rbd.py
index 8461607f6..7e012113f 100644
--- a/cinder/volume/drivers/rbd.py
+++ b/cinder/volume/drivers/rbd.py
@@ -19,7 +19,6 @@ import json
 import math
 import os
 import tempfile
-import urllib
 
 from eventlet import tpool
 from oslo_config import cfg
@@ -27,6 +26,7 @@ from oslo_log import log as logging
 from oslo_utils import encodeutils
 from oslo_utils import units
 import six
+from six.moves import urllib
 
 from cinder import exception
 from cinder.i18n import _, _LE, _LI, _LW
@@ -795,7 +795,7 @@ class RBDDriver(driver.RetypeVD, driver.TransferVD, driver.ExtendVD,
         if not location.startswith(prefix):
             reason = _('Not stored in rbd')
             raise exception.ImageUnacceptable(image_id=location, reason=reason)
-        pieces = map(urllib.unquote, location[len(prefix):].split('/'))
+        pieces = map(urllib.parse.unquote, location[len(prefix):].split('/'))
         if any(map(lambda p: p == '', pieces)):
             reason = _('Blank components')
             raise exception.ImageUnacceptable(image_id=location, reason=reason)
diff --git a/cinder/volume/drivers/scality.py b/cinder/volume/drivers/scality.py
index d4edc0ea4..0eec3247e 100644
--- a/cinder/volume/drivers/scality.py
+++ b/cinder/volume/drivers/scality.py
@@ -18,13 +18,12 @@ Scality SOFS Volume Driver.
 
 
 import os
-import urllib2
 
 from oslo_concurrency import lockutils
 from oslo_config import cfg
 from oslo_log import log as logging
 from oslo_utils import units
-import six.moves.urllib.parse as urlparse
+from six.moves import urllib
 
 from cinder import exception
 from cinder.i18n import _, _LI
@@ -76,12 +75,12 @@ class ScalityDriver(driver.VolumeDriver):
             raise exception.VolumeBackendAPIException(data=msg)
 
         # config can be a file path or a URL, check it
-        if urlparse.urlparse(config).scheme == '':
+        if urllib.parse.urlparse(config).scheme == '':
             # turn local path into URL
             config = 'file://%s' % config
         try:
-            urllib2.urlopen(config, timeout=5).close()
-        except urllib2.URLError as e:
+            urllib.request.urlopen(config, timeout=5).close()
+        except urllib.error.URLError as e:
             msg = _("Cannot access 'scality_sofs_config': %s") % e
             LOG.warning(msg)
             raise exception.VolumeBackendAPIException(data=msg)
diff --git a/cinder/volume/drivers/tintri.py b/cinder/volume/drivers/tintri.py
index df31e0636..b3566601e 100644
--- a/cinder/volume/drivers/tintri.py
+++ b/cinder/volume/drivers/tintri.py
@@ -26,7 +26,7 @@ from oslo_config import cfg
 from oslo_log import log as logging
 from oslo_utils import units
 import requests
-import six.moves.urllib.parse as urlparse
+from six.moves import urllib
 
 from cinder import exception
 from cinder import utils
@@ -550,7 +550,7 @@ class TintriDriver(nfs.NfsDriver):
         mount_point = location['metadata'].get('mount_point')
         if not share_location or not mount_point:
             return url
-        url_parse = urlparse.urlparse(url)
+        url_parse = urllib.parse.urlparse(url)
         abs_path = os.path.join(url_parse.netloc, url_parse.path)
         rel_path = os.path.relpath(abs_path, mount_point)
         direct_url = "%s/%s" % (share_location, rel_path)
diff --git a/cinder/volume/drivers/vmware/volumeops.py b/cinder/volume/drivers/vmware/volumeops.py
index a99566fb7..a54d6ca1e 100644
--- a/cinder/volume/drivers/vmware/volumeops.py
+++ b/cinder/volume/drivers/vmware/volumeops.py
@@ -17,12 +17,12 @@
 Implements operations on volumes residing on VMware datastores.
 """
 
-import urllib
 
 from oslo_log import log as logging
 from oslo_utils import units
 from oslo_vmware import exceptions
 from oslo_vmware import vim_util
+from six.moves import urllib
 
 from cinder.i18n import _, _LE, _LI
 from cinder.volume.drivers.vmware import exceptions as vmdk_exceptions
@@ -528,8 +528,9 @@ class VMwareVolumeOps(object):
                 if child_entity._type != 'Folder':
                     continue
                 child_entity_name = self.get_entity_name(child_entity)
-                if child_entity_name and (urllib.unquote(child_entity_name) ==
-                                          child_folder_name):
+                if (child_entity_name
+                    and (urllib.parse.unquote(child_entity_name)
+                         == child_folder_name)):
                     LOG.debug("Child folder: %s exists.", child_folder_name)
                     return child_entity
 
diff --git a/cinder/volume/drivers/xio.py b/cinder/volume/drivers/xio.py
index 9023c9da2..32a80998d 100644
--- a/cinder/volume/drivers/xio.py
+++ b/cinder/volume/drivers/xio.py
@@ -15,11 +15,11 @@
 
 import base64
 import string
-import urllib2
 
 from lxml import etree
 from oslo_config import cfg
 from oslo_log import log as logging
+from six.moves import urllib
 
 from cinder import context
 from cinder import exception
@@ -238,17 +238,17 @@ class XIOISEDriver(object):
         response['content'] = ''
         response['location'] = ''
         # send the request
-        req = urllib2.Request(url, body, header)
+        req = urllib.request.Request(url, body, header)
         # Override method to allow GET, PUT, POST, DELETE
         req.get_method = lambda: method
         try:
-            resp = urllib2.urlopen(req)
-        except urllib2.HTTPError as err:
+            resp = urllib.request.urlopen(req)
+        except urllib.error.HTTPError as err:
             # HTTP error. Return HTTP status and content and let caller
             # handle retries.
             response['status'] = err.code
             response['content'] = err.read()
-        except urllib2.URLError as err:
+        except urllib.error.URLError as err:
             # Connection failure.  Return a status of 0 to indicate error.
             response['status'] = 0
         else:
diff --git a/cinder/volume/drivers/zfssa/restclient.py b/cinder/volume/drivers/zfssa/restclient.py
index f8cb6ecd7..41eb6c264 100644
--- a/cinder/volume/drivers/zfssa/restclient.py
+++ b/cinder/volume/drivers/zfssa/restclient.py
@@ -19,9 +19,9 @@ import httplib
 import json
 import StringIO
 import time
-import urllib2
 
 from oslo_log import log
+from six.moves import urllib
 
 from cinder.i18n import _LE, _LI
 
@@ -129,7 +129,7 @@ class RestClientError(Exception):
 
 
 class RestClientURL(object):
-    """ZFSSA urllib2 client"""
+    """ZFSSA urllib client"""
     def __init__(self, url, **kwargs):
         """Initialize a REST client.
 
@@ -262,7 +262,7 @@ class RestClientURL(object):
             out_hdrs['content-length'] = len(body)
 
         zfssaurl = self._path(path, kwargs.get("base_path"))
-        req = urllib2.Request(zfssaurl, body, out_hdrs)
+        req = urllib.request.Request(zfssaurl, body, out_hdrs)
         req.get_method = lambda: request
         maxreqretries = kwargs.get("maxreqretries", 10)
         retry = 0
@@ -275,8 +275,8 @@ class RestClientURL(object):
 
         while retry < maxreqretries:
             try:
-                response = urllib2.urlopen(req, timeout=self.timeout)
-            except urllib2.HTTPError as err:
+                response = urllib.request.urlopen(req, timeout=self.timeout)
+            except urllib.error.HTTPError as err:
                 if err.code == httplib.NOT_FOUND:
                     LOG.debug('REST Not Found: %s', err.code)
                 else:
@@ -306,7 +306,7 @@ class RestClientURL(object):
 
                 return RestResult(err=err)
 
-            except urllib2.URLError as err:
+            except urllib.error.URLError as err:
                 LOG.error(_LE('URLError: %s'), err.reason)
                 raise RestClientError(-1, name="ERR_URLError",
                                       message=err.reason)
diff --git a/cinder/volume/drivers/zfssa/webdavclient.py b/cinder/volume/drivers/zfssa/webdavclient.py
index 80431485f..f8ec06dcf 100644
--- a/cinder/volume/drivers/zfssa/webdavclient.py
+++ b/cinder/volume/drivers/zfssa/webdavclient.py
@@ -17,9 +17,9 @@ ZFS Storage Appliance WebDAV Client
 
 import httplib
 import time
-import urllib2
 
 from oslo_log import log
+from six.moves import urllib
 
 from cinder import exception
 from cinder.i18n import _, _LE
@@ -72,7 +72,7 @@ class ZFSSAWebDAVClient(object):
         retry = 0
         src_url = self.https_path + "/" + src_file
         dst_url = self.https_path + "/" + dst_file
-        request = urllib2.Request(src_url)
+        request = urllib.request.Request(src_url)
 
         if dst_file != "":
             request.add_header('Destination', dst_url)
@@ -86,8 +86,8 @@ class ZFSSAWebDAVClient(object):
 
         while retry < maxretries:
             try:
-                response = urllib2.urlopen(request, timeout=None)
-            except urllib2.HTTPError as err:
+                response = urllib.request.urlopen(request, timeout=None)
+            except urllib.error.HTTPError as err:
                 LOG.error(_LE('WebDAV returned with %(code)s error during '
                               '%(method)s call.'),
                           {'code': err.code, 'method': method})
@@ -116,7 +116,7 @@ class ZFSSAWebDAVClient(object):
                                                   src=src_file, dst=dst_file,
                                                   method=method)
 
-            except urllib2.URLError as err:
+            except urllib.error.URLError as err:
                 reason = ''
                 if getattr(err, 'reason'):
                     reason = err.reason