Merge "config options: Move crypto options into a group"

This commit is contained in:
Jenkins
2016-04-07 14:24:16 +00:00
committed by Gerrit Code Review
8 changed files with 46 additions and 28 deletions

View File

@@ -52,7 +52,7 @@ class CloudpipeController(wsgi.Controller):
# NOTE(vish): One of the drawbacks of doing this in the api is # NOTE(vish): One of the drawbacks of doing this in the api is
# the keys will only be on the api node that launched # the keys will only be on the api node that launched
# the cloudpipe. # the cloudpipe.
fileutils.ensure_tree(CONF.keys_path) fileutils.ensure_tree(CONF.crypto.keys_path)
def _get_all_cloudpipes(self, context): def _get_all_cloudpipes(self, context):
"""Get all cloudpipes.""" """Get all cloudpipes."""

View File

@@ -47,7 +47,7 @@ class CloudpipeController(object):
# NOTE(vish): One of the drawbacks of doing this in the api is # NOTE(vish): One of the drawbacks of doing this in the api is
# the keys will only be on the api node that launched # the keys will only be on the api node that launched
# the cloudpipe. # the cloudpipe.
fileutils.ensure_tree(CONF.keys_path) fileutils.ensure_tree(CONF.crypto.keys_path)
def _get_all_cloudpipes(self, context): def _get_all_cloudpipes(self, context):
"""Get all cloudpipes.""" """Get all cloudpipes."""

View File

@@ -135,7 +135,7 @@ class CloudPipe(object):
result, private_key = keypair_api.create_key_pair(context, result, private_key = keypair_api.create_key_pair(context,
context.user_id, context.user_id,
key_name) key_name)
key_dir = os.path.join(CONF.keys_path, context.user_id) key_dir = os.path.join(CONF.crypto.keys_path, context.user_id)
fileutils.ensure_tree(key_dir) fileutils.ensure_tree(key_dir)
key_path = os.path.join(key_dir, '%s.pem' % key_name) key_path = os.path.join(key_dir, '%s.pem' % key_name)
with open(key_path, 'w') as f: with open(key_path, 'w') as f:

View File

@@ -19,48 +19,61 @@ from oslo_config import cfg
from nova.i18n import _ from nova.i18n import _
from nova import paths from nova import paths
crypto_opts_group = cfg.OptGroup(
'crypto',
title='Crypto Options')
crypto_opts = [ crypto_opts = [
cfg.StrOpt( cfg.StrOpt(
'ca_file', 'ca_file',
default='cacert.pem', default='cacert.pem',
deprecated_group='DEFAULT',
help=_('Filename of root CA')), help=_('Filename of root CA')),
cfg.StrOpt( cfg.StrOpt(
'key_file', 'key_file',
default=os.path.join('private', 'cakey.pem'), default=os.path.join('private', 'cakey.pem'),
deprecated_group='DEFAULT',
help=_('Filename of private key')), help=_('Filename of private key')),
cfg.StrOpt( cfg.StrOpt(
'crl_file', 'crl_file',
default='crl.pem', default='crl.pem',
deprecated_group='DEFAULT',
help=_('Filename of root Certificate Revocation List')), help=_('Filename of root Certificate Revocation List')),
cfg.StrOpt( cfg.StrOpt(
'keys_path', 'keys_path',
default=paths.state_path_def('keys'), default=paths.state_path_def('keys'),
deprecated_group='DEFAULT',
help=_('Where we keep our keys')), help=_('Where we keep our keys')),
cfg.StrOpt( cfg.StrOpt(
'ca_path', 'ca_path',
default=paths.state_path_def('CA'), default=paths.state_path_def('CA'),
deprecated_group='DEFAULT',
help=_('Where we keep our root CA')), help=_('Where we keep our root CA')),
cfg.BoolOpt( cfg.BoolOpt(
'use_project_ca', 'use_project_ca',
default=False, default=False,
deprecated_group='DEFAULT',
help=_('Should we use a CA for each project?')), help=_('Should we use a CA for each project?')),
cfg.StrOpt( cfg.StrOpt(
'user_cert_subject', 'user_cert_subject',
default='/C=US/ST=California/O=OpenStack/' default='/C=US/ST=California/O=OpenStack/'
'OU=NovaDev/CN=%.16s-%.16s-%s', 'OU=NovaDev/CN=%.16s-%.16s-%s',
deprecated_group='DEFAULT',
help=_('Subject for certificate for users, %s for ' help=_('Subject for certificate for users, %s for '
'project, user, timestamp')), 'project, user, timestamp')),
cfg.StrOpt( cfg.StrOpt(
'project_cert_subject', 'project_cert_subject',
default='/C=US/ST=California/O=OpenStack/' default='/C=US/ST=California/O=OpenStack/'
'OU=NovaDev/CN=project-ca-%.16s-%s', 'OU=NovaDev/CN=project-ca-%.16s-%s',
deprecated_group='DEFAULT',
help=_('Subject for certificate for projects, %s for ' help=_('Subject for certificate for projects, %s for '
'project, timestamp'))] 'project, timestamp'))]
def register_opts(conf): def register_opts(conf):
conf.register_opts(crypto_opts) conf.register_group(crypto_opts_group)
conf.register_opts(crypto_opts, crypto_opts_group)
def list_opts(): def list_opts():
return {'DEFAULT': crypto_opts} return {crypto_opts_group: crypto_opts}

