Initial connect up retry task submit and re-enqueue
This CR adds the remaining pieces need to allow worker task processing to add tasks needing retries to the order retry tasks table, and then to have the periodic task service pick these retry tasks up and enqueue them for retries. With this initial CR no attempt is made to protect against concurrency between the existing worker RPC process and the separate periodic retry scheduler process. A subsequent CR will add concurrency protection. This CR does allow the retry behavior to be demonstrated locally as follows: 1) run the 'barbican.sh start', then 2) run the new barbican-worker-retry-scheduler.py script, then 3) POST to the orders resource a 'certificate' type order, and finally poll this new order until it becomes ACTIVE. The simple certificate plugin will call for a retry for the status check method after the initial certificate request is made. The retry processing will eventually call the plugins status check method, which then produces a fake certificate. Change-Id: Idee08abcd3bf2920039f91a7f5b6125eacd1f785
This commit is contained in:
parent
edb3c6d7b1
commit
eb4b711679
@ -21,6 +21,9 @@ from barbican.plugin.interface import certificate_manager as cert
|
||||
LOG = utils.getLogger(__name__)
|
||||
|
||||
|
||||
MSEC_UNTIL_CHECK_STATUS = 5000
|
||||
|
||||
|
||||
class SimpleCertificatePlugin(cert.CertificatePluginBase):
|
||||
"""Simple/default certificate plugin."""
|
||||
|
||||
@ -49,7 +52,9 @@ class SimpleCertificatePlugin(cert.CertificatePluginBase):
|
||||
:rtype: :class:`ResultDTO`
|
||||
"""
|
||||
LOG.info(u._LI('Invoking issue_certificate_request()'))
|
||||
return cert.ResultDTO(cert.CertificateStatus.WAITING_FOR_CA)
|
||||
return cert.ResultDTO(
|
||||
cert.CertificateStatus.WAITING_FOR_CA,
|
||||
retry_msec=MSEC_UNTIL_CHECK_STATUS)
|
||||
|
||||
def modify_certificate_request(self, order_id, order_meta, plugin_meta,
|
||||
barbican_meta_dto):
|
||||
@ -103,7 +108,7 @@ class SimpleCertificatePlugin(cert.CertificatePluginBase):
|
||||
:rtype: :class:`ResultDTO`
|
||||
"""
|
||||
LOG.info(u._LI('Invoking check_certificate_status()'))
|
||||
return cert.ResultDTO(cert.CertificateStatus.WAITING_FOR_CA)
|
||||
return cert.ResultDTO(cert.CertificateStatus.CERTIFICATE_GENERATED)
|
||||
|
||||
def supports(self, certificate_spec):
|
||||
"""Indicates whether the plugin supports the certificate type.
|
||||
|
@ -51,6 +51,12 @@ class TaskClient(object):
|
||||
project_id=project_id,
|
||||
updated_meta=updated_meta)
|
||||
|
||||
def check_certificate_status(self, order_id, project_id):
|
||||
"""Check the status of a certificate order."""
|
||||
self._cast('check_certificate_status',
|
||||
order_id=order_id,
|
||||
project_id=project_id)
|
||||
|
||||
def _cast(self, name, **kwargs):
|
||||
"""Asynchronous call handler. Barbican probably only needs casts.
|
||||
|
||||
|
@ -16,10 +16,14 @@
|
||||
"""
|
||||
Retry/scheduler classes and logic.
|
||||
"""
|
||||
import datetime
|
||||
import random
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
from barbican.common import utils
|
||||
from barbican import i18n as u
|
||||
from barbican.model import models
|
||||
from barbican.model import repositories
|
||||
from barbican.openstack.common import periodic_task
|
||||
from barbican.openstack.common import service
|
||||
@ -32,10 +36,10 @@ retry_opt_group = cfg.OptGroup(name='retry_scheduler',
|
||||
|
||||
retry_opts = [
|
||||
cfg.FloatOpt(
|
||||
'task_retry_tg_initial_delay', default=10.0,
|
||||
'initial_delay_seconds', default=10.0,
|
||||
help=u._('Seconds (float) to wait before starting retry scheduler')),
|
||||
cfg.FloatOpt(
|
||||
'task_retry_tg_periodic_interval_max', default=10.0,
|
||||
'periodic_interval_max_seconds', default=10.0,
|
||||
help=u._('Seconds (float) to wait between periodic schedule events')),
|
||||
]
|
||||
|
||||
@ -44,6 +48,15 @@ CONF.register_group(retry_opt_group)
|
||||
CONF.register_opts(retry_opts, group=retry_opt_group)
|
||||
|
||||
|
||||
def _compute_next_periodic_interval():
|
||||
periodic_interval = (
|
||||
CONF.retry_scheduler.periodic_interval_max_seconds
|
||||
)
|
||||
|
||||
# Return +- 20% of interval.
|
||||
return random.uniform(0.8 * periodic_interval, 1.2 * periodic_interval)
|
||||
|
||||
|
||||
class PeriodicServer(service.Service):
|
||||
"""Server to process retry and scheduled tasks.
|
||||
|
||||
@ -64,13 +77,15 @@ class PeriodicServer(service.Service):
|
||||
|
||||
# Start the task retry periodic scheduler process up.
|
||||
periodic_interval = (
|
||||
CONF.retry_scheduler.task_retry_tg_periodic_interval_max
|
||||
CONF.retry_scheduler.periodic_interval_max_seconds
|
||||
)
|
||||
self.tg.add_dynamic_timer(
|
||||
self._check_retry_tasks,
|
||||
initial_delay=CONF.retry_scheduler.task_retry_tg_initial_delay,
|
||||
initial_delay=CONF.retry_scheduler.initial_delay_seconds,
|
||||
periodic_interval_max=periodic_interval)
|
||||
|
||||
self.order_retry_repo = repositories.get_order_retry_tasks_repository()
|
||||
|
||||
def start(self):
|
||||
LOG.info("Starting the PeriodicServer")
|
||||
super(PeriodicServer, self).start()
|
||||
@ -81,9 +96,68 @@ class PeriodicServer(service.Service):
|
||||
|
||||
@periodic_task.periodic_task
|
||||
def _check_retry_tasks(self):
|
||||
"""Periodically check to see if tasks need to be scheduled."""
|
||||
LOG.debug("Processing scheduled retry tasks")
|
||||
"""Periodically check to see if tasks need to be scheduled.
|
||||
|
||||
# Return the next delay before this method is invoked again
|
||||
# TODO(john-wood-w) A future CR will fill in the blanks here.
|
||||
return 60.0
|
||||
:return: Return the number of seconds to wait before invoking this
|
||||
method again.
|
||||
"""
|
||||
LOG.info(u._LI("Processing scheduled retry tasks:"))
|
||||
|
||||
# Retrieve tasks to retry.
|
||||
entities, _, _, total = self.order_retry_repo.get_by_create_date(
|
||||
only_at_or_before_this_date=datetime.datetime.utcnow(),
|
||||
suppress_exception=True)
|
||||
|
||||
# Create RPC tasks for each retry task found.
|
||||
if total > 0:
|
||||
for task in entities:
|
||||
self._enqueue_task(task)
|
||||
|
||||
# Return the next delay before this method is invoked again.
|
||||
check_again_in_seconds = _compute_next_periodic_interval()
|
||||
LOG.info(
|
||||
u._LI("Done processing '%(total)s' tasks, will check again in "
|
||||
"'%(next)s' seconds."),
|
||||
{
|
||||
'total': total,
|
||||
'next': check_again_in_seconds
|
||||
}
|
||||
)
|
||||
return check_again_in_seconds
|
||||
|
||||
def _enqueue_task(self, task):
|
||||
retry_task_name = 'N/A'
|
||||
retry_args = 'N/A'
|
||||
retry_kwargs = 'N/A'
|
||||
try:
|
||||
# Invoke queue client to place retried RPC task on queue.
|
||||
retry_task_name = task.retry_task
|
||||
retry_args = task.retry_args
|
||||
retry_kwargs = task.retry_kwargs
|
||||
retry_method = getattr(self.queue, retry_task_name)
|
||||
retry_method(*retry_args, **retry_kwargs)
|
||||
|
||||
# Remove the retry record from the queue.
|
||||
task.status = models.States.ACTIVE
|
||||
self.order_retry_repo.delete_entity_by_id(task.id, None)
|
||||
|
||||
repositories.commit()
|
||||
|
||||
LOG.debug(
|
||||
"(Enqueued method '{0}' with args '{1}' and "
|
||||
"kwargs '{2}')".format(
|
||||
retry_task_name, retry_args, retry_kwargs))
|
||||
except Exception:
|
||||
LOG.exception(
|
||||
u._LE(
|
||||
"Problem enqueuing method '%(name)s' with args '%(args)s' "
|
||||
"and kwargs '%(kwargs)s'."),
|
||||
{
|
||||
'name': retry_task_name,
|
||||
'args': retry_args,
|
||||
'kwargs': retry_kwargs
|
||||
}
|
||||
)
|
||||
repositories.rollback()
|
||||
finally:
|
||||
repositories.clear()
|
||||
|
@ -134,7 +134,7 @@ def monitored(fn): # pragma: no cover
|
||||
|
||||
|
||||
def schedule_order_retry_tasks(
|
||||
invoked_task, retry_result, order_id, *args, **kwargs):
|
||||
invoked_task, retry_result, context, *args, **kwargs):
|
||||
"""Schedules an Order-related task for retry.
|
||||
|
||||
:param invoked_task: The RPC method that was just invoked.
|
||||
@ -142,6 +142,7 @@ def schedule_order_retry_tasks(
|
||||
processing (such as retrying this or another task) is
|
||||
required, otherwise None indicates no such follow-on
|
||||
processing is required.
|
||||
:param context: Queue context, not used.
|
||||
:param order_id: ID of the Order entity the task to retry is for.
|
||||
:param args: List of arguments passed in to the just-invoked task.
|
||||
:param kwargs: Dict of arguments passed in to the just-invoked task.
|
||||
@ -150,6 +151,7 @@ def schedule_order_retry_tasks(
|
||||
"""
|
||||
|
||||
retry_rpc_method = None
|
||||
order_id = kwargs.get('order_id')
|
||||
|
||||
if not retry_result or not order_id:
|
||||
pass
|
||||
@ -166,7 +168,7 @@ def schedule_order_retry_tasks(
|
||||
LOG.debug(
|
||||
'Scheduling RPC method for retry: {0}'.format(retry_rpc_method))
|
||||
|
||||
date_to_retry_at = datetime.datetime.now() + datetime.timedelta(
|
||||
date_to_retry_at = datetime.datetime.utcnow() + datetime.timedelta(
|
||||
milliseconds=retry_result.retry_msec)
|
||||
|
||||
retry_model = models.OrderRetryTask()
|
||||
@ -221,6 +223,19 @@ class Tasks(object):
|
||||
return resources.UpdateOrder().process(
|
||||
order_id, project_id, updated_meta)
|
||||
|
||||
@monitored
|
||||
@transactional
|
||||
@retryable_order
|
||||
def check_certificate_status(self, context, order_id, project_id):
|
||||
"""Check the status of a certificate order."""
|
||||
LOG.info(
|
||||
u._LI("Processing check certificate status on order: order ID is "
|
||||
"'%s'"),
|
||||
order_id
|
||||
)
|
||||
return resources.CheckCertificateStatusOrder().process(
|
||||
order_id, project_id)
|
||||
|
||||
|
||||
class TaskServer(Tasks, service.Service):
|
||||
"""Server to process asynchronous tasking from Barbican API nodes.
|
||||
|
@ -23,6 +23,7 @@ from barbican.model import models
|
||||
from barbican.model import repositories as repos
|
||||
from barbican.plugin.interface import certificate_manager as cert
|
||||
from barbican.plugin import resources as plugin
|
||||
from barbican.tasks import common
|
||||
|
||||
LOG = utils.getLogger(__name__)
|
||||
|
||||
@ -64,128 +65,154 @@ ORDER_STATUS_CA_UNAVAIL_FOR_CHECK = models.OrderStatus(
|
||||
)
|
||||
|
||||
|
||||
def issue_certificate_request(order_model, project_model):
|
||||
def issue_certificate_request(order_model, project_model, result_follow_on):
|
||||
"""Create the initial order with CA.
|
||||
|
||||
Note that this method may be called more than once if retries are
|
||||
required. Barbican metadata is used to store intermediate information,
|
||||
including selected plugins by name, to support such retries.
|
||||
|
||||
:param: order_model - order associated with this cert request
|
||||
:param: project_model - project associated with this request
|
||||
:param: result_follow_on - A :class:`FollowOnProcessingStatusDTO` instance
|
||||
instantiated by the client that this function may optionally update
|
||||
with information on how to process this task into the future.
|
||||
:returns: container_model - container with the relevant cert if
|
||||
the request has been completed. None otherwise
|
||||
"""
|
||||
container_model = None
|
||||
|
||||
plugin_meta = _get_plugin_meta(order_model)
|
||||
barbican_meta_dto = cert.BarbicanMetaDTO()
|
||||
barbican_meta = _get_barbican_meta(order_model)
|
||||
|
||||
# TODO(john-wood-w) We need to de-conflict barbican_meta (stored with order
|
||||
# and not shown to plugins) with barbican_meta_dto (shared with plugins).
|
||||
# As a minimum we should change the name of the DTO to something like
|
||||
# 'extended_meta_dto' or some such.
|
||||
barbican_meta_for_plugins_dto = cert.BarbicanMetaDTO()
|
||||
|
||||
# refresh the CA table. This is mostly a no-op unless the entries
|
||||
# for a plugin are expired.
|
||||
cert.CertificatePluginManager().refresh_ca_table()
|
||||
|
||||
# Locate the required certificate plugin.
|
||||
cert_plugin_name = barbican_meta.get('plugin_name')
|
||||
if cert_plugin_name:
|
||||
cert_plugin = cert.CertificatePluginManager().get_plugin_by_name(
|
||||
cert_plugin_name)
|
||||
else:
|
||||
ca_id = _get_ca_id(order_model.meta, project_model.id)
|
||||
if ca_id:
|
||||
barbican_meta_dto.plugin_ca_id = ca_id
|
||||
barbican_meta_for_plugins_dto.plugin_ca_id = ca_id
|
||||
cert_plugin = cert.CertificatePluginManager().get_plugin_by_ca_id(
|
||||
ca_id)
|
||||
else:
|
||||
cert_plugin = cert.CertificatePluginManager().get_plugin(
|
||||
order_model.meta)
|
||||
barbican_meta['plugin_name'] = utils.generate_fullname_for(cert_plugin)
|
||||
|
||||
# Generate CSR if needed.
|
||||
request_type = order_model.meta.get(cert.REQUEST_TYPE)
|
||||
if request_type == cert.CertificateRequestType.STORED_KEY_REQUEST:
|
||||
csr = order_model.order_barbican_metadata.get('generated_csr')
|
||||
csr = barbican_meta.get('generated_csr')
|
||||
if csr is None:
|
||||
csr = _generate_csr(order_model)
|
||||
order_model.order_barbican_metadata['generated_csr'] = csr
|
||||
order_model.save()
|
||||
barbican_meta_dto.generated_csr = csr
|
||||
barbican_meta['generated_csr'] = csr
|
||||
barbican_meta_for_plugins_dto.generated_csr = csr
|
||||
|
||||
result = cert_plugin.issue_certificate_request(order_model.id,
|
||||
order_model.meta,
|
||||
plugin_meta,
|
||||
barbican_meta_dto)
|
||||
result = cert_plugin.issue_certificate_request(
|
||||
order_model.id, order_model.meta,
|
||||
plugin_meta, barbican_meta_for_plugins_dto)
|
||||
|
||||
# Save plugin order plugin state
|
||||
# Save plugin and barbican metadata for this order.
|
||||
_save_plugin_metadata(order_model, plugin_meta)
|
||||
_save_barbican_metadata(order_model, barbican_meta)
|
||||
|
||||
# Handle result
|
||||
if cert.CertificateStatus.WAITING_FOR_CA == result.status:
|
||||
# TODO(alee-3): Add code to set sub status of "waiting for CA"
|
||||
_update_order_status(ORDER_STATUS_REQUEST_PENDING)
|
||||
_schedule_check_cert_request(cert_plugin, order_model, plugin_meta,
|
||||
result, project_model, cert.RETRY_MSEC)
|
||||
_update_result_follow_on(
|
||||
result_follow_on,
|
||||
order_status=ORDER_STATUS_REQUEST_PENDING,
|
||||
retry_task=common.RetryTasks.INVOKE_CERT_STATUS_CHECK_TASK,
|
||||
retry_msec=result.retry_msec)
|
||||
elif cert.CertificateStatus.CERTIFICATE_GENERATED == result.status:
|
||||
_update_order_status(ORDER_STATUS_CERT_GENERATED)
|
||||
_update_result_follow_on(
|
||||
result_follow_on,
|
||||
order_status=ORDER_STATUS_CERT_GENERATED)
|
||||
container_model = _save_secrets(result, project_model)
|
||||
elif cert.CertificateStatus.CLIENT_DATA_ISSUE_SEEN == result.status:
|
||||
_update_order_status(ORDER_STATUS_DATA_INVALID)
|
||||
raise cert.CertificateStatusClientDataIssue(result.status_message)
|
||||
elif cert.CertificateStatus.CA_UNAVAILABLE_FOR_REQUEST == result.status:
|
||||
# TODO(alee-3): set retry counter and error out if retries are exceeded
|
||||
_update_order_status(ORDER_STATUS_CA_UNAVAIL_FOR_ISSUE)
|
||||
|
||||
_schedule_issue_cert_request(cert_plugin, order_model, plugin_meta,
|
||||
result, project_model,
|
||||
cert.ERROR_RETRY_MSEC)
|
||||
_update_result_follow_on(
|
||||
result_follow_on,
|
||||
order_status=ORDER_STATUS_CA_UNAVAIL_FOR_ISSUE,
|
||||
retry_task=common.RetryTasks.INVOKE_SAME_TASK,
|
||||
retry_msec=cert.ERROR_RETRY_MSEC)
|
||||
_notify_ca_unavailable(order_model, result)
|
||||
elif cert.CertificateStatus.INVALID_OPERATION == result.status:
|
||||
_update_order_status(ORDER_STATUS_INVALID_OPERATION)
|
||||
|
||||
raise cert.CertificateStatusInvalidOperation(result.status_message)
|
||||
else:
|
||||
_update_order_status(ORDER_STATUS_INTERNAL_ERROR)
|
||||
raise cert.CertificateStatusNotSupported(result.status)
|
||||
|
||||
return container_model
|
||||
|
||||
|
||||
def check_certificate_request(order_model, project_model, plugin_name):
|
||||
def check_certificate_request(order_model, project_model, result_follow_on):
|
||||
"""Check the status of a certificate request with the CA.
|
||||
|
||||
Note that this method may be called more than once if retries are
|
||||
required. Barbican metadata is used to store intermediate information,
|
||||
including selected plugins by name, to support such retries.
|
||||
|
||||
:param: order_model - order associated with this cert request
|
||||
:param: project_model - project associated with this request
|
||||
:param: plugin_name - plugin the issued the certificate request
|
||||
:param: result_follow_on - A :class:`FollowOnProcessingStatusDTO` instance
|
||||
instantiated by the client that this function may optionally update
|
||||
with information on how to process this task into the future.
|
||||
:returns: container_model - container with the relevant cert if the
|
||||
request has been completed. None otherwise.
|
||||
"""
|
||||
container_model = None
|
||||
plugin_meta = _get_plugin_meta(order_model)
|
||||
barbican_meta_dto = cert.BarbicanMetaDTO()
|
||||
barbican_meta = _get_barbican_meta(order_model)
|
||||
|
||||
# TODO(john-wood-w) See note above about DTO's name.
|
||||
barbican_meta_for_plugins_dto = cert.BarbicanMetaDTO()
|
||||
|
||||
cert_plugin = cert.CertificatePluginManager().get_plugin_by_name(
|
||||
plugin_name)
|
||||
barbican_meta.get('plugin_name'))
|
||||
|
||||
result = cert_plugin.check_certificate_request(order_model.id,
|
||||
order_model.meta,
|
||||
plugin_meta,
|
||||
barbican_meta_dto)
|
||||
result = cert_plugin.check_certificate_status(
|
||||
order_model.id, order_model.meta,
|
||||
plugin_meta, barbican_meta_for_plugins_dto)
|
||||
|
||||
# Save plugin order plugin state
|
||||
_save_plugin_metadata(order_model, plugin_meta)
|
||||
|
||||
# Handle result
|
||||
if cert.CertificateStatus.WAITING_FOR_CA == result.status:
|
||||
_update_order_status(ORDER_STATUS_REQUEST_PENDING)
|
||||
_schedule_check_cert_request(cert_plugin, order_model, plugin_meta,
|
||||
result, project_model,
|
||||
cert.RETRY_MSEC)
|
||||
_update_result_follow_on(
|
||||
result_follow_on,
|
||||
order_status=ORDER_STATUS_REQUEST_PENDING,
|
||||
retry_task=common.RetryTasks.INVOKE_CERT_STATUS_CHECK_TASK,
|
||||
retry_msec=result.retry_msec)
|
||||
elif cert.CertificateStatus.CERTIFICATE_GENERATED == result.status:
|
||||
_update_order_status(ORDER_STATUS_CERT_GENERATED)
|
||||
_update_result_follow_on(
|
||||
result_follow_on,
|
||||
order_status=ORDER_STATUS_CERT_GENERATED)
|
||||
container_model = _save_secrets(result, project_model)
|
||||
elif cert.CertificateStatus.CLIENT_DATA_ISSUE_SEEN == result.status:
|
||||
_update_order_status(cert.ORDER_STATUS_DATA_INVALID)
|
||||
raise cert.CertificateStatusClientDataIssue(result.status_message)
|
||||
elif cert.CertificateStatus.CA_UNAVAILABLE_FOR_REQUEST == result.status:
|
||||
# TODO(alee-3): decide what to do about retries here
|
||||
_update_order_status(ORDER_STATUS_CA_UNAVAIL_FOR_CHECK)
|
||||
_schedule_check_cert_request(cert_plugin, order_model, plugin_meta,
|
||||
result, project_model,
|
||||
cert.ERROR_RETRY_MSEC)
|
||||
|
||||
_update_result_follow_on(
|
||||
result_follow_on,
|
||||
order_status=ORDER_STATUS_CA_UNAVAIL_FOR_CHECK,
|
||||
retry_task=common.RetryTasks.INVOKE_SAME_TASK,
|
||||
retry_msec=cert.ERROR_RETRY_MSEC)
|
||||
_notify_ca_unavailable(order_model, result)
|
||||
elif cert.CertificateStatus.INVALID_OPERATION == result.status:
|
||||
_update_order_status(ORDER_STATUS_INVALID_OPERATION)
|
||||
raise cert.CertificateStatusInvalidOperation(result.status_message)
|
||||
else:
|
||||
_update_order_status(ORDER_STATUS_INTERNAL_ERROR)
|
||||
raise cert.CertificateStatusNotSupported(result.status)
|
||||
|
||||
return container_model
|
||||
@ -216,57 +243,17 @@ def _get_ca_id(order_meta, project_id):
|
||||
return None
|
||||
|
||||
|
||||
def _schedule_cert_retry_task(cert_result_dto, cert_plugin, order_model,
|
||||
plugin_meta,
|
||||
retry_method=None,
|
||||
retry_object=None,
|
||||
retry_time=None,
|
||||
retry_args=None):
|
||||
if cert_result_dto.retry_msec > 0:
|
||||
retry_time = cert_result_dto.retry_msec
|
||||
|
||||
if cert_result_dto.retry_method:
|
||||
retry_method = cert_result_dto.retry_method
|
||||
retry_object = utils.generate_fullname_for(cert_plugin)
|
||||
retry_args = [order_model.id, order_model.meta, plugin_meta]
|
||||
|
||||
_schedule_retry_task(retry_object, retry_method, retry_time, retry_args)
|
||||
|
||||
|
||||
def _schedule_issue_cert_request(cert_plugin, order_model, plugin_meta,
|
||||
cert_result_dto, project_model, retry_time):
|
||||
retry_args = [order_model,
|
||||
project_model]
|
||||
_schedule_cert_retry_task(
|
||||
cert_result_dto, cert_plugin, order_model, plugin_meta,
|
||||
retry_method="issue_certificate_request",
|
||||
retry_object="barbican.tasks.certificate_resources",
|
||||
retry_time=retry_time,
|
||||
retry_args=retry_args)
|
||||
|
||||
|
||||
def _schedule_check_cert_request(cert_plugin, order_model, plugin_meta,
|
||||
cert_result_dto, project_model, retry_time):
|
||||
retry_args = [order_model,
|
||||
project_model,
|
||||
utils.generate_fullname_for(cert_plugin)]
|
||||
_schedule_cert_retry_task(
|
||||
cert_result_dto, cert_plugin, order_model, plugin_meta,
|
||||
retry_method="check_certificate_request",
|
||||
retry_object="barbican.tasks.certificate_resources",
|
||||
retry_time=retry_time,
|
||||
retry_args=retry_args)
|
||||
|
||||
|
||||
def _update_order_status(order_status):
|
||||
# TODO(alee-3): add code to set order substatus, substatus message
|
||||
# and save the order. most likely this call methods defined in Order.
|
||||
pass
|
||||
|
||||
|
||||
def _schedule_retry_task(retry_object, retry_method, retry_time, args):
|
||||
# TODO(alee-3): Implement this method - here or elsewhere .
|
||||
pass
|
||||
def _update_result_follow_on(
|
||||
result_follow_on,
|
||||
order_status=None,
|
||||
retry_task=common.RetryTasks.NO_ACTION_REQUIRED,
|
||||
retry_msec=common.RETRY_MSEC_DEFAULT):
|
||||
if order_status:
|
||||
result_follow_on.status = order_status.id
|
||||
result_follow_on.status_message = order_status.message
|
||||
result_follow_on.retry_task = retry_task
|
||||
if retry_msec and retry_msec >= 0:
|
||||
result_follow_on.retry_msec = retry_msec
|
||||
|
||||
|
||||
def _get_plugin_meta(order_model):
|
||||
@ -277,6 +264,14 @@ def _get_plugin_meta(order_model):
|
||||
return {}
|
||||
|
||||
|
||||
def _get_barbican_meta(order_model):
|
||||
if order_model:
|
||||
order_barbican_meta_repo = repos.get_order_barbican_meta_repository()
|
||||
return order_barbican_meta_repo.get_metadata_for_order(order_model.id)
|
||||
else:
|
||||
return {}
|
||||
|
||||
|
||||
def _generate_csr(order_model):
|
||||
"""Generate a CSR from the public key.
|
||||
|
||||
@ -355,6 +350,16 @@ def _save_plugin_metadata(order_model, plugin_meta):
|
||||
order_plugin_meta_repo.save(plugin_meta, order_model)
|
||||
|
||||
|
||||
def _save_barbican_metadata(order_model, barbican_meta):
|
||||
"""Add barbican metadata to an order."""
|
||||
|
||||
if not isinstance(barbican_meta, dict):
|
||||
barbican_meta = {}
|
||||
|
||||
order_barbican_meta_repo = repos.get_order_barbican_meta_repository()
|
||||
order_barbican_meta_repo.save(barbican_meta, order_model)
|
||||
|
||||
|
||||
def _save_secrets(result, project_model):
|
||||
cert_secret_model, transport_key_model = plugin.store_secret(
|
||||
unencrypted_raw=result.certificate,
|
||||
|
@ -27,6 +27,7 @@ from barbican.model import models
|
||||
from barbican.model import repositories as rep
|
||||
from barbican.plugin import resources as plugin
|
||||
from barbican.tasks import certificate_resources as cert
|
||||
from barbican.tasks import common
|
||||
|
||||
|
||||
LOG = utils.getLogger(__name__)
|
||||
@ -221,7 +222,7 @@ class BeginTypeOrder(BaseTask):
|
||||
return self.helper.retrieve_entity(*args, **kwargs)
|
||||
|
||||
def handle_processing(self, order, *args, **kwargs):
|
||||
self.handle_order(order)
|
||||
return self.handle_order(order)
|
||||
|
||||
def handle_order(self, order):
|
||||
"""Handle secret creation using meta info.
|
||||
@ -234,7 +235,12 @@ class BeginTypeOrder(BaseTask):
|
||||
if type is certificate
|
||||
TBD
|
||||
:param order: Order to process.
|
||||
:return: None if no follow on processing is needed for this task,
|
||||
otherwise a :class:`FollowOnProcessingStatusDTO` instance
|
||||
with information on how to process this task into the future.
|
||||
"""
|
||||
result_follow_on = common.FollowOnProcessingStatusDTO()
|
||||
|
||||
order_info = order.to_dict_fields()
|
||||
order_type = order_info.get('type')
|
||||
meta_info = order_info.get('meta')
|
||||
@ -263,7 +269,8 @@ class BeginTypeOrder(BaseTask):
|
||||
LOG.debug("...done creating asymmetric order's secret.")
|
||||
elif order_type == models.OrderType.CERTIFICATE:
|
||||
# Request a certificate
|
||||
new_container = cert.issue_certificate_request(order, project)
|
||||
new_container = cert.issue_certificate_request(
|
||||
order, project, result_follow_on)
|
||||
if new_container:
|
||||
order.container_id = new_container.id
|
||||
LOG.debug("...done requesting a certificate.")
|
||||
@ -272,6 +279,8 @@ class BeginTypeOrder(BaseTask):
|
||||
u._('Order type "{order_type}" not implemented.').format(
|
||||
order_type=order_type))
|
||||
|
||||
return result_follow_on
|
||||
|
||||
def handle_error(self, order, status, message, exception,
|
||||
*args, **kwargs):
|
||||
self.helper.handle_error(
|
||||
@ -326,3 +335,60 @@ class UpdateOrder(BaseTask):
|
||||
def handle_success(self, order, result, *args, **kwargs):
|
||||
self.helper.handle_success(
|
||||
order, result, *args, **kwargs)
|
||||
|
||||
|
||||
class CheckCertificateStatusOrder(BaseTask):
|
||||
"""Handles checking the status of a certificate order."""
|
||||
|
||||
def get_name(self):
|
||||
return u._('Check Certificate Order Status')
|
||||
|
||||
def __init__(self):
|
||||
LOG.debug('Creating CheckCertificateStatusOrder task processor')
|
||||
self.project_repo = rep.get_project_repository()
|
||||
self.helper = _OrderTaskHelper()
|
||||
|
||||
def retrieve_entity(self, *args, **kwargs):
|
||||
return self.helper.retrieve_entity(*args, **kwargs)
|
||||
|
||||
def handle_processing(self, order, *args, **kwargs):
|
||||
return self.handle_order(order)
|
||||
|
||||
def handle_order(self, order):
|
||||
"""Handle checking the status of a certificate order.
|
||||
|
||||
:param order: Order to process.
|
||||
:return: None if no follow on processing is needed for this task,
|
||||
otherwise a :class:`FollowOnProcessingStatusDTO` instance
|
||||
with information on how to process this task into the future.
|
||||
"""
|
||||
result_follow_on = common.FollowOnProcessingStatusDTO()
|
||||
|
||||
order_info = order.to_dict_fields()
|
||||
order_type = order_info.get('type')
|
||||
|
||||
# Retrieve the project.
|
||||
project = self.project_repo.get(order.project_id)
|
||||
|
||||
if order_type != models.OrderType.CERTIFICATE:
|
||||
raise NotImplementedError(
|
||||
u._('Order type "{order_type}" not supported.').format(
|
||||
order_type=order_type))
|
||||
|
||||
# Request a certificate
|
||||
new_container = cert.check_certificate_request(
|
||||
order, project, result_follow_on)
|
||||
if new_container:
|
||||
order.container_id = new_container.id
|
||||
LOG.debug("...done checking status of a certificate order.")
|
||||
|
||||
return result_follow_on
|
||||
|
||||
def handle_error(self, order, status, message, exception,
|
||||
*args, **kwargs):
|
||||
self.helper.handle_error(
|
||||
order, status, message, exception, *args, **kwargs)
|
||||
|
||||
def handle_success(self, order, result, *args, **kwargs):
|
||||
self.helper.handle_success(
|
||||
order, result, *args, **kwargs)
|
||||
|
@ -53,7 +53,10 @@ def create_project(external_id="my keystone id", session=None):
|
||||
return project
|
||||
|
||||
|
||||
def create_order(project, session=None):
|
||||
def create_order(project=None, session=None):
|
||||
if not project:
|
||||
project = create_project(session=session)
|
||||
|
||||
order = models.Order()
|
||||
order.project_id = project.id
|
||||
order_repo = repositories.get_order_repository()
|
||||
|
@ -28,7 +28,7 @@ class WhenTestingOrderRetryTaskRepository(database_utils.RepositoryTestCase):
|
||||
def setUp(self):
|
||||
super(WhenTestingOrderRetryTaskRepository, self).setUp()
|
||||
|
||||
self.date_time_now = datetime.datetime.now()
|
||||
self.date_time_now = datetime.datetime.utcnow()
|
||||
self.test_args = ['test', 'args']
|
||||
self.test_kwargs = {'test': 1, 'kwargs': 2}
|
||||
|
||||
@ -79,7 +79,7 @@ class WhenTestingOrderRetryTaskRepository(database_utils.RepositoryTestCase):
|
||||
|
||||
# Now, a retrieve by the current time should return our entry.
|
||||
entities, offset, limit, total = self.repo.get_by_create_date(
|
||||
only_at_or_before_this_date=datetime.datetime.now(),
|
||||
only_at_or_before_this_date=datetime.datetime.utcnow(),
|
||||
session=session,
|
||||
suppress_exception=True
|
||||
)
|
||||
|
@ -31,7 +31,8 @@ class WhenTestingSimpleCertificateManagerPlugin(testtools.TestCase):
|
||||
def test_check_certificate_status(self):
|
||||
result = self.plugin.check_certificate_status(None, None, None, None)
|
||||
|
||||
self.assertEqual(cm.CertificateStatus.WAITING_FOR_CA, result.status)
|
||||
self.assertEqual(
|
||||
cm.CertificateStatus.CERTIFICATE_GENERATED, result.status)
|
||||
|
||||
def test_modify_certificate_request(self):
|
||||
result = self.plugin.modify_certificate_request(None, None, None, None)
|
||||
|
@ -25,17 +25,27 @@ class WhenUsingAsyncTaskClient(utils.BaseTestCase):
|
||||
def setUp(self):
|
||||
super(WhenUsingAsyncTaskClient, self).setUp()
|
||||
|
||||
# Mock out the queue get_client() call:
|
||||
self.mock_client = mock.MagicMock()
|
||||
self.mock_client.cast.return_value = None
|
||||
|
||||
queue.get_client = mock.MagicMock(return_value=self.mock_client)
|
||||
get_client_config = {
|
||||
'return_value': self.mock_client
|
||||
}
|
||||
self.get_client_patcher = mock.patch(
|
||||
'barbican.queue.get_client',
|
||||
**get_client_config
|
||||
)
|
||||
self.get_client_patcher.start()
|
||||
|
||||
self.client = client.TaskClient()
|
||||
|
||||
def tearDown(self):
|
||||
super(WhenUsingAsyncTaskClient, self).tearDown()
|
||||
self.get_client_patcher.stop()
|
||||
|
||||
def test_should_process_type_order(self):
|
||||
self.client.process_type_order(order_id=self.order_id,
|
||||
project_id=self.external_project_id)
|
||||
queue.get_client.assert_called_with()
|
||||
self.mock_client.cast.assert_called_with(
|
||||
{}, 'process_type_order', order_id=self.order_id,
|
||||
project_id=self.external_project_id)
|
||||
@ -45,11 +55,18 @@ class WhenUsingAsyncTaskClient(utils.BaseTestCase):
|
||||
self.client.update_order(order_id=self.order_id,
|
||||
project_id=self.external_project_id,
|
||||
updated_meta=updated_meta)
|
||||
queue.get_client.assert_called_with()
|
||||
self.mock_client.cast.assert_called_with(
|
||||
{}, 'update_order', order_id=self.order_id,
|
||||
project_id=self.external_project_id, updated_meta=updated_meta)
|
||||
|
||||
def test_should_check_certificate_order(self):
|
||||
self.client.check_certificate_status(
|
||||
order_id=self.order_id,
|
||||
project_id=self.external_project_id)
|
||||
self.mock_client.cast.assert_called_with(
|
||||
{}, 'check_certificate_status',
|
||||
order_id=self.order_id, project_id=self.external_project_id)
|
||||
|
||||
|
||||
class WhenCreatingDirectTaskClient(utils.BaseTestCase):
|
||||
"""Test using the synchronous task client (i.e. standalone mode)."""
|
||||
|
@ -11,13 +11,17 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import datetime
|
||||
import time
|
||||
|
||||
import eventlet
|
||||
import mock
|
||||
import oslotest.base as oslotest
|
||||
|
||||
from barbican.model import models
|
||||
from barbican.model import repositories
|
||||
from barbican.queue import retry_scheduler
|
||||
from barbican.tests import database_utils
|
||||
|
||||
# Oslo messaging RPC server uses eventlet.
|
||||
eventlet.monkey_patch()
|
||||
@ -27,7 +31,7 @@ INITIAL_DELAY_SECONDS = 5.0
|
||||
NEXT_RETRY_SECONDS = 5.0
|
||||
|
||||
|
||||
class WhenRunningPeriodicServerRetryLogic(oslotest.BaseTestCase):
|
||||
class WhenRunningPeriodicServerRetryLogic(database_utils.RepositoryTestCase):
|
||||
"""Tests the retry logic invoked by the periodic task retry server.
|
||||
|
||||
These tests are only concerned with the logic of the invoked periodic
|
||||
@ -40,27 +44,96 @@ class WhenRunningPeriodicServerRetryLogic(oslotest.BaseTestCase):
|
||||
super(WhenRunningPeriodicServerRetryLogic, self).setUp()
|
||||
|
||||
retry_scheduler.CONF.set_override(
|
||||
"task_retry_tg_initial_delay",
|
||||
"initial_delay_seconds",
|
||||
2 * INITIAL_DELAY_SECONDS,
|
||||
group='retry_scheduler')
|
||||
|
||||
self.database_patcher = _DatabasePatcherHelper()
|
||||
self.database_patcher.start()
|
||||
retry_scheduler.CONF.set_override(
|
||||
"periodic_interval_max_seconds",
|
||||
NEXT_RETRY_SECONDS,
|
||||
group='retry_scheduler')
|
||||
|
||||
self.queue_client = mock.MagicMock()
|
||||
|
||||
self.periodic_server = retry_scheduler.PeriodicServer(
|
||||
queue_resource=None)
|
||||
queue_resource=self.queue_client)
|
||||
|
||||
def tearDown(self):
|
||||
super(WhenRunningPeriodicServerRetryLogic, self).tearDown()
|
||||
self.periodic_server.stop()
|
||||
self.database_patcher.stop()
|
||||
|
||||
def test_should_perform_retry_processing(self):
|
||||
next_interval = self.periodic_server._check_retry_tasks()
|
||||
def test_should_perform_retry_processing_no_tasks(self):
|
||||
interval = self.periodic_server._check_retry_tasks()
|
||||
|
||||
# TODO(john-wood-w) Will be updated by future CR with actual retry
|
||||
# logic unit tests.
|
||||
self.assertEqual(60, next_interval)
|
||||
self.assertEqual(
|
||||
True,
|
||||
NEXT_RETRY_SECONDS * .8 <= interval < NEXT_RETRY_SECONDS * 1.2)
|
||||
|
||||
def test_should_perform_retry_processing_one_task(self):
|
||||
# Add one retry task.
|
||||
args, kwargs, retry_repo = self._create_retry_task()
|
||||
|
||||
# Retrieve this entity.
|
||||
entities, _, _, total = retry_repo.get_by_create_date()
|
||||
self.assertEqual(1, total)
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
interval = self.periodic_server._check_retry_tasks()
|
||||
|
||||
# Attempt to retrieve this entity, should have been deleted above.
|
||||
entities, _, _, total = retry_repo.get_by_create_date(
|
||||
suppress_exception=True)
|
||||
self.assertEqual(0, total)
|
||||
|
||||
self.assertEqual(
|
||||
True,
|
||||
NEXT_RETRY_SECONDS * .8 <= interval < NEXT_RETRY_SECONDS * 1.2)
|
||||
self.queue_client.test_task.assert_called_once_with(
|
||||
*args, **kwargs
|
||||
)
|
||||
|
||||
@mock.patch('barbican.model.repositories.commit')
|
||||
def test_should_fail_and_force_a_rollback(self, mock_commit):
|
||||
mock_commit.side_effect = Exception()
|
||||
|
||||
# Add one retry task.
|
||||
args, kwargs, retry_repo = self._create_retry_task()
|
||||
|
||||
# Retrieve this entity.
|
||||
entities, _, _, total = retry_repo.get_by_create_date()
|
||||
self.assertEqual(1, total)
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
self.periodic_server._check_retry_tasks()
|
||||
|
||||
# Attempt to retrieve this entity, should not have been deleted above.
|
||||
entities, _, _, total = retry_repo.get_by_create_date(
|
||||
suppress_exception=True)
|
||||
self.assertEqual(1, total)
|
||||
|
||||
def _create_retry_task(self):
|
||||
# Add one retry task:
|
||||
task = 'test_task'
|
||||
args = ('foo', 'bar')
|
||||
kwargs = {'k_foo': 1, 'k_bar': 2}
|
||||
|
||||
order = database_utils.create_order()
|
||||
|
||||
retry = models.OrderRetryTask()
|
||||
retry.order_id = order.id
|
||||
retry.retry_at = datetime.datetime.utcnow()
|
||||
retry.retry_task = task
|
||||
retry.retry_args = args
|
||||
retry.retry_kwargs = kwargs
|
||||
|
||||
retry_repo = repositories.get_order_retry_tasks_repository()
|
||||
retry_repo.create_from(retry)
|
||||
|
||||
database_utils.get_session().commit()
|
||||
|
||||
return args, kwargs, retry_repo
|
||||
|
||||
|
||||
class WhenRunningPeriodicServer(oslotest.BaseTestCase):
|
||||
@ -76,7 +149,7 @@ class WhenRunningPeriodicServer(oslotest.BaseTestCase):
|
||||
super(WhenRunningPeriodicServer, self).setUp()
|
||||
|
||||
retry_scheduler.CONF.set_override(
|
||||
"task_retry_tg_initial_delay",
|
||||
"initial_delay_seconds",
|
||||
INITIAL_DELAY_SECONDS,
|
||||
group='retry_scheduler')
|
||||
|
@ -189,9 +189,11 @@ class WhenCallingScheduleOrderRetryTasks(database_utils.RepositoryTestCase):
|
||||
self.result = common.FollowOnProcessingStatusDTO()
|
||||
|
||||
self.args = ['args-foo', 'args-bar']
|
||||
self.kwargs = {'foo': 1, 'bar': 2}
|
||||
self.date_to_retry_at = datetime.datetime.now() + datetime.timedelta(
|
||||
self.kwargs = {'order_id': self.order.id, 'foo': 1, 'bar': 2}
|
||||
self.date_to_retry_at = (
|
||||
datetime.datetime.utcnow() + datetime.timedelta(
|
||||
milliseconds=self.result.retry_msec)
|
||||
)
|
||||
|
||||
def test_should_not_schedule_task_due_to_no_result(self):
|
||||
retry_rpc_method = server.schedule_order_retry_tasks(None, None, None)
|
||||
@ -213,7 +215,7 @@ class WhenCallingScheduleOrderRetryTasks(database_utils.RepositoryTestCase):
|
||||
retry_rpc_method = server.schedule_order_retry_tasks(
|
||||
self.test_should_schedule_invoking_task_for_retry,
|
||||
self.result,
|
||||
self.order.id,
|
||||
None, # Not used.
|
||||
*self.args,
|
||||
**self.kwargs)
|
||||
database_utils.get_session().commit() # Flush to the database.
|
||||
@ -232,7 +234,7 @@ class WhenCallingScheduleOrderRetryTasks(database_utils.RepositoryTestCase):
|
||||
retry_rpc_method = server.schedule_order_retry_tasks(
|
||||
None, # Should be ignored for non-self retries.
|
||||
self.result,
|
||||
self.order.id,
|
||||
None, # Not used.
|
||||
*self.args,
|
||||
**self.kwargs)
|
||||
database_utils.get_session().commit() # Flush to the database.
|
||||
@ -262,11 +264,11 @@ class WhenCallingScheduleOrderRetryTasks(database_utils.RepositoryTestCase):
|
||||
self.assertEqual(True, delta_seconds <= 2)
|
||||
|
||||
|
||||
class WhenUsingBeginTypeOrderTask(utils.BaseTestCase):
|
||||
"""Test using the Tasks class for 'type order' task."""
|
||||
class WhenCallingTasksMethod(utils.BaseTestCase):
|
||||
"""Test calling methods on the Tasks class."""
|
||||
|
||||
def setUp(self):
|
||||
super(WhenUsingBeginTypeOrderTask, self).setUp()
|
||||
super(WhenCallingTasksMethod, self).setUp()
|
||||
|
||||
# Mock the 'am I a server process?' flag used by the decorator around
|
||||
# all task methods. Since this test class focuses on testing task
|
||||
@ -284,7 +286,7 @@ class WhenUsingBeginTypeOrderTask(utils.BaseTestCase):
|
||||
self.tasks = server.Tasks()
|
||||
|
||||
def tearDown(self):
|
||||
super(WhenUsingBeginTypeOrderTask, self).tearDown()
|
||||
super(WhenCallingTasksMethod, self).tearDown()
|
||||
self.is_server_side_patcher.stop()
|
||||
|
||||
@mock.patch('barbican.tasks.resources.BeginTypeOrder')
|
||||
@ -308,6 +310,16 @@ class WhenUsingBeginTypeOrderTask(utils.BaseTestCase):
|
||||
self.order_id, self.external_project_id, updated_meta
|
||||
)
|
||||
|
||||
@mock.patch('barbican.tasks.resources.CheckCertificateStatusOrder')
|
||||
def test_should_check_certificate_order(self, mock_check_cert_order):
|
||||
mock_check_cert_order.return_value.process.return_value = None
|
||||
|
||||
self.tasks.check_certificate_status(
|
||||
None, self.order_id, self.external_project_id)
|
||||
mock_check_cert_order.return_value.process.assert_called_with(
|
||||
self.order_id, self.external_project_id
|
||||
)
|
||||
|
||||
@mock.patch('barbican.tasks.resources.BeginTypeOrder')
|
||||
def test_process_order_catch_exception(self, mock_begin_order):
|
||||
"""Test that BeginTypeOrder's process() handles all exceptions."""
|
||||
|
@ -22,6 +22,7 @@ from barbican.common import hrefs
|
||||
from barbican.model import models
|
||||
from barbican.plugin.interface import certificate_manager as cert_man
|
||||
from barbican.tasks import certificate_resources as cert_res
|
||||
from barbican.tasks import common
|
||||
from barbican.tests import utils
|
||||
|
||||
|
||||
@ -35,6 +36,10 @@ class WhenPerformingPrivateOperations(utils.BaseTestCase,
|
||||
self.setup_order_plugin_meta_repository_mock(
|
||||
self.order_plugin_meta_repo)
|
||||
|
||||
self.order_barbican_meta_repo = mock.MagicMock()
|
||||
self.setup_order_barbican_meta_repository_mock(
|
||||
self.order_barbican_meta_repo)
|
||||
|
||||
def test_get_plugin_meta(self):
|
||||
class Value(object):
|
||||
def __init__(self, value):
|
||||
@ -80,6 +85,21 @@ class WhenPerformingPrivateOperations(utils.BaseTestCase,
|
||||
self.order_plugin_meta_repo.save.assert_called_once_with(
|
||||
{}, test_order_model)
|
||||
|
||||
def test_get_barbican_meta_with_empty_dict(self):
|
||||
result = cert_res._get_barbican_meta(None)
|
||||
|
||||
self._assert_dict_equal({}, result)
|
||||
|
||||
def test_save_barbican_w_null_meta(self):
|
||||
test_order_model = 'My order model'
|
||||
|
||||
# Test None for plugin meta data.
|
||||
cert_res._save_barbican_metadata(
|
||||
test_order_model, None)
|
||||
|
||||
self.order_barbican_meta_repo.save.assert_called_once_with(
|
||||
{}, test_order_model)
|
||||
|
||||
def _assert_dict_equal(self, expected, test):
|
||||
self.assertIsInstance(expected, dict)
|
||||
self.assertIsInstance(test, dict)
|
||||
@ -94,12 +114,12 @@ class WhenPerformingPrivateOperations(utils.BaseTestCase,
|
||||
'between the expected and test dicts')
|
||||
|
||||
|
||||
class WhenIssuingCertificateRequests(utils.BaseTestCase,
|
||||
class BaseCertificateRequestsTestCase(utils.BaseTestCase,
|
||||
utils.MockModelRepositoryMixin):
|
||||
"""Tests the 'issue_certificate_request()' function."""
|
||||
"""Tests the 'xxxx_certificate_request()' functions."""
|
||||
|
||||
def setUp(self):
|
||||
super(WhenIssuingCertificateRequests, self).setUp()
|
||||
super(BaseCertificateRequestsTestCase, self).setUp()
|
||||
self.project_id = "56789"
|
||||
self.order_id = "12345"
|
||||
self.barbican_meta_dto = mock.MagicMock()
|
||||
@ -109,9 +129,11 @@ class WhenIssuingCertificateRequests(utils.BaseTestCase,
|
||||
self.result = cert_man.ResultDTO(
|
||||
cert_man.CertificateStatus.WAITING_FOR_CA
|
||||
)
|
||||
self.result_follow_on = common.FollowOnProcessingStatusDTO()
|
||||
|
||||
self.cert_plugin = mock.MagicMock()
|
||||
self.cert_plugin.issue_certificate_request.return_value = self.result
|
||||
self.cert_plugin.check_certificate_status.return_value = self.result
|
||||
|
||||
self.order_model = mock.MagicMock()
|
||||
self.order_model.id = self.order_id
|
||||
@ -124,6 +146,8 @@ class WhenIssuingCertificateRequests(utils.BaseTestCase,
|
||||
self._config_cert_event_plugin()
|
||||
self._config_save_meta_plugin()
|
||||
self._config_get_meta_plugin()
|
||||
self._config_save_barbican_meta_plugin()
|
||||
self._config_get_barbican_meta_plugin()
|
||||
self._config_barbican_meta_dto()
|
||||
|
||||
self.private_key_secret_id = "private_key_secret_id"
|
||||
@ -168,11 +192,161 @@ class WhenIssuingCertificateRequests(utils.BaseTestCase,
|
||||
"https://localhost/containers/" + self.container_id,
|
||||
"subject_name": "cn=host.example.com,ou=dev,ou=us,o=example.com"
|
||||
}
|
||||
self.order_model.order_barbican_metadata = {}
|
||||
|
||||
# Set up mocked repos
|
||||
self.container_repo = mock.MagicMock()
|
||||
self.secret_repo = mock.MagicMock()
|
||||
|
||||
# Set up mocked repositories
|
||||
self.setup_container_repository_mock(self.container_repo)
|
||||
self.setup_container_secret_repository_mock()
|
||||
self.setup_order_plugin_meta_repository_mock()
|
||||
self.setup_project_secret_repository_mock()
|
||||
self.setup_secret_repository_mock(self.secret_repo)
|
||||
|
||||
def tearDown(self):
|
||||
super(BaseCertificateRequestsTestCase, self).tearDown()
|
||||
self.cert_plugin_patcher.stop()
|
||||
self.save_plugin_meta_patcher.stop()
|
||||
self.get_plugin_meta_patcher.stop()
|
||||
self.cert_event_plugin_patcher.stop()
|
||||
self.barbican_meta_dto_patcher.stop()
|
||||
self.save_barbican_barbican_meta_patcher.stop()
|
||||
self.get_barbican_plugin_meta_patcher.stop()
|
||||
|
||||
def _test_should_return_waiting_for_ca(self, method_to_test):
|
||||
self.result.status = cert_man.CertificateStatus.WAITING_FOR_CA
|
||||
|
||||
method_to_test(
|
||||
self.order_model, self.project_model, self.result_follow_on)
|
||||
|
||||
self.assertEqual(
|
||||
common.RetryTasks.INVOKE_CERT_STATUS_CHECK_TASK,
|
||||
self.result_follow_on.retry_task)
|
||||
self.assertEqual(
|
||||
cert_res.ORDER_STATUS_REQUEST_PENDING.id,
|
||||
self.result_follow_on.status)
|
||||
self.assertEqual(
|
||||
cert_res.ORDER_STATUS_REQUEST_PENDING.message,
|
||||
self.result_follow_on.status_message)
|
||||
|
||||
def _test_should_return_certificate_generated(self, method_to_test):
|
||||
self.result.status = cert_man.CertificateStatus.CERTIFICATE_GENERATED
|
||||
|
||||
method_to_test(
|
||||
self.order_model, self.project_model, self.result_follow_on)
|
||||
|
||||
self.assertEqual(
|
||||
common.RetryTasks.NO_ACTION_REQUIRED,
|
||||
self.result_follow_on.retry_task)
|
||||
self.assertEqual(
|
||||
cert_res.ORDER_STATUS_CERT_GENERATED.id,
|
||||
self.result_follow_on.status)
|
||||
self.assertEqual(
|
||||
cert_res.ORDER_STATUS_CERT_GENERATED.message,
|
||||
self.result_follow_on.status_message)
|
||||
|
||||
def _test_should_raise_client_data_issue_seen(self, method_to_test):
|
||||
self.result.status = cert_man.CertificateStatus.CLIENT_DATA_ISSUE_SEEN
|
||||
|
||||
self.assertRaises(
|
||||
cert_man.CertificateStatusClientDataIssue,
|
||||
method_to_test,
|
||||
self.order_model,
|
||||
self.project_model,
|
||||
self.result_follow_on
|
||||
)
|
||||
|
||||
def _test_should_raise_status_not_supported(self, method_to_test):
|
||||
self.result.status = "Legend of Link"
|
||||
|
||||
self.assertRaises(
|
||||
cert_man.CertificateStatusNotSupported,
|
||||
method_to_test,
|
||||
self.order_model,
|
||||
self.project_model,
|
||||
self.result_follow_on
|
||||
)
|
||||
|
||||
def _config_cert_plugin(self):
|
||||
"""Mock the certificate plugin manager."""
|
||||
cert_plugin_config = {
|
||||
'return_value.get_plugin.return_value': self.cert_plugin,
|
||||
'return_value.get_plugin_by_name.return_value': self.cert_plugin,
|
||||
'return_value.get_plugin_by_ca_id.return_value': self.cert_plugin
|
||||
}
|
||||
self.cert_plugin_patcher = mock.patch(
|
||||
'barbican.plugin.interface.certificate_manager'
|
||||
'.CertificatePluginManager',
|
||||
**cert_plugin_config
|
||||
)
|
||||
self.cert_plugin_patcher.start()
|
||||
|
||||
def _config_cert_event_plugin(self):
|
||||
"""Mock the certificate event plugin manager."""
|
||||
self.cert_event_plugin_patcher = mock.patch(
|
||||
'barbican.plugin.interface.certificate_manager'
|
||||
'.EVENT_PLUGIN_MANAGER'
|
||||
)
|
||||
self.cert_event_plugin_patcher.start()
|
||||
|
||||
def _config_save_meta_plugin(self):
|
||||
"""Mock the save plugin meta function."""
|
||||
self.save_plugin_meta_patcher = mock.patch(
|
||||
'barbican.tasks.certificate_resources._save_plugin_metadata'
|
||||
)
|
||||
self.mock_save_plugin = self.save_plugin_meta_patcher.start()
|
||||
|
||||
def _config_get_meta_plugin(self):
|
||||
"""Mock the get plugin meta function."""
|
||||
get_plugin_config = {'return_value': self.plugin_meta}
|
||||
self.get_plugin_meta_patcher = mock.patch(
|
||||
'barbican.tasks.certificate_resources._get_plugin_meta',
|
||||
**get_plugin_config
|
||||
)
|
||||
self.get_plugin_meta_patcher.start()
|
||||
|
||||
def _config_save_barbican_meta_plugin(self):
|
||||
"""Mock the save barbican plugin meta function."""
|
||||
self.save_barbican_barbican_meta_patcher = mock.patch(
|
||||
'barbican.tasks.certificate_resources._save_barbican_metadata'
|
||||
)
|
||||
self.mock_barbican_save_plugin = (
|
||||
self.save_barbican_barbican_meta_patcher.start()
|
||||
)
|
||||
|
||||
def _config_get_barbican_meta_plugin(self):
|
||||
"""Mock the get barbican plugin meta function."""
|
||||
get_barbican_plugin_config = {'return_value': self.barbican_meta}
|
||||
self.get_barbican_plugin_meta_patcher = mock.patch(
|
||||
'barbican.tasks.certificate_resources._get_barbican_meta',
|
||||
**get_barbican_plugin_config
|
||||
)
|
||||
self.get_barbican_plugin_meta_patcher.start()
|
||||
|
||||
def _config_barbican_meta_dto(self):
|
||||
"""Mock the BarbicanMetaDTO."""
|
||||
get_plugin_config = {'return_value': self.barbican_meta_dto}
|
||||
self.barbican_meta_dto_patcher = mock.patch(
|
||||
'barbican.plugin.interface.certificate_manager'
|
||||
'.BarbicanMetaDTO',
|
||||
**get_plugin_config
|
||||
)
|
||||
self.barbican_meta_dto_patcher.start()
|
||||
|
||||
|
||||
class WhenIssuingCertificateRequests(BaseCertificateRequestsTestCase):
|
||||
"""Tests the 'issue_certificate_request()' function."""
|
||||
|
||||
def setUp(self):
|
||||
super(WhenIssuingCertificateRequests, self).setUp()
|
||||
|
||||
self.private_key_secret_id = "private_key_secret_id"
|
||||
self.public_key_secret_id = "public_key_secret_id"
|
||||
self.passphrase_secret_id = "passphrase_secret_id"
|
||||
self.private_key_value = None
|
||||
self.public_key_value = "my public key"
|
||||
self.passphrase_value = "my passphrase"
|
||||
self.ca_repo = mock.MagicMock()
|
||||
self.preferred_ca_repo = mock.MagicMock()
|
||||
|
||||
@ -184,12 +358,6 @@ class WhenIssuingCertificateRequests(utils.BaseTestCase,
|
||||
self.project_id,
|
||||
"ca_id")
|
||||
|
||||
# Set up mocked repositories
|
||||
self.setup_container_repository_mock(self.container_repo)
|
||||
self.setup_container_secret_repository_mock()
|
||||
self.setup_order_plugin_meta_repository_mock()
|
||||
self.setup_project_secret_repository_mock()
|
||||
self.setup_secret_repository_mock(self.secret_repo)
|
||||
self.setup_ca_repository_mock(self.ca_repo)
|
||||
self.setup_preferred_ca_repository_mock(self.preferred_ca_repo)
|
||||
|
||||
@ -205,37 +373,33 @@ class WhenIssuingCertificateRequests(utils.BaseTestCase,
|
||||
|
||||
def tearDown(self):
|
||||
super(WhenIssuingCertificateRequests, self).tearDown()
|
||||
self.cert_plugin_patcher.stop()
|
||||
self.save_plugin_meta_patcher.stop()
|
||||
self.get_plugin_meta_patcher.stop()
|
||||
self.cert_event_plugin_patcher.stop()
|
||||
self.barbican_meta_dto_patcher.stop()
|
||||
|
||||
def test_should_return_waiting_for_ca(self):
|
||||
self.result.status = cert_man.CertificateStatus.WAITING_FOR_CA
|
||||
self._test_should_return_waiting_for_ca(
|
||||
cert_res.issue_certificate_request)
|
||||
|
||||
cert_res.issue_certificate_request(self.order_model,
|
||||
self.project_model)
|
||||
self._verify_issue_certificate_plugins_called()
|
||||
|
||||
def test_should_return_waiting_for_ca_as_retry(self):
|
||||
# For a retry, the plugin-name to look up would have already been
|
||||
# saved into the barbican metadata for the order, so just make sure
|
||||
# we can retrieve it.
|
||||
self.barbican_meta.update({'plugin_name': 'foo-plugin'})
|
||||
|
||||
self._test_should_return_waiting_for_ca(
|
||||
cert_res.issue_certificate_request)
|
||||
|
||||
self._verify_issue_certificate_plugins_called()
|
||||
|
||||
def test_should_return_certificate_generated(self):
|
||||
self.result.status = cert_man.CertificateStatus.CERTIFICATE_GENERATED
|
||||
|
||||
cert_res.issue_certificate_request(self.order_model,
|
||||
self.project_model)
|
||||
self._test_should_return_certificate_generated(
|
||||
cert_res.issue_certificate_request)
|
||||
|
||||
self._verify_issue_certificate_plugins_called()
|
||||
|
||||
def test_should_raise_client_data_issue_seen(self):
|
||||
self.result.status = cert_man.CertificateStatus.CLIENT_DATA_ISSUE_SEEN
|
||||
|
||||
self.assertRaises(
|
||||
cert_man.CertificateStatusClientDataIssue,
|
||||
cert_res.issue_certificate_request,
|
||||
self.order_model,
|
||||
self.project_model
|
||||
)
|
||||
self._test_should_raise_client_data_issue_seen(
|
||||
cert_res.issue_certificate_request)
|
||||
|
||||
def _do_pyopenssl_stored_key_request(self):
|
||||
self.container = models.Container(
|
||||
@ -254,13 +418,14 @@ class WhenIssuingCertificateRequests(utils.BaseTestCase,
|
||||
self.result.status = cert_man.CertificateStatus.WAITING_FOR_CA
|
||||
|
||||
cert_res.issue_certificate_request(self.order_model,
|
||||
self.project_model)
|
||||
self.project_model,
|
||||
self.result_follow_on)
|
||||
|
||||
def test_should_return_for_pyopenssl_stored_key(self):
|
||||
self._do_pyopenssl_stored_key_request()
|
||||
self._verify_issue_certificate_plugins_called()
|
||||
self.assertIsNotNone(
|
||||
self.order_model.order_barbican_metadata['generated_csr'])
|
||||
self.order_model.order_barbican_metadata.get('generated_csr'))
|
||||
|
||||
# TODO(alee-3) Add tests to validate the request based on the validator
|
||||
# code that dave-mccowan is adding.
|
||||
@ -306,7 +471,8 @@ class WhenIssuingCertificateRequests(utils.BaseTestCase,
|
||||
self.result.status = cert_man.CertificateStatus.WAITING_FOR_CA
|
||||
|
||||
cert_res.issue_certificate_request(self.order_model,
|
||||
self.project_model)
|
||||
self.project_model,
|
||||
self.result_follow_on)
|
||||
|
||||
self._verify_issue_certificate_plugins_called()
|
||||
self.assertIsNotNone(
|
||||
@ -332,7 +498,8 @@ class WhenIssuingCertificateRequests(utils.BaseTestCase,
|
||||
self.result.status = cert_man.CertificateStatus.WAITING_FOR_CA
|
||||
|
||||
cert_res.issue_certificate_request(self.order_model,
|
||||
self.project_model)
|
||||
self.project_model,
|
||||
self.result_follow_on)
|
||||
|
||||
self._verify_issue_certificate_plugins_called()
|
||||
self.assertIsNotNone(
|
||||
@ -357,7 +524,8 @@ class WhenIssuingCertificateRequests(utils.BaseTestCase,
|
||||
self.result.status = cert_man.CertificateStatus.WAITING_FOR_CA
|
||||
|
||||
cert_res.issue_certificate_request(self.order_model,
|
||||
self.project_model)
|
||||
self.project_model,
|
||||
self.result_follow_on)
|
||||
|
||||
self._verify_issue_certificate_plugins_called()
|
||||
self.assertIsNotNone(
|
||||
@ -384,7 +552,8 @@ class WhenIssuingCertificateRequests(utils.BaseTestCase,
|
||||
self.assertRaises(excep.StoredKeyContainerNotFound,
|
||||
cert_res.issue_certificate_request,
|
||||
self.order_model,
|
||||
self.project_model)
|
||||
self.project_model,
|
||||
self.result_follow_on)
|
||||
|
||||
def test_should_raise_for_pycrypto_stored_key_no_private_key(self):
|
||||
self.container = models.Container(
|
||||
@ -404,7 +573,8 @@ class WhenIssuingCertificateRequests(utils.BaseTestCase,
|
||||
self.assertRaises(excep.StoredKeyPrivateKeyNotFound,
|
||||
cert_res.issue_certificate_request,
|
||||
self.order_model,
|
||||
self.project_model)
|
||||
self.project_model,
|
||||
self.result_follow_on)
|
||||
|
||||
def test_should_return_for_pyopenssl_stored_key_with_extensions(self):
|
||||
self.container = models.Container(
|
||||
@ -425,7 +595,8 @@ class WhenIssuingCertificateRequests(utils.BaseTestCase,
|
||||
self.result.status = cert_man.CertificateStatus.WAITING_FOR_CA
|
||||
|
||||
cert_res.issue_certificate_request(self.order_model,
|
||||
self.project_model)
|
||||
self.project_model,
|
||||
self.result_follow_on)
|
||||
|
||||
self._verify_issue_certificate_plugins_called()
|
||||
self.assertIsNotNone(
|
||||
@ -442,7 +613,8 @@ class WhenIssuingCertificateRequests(utils.BaseTestCase,
|
||||
cert_man.CertificateStatusInvalidOperation,
|
||||
cert_res.issue_certificate_request,
|
||||
self.order_model,
|
||||
self.project_model
|
||||
self.project_model,
|
||||
self.result_follow_on
|
||||
)
|
||||
|
||||
def test_should_return_ca_unavailable_for_request(self):
|
||||
@ -455,7 +627,8 @@ class WhenIssuingCertificateRequests(utils.BaseTestCase,
|
||||
order_ref = hrefs.convert_order_to_href(self.order_id)
|
||||
|
||||
cert_res.issue_certificate_request(self.order_model,
|
||||
self.project_model)
|
||||
self.project_model,
|
||||
self.result_follow_on)
|
||||
|
||||
self._verify_issue_certificate_plugins_called()
|
||||
|
||||
@ -466,16 +639,19 @@ class WhenIssuingCertificateRequests(utils.BaseTestCase,
|
||||
status_msg,
|
||||
retry_msec
|
||||
)
|
||||
self.assertEqual(
|
||||
common.RetryTasks.INVOKE_SAME_TASK,
|
||||
self.result_follow_on.retry_task)
|
||||
self.assertEqual(
|
||||
cert_res.ORDER_STATUS_CA_UNAVAIL_FOR_ISSUE.id,
|
||||
self.result_follow_on.status)
|
||||
self.assertEqual(
|
||||
cert_res.ORDER_STATUS_CA_UNAVAIL_FOR_ISSUE.message,
|
||||
self.result_follow_on.status_message)
|
||||
|
||||
def test_should_raise_status_not_supported(self):
|
||||
self.result.status = "Legend of Link"
|
||||
|
||||
self.assertRaises(
|
||||
cert_man.CertificateStatusNotSupported,
|
||||
cert_res.issue_certificate_request,
|
||||
self.order_model,
|
||||
self.project_model
|
||||
)
|
||||
self._test_should_raise_status_not_supported(
|
||||
cert_res.issue_certificate_request)
|
||||
|
||||
def _verify_issue_certificate_plugins_called(self):
|
||||
self.cert_plugin.issue_certificate_request.assert_called_once_with(
|
||||
@ -490,49 +666,82 @@ class WhenIssuingCertificateRequests(utils.BaseTestCase,
|
||||
self.plugin_meta
|
||||
)
|
||||
|
||||
def _config_cert_plugin(self):
|
||||
"""Mock the certificate plugin manager."""
|
||||
cert_plugin_config = {
|
||||
'return_value.get_plugin.return_value': self.cert_plugin,
|
||||
'return_value.get_plugin_by_ca_id.return_value': self.cert_plugin
|
||||
}
|
||||
self.cert_plugin_patcher = mock.patch(
|
||||
'barbican.plugin.interface.certificate_manager'
|
||||
'.CertificatePluginManager',
|
||||
**cert_plugin_config
|
||||
self.mock_barbican_save_plugin.assert_called_once_with(
|
||||
self.order_model,
|
||||
self.barbican_meta
|
||||
)
|
||||
self.cert_plugin_patcher.start()
|
||||
|
||||
def _config_cert_event_plugin(self):
|
||||
"""Mock the certificate event plugin manager."""
|
||||
self.cert_event_plugin_patcher = mock.patch(
|
||||
'barbican.plugin.interface.certificate_manager'
|
||||
'.EVENT_PLUGIN_MANAGER'
|
||||
)
|
||||
self.cert_event_plugin_patcher.start()
|
||||
|
||||
def _config_save_meta_plugin(self):
|
||||
"""Mock the save plugin meta function."""
|
||||
self.save_plugin_meta_patcher = mock.patch(
|
||||
'barbican.tasks.certificate_resources._save_plugin_metadata'
|
||||
)
|
||||
self.mock_save_plugin = self.save_plugin_meta_patcher.start()
|
||||
class WhenCheckingCertificateRequests(BaseCertificateRequestsTestCase):
|
||||
"""Tests the 'check_certificate_request()' function."""
|
||||
|
||||
def _config_get_meta_plugin(self):
|
||||
"""Mock the get plugin meta function."""
|
||||
get_plugin_config = {'return_value': self.plugin_meta}
|
||||
self.get_plugin_meta_patcher = mock.patch(
|
||||
'barbican.tasks.certificate_resources._get_plugin_meta',
|
||||
**get_plugin_config
|
||||
)
|
||||
self.get_plugin_meta_patcher.start()
|
||||
def setUp(self):
|
||||
super(WhenCheckingCertificateRequests, self).setUp()
|
||||
|
||||
def _config_barbican_meta_dto(self):
|
||||
"""Mock the BarbicanMetaDTO."""
|
||||
get_plugin_config = {'return_value': self.barbican_meta_dto}
|
||||
self.barbican_meta_dto_patcher = mock.patch(
|
||||
'barbican.plugin.interface.certificate_manager'
|
||||
'.BarbicanMetaDTO',
|
||||
**get_plugin_config
|
||||
def tearDown(self):
|
||||
super(WhenCheckingCertificateRequests, self).tearDown()
|
||||
|
||||
def test_should_return_waiting_for_ca(self):
|
||||
self._test_should_return_waiting_for_ca(
|
||||
cert_res.check_certificate_request)
|
||||
|
||||
self._verify_check_certificate_plugins_called()
|
||||
|
||||
def test_should_return_certificate_generated(self):
|
||||
self._test_should_return_certificate_generated(
|
||||
cert_res.check_certificate_request)
|
||||
|
||||
self._verify_check_certificate_plugins_called()
|
||||
|
||||
def test_should_raise_client_data_issue_seen(self):
|
||||
self._test_should_raise_client_data_issue_seen(
|
||||
cert_res.check_certificate_request)
|
||||
|
||||
def test_should_raise_status_not_supported(self):
|
||||
self._test_should_raise_status_not_supported(
|
||||
cert_res.check_certificate_request)
|
||||
|
||||
def test_should_return_ca_unavailable_for_request(self):
|
||||
retry_msec = 123
|
||||
status_msg = 'Test status'
|
||||
self.result.status = (
|
||||
cert_man.CertificateStatus.CA_UNAVAILABLE_FOR_REQUEST)
|
||||
self.result.retry_msec = retry_msec
|
||||
self.result.status_message = status_msg
|
||||
order_ref = hrefs.convert_order_to_href(self.order_id)
|
||||
|
||||
cert_res.check_certificate_request(self.order_model,
|
||||
self.project_model,
|
||||
self.result_follow_on)
|
||||
|
||||
self._verify_check_certificate_plugins_called()
|
||||
|
||||
epm = self.cert_event_plugin_patcher.target.EVENT_PLUGIN_MANAGER
|
||||
epm.notify_ca_is_unavailable.assert_called_once_with(
|
||||
self.project_id,
|
||||
order_ref,
|
||||
status_msg,
|
||||
retry_msec
|
||||
)
|
||||
self.assertEqual(
|
||||
common.RetryTasks.INVOKE_SAME_TASK,
|
||||
self.result_follow_on.retry_task)
|
||||
self.assertEqual(
|
||||
cert_res.ORDER_STATUS_CA_UNAVAIL_FOR_CHECK.id,
|
||||
self.result_follow_on.status)
|
||||
self.assertEqual(
|
||||
cert_res.ORDER_STATUS_CA_UNAVAIL_FOR_CHECK.message,
|
||||
self.result_follow_on.status_message)
|
||||
|
||||
def _verify_check_certificate_plugins_called(self):
|
||||
self.cert_plugin.check_certificate_status.assert_called_once_with(
|
||||
self.order_id,
|
||||
self.order_meta,
|
||||
self.plugin_meta,
|
||||
self.barbican_meta_dto
|
||||
)
|
||||
|
||||
self.mock_save_plugin.assert_called_once_with(
|
||||
self.order_model,
|
||||
self.plugin_meta
|
||||
)
|
||||
self.barbican_meta_dto_patcher.start()
|
||||
|
@ -14,6 +14,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
import mock
|
||||
import six
|
||||
|
||||
from barbican import i18n as u
|
||||
from barbican.model import models
|
||||
@ -169,6 +170,7 @@ class WhenBeginningKeyTypeOrder(BaseOrderTestCase):
|
||||
@mock.patch('barbican.plugin.resources.generate_secret')
|
||||
def test_should_process_key_order(self, mock_generate_secret):
|
||||
mock_generate_secret.return_value = self.secret
|
||||
|
||||
self.resource.process(self.order.id, self.external_project_id)
|
||||
|
||||
self.order_repo.get.assert_called_once_with(
|
||||
@ -253,6 +255,57 @@ class WhenBeginningKeyTypeOrder(BaseOrderTestCase):
|
||||
)
|
||||
|
||||
|
||||
class WhenBeginningCertificateTypeOrder(BaseOrderTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(WhenBeginningCertificateTypeOrder, self).setUp()
|
||||
|
||||
self.order.type = models.OrderType.CERTIFICATE
|
||||
self.resource = resources.BeginTypeOrder()
|
||||
|
||||
@mock.patch(
|
||||
'barbican.tasks.certificate_resources.issue_certificate_request')
|
||||
def test_should_process_order_no_container(
|
||||
self, mock_issue_cert_request):
|
||||
mock_issue_cert_request.return_value = None
|
||||
|
||||
self.resource.process(self.order.id, self.external_project_id)
|
||||
|
||||
self.order_repo.get.assert_called_once_with(
|
||||
entity_id=self.order.id,
|
||||
external_project_id=self.external_project_id)
|
||||
|
||||
self.assertEqual(self.order.status, models.States.ACTIVE)
|
||||
|
||||
mock_issue_cert_request.assert_called_once_with(
|
||||
self.order,
|
||||
self.project,
|
||||
mock.ANY
|
||||
)
|
||||
self.assertIsNone(self.order.container_id)
|
||||
|
||||
@mock.patch(
|
||||
'barbican.tasks.certificate_resources.issue_certificate_request')
|
||||
def test_should_process_order_with_container(
|
||||
self, mock_issue_cert_request):
|
||||
mock_issue_cert_request.return_value = self.container
|
||||
|
||||
self.resource.process(self.order.id, self.external_project_id)
|
||||
|
||||
self.order_repo.get.assert_called_once_with(
|
||||
entity_id=self.order.id,
|
||||
external_project_id=self.external_project_id)
|
||||
|
||||
self.assertEqual(self.order.status, models.States.ACTIVE)
|
||||
|
||||
mock_issue_cert_request.assert_called_once_with(
|
||||
self.order,
|
||||
self.project,
|
||||
mock.ANY
|
||||
)
|
||||
self.assertEqual(self.container.id, self.order.container_id)
|
||||
|
||||
|
||||
class WhenUpdatingOrder(BaseOrderTestCase):
|
||||
|
||||
def setUp(self):
|
||||
@ -398,3 +451,73 @@ class WhenBeginningAsymmetricTypeOrder(BaseOrderTestCase):
|
||||
self.order.id,
|
||||
self.external_project_id,
|
||||
)
|
||||
|
||||
|
||||
class WhenCheckingCertificateStatus(BaseOrderTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(WhenCheckingCertificateStatus, self).setUp()
|
||||
|
||||
self.order.type = models.OrderType.CERTIFICATE
|
||||
|
||||
self.resource = resources.CheckCertificateStatusOrder()
|
||||
|
||||
@mock.patch(
|
||||
'barbican.tasks.certificate_resources.check_certificate_request')
|
||||
def test_should_process_order_no_container(
|
||||
self, mock_check_cert_request):
|
||||
mock_check_cert_request.return_value = None
|
||||
|
||||
self.resource.process(self.order.id, self.external_project_id)
|
||||
|
||||
self.order_repo.get.assert_called_once_with(
|
||||
entity_id=self.order.id,
|
||||
external_project_id=self.external_project_id)
|
||||
|
||||
self.assertEqual(self.order.status, models.States.ACTIVE)
|
||||
|
||||
mock_check_cert_request.assert_called_once_with(
|
||||
self.order,
|
||||
self.project,
|
||||
mock.ANY
|
||||
)
|
||||
self.assertIsNone(self.order.container_id)
|
||||
|
||||
@mock.patch(
|
||||
'barbican.tasks.certificate_resources.check_certificate_request')
|
||||
def test_should_process_order_with_container(
|
||||
self, mock_check_cert_request):
|
||||
mock_check_cert_request.return_value = self.container
|
||||
|
||||
self.resource.process(self.order.id, self.external_project_id)
|
||||
|
||||
self.order_repo.get.assert_called_once_with(
|
||||
entity_id=self.order.id,
|
||||
external_project_id=self.external_project_id)
|
||||
|
||||
self.assertEqual(self.order.status, models.States.ACTIVE)
|
||||
|
||||
mock_check_cert_request.assert_called_once_with(
|
||||
self.order,
|
||||
self.project,
|
||||
mock.ANY
|
||||
)
|
||||
self.assertEqual(self.container.id, self.order.container_id)
|
||||
|
||||
def test_should_fail_with_bogus_order_type(self):
|
||||
self.order.type = 'bogus-type'
|
||||
|
||||
self.assertRaises(
|
||||
NotImplementedError,
|
||||
self.resource.process,
|
||||
self.order.id,
|
||||
self.external_project_id,
|
||||
)
|
||||
|
||||
# Order state should be set to ERROR.
|
||||
self.assertEqual(models.States.ERROR, self.order.status)
|
||||
self.assertEqual(
|
||||
six.u('Check Certificate Order Status failure seen - '
|
||||
'please contact site administrator.'),
|
||||
self.order.error_reason)
|
||||
self.assertEqual(500, self.order.error_status_code)
|
||||
|
@ -156,10 +156,10 @@ server_name = 'barbican.queue'
|
||||
|
||||
[retry_scheduler]
|
||||
# Seconds (float) to wait between starting retry scheduler
|
||||
task_retry_tg_initial_delay = 10.0
|
||||
initial_delay_seconds = 10.0
|
||||
|
||||
# Seconds (float) to wait between starting retry scheduler
|
||||
task_retry_tg_periodic_interval_max = 10.0
|
||||
periodic_interval_max_seconds = 10.0
|
||||
|
||||
|
||||
# ================= Keystone Notification Options - Application ===============
|
||||
|
@ -21,11 +21,14 @@ class OrderModel(BaseModel):
|
||||
def __init__(self, type=None, name=None, status=None, secret_ref=None,
|
||||
expiration=None, updated=None, created=None, meta=None,
|
||||
payload_content_type=None, order_ref=None, container_ref=None,
|
||||
error_status_code=None, error_reason=None):
|
||||
error_status_code=None, error_reason=None,
|
||||
sub_status=None, sub_status_message=None):
|
||||
super(OrderModel, self).__init__()
|
||||
self.type = type
|
||||
self.name = name
|
||||
self.status = status
|
||||
self.sub_status = sub_status
|
||||
self.sub_status_message = sub_status_message
|
||||
self.secret_ref = secret_ref
|
||||
self.expiration = expiration
|
||||
self.updated = updated
|
||||
|
Loading…
Reference in New Issue
Block a user