diff --git a/lemur/certificates/cli.py b/lemur/certificates/cli.py index b883dee0..f23948be 100644 --- a/lemur/certificates/cli.py +++ b/lemur/certificates/cli.py @@ -735,3 +735,45 @@ def automatically_enable_autorotate(): }) cert.rotation = True database.update(cert) + + +@manager.command +def deactivate_entrust_certificates(): + """ + Attempt to deactivate test certificates issued by Entrust + """ + + log_data = { + "function": f"{__name__}.{sys._getframe().f_code.co_name}", + "message": "Deactivating Entrust certificates" + } + + certificates = get_all_valid_certs(['entrust-issuer']) + entrust_plugin = plugins.get('entrust-issuer') + for cert in certificates: + try: + response = entrust_plugin.deactivate_certificate(cert) + if response == 200: + cert.status = "revoked" + else: + cert.status = "unknown" + + log_data["valid"] = cert.status + log_data["certificate_name"] = cert.name + log_data["certificate_id"] = cert.id + metrics.send( + "certificate_deactivate", + "counter", + 1, + metric_tags={"status": log_data["valid"], + "certificate_name": log_data["certificate_name"], + "certificate_id": log_data["certificate_id"]}, + ) + current_app.logger.info(log_data) + + database.update(cert) + + except Exception as e: + current_app.logger.info(log_data) + sentry.captureException() + current_app.logger.exception(e) diff --git a/lemur/certificates/service.py b/lemur/certificates/service.py index 6d1bd2ac..6daaa641 100644 --- a/lemur/certificates/service.py +++ b/lemur/certificates/service.py @@ -105,7 +105,7 @@ def get_all_certs(): def get_all_valid_certs(authority_plugin_name): """ - Retrieves all valid (not expired) certificates within Lemur, for the given authority plugin names + Retrieves all valid (not expired & not revoked) certificates within Lemur, for the given authority plugin names ignored if no authority_plugin_name provided. Note that depending on the DB size retrieving all certificates might an expensive operation @@ -116,11 +116,12 @@ def get_all_valid_certs(authority_plugin_name): return ( Certificate.query.outerjoin(Authority, Authority.id == Certificate.authority_id).filter( Certificate.not_after > arrow.now().format("YYYY-MM-DD")).filter( - Authority.plugin_name.in_(authority_plugin_name)).all() + Authority.plugin_name.in_(authority_plugin_name)).filter(Certificate.revoked.is_(False)).all() ) else: return ( - Certificate.query.filter(Certificate.not_after > arrow.now().format("YYYY-MM-DD")).all() + Certificate.query.filter(Certificate.not_after > arrow.now().format("YYYY-MM-DD")).filter( + Certificate.revoked.is_(False)).all() ) diff --git a/lemur/common/celery.py b/lemur/common/celery.py index a490b13b..f9d58bd9 100644 --- a/lemur/common/celery.py +++ b/lemur/common/celery.py @@ -759,7 +759,7 @@ def check_revoked(): log_data = { "function": function, - "message": "check if any certificates are revoked revoked", + "message": "check if any valid certificate is revoked", "task_id": task_id, } @@ -842,3 +842,39 @@ def enable_autorotate_for_certs_attached_to_endpoint(): cli_certificate.automatically_enable_autorotate() metrics.send(f"{function}.success", "counter", 1) return log_data + + +@celery.task(soft_time_limit=3600) +def deactivate_entrust_test_certificates(): + """ + This celery task attempts to deactivate all not yet deactivated Entrust certificates, and should only run in TEST + :return: + """ + function = f"{__name__}.{sys._getframe().f_code.co_name}" + task_id = None + if celery.current_task: + task_id = celery.current_task.request.id + + log_data = { + "function": function, + "message": "deactivate entrust certificates", + "task_id": task_id, + } + + if task_id and is_task_active(function, task_id, None): + log_data["message"] = "Skipping task: Task is already active" + current_app.logger.debug(log_data) + return + + current_app.logger.debug(log_data) + try: + cli_certificate.deactivate_entrust_certificates() + except SoftTimeLimitExceeded: + log_data["message"] = "Time limit exceeded." + current_app.logger.error(log_data) + sentry.captureException() + metrics.send("celery.timeout", "counter", 1, metric_tags={"function": function}) + return + + metrics.send(f"{function}.success", "counter", 1) + return log_data diff --git a/lemur/plugins/lemur_entrust/plugin.py b/lemur/plugins/lemur_entrust/plugin.py index 515e2400..0e9f6b7f 100644 --- a/lemur/plugins/lemur_entrust/plugin.py +++ b/lemur/plugins/lemur_entrust/plugin.py @@ -109,7 +109,12 @@ def handle_response(my_response): "response": d } current_app.logger.info(log_data) - return d + if d == {'response': 'No detailed message'}: + # status if no data + return s + else: + # return data from the response + return d class EntrustIssuerPlugin(IssuerPlugin):