164 lines
6.0 KiB
Python
164 lines
6.0 KiB
Python
# Copyright 2014 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.
|
|
|
|
import os
|
|
import stat
|
|
|
|
import mock
|
|
from oslo_config import cfg
|
|
from oslo_config import fixture as oslo_fixture
|
|
from oslo_utils import uuidutils
|
|
|
|
import octavia.certificates.common.cert as cert
|
|
import octavia.certificates.manager.local as local_cert_mgr
|
|
from octavia.common import exceptions
|
|
from octavia.tests.common import sample_certs
|
|
import octavia.tests.unit.base as base
|
|
|
|
|
|
class TestLocalManager(base.TestCase):
|
|
|
|
def setUp(self):
|
|
self.certificate = sample_certs.X509_CERT.decode('utf-8')
|
|
self.intermediates = sample_certs.X509_IMDS.decode('utf-8')
|
|
self.private_key = sample_certs.X509_CERT_KEY.decode('utf-8')
|
|
self.private_key_passphrase = "My Private Key Passphrase"
|
|
|
|
conf = oslo_fixture.Config(cfg.CONF)
|
|
conf.config(group="certificates", storage_path="/tmp/")
|
|
|
|
super(TestLocalManager, self).setUp()
|
|
|
|
def _store_cert(self):
|
|
fd_mock = mock.mock_open()
|
|
open_mock = mock.Mock()
|
|
# Attempt to store the cert
|
|
with mock.patch('os.open', open_mock), mock.patch.object(
|
|
os, 'fdopen', fd_mock):
|
|
cert_id = local_cert_mgr.LocalCertManager.store_cert(
|
|
context=None,
|
|
certificate=self.certificate,
|
|
intermediates=self.intermediates,
|
|
private_key=self.private_key,
|
|
private_key_passphrase=self.private_key_passphrase
|
|
)
|
|
|
|
# Check that something came back
|
|
self.assertIsNotNone(cert_id)
|
|
|
|
# Verify the correct files were opened
|
|
flags = os.O_WRONLY | os.O_CREAT
|
|
mode = stat.S_IRUSR | stat.S_IWUSR # mode 0600
|
|
open_mock.assert_has_calls([
|
|
mock.call(
|
|
os.path.join('/tmp/{0}.crt'.format(cert_id)), flags, mode),
|
|
mock.call(
|
|
os.path.join('/tmp/{0}.key'.format(cert_id)), flags, mode),
|
|
mock.call(
|
|
os.path.join('/tmp/{0}.int'.format(cert_id)), flags, mode),
|
|
mock.call(
|
|
os.path.join('/tmp/{0}.pass'.format(cert_id)), flags, mode)
|
|
], any_order=True)
|
|
|
|
# Verify the writes were made
|
|
fd_mock().write.assert_has_calls([
|
|
mock.call(self.certificate),
|
|
mock.call(self.intermediates),
|
|
mock.call(self.private_key),
|
|
mock.call(self.private_key_passphrase)
|
|
], any_order=True)
|
|
|
|
return cert_id
|
|
|
|
def _get_cert(self, cert_id):
|
|
fd_mock = mock.mock_open()
|
|
fd_mock.side_effect = [
|
|
mock.mock_open(read_data=self.certificate).return_value,
|
|
mock.mock_open(read_data=self.private_key).return_value,
|
|
mock.mock_open(read_data=self.intermediates).return_value,
|
|
mock.mock_open(read_data=self.private_key_passphrase).return_value
|
|
]
|
|
open_mock = mock.Mock()
|
|
# Attempt to retrieve the cert
|
|
with mock.patch('os.open', open_mock), mock.patch.object(
|
|
os, 'fdopen', fd_mock):
|
|
data = local_cert_mgr.LocalCertManager.get_cert(None, cert_id)
|
|
|
|
# Verify the correct files were opened
|
|
flags = os.O_RDONLY
|
|
open_mock.assert_has_calls([
|
|
mock.call(os.path.join('/tmp/{0}.crt'.format(cert_id)), flags),
|
|
mock.call(os.path.join('/tmp/{0}.key'.format(cert_id)), flags),
|
|
mock.call(os.path.join('/tmp/{0}.int'.format(cert_id)), flags),
|
|
mock.call(os.path.join('/tmp/{0}.pass'.format(cert_id)), flags)
|
|
], any_order=True)
|
|
|
|
# The returned data should be a Cert object
|
|
self.assertIsInstance(data, cert.Cert)
|
|
|
|
return data
|
|
|
|
def _delete_cert(self, cert_id):
|
|
remove_mock = mock.Mock()
|
|
# Delete the cert
|
|
with mock.patch('os.remove', remove_mock):
|
|
local_cert_mgr.LocalCertManager.delete_cert(None, cert_id)
|
|
|
|
# Verify the correct files were removed
|
|
remove_mock.assert_has_calls([
|
|
mock.call(os.path.join('/tmp/{0}.crt'.format(cert_id))),
|
|
mock.call(os.path.join('/tmp/{0}.key'.format(cert_id))),
|
|
mock.call(os.path.join('/tmp/{0}.int'.format(cert_id))),
|
|
mock.call(os.path.join('/tmp/{0}.pass'.format(cert_id)))
|
|
], any_order=True)
|
|
|
|
def test_store_cert(self):
|
|
self._store_cert()
|
|
|
|
def test_get_cert(self):
|
|
# Get the cert
|
|
self._get_cert("cert1")
|
|
|
|
def test_delete_cert(self):
|
|
# Store a cert
|
|
cert_id = self._store_cert()
|
|
|
|
# Verify the cert exists
|
|
self._get_cert(cert_id)
|
|
|
|
# Delete the cert
|
|
self._delete_cert(cert_id)
|
|
|
|
def test_get_secret(self):
|
|
fd_mock = mock.mock_open()
|
|
open_mock = mock.Mock()
|
|
secret_id = uuidutils.generate_uuid()
|
|
# Attempt to retrieve the secret
|
|
with mock.patch('os.open', open_mock), mock.patch.object(
|
|
os, 'fdopen', fd_mock):
|
|
local_cert_mgr.LocalCertManager.get_secret(None, secret_id)
|
|
|
|
# Verify the correct files were opened
|
|
flags = os.O_RDONLY
|
|
open_mock.assert_called_once_with('/tmp/{0}.crt'.format(secret_id),
|
|
flags)
|
|
|
|
# Test failure path
|
|
with mock.patch('os.open', open_mock), mock.patch.object(
|
|
os, 'fdopen', fd_mock) as mock_open:
|
|
mock_open.side_effect = IOError
|
|
self.assertRaises(exceptions.CertificateRetrievalException,
|
|
local_cert_mgr.LocalCertManager.get_secret,
|
|
None, secret_id)
|