Ejemplo n.º 1
0
def rotate_all_pending_endpoints():
    """."""
    function = f"{__name__}.{sys._getframe().f_code.co_name}"
    logger = logging.getLogger(function)
    task_id = None
    if celery.current_task:
        task_id = celery.current_task.request.id

    log_data = {
        "task_id": task_id,
    }

    if task_id and is_task_active(function, task_id, None):
        logger.debug("Skipping task: Task is already active", extra=log_data)
        return

    pending_endpoints = endpoint_service.get_all_pending_rotation()
    rotate_endpoint_tasks = []
    for endpoint in pending_endpoints:
        new_cert = endpoint.certificate.replaced[0]

        # verify that the certificate has been uploaded before rotating the endpoints
        if not all([
                dest.plugin.verify(new_cert.name, dest.options)
                for dest in new_cert.destinations
        ]):
            logger.warning(
                "Certificate has not been uploaded to all destinations, skipping rotate"
            )
            continue

        project, lb, old_cert_name = endpoint.name.split("/")
        task = rotate_endpoint.s(
            endpoint.id,
            lb=lb,
            project=project,
            new_cert=new_cert.name,
            old_cert=old_cert_name,
        )
        rotate_endpoint_tasks.append(task)

    logger.info(
        f"Creating tasks to rotate {len(rotate_endpoint_tasks)} endpoints.")

    # create task group and skew execution
    skew_config = current_app.config.get("CELERY_ROTATE_ENDPOINT_SKEW", {})
    start = skew_config.get("start",
                            0)  # seconds until execution of first task
    stop = skew_config.get(
        "stop", None)  # maximum number of seconds to wait for a task
    step = skew_config.get(
        "step", 10
    )  # number of seconds to wait until next task is executed (stop might override this)
    logger.debug(
        f"Scheduling endpoint rotations (start={start}, stop={stop}, step={step})"
    )

    g = group(rotate_endpoint_tasks).skew(start, stop, step)
    g.apply_async()
Ejemplo n.º 2
0
Archivo: cli.py Proyecto: sotnasf/lemur
def rotate(endpoint_name, new_certificate_name, old_certificate_name, message,
           commit):
    """
    Rotates an endpoint and reissues it if it has not already been replaced. If it has
    been replaced, will use the replacement certificate for the rotation.
    """
    if commit:
        print("[!] Running in COMMIT mode.")

    print("[+] Starting endpoint rotation.")

    try:
        old_cert = validate_certificate(old_certificate_name)
        new_cert = validate_certificate(new_certificate_name)
        endpoint = validate_endpoint(endpoint_name)

        if endpoint and new_cert:
            print("[+] Rotating endpoint: {0} to certificate {1}".format(
                endpoint.name, new_cert.name))
            request_rotation(endpoint, new_cert, message, commit)

        elif old_cert and new_cert:
            print("[+] Rotating all endpoints from {0} to {1}".format(
                old_cert.name, new_cert.name))

            for endpoint in old_cert.endpoints:
                print("[+] Rotating {0}".format(endpoint.name))
                request_rotation(endpoint, new_cert, message, commit)

        else:
            print(
                "[+] Rotating all endpoints that have new certificates available"
            )
            for endpoint in endpoint_service.get_all_pending_rotation():
                if len(endpoint.certificate.replaced) == 1:
                    print("[+] Rotating {0} to {1}".format(
                        endpoint.name, endpoint.certificate.replaced[0].name))
                    request_rotation(endpoint,
                                     endpoint.certificate.replaced[0], message,
                                     commit)
                else:
                    metrics.send('endpoint_rotation_failure', 'counter', 1)
                    print(
                        "[!] Failed to rotate endpoint {0} reason: Multiple replacement certificates found."
                        .format(endpoint.name))
        print("[+] Done!")
    except Exception as e:
        sentry.captureException()