View File

@@ -54,25 +54,25 @@ CONF = nova.conf.CONF
def ca_folder(project_id=None): def ca_folder(project_id=None):
if CONF.use_project_ca and project_id: if CONF.crypto.use_project_ca and project_id:
return os.path.join(CONF.ca_path, 'projects', project_id) return os.path.join(CONF.crypto.ca_path, 'projects', project_id)
return CONF.ca_path return CONF.crypto.ca_path
def ca_path(project_id=None): def ca_path(project_id=None):
return os.path.join(ca_folder(project_id), CONF.ca_file) return os.path.join(ca_folder(project_id), CONF.crypto.ca_file)
def key_path(project_id=None): def key_path(project_id=None):
return os.path.join(ca_folder(project_id), CONF.key_file) return os.path.join(ca_folder(project_id), CONF.crypto.key_file)
def crl_path(project_id=None): def crl_path(project_id=None):
return os.path.join(ca_folder(project_id), CONF.crl_file) return os.path.join(ca_folder(project_id), CONF.crypto.crl_file)
def fetch_ca(project_id=None): def fetch_ca(project_id=None):
if not CONF.use_project_ca: if not CONF.crypto.use_project_ca:
project_id = None project_id = None
ca_file_path = ca_path(project_id) ca_file_path = ca_path(project_id)
if not os.path.exists(ca_file_path): if not os.path.exists(ca_file_path):
@@ -160,7 +160,7 @@ def generate_key_pair(bits=2048):
def fetch_crl(project_id): def fetch_crl(project_id):
"""Get crl file for project.""" """Get crl file for project."""
if not CONF.use_project_ca: if not CONF.crypto.use_project_ca:
project_id = None project_id = None
crl_file_path = crl_path(project_id) crl_file_path = crl_path(project_id)
if not os.path.exists(crl_file_path): if not os.path.exists(crl_file_path):
@@ -206,7 +206,7 @@ def revoke_cert(project_id, file_name):
utils.execute('openssl', 'ca', '-config', './openssl.cnf', '-revoke', utils.execute('openssl', 'ca', '-config', './openssl.cnf', '-revoke',
file_name, cwd=ca_folder(project_id)) file_name, cwd=ca_folder(project_id))
utils.execute('openssl', 'ca', '-gencrl', '-config', './openssl.cnf', utils.execute('openssl', 'ca', '-gencrl', '-config', './openssl.cnf',
'-out', CONF.crl_file, cwd=ca_folder(project_id)) '-out', CONF.crypto.crl_file, cwd=ca_folder(project_id))
except OSError: except OSError:
raise exception.ProjectNotFound(project_id=project_id) raise exception.ProjectNotFound(project_id=project_id)
except processutils.ProcessExecutionError: except processutils.ProcessExecutionError:
@@ -239,12 +239,13 @@ def revoke_certs_by_user_and_project(user_id, project_id):
def _project_cert_subject(project_id): def _project_cert_subject(project_id):
"""Helper to generate user cert subject.""" """Helper to generate user cert subject."""
return CONF.project_cert_subject % (project_id, utils.isotime()) return CONF.crypto.project_cert_subject % (project_id, utils.isotime())
def _user_cert_subject(user_id, project_id): def _user_cert_subject(user_id, project_id):
"""Helper to generate user cert subject.""" """Helper to generate user cert subject."""
return CONF.user_cert_subject % (project_id, user_id, utils.isotime()) return CONF.crypto.user_cert_subject % (project_id, user_id,
utils.isotime())
def generate_x509_cert(user_id, project_id, bits=2048): def generate_x509_cert(user_id, project_id, bits=2048):
@@ -342,7 +343,7 @@ def generate_vpn_files(project_id):
def sign_csr(csr_text, project_id=None): def sign_csr(csr_text, project_id=None):
if not CONF.use_project_ca: if not CONF.crypto.use_project_ca:
project_id = None project_id = None
if not project_id: if not project_id:
return _sign_csr(csr_text, ca_folder()) return _sign_csr(csr_text, ca_folder())

