summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/requirements.txt6
-rw-r--r--doc/source/conf.py13
-rw-r--r--glanceclient/common/http.py25
-rw-r--r--glanceclient/common/https.py21
-rw-r--r--glanceclient/common/progressbar.py4
-rw-r--r--glanceclient/common/utils.py23
-rw-r--r--glanceclient/exc.py5
-rw-r--r--glanceclient/shell.py40
-rw-r--r--glanceclient/tests/unit/test_http.py30
-rw-r--r--glanceclient/tests/unit/test_progressbar.py6
-rw-r--r--glanceclient/tests/unit/test_shell.py65
-rw-r--r--glanceclient/tests/unit/test_ssl.py10
-rw-r--r--glanceclient/tests/unit/test_utils.py29
-rw-r--r--glanceclient/tests/unit/v1/test_images.py14
-rw-r--r--glanceclient/tests/unit/v1/test_shell.py16
-rw-r--r--glanceclient/tests/unit/v2/test_shell_v2.py64
-rw-r--r--glanceclient/tests/unit/var/ca.crt66
-rw-r--r--glanceclient/tests/unit/var/certificate.crt96
-rw-r--r--glanceclient/tests/unit/var/privatekey.key98
-rw-r--r--glanceclient/tests/utils.py24
-rw-r--r--glanceclient/v1/apiclient/base.py12
-rw-r--r--glanceclient/v1/apiclient/exceptions.py4
-rw-r--r--glanceclient/v1/apiclient/utils.py6
-rw-r--r--glanceclient/v1/images.py13
-rw-r--r--glanceclient/v1/shell.py2
-rw-r--r--glanceclient/v2/images.py15
-rw-r--r--glanceclient/v2/metadefs.py9
-rw-r--r--glanceclient/v2/shell.py3
-rw-r--r--glanceclient/v2/tasks.py7
-rw-r--r--lower-constraints.txt11
-rw-r--r--releasenotes/notes/fix_1889666-22dc97ce577eccc6.yaml6
-rw-r--r--releasenotes/notes/sess_client_grid-3c2101609110f413.yaml6
-rw-r--r--releasenotes/source/conf.py14
-rw-r--r--requirements.txt1
-rw-r--r--tox.ini2
35 files changed, 340 insertions, 426 deletions
diff --git a/doc/requirements.txt b/doc/requirements.txt
index e8ba0fa..97c1879 100644
--- a/doc/requirements.txt
+++ b/doc/requirements.txt
@@ -1,7 +1,7 @@
# The order of packages is significant, because pip processes them in the order
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
-openstackdocstheme>=1.20.0 # Apache-2.0
-reno>=2.5.0 # Apache-2.0
-sphinx!=1.6.6,!=1.6.7,!=2.1.0,>=1.6.2 # BSD
+openstackdocstheme>=2.2.1 # Apache-2.0
+reno>=3.1.0 # Apache-2.0
+sphinx>=2.0.0,!=2.1.0 # BSD
sphinxcontrib-apidoc>=0.2.0 # BSD
diff --git a/doc/source/conf.py b/doc/source/conf.py
index 74d6595..bfe9b56 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -16,7 +16,6 @@
import os
import sys
-import openstackdocstheme
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__),
'..', '..')))
@@ -39,9 +38,9 @@ apidoc_excluded_paths = [
apidoc_separate_modules = True
# openstackdocstheme options
-repository_name = 'openstack/python-glanceclient'
-bug_project = 'python-glanceclient'
-bug_tag = ''
+openstackdocs_repo_name = 'openstack/python-glanceclient'
+openstackdocs_bug_project = 'python-glanceclient'
+openstackdocs_bug_tag = ''
# autodoc generation is a bit aggressive and a nuisance when doing heavy
# text edit cycles.
@@ -68,7 +67,7 @@ add_function_parentheses = True
add_module_names = True
# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
+pygments_style = 'native'
# -- Options for HTML output --------------------------------------------------
@@ -77,10 +76,6 @@ pygments_style = 'sphinx'
#html_theme = 'nature'
html_theme = 'openstackdocs'
-# Add any paths that contain custom themes here, relative to this directory.
-#html_theme_path = ['_theme']
-html_theme_path = [openstackdocstheme.get_html_theme_path()]
-
# Output file base name for HTML help builder.
htmlhelp_basename = '%sdoc' % project
diff --git a/glanceclient/common/http.py b/glanceclient/common/http.py
index 6973f60..e24ba35 100644
--- a/glanceclient/common/http.py
+++ b/glanceclient/common/http.py
@@ -14,6 +14,7 @@
# under the License.
import copy
+import io
import logging
import socket
@@ -23,8 +24,7 @@ import OpenSSL
from oslo_utils import importutils
from oslo_utils import netutils
import requests
-import six
-import six.moves.urllib.parse as urlparse
+import urllib.parse
try:
import json
@@ -66,19 +66,13 @@ def encode_headers(headers):
for h, v in headers.items():
if v is not None:
# if the item is token, do not quote '+' as well.
- # NOTE(imacdonn): urlparse.quote() is intended for quoting the
+ # NOTE(imacdonn): urllib.parse.quote() is intended for quoting the
# path part of a URL, but headers like x-image-meta-location
# include an entire URL. We should avoid encoding the colon in
# this case (bug #1788942)
safe = '=+/' if h in TOKEN_HEADERS else '/:'
- if six.PY2:
- # incoming items may be unicode, so get them into something
- # the py2 version of urllib can handle before percent encoding
- key = urlparse.quote(encodeutils.safe_encode(h), safe)
- value = urlparse.quote(encodeutils.safe_encode(v), safe)
- else:
- key = urlparse.quote(h, safe)
- value = urlparse.quote(v, safe)
+ key = urllib.parse.quote(h, safe)
+ value = urllib.parse.quote(v, safe)
encoded_dict[key] = value
return dict((encodeutils.safe_encode(h, encoding='ascii'),
encodeutils.safe_encode(v, encoding='ascii'))
@@ -105,7 +99,7 @@ class _BaseHTTPClient(object):
# NOTE(jamielennox): remove this later. Managers should pass json= if
# they want to send json data.
data = kwargs.pop("data", None)
- if data is not None and not isinstance(data, six.string_types):
+ if data is not None and not isinstance(data, str):
try:
data = json.dumps(data)
content_type = 'application/json'
@@ -143,7 +137,7 @@ class _BaseHTTPClient(object):
# response encoding
body_iter = resp.json()
else:
- body_iter = six.StringIO(content)
+ body_iter = io.StringIO(content)
try:
body_iter = json.loads(''.join([c for c in body_iter]))
except ValueError:
@@ -209,13 +203,13 @@ class HTTPClient(_BaseHTTPClient):
if not self.session.verify:
curl.append('-k')
else:
- if isinstance(self.session.verify, six.string_types):
+ if isinstance(self.session.verify, str):
curl.append(' --cacert %s' % self.session.verify)
if self.session.cert:
curl.append(' --cert %s --key %s' % self.session.cert)
- if data and isinstance(data, six.string_types):
+ if data and isinstance(data, str):
curl.append('-d \'%s\'' % data)
curl.append(url)
@@ -352,7 +346,6 @@ class SessionClient(adapter.Adapter, _BaseHTTPClient):
def __init__(self, session, **kwargs):
kwargs.setdefault('user_agent', USER_AGENT)
kwargs.setdefault('service_type', 'image')
- self.global_request_id = kwargs.pop('global_request_id', None)
super(SessionClient, self).__init__(session, **kwargs)
def request(self, url, method, **kwargs):
diff --git a/glanceclient/common/https.py b/glanceclient/common/https.py
index deb7eb0..94aeeb3 100644
--- a/glanceclient/common/https.py
+++ b/glanceclient/common/https.py
@@ -20,10 +20,6 @@ import struct
import OpenSSL
-import six
-# NOTE(jokke): simplified transition to py3, behaves like py2 xrange
-from six.moves import range
-
try:
from eventlet import patcher
# Handle case where we are running in a monkey patched environment
@@ -33,9 +29,9 @@ try:
else:
raise ImportError
except ImportError:
+ import http.client
from OpenSSL import SSL
- from six.moves import http_client
- HTTPSConnection = http_client.HTTPSConnection
+ HTTPSConnection = http.client.HTTPSConnection
Connection = SSL.Connection
@@ -120,8 +116,8 @@ def host_matches_cert(host, x509):
def to_bytes(s):
- if isinstance(s, six.string_types):
- return six.b(s)
+ if isinstance(s, str):
+ return bytes(s, 'latin-1')
else:
return s
@@ -161,14 +157,7 @@ class VerifiedHTTPSConnection(HTTPSConnection):
ssl_compression=True):
# List of exceptions reported by Python3 instead of
# SSLConfigurationError
- if six.PY3:
- excp_lst = (TypeError, FileNotFoundError, ssl.SSLError)
- else:
- # NOTE(jamespage)
- # Accommodate changes in behaviour for pep-0467, introduced
- # in python 2.7.9.
- # https://github.com/python/peps/blob/master/pep-0476.txt
- excp_lst = (TypeError, IOError, ssl.SSLError)
+ excp_lst = (TypeError, FileNotFoundError, ssl.SSLError)
try:
HTTPSConnection.__init__(self, host, port,
key_file=key_file,
diff --git a/glanceclient/common/progressbar.py b/glanceclient/common/progressbar.py
index 6cf0df3..bb8b21b 100644
--- a/glanceclient/common/progressbar.py
+++ b/glanceclient/common/progressbar.py
@@ -15,8 +15,6 @@
import sys
-import six
-
class _ProgressBarBase(object):
"""A progress bar provider for a wrapped obect.
@@ -83,7 +81,7 @@ class VerboseIteratorWrapper(_ProgressBarBase):
def next(self):
try:
- data = six.next(self._wrapped)
+ data = next(self._wrapped)
# NOTE(mouad): Assuming that data is a string b/c otherwise calling
# len function will not make any sense.
self._display_progress_bar(len(data))
diff --git a/glanceclient/common/utils.py b/glanceclient/common/utils.py
index 0fde763..4084e0e 100644
--- a/glanceclient/common/utils.py
+++ b/glanceclient/common/utils.py
@@ -13,20 +13,17 @@
# License for the specific language governing permissions and limitations
# under the License.
-from __future__ import print_function
-
import errno
import functools
import hashlib
import json
import os
import re
-import six.moves.urllib.parse as urlparse
import sys
import threading
+import urllib.parse
import uuid
-import six
if os.name == 'nt': # noqa
import msvcrt # noqa
@@ -161,7 +158,7 @@ def schema_args(schema_getter, omit=None):
# for the `join` to succeed. Enum types can also be `None`
# therefore, join's call would fail without the following
# list comprehension
- vals = [six.text_type(val) for val in property.get('enum')]
+ vals = [str(val) for val in property.get('enum')]
description += ('Valid values: ' + ', '.join(vals))
kwargs['help'] = description
@@ -216,8 +213,6 @@ def print_list(objs, fields, formatters=None, field_settings=None):
def _encode(src):
"""remove extra 'u' in PY2."""
- if six.PY2 and isinstance(src, unicode):
- return src.encode('utf-8')
return src
@@ -345,7 +340,7 @@ def get_file_size(file_obj):
:retval: The file's size or None if it cannot be determined.
"""
if (hasattr(file_obj, 'seek') and hasattr(file_obj, 'tell') and
- (six.PY2 or six.PY3 and file_obj.seekable())):
+ file_obj.seekable()):
try:
curr = file_obj.tell()
file_obj.seek(0, os.SEEK_END)
@@ -401,13 +396,13 @@ def strip_version(endpoint):
# we make endpoint the first argument. However, we
# can't do that just yet because we need to keep
# backwards compatibility.
- if not isinstance(endpoint, six.string_types):
+ if not isinstance(endpoint, str):
raise ValueError("Expected endpoint")
version = None
# Get rid of trailing '/' if present
endpoint = endpoint.rstrip('/')
- url_parts = urlparse.urlparse(endpoint)
+ url_parts = urllib.parse.urlparse(endpoint)
(scheme, netloc, path, __, __, __) = url_parts
path = path.lstrip('/')
# regex to match 'v1' or 'v2.0' etc
@@ -446,8 +441,8 @@ def integrity_iter(iter, checksum):
for chunk in iter:
yield chunk
- if isinstance(chunk, six.string_types):
- chunk = six.b(chunk)
+ if isinstance(chunk, str):
+ chunk = bytes(chunk, 'latin-1')
md5sum.update(chunk)
md5sum = md5sum.hexdigest()
if md5sum != checksum:
@@ -466,8 +461,8 @@ def serious_integrity_iter(iter, hasher, hash_value):
"""
for chunk in iter:
yield chunk
- if isinstance(chunk, six.string_types):
- chunk = six.b(chunk)
+ if isinstance(chunk, str):
+ chunk = bytes(chunk, 'latin-1')
hasher.update(chunk)
computed = hasher.hexdigest()
if computed != hash_value:
diff --git a/glanceclient/exc.py b/glanceclient/exc.py
index eee47ca..5efe805 100644
--- a/glanceclient/exc.py
+++ b/glanceclient/exc.py
@@ -16,8 +16,6 @@
import re
import sys
-import six
-
class BaseException(Exception):
"""An error occurred."""
@@ -179,8 +177,7 @@ def from_response(response, body=None):
details = ': '.join(details_temp)
return cls(details=details)
elif body:
- if six.PY3:
- body = body.decode('utf-8')
+ body = body.decode('utf-8')
details = body.replace('\n\n', '\n')
return cls(details=details)
diff --git a/glanceclient/shell.py b/glanceclient/shell.py
index 3dfa14a..ca10359 100644
--- a/glanceclient/shell.py
+++ b/glanceclient/shell.py
@@ -17,8 +17,6 @@
Command-line interface to the OpenStack Images API.
"""
-from __future__ import print_function
-
import argparse
import copy
import getpass
@@ -31,8 +29,7 @@ import traceback
from oslo_utils import encodeutils
from oslo_utils import importutils
-import six
-import six.moves.urllib.parse as urlparse
+import urllib.parse
import glanceclient
from glanceclient._i18n import _
@@ -259,7 +256,7 @@ class OpenStackImagesShell(object):
except ks_exc.ClientException as e:
# Identity service may not support discover API version.
# Lets trying to figure out the API version from the original URL.
- url_parts = urlparse.urlparse(auth_url)
+ url_parts = urllib.parse.urlparse(auth_url)
(scheme, netloc, path, params, query, fragment) = url_parts
path = path.lower()
if path.startswith('/v3'):
@@ -522,12 +519,6 @@ class OpenStackImagesShell(object):
self.do_help(options, parser=parser)
return 0
- # NOTE(sigmavirus24): Above, args is defined as the left over
- # arguments from parser.parse_known_args(). This allows us to
- # skip any parameters to command-line flags that may have been passed
- # to glanceclient, e.g., --os-auth-token.
- self._fixup_subcommand(args, argv)
-
# short-circuit and deal with help command right away.
sub_parser = _get_subparser(api_version)
args = sub_parser.parse_args(argv)
@@ -598,33 +589,6 @@ class OpenStackImagesShell(object):
print("To display trace use next command:\n"
"osprofiler trace show --html %s " % trace_id)
- @staticmethod
- def _fixup_subcommand(unknown_args, argv):
- # NOTE(sigmavirus24): Sometimes users pass the wrong subcommand name
- # to glanceclient. If they're using Python 2 they will see an error:
- # > invalid choice: u'imgae-list' (choose from ...)
- # To avoid this, we look at the extra args already parsed from above
- # and try to predict what the subcommand will be based on it being the
- # first non - or -- prefixed argument in args. We then find that in
- # argv and encode it from unicode so users don't see the pesky `u'`
- # prefix.
- for arg in unknown_args:
- if not arg.startswith('-'): # This will cover both - and --
- subcommand_name = arg
- break
- else:
- subcommand_name = ''
-
- if (subcommand_name and six.PY2 and
- isinstance(subcommand_name, six.text_type)):
- # NOTE(sigmavirus24): if we found a subcommand name, then let's
- # find it in the argv list and replace it with a bytes object
- # instead. Note, that if we encode the argument on Python 3, the
- # user will instead see a pesky `b'` string instead of the `u'`
- # string we mention above.
- subcommand_index = argv.index(subcommand_name)
- argv[subcommand_index] = encodeutils.safe_encode(subcommand_name)
-
@utils.arg('command', metavar='<subcommand>', nargs='?',
help='Display help for <subcommand>.')
def do_help(self, args, parser):
diff --git a/glanceclient/tests/unit/test_http.py b/glanceclient/tests/unit/test_http.py
index 0cf8f5b..5759ccd 100644
--- a/glanceclient/tests/unit/test_http.py
+++ b/glanceclient/tests/unit/test_http.py
@@ -19,13 +19,13 @@ from unittest import mock
import uuid
import fixtures
+import io
from keystoneauth1 import session
from keystoneauth1 import token_endpoint
from oslo_utils import encodeutils
import requests
from requests_mock.contrib import fixture
-import six
-from six.moves.urllib import parse
+from urllib import parse
from testscenarios import load_tests_apply_scenarios as load_tests # noqa
import testtools
from testtools import matchers
@@ -267,6 +267,20 @@ class TestClient(testtools.TestCase):
self.assertEqual(b"application/openstack-images-v2.1-json-patch",
ksarqh[b"Content-Type"])
+ def test_request_id_header_session_client(self):
+ global_id = "req-%s" % uuid.uuid4()
+ kwargs = {'global_request_id': global_id}
+ auth = token_endpoint.Token(self.endpoint, self.token)
+ sess = session.Session(auth=auth)
+ http_client = http.SessionClient(sess, **kwargs)
+
+ path = '/v2/images/my-image'
+ self.mock.get(self.endpoint + path)
+ http_client.get(path)
+
+ headers = self.mock.last_request.headers
+ self.assertEqual(global_id, headers['X-OpenStack-Request-ID'])
+
def test_raw_request(self):
"""Verify the path being used for HTTP requests reflects accurately."""
headers = {"Content-Type": "text/plain"}
@@ -296,14 +310,14 @@ class TestClient(testtools.TestCase):
def test__chunk_body_exact_size_chunk(self):
test_client = http._BaseHTTPClient()
bytestring = b'x' * http.CHUNKSIZE
- data = six.BytesIO(bytestring)
+ data = io.BytesIO(bytestring)
chunk = list(test_client._chunk_body(data))
self.assertEqual(1, len(chunk))
self.assertEqual([bytestring], chunk)
def test_http_chunked_request(self):
text = "Ok"
- data = six.StringIO(text)
+ data = io.StringIO(text)
path = '/v1/images/'
self.mock.post(self.endpoint + path, text=text)
@@ -322,13 +336,13 @@ class TestClient(testtools.TestCase):
resp, body = self.client.post(path, headers=headers, data=data)
self.assertEqual(text, resp.text)
- self.assertIsInstance(self.mock.last_request.body, six.string_types)
+ self.assertIsInstance(self.mock.last_request.body, str)
self.assertEqual(data, json.loads(self.mock.last_request.body))
def test_http_chunked_response(self):
data = "TEST"
path = '/v1/images/'
- self.mock.get(self.endpoint + path, body=six.StringIO(data),
+ self.mock.get(self.endpoint + path, body=io.StringIO(data),
headers={"Content-Type": "application/octet-stream"})
resp, body = self.client.get(path)
@@ -341,7 +355,7 @@ class TestClient(testtools.TestCase):
response = 'Ok'
headers = {"Content-Type": "text/plain",
"test": "value1\xa5\xa6"}
- fake = utils.FakeResponse(headers, six.StringIO(response))
+ fake = utils.FakeResponse(headers, io.StringIO(response))
self.client.log_http_response(fake)
except UnicodeDecodeError as e:
self.fail("Unexpected UnicodeDecodeError exception '%s'" % e)
@@ -444,7 +458,7 @@ class TestClient(testtools.TestCase):
logger = self.useFixture(fixtures.FakeLogger(level=logging.DEBUG))
data = "TEST"
path = '/v1/images/'
- self.mock.get(self.endpoint + path, body=six.StringIO(data),
+ self.mock.get(self.endpoint + path, body=io.StringIO(data),
headers={"Content-Type": "application/octet-stream",
'x-openstack-request-id': "1234"})
diff --git a/glanceclient/tests/unit/test_progressbar.py b/glanceclient/tests/unit/test_progressbar.py
index 76f96fb..d0596d5 100644
--- a/glanceclient/tests/unit/test_progressbar.py
+++ b/glanceclient/tests/unit/test_progressbar.py
@@ -13,10 +13,10 @@
# License for the specific language governing permissions and limitations
# under the License.
+import io
import sys
import requests
-import six
import testtools
from glanceclient.common import progressbar
@@ -49,7 +49,7 @@ class TestProgressBarWrapper(testtools.TestCase):
def test_iter_file_display_progress_bar(self):
size = 98304
- file_obj = six.StringIO('X' * size)
+ file_obj = io.StringIO('X' * size)
saved_stdout = sys.stdout
try:
sys.stdout = output = test_utils.FakeTTYStdout()
@@ -67,7 +67,7 @@ class TestProgressBarWrapper(testtools.TestCase):
def test_iter_file_no_tty(self):
size = 98304
- file_obj = six.StringIO('X' * size)
+ file_obj = io.StringIO('X' * size)
saved_stdout = sys.stdout
try:
sys.stdout = output = test_utils.FakeNoTTYStdout()
diff --git a/glanceclient/tests/unit/test_shell.py b/glanceclient/tests/unit/test_shell.py
index b23591f..74d1c33 100644
--- a/glanceclient/tests/unit/test_shell.py
+++ b/glanceclient/tests/unit/test_shell.py
@@ -17,6 +17,7 @@
import argparse
from collections import OrderedDict
import hashlib
+import io
import logging
import os
import sys
@@ -28,7 +29,6 @@ import fixtures
from keystoneauth1 import exceptions as ks_exc
from keystoneauth1 import fixture as ks_fixture
from requests_mock.contrib import fixture as rm_fixture
-import six
from glanceclient.common import utils
from glanceclient import exc
@@ -144,8 +144,8 @@ class ShellTest(testutils.TestCase):
orig = sys.stdout
orig_stderr = sys.stderr
try:
- sys.stdout = six.StringIO()
- sys.stderr = six.StringIO()
+ sys.stdout = io.StringIO()
+ sys.stderr = io.StringIO()
_shell = openstack_shell.OpenStackImagesShell()
_shell.main(argstr.split())
except SystemExit:
@@ -160,42 +160,13 @@ class ShellTest(testutils.TestCase):
sys.stderr = orig_stderr
return (stdout, stderr)
- def test_fixup_subcommand(self):
- arglist = [u'image-list', u'--help']
- if six.PY2:
- expected_arglist = [b'image-list', u'--help']
- elif six.PY3:
- expected_arglist = [u'image-list', u'--help']
-
- openstack_shell.OpenStackImagesShell._fixup_subcommand(
- arglist, arglist
- )
- self.assertEqual(expected_arglist, arglist)
-
- def test_fixup_subcommand_with_options_preceding(self):
- arglist = [u'--os-auth-token', u'abcdef', u'image-list', u'--help']
- unknown = arglist[2:]
- if six.PY2:
- expected_arglist = [
- u'--os-auth-token', u'abcdef', b'image-list', u'--help'
- ]
- elif six.PY3:
- expected_arglist = [
- u'--os-auth-token', u'abcdef', u'image-list', u'--help'
- ]
-
- openstack_shell.OpenStackImagesShell._fixup_subcommand(
- unknown, arglist
- )
- self.assertEqual(expected_arglist, arglist)
-
def test_help_unknown_command(self):
shell = openstack_shell.OpenStackImagesShell()
argstr = '--os-image-api-version 2 help foofoo'
self.assertRaises(exc.CommandError, shell.main, argstr.split())
- @mock.patch('sys.stdout', six.StringIO())
- @mock.patch('sys.stderr', six.StringIO())
+ @mock.patch('sys.stdout', io.StringIO())
+ @mock.patch('sys.stderr', io.StringIO())
@mock.patch('sys.argv', ['glance', 'help', 'foofoo'])
def test_no_stacktrace_when_debug_disabled(self):
with mock.patch.object(traceback, 'print_exc') as mock_print_exc:
@@ -205,8 +176,8 @@ class ShellTest(testutils.TestCase):
pass
self.assertFalse(mock_print_exc.called)
- @mock.patch('sys.stdout', six.StringIO())
- @mock.patch('sys.stderr', six.StringIO())
+ @mock.patch('sys.stdout', io.StringIO())
+ @mock.patch('sys.stderr', io.StringIO())
@mock.patch('sys.argv', ['glance', 'help', 'foofoo'])
def test_stacktrace_when_debug_enabled_by_env(self):
old_environment = os.environ.copy()
@@ -221,8 +192,8 @@ class ShellTest(testutils.TestCase):
finally:
os.environ = old_environment
- @mock.patch('sys.stdout', six.StringIO())
- @mock.patch('sys.stderr', six.StringIO())
+ @mock.patch('sys.stdout', io.StringIO())
+ @mock.patch('sys.stderr', io.StringIO())
@mock.patch('sys.argv', ['glance', '--debug', 'help', 'foofoo'])
def test_stacktrace_when_debug_enabled(self):
with mock.patch.object(traceback, 'print_exc') as mock_print_exc:
@@ -589,8 +560,8 @@ class ShellTest(testutils.TestCase):
self.assertRaises(exc.CommandError, glance_shell.main, args.split())
@mock.patch('sys.argv', ['glance'])
- @mock.patch('sys.stdout', six.StringIO())
- @mock.patch('sys.stderr', six.StringIO())
+ @mock.patch('sys.stdout', io.StringIO())
+ @mock.patch('sys.stderr', io.StringIO())
def test_main_noargs(self):
# Ensure that main works with no command-line arguments
try:
@@ -781,7 +752,7 @@ class ShellCacheSchemaTest(testutils.TestCase):
return Args(args)
- @mock.patch('six.moves.builtins.open', new=mock.mock_open(), create=True)
+ @mock.patch('builtins.open', new=mock.mock_open(), create=True)
@mock.patch('os.path.exists', return_value=True)
def test_cache_schemas_gets_when_forced(self, exists_mock):
options = {
@@ -804,7 +775,7 @@ class ShellCacheSchemaTest(testutils.TestCase):
actual = json.loads(open.mock_calls[6][1][0])
self.assertEqual(schema_odict, actual)
- @mock.patch('six.moves.builtins.open', new=mock.mock_open(), create=True)
+ @mock.patch('builtins.open', new=mock.mock_open(), create=True)
@mock.patch('os.path.exists', side_effect=[True, False, False, False])
def test_cache_schemas_gets_when_not_exists(self, exists_mock):
options = {
@@ -827,7 +798,7 @@ class ShellCacheSchemaTest(testutils.TestCase):
actual = json.loads(open.mock_calls[6][1][0])
self.assertEqual(schema_odict, actual)
- @mock.patch('six.moves.builtins.open', new=mock.mock_open(), create=True)
+ @mock.patch('builtins.open', new=mock.mock_open(), create=True)
@mock.patch('os.path.exists', return_value=True)
def test_cache_schemas_leaves_when_present_not_forced(self, exists_mock):
options = {
@@ -848,7 +819,7 @@ class ShellCacheSchemaTest(testutils.TestCase):
self.assertEqual(4, exists_mock.call_count)
self.assertEqual(0, open.mock_calls.__len__())
- @mock.patch('six.moves.builtins.open', new=mock.mock_open(), create=True)
+ @mock.patch('builtins.open', new=mock.mock_open(), create=True)
@mock.patch('os.path.exists', return_value=True)
def test_cache_schemas_leaves_auto_switch(self, exists_mock):
options = {
@@ -899,7 +870,7 @@ class ShellTestRequests(testutils.TestCase):
headers = {'Content-Length': '4',
'Content-type': 'application/octet-stream'}
- fake = testutils.FakeResponse(headers, six.StringIO('DATA'))
+ fake = testutils.FakeResponse(headers, io.StringIO('DATA'))
self.requests.get('http://example.com/v1/images/%s' % id,
raw=fake)
@@ -938,7 +909,7 @@ class ShellTestRequests(testutils.TestCase):
headers = {'Content-Length': '4',
'Content-type': 'application/octet-stream'}
- fake = testutils.FakeResponse(headers, six.StringIO('DATA'))
+ fake = testutils.FakeResponse(headers, io.StringIO('DATA'))
self.requests.get('http://example.com/v1/images/%s' % id,
headers=headers, raw=fake)
@@ -960,7 +931,7 @@ class ShellTestRequests(testutils.TestCase):
id = image_show_fixture['id']
headers = {'Content-Length': '4',
'Content-type': 'application/octet-stream'}
- fake = testutils.FakeResponse(headers, six.StringIO('DATA'))
+ fake = testutils.FakeResponse(headers, io.StringIO('DATA'))
self.requests = self.useFixture(rm_fixture.Fixture())
self.requests.get('http://example.com/v2/images/%s/file' % id,
diff --git a/glanceclient/tests/unit/test_ssl.py b/glanceclient/tests/unit/test_ssl.py
index 320dfde..f95e777 100644
--- a/glanceclient/tests/unit/test_ssl.py
+++ b/glanceclient/tests/unit/test_ssl.py
@@ -16,7 +16,6 @@
import os
from unittest import mock
-import six
import ssl
import testtools
import threading
@@ -26,10 +25,7 @@ from glanceclient import exc
from glanceclient import v1
from glanceclient import v2
-if six.PY3 is True:
- import socketserver
-else:
- import SocketServer as socketserver
+import socketserver
TEST_VAR_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__),
@@ -217,9 +213,7 @@ class TestHTTPSVerifyCert(testtools.TestCase):
# starting from python 2.7.8 the way to handle loading private
# keys into the SSL_CTX was changed and error message become
# similar to the one in 3.X
- if (six.PY2 and 'PrivateKey' not in e.message and
- 'PEM lib' not in e.message or
- six.PY3 and 'PEM lib' not in e.message):
+ if 'PEM lib' not in e.message:
self.fail('No appropriate failure message is received')
@mock.patch('sys.stderr')
diff --git a/glanceclient/tests/unit/test_utils.py b/glanceclient/tests/unit/test_utils.py
index 6128d6c..46cefbf 100644
--- a/glanceclient/tests/unit/test_utils.py
+++ b/glanceclient/tests/unit/test_utils.py
@@ -13,14 +13,13 @@
# License for the specific language governing permissions and limitations
# under the License.
+import io
import sys
from unittest import mock
from oslo_utils import encodeutils
from requests import Response
-import six
# NOTE(jokke): simplified transition to py3, behaves like py2 xrange
-from six.moves import range
import testtools
from glanceclient.common import utils
@@ -47,7 +46,7 @@ class TestUtils(testtools.TestCase):
def test_get_new_file_size(self):
size = 98304
- file_obj = six.StringIO('X' * size)
+ file_obj = io.StringIO('X' * size)
try:
self.assertEqual(size, utils.get_file_size(file_obj))
# Check that get_file_size didn't change original file position.
@@ -57,7 +56,7 @@ class TestUtils(testtools.TestCase):
def test_get_consumed_file_size(self):
size, consumed = 98304, 304
- file_obj = six.StringIO('X' * size)
+ file_obj = io.StringIO('X' * size)
file_obj.seek(consumed)
try:
self.assertEqual(size, utils.get_file_size(file_obj))
@@ -79,10 +78,10 @@ class TestUtils(testtools.TestCase):
saved_stdout = sys.stdout
try:
- sys.stdout = output_list = six.StringIO()
+ sys.stdout = output_list = io.StringIO()
utils.print_list(images, columns)
- sys.stdout = output_dict = six.StringIO()
+ sys.stdout = output_dict = io.StringIO()
utils.print_dict({'K': 'k', 'Key': 'veeeeeeeeeeeeeeeeeeeeeeee'
'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'
'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'
@@ -126,7 +125,7 @@ class TestUtils(testtools.TestCase):
'tags': [u'Name1', u'Tag_123', u'veeeery long']})]
saved_stdout = sys.stdout
try:
- sys.stdout = output_list = six.StringIO()
+ sys.stdout = output_list = io.StringIO()
utils.print_list(images, columns)
finally:
@@ -145,7 +144,7 @@ class TestUtils(testtools.TestCase):
image = {'id': '42', 'virtual_size': 1337}
saved_stdout = sys.stdout
try:
- sys.stdout = output_list = six.StringIO()
+ sys.stdout = output_list = io.StringIO()
utils.print_image(image)
finally:
sys.stdout = saved_stdout
@@ -164,7 +163,7 @@ class TestUtils(testtools.TestCase):
image = {'id': '42', 'virtual_size': None}
saved_stdout = sys.stdout
try:
- sys.stdout = output_list = six.StringIO()
+ sys.stdout = output_list = io.StringIO()
utils.print_image(image)
finally:
sys.stdout = saved_stdout
@@ -181,13 +180,9 @@ class TestUtils(testtools.TestCase):
def test_unicode_key_value_to_string(self):
src = {u'key': u'\u70fd\u7231\u5a77'}
- expected = {'key': '\xe7\x83\xbd\xe7\x88\xb1\xe5\xa9\xb7'}
- if six.PY2:
- self.assertEqual(expected, utils.unicode_key_value_to_string(src))
- else:
- # u'xxxx' in PY3 is str, we will not get extra 'u' from cli
- # output in PY3
- self.assertEqual(src, utils.unicode_key_value_to_string(src))
+ # u'xxxx' in PY3 is str, we will not get extra 'u' from cli
+ # output in PY3
+ self.assertEqual(src, utils.unicode_key_value_to_string(src))
def test_schema_args_with_list_types(self):
# NOTE(flaper87): Regression for bug
@@ -240,7 +235,7 @@ class TestUtils(testtools.TestCase):
for chunk in i:
raise(IOError)
- data = six.moves.StringIO('somestring')
+ data = io.StringIO('somestring')
data.close = mock.Mock()
i = utils.IterableWithLength(data, 10)
self.assertRaises(IOError, _iterate, i)
diff --git a/glanceclient/tests/unit/v1/test_images.py b/glanceclient/tests/unit/v1/test_images.py
index 1f43b83..1af7412 100644
--- a/glanceclient/tests/unit/v1/test_images.py
+++ b/glanceclient/tests/unit/v1/test_images.py
@@ -14,11 +14,10 @@
# under the License.
import errno
+import io
import json
import testtools
-
-import six
-from six.moves.urllib import parse
+from urllib import parse
from glanceclient.tests import utils
from glanceclient.v1 import client
@@ -634,7 +633,7 @@ class ImageManagerTest(testtools.TestCase):
self.assertEqual({'a': 'b', 'c': 'd'}, image.properties)
def test_create_with_data(self):
- image_data = six.StringIO('XXX')
+ image_data = io.StringIO('XXX')
self.mgr.create(data=image_data)
expect_headers = {'x-image-meta-size': '3'}
expect = [('POST', '/v1/images', expect_headers, image_data)]
@@ -711,7 +710,7 @@ class ImageManagerTest(testtools.TestCase):
self.assertEqual(10, image.min_disk)
def test_update_with_data(self):
- image_data = six.StringIO('XXX')
+ image_data = io.StringIO('XXX')
self.mgr.update('1', data=image_data)
expect_headers = {'x-image-meta-size': '3',
'x-glance-registry-purge-props': 'false'}
@@ -744,10 +743,7 @@ class ImageManagerTest(testtools.TestCase):
def test_image_meta_from_headers_encoding(self):
value = u"ni\xf1o"
- if six.PY2:
- fields = {"x-image-meta-name": "ni\xc3\xb1o"}
- else:
- fields = {"x-image-meta-name": value}
+ fields = {"x-image-meta-name": value}
headers = self.mgr._image_meta_from_headers(fields)
self.assertEqual(value, headers["name"])
diff --git a/glanceclient/tests/unit/v1/test_shell.py b/glanceclient/tests/unit/v1/test_shell.py
index 5476a2f..46c6f68 100644
--- a/glanceclient/tests/unit/v1/test_shell.py
+++ b/glanceclient/tests/unit/v1/test_shell.py
@@ -15,11 +15,11 @@
# under the License.
import argparse
+import io
import json
import os
from unittest import mock
-import six
import subprocess
import tempfile
import testtools
@@ -34,12 +34,6 @@ import glanceclient.v1.shell as v1shell
from glanceclient.tests import utils
-if six.PY3:
- import io
- file_type = io.IOBase
-else:
- file_type = file
-
fixtures = {
'/v1/images/96d2c7e1-de4e-4612-8aa2-ba26610c804e': {
'PUT': (
@@ -351,7 +345,7 @@ class ShellInvalidEndpointandParameterTest(utils.TestCase):
@mock.patch('sys.stderr')
def test_image_create_missing_container_format_stdin_data(self, __):
# Fake that get_data_file method returns data
- self.mock_get_data_file.return_value = six.StringIO()
+ self.mock_get_data_file.return_value = io.StringIO()
e = self.assertRaises(exc.CommandError, self.run_command,
'--os-image-api-version 1 image-create'
' --disk-format qcow2')
@@ -361,7 +355,7 @@ class ShellInvalidEndpointandParameterTest(utils.TestCase):
@mock.patch('sys.stderr')
def test_image_create_missing_disk_format_stdin_data(self, __):
# Fake that get_data_file method returns data
- self.mock_get_data_file.return_value = six.StringIO()
+ self.mock_get_data_file.return_value = io.StringIO()
e = self.assertRaises(exc.CommandError, self.run_command,
'--os-image-api-version 1 image-create'
' --container-format bare')
@@ -574,7 +568,7 @@ class ShellStdinHandlingTests(testtools.TestCase):
self._do_update('44d2c7e1-de4e-4612-8aa2-ba26610c444f')
self.assertIn('data', self.collected_args[1])
- self.assertIsInstance(self.collected_args[1]['data'], file_type)
+ self.assertIsInstance(self.collected_args[1]['data'], io.IOBase)
self.assertEqual(b'Some Data',
self.collected_args[1]['data'].read())
@@ -599,7 +593,7 @@ class ShellStdinHandlingTests(testtools.TestCase):
self._do_update('44d2c7e1-de4e-4612-8aa2-ba26610c444f')
self.assertIn('data', self.collected_args[1])
- self.assertIsInstance(self.collected_args[1]['data'], file_type)
+ self.assertIsInstance(self.collected_args[1]['data'], io.IOBase)
self.assertEqual(b'Some Data\n',
self.collected_args[1]['data'].read())
diff --git a/glanceclient/tests/unit/v2/test_shell_v2.py b/glanceclient/tests/unit/v2/test_shell_v2.py
index 9c19551..3f1d77a 100644
--- a/glanceclient/tests/unit/v2/test_shell_v2.py
+++ b/glanceclient/tests/unit/v2/test_shell_v2.py
@@ -15,11 +15,11 @@
# under the License.
import argparse
from copy import deepcopy
+import io
import json
import os
from unittest import mock
-import six
import sys
import tempfile
import testtools
@@ -196,7 +196,7 @@ class ShellV2Test(testtools.TestCase):
@mock.patch('sys.stderr')
def test_image_create_missing_container_format_stdin_data(self, __):
# Fake that get_data_file method returns data
- self.mock_get_data_file.return_value = six.StringIO()
+ self.mock_get_data_file.return_value = io.StringIO()
e = self.assertRaises(exc.CommandError, self._run_command,
'--os-image-api-version 2 image-create'
' --disk-format qcow2')
@@ -206,7 +206,7 @@ class ShellV2Test(testtools.TestCase):
@mock.patch('sys.stderr')
def test_image_create_missing_disk_format_stdin_data(self, __):
# Fake that get_data_file method returns data
- self.mock_get_data_file.return_value = six.StringIO()
+ self.mock_get_data_file.return_value = io.StringIO()
e = self.assertRaises(exc.CommandError, self._run_command,
'--os-image-api-version 2 image-create'
' --container-format bare')
@@ -618,7 +618,7 @@ class ShellV2Test(testtools.TestCase):
'os_hash_value': None})
def test_do_image_create_with_multihash(self):
- self.mock_get_data_file.return_value = six.StringIO()
+ self.mock_get_data_file.return_value = io.StringIO()
try:
with open(tempfile.mktemp(), 'w+') as f:
f.write('Some data here')
@@ -694,7 +694,7 @@ class ShellV2Test(testtools.TestCase):
'container_format': 'bare', 'os_hidden': True})
def test_do_image_create_with_file(self):
- self.mock_get_data_file.return_value = six.StringIO()
+ self.mock_get_data_file.return_value = io.StringIO()
try:
file_name = None
with open(tempfile.mktemp(), 'w+') as f:
@@ -1412,7 +1412,7 @@ class ShellV2Test(testtools.TestCase):
self, mock_stdin, mock_do_stage, mock_do_import):
"""Backward compat -> handle this like a glance-direct"""
mock_stdin.isatty = lambda: False
- self.mock_get_data_file.return_value = six.StringIO()
+ self.mock_get_data_file.return_value = io.StringIO()
args = self._make_args(self.base_args)
with mock.patch.object(self.gc.images, 'create') as mocked_create:
with mock.patch.object(self.gc.images, 'get') as mocked_get:
@@ -1447,7 +1447,7 @@ class ShellV2Test(testtools.TestCase):
self, mock_stdin, mock_access, mock_do_stage, mock_do_import):
"""Backward compat -> handle this like a glance-direct"""
mock_stdin.isatty = lambda: True
- self.mock_get_data_file.return_value = six.StringIO()
+ self.mock_get_data_file.return_value = io.StringIO()
mock_access.return_value = True
my_args = self.base_args.copy()
my_args['file'] = 'fake-image-file.browncow'
@@ -1557,6 +1557,56 @@ class ShellV2Test(testtools.TestCase):
'id': 'pass', 'name': 'IMG-01', 'disk_format': 'vhd',
'container_format': 'bare', 'status': 'queued'})
+ @mock.patch('glanceclient.v2.shell.do_image_import')
+ @mock.patch('glanceclient.v2.shell.do_image_stage')
+ @mock.patch('sys.stdin', autospec=True)
+ def test_do_image_create_via_import_with_web_download_with_stores(
+ self, mock_stdin, mock_do_image_stage, mock_do_image_import):
+ temp_args = {'name': 'IMG-01',
+ 'disk_format': 'vhd',
+ 'container_format': 'bare',
+ 'uri': 'http://example.com/image.qcow',
+ 'import_method': 'web-download',
+ 'progress': False,
+ 'stores': 'file1,file2'}
+ tmp2_args = {'name': 'IMG-01',
+ 'disk_format': 'vhd',
+ 'container_format': 'bare',
+ 'uri': 'http://example.com/image.qcow',
+ 'import_method': 'web-download',
+ 'progress': False}
+ args = self._make_args(temp_args)
+ with mock.patch.object(self.gc.images, 'create') as mocked_create:
+ with mock.patch.object(self.gc.images, 'get') as mocked_get:
+ with mock.patch.object(self.gc.images,
+ 'get_import_info') as mocked_info:
+ with mock.patch.object(self.gc.images,
+ 'get_stores_info') as m_stores_info:
+
+ ignore_fields = ['self', 'access', 'schema']
+ expect_image = dict([(field, field) for field in
+ ignore_fields])
+ expect_image['id'] = 'pass'
+ expect_image['name'] = 'IMG-01'
+ expect_image['disk_format'] = 'vhd'
+ expect_image['container_format'] = 'bare'
+ expect_image['status'] = 'queued'
+ mocked_create.return_value = expect_image
+ mocked_get.return_value = expect_image
+ mocked_info.return_value = self.import_info_response
+ m_stores_info.return_value = self.stores_info_response
+ mock_stdin.isatty = lambda: True
+
+ test_shell.do_image_create_via_import(self.gc, args)
+ mock_do_image_stage.assert_not_called()
+ mock_do_image_import.assert_called_once()
+ mocked_create.assert_called_once_with(**tmp2_args)
+ mocked_get.assert_called_with('pass')
+ utils.print_dict.assert_called_with({
+ 'id': 'pass', 'name': 'IMG-01',
+ 'disk_format': 'vhd',
+ 'container_format': 'bare', 'status': 'queued'})
+
def test_do_image_update_no_user_props(self):
args = self._make_args({'id': 'pass', 'name': 'IMG-01',
'disk_format': 'vhd',
diff --git a/glanceclient/tests/unit/var/ca.crt b/glanceclient/tests/unit/var/ca.crt
index c149d8c..cfdda79 100644
--- a/glanceclient/tests/unit/var/ca.crt
+++ b/glanceclient/tests/unit/var/ca.crt
@@ -1,34 +1,36 @@
-----BEGIN CERTIFICATE-----
-MIIF7jCCA9YCCQDbl9qx7iIeJDANBgkqhkiG9w0BAQUFADCBuDEZMBcGA1UEChMQ
-T3BlbnN0YWNrIENBIE9yZzEaMBgGA1UECxMRT3BlbnN0YWNrIFRlc3QgQ0ExIzAh
-BgkqhkiG9w0BCQEWFGFkbWluQGNhLmV4YW1wbGUuY29tMREwDwYDVQQHEwhTdGF0
-ZSBDQTELMAkGA1UECBMCQ0ExCzAJBgNVBAYTAkFVMS0wKwYDVQQDEyRPcGVuc3Rh
-Y2sgVGVzdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMTIxMTE2MTI1MDE2WhcN
-NDAwNDAzMTI1MDE2WjCBuDEZMBcGA1UEChMQT3BlbnN0YWNrIENBIE9yZzEaMBgG
-A1UECxMRT3BlbnN0YWNrIFRlc3QgQ0ExIzAhBgkqhkiG9w0BCQEWFGFkbWluQGNh
-LmV4YW1wbGUuY29tMREwDwYDVQQHEwhTdGF0ZSBDQTELMAkGA1UECBMCQ0ExCzAJ
-BgNVBAYTAkFVMS0wKwYDVQQDEyRPcGVuc3RhY2sgVGVzdCBDZXJ0aWZpY2F0ZSBB
-dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC94cpBjwj2
-MD0w5j1Jlcy8Ljmk3r7CRaoV5vhWUrAWpT7Thxr/Ti0qAfZZRSIVpvBM0RlseH0Q
-toUJixuYMoNRPUQ74r/TRoO8HfjQDJfnXtWg2L7DRP8p4Zgj3vByBUCU+rKsbI/H
-Nssl/AronADbZXCoL5hJRN8euMYZGrt/Gh1ZotKE5gQlEjylDFlA3s3pn+ABLgzf
-7L7iufwV3zLdPRHCb6Ve8YvUmKfI6gy+WwTRhNhLz4Nj0uBthnj6QhnRXtxkNT7A
-aAStqKH6TtYRnk2Owh8ITFbtLQ0/MSV8jHAxMXx9AloBhEKxv3cIpgLH6lOCnj//
-Ql+H6/QWtmTUHzP1kBfMhTQnWTfR92QTcgEMiZ7a07VyVtLh+kp/G5IUqpM6Pyz/
-O6QDs7FF69bTpws7Ce916PPrGFZ9Gqvo/P0jXge8kYqO+a8QnTRldAxdUzPJCK9+
-Dyi2LWeHf8nPFYdwW9Ov6Jw1CKDYxjJg6KIwnrMPa2eUdPB6/OKkqr9/KemOoKQu
-4KSaYadFZbaJwt7JPZaHy6TpkGxW7Af8RqGrW6a6nWEFcfO2POuHcAHWL5LiRmni
-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
+MIIGVTCCBD2gAwIBAgIUEstxpjoCFDZo8K1Mmz7QIpYwSXIwDQYJKoZIhvcNAQEL
+BQAwgbgxCzAJBgNVBAYTAkFVMREwDwYDVQQIDAhTdGF0ZSBDQTELMAkGA1UEBwwC
+Q0ExGTAXBgNVBAoMEE9wZW5TdGFjayBDQSBPcmcxGjAYBgNVBAsMEU9wZW5TdGFj
+ayBUZXN0IENBMS0wKwYDVQQDDCRPcGVuc3RhY2sgVGVzdCBDZXJ0aWZpY2F0ZSBB
+dXRob3JpdHkxIzAhBgkqhkiG9w0BCQEWFGFkbWluQGNhLmV4YW1wbGUuY29tMCAX
+DTIwMDQwNzEyMjYwMVoYDzI5OTkwMTAxMTIyNjAxWjCBuDELMAkGA1UEBhMCQVUx
+ETAPBgNVBAgMCFN0YXRlIENBMQswCQYDVQQHDAJDQTEZMBcGA1UECgwQT3BlblN0
+YWNrIENBIE9yZzEaMBgGA1UECwwRT3BlblN0YWNrIFRlc3QgQ0ExLTArBgNVBAMM
+JE9wZW5zdGFjayBUZXN0IENlcnRpZmljYXRlIEF1dGhvcml0eTEjMCEGCSqGSIb3
+DQEJARYUYWRtaW5AY2EuZXhhbXBsZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4IC
+DwAwggIKAoICAQD6KfGpVSJsmhTgdbdovaaa3Qe4PeP+Dg9Y7muSggVQVlqUp3YB
+xUSo1RDoLyu1ci+KrNODr+kkD/Cbo8yJQCxqTzUpCw3tadFhUJOWvPaqdcYTA8R9
+p7Xjvw3Me7Q7xr4l0pCUIiz/kwxYxk+GCQyXzpXZm14zz+Qm8gz37eoW2jJfoyzA
+dB9Tp609Id7C6VHFCWZ2Zsa4+Ua/q+Pn7vLNJ61C2H5sfus8dtcGDzViDWwnWyHw
+spyR79rciV2yA3xeq09RvIx2SB1tc3S2Rxw7SmKeYcnkv6YplvhIG5QpErvp+URh
+De2wbbxzjFzJqFQO0Yh8IgTBIvQI02++lA8ZX84UDaxmrT92m8GfqQvb96em/H1k
+RKJTq0QqSC+BbGDeFxHkuOTJiOZm5Bnivpo0TAPwX6YqpadXARAFWw+fJiHCuFGr
+6ltD7zgRnx6SR5WNRNWmTZQNx7wC2Bm0cJ2ec0Asn+bl93RVloaNtbFJhkaN555G
+GnUDLvxiwIN7aMGviJLte/qIhkKTtxD7zxyk+PQhokPAiz8J9P8INDd3GzMvcRPX
+ufDoXjSGjSLzjVPMhkFxXaHHylBdEAtHxROKz5wJnHqCnKlyyyv0nGBPQxFjT+rb
+G0HFn1JjodPBLrwooPttDgkEnq5yBpDkhFuYdZbgwjvQ4p5qrCp3EbDJ/QIDAQAB
+o1MwUTAdBgNVHQ4EFgQUkfKdH+sf7F/69HDbvtZ/ggVDCt4wHwYDVR0jBBgwFoAU
+kfKdH+sf7F/69HDbvtZ/ggVDCt4wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0B
+AQsFAAOCAgEAsUIwMa+2lR2a77AaVDDJikt4twylxJudJ4WEerFWOJeshCUCEGZF
+udlkLDMl9/f7XjpWPH2jc8c1xoxO63GZiLumk8mO9VzleGW6O03fQ9z6pOE1ueSg
+WnqHQYLbb5KizbiLen4xpa13cjZ2KFKJBkBEn2yOXXSOGP/yuWf1nQ1QumHCFFxf
+SRrJaaVqR8Ow6yPIjeCFT0IyeoGP5ihlxTvgSo+HeQx1wuYcBIG6clx4BGEgUa2N
+kaUF6v6EBl/mfX6YkhzvDygaS3men1XRgAkNFPXN9L7XVQdAh2hJSenq73seCJcc
+lD6Pr4U3VdWaTNYNZqpySspfJ6vp4XGNJFWZiaHPC5CALjgMzljdq9Xohedl2v0i
+zFZ4T3Zd+RT1941yD5rqlTnaqscpPnZpEUkULjH63v42/vLRSVkZOb6uSdOTL/c3
+bxDr4ZbN6cPY5As+XADPgOALuiQql+bRYOZOQL6i5lwtepfvmT6YGZZMk0WKhDcD
+C/cWX7z7834T2yYez2OmFdTr1UCmGd9IqTTQ01JTgr02y5lCN5J4KlG0SQBnQeQB
+Pj+gi1WElCIsBIX67WNCss5bpzn+T9cvMD5w2uG94ceT7jbIQ8LQ5x90kn+4HKr0
+PnD937DKLY+HPbm5l9CIhmsX+mWUOcqqWSvxBWeJSk4Qk60K3G/oQeY=
-----END CERTIFICATE-----
diff --git a/glanceclient/tests/unit/var/certificate.crt b/glanceclient/tests/unit/var/certificate.crt
index 06c02ab..64b2291 100644
--- a/glanceclient/tests/unit/var/certificate.crt
+++ b/glanceclient/tests/unit/var/certificate.crt
@@ -1,66 +1,34 @@
-# Certificate:
-# Data:
-# Version: 3 (0x2)
-# Serial Number: 1 (0x1)
-# Signature Algorithm: sha1WithRSAEncryption
-# Issuer: O=Openstack CA Org, OU=Openstack Test CA/emailAddress=admin@ca.example.com,
-# L=State CA, ST=CA, C=AU, CN=Openstack Test Certificate Authority
-# Validity
-# Not Before: Nov 16 12:50:19 2012 GMT
-# Not After : Apr 3 12:50:19 2040 GMT
-# Subject: O=Openstack Test Org, OU=Openstack Test Unit/emailAddress=admin@example.com,
-# L=State1, ST=CA, C=US, CN=0.0.0.0
-# Subject Public Key Info:
-# Public Key Algorithm: rsaEncryption
-# RSA Public Key: (4096 bit)
-# Modulus (4096 bit):
-# 00:d4:bb:3a:c4:a0:06:54:31:23:5d:b0:78:5a:be:
-# 45:44:ae:a1:89:86:11:d8:ca:a8:33:b0:4f:f3:e1:
-# .
-# .
-# .
-# Exponent: 65537 (0x10001)
-# X509v3 extensions:
-# X509v3 Subject Alternative Name:
-# DNS:alt1.example.com, DNS:alt2.example.com
-# Signature Algorithm: sha1WithRSAEncryption
-# 2c:fc:5c:87:24:bd:4a:fa:40:d2:2e:35:a4:2a:f3:1c:b3:67:
-# b0:e4:8a:cd:67:6b:55:50:d4:cb:dd:2d:26:a5:15:62:90:a3:
-# .
-# .
-# .
-----BEGIN CERTIFICATE-----
-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
-tdc5rw==
+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
+9l4gwJ1ojNB2abF4LOEf5bU=
-----END CERTIFICATE-----
diff --git a/glanceclient/tests/unit/var/privatekey.key b/glanceclient/tests/unit/var/privatekey.key
index 5b47d44..6cd8725 100644
--- a/glanceclient/tests/unit/var/privatekey.key
+++ b/glanceclient/tests/unit/var/privatekey.key
@@ -1,51 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
-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
+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
-----END RSA PRIVATE KEY-----
diff --git a/glanceclient/tests/utils.py b/glanceclient/tests/utils.py
index 3deddb1..730b928 100644
--- a/glanceclient/tests/utils.py
+++ b/glanceclient/tests/utils.py
@@ -14,10 +14,10 @@
# under the License.
import copy
+import io
import json
-import six
-import six.moves.urllib.parse as urlparse
import testtools
+from urllib import parse
from glanceclient.v2 import schemas
@@ -38,11 +38,11 @@ class FakeAPI(object):
fixture = self.fixtures[sort_url_by_query_keys(url)][method]
data = fixture[1]
- if isinstance(fixture[1], six.string_types):
+ if isinstance(fixture[1], str):
try:
data = json.loads(fixture[1])
except ValueError:
- data = six.StringIO(fixture[1])
+ data = io.StringIO(fixture[1])
return FakeResponse(fixture[0], fixture[1]), data
@@ -141,7 +141,7 @@ class FakeResponse(object):
@property
def text(self):
- if isinstance(self.content, six.binary_type):
+ if isinstance(self.content, bytes):
return self.content.decode('utf-8')
return self.content
@@ -166,7 +166,7 @@ class TestCase(testtools.TestCase):
'verify': True}
-class FakeTTYStdout(six.StringIO):
+class FakeTTYStdout(io.StringIO):
"""A Fake stdout that try to emulate a TTY device as much as possible."""
def isatty(self):
@@ -177,7 +177,7 @@ class FakeTTYStdout(six.StringIO):
if data.startswith('\r'):
self.seek(0)
data = data[1:]
- return six.StringIO.write(self, data)
+ return io.StringIO.write(self, data)
class FakeNoTTYStdout(FakeTTYStdout):
@@ -197,24 +197,24 @@ def sort_url_by_query_keys(url):
:param url: url which will be ordered by query keys
:returns url: url with ordered query keys
"""
- parsed = urlparse.urlparse(url)
- queries = urlparse.parse_qsl(parsed.query, True)
+ parsed = parse.urlparse(url)
+ queries = parse.parse_qsl(parsed.query, True)
sorted_query = sorted(queries, key=lambda x: x[0])
- encoded_sorted_query = urlparse.urlencode(sorted_query, True)
+ encoded_sorted_query = parse.urlencode(sorted_query, True)
url_parts = (parsed.scheme, parsed.netloc, parsed.path,
parsed.params, encoded_sorted_query,
parsed.fragment)
- return urlparse.urlunparse(url_parts)
+ return parse.urlunparse(url_parts)
def build_call_record(method, url, headers, data):
"""Key the request body be ordered if it's a dict type."""
if isinstance(data, dict):
data = sorted(data.items())
- if isinstance(data, six.string_types):
+ if isinstance(data, str):
# NOTE(flwang): For image update, the data will be a 'list' which
# contains operation dict, such as: [{"op": "remove", "path": "/a"}]
try:
diff --git a/glanceclient/v1/apiclient/base.py b/glanceclient/v1/apiclient/base.py
index a12a8cc..165e6de 100644
--- a/glanceclient/v1/apiclient/base.py
+++ b/glanceclient/v1/apiclient/base.py
@@ -41,8 +41,7 @@ import abc
import copy
from oslo_utils import strutils
-import six
-from six.moves.urllib import parse
+import urllib.parse
from glanceclient._i18n import _
from glanceclient.v1.apiclient import exceptions
@@ -224,8 +223,7 @@ class BaseManager(HookableMixin):
return self.client.delete(url)
-@six.add_metaclass(abc.ABCMeta)
-class ManagerWithFind(BaseManager):
+class ManagerWithFind(BaseManager, metaclass=abc.ABCMeta):
"""Manager with additional `find()`/`findall()` methods."""
@abc.abstractmethod
@@ -350,10 +348,11 @@ class CrudManager(BaseManager):
"""
kwargs = self._filter_kwargs(kwargs)
+ query = urllib.parse.urlencode(kwargs) if kwargs else '',
return self._list(
'%(base_url)s%(query)s' % {
'base_url': self.build_url(base_url=base_url, **kwargs),
- 'query': '?%s' % parse.urlencode(kwargs) if kwargs else '',
+ 'query': '?%s' % query,
},
self.collection_key)
@@ -389,10 +388,11 @@ class CrudManager(BaseManager):
"""
kwargs = self._filter_kwargs(kwargs)
+ query = urllib.parse.urlencode(kwargs) if kwargs else '',
rl = self._list(
'%(base_url)s%(query)s' % {
'base_url': self.build_url(base_url=base_url, **kwargs),
- 'query': '?%s' % parse.urlencode(kwargs) if kwargs else '',
+ 'query': '?%s' % query,
},
self.collection_key)
num = len(rl)
diff --git a/glanceclient/v1/apiclient/exceptions.py b/glanceclient/v1/apiclient/exceptions.py
index f3d778c..27b3eba 100644
--- a/glanceclient/v1/apiclient/exceptions.py
+++ b/glanceclient/v1/apiclient/exceptions.py
@@ -36,8 +36,6 @@ Exception definitions.
import inspect
import sys
-import six
-
from glanceclient._i18n import _
@@ -461,7 +459,7 @@ def from_response(response, method, url):
kwargs["message"] = (error.get("message") or
error.get("faultstring"))
kwargs["details"] = (error.get("details") or
- six.text_type(body))
+ str(body))
elif content_type.startswith("text/"):
kwargs["details"] = getattr(response, 'text', '')
diff --git a/glanceclient/v1/apiclient/utils.py b/glanceclient/v1/apiclient/utils.py
index 814a37b..7d3e4e0 100644
--- a/glanceclient/v1/apiclient/utils.py
+++ b/glanceclient/v1/apiclient/utils.py
@@ -26,7 +26,6 @@
from oslo_utils import encodeutils
from oslo_utils import uuidutils
-import six
from glanceclient._i18n import _
from glanceclient.v1.apiclient import exceptions
@@ -52,10 +51,7 @@ def find_resource(manager, name_or_id, **find_args):
# now try to get entity as uuid
try:
- if six.PY2:
- tmp_id = encodeutils.safe_encode(name_or_id)
- else:
- tmp_id = encodeutils.safe_decode(name_or_id)
+ tmp_id = encodeutils.safe_decode(name_or_id)
if uuidutils.is_uuid_like(tmp_id):
return manager.get(tmp_id)
diff --git a/glanceclient/v1/images.py b/glanceclient/v1/images.py
index 966d45a..b8e2ee2 100644
--- a/glanceclient/v1/images.py
+++ b/glanceclient/v1/images.py
@@ -17,8 +17,7 @@ import copy
from oslo_utils import encodeutils
from oslo_utils import strutils
-import six
-import six.moves.urllib.parse as urlparse
+import urllib.parse
from glanceclient.common import utils
from glanceclient.v1.apiclient import base
@@ -101,7 +100,7 @@ class ImageManager(base.ManagerWithFind):
# headers will be encoded later, before the
# request is sent.
def to_str(value):
- if not isinstance(value, six.string_types):
+ if not isinstance(value, str):
return str(value)
return value
@@ -129,7 +128,7 @@ class ImageManager(base.ManagerWithFind):
"""
image_id = base.getid(image)
resp, body = self.client.head('/v1/images/%s'
- % urlparse.quote(str(image_id)))
+ % urllib.parse.quote(str(image_id)))
meta = self._image_meta_from_headers(resp.headers)
return_request_id = kwargs.get('return_req_id', None)
if return_request_id is not None:
@@ -145,7 +144,7 @@ class ImageManager(base.ManagerWithFind):
"""
image_id = base.getid(image)
resp, body = self.client.get('/v1/images/%s'
- % urlparse.quote(str(image_id)))
+ % urllib.parse.quote(str(image_id)))
content_length = int(resp.headers.get('content-length', 0))
checksum = resp.headers.get('x-image-meta-checksum', None)
if do_checksum and checksum is not None:
@@ -225,7 +224,7 @@ class ImageManager(base.ManagerWithFind):
def paginate(qp, return_request_id=None):
for param, value in qp.items():
- if isinstance(value, six.string_types):
+ if isinstance(value, str):
# Note(flaper87) Url encoding should
# be moved inside http utils, at least
# shouldn't be here.
@@ -234,7 +233,7 @@ class ImageManager(base.ManagerWithFind):
# trying to encode them
qp[param] = encodeutils.safe_decode(value)
- url = '/v1/images/detail?%s' % urlparse.urlencode(qp)
+ url = '/v1/images/detail?%s' % urllib.parse.urlencode(qp)
images, resp = self._list(url, "images")
if return_request_id is not None:
diff --git a/glanceclient/v1/shell.py b/glanceclient/v1/shell.py
index 8a4d29d..682ca98 100644
--- a/glanceclient/v1/shell.py
+++ b/glanceclient/v1/shell.py
@@ -13,8 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from __future__ import print_function
-
import copy
import functools
import os
diff --git a/glanceclient/v2/images.py b/glanceclient/v2/images.py
index b07eecc..341485d 100644
--- a/glanceclient/v2/images.py
+++ b/glanceclient/v2/images.py
@@ -17,8 +17,7 @@ import hashlib
import json
from oslo_utils import encodeutils
from requests import codes
-import six
-from six.moves.urllib import parse
+import urllib.parse
import warlock
from glanceclient.common import utils
@@ -55,7 +54,7 @@ class Controller(object):
@staticmethod
def _wrap(value):
- if isinstance(value, six.string_types):
+ if isinstance(value, str):
return [value]
return value
@@ -142,19 +141,19 @@ class Controller(object):
tags_url_params = []
for tag in tags:
- if not isinstance(tag, six.string_types):
+ if not isinstance(tag, str):
raise exc.HTTPBadRequest("Invalid tag value %s" % tag)
tags_url_params.append({'tag': encodeutils.safe_encode(tag)})
for param, value in filters.items():
- if isinstance(value, six.string_types):
+ if isinstance(value, str):
filters[param] = encodeutils.safe_encode(value)
- url = '/v2/images?%s' % parse.urlencode(filters)
+ url = '/v2/images?%s' % urllib.parse.urlencode(filters)
for param in tags_url_params:
- url = '%s&%s' % (url, parse.urlencode(param))
+ url = '%s&%s' % (url, urllib.parse.urlencode(param))
if 'sort' in kwargs:
if 'sort_key' in kwargs or 'sort_dir' in kwargs:
@@ -178,7 +177,7 @@ class Controller(object):
for dir in sort_dir:
url = '%s&sort_dir=%s' % (url, dir)
- if isinstance(kwargs.get('marker'), six.string_types):
+ if isinstance(kwargs.get('marker'), str):
url = '%s&marker=%s' % (url, kwargs['marker'])
for image, resp in paginate(url, page_size, limit):
diff --git a/glanceclient/v2/metadefs.py b/glanceclient/v2/metadefs.py
index a6df87a..1b641ac 100644
--- a/glanceclient/v2/metadefs.py
+++ b/glanceclient/v2/metadefs.py
@@ -14,8 +14,7 @@
# under the License.
from oslo_utils import encodeutils
-import six
-from six.moves.urllib import parse
+import urllib.parse
import warlock
from glanceclient.common import utils
@@ -89,7 +88,7 @@ class NamespaceController(object):
@utils.add_req_id_to_object()
def _get(self, namespace, header=None, **kwargs):
"""Get one namespace."""
- query_params = parse.urlencode(kwargs)
+ query_params = urllib.parse.urlencode(kwargs)
if kwargs:
query_params = '?%s' % query_params
@@ -179,10 +178,10 @@ class NamespaceController(object):
for param, value in filters.items():
if isinstance(value, list):
filters[param] = encodeutils.safe_encode(','.join(value))
- elif isinstance(value, six.string_types):
+ elif isinstance(value, str):
filters[param] = encodeutils.safe_encode(value)
- url = '/v2/metadefs/namespaces?%s' % parse.urlencode(filters)
+ url = '/v2/metadefs/namespaces?%s' % urllib.parse.urlencode(filters)
for namespace, resp in paginate(url):
yield namespace, resp
diff --git a/glanceclient/v2/shell.py b/glanceclient/v2/shell.py
index 8414308..592b2da 100644
--- a/glanceclient/v2/shell.py
+++ b/glanceclient/v2/shell.py
@@ -235,6 +235,9 @@ def do_image_create_via_import(gc, args):
# determine if backend is valid
_validate_backend(backend, gc)
elif stores:
+ # NOTE(jokke): Making sure here that we do not include the stores in
+ # the create call
+ fields.pop("stores")
stores = str(stores).split(',')
for store in stores:
# determine if backend is valid
diff --git a/glanceclient/v2/tasks.py b/glanceclient/v2/tasks.py
index 177c8bf..6649f4b 100644
--- a/glanceclient/v2/tasks.py
+++ b/glanceclient/v2/tasks.py
@@ -14,8 +14,9 @@
# License for the specific language governing permissions and limitations
# under the License.
+import urllib.parse
+
from oslo_utils import encodeutils
-import six
import warlock
from glanceclient.common import utils
@@ -85,10 +86,10 @@ class Controller(object):
% ', '.join(SORT_DIR_VALUES))
for param, value in filters.items():
- if isinstance(value, six.string_types):
+ if isinstance(value, str):
filters[param] = encodeutils.safe_encode(value)
- url = '/v2/tasks?%s' % six.moves.urllib.parse.urlencode(filters)
+ url = '/v2/tasks?%s' % urllib.parse.urlencode(filters)
for task, resp in paginate(url):
# NOTE(flwang): remove 'self' for now until we have an elegant
# way to pass it into the model constructor without conflict
diff --git a/lower-constraints.txt b/lower-constraints.txt
index ecb84ad..8e63056 100644
--- a/lower-constraints.txt
+++ b/lower-constraints.txt
@@ -2,11 +2,11 @@ alabaster==0.7.10
appdirs==1.3.0
asn1crypto==0.23.0
Babel==2.3.4
-cffi==1.7.0
+cffi==1.14.0
cliff==2.8.0
cmd2==0.8.0
coverage==4.0
-cryptography==2.1
+cryptography==2.7
ddt==1.2.1
debtcollector==1.2.0
docutils==0.11
@@ -31,7 +31,6 @@ monotonic==0.6
msgpack-python==0.4.0
netaddr==0.7.18
netifaces==0.10.4
-openstackdocstheme==1.20.0
ordereddict==1.1
os-client-config==1.28.0
os-testr==1.0.0
@@ -56,16 +55,12 @@ python-dateutil==2.5.3
python-mimeparse==1.6.0
python-subunit==1.0.0
pytz==2013.6
-PyYAML==3.12
-reno==2.5.0
+PyYAML==3.13
requests-mock==1.2.0
requests==2.14.2
requestsexceptions==1.2.0
rfc3986==0.3.1
-six==1.10.0
snowballstemmer==1.2.1
-Sphinx==1.6.2
-sphinxcontrib-websupport==1.0.1
stestr==2.0.0
stevedore==1.20.0
tempest==17.1.0
diff --git a/releasenotes/notes/fix_1889666-22dc97ce577eccc6.yaml b/releasenotes/notes/fix_1889666-22dc97ce577eccc6.yaml
new file mode 100644
index 0000000..553c377
--- /dev/null
+++ b/releasenotes/notes/fix_1889666-22dc97ce577eccc6.yaml
@@ -0,0 +1,6 @@
+---
+fixes:
+ - |
+ Bug 1889666_: 'stores' property added when using image-create-via-import --stores <list>
+
+ .. _1889666: https://bugs.launchpad.net/glance/+bug/1889666
diff --git a/releasenotes/notes/sess_client_grid-3c2101609110f413.yaml b/releasenotes/notes/sess_client_grid-3c2101609110f413.yaml
new file mode 100644
index 0000000..4552c43
--- /dev/null
+++ b/releasenotes/notes/sess_client_grid-3c2101609110f413.yaml
@@ -0,0 +1,6 @@
+---
+fixes:
+ - |
+ * Bug 1886650_: Glance client does not correctly forward global request IDs
+
+ .. _1886650: https://code.launchpad.net/bugs/1886650
diff --git a/releasenotes/source/conf.py b/releasenotes/source/conf.py
index 75aab4d..d20e2f4 100644
--- a/releasenotes/source/conf.py
+++ b/releasenotes/source/conf.py
@@ -29,8 +29,6 @@
# documentation root, use os.path.abspath to make it absolute, like shown here.
# sys.path.insert(0, os.path.abspath('.'))
-import openstackdocstheme
-
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
@@ -41,6 +39,7 @@ import openstackdocstheme
# ones.
extensions = [
'reno.sphinxext',
+ 'openstackdocstheme'
]
# Add any paths that contain templates here, relative to this directory.
@@ -59,6 +58,11 @@ master_doc = 'index'
project = u'glanceclient Release Notes'
copyright = u'2016, Glance Developers'
+openstackdocs_repo_name = 'openstack/python-glanceclient'
+openstackdocs_bug_project = 'python-glanceclient'
+openstackdocs_bug_tag = ''
+openstackdocs_auto_name = False
+
# Release notes are not versioned, so we don't need to set version or release
version = ''
release = ''
@@ -93,7 +97,7 @@ exclude_patterns = []
# show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
+pygments_style = 'native'
# A list of ignored prefixes for module index sorting.
# modindex_common_prefix = []
@@ -113,10 +117,6 @@ html_theme = 'openstackdocs'
# documentation.
# html_theme_options = {}
-# Add any paths that contain custom themes here, relative to this directory.
-# html_theme_path = []
-html_theme_path = [openstackdocstheme.get_html_theme_path()]
-
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
# html_title = None
diff --git a/requirements.txt b/requirements.txt
index 25b670a..ca8abaf 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -6,7 +6,6 @@ PrettyTable<0.8,>=0.7.1 # BSD
keystoneauth1>=3.6.2 # Apache-2.0
requests>=2.14.2 # Apache-2.0
warlock<2,>=1.2.0 # Apache-2.0
-six>=1.10.0 # MIT
oslo.utils>=3.33.0 # Apache-2.0
oslo.i18n>=3.15.3 # Apache-2.0
wrapt>=1.7.0 # BSD License
diff --git a/tox.ini b/tox.ini
index f001df9..13238b1 100644
--- a/tox.ini
+++ b/tox.ini
@@ -69,7 +69,7 @@ show-source = True
exclude = .venv*,.tox,dist,*egg,build,.git,doc,*lib/python*,.update-venv
[hacking]
-import_exceptions = six.moves,glanceclient._i18n
+import_exceptions = glanceclient._i18n
[testenv:lower-constraints]
basepython = python3