Files
octavia/octavia/certificates/manager/local.py
Adam Harwell 52351a5698 Refactor BarbicanAuth to allow for configurable auth method
There is now a new configuration option "barbican_auth" in the
certificates section, to specify which auth plugin to use when
communicating with Barbican. This is because the default option (using
ACLs inside Barbican to control access) should be ok as a default
workflow, but it might be required to use other methods depending on
your deployment. For example, another possible auth method would be
BarbicanTrustAuth, utilizing Keystone Trusts.

Some deployers may need custom auth methods that do not exist in
upstream Keystone, and will need their own Auth plugin. This should be in line
with the way Octavia's network and compute drivers work already.

While we're in this file, prune the unused (and really bad) method that
would *actually* delete certs from Barbican (not in our scope).
Also do the tenant_id -> project_id rename.

Change-Id: Ic9aef68924bb5c216734afd25403e59476c576e7
2015-12-08 14:56:32 -06:00

162 lines
6.1 KiB
Python

# Copyright (c) 2014 Rackspace US, Inc
# 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 uuid
from oslo_config import cfg
from oslo_log import log as logging
from octavia.certificates.common import local as local_common
from octavia.certificates.manager import cert_mgr
from octavia.common import exceptions
from octavia.i18n import _LE, _LI
LOG = logging.getLogger(__name__)
CONF = cfg.CONF
class LocalCertManager(cert_mgr.CertManager):
"""Cert Manager Interface that stores data locally."""
@staticmethod
def store_cert(project_id, certificate, private_key, intermediates=None,
private_key_passphrase=None, **kwargs):
"""Stores (i.e., registers) a cert with the cert manager.
This method stores the specified cert to the filesystem and returns
a UUID that can be used to retrieve it.
:param project_id: Ignored in this implementation
:param certificate: PEM encoded TLS certificate
:param private_key: private key for the supplied certificate
:param intermediates: ordered and concatenated intermediate certs
:param private_key_passphrase: optional passphrase for the supplied key
:returns: the UUID of the stored cert
:raises CertificateStorageException: if certificate storage fails
"""
cert_ref = str(uuid.uuid4())
filename_base = os.path.join(CONF.certificates.storage_path, cert_ref)
LOG.info(_LI(
"Storing certificate data on the local filesystem."
))
try:
filename_certificate = "{0}.crt".format(filename_base)
with open(filename_certificate, 'w') as cert_file:
cert_file.write(certificate)
filename_private_key = "{0}.key".format(filename_base)
with open(filename_private_key, 'w') as key_file:
key_file.write(private_key)
if intermediates:
filename_intermediates = "{0}.int".format(filename_base)
with open(filename_intermediates, 'w') as int_file:
int_file.write(intermediates)
if private_key_passphrase:
filename_pkp = "{0}.pass".format(filename_base)
with open(filename_pkp, 'w') as pass_file:
pass_file.write(private_key_passphrase)
except IOError as ioe:
LOG.error(_LE("Failed to store certificate."))
raise exceptions.CertificateStorageException(message=ioe.message)
return cert_ref
@staticmethod
def get_cert(project_id, cert_ref, **kwargs):
"""Retrieves the specified cert.
:param project_id: Ignored in this implementation
:param cert_ref: the UUID of the cert to retrieve
:return: octavia.certificates.common.Cert representation of the
certificate data
:raises CertificateStorageException: if certificate retrieval fails
"""
LOG.info(_LI("Loading certificate %s from the local filesystem."),
cert_ref)
filename_base = os.path.join(CONF.certificates.storage_path, cert_ref)
filename_certificate = "{0}.crt".format(filename_base)
filename_private_key = "{0}.key".format(filename_base)
filename_intermediates = "{0}.int".format(filename_base)
filename_pkp = "{0}.pass".format(filename_base)
cert_data = dict()
try:
with open(filename_certificate, 'r') as cert_file:
cert_data['certificate'] = cert_file.read()
except IOError:
LOG.error(_LE("Failed to read certificate for %s."), cert_ref)
raise exceptions.CertificateStorageException(
msg="Certificate could not be read."
)
try:
with open(filename_private_key, 'r') as key_file:
cert_data['private_key'] = key_file.read()
except IOError:
LOG.error(_LE("Failed to read private key for %s"), cert_ref)
raise exceptions.CertificateStorageException(
msg="Private Key could not be read."
)
try:
with open(filename_intermediates, 'r') as int_file:
cert_data['intermediates'] = int_file.read()
except IOError:
pass
try:
with open(filename_pkp, 'r') as pass_file:
cert_data['private_key_passphrase'] = pass_file.read()
except IOError:
pass
return local_common.LocalCert(**cert_data)
@staticmethod
def delete_cert(project_id, cert_ref, **kwargs):
"""Deletes the specified cert.
:param project_id: Ignored in this implementation
:param cert_ref: the UUID of the cert to delete
:raises CertificateStorageException: if certificate deletion fails
"""
LOG.info(_LI("Deleting certificate %s from the local filesystem."),
cert_ref)
filename_base = os.path.join(CONF.certificates.storage_path, cert_ref)
filename_certificate = "{0}.crt".format(filename_base)
filename_private_key = "{0}.key".format(filename_base)
filename_intermediates = "{0}.int".format(filename_base)
filename_pkp = "{0}.pass".format(filename_base)
try:
os.remove(filename_certificate)
os.remove(filename_private_key)
os.remove(filename_intermediates)
os.remove(filename_pkp)
except IOError as ioe:
LOG.error(_LE("Failed to delete certificate %s"), cert_ref)
raise exceptions.CertificateStorageException(message=ioe.message)