Ejemplo n.º 3
0
Archivo: cli.py Proyecto: Netflix/lemur
def rotate(endpoint_name, new_certificate_name, old_certificate_name, message, commit):
    """
    Rotates an endpoint and reissues it if it has not already been replaced. If it has
    been replaced, will use the replacement certificate for the rotation.
    """
    if commit:
        print("[!] Running in COMMIT mode.")

    print("[+] Starting endpoint rotation.")

    status = FAILURE_METRIC_STATUS

    try:
        old_cert = validate_certificate(old_certificate_name)
        new_cert = validate_certificate(new_certificate_name)
        endpoint = validate_endpoint(endpoint_name)

        if endpoint and new_cert:
            print("[+] Rotating endpoint: {0} to certificate {1}".format(endpoint.name, new_cert.name))
            request_rotation(endpoint, new_cert, message, commit)

        elif old_cert and new_cert:
            print("[+] Rotating all endpoints from {0} to {1}".format(old_cert.name, new_cert.name))

            for endpoint in old_cert.endpoints:
                print("[+] Rotating {0}".format(endpoint.name))
                request_rotation(endpoint, new_cert, message, commit)

        else:
            print("[+] Rotating all endpoints that have new certificates available")
            for endpoint in endpoint_service.get_all_pending_rotation():
                if len(endpoint.certificate.replaced) == 1:
                    print("[+] Rotating {0} to {1}".format(endpoint.name, endpoint.certificate.replaced[0].name))
                    request_rotation(endpoint, endpoint.certificate.replaced[0], message, commit)
                else:
                    metrics.send('endpoint_rotation', 'counter', 1, metric_tags={'status': FAILURE_METRIC_STATUS})
                    print("[!] Failed to rotate endpoint {0} reason: Multiple replacement certificates found.".format(
                        endpoint.name
                    ))

        status = SUCCESS_METRIC_STATUS
        print("[+] Done!")

    except Exception as e:
        sentry.captureException()

    metrics.send('endpoint_rotation_job', 'counter', 1, metric_tags={'status': status})
