Merge "Fix Python 3 issues in the blockbridge driver"
This commit is contained in:
commit
ee30299d94
|
@ -16,13 +16,17 @@ Blockbridge EPS iSCSI Volume Driver Tests
|
|||
"""
|
||||
|
||||
import base64
|
||||
import httplib
|
||||
import urllib
|
||||
|
||||
import mock
|
||||
try:
|
||||
from unittest import mock
|
||||
except ImportError:
|
||||
import mock
|
||||
from oslo_log import log as logging
|
||||
from oslo_serialization import jsonutils
|
||||
from oslo_utils import units
|
||||
import six
|
||||
from six.moves import http_client
|
||||
from six.moves import urllib
|
||||
|
||||
from cinder import context
|
||||
from cinder import exception
|
||||
|
@ -71,7 +75,7 @@ def common_mocks(f):
|
|||
mocks that can't/don't get unset.
|
||||
"""
|
||||
def _common_inner_inner1(inst, *args, **kwargs):
|
||||
@mock.patch("httplib.HTTPSConnection", autospec=True)
|
||||
@mock.patch("six.moves.http_client.HTTPSConnection", autospec=True)
|
||||
def _common_inner_inner2(mock_conn):
|
||||
inst.mock_httplib = mock_conn
|
||||
inst.mock_conn = mock_conn.return_value
|
||||
|
@ -154,7 +158,7 @@ class BlockbridgeISCSIDriverTestCase(test.TestCase):
|
|||
self.mock_response.read.return_value = '{}'
|
||||
self.mock_response.status = 200
|
||||
|
||||
conn = httplib.HTTPSConnection('whatever', None)
|
||||
conn = http_client.HTTPSConnection('whatever', None)
|
||||
conn.request('GET', '/blah', '{}', {})
|
||||
rsp = conn.getresponse()
|
||||
|
||||
|
@ -168,7 +172,7 @@ class BlockbridgeISCSIDriverTestCase(test.TestCase):
|
|||
self.mock_response.read.return_value = mock_body
|
||||
self.mock_response.status = 413
|
||||
|
||||
conn = httplib.HTTPSConnection('whatever', None)
|
||||
conn = http_client.HTTPSConnection('whatever', None)
|
||||
conn.request('GET', '/blah', '{}', {})
|
||||
rsp = conn.getresponse()
|
||||
|
||||
|
@ -196,28 +200,37 @@ class BlockbridgeISCSIDriverTestCase(test.TestCase):
|
|||
with mock.patch.object(self.driver, 'hostname', 'mock-hostname'):
|
||||
self.driver.get_volume_stats(True)
|
||||
|
||||
b64_creds = base64.encodestring("%s:%s" % (
|
||||
self.cfg.blockbridge_auth_user,
|
||||
self.cfg.blockbridge_auth_password)).replace("\n", "")
|
||||
creds = "%s:%s" % (self.cfg.blockbridge_auth_user,
|
||||
self.cfg.blockbridge_auth_password)
|
||||
if six.PY3:
|
||||
creds = creds.encode('utf-8')
|
||||
b64_creds = base64.encodestring(creds).decode('ascii')
|
||||
else:
|
||||
b64_creds = base64.encodestring(creds)
|
||||
|
||||
params = dict(
|
||||
hostname='mock-hostname',
|
||||
version=self.driver.VERSION,
|
||||
backend_name='BlockbridgeISCSIDriver',
|
||||
pool='OpenStack',
|
||||
query='%2Bopenstack')
|
||||
query='+openstack')
|
||||
|
||||
full_url = ("/api/cinder/status?query=%(query)s&"
|
||||
"hostname=%(hostname)s&backend_name=%(backend_name)s&"
|
||||
"version=%(version)s&pool=%(pool)s" % params)
|
||||
headers = {
|
||||
'Accept': 'application/vnd.blockbridge-3+json',
|
||||
'Authorization': "Basic %s" % b64_creds,
|
||||
'Authorization': "Basic %s" % b64_creds.replace("\n", ""),
|
||||
'User-Agent': "cinder-volume/%s" % self.driver.VERSION,
|
||||
}
|
||||
|
||||
self.mock_conn.request.assert_called_once_with(
|
||||
'GET', full_url, None, headers)
|
||||
'GET', mock.ANY, None, headers)
|
||||
# Parse the URL instead of comparing directly both URLs.
|
||||
# On Python 3, parameters are formatted in a random order because
|
||||
# of the hash randomization.
|
||||
conn_url = self.mock_conn.request.call_args[0][1]
|
||||
conn_params = dict(urllib.parse.parse_qsl(conn_url.split("?", 1)[1]))
|
||||
self.assertTrue(conn_url.startswith("/api/cinder/status?"),
|
||||
repr(conn_url))
|
||||
self.assertEqual(params, conn_params)
|
||||
|
||||
@common_mocks
|
||||
def test_create_volume(self):
|
||||
|
@ -508,7 +521,7 @@ class BlockbridgeISCSIDriverTestCase(test.TestCase):
|
|||
|
||||
self.assertEqual(expected_props, props)
|
||||
|
||||
ini_name = urllib.quote(self.connector["initiator"], "")
|
||||
ini_name = urllib.parse.quote(self.connector["initiator"], "")
|
||||
url = "/volumes/%s/exports/%s" % (self.volume_id, ini_name)
|
||||
params = dict(
|
||||
chap_user="mock-user-abcdef123456",
|
||||
|
@ -525,7 +538,7 @@ class BlockbridgeISCSIDriverTestCase(test.TestCase):
|
|||
def test_terminate_connection(self):
|
||||
self.driver.terminate_connection(self.volume, self.connector)
|
||||
|
||||
ini_name = urllib.quote(self.connector["initiator"], "")
|
||||
ini_name = urllib.parse.quote(self.connector["initiator"], "")
|
||||
url = "/volumes/%s/exports/%s" % (self.volume_id, ini_name)
|
||||
kwargs = dict(
|
||||
method='DELETE',
|
||||
|
|
|
@ -16,14 +16,15 @@ Blockbridge EPS iSCSI Volume Driver
|
|||
"""
|
||||
|
||||
import base64
|
||||
import httplib
|
||||
import socket
|
||||
import urllib
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
from oslo_serialization import jsonutils
|
||||
from oslo_utils import units
|
||||
import six
|
||||
from six.moves import http_client
|
||||
from six.moves import urllib
|
||||
|
||||
from cinder import context
|
||||
from cinder import exception
|
||||
|
@ -84,7 +85,12 @@ class BlockbridgeAPIClient(object):
|
|||
if self.configuration.blockbridge_auth_scheme == 'password':
|
||||
user = self.configuration.safe_get('blockbridge_auth_user')
|
||||
pw = self.configuration.safe_get('blockbridge_auth_password')
|
||||
b64_creds = base64.encodestring("%s:%s" % (user, pw))
|
||||
creds = "%s:%s" % (user, pw)
|
||||
if six.PY3:
|
||||
creds = creds.encode('utf-8')
|
||||
b64_creds = base64.encodestring(creds).decode('ascii')
|
||||
else:
|
||||
b64_creds = base64.encodestring(creds)
|
||||
authz = "Basic %s" % b64_creds.replace("\n", "")
|
||||
elif self.configuration.blockbridge_auth_scheme == 'token':
|
||||
token = self.configuration.blockbridge_auth_token or ''
|
||||
|
@ -137,7 +143,7 @@ class BlockbridgeAPIClient(object):
|
|||
if method in ['GET', 'DELETE']:
|
||||
# For GET method add parameters to the URL
|
||||
if params:
|
||||
url += '?' + urllib.urlencode(params)
|
||||
url += '?' + urllib.parse.urlencode(params)
|
||||
elif method in ['POST', 'PUT', 'PATCH']:
|
||||
body = jsonutils.dumps(params)
|
||||
headers['Content-Type'] = 'application/json'
|
||||
|
@ -145,7 +151,7 @@ class BlockbridgeAPIClient(object):
|
|||
raise exception.UnknownCmd(cmd=method)
|
||||
|
||||
# connect and execute the request
|
||||
connection = httplib.HTTPSConnection(cfg['host'], cfg['port'])
|
||||
connection = http_client.HTTPSConnection(cfg['host'], cfg['port'])
|
||||
connection.request(method, url, body, headers)
|
||||
response = connection.getresponse()
|
||||
|
||||
|
@ -231,7 +237,7 @@ class BlockbridgeISCSIDriver(driver.ISCSIDriver):
|
|||
reason=_("Blockbridge default pool does not exist"))
|
||||
|
||||
def _vol_api_submit(self, vol_id, **kwargs):
|
||||
vol_id = urllib.quote(vol_id, '')
|
||||
vol_id = urllib.parse.quote(vol_id, '')
|
||||
rel_url = "/volumes/%s" % vol_id
|
||||
|
||||
return self.client.submit(rel_url, **kwargs)
|
||||
|
@ -256,8 +262,8 @@ class BlockbridgeISCSIDriver(driver.ISCSIDriver):
|
|||
params=params, **kwargs)
|
||||
|
||||
def _snap_api_submit(self, vol_id, snap_id, **kwargs):
|
||||
vol_id = urllib.quote(vol_id, '')
|
||||
snap_id = urllib.quote(snap_id, '')
|
||||
vol_id = urllib.parse.quote(vol_id, '')
|
||||
snap_id = urllib.parse.quote(snap_id, '')
|
||||
rel_url = "/volumes/%s/snapshots/%s" % (vol_id, snap_id)
|
||||
|
||||
return self.client.submit(rel_url, **kwargs)
|
||||
|
@ -275,8 +281,8 @@ class BlockbridgeISCSIDriver(driver.ISCSIDriver):
|
|||
**kwargs)
|
||||
|
||||
def _export_api_submit(self, vol_id, ini_name, **kwargs):
|
||||
vol_id = urllib.quote(vol_id, '')
|
||||
ini_name = urllib.quote(ini_name, '')
|
||||
vol_id = urllib.parse.quote(vol_id, '')
|
||||
ini_name = urllib.parse.quote(ini_name, '')
|
||||
rel_url = "/volumes/%s/exports/%s" % (vol_id, ini_name)
|
||||
|
||||
return self.client.submit(rel_url, **kwargs)
|
||||
|
@ -321,7 +327,7 @@ class BlockbridgeISCSIDriver(driver.ISCSIDriver):
|
|||
else:
|
||||
# no pool specified or defaulted -- just pick whatever comes out of
|
||||
# the dictionary first.
|
||||
return pools.values()[0]
|
||||
return list(pools.values())[0]
|
||||
|
||||
def create_volume(self, volume):
|
||||
"""Create a volume on a Blockbridge EPS backend.
|
||||
|
|
Loading…
Reference in New Issue