diff --git a/.zuul.yaml b/.zuul.yaml index 358e9079fe..af3a443754 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -9,25 +9,6 @@ - openstack/devstack-gate - openstack/glance -- job: - name: glance-eventlet-ssl-handshake-broken-py3 - parent: tox - description: | - See https://bugs.launchpad.net/glance/+bug/1482633 - vars: - tox_envlist: broken-py3-ssl-tests - irrelevant-files: - - ^(test-|)requirements.txt$ - - ^lower-constraints.txt$ - - ^.*\.rst$ - - ^api-ref/.*$ - - ^doc/.*$ - - ^etc/.*$ - - ^releasenotes/.*$ - - ^setup.cfg$ - - ^tox.ini$ - - ^\.zuul\.yaml$ - - job: name: glance-code-constants-check parent: tox @@ -231,8 +212,6 @@ jobs: - openstack-tox-functional - openstack-tox-functional-py37 - - glance-eventlet-ssl-handshake-broken-py3: - voting: false - glance-code-constants-check - devstack-plugin-ceph-tempest: voting: false diff --git a/broken-functional-py3-ssl-tests.txt b/broken-functional-py3-ssl-tests.txt deleted file mode 100644 index 58c55b3901..0000000000 --- a/broken-functional-py3-ssl-tests.txt +++ /dev/null @@ -1,2 +0,0 @@ -^glance\.tests\.functional\.test_reload\.TestReload\.test_reload$ -^glance\.tests\.functional\.test_ssl\.TestSSL\.test_ssl_ok$ diff --git a/glance/common/utils.py b/glance/common/utils.py index 3ea76e3b01..b4144f1823 100644 --- a/glance/common/utils.py +++ b/glance/common/utils.py @@ -31,12 +31,9 @@ from eventlet.green import socket import functools import os import re -import uuid -from OpenSSL import crypto from oslo_config import cfg from oslo_log import log as logging -from oslo_utils import encodeutils from oslo_utils import excutils from oslo_utils import netutils from oslo_utils import strutils @@ -46,7 +43,7 @@ from webob import exc from glance.common import exception from glance.common import timeutils -from glance.i18n import _, _LE, _LW +from glance.i18n import _, _LE CONF = cfg.CONF @@ -440,61 +437,6 @@ def setup_remote_pydev_debug(host, port): LOG.exception(error_msg) -def validate_key_cert(key_file, cert_file): - try: - error_key_name = "private key" - error_filename = key_file - with open(key_file, 'r') as keyfile: - key_str = keyfile.read() - key = crypto.load_privatekey(crypto.FILETYPE_PEM, key_str) - - error_key_name = "certificate" - error_filename = cert_file - with open(cert_file, 'r') as certfile: - cert_str = certfile.read() - cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert_str) - except IOError as ioe: - raise RuntimeError(_("There is a problem with your %(error_key_name)s " - "%(error_filename)s. Please verify it." - " Error: %(ioe)s") % - {'error_key_name': error_key_name, - 'error_filename': error_filename, - 'ioe': ioe}) - except crypto.Error as ce: - raise RuntimeError(_("There is a problem with your %(error_key_name)s " - "%(error_filename)s. Please verify it. OpenSSL" - " error: %(ce)s") % - {'error_key_name': error_key_name, - 'error_filename': error_filename, - 'ce': ce}) - - try: - data = str(uuid.uuid4()) - # On Python 3, explicitly encode to UTF-8 to call crypto.sign() which - # requires bytes. Otherwise, it raises a deprecation warning (and - # will raise an error later). - data = encodeutils.to_utf8(data) - digest = CONF.digest_algorithm - if digest == 'sha1': - LOG.warn( - _LW('The FIPS (FEDERAL INFORMATION PROCESSING STANDARDS)' - ' state that the SHA-1 is not suitable for' - ' general-purpose digital signature applications (as' - ' specified in FIPS 186-3) that require 112 bits of' - ' security. The default value is sha1 in Kilo for a' - ' smooth upgrade process, and it will be updated' - ' with sha256 in next release(L).')) - out = crypto.sign(key, data, digest) - crypto.verify(cert, out, data, digest) - except crypto.Error as ce: - raise RuntimeError(_("There is a problem with your key pair. " - "Please verify that cert %(cert_file)s and " - "key %(key_file)s belong together. OpenSSL " - "error %(ce)s") % {'cert_file': cert_file, - 'key_file': key_file, - 'ce': ce}) - - def get_test_suite_socket(): global GLANCE_TEST_SOCKET_FD_STR if GLANCE_TEST_SOCKET_FD_STR in os.environ: diff --git a/glance/common/wsgi.py b/glance/common/wsgi.py index e63fa4a517..95b2ebcf18 100644 --- a/glance/common/wsgi.py +++ b/glance/common/wsgi.py @@ -34,7 +34,6 @@ import threading import time from eventlet.green import socket -from eventlet.green import ssl import eventlet.greenio import eventlet.wsgi import glance_store @@ -143,67 +142,6 @@ Possible values: Related options: * None -""")), - - cfg.StrOpt('ca_file', - sample_default='/etc/ssl/cafile', - help=_(""" -Absolute path to the CA file. - -Provide a string value representing a valid absolute path to -the Certificate Authority file to use for client authentication. - -A CA file typically contains necessary trusted certificates to -use for the client authentication. This is essential to ensure -that a secure connection is established to the server via the -internet. - -Possible values: - * Valid absolute path to the CA file - -Related options: - * None - -""")), - - cfg.StrOpt('cert_file', - sample_default='/etc/ssl/certs', - help=_(""" -Absolute path to the certificate file. - -Provide a string value representing a valid absolute path to the -certificate file which is required to start the API service -securely. - -A certificate file typically is a public key container and includes -the server's public key, server name, server information and the -signature which was a result of the verification process using the -CA certificate. This is required for a secure connection -establishment. - -Possible values: - * Valid absolute path to the certificate file - -Related options: - * None - -""")), - - cfg.StrOpt('key_file', - sample_default='/etc/ssl/key/key-file.pem', - help=_(""" -Absolute path to a private key file. - -Provide a string value representing a valid absolute path to a -private key file which is required to establish the client-server -connection. - -Possible values: - * Absolute path to the private key file - -Related options: - * None - """)), ] @@ -402,30 +340,6 @@ def get_bind_addr(default_port=None): return (CONF.bind_host, CONF.bind_port or default_port) -def ssl_wrap_socket(sock): - """ - Wrap an existing socket in SSL - - :param sock: non-SSL socket to wrap - - :returns: An SSL wrapped socket - """ - utils.validate_key_cert(CONF.key_file, CONF.cert_file) - - ssl_kwargs = { - 'server_side': True, - 'certfile': CONF.cert_file, - 'keyfile': CONF.key_file, - 'cert_reqs': ssl.CERT_NONE, - } - - if CONF.ca_file: - ssl_kwargs['ca_certs'] = CONF.ca_file - ssl_kwargs['cert_reqs'] = ssl.CERT_REQUIRED - - return ssl.wrap_socket(sock, **ssl_kwargs) - - def get_socket(default_port): """ Bind socket to bind ip:port in conf @@ -434,8 +348,7 @@ def get_socket(default_port): :param default_port: port to bind to if none is specified in conf - :returns: a socket object as returned from socket.listen or - ssl.wrap_socket if conf specifies cert_file + :returns: a socket object as returned from socket.listen """ bind_addr = get_bind_addr(default_port) @@ -450,12 +363,6 @@ def get_socket(default_port): if addr[0] in (socket.AF_INET, socket.AF_INET6) ][0] - use_ssl = CONF.key_file or CONF.cert_file - if use_ssl and (not CONF.key_file or not CONF.cert_file): - raise RuntimeError(_("When running server in SSL mode, you must " - "specify both a cert_file and key_file " - "option value in your configuration file")) - sock = utils.get_test_suite_socket() retry_until = time.time() + 30 @@ -701,16 +608,6 @@ class BaseServer(object): new_sock = (old_conf is None or ( has_changed('bind_host') or has_changed('bind_port'))) - # Will we be using https? - use_ssl = not (not CONF.cert_file or not CONF.key_file) - # Were we using https before? - old_use_ssl = (old_conf is not None and not ( - not old_conf.get('key_file') or - not old_conf.get('cert_file'))) - # Do we now need to perform an SSL wrap on the socket? - wrap_sock = use_ssl is True and (old_use_ssl is False or new_sock) - # Do we now need to perform an SSL unwrap on the socket? - unwrap_sock = use_ssl is False and old_use_ssl is True if new_sock: self._sock = None @@ -722,25 +619,7 @@ class BaseServer(object): # sockets can hang around forever without keepalive _sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) - self._sock = _sock - - if wrap_sock: - self.sock = ssl_wrap_socket(self._sock) - - if unwrap_sock: - self.sock = self._sock - - if new_sock and not use_ssl: - self.sock = self._sock - - # Pick up newly deployed certs - if old_conf is not None and use_ssl is True and old_use_ssl is True: - if has_changed('cert_file') or has_changed('key_file'): - utils.validate_key_cert(CONF.key_file, CONF.cert_file) - if has_changed('cert_file'): - self.sock.certfile = CONF.cert_file - if has_changed('key_file'): - self.sock.keyfile = CONF.key_file + self.sock = _sock if new_sock or (old_conf is not None and has_changed('tcp_keepidle')): # This option isn't available in the OS X version of eventlet @@ -982,19 +861,13 @@ class Win32Server(BaseServer): def configure_socket(self, old_conf=None, has_changed=None): fresh_start = not (old_conf or has_changed) - use_ssl = CONF.cert_file or CONF.key_file pipe_handle = getattr(CONF, 'pipe_handle', None) if not (fresh_start and pipe_handle): return super(Win32Server, self).configure_socket( old_conf, has_changed) - self._sock = self._get_sock_from_parent() - - if use_ssl: - self.sock = ssl_wrap_socket(self._sock) - else: - self.sock = self._sock + self.sock = self._get_sock_from_parent() if hasattr(socket, 'TCP_KEEPIDLE'): # This was introduced in WS 2016 RS3 diff --git a/glance/tests/functional/__init__.py b/glance/tests/functional/__init__.py index 938313254f..9ee1a4d326 100644 --- a/glance/tests/functional/__init__.py +++ b/glance/tests/functional/__init__.py @@ -379,8 +379,6 @@ class ApiServer(Server): self.default_store = kwargs.get("default_store", "file") self.bind_host = "127.0.0.1" self.registry_host = "127.0.0.1" - self.key_file = "" - self.cert_file = "" self.metadata_encryption_key = "012345678901234567890123456789ab" self.image_dir = os.path.join(self.test_dir, "images") self.pid_file = pid_file or os.path.join(self.test_dir, "api.pid") @@ -421,8 +419,6 @@ debug = %(debug)s default_log_levels = eventlet.wsgi.server=DEBUG bind_host = %(bind_host)s bind_port = %(bind_port)s -key_file = %(key_file)s -cert_file = %(cert_file)s metadata_encryption_key = %(metadata_encryption_key)s registry_host = %(registry_host)s registry_port = %(registry_port)s @@ -560,8 +556,6 @@ class ApiServerForMultipleBackend(Server): self.default_backend = kwargs.get("default_backend", "file1") self.bind_host = "127.0.0.1" self.registry_host = "127.0.0.1" - self.key_file = "" - self.cert_file = "" self.metadata_encryption_key = "012345678901234567890123456789ab" self.image_dir_backend_1 = os.path.join(self.test_dir, "images_1") self.image_dir_backend_2 = os.path.join(self.test_dir, "images_2") @@ -605,8 +599,6 @@ debug = %(debug)s default_log_levels = eventlet.wsgi.server=DEBUG bind_host = %(bind_host)s bind_port = %(bind_port)s -key_file = %(key_file)s -cert_file = %(cert_file)s metadata_encryption_key = %(metadata_encryption_key)s registry_host = %(registry_host)s registry_port = %(registry_port)s diff --git a/glance/tests/functional/test_reload.py b/glance/tests/functional/test_reload.py index 710b030c33..f616a55db1 100644 --- a/glance/tests/functional/test_reload.py +++ b/glance/tests/functional/test_reload.py @@ -23,6 +23,7 @@ from six.moves import http_client as http from glance.tests import functional from glance.tests.utils import execute +from glance.tests.utils import skip_if_disabled TEST_VAR_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '../', 'var')) @@ -44,11 +45,16 @@ class TestReload(functional.FunctionalTest): """Test configuration reload""" def setUp(self): - self.workers = 1 super(TestReload, self).setUp() + self.cleanup() + self.workers = 1 + self.include_scrubber = False + self.disabled = True + self.disabled_message = "Reload is broken, Bug 1855708" def tearDown(self): - self.stop_servers() + if not self.disabled: + self.stop_servers() super(TestReload, self).tearDown() def ticker(self, message, seconds=60, tick=0.01): @@ -101,6 +107,7 @@ class TestReload(functional.FunctionalTest): def _url(self, protocol, path): return '%s://127.0.0.1:%d%s' % (protocol, self.api_port, path) + @skip_if_disabled def test_reload(self): """Test SIGHUP picks up new config values""" def check_pids(pre, post=None, workers=2): @@ -121,6 +128,13 @@ class TestReload(functional.FunctionalTest): pre_pids = {} post_pids = {} + path = self._url('http', '/') + response = requests.get(path) + self.assertEqual(http.MULTIPLE_CHOICES, response.status_code) + del response # close socket so that process audit is reliable + + pre_pids['api'] = self._get_children('api') + # Test changing the workers value creates all new children # This recycles the existing socket msg = 'Start timeout' @@ -145,88 +159,6 @@ class TestReload(functional.FunctionalTest): if check_pids(pre_pids['api'], post_pids['api']): break - # Test changing from http to https - # This recycles the existing socket - path = self._url('http', '/') - response = requests.get(path) - self.assertEqual(http.MULTIPLE_CHOICES, response.status_code) - del response # close socket so that process audit is reliable - - pre_pids['api'] = self._get_children('api') - key_file = os.path.join(TEST_VAR_DIR, 'privatekey.key') - set_config_value(self._conffile('api'), 'key_file', key_file) - cert_file = os.path.join(TEST_VAR_DIR, 'certificate.crt') - set_config_value(self._conffile('api'), 'cert_file', cert_file) - cmd = "kill -HUP %s" % self._get_parent('api') - execute(cmd, raise_error=True) - - msg = 'http to https timeout' - for _ in self.ticker(msg): - post_pids['api'] = self._get_children('api') - if check_pids(pre_pids['api'], post_pids['api']): - break - - ca_file = os.path.join(TEST_VAR_DIR, 'ca.crt') - path = self._url('https', '/') - response = requests.get(path, verify=ca_file) - self.assertEqual(http.MULTIPLE_CHOICES, response.status_code) - del response - - # Test https restart - # This recycles the existing socket - pre_pids['api'] = self._get_children('api') - cmd = "kill -HUP %s" % self._get_parent('api') - execute(cmd, raise_error=True) - - msg = 'https restart timeout' - for _ in self.ticker(msg): - post_pids['api'] = self._get_children('api') - if check_pids(pre_pids['api'], post_pids['api']): - break - - ca_file = os.path.join(TEST_VAR_DIR, 'ca.crt') - path = self._url('https', '/') - response = requests.get(path, verify=ca_file) - self.assertEqual(http.MULTIPLE_CHOICES, response.status_code) - del response - - # Test changing the https bind_host - # This requires a new socket - pre_pids['api'] = self._get_children('api') - set_config_value(self._conffile('api'), 'bind_host', '127.0.0.1') - cmd = "kill -HUP %s" % self._get_parent('api') - execute(cmd, raise_error=True) - - msg = 'https bind_host timeout' - for _ in self.ticker(msg): - post_pids['api'] = self._get_children('api') - if check_pids(pre_pids['api'], post_pids['api']): - break - - path = self._url('https', '/') - response = requests.get(path, verify=ca_file) - self.assertEqual(http.MULTIPLE_CHOICES, response.status_code) - del response - - # Test https -> http - # This recycles the existing socket - pre_pids['api'] = self._get_children('api') - set_config_value(self._conffile('api'), 'key_file', '') - set_config_value(self._conffile('api'), 'cert_file', '') - cmd = "kill -HUP %s" % self._get_parent('api') - execute(cmd, raise_error=True) - - msg = 'https to http timeout' - for _ in self.ticker(msg): - post_pids['api'] = self._get_children('api') - if check_pids(pre_pids['api'], post_pids['api']): - break - - path = self._url('http', '/') - response = requests.get(path) - self.assertEqual(http.MULTIPLE_CHOICES, response.status_code) - del response - # Test changing the http bind_host # This requires a new socket pre_pids['api'] = self._get_children('api') diff --git a/glance/tests/functional/test_ssl.py b/glance/tests/functional/test_ssl.py deleted file mode 100644 index 7b584c2def..0000000000 --- a/glance/tests/functional/test_ssl.py +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright 2015 OpenStack Foundation -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import os - -import httplib2 -from six.moves import http_client as http - -from glance.tests import functional - -TEST_VAR_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), - '..', 'var')) - - -class TestSSL(functional.FunctionalTest): - - """Functional tests verifying SSL communication""" - - def setUp(self): - super(TestSSL, self).setUp() - - if getattr(self, 'inited', False): - return - - self.inited = False - self.disabled = True - - # NOTE (stevelle): Test key/cert/CA file created as per: - # http://nrocco.github.io/2013/01/25/ - # self-signed-ssl-certificate-chains.html - # For these tests certificate.crt must be created with 'Common Name' - # set to 127.0.0.1 - - self.key_file = os.path.join(TEST_VAR_DIR, 'privatekey.key') - if not os.path.exists(self.key_file): - self.disabled_message = ("Could not find private key file %s" % - self.key_file) - self.inited = True - return - - self.cert_file = os.path.join(TEST_VAR_DIR, 'certificate.crt') - if not os.path.exists(self.cert_file): - self.disabled_message = ("Could not find certificate file %s" % - self.cert_file) - self.inited = True - return - - self.ca_file = os.path.join(TEST_VAR_DIR, 'ca.crt') - if not os.path.exists(self.ca_file): - self.disabled_message = ("Could not find CA file %s" % - self.ca_file) - self.inited = True - return - - self.inited = True - self.disabled = False - - def tearDown(self): - super(TestSSL, self).tearDown() - if getattr(self, 'inited', False): - return - - def test_ssl_ok(self): - """Make sure the public API works with HTTPS.""" - self.cleanup() - self.start_servers(**self.__dict__.copy()) - - path = "https://%s:%d/versions" % ("127.0.0.1", self.api_port) - https = httplib2.Http(ca_certs=self.ca_file) - response, content = https.request(path, 'GET') - self.assertEqual(http.OK, response.status) diff --git a/glance/tests/unit/common/test_utils.py b/glance/tests/unit/common/test_utils.py index 530f4d9c94..a19855d9bf 100644 --- a/glance/tests/unit/common/test_utils.py +++ b/glance/tests/unit/common/test_utils.py @@ -15,7 +15,6 @@ # under the License. import mock -import os import tempfile from oslo_log import log as logging @@ -326,46 +325,6 @@ class TestUtils(test_utils.BaseTestCase): result = utils.mutating(fake_function) self.assertEqual("test passed", result(req, Fake())) - def test_validate_key_cert_key(self): - self.config(digest_algorithm='sha256') - var_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), - '../../', 'var')) - keyfile = os.path.join(var_dir, 'privatekey.key') - certfile = os.path.join(var_dir, 'certificate.crt') - utils.validate_key_cert(keyfile, certfile) - - def test_validate_key_cert_no_private_key(self): - with tempfile.NamedTemporaryFile('w+') as tmpf: - self.assertRaises(RuntimeError, - utils.validate_key_cert, - "/not/a/file", tmpf.name) - - def test_validate_key_cert_cert_cant_read(self): - with tempfile.NamedTemporaryFile('w+') as keyf: - with tempfile.NamedTemporaryFile('w+') as certf: - os.chmod(certf.name, 0) - self.assertRaises(RuntimeError, - utils.validate_key_cert, - keyf.name, certf.name) - - def test_validate_key_cert_key_cant_read(self): - with tempfile.NamedTemporaryFile('w+') as keyf: - with tempfile.NamedTemporaryFile('w+') as certf: - os.chmod(keyf.name, 0) - self.assertRaises(RuntimeError, - utils.validate_key_cert, - keyf.name, certf.name) - - def test_invalid_digest_algorithm(self): - self.config(digest_algorithm='fake_algorithm') - var_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), - '../../', 'var')) - keyfile = os.path.join(var_dir, 'privatekey.key') - certfile = os.path.join(var_dir, 'certificate.crt') - self.assertRaises(ValueError, - utils.validate_key_cert, - keyfile, certfile) - def test_valid_hostname(self): valid_inputs = ['localhost', 'glance04-a' diff --git a/glance/tests/unit/common/test_wsgi.py b/glance/tests/unit/common/test_wsgi.py index 0a205b4330..94dd905f91 100644 --- a/glance/tests/unit/common/test_wsgi.py +++ b/glance/tests/unit/common/test_wsgi.py @@ -705,17 +705,11 @@ class GetSocketTestCase(test_utils.BaseTestCase): self.useFixture(fixtures.MonkeyPatch( "glance.common.wsgi.utils.validate_key_cert", lambda *x: None)) - wsgi.CONF.cert_file = '/etc/ssl/cert' - wsgi.CONF.key_file = '/etc/ssl/key' - wsgi.CONF.ca_file = '/etc/ssl/ca_cert' wsgi.CONF.tcp_keepidle = 600 @mock.patch.object(prefetcher, 'Prefetcher') def test_correct_configure_socket(self, mock_prefetcher): mock_socket = mock.Mock() - self.useFixture(fixtures.MonkeyPatch( - 'glance.common.wsgi.ssl.wrap_socket', - mock_socket)) self.useFixture(fixtures.MonkeyPatch( 'glance.common.wsgi.eventlet.listen', lambda *x, **y: mock_socket)) @@ -731,23 +725,16 @@ class GetSocketTestCase(test_utils.BaseTestCase): socket.SO_KEEPALIVE, 1), mock_socket.mock_calls) if hasattr(socket, 'TCP_KEEPIDLE'): - self.assertIn(mock.call().setsockopt( + self.assertIn(mock.call.setsockopt( socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, wsgi.CONF.tcp_keepidle), mock_socket.mock_calls) - def test_get_socket_without_all_ssl_reqs(self): - wsgi.CONF.key_file = None - self.assertRaises(RuntimeError, wsgi.get_socket, 1234) - def test_get_socket_with_bind_problems(self): self.useFixture(fixtures.MonkeyPatch( 'glance.common.wsgi.eventlet.listen', mock.Mock(side_effect=( [wsgi.socket.error(socket.errno.EADDRINUSE)] * 3 + [None])))) - self.useFixture(fixtures.MonkeyPatch( - 'glance.common.wsgi.ssl.wrap_socket', - lambda *x, **y: None)) self.assertRaises(RuntimeError, wsgi.get_socket, 1234) @@ -755,9 +742,6 @@ class GetSocketTestCase(test_utils.BaseTestCase): self.useFixture(fixtures.MonkeyPatch( 'glance.common.wsgi.eventlet.listen', mock.Mock(side_effect=wsgi.socket.error(socket.errno.ENOMEM)))) - self.useFixture(fixtures.MonkeyPatch( - 'glance.common.wsgi.ssl.wrap_socket', - lambda *x, **y: None)) self.assertRaises(wsgi.socket.error, wsgi.get_socket, 1234) diff --git a/releasenotes/notes/remove_native_ssl-c16d5a127b57583d.yaml b/releasenotes/notes/remove_native_ssl-c16d5a127b57583d.yaml new file mode 100644 index 0000000000..c4849493b2 --- /dev/null +++ b/releasenotes/notes/remove_native_ssl-c16d5a127b57583d.yaml @@ -0,0 +1,15 @@ +--- +upgrade: + - | + If upgrade is conducted from PY27 where ssl connections has been terminated + into glance-api, the termination needs to happen externally from now on. +security: + - | + The ssl support from Glance has been removed as it worked only under PY27 + which is not anymore supported environment. Termination of encrypted + connections needs to happen externally as soon as move to PY3 happens. Any + deployment needing end to end encryption would need to put either reverse + proxy (using fully blown http server like Apache or Nginx will cause + significant performance hit and we advice using something more simple that + does not break the http protocol) in front of the service or utilize + ssl tunneling (like stunnel) between loadbalancers and glance-api. diff --git a/tox.ini b/tox.ini index 5ba8fd37fd..6f720d7200 100644 --- a/tox.ini +++ b/tox.ini @@ -57,7 +57,7 @@ ignore_errors = True whitelist_externals = bash commands = - stestr run --blacklist-file ./broken-functional-py3-ssl-tests.txt {posargs} + stestr run {posargs} [testenv:functional-py37] basepython = python3.7 @@ -67,18 +67,7 @@ ignore_errors = True whitelist_externals = bash commands = - stestr run --blacklist-file ./broken-functional-py3-ssl-tests.txt {posargs} - -[testenv:broken-py3-ssl-tests] -# NOTE(rosmaita): these tests were being skipped due to bug #1482633, but we -# want it to be obvious that Glance is affected by the eventlet ssl-handshake -# problem under py3. (When this testenv is removed, don't forget to adjust -# the blacklist generation in the functional-py3 testenv.) -basepython = python3 -setenv = - TEST_PATH = ./glance/tests/functional -commands = - stestr run --whitelist-file ./broken-functional-py3-ssl-tests.txt {posargs} + stestr run {posargs} [testenv:gateonly] # NOTE(rosmaita): these tests catch configuration problems for some code