Ejemplo n.º 4
0
def rotate_region(endpoint_name, new_certificate_name, old_certificate_name,
                  message, commit, region):
    """
    Rotates an endpoint in a defined region it if it has not already been replaced. If it has
    been replaced, will use the replacement certificate for the rotation.
    :param old_certificate_name: Name of the certificate you wish to rotate.
    :param new_certificate_name: Name of the certificate you wish to rotate to.
    :param endpoint_name: Name of the endpoint you wish to rotate.
    :param message: Send a rotation notification to the certificates owner.
    :param commit: Persist changes.
    :param region: Region in which to rotate the endpoint.
    """
    if commit:
        print("[!] Running in COMMIT mode.")

    print("[+] Starting endpoint rotation.")
    status = FAILURE_METRIC_STATUS

    log_data = {
        "function": f"{__name__}.{sys._getframe().f_code.co_name}",
        "region": region,
    }

    try:
        old_cert = validate_certificate(old_certificate_name)
        new_cert = validate_certificate(new_certificate_name)
        endpoint = validate_endpoint(endpoint_name)

        if endpoint and new_cert:
            log_data["endpoint"] = endpoint.dnsname
            log_data["certificate"] = new_cert.name
            request_rotation_region(endpoint, new_cert, message, commit,
                                    log_data, region)

        elif old_cert and new_cert:
            log_data["certificate"] = new_cert.name
            log_data["certificate_old"] = old_cert.name
            log_data["message"] = "Rotating endpoint from old to new cert"
            print(log_data)
            current_app.logger.info(log_data)
            for endpoint in old_cert.endpoints:
                log_data["endpoint"] = endpoint.dnsname
                request_rotation_region(endpoint, new_cert, message, commit,
                                        log_data, region)

        else:
            log_data[
                "message"] = "Rotating all endpoints that have new certificates available"
            print(log_data)
            current_app.logger.info(log_data)
            all_pending_rotation_endpoints = endpoint_service.get_all_pending_rotation(
            )
            for endpoint in all_pending_rotation_endpoints:
                log_data["endpoint"] = endpoint.dnsname
                if region not in endpoint.dnsname:
                    log_data["message"] = "Skipping rotation, region mismatch"
                    print(log_data)
                    current_app.logger.info(log_data)
                    metrics.send(
                        "endpoint_rotation_region_skipped",
                        "counter",
                        1,
                        metric_tags={
                            "region":
                            region,
                            "old_certificate_name":
                            str(old_cert),
                            "new_certificate_name":
                            str(endpoint.certificate.replaced[0].name),
                            "endpoint_name":
                            str(endpoint.dnsname),
                        },
                    )

                if len(endpoint.certificate.replaced) == 1:
                    log_data["certificate"] = endpoint.certificate.replaced[
                        0].name
                    log_data["message"] = "Rotating all endpoints in region"
                    print(log_data)
                    current_app.logger.info(log_data)
                    request_rotation(endpoint,
                                     endpoint.certificate.replaced[0], message,
                                     commit)
                    status = SUCCESS_METRIC_STATUS
                else:
                    status = FAILURE_METRIC_STATUS
                    log_data[
                        "message"] = "Failed to rotate endpoint due to Multiple replacement certificates found"
                    print(log_data)
                    current_app.logger.info(log_data)

                metrics.send(
                    "endpoint_rotation_region",
                    "counter",
                    1,
                    metric_tags={
                        "status":
                        FAILURE_METRIC_STATUS,
                        "old_certificate_name":
                        str(old_cert),
                        "new_certificate_name":
                        str(endpoint.certificate.replaced[0].name),
                        "endpoint_name":
                        str(endpoint.dnsname),
                        "message":
                        str(message),
                        "region":
                        str(region),
                    },
                )
        status = SUCCESS_METRIC_STATUS
        print("[+] Done!")

    except Exception as e:
        sentry.captureException(
            extra={
                "old_certificate_name": str(old_certificate_name),
                "new_certificate_name": str(new_certificate_name),
                "endpoint": str(endpoint_name),
                "message": str(message),
                "region": str(region),
            })

    metrics.send(
        "endpoint_rotation_region_job",
        "counter",
        1,
        metric_tags={
            "status": status,
            "old_certificate_name": str(old_certificate_name),
            "new_certificate_name": str(new_certificate_name),
            "endpoint_name": str(endpoint_name),
            "message": str(message),
            "endpoint": str(globals().get("endpoint")),
            "region": str(region),
        },
    )
