Release certs/trust when creating bay is failed
Certificates and trust/trustee should be released correctly when creating bay is failed. This fixes it. Change-Id: Ic784a57ef751526123898f00447ebe8fac650d3e Closes-Bug: #1560308
This commit is contained in:
parent
b52cc471f2
commit
f3a56f98c4
@ -569,3 +569,11 @@ class QuotaAlreadyExists(Conflict):
|
|||||||
|
|
||||||
class RegionsListFailed(MagnumException):
|
class RegionsListFailed(MagnumException):
|
||||||
message = _("Failed to list regions.")
|
message = _("Failed to list regions.")
|
||||||
|
|
||||||
|
|
||||||
|
class TrusteeOrTrustToBayFailed(MagnumException):
|
||||||
|
message = _("Failed to create trustee or trust for Bay: %(bay_uuid)s")
|
||||||
|
|
||||||
|
|
||||||
|
class CertificatesToBayFailed(MagnumException):
|
||||||
|
message = _("Failed to create certificates for Bay: %(bay_uuid)s")
|
||||||
|
@ -132,12 +132,14 @@ class Handler(object):
|
|||||||
cert_manager.generate_certificates_to_bay(bay)
|
cert_manager.generate_certificates_to_bay(bay)
|
||||||
created_stack = _create_stack(context, osc, bay,
|
created_stack = _create_stack(context, osc, bay,
|
||||||
bay_create_timeout)
|
bay_create_timeout)
|
||||||
except exc.HTTPBadRequest as e:
|
except Exception as e:
|
||||||
cert_manager.delete_certificates_from_bay(bay)
|
cert_manager.delete_certificates_from_bay(bay)
|
||||||
trust_manager.delete_trustee_and_trust(osc, bay)
|
trust_manager.delete_trustee_and_trust(osc, bay)
|
||||||
raise exception.InvalidParameterValue(message=six.text_type(e))
|
|
||||||
except Exception:
|
if isinstance(e, exc.HTTPBadRequest):
|
||||||
raise
|
e = exception.InvalidParameterValue(message=six.text_type(e))
|
||||||
|
|
||||||
|
raise e
|
||||||
|
|
||||||
bay.stack_id = created_stack['stack']['id']
|
bay.stack_id = created_stack['stack']['id']
|
||||||
bay.status = bay_status.CREATE_IN_PROGRESS
|
bay.status = bay_status.CREATE_IN_PROGRESS
|
||||||
|
@ -18,8 +18,10 @@ from oslo_log import log as logging
|
|||||||
import six
|
import six
|
||||||
|
|
||||||
from magnum.common import cert_manager
|
from magnum.common import cert_manager
|
||||||
|
from magnum.common import exception
|
||||||
from magnum.common import short_id
|
from magnum.common import short_id
|
||||||
from magnum.common.x509 import operations as x509
|
from magnum.common.x509 import operations as x509
|
||||||
|
from magnum.i18n import _LE
|
||||||
from magnum.i18n import _LW
|
from magnum.i18n import _LW
|
||||||
|
|
||||||
CONDUCTOR_CLIENT_NAME = six.u('Magnum-Conductor')
|
CONDUCTOR_CLIENT_NAME = six.u('Magnum-Conductor')
|
||||||
@ -87,15 +89,22 @@ def generate_certificates_to_bay(bay):
|
|||||||
:param bay: The bay to set CA cert and magnum client cert
|
:param bay: The bay to set CA cert and magnum client cert
|
||||||
:returns: CA cert uuid and magnum client cert uuid
|
:returns: CA cert uuid and magnum client cert uuid
|
||||||
"""
|
"""
|
||||||
|
try:
|
||||||
issuer_name = _get_issuer_name(bay)
|
issuer_name = _get_issuer_name(bay)
|
||||||
|
|
||||||
LOG.debug('Start to generate certificates: %s', issuer_name)
|
LOG.debug('Start to generate certificates: %s', issuer_name)
|
||||||
|
|
||||||
ca_cert_ref, ca_cert, ca_password = _generate_ca_cert(issuer_name)
|
ca_cert_ref, ca_cert, ca_password = _generate_ca_cert(issuer_name)
|
||||||
magnum_cert_ref = _generate_client_cert(issuer_name, ca_cert, ca_password)
|
magnum_cert_ref = _generate_client_cert(issuer_name,
|
||||||
|
ca_cert,
|
||||||
|
ca_password)
|
||||||
|
|
||||||
bay.ca_cert_ref = ca_cert_ref
|
bay.ca_cert_ref = ca_cert_ref
|
||||||
bay.magnum_cert_ref = magnum_cert_ref
|
bay.magnum_cert_ref = magnum_cert_ref
|
||||||
|
except Exception:
|
||||||
|
LOG.exception(_LE('Failed to generate certificates for Bay: %s'),
|
||||||
|
bay.uuid)
|
||||||
|
raise exception.CertificatesToBayFailed(bay_uuid=bay.uuid)
|
||||||
|
|
||||||
|
|
||||||
def get_bay_ca_certificate(bay):
|
def get_bay_ca_certificate(bay):
|
||||||
@ -153,10 +162,11 @@ def delete_certificates_from_bay(bay):
|
|||||||
|
|
||||||
:param bay: The bay which has certs
|
:param bay: The bay which has certs
|
||||||
"""
|
"""
|
||||||
for cert_ref in [bay.ca_cert_ref, bay.magnum_cert_ref]:
|
for cert_ref in ['ca_cert_ref', 'magnum_cert_ref']:
|
||||||
try:
|
try:
|
||||||
|
cert_ref = getattr(bay, cert_ref, None)
|
||||||
if cert_ref:
|
if cert_ref:
|
||||||
cert_manager.get_backend().CertManager.delete_cert(
|
cert_manager.get_backend().CertManager.delete_cert(
|
||||||
cert_ref, resource_ref=bay.uuid)
|
cert_ref, resource_ref=bay.uuid)
|
||||||
except Exception:
|
except Exception:
|
||||||
LOG.warning(_LW("Deleting cert is failed: %s"), cert_ref)
|
LOG.warning(_LW("Deleting certs is failed for Bay %s"), bay.uuid)
|
||||||
|
@ -13,7 +13,9 @@
|
|||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
|
|
||||||
|
from magnum.common import exception
|
||||||
from magnum.common import utils
|
from magnum.common import utils
|
||||||
|
from magnum.i18n import _LE
|
||||||
|
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
CONF.import_opt('trustee_domain_id', 'magnum.common.keystone',
|
CONF.import_opt('trustee_domain_id', 'magnum.common.keystone',
|
||||||
@ -23,6 +25,7 @@ LOG = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
def create_trustee_and_trust(osc, bay):
|
def create_trustee_and_trust(osc, bay):
|
||||||
|
try:
|
||||||
password = utils.generate_password(length=18)
|
password = utils.generate_password(length=18)
|
||||||
trustee = osc.keystone().create_trustee(
|
trustee = osc.keystone().create_trustee(
|
||||||
bay.uuid,
|
bay.uuid,
|
||||||
@ -33,6 +36,10 @@ def create_trustee_and_trust(osc, bay):
|
|||||||
bay.trustee_password = password
|
bay.trustee_password = password
|
||||||
trust = osc.keystone().create_trust(trustee.id)
|
trust = osc.keystone().create_trust(trustee.id)
|
||||||
bay.trust_id = trust.id
|
bay.trust_id = trust.id
|
||||||
|
except Exception:
|
||||||
|
LOG.exception(_LE('Failed to create trustee and trust for Bay: %s'),
|
||||||
|
bay.uuid)
|
||||||
|
raise exception.TrusteeOrTrustToBayFailed(bay_uuid=bay.uuid)
|
||||||
|
|
||||||
|
|
||||||
def delete_trustee_and_trust(osc, bay):
|
def delete_trustee_and_trust(osc, bay):
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
|
from magnum.common import exception
|
||||||
from magnum.conductor.handlers.common import cert_manager
|
from magnum.conductor.handlers.common import cert_manager
|
||||||
from magnum.tests import base
|
from magnum.tests import base
|
||||||
|
|
||||||
@ -152,6 +153,16 @@ class CertManagerTestCase(base.BaseTestCase):
|
|||||||
mock_generate_ca_cert,
|
mock_generate_ca_cert,
|
||||||
mock_generate_client_cert)
|
mock_generate_client_cert)
|
||||||
|
|
||||||
|
@mock.patch('magnum.conductor.handlers.common.cert_manager.'
|
||||||
|
'_get_issuer_name')
|
||||||
|
def test_generate_certificates_with_error(self, mock_get_issuer_name):
|
||||||
|
mock_bay = mock.MagicMock()
|
||||||
|
mock_get_issuer_name.side_effect = exception.MagnumException()
|
||||||
|
|
||||||
|
self.assertRaises(exception.CertificatesToBayFailed,
|
||||||
|
cert_manager.generate_certificates_to_bay,
|
||||||
|
mock_bay)
|
||||||
|
|
||||||
@mock.patch('magnum.common.x509.operations.sign')
|
@mock.patch('magnum.common.x509.operations.sign')
|
||||||
def test_sign_node_certificate(self, mock_x509_sign):
|
def test_sign_node_certificate(self, mock_x509_sign):
|
||||||
mock_bay = mock.MagicMock()
|
mock_bay = mock.MagicMock()
|
||||||
|
@ -16,6 +16,7 @@ import mock
|
|||||||
from mock import patch
|
from mock import patch
|
||||||
from oslo_config import fixture
|
from oslo_config import fixture
|
||||||
|
|
||||||
|
from magnum.common import exception
|
||||||
from magnum.conductor.handlers.common import trust_manager
|
from magnum.conductor.handlers.common import trust_manager
|
||||||
from magnum.tests import base
|
from magnum.tests import base
|
||||||
|
|
||||||
@ -67,6 +68,16 @@ class TrustManagerTestCase(base.BaseTestCase):
|
|||||||
self.assertEqual(mock_password, mock_bay.trustee_password)
|
self.assertEqual(mock_password, mock_bay.trustee_password)
|
||||||
self.assertEqual(mock_trust.id, mock_bay.trust_id)
|
self.assertEqual(mock_trust.id, mock_bay.trust_id)
|
||||||
|
|
||||||
|
@patch('magnum.common.utils.generate_password')
|
||||||
|
def test_create_trustee_and_trust_with_error(self, mock_generate_password):
|
||||||
|
mock_bay = mock.MagicMock()
|
||||||
|
mock_generate_password.side_effect = exception.MagnumException()
|
||||||
|
|
||||||
|
self.assertRaises(exception.TrusteeOrTrustToBayFailed,
|
||||||
|
trust_manager.create_trustee_and_trust,
|
||||||
|
self.osc,
|
||||||
|
mock_bay)
|
||||||
|
|
||||||
def test_delete_trustee_and_trust(self):
|
def test_delete_trustee_and_trust(self):
|
||||||
mock_bay = mock.MagicMock()
|
mock_bay = mock.MagicMock()
|
||||||
mock_bay.trust_id = 'trust_id'
|
mock_bay.trust_id = 'trust_id'
|
||||||
|
@ -191,6 +191,39 @@ class TestHandler(db_base.DbTestCase):
|
|||||||
mock_trust_manager.create_trustee_and_trust.assert_called_once_with(
|
mock_trust_manager.create_trustee_and_trust.assert_called_once_with(
|
||||||
osc, self.bay)
|
osc, self.bay)
|
||||||
|
|
||||||
|
def _test_create_failed(self,
|
||||||
|
mock_openstack_client_class,
|
||||||
|
mock_cert_manager,
|
||||||
|
mock_trust_manager,
|
||||||
|
expected_exception,
|
||||||
|
is_create_cert_called=True,
|
||||||
|
is_create_trust_called=True):
|
||||||
|
osc = mock.MagicMock()
|
||||||
|
mock_openstack_client_class.return_value = osc
|
||||||
|
timeout = 15
|
||||||
|
|
||||||
|
self.assertRaises(
|
||||||
|
expected_exception,
|
||||||
|
self.handler.bay_create,
|
||||||
|
self.context,
|
||||||
|
self.bay, timeout
|
||||||
|
)
|
||||||
|
|
||||||
|
gctb = mock_cert_manager.generate_certificates_to_bay
|
||||||
|
if is_create_cert_called:
|
||||||
|
gctb.assert_called_once_with(self.bay)
|
||||||
|
else:
|
||||||
|
gctb.assert_not_called()
|
||||||
|
ctat = mock_trust_manager.create_trustee_and_trust
|
||||||
|
if is_create_trust_called:
|
||||||
|
ctat.assert_called_once_with(osc, self.bay)
|
||||||
|
else:
|
||||||
|
ctat.assert_not_called()
|
||||||
|
|
||||||
|
mock_cert_manager.delete_certificates_from_bay(self.bay)
|
||||||
|
mock_trust_manager.delete_trustee_and_trust.assert_called_once_with(
|
||||||
|
osc, self.bay)
|
||||||
|
|
||||||
@patch('magnum.conductor.handlers.bay_conductor.trust_manager')
|
@patch('magnum.conductor.handlers.bay_conductor.trust_manager')
|
||||||
@patch('magnum.conductor.handlers.bay_conductor.cert_manager')
|
@patch('magnum.conductor.handlers.bay_conductor.cert_manager')
|
||||||
@patch('magnum.conductor.handlers.bay_conductor._create_stack')
|
@patch('magnum.conductor.handlers.bay_conductor._create_stack')
|
||||||
@ -199,20 +232,49 @@ class TestHandler(db_base.DbTestCase):
|
|||||||
mock_create_stack,
|
mock_create_stack,
|
||||||
mock_cert_manager,
|
mock_cert_manager,
|
||||||
mock_trust_manager):
|
mock_trust_manager):
|
||||||
osc = mock.MagicMock()
|
|
||||||
mock_openstack_client_class.return_value = osc
|
|
||||||
mock_create_stack.side_effect = exc.HTTPBadRequest
|
mock_create_stack.side_effect = exc.HTTPBadRequest
|
||||||
timeout = 15
|
|
||||||
self.assertRaises(exception.InvalidParameterValue,
|
self._test_create_failed(
|
||||||
self.handler.bay_create, self.context,
|
mock_openstack_client_class,
|
||||||
self.bay, timeout)
|
mock_cert_manager,
|
||||||
mock_cert_manager.generate_certificates_to_bay.assert_called_once_with(
|
mock_trust_manager,
|
||||||
self.bay)
|
exception.InvalidParameterValue
|
||||||
mock_cert_manager.delete_certificates_from_bay(self.bay)
|
)
|
||||||
mock_trust_manager.create_trustee_and_trust.assert_called_once_with(
|
|
||||||
osc, self.bay)
|
@patch('magnum.conductor.handlers.bay_conductor.trust_manager')
|
||||||
mock_trust_manager.delete_trustee_and_trust.assert_called_once_with(
|
@patch('magnum.conductor.handlers.bay_conductor.cert_manager')
|
||||||
osc, self.bay)
|
@patch('magnum.common.clients.OpenStackClients')
|
||||||
|
def test_create_with_cert_failed(self, mock_openstack_client_class,
|
||||||
|
mock_cert_manager,
|
||||||
|
mock_trust_manager):
|
||||||
|
e = exception.CertificatesToBayFailed(bay_uuid='uuid')
|
||||||
|
mock_cert_manager.generate_certificates_to_bay.side_effect = e
|
||||||
|
|
||||||
|
self._test_create_failed(
|
||||||
|
mock_openstack_client_class,
|
||||||
|
mock_cert_manager,
|
||||||
|
mock_trust_manager,
|
||||||
|
exception.CertificatesToBayFailed
|
||||||
|
)
|
||||||
|
|
||||||
|
@patch('magnum.conductor.handlers.bay_conductor.trust_manager')
|
||||||
|
@patch('magnum.conductor.handlers.bay_conductor.cert_manager')
|
||||||
|
@patch('magnum.conductor.handlers.bay_conductor._create_stack')
|
||||||
|
@patch('magnum.common.clients.OpenStackClients')
|
||||||
|
def test_create_with_trust_failed(self, mock_openstack_client_class,
|
||||||
|
mock_create_stack,
|
||||||
|
mock_cert_manager,
|
||||||
|
mock_trust_manager):
|
||||||
|
e = exception.TrusteeOrTrustToBayFailed(bay_uuid='uuid')
|
||||||
|
mock_trust_manager.create_trustee_and_trust.side_effect = e
|
||||||
|
|
||||||
|
self._test_create_failed(
|
||||||
|
mock_openstack_client_class,
|
||||||
|
mock_cert_manager,
|
||||||
|
mock_trust_manager,
|
||||||
|
exception.TrusteeOrTrustToBayFailed,
|
||||||
|
False
|
||||||
|
)
|
||||||
|
|
||||||
@patch('magnum.conductor.handlers.bay_conductor.trust_manager')
|
@patch('magnum.conductor.handlers.bay_conductor.trust_manager')
|
||||||
@patch('magnum.conductor.handlers.bay_conductor.cert_manager')
|
@patch('magnum.conductor.handlers.bay_conductor.cert_manager')
|
||||||
@ -225,9 +287,6 @@ class TestHandler(db_base.DbTestCase):
|
|||||||
mock_create_stack,
|
mock_create_stack,
|
||||||
mock_cert_manager,
|
mock_cert_manager,
|
||||||
mock_trust_manager):
|
mock_trust_manager):
|
||||||
timeout = 15
|
|
||||||
osc = mock.MagicMock()
|
|
||||||
mock_openstack_client_class.return_value = osc
|
|
||||||
test_uuid = uuid.uuid4()
|
test_uuid = uuid.uuid4()
|
||||||
mock_uuid.uuid4.return_value = test_uuid
|
mock_uuid.uuid4.return_value = test_uuid
|
||||||
error_message = six.u("""Invalid stack name 测试集群-zoyh253geukk
|
error_message = six.u("""Invalid stack name 测试集群-zoyh253geukk
|
||||||
@ -235,13 +294,12 @@ class TestHandler(db_base.DbTestCase):
|
|||||||
characters, must start with alpha""")
|
characters, must start with alpha""")
|
||||||
mock_create_stack.side_effect = exc.HTTPBadRequest(error_message)
|
mock_create_stack.side_effect = exc.HTTPBadRequest(error_message)
|
||||||
|
|
||||||
self.assertRaises(exception.InvalidParameterValue,
|
self._test_create_failed(
|
||||||
self.handler.bay_create, self.context,
|
mock_openstack_client_class,
|
||||||
self.bay, timeout)
|
mock_cert_manager,
|
||||||
mock_cert_manager.generate_certificates_to_bay.assert_called_once_with(
|
mock_trust_manager,
|
||||||
self.bay)
|
exception.InvalidParameterValue
|
||||||
mock_trust_manager.create_trustee_and_trust.assert_called_once_with(
|
)
|
||||||
osc, self.bay)
|
|
||||||
|
|
||||||
@patch('magnum.common.clients.OpenStackClients')
|
@patch('magnum.common.clients.OpenStackClients')
|
||||||
def test_bay_delete(self, mock_openstack_client_class):
|
def test_bay_delete(self, mock_openstack_client_class):
|
||||||
|
Loading…
Reference in New Issue
Block a user