View File

@@ -36,7 +36,7 @@ class X509Test(test.NoDBTestCase):
@mock.patch('nova.db.certificate_create') @mock.patch('nova.db.certificate_create')
def test_can_generate_x509(self, mock_create): def test_can_generate_x509(self, mock_create):
with utils.tempdir() as tmpdir: with utils.tempdir() as tmpdir:
self.flags(ca_path=tmpdir) self.flags(ca_path=tmpdir, group='crypto')
crypto.ensure_ca_filesystem() crypto.ensure_ca_filesystem()
_key, cert_str = crypto.generate_x509_cert('fake', 'fake') _key, cert_str = crypto.generate_x509_cert('fake', 'fake')
@@ -56,7 +56,7 @@ class X509Test(test.NoDBTestCase):
def test_encrypt_decrypt_x509(self): def test_encrypt_decrypt_x509(self):
with utils.tempdir() as tmpdir: with utils.tempdir() as tmpdir:
self.flags(ca_path=tmpdir) self.flags(ca_path=tmpdir, group='crypto')
project_id = "fake" project_id = "fake"
crypto.ensure_ca_filesystem() crypto.ensure_ca_filesystem()
@@ -85,7 +85,7 @@ class X509Test(test.NoDBTestCase):
side_effect=processutils.ProcessExecutionError) side_effect=processutils.ProcessExecutionError)
def test_ensure_ca_filesystem_chdir(self, *args, **kargs): def test_ensure_ca_filesystem_chdir(self, *args, **kargs):
with utils.tempdir() as tmpdir: with utils.tempdir() as tmpdir:
self.flags(ca_path=tmpdir) self.flags(ca_path=tmpdir, group='crypto')
start = os.getcwd() start = os.getcwd()
self.assertRaises(processutils.ProcessExecutionError, self.assertRaises(processutils.ProcessExecutionError,
crypto.ensure_ca_filesystem) crypto.ensure_ca_filesystem)
@@ -156,7 +156,7 @@ class RevokeCertsTest(test.NoDBTestCase):
2, 'test_file') 2, 'test_file')
def test_revoke_cert_project_not_found_chdir_fails(self, *args, **kargs): def test_revoke_cert_project_not_found_chdir_fails(self, *args, **kargs):
self.flags(use_project_ca=True) self.flags(use_project_ca=True, group='crypto')
self.assertRaises(exception.ProjectNotFound, crypto.revoke_cert, self.assertRaises(exception.ProjectNotFound, crypto.revoke_cert,
str(uuid.uuid4()), 'test_file') str(uuid.uuid4()), 'test_file')
@@ -164,16 +164,16 @@ class RevokeCertsTest(test.NoDBTestCase):
class CertExceptionTests(test.NoDBTestCase): class CertExceptionTests(test.NoDBTestCase):
def test_fetch_ca_file_not_found(self): def test_fetch_ca_file_not_found(self):
with utils.tempdir() as tmpdir: with utils.tempdir() as tmpdir:
self.flags(ca_path=tmpdir) self.flags(ca_path=tmpdir, group='crypto')
self.flags(use_project_ca=True) self.flags(use_project_ca=True, group='crypto')
self.assertRaises(exception.CryptoCAFileNotFound, crypto.fetch_ca, self.assertRaises(exception.CryptoCAFileNotFound, crypto.fetch_ca,
project_id='fake') project_id='fake')
def test_fetch_crl_file_not_found(self): def test_fetch_crl_file_not_found(self):
with utils.tempdir() as tmpdir: with utils.tempdir() as tmpdir:
self.flags(ca_path=tmpdir) self.flags(ca_path=tmpdir, group='crypto')
self.flags(use_project_ca=True) self.flags(use_project_ca=True, group='crypto')
self.assertRaises(exception.CryptoCRLFileNotFound, self.assertRaises(exception.CryptoCRLFileNotFound,
crypto.fetch_crl, project_id='fake') crypto.fetch_crl, project_id='fake')

