From 928d23db022157ae24d49eb9b7772cc0e07345a4 Mon Sep 17 00:00:00 2001 From: David Stanek Date: Wed, 8 Feb 2017 13:45:17 +0000 Subject: [PATCH] Removed the deprecated pki_setup command bp removed-as-of-pike Change-Id: Ib39d21ed547e3be7a3a2c333a7193f990043a80b --- doc/source/configuration.rst | 23 -- doc/source/man/commands.rst | 1 - keystone/cmd/cli.py | 40 --- keystone/common/openssl.py | 324 ------------------ keystone/conf/signing.py | 27 ++ keystone/tests/unit/test_cert_setup.py | 183 ---------- .../removed-as-of-pike-deadbeefdeadbeef.yaml | 5 + 7 files changed, 32 insertions(+), 571 deletions(-) delete mode 100644 keystone/common/openssl.py delete mode 100644 keystone/tests/unit/test_cert_setup.py diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst index cb7a218a75..a511632f49 100644 --- a/doc/source/configuration.rst +++ b/doc/source/configuration.rst @@ -949,29 +949,6 @@ If your certificate directory path is different from the default section of the configuration file. -Generating a Signing Certificate using ``pki_setup`` ----------------------------------------------------- - -``keystone-manage pki_setup`` is a development tool. We recommend that you do -not use ``keystone-manage pki_setup`` in a production environment. In -production, an external CA should be used instead. This is because the CA -secret key should generally be kept apart from the token signing secret keys so -that a compromise of a node does not lead to an attacker being able to generate -valid signed keystone tokens. This is a low probability attack vector, as -compromise of a keystone service machine's filesystem security almost certainly -means the attacker will be able to gain direct access to the token backend. - -When using the ``keystone-manage pki_setup`` to generate the certificates, the -following configuration options in the ``[signing]`` section are used: - -* ``ca_key`` - Default is ``/etc/keystone/ssl/private/cakey.pem`` -* ``key_size`` - Default is ``2048`` -* ``valid_days`` - Default is ``3650`` - -If ``keystone-manage pki_setup`` is not used then these options don't need to -be set. - - Service Catalog =============== diff --git a/doc/source/man/commands.rst b/doc/source/man/commands.rst index 9b858b98a6..fcb50465e5 100644 --- a/doc/source/man/commands.rst +++ b/doc/source/man/commands.rst @@ -22,6 +22,5 @@ Available commands: * ``mapping_populate``: Prepare domain-specific LDAP backend. * ``mapping_purge``: Purge the identity mapping table. * ``mapping_engine``: Test your federation mapping rules. -* ``pki_setup``: Initialize the certificates used to sign revocation lists. **deprecated** * ``saml_idp_metadata``: Generate identity provider metadata. * ``token_flush``: Purge expired tokens. diff --git a/keystone/cmd/cli.py b/keystone/cmd/cli.py index 1867c9d9c3..cc12fa5cfc 100644 --- a/keystone/cmd/cli.py +++ b/keystone/cmd/cli.py @@ -30,7 +30,6 @@ import pbr.version from keystone.cmd import doctor from keystone.common import driver_hints from keystone.common import fernet_utils -from keystone.common import openssl from keystone.common import sql from keystone.common.sql import upgrades from keystone.common import utils @@ -582,44 +581,6 @@ class BasePermissionsSetup(BaseApp): return keystone_user_id, keystone_group_id -class BaseCertificateSetup(BasePermissionsSetup): - """Provides common options for certificate setup.""" - - @classmethod - def add_argument_parser(cls, subparsers): - parser = super(BaseCertificateSetup, - cls).add_argument_parser(subparsers) - parser.add_argument('--rebuild', default=False, action='store_true', - help=('Rebuild certificate files: erase previous ' - 'files and regenerate them.')) - return parser - - -class PKISetup(BaseCertificateSetup): - """Setup keys and certificates for signing and verifying revocation lists. - - This is NOT intended for production use, see Keystone Configuration - documentation for details. As of the Mitaka release, this command has - been DEPRECATED and may be removed in the 'O' release. - """ - - name = 'pki_setup' - - @classmethod - def main(cls): - versionutils.report_deprecated_feature( - LOG, - "keystone-manage pki_setup is deprecated as of Mitaka in " - "favor of not using PKI tokens and may be removed in 'O' " - "release.") - LOG.warning('keystone-manage pki_setup is not recommended for ' - 'production use.') - keystone_user_id, keystone_group_id = cls.get_user_group() - conf_pki = openssl.ConfigurePKI(keystone_user_id, keystone_group_id, - rebuild=CONF.command.rebuild) - conf_pki.run() - - class FernetSetup(BasePermissionsSetup): """Setup a key repository for Fernet tokens. @@ -1336,7 +1297,6 @@ CMDS = [ MappingPopulate, MappingPurge, MappingEngineTester, - PKISetup, SamlIdentityProviderMetadata, TokenFlush, ] diff --git a/keystone/common/openssl.py b/keystone/common/openssl.py deleted file mode 100644 index d9e4a93a5e..0000000000 --- a/keystone/common/openssl.py +++ /dev/null @@ -1,324 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# -# 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 subprocess # nosec : see comments in the code below - -from oslo_log import log - -from keystone.common import utils -import keystone.conf - -LOG = log.getLogger(__name__) -CONF = keystone.conf.CONF - -PUBLIC_DIR_PERMS = 0o755 # -rwxr-xr-x -PRIVATE_DIR_PERMS = 0o750 # -rwxr-x--- -PUBLIC_FILE_PERMS = 0o644 # -rw-r--r-- -PRIVATE_FILE_PERMS = 0o640 # -rw-r----- - - -def file_exists(file_path): - return os.path.exists(file_path) - - -class BaseCertificateConfigure(object): - """Create a certificate signing environment. - - This is based on a config section and reasonable OpenSSL defaults. - - """ - - def __init__(self, conf_obj, keystone_user, - keystone_group, rebuild, **kwargs): - self.conf_dir = os.path.dirname(conf_obj.ca_certs) - self.use_keystone_user = keystone_user - self.use_keystone_group = keystone_group - self.rebuild = rebuild - self.ssl_config_file_name = os.path.join(self.conf_dir, "openssl.conf") - self.request_file_name = os.path.join(self.conf_dir, "req.pem") - self.ssl_dictionary = {'conf_dir': self.conf_dir, - 'ca_cert': conf_obj.ca_certs, - 'default_md': 'default', - 'ssl_config': self.ssl_config_file_name, - 'ca_private_key': conf_obj.ca_key, - 'request_file': self.request_file_name, - 'signing_key': conf_obj.keyfile, - 'signing_cert': conf_obj.certfile, - 'key_size': int(conf_obj.key_size), - 'valid_days': int(conf_obj.valid_days), - 'cert_subject': conf_obj.cert_subject} - - try: - # OpenSSL 1.0 and newer support default_md = default, - # older versions do not - openssl_ver = subprocess.check_output( # nosec : the arguments - # are hardcoded and just check the openssl version - ['openssl', 'version']) - if b'OpenSSL 0.' in openssl_ver: - self.ssl_dictionary['default_md'] = 'sha1' - except subprocess.CalledProcessError: - LOG.warning('Failed to invoke ``openssl version``, ' - 'assuming is v1.0 or newer') - self.ssl_dictionary.update(kwargs) - - def exec_command(self, command): - to_exec = [part % self.ssl_dictionary for part in command] - LOG.info('Running command - %s', ' '.join(to_exec)) - try: - # NOTE(shaleh): use check_output instead of the simpler - # `check_call()` in order to log any output from an error. - subprocess.check_output( # nosec : the arguments being passed - # in are defined in this file and trusted to build CAs, keys - # and certs - to_exec, - stderr=subprocess.STDOUT) - except subprocess.CalledProcessError as e: - msg = ("Command %(to_exec)s exited with %(retcode)s - " - "%(output)s)") - LOG.error(msg, - {'to_exec': to_exec, - 'retcode': e.returncode, - 'output': e.output}) - raise - - def clean_up_existing_files(self): - files_to_clean = [self.ssl_dictionary['ca_private_key'], - self.ssl_dictionary['ca_cert'], - self.ssl_dictionary['signing_key'], - self.ssl_dictionary['signing_cert'], - ] - - existing_files = [] - - for file_path in files_to_clean: - if file_exists(file_path): - if self.rebuild: - # The file exists but the user wants to rebuild it, so blow - # it away - try: - os.remove(file_path) - except OSError as exc: - msg = ("Failed to remove file %(file_path)r: " - "%(error)s") - LOG.error(msg, - {'file_path': file_path, - 'error': exc.strerror}) - raise - else: - existing_files.append(file_path) - - return existing_files - - def build_ssl_config_file(self): - utils.make_dirs(os.path.dirname(self.ssl_config_file_name), - mode=PUBLIC_DIR_PERMS, - user=self.use_keystone_user, - group=self.use_keystone_group, log=LOG) - if not file_exists(self.ssl_config_file_name): - with open(self.ssl_config_file_name, 'w') as ssl_config_file: - ssl_config_file.write(self.sslconfig % self.ssl_dictionary) - utils.set_permissions(self.ssl_config_file_name, - mode=PRIVATE_FILE_PERMS, - user=self.use_keystone_user, - group=self.use_keystone_group, log=LOG) - - index_file_name = os.path.join(self.conf_dir, 'index.txt') - if not file_exists(index_file_name): - with open(index_file_name, 'w') as index_file: - index_file.write('') - utils.set_permissions(index_file_name, - mode=PRIVATE_FILE_PERMS, - user=self.use_keystone_user, - group=self.use_keystone_group, log=LOG) - - serial_file_name = os.path.join(self.conf_dir, 'serial') - if not file_exists(serial_file_name): - with open(serial_file_name, 'w') as index_file: - index_file.write('01') - utils.set_permissions(serial_file_name, - mode=PRIVATE_FILE_PERMS, - user=self.use_keystone_user, - group=self.use_keystone_group, log=LOG) - - def build_ca_cert(self): - ca_key_file = self.ssl_dictionary['ca_private_key'] - utils.make_dirs(os.path.dirname(ca_key_file), - mode=PRIVATE_DIR_PERMS, - user=self.use_keystone_user, - group=self.use_keystone_group, log=LOG) - if not file_exists(ca_key_file): - self.exec_command(['openssl', 'genrsa', - '-out', '%(ca_private_key)s', - '%(key_size)d']) - utils.set_permissions(ca_key_file, - mode=PRIVATE_FILE_PERMS, - user=self.use_keystone_user, - group=self.use_keystone_group, log=LOG) - - ca_cert = self.ssl_dictionary['ca_cert'] - utils.make_dirs(os.path.dirname(ca_cert), - mode=PUBLIC_DIR_PERMS, - user=self.use_keystone_user, - group=self.use_keystone_group, log=LOG) - if not file_exists(ca_cert): - self.exec_command(['openssl', 'req', '-new', '-x509', - '-extensions', 'v3_ca', - '-key', '%(ca_private_key)s', - '-out', '%(ca_cert)s', - '-days', '%(valid_days)d', - '-config', '%(ssl_config)s', - '-subj', '%(cert_subject)s']) - utils.set_permissions(ca_cert, - mode=PUBLIC_FILE_PERMS, - user=self.use_keystone_user, - group=self.use_keystone_group, log=LOG) - - def build_private_key(self): - signing_keyfile = self.ssl_dictionary['signing_key'] - utils.make_dirs(os.path.dirname(signing_keyfile), - mode=PRIVATE_DIR_PERMS, - user=self.use_keystone_user, - group=self.use_keystone_group, log=LOG) - if not file_exists(signing_keyfile): - self.exec_command(['openssl', 'genrsa', '-out', '%(signing_key)s', - '%(key_size)d']) - utils.set_permissions(signing_keyfile, - mode=PRIVATE_FILE_PERMS, - user=self.use_keystone_user, - group=self.use_keystone_group, log=LOG) - - def build_signing_cert(self): - signing_cert = self.ssl_dictionary['signing_cert'] - - utils.make_dirs(os.path.dirname(signing_cert), - mode=PUBLIC_DIR_PERMS, - user=self.use_keystone_user, - group=self.use_keystone_group, log=LOG) - if not file_exists(signing_cert): - self.exec_command(['openssl', 'req', '-key', '%(signing_key)s', - '-new', '-out', '%(request_file)s', - '-config', '%(ssl_config)s', - '-subj', '%(cert_subject)s']) - - self.exec_command(['openssl', 'ca', '-batch', - '-out', '%(signing_cert)s', - '-config', '%(ssl_config)s', - '-days', '%(valid_days)d', - '-cert', '%(ca_cert)s', - '-keyfile', '%(ca_private_key)s', - '-infiles', '%(request_file)s']) - - def run(self): - try: - existing_files = self.clean_up_existing_files() - except OSError: - print('An error occurred when rebuilding cert files.') - return - if existing_files: - print('The following cert files already exist, use --rebuild to ' - 'remove the existing files before regenerating:') - for f in existing_files: - print('%s already exists' % f) - return - - self.build_ssl_config_file() - self.build_ca_cert() - self.build_private_key() - self.build_signing_cert() - - -class ConfigurePKI(BaseCertificateConfigure): - """Generate files for PKI signing using OpenSSL. - - Signed tokens require a private key and signing certificate which itself - must be signed by a CA. This class generates them with workable defaults - if each of the files are not present - - """ - - def __init__(self, keystone_user, keystone_group, rebuild=False): - super(ConfigurePKI, self).__init__(CONF.signing, keystone_user, - keystone_group, rebuild=rebuild) - - -BaseCertificateConfigure.sslconfig = """ -# OpenSSL configuration file. -# - -# Establish working directory. - -dir = %(conf_dir)s - -[ ca ] -default_ca = CA_default - -[ CA_default ] -new_certs_dir = $dir -serial = $dir/serial -database = $dir/index.txt -default_days = 365 -default_md = %(default_md)s -preserve = no -email_in_dn = no -nameopt = default_ca -certopt = default_ca -policy = policy_anything -x509_extensions = usr_cert -unique_subject = no - -[ policy_anything ] -countryName = optional -stateOrProvinceName = optional -organizationName = optional -organizationalUnitName = optional -commonName = supplied -emailAddress = optional - -[ req ] -default_bits = 2048 # Size of keys -default_keyfile = key.pem # name of generated keys -string_mask = utf8only # permitted characters -distinguished_name = req_distinguished_name -req_extensions = v3_req -x509_extensions = v3_ca - -[ req_distinguished_name ] -countryName = Country Name (2 letter code) -countryName_min = 2 -countryName_max = 2 -stateOrProvinceName = State or Province Name (full name) -localityName = Locality Name (city, district) -0.organizationName = Organization Name (company) -organizationalUnitName = Organizational Unit Name (department, division) -commonName = Common Name (hostname, IP, or your name) -commonName_max = 64 -emailAddress = Email Address -emailAddress_max = 64 - -[ v3_ca ] -basicConstraints = CA:TRUE -subjectKeyIdentifier = hash -authorityKeyIdentifier = keyid:always,issuer - -[ v3_req ] -basicConstraints = CA:FALSE -keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -[ usr_cert ] -basicConstraints = CA:FALSE -subjectKeyIdentifier = hash -authorityKeyIdentifier = keyid:always -""" diff --git a/keystone/conf/signing.py b/keystone/conf/signing.py index 6195fd8d39..f868269b9c 100644 --- a/keystone/conf/signing.py +++ b/keystone/conf/signing.py @@ -11,14 +11,23 @@ # under the License. from oslo_config import cfg +from oslo_log import versionutils from keystone.conf import constants from keystone.conf import utils +_DEPRECATED_MSG = utils.fmt(""" +`keystone-manage pki_setup` was deprecated in Mitaka and removed in Pike. +These options remain for backwards compatibility. +""") + certfile = cfg.StrOpt( 'certfile', default=constants._CERTFILE, + deprecated_for_removal=True, + deprecated_reason=_DEPRECATED_MSG, + deprecated_since=versionutils.deprecated.PIKE, help=utils.fmt(""" Absolute path to the public certificate file to use for signing responses to revocation lists requests. Set this together with `[signing] keyfile`. For @@ -29,6 +38,9 @@ pki_setup` to generate self-signed certificates. keyfile = cfg.StrOpt( 'keyfile', default=constants._KEYFILE, + deprecated_for_removal=True, + deprecated_reason=_DEPRECATED_MSG, + deprecated_since=versionutils.deprecated.PIKE, help=utils.fmt(""" Absolute path to the private key file to use for signing responses to revocation lists requests. Set this together with `[signing] certfile`. @@ -36,6 +48,9 @@ revocation lists requests. Set this together with `[signing] certfile`. ca_certs = cfg.StrOpt( 'ca_certs', + deprecated_for_removal=True, + deprecated_reason=_DEPRECATED_MSG, + deprecated_since=versionutils.deprecated.PIKE, default='/etc/keystone/ssl/certs/ca.pem', help=utils.fmt(""" Absolute path to the public certificate authority (CA) file to use when @@ -48,6 +63,9 @@ you are requesting revocation lists in a non-production environment. Use a ca_key = cfg.StrOpt( 'ca_key', default='/etc/keystone/ssl/private/cakey.pem', + deprecated_for_removal=True, + deprecated_reason=_DEPRECATED_MSG, + deprecated_since=versionutils.deprecated.PIKE, help=utils.fmt(""" Absolute path to the private certificate authority (CA) key file to use when creating self-signed certificates with `keystone-manage pki_setup`. Set this @@ -60,6 +78,9 @@ key_size = cfg.IntOpt( 'key_size', default=2048, min=1024, + deprecated_for_removal=True, + deprecated_reason=_DEPRECATED_MSG, + deprecated_since=versionutils.deprecated.PIKE, help=utils.fmt(""" Key size (in bits) to use when generating a self-signed token signing certificate. There is no reason to set this option unless you are requesting @@ -70,6 +91,9 @@ issued from a trusted certificate authority instead. valid_days = cfg.IntOpt( 'valid_days', default=3650, + deprecated_for_removal=True, + deprecated_reason=_DEPRECATED_MSG, + deprecated_since=versionutils.deprecated.PIKE, help=utils.fmt(""" The validity period (in days) to use when generating a self-signed token signing certificate. There is no reason to set this option unless you are @@ -80,6 +104,9 @@ requesting revocation lists in a non-production environment. Use a cert_subject = cfg.StrOpt( 'cert_subject', default=('/C=US/ST=Unset/L=Unset/O=Unset/CN=www.example.com'), + deprecated_for_removal=True, + deprecated_reason=_DEPRECATED_MSG, + deprecated_since=versionutils.deprecated.PIKE, help=utils.fmt(""" The certificate subject to use when generating a self-signed token signing certificate. There is no reason to set this option unless you are requesting diff --git a/keystone/tests/unit/test_cert_setup.py b/keystone/tests/unit/test_cert_setup.py deleted file mode 100644 index 255a721a94..0000000000 --- a/keystone/tests/unit/test_cert_setup.py +++ /dev/null @@ -1,183 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# -# 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 shutil -import subprocess - -import mock -from six.moves import http_client -from testtools import matchers - -from keystone.common import openssl -from keystone.tests import unit -from keystone.tests.unit import ksfixtures -from keystone.tests.unit import rest - - -SSLDIR = unit.dirs.tmp('ssl') -CONF = unit.CONF - - -CERTDIR = os.path.join(SSLDIR, 'certs') -KEYDIR = os.path.join(SSLDIR, 'private') - - -class CertSetupTestCase(rest.RestfulTestCase): - - def setUp(self): - super(CertSetupTestCase, self).setUp() - - def cleanup_ssldir(): - try: - shutil.rmtree(SSLDIR) - except OSError: - pass - - self.addCleanup(cleanup_ssldir) - - def config_overrides(self): - super(CertSetupTestCase, self).config_overrides() - ca_certs = os.path.join(CERTDIR, 'ca.pem') - ca_key = os.path.join(CERTDIR, 'cakey.pem') - - self.config_fixture.config( - group='signing', - certfile=os.path.join(CERTDIR, 'signing_cert.pem'), - ca_certs=ca_certs, - ca_key=ca_key, - keyfile=os.path.join(KEYDIR, 'signing_key.pem')) - self.config_fixture.config(group='token', provider='fernet') - self.useFixture( - ksfixtures.KeyRepository( - self.config_fixture, - 'fernet_tokens', - CONF.fernet_tokens.max_active_keys - ) - ) - - def test_create_pki_certs(self, rebuild=False): - pki = openssl.ConfigurePKI(None, None, rebuild=rebuild) - pki.run() - self.assertTrue(os.path.exists(CONF.signing.certfile)) - self.assertTrue(os.path.exists(CONF.signing.ca_certs)) - self.assertTrue(os.path.exists(CONF.signing.keyfile)) - - def test_fetch_signing_cert(self, rebuild=False): - pki = openssl.ConfigurePKI(None, None, rebuild=rebuild) - pki.run() - - # NOTE(jamielennox): Use request directly because certificate - # requests don't have some of the normal information - signing_resp = self.request(self.public_app, - '/v2.0/certificates/signing', - method='GET', - expected_status=http_client.OK) - - cacert_resp = self.request(self.public_app, - '/v2.0/certificates/ca', - method='GET', - expected_status=http_client.OK) - - with open(CONF.signing.certfile) as f: - self.assertEqual(f.read(), signing_resp.text) - - with open(CONF.signing.ca_certs) as f: - self.assertEqual(f.read(), cacert_resp.text) - - # NOTE(jamielennox): This is weird behaviour that we need to enforce. - # It doesn't matter what you ask for it's always going to give text - # with a text/html content_type. - - for path in ['/v2.0/certificates/signing', '/v2.0/certificates/ca']: - for accept in [None, 'text/html', 'application/json', 'text/xml']: - headers = {'Accept': accept} if accept else {} - resp = self.request(self.public_app, path, method='GET', - expected_status=http_client.OK, - headers=headers) - - self.assertEqual('text/html', resp.content_type) - - def test_fetch_signing_cert_when_rebuild(self): - pki = openssl.ConfigurePKI(None, None) - pki.run() - self.test_fetch_signing_cert(rebuild=True) - - def test_failure(self): - for path in ['/v2.0/certificates/signing', '/v2.0/certificates/ca']: - self.request(self.public_app, path, method='GET', - expected_status=http_client.INTERNAL_SERVER_ERROR) - - def test_pki_certs_rebuild(self): - self.test_create_pki_certs() - with open(CONF.signing.certfile) as f: - cert_file1 = f.read() - - self.test_create_pki_certs(rebuild=True) - with open(CONF.signing.certfile) as f: - cert_file2 = f.read() - - self.assertNotEqual(cert_file1, cert_file2) - - @mock.patch.object(os, 'remove') - def test_rebuild_pki_certs_remove_error(self, mock_remove): - self.test_create_pki_certs() - with open(CONF.signing.certfile) as f: - cert_file1 = f.read() - - mock_remove.side_effect = OSError() - self.test_create_pki_certs(rebuild=True) - with open(CONF.signing.certfile) as f: - cert_file2 = f.read() - - self.assertEqual(cert_file1, cert_file2) - - def test_create_pki_certs_twice_without_rebuild(self): - self.test_create_pki_certs() - with open(CONF.signing.certfile) as f: - cert_file1 = f.read() - - self.test_create_pki_certs() - with open(CONF.signing.certfile) as f: - cert_file2 = f.read() - - self.assertEqual(cert_file1, cert_file2) - - -class TestExecCommand(unit.TestCase): - - @mock.patch.object(subprocess.Popen, 'poll') - def test_running_a_successful_command(self, mock_poll): - mock_poll.return_value = 0 - - ssl = openssl.ConfigurePKI('keystone_user', 'keystone_group') - ssl.exec_command(['ls']) - - @mock.patch.object(subprocess, 'check_output') - def test_running_an_invalid_command(self, mock_check_output): - cmd = ['ls'] - - output = 'this is the output string' - - error = subprocess.CalledProcessError(returncode=1, - cmd=cmd, - output=output) - mock_check_output.side_effect = error - - ssl = openssl.ConfigurePKI('keystone_user', 'keystone_group') - e = self.assertRaises(subprocess.CalledProcessError, - ssl.exec_command, - cmd) - self.assertThat(e.output, matchers.Equals(output)) diff --git a/releasenotes/notes/removed-as-of-pike-deadbeefdeadbeef.yaml b/releasenotes/notes/removed-as-of-pike-deadbeefdeadbeef.yaml index e21a597f2c..933c3b529d 100644 --- a/releasenotes/notes/removed-as-of-pike-deadbeefdeadbeef.yaml +++ b/releasenotes/notes/removed-as-of-pike-deadbeefdeadbeef.yaml @@ -31,3 +31,8 @@ other: The ``keystone.common.ldap`` module was removed from the code tree. It was deprecated in the Newton release in favor of using ``keystone.identity.backends.ldap.common`` which has the same functionality. + - > + [`blueprint removed-as-of-pike `_] + The ``keystone-manage pki_setup`` was added to aid developer setup by hiding the sometimes cryptic + openssl commands. This is no longer needed since keystone no longer supports PKI tokens and can no + longer serve SSL. This was deprecated in the Mitaka release.