Merge pull request #2951 from Netflix/enable_autorotate_attached_certs
Autorotate certs attached to endpoints
This commit is contained in:
commit
eaaacfad3e
|
@ -5,29 +5,18 @@
|
||||||
:license: Apache, see LICENSE for more details.
|
:license: Apache, see LICENSE for more details.
|
||||||
.. moduleauthor:: Kevin Glisson <kglisson@netflix.com>
|
.. moduleauthor:: Kevin Glisson <kglisson@netflix.com>
|
||||||
"""
|
"""
|
||||||
import sys
|
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
from tabulate import tabulate
|
import sys
|
||||||
from sqlalchemy import or_
|
|
||||||
|
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
|
|
||||||
from flask_script import Manager
|
|
||||||
from flask_principal import Identity, identity_changed
|
from flask_principal import Identity, identity_changed
|
||||||
|
from flask_script import Manager
|
||||||
|
from sqlalchemy import or_
|
||||||
|
from tabulate import tabulate
|
||||||
|
|
||||||
from lemur import database
|
from lemur import database
|
||||||
from lemur.extensions import sentry
|
|
||||||
from lemur.extensions import metrics
|
|
||||||
from lemur.plugins.base import plugins
|
|
||||||
from lemur.constants import SUCCESS_METRIC_STATUS, FAILURE_METRIC_STATUS
|
|
||||||
from lemur.deployment import service as deployment_service
|
|
||||||
from lemur.endpoints import service as endpoint_service
|
|
||||||
from lemur.notifications.messaging import send_rotation_notification
|
|
||||||
from lemur.domains.models import Domain
|
|
||||||
from lemur.authorities.models import Authority
|
from lemur.authorities.models import Authority
|
||||||
from lemur.certificates.schemas import CertificateOutputSchema
|
|
||||||
from lemur.certificates.models import Certificate
|
from lemur.certificates.models import Certificate
|
||||||
|
from lemur.certificates.schemas import CertificateOutputSchema
|
||||||
from lemur.certificates.service import (
|
from lemur.certificates.service import (
|
||||||
reissue_certificate,
|
reissue_certificate,
|
||||||
get_certificate_primitives,
|
get_certificate_primitives,
|
||||||
|
@ -35,9 +24,16 @@ from lemur.certificates.service import (
|
||||||
get_by_name,
|
get_by_name,
|
||||||
get_all_certs,
|
get_all_certs,
|
||||||
get,
|
get,
|
||||||
|
get_all_certs_attached_to_endpoint_without_autorotate,
|
||||||
)
|
)
|
||||||
|
|
||||||
from lemur.certificates.verify import verify_string
|
from lemur.certificates.verify import verify_string
|
||||||
|
from lemur.constants import SUCCESS_METRIC_STATUS, FAILURE_METRIC_STATUS
|
||||||
|
from lemur.deployment import service as deployment_service
|
||||||
|
from lemur.domains.models import Domain
|
||||||
|
from lemur.endpoints import service as endpoint_service
|
||||||
|
from lemur.extensions import sentry, metrics
|
||||||
|
from lemur.notifications.messaging import send_rotation_notification
|
||||||
|
from lemur.plugins.base import plugins
|
||||||
|
|
||||||
manager = Manager(usage="Handles all certificate related tasks.")
|
manager = Manager(usage="Handles all certificate related tasks.")
|
||||||
|
|
||||||
|
@ -482,3 +478,23 @@ def check_revoked():
|
||||||
cert.status = "unknown"
|
cert.status = "unknown"
|
||||||
|
|
||||||
database.update(cert)
|
database.update(cert)
|
||||||
|
|
||||||
|
|
||||||
|
@manager.command
|
||||||
|
def automatically_enable_autorotate():
|
||||||
|
"""
|
||||||
|
This function automatically enables autorotation for unexpired certificates that are
|
||||||
|
attached to an endpoint but do not have autorotate enabled.
|
||||||
|
"""
|
||||||
|
log_data = {
|
||||||
|
"function": f"{__name__}.{sys._getframe().f_code.co_name}",
|
||||||
|
}
|
||||||
|
|
||||||
|
eligible_certs = get_all_certs_attached_to_endpoint_without_autorotate()
|
||||||
|
for cert in eligible_certs:
|
||||||
|
log_data["certificate"] = cert.name
|
||||||
|
log_data["certificate_id"] = cert.id
|
||||||
|
log_data["message"] = "Enabling auto-rotate for certificate"
|
||||||
|
current_app.logger.info(log_data)
|
||||||
|
cert.rotation = True
|
||||||
|
database.update(cert)
|
||||||
|
|
|
@ -118,6 +118,21 @@ def get_all_pending_cleaning_expired(source):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_all_certs_attached_to_endpoint_without_autorotate():
|
||||||
|
"""
|
||||||
|
Retrieves all certificates that are attached to an endpoint, but that do not have autorotate enabled.
|
||||||
|
|
||||||
|
:return: list of certificates attached to an endpoint without autorotate
|
||||||
|
"""
|
||||||
|
return (
|
||||||
|
Certificate.query.filter(Certificate.endpoints.any())
|
||||||
|
.filter(Certificate.rotation == False)
|
||||||
|
.filter(Certificate.not_after >= arrow.now())
|
||||||
|
.filter(not_(Certificate.replaced.any()))
|
||||||
|
.all() # noqa
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_all_pending_cleaning_expiring_in_days(source, days_to_expire):
|
def get_all_pending_cleaning_expiring_in_days(source, days_to_expire):
|
||||||
"""
|
"""
|
||||||
Retrieves all certificates that are available for cleaning, not attached to endpoint,
|
Retrieves all certificates that are available for cleaning, not attached to endpoint,
|
||||||
|
@ -144,7 +159,9 @@ def get_all_pending_cleaning_issued_since_days(source, days_since_issuance):
|
||||||
:param source: the source to search for certificates
|
:param source: the source to search for certificates
|
||||||
:return: list of pending certificates
|
:return: list of pending certificates
|
||||||
"""
|
"""
|
||||||
not_in_use_window = arrow.now().shift(days=-days_since_issuance).format("YYYY-MM-DD")
|
not_in_use_window = (
|
||||||
|
arrow.now().shift(days=-days_since_issuance).format("YYYY-MM-DD")
|
||||||
|
)
|
||||||
return (
|
return (
|
||||||
Certificate.query.filter(Certificate.sources.any(id=source.id))
|
Certificate.query.filter(Certificate.sources.any(id=source.id))
|
||||||
.filter(not_(Certificate.endpoints.any()))
|
.filter(not_(Certificate.endpoints.any()))
|
||||||
|
@ -367,9 +384,11 @@ def render(args):
|
||||||
|
|
||||||
show_expired = args.pop("showExpired")
|
show_expired = args.pop("showExpired")
|
||||||
if show_expired != 1:
|
if show_expired != 1:
|
||||||
one_month_old = arrow.now()\
|
one_month_old = (
|
||||||
.shift(months=current_app.config.get("HIDE_EXPIRED_CERTS_AFTER_MONTHS", -1))\
|
arrow.now()
|
||||||
|
.shift(months=current_app.config.get("HIDE_EXPIRED_CERTS_AFTER_MONTHS", -1))
|
||||||
.format("YYYY-MM-DD")
|
.format("YYYY-MM-DD")
|
||||||
|
)
|
||||||
query = query.filter(Certificate.not_after > one_month_old)
|
query = query.filter(Certificate.not_after > one_month_old)
|
||||||
|
|
||||||
time_range = args.pop("time_range")
|
time_range = args.pop("time_range")
|
||||||
|
|
|
@ -812,3 +812,27 @@ def notify_expirations():
|
||||||
|
|
||||||
metrics.send(f"{function}.success", "counter", 1)
|
metrics.send(f"{function}.success", "counter", 1)
|
||||||
return log_data
|
return log_data
|
||||||
|
|
||||||
|
|
||||||
|
@celery.task(soft_time_limit=3600)
|
||||||
|
def enable_autorotate_for_certs_attached_to_endpoint():
|
||||||
|
"""
|
||||||
|
This celery task automatically enables autorotation for unexpired certificates that are
|
||||||
|
attached to an endpoint but do not have autorotate enabled.
|
||||||
|
: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,
|
||||||
|
"task_id": task_id,
|
||||||
|
"message": "Enabling autorotate to eligible certificates",
|
||||||
|
}
|
||||||
|
current_app.logger.debug(log_data)
|
||||||
|
|
||||||
|
cli_certificate.automatically_enable_autorotate()
|
||||||
|
metrics.send(f"{function}.success", "counter", 1)
|
||||||
|
return log_data
|
||||||
|
|
Loading…
Reference in New Issue