View File

@@ -34,7 +34,7 @@ class PipelibTest(test.TestCase):
def test_get_encoded_zip(self): def test_get_encoded_zip(self):
with utils.tempdir() as tmpdir: with utils.tempdir() as tmpdir:
self.flags(ca_path=tmpdir) self.flags(ca_path=tmpdir, group='crypto')
crypto.ensure_ca_filesystem() crypto.ensure_ca_filesystem()
ret = self.cloudpipe.get_encoded_zip(self.project) ret = self.cloudpipe.get_encoded_zip(self.project)
@@ -45,7 +45,7 @@ class PipelibTest(test.TestCase):
"create", "create",
lambda *a, **kw: (None, "r-fakeres")) lambda *a, **kw: (None, "r-fakeres"))
with utils.tempdir() as tmpdir: with utils.tempdir() as tmpdir:
self.flags(ca_path=tmpdir, keys_path=tmpdir) self.flags(ca_path=tmpdir, keys_path=tmpdir, group='crypto')
crypto.ensure_ca_filesystem() crypto.ensure_ca_filesystem()
self.cloudpipe.launch_vpn_instance(self.context) self.cloudpipe.launch_vpn_instance(self.context)
@@ -63,7 +63,7 @@ class PipelibTest(test.TestCase):
def test_setup_key_pair(self): def test_setup_key_pair(self):
key_name = "%s%s" % (self.project, CONF.vpn_key_suffix) key_name = "%s%s" % (self.project, CONF.vpn_key_suffix)
with utils.tempdir() as tmpdir: with utils.tempdir() as tmpdir:
self.flags(keys_path=tmpdir) self.flags(keys_path=tmpdir, group='crypto')
# First attempt, key does not exist (thus it is generated) # First attempt, key does not exist (thus it is generated)
res1_key = self.cloudpipe.setup_key_pair(self.context) res1_key = self.cloudpipe.setup_key_pair(self.context)

View File

@@ -0,0 +1,4 @@
---
upgrade:
- All crypto configuration options have been added to the 'crypto'
group. They should no longer be included in the 'DEFAULT' group.