Ejemplo n.º 5
0
def rotate(endpoint_name, new_certificate_name, old_certificate_name, message,
           commit):
    """
    Rotates an endpoint and reissues it if it has not already been replaced. If it has
    been replaced, will use the replacement certificate for the rotation.
    """
    if commit:
        print("[!] Running in COMMIT mode.")

    print("[+] Starting endpoint rotation.")

    status = FAILURE_METRIC_STATUS

    log_data = {
        "function": f"{__name__}.{sys._getframe().f_code.co_name}",
    }

    try:
        old_cert = validate_certificate(old_certificate_name)
        new_cert = validate_certificate(new_certificate_name)
        endpoint = validate_endpoint(endpoint_name)

        if endpoint and new_cert:
            print(
                f"[+] Rotating endpoint: {endpoint.name} to certificate {new_cert.name}"
            )
            log_data["message"] = "Rotating endpoint"
            log_data["endpoint"] = endpoint.dnsname
            log_data["certificate"] = new_cert.name
            request_rotation(endpoint, new_cert, message, commit)
            current_app.logger.info(log_data)

        elif old_cert and new_cert:
            print(
                f"[+] Rotating all endpoints from {old_cert.name} to {new_cert.name}"
            )

            log_data["message"] = "Rotating all endpoints"
            log_data["certificate"] = new_cert.name
            log_data["certificate_old"] = old_cert.name
            log_data["message"] = "Rotating endpoint from old to new cert"
            for endpoint in old_cert.endpoints:
                print(f"[+] Rotating {endpoint.name}")
                log_data["endpoint"] = endpoint.dnsname
                request_rotation(endpoint, new_cert, message, commit)
                current_app.logger.info(log_data)

        else:
            print(
                "[+] Rotating all endpoints that have new certificates available"
            )
            log_data[
                "message"] = "Rotating all endpoints that have new certificates available"
            for endpoint in endpoint_service.get_all_pending_rotation():
                log_data["endpoint"] = endpoint.dnsname
                if len(endpoint.certificate.replaced) == 1:
                    print(
                        f"[+] Rotating {endpoint.name} to {endpoint.certificate.replaced[0].name}"
                    )
                    log_data["certificate"] = endpoint.certificate.replaced[
                        0].name
                    request_rotation(endpoint,
                                     endpoint.certificate.replaced[0], message,
                                     commit)
                    current_app.logger.info(log_data)

                else:
                    log_data[
                        "message"] = "Failed to rotate endpoint due to Multiple replacement certificates found"
                    print(log_data)
                    metrics.send(
                        "endpoint_rotation",
                        "counter",
                        1,
                        metric_tags={
                            "status":
                            FAILURE_METRIC_STATUS,
                            "old_certificate_name":
                            str(old_cert),
                            "new_certificate_name":
                            str(endpoint.certificate.replaced[0].name),
                            "endpoint_name":
                            str(endpoint.name),
                            "message":
                            str(message),
                        },
                    )
                    print(
                        f"[!] Failed to rotate endpoint {endpoint.name} reason: "
                        "Multiple replacement certificates found.")

        status = SUCCESS_METRIC_STATUS
        print("[+] Done!")

    except Exception as e:
        sentry.captureException(
            extra={
                "old_certificate_name": str(old_certificate_name),
                "new_certificate_name": str(new_certificate_name),
                "endpoint_name": str(endpoint_name),
                "message": str(message),
            })

    metrics.send(
        "endpoint_rotation_job",
        "counter",
        1,
        metric_tags={
            "status": status,
            "old_certificate_name": str(old_certificate_name),
            "new_certificate_name": str(new_certificate_name),
            "endpoint_name": str(endpoint_name),
            "message": str(message),
            "endpoint": str(globals().get("endpoint")),
        },
    )
Ejemplo n.º 6
0
def rotate(endpoint_name, new_certificate_name, old_certificate_name, message,
           commit):
    """
    Rotates an endpoint and reissues it if it has not already been replaced. If it has
    been replaced, will use the replacement certificate for the rotation.
    """
    if commit:
        print("[!] Running in COMMIT mode.")

    print("[+] Starting endpoint rotation.")

    status = FAILURE_METRIC_STATUS

    try:
        old_cert = validate_certificate(old_certificate_name)
        new_cert = validate_certificate(new_certificate_name)
        endpoint = validate_endpoint(endpoint_name)

        if endpoint and new_cert:
            print(
                f"[+] Rotating endpoint: {endpoint.name} to certificate {new_cert.name}"
            )
            request_rotation(endpoint, new_cert, message, commit)

        elif old_cert and new_cert:
            print(
                f"[+] Rotating all endpoints from {old_cert.name} to {new_cert.name}"
            )

            for endpoint in old_cert.endpoints:
                print(f"[+] Rotating {endpoint.name}")
                request_rotation(endpoint, new_cert, message, commit)

        else:
            print(
                "[+] Rotating all endpoints that have new certificates available"
            )
            for endpoint in endpoint_service.get_all_pending_rotation():
                if len(endpoint.certificate.replaced) == 1:
                    print(
                        f"[+] Rotating {endpoint.name} to {endpoint.certificate.replaced[0].name}"
                    )
                    request_rotation(endpoint,
                                     endpoint.certificate.replaced[0], message,
                                     commit)
                else:
                    metrics.send(
                        "endpoint_rotation",
                        "counter",
                        1,
                        metric_tags={
                            "status":
                            FAILURE_METRIC_STATUS,
                            "old_certificate_name":
                            str(old_cert),
                            "new_certificate_name":
                            str(endpoint.certificate.replaced[0].name),
                            "endpoint_name":
                            str(endpoint.name),
                            "message":
                            str(message),
                        },
                    )
                    print(
                        f"[!] Failed to rotate endpoint {endpoint.name} reason: "
                        "Multiple replacement certificates found.")

        status = SUCCESS_METRIC_STATUS
        print("[+] Done!")

    except Exception as e:
        sentry.captureException(
            extra={
                "old_certificate_name": str(old_certificate_name),
                "new_certificate_name": str(new_certificate_name),
                "endpoint_name": str(endpoint_name),
                "message": str(message),
            })

    metrics.send(
        "endpoint_rotation_job",
        "counter",
        1,
        metric_tags={
            "status": status,
            "old_certificate_name": str(old_certificate_name),
            "new_certificate_name": str(new_certificate_name),
            "endpoint_name": str(endpoint_name),
            "message": str(message),
            "endpoint": str(globals().get("endpoint")),
        },
    )
