Copy octavia.certmgr to Castellan
Change-Id: I6971735681cb31bb66fc8d52d2f46fdfca8abebe
This commit is contained in:
parent
2271737fd0
commit
f8e6be10bf
|
@ -0,0 +1,45 @@
|
|||
# Copyright 2014, 2015 Rackspace US, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
Base Certificate Class
|
||||
"""
|
||||
import abc
|
||||
|
||||
import six
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class Cert(object):
|
||||
"""Base class to represent all certificates."""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_certificate(self):
|
||||
"""Returns the certificate."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_intermediates(self):
|
||||
"""Returns the intermediate certificates."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_private_key(self):
|
||||
"""Returns the private key for the certificate."""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_private_key_passphrase(self):
|
||||
"""Returns the passphrase for the private key."""
|
||||
pass
|
|
@ -0,0 +1,60 @@
|
|||
# Copyright 2014, 2015 Rackspace US, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
Certificate manager API
|
||||
"""
|
||||
import abc
|
||||
|
||||
import six
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class CertManager(object):
|
||||
"""Base Certificate Manager Interface
|
||||
|
||||
A Cert Manager is responsible for managing certificates for TLS. A Cert
|
||||
Manager is responsible for storing, reading, and deleting certs.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def store_cert(self, ctxt, 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 and returns its UUID that
|
||||
identifies it within the cert manager.
|
||||
If storage of the certificate data fails, a CertificateStorageException
|
||||
should be raised.
|
||||
"""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_cert(self, ctxt, cert_ref, check_only=False, **kwargs):
|
||||
"""Retrieves the specified cert.
|
||||
|
||||
If check_only is True, don't perform any sort of registration.
|
||||
If the specified cert does not exist, a CertificateStorageException
|
||||
should be raised.
|
||||
"""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def delete_cert(self, ctxt, cert_ref, **kwargs):
|
||||
"""Deletes the specified cert.
|
||||
|
||||
If the specified cert does not exist, a CertificateStorageException
|
||||
should be raised.
|
||||
"""
|
||||
pass
|
|
@ -0,0 +1,35 @@
|
|||
# Copyright 2014, 2015 Rackspace US, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
Certificate manager implementation that raises NotImplementedError
|
||||
"""
|
||||
|
||||
from castellan.certmgr import cert_mgr
|
||||
|
||||
|
||||
class NotImplementedCertManager(cert_mgr.CertManager):
|
||||
"""Cert Manager implementation that raises NotImplementedError for all ops.
|
||||
|
||||
"""
|
||||
|
||||
def store_cert(self, ctxt, certificate, private_key, intermediates=None,
|
||||
private_key_passphrase=None, **kwargs):
|
||||
raise NotImplementedError()
|
||||
|
||||
def get_cert(self, ctxt, cert_ref, check_only=False, **kwargs):
|
||||
raise NotImplementedError()
|
||||
|
||||
def delete_cert(self, ctxt, cert_ref, **kwargs):
|
||||
raise NotImplementedError()
|
|
@ -0,0 +1,24 @@
|
|||
# Copyright 2011 Justin Santa Barbara
|
||||
# Copyright 2012 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.
|
||||
|
||||
"""Implementation of a fake key manager."""
|
||||
|
||||
|
||||
from castellan.tests.certmgr import mock_cert_mgr
|
||||
|
||||
|
||||
def fake_api():
|
||||
return mock_cert_mgr.MockCertManager()
|
|
@ -0,0 +1,53 @@
|
|||
# Copyright 2014, 2015 Rackspace US, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
Mock Certificate Class
|
||||
"""
|
||||
from castellan.certmgr import cert
|
||||
|
||||
|
||||
class MockCert(cert.Cert):
|
||||
"""Mock class to represent a certificate."""
|
||||
def __init__(self, certificate=None, intermediates=None, private_key=None,
|
||||
private_key_passphrase=None):
|
||||
self.certificate = certificate
|
||||
self.intermediates = intermediates
|
||||
self.private_key = private_key
|
||||
self.private_key_passphrase = private_key_passphrase
|
||||
|
||||
def get_certificate(self):
|
||||
"""Returns the certificate."""
|
||||
return self.certificate
|
||||
|
||||
def get_intermediates(self):
|
||||
"""Returns the intermediate certificates."""
|
||||
return self.intermediates
|
||||
|
||||
def get_private_key(self):
|
||||
"""Returns the private key for the certificate."""
|
||||
return self.private_key
|
||||
|
||||
def get_private_key_passphrase(self):
|
||||
"""Returns the passphrase for the private key."""
|
||||
return self.private_key_passphrase
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
return self.__dict__ == other.__dict__
|
||||
else:
|
||||
return False
|
||||
|
||||
def __ne__(self, other):
|
||||
return not self.__eq__(other)
|
|
@ -0,0 +1,100 @@
|
|||
# Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory
|
||||
# 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.
|
||||
|
||||
"""
|
||||
A mock implementation of a cert manager that stores certs in a dictionary.
|
||||
|
||||
This cert manager implementation is primarily intended for testing. In
|
||||
particular, it does not store certs persistently. Lack of a centralized cert
|
||||
store also makes this implementation unsuitable for use among different
|
||||
services.
|
||||
|
||||
Note: Instantiating this class multiple times will create separate cert stores.
|
||||
Certs created in one instance will not be accessible from other instances of
|
||||
this class.
|
||||
"""
|
||||
|
||||
import uuid
|
||||
|
||||
from castellan.certmgr import cert_mgr
|
||||
from castellan.common import exception
|
||||
from castellan.tests.certmgr import mock_cert
|
||||
|
||||
|
||||
class MockCertManager(cert_mgr.CertManager):
|
||||
"""Mocking manager for integration tests.
|
||||
|
||||
This mock cert manager implementation supports all the methods specified
|
||||
by the cert manager interface. This implementation stores certs within a
|
||||
dictionary, and as a result, it is not acceptable for use across different
|
||||
services. Side effects (e.g., raising exceptions) for each method are
|
||||
handled as specified by the cert manager interface.
|
||||
|
||||
This cert manager is not suitable for use in production deployments.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.certs = {}
|
||||
|
||||
def _generate_cert_id(self):
|
||||
cert_id = str(uuid.uuid4())
|
||||
while cert_id in self.certs:
|
||||
cert_id = str(uuid.uuid4())
|
||||
|
||||
return cert_id
|
||||
|
||||
def store_cert(self, ctxt, certificate, private_key, intermediates=None,
|
||||
private_key_passphrase=None, **kwargs):
|
||||
"""Stores a certificate.
|
||||
|
||||
This implementation returns a UUID for the created cert. A
|
||||
Forbidden exception is raised if the specified context is None.
|
||||
"""
|
||||
if ctxt is None:
|
||||
raise exception.Forbidden()
|
||||
|
||||
cert_id = self._generate_cert_id()
|
||||
cert = mock_cert.MockCert(
|
||||
certificate=certificate,
|
||||
private_key=private_key,
|
||||
intermediates=intermediates,
|
||||
private_key_passphrase=private_key_passphrase
|
||||
)
|
||||
self.certs[cert_id] = cert
|
||||
|
||||
return cert_id
|
||||
|
||||
def get_cert(self, ctxt, cert_id, **kwargs):
|
||||
"""Retrieves the cert identified by the specified id.
|
||||
|
||||
This implementation returns the cert that is associated with the
|
||||
specified UUID. A Forbidden exception is raised if the specified
|
||||
context is None; a KeyError is raised if the UUID is invalid.
|
||||
"""
|
||||
if ctxt is None:
|
||||
raise exception.Forbidden()
|
||||
|
||||
return self.certs[cert_id]
|
||||
|
||||
def delete_cert(self, ctxt, cert_id, **kwargs):
|
||||
"""Deletes the cert identified by the specified id.
|
||||
|
||||
A Forbidden exception is raised if the context is None and a
|
||||
KeyError is raised if the UUID is invalid.
|
||||
"""
|
||||
if ctxt is None:
|
||||
raise exception.Forbidden()
|
||||
|
||||
del self.certs[cert_id]
|
|
@ -0,0 +1,33 @@
|
|||
# Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory
|
||||
# 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.
|
||||
|
||||
"""
|
||||
Test cases for the cert manager.
|
||||
"""
|
||||
|
||||
from castellan.tests import base
|
||||
|
||||
|
||||
class CertManagerTestCase(base.TestCase):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(CertManagerTestCase, self).__init__(*args, **kwargs)
|
||||
|
||||
def _create_cert_manager(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
def setUp(self):
|
||||
super(CertManagerTestCase, self).setUp()
|
||||
|
||||
self.cert_mgr = self._create_cert_manager()
|
|
@ -0,0 +1,90 @@
|
|||
# Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory
|
||||
# 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.
|
||||
|
||||
"""
|
||||
Test cases for the mock cert manager.
|
||||
"""
|
||||
|
||||
from castellan.common import exception
|
||||
from castellan import context
|
||||
from castellan.tests.certmgr import mock_cert
|
||||
from castellan.tests.certmgr import mock_cert_mgr
|
||||
from castellan.tests.certmgr import test_cert_mgr
|
||||
|
||||
|
||||
class MockCertManagerTestCase(test_cert_mgr.CertManagerTestCase):
|
||||
|
||||
def _create_cert_manager(self):
|
||||
return mock_cert_mgr.MockCertManager()
|
||||
|
||||
def setUp(self):
|
||||
super(MockCertManagerTestCase, self).setUp()
|
||||
|
||||
self.ctxt = context.RequestContext('fake', 'fake')
|
||||
self.certificate = "This is a certificate. I swear."
|
||||
self.intermediates = "This is a list of intermediates. Really."
|
||||
self.private_key = "Don't look at me!"
|
||||
self.private_key_passphrase = "hunter2"
|
||||
|
||||
def test_store_cert(self):
|
||||
_cert = mock_cert.MockCert(
|
||||
certificate=self.certificate,
|
||||
private_key=self.private_key,
|
||||
intermediates=self.intermediates,
|
||||
private_key_passphrase=self.private_key_passphrase
|
||||
)
|
||||
cert_id = self.cert_mgr.store_cert(
|
||||
ctxt=self.ctxt,
|
||||
certificate=self.certificate,
|
||||
private_key=self.private_key,
|
||||
intermediates=self.intermediates,
|
||||
private_key_passphrase=self.private_key_passphrase
|
||||
)
|
||||
|
||||
actual_cert = self.cert_mgr.get_cert(self.ctxt, cert_id)
|
||||
self.assertEqual(_cert, actual_cert)
|
||||
|
||||
def test_store_null_context(self):
|
||||
self.assertRaises(exception.Forbidden,
|
||||
self.cert_mgr.store_cert, None, None, None)
|
||||
|
||||
def test_get_cert(self):
|
||||
pass
|
||||
|
||||
def test_get_null_context(self):
|
||||
self.assertRaises(exception.Forbidden,
|
||||
self.cert_mgr.get_cert, None, None)
|
||||
|
||||
def test_get_unknown_cert(self):
|
||||
self.assertRaises(KeyError, self.cert_mgr.get_cert, self.ctxt, None)
|
||||
|
||||
def test_delete_cert(self):
|
||||
cert_id = self.cert_mgr.store_cert(
|
||||
ctxt=self.ctxt,
|
||||
certificate=self.certificate,
|
||||
private_key=self.private_key,
|
||||
intermediates=self.intermediates,
|
||||
private_key_passphrase=self.private_key_passphrase
|
||||
)
|
||||
self.cert_mgr.delete_cert(self.ctxt, cert_id)
|
||||
|
||||
self.assertRaises(KeyError, self.cert_mgr.get_cert, self.ctxt, cert_id)
|
||||
|
||||
def test_delete_null_context(self):
|
||||
self.assertRaises(exception.Forbidden,
|
||||
self.cert_mgr.delete_cert, None, None)
|
||||
|
||||
def test_delete_unknown_cert(self):
|
||||
self.assertRaises(KeyError, self.cert_mgr.delete_cert, self.ctxt, None)
|
|
@ -0,0 +1,42 @@
|
|||
# Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory
|
||||
# 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.
|
||||
|
||||
"""
|
||||
Test cases for the not implemented cert manager.
|
||||
"""
|
||||
|
||||
from castellan.certmgr import not_implemented_cert_mgr
|
||||
from castellan.tests.certmgr import test_cert_mgr
|
||||
|
||||
|
||||
class NotImplementedCertManagerTestCase(test_cert_mgr.CertManagerTestCase):
|
||||
|
||||
def _create_cert_manager(self):
|
||||
return not_implemented_cert_mgr.NotImplementedCertManager()
|
||||
|
||||
def setUp(self):
|
||||
super(NotImplementedCertManagerTestCase, self).setUp()
|
||||
|
||||
def test_store_cert(self):
|
||||
self.assertRaises(NotImplementedError,
|
||||
self.cert_mgr.store_cert, None, None, None)
|
||||
|
||||
def test_get_cert(self):
|
||||
self.assertRaises(NotImplementedError,
|
||||
self.cert_mgr.get_cert, None, None)
|
||||
|
||||
def test_delete_cert(self):
|
||||
self.assertRaises(NotImplementedError,
|
||||
self.cert_mgr.delete_cert, None, None)
|
Loading…
Reference in New Issue