Ejemplo n.º 7
0
def rotate(endpoint_name, new_certificate_name, old_certificate_name, message,
           commit):
    """
    Rotates an endpoint and reissues it if it has not already been replaced. If it has
    been replaced, will use the replacement certificate for the rotation.
    """
    if commit:
        print("[!] Running in COMMIT mode.")

    print("[+] Starting endpoint rotation.")

    status = FAILURE_METRIC_STATUS

    log_data = {
        "function": f"{__name__}.{sys._getframe().f_code.co_name}",
    }

    try:
        old_cert = validate_certificate(old_certificate_name)
        new_cert = validate_certificate(new_certificate_name)
        endpoint = validate_endpoint(endpoint_name)

        if endpoint and new_cert:
            print(
                f"[+] Rotating endpoint: {endpoint.name} to certificate {new_cert.name}"
            )
            log_data["message"] = "Rotating one endpoint"
            log_data["endpoint"] = endpoint.dnsname
            log_data["certificate"] = new_cert.name
            request_rotation(endpoint, new_cert, message, commit)
            current_app.logger.info(log_data)

        elif old_cert and new_cert:
            print(
                f"[+] Rotating all endpoints from {old_cert.name} to {new_cert.name}"
            )
            log_data["certificate"] = new_cert.name
            log_data["certificate_old"] = old_cert.name
            log_data["message"] = "Rotating endpoint from old to new cert"
            for endpoint in old_cert.endpoints:
                print(f"[+] Rotating {endpoint.name}")
                log_data["endpoint"] = endpoint.dnsname
                request_rotation(endpoint, new_cert, message, commit)
                current_app.logger.info(log_data)

        else:
            # No certificate name or endpoint is provided. We will now fetch all endpoints,
            # which are associated with a certificate that has been replaced
            print(
                "[+] Rotating all endpoints that have new certificates available"
            )
            for endpoint in endpoint_service.get_all_pending_rotation():

                log_data["message"] = "Rotating endpoint from old to new cert"
                if len(endpoint.certificate.replaced) > 1:
                    log_data["message"] = f"Multiple replacement certificates found, going with the first one out of " \
                                          f"{len(endpoint.certificate.replaced)}"

                log_data["endpoint"] = endpoint.dnsname
                log_data["certificate"] = endpoint.certificate.replaced[0].name
                print(
                    f"[+] Rotating {endpoint.name} to {endpoint.certificate.replaced[0].name}"
                )
                request_rotation(endpoint, endpoint.certificate.replaced[0],
                                 message, commit)
                current_app.logger.info(log_data)

        status = SUCCESS_METRIC_STATUS
        print("[+] Done!")

    except Exception as e:
        capture_exception(
            extra={
                "old_certificate_name": str(old_certificate_name),
                "new_certificate_name": str(new_certificate_name),
                "endpoint_name": str(endpoint_name),
                "message": str(message),
            })

    metrics.send(
        "endpoint_rotation_job",
        "counter",
        1,
        metric_tags={
            "status": status,
            "old_certificate_name": str(old_certificate_name),
            "new_certificate_name": str(new_certificate_name),
            "endpoint_name": str(endpoint_name),
            "message": str(message),
            "endpoint": str(globals().get("endpoint")),
        },
    )