def get_ordered_certificates()

in lemur/plugins/lemur_acme/plugin.py [0:0]


    def get_ordered_certificates(self, pending_certs):
        self.acme = AcmeDnsHandler()
        self.acme_dns_challenge = AcmeDnsChallenge()
        pending = []
        certs = []
        for pending_cert in pending_certs:
            try:
                acme_client, registration = self.acme.setup_acme_client(
                    pending_cert.authority
                )
                order_info = authorization_service.get(pending_cert.external_id)
                if pending_cert.dns_provider_id:
                    dns_provider = dns_provider_service.get(
                        pending_cert.dns_provider_id
                    )

                    for domain in order_info.domains:
                        # Currently, we only support specifying one DNS provider per certificate, even if that
                        # certificate has multiple SANs that may belong to different providers.
                        self.acme.dns_providers_for_domain[domain] = [dns_provider]
                else:
                    for domain in order_info.domains:
                        self.acme.autodetect_dns_providers(domain)

                try:
                    order = acme_client.new_order(pending_cert.csr)
                except WildcardUnsupportedError:
                    sentry.captureException()
                    metrics.send(
                        "get_ordered_certificates_wildcard_unsupported_error",
                        "counter",
                        1,
                    )
                    raise Exception(
                        "The currently selected ACME CA endpoint does"
                        " not support issuing wildcard certificates."
                    )

                authorizations = self.acme.get_authorizations(
                    acme_client, order, order_info
                )

                pending.append(
                    {
                        "acme_client": acme_client,
                        "authorizations": authorizations,
                        "pending_cert": pending_cert,
                        "order": order,
                    }
                )
            except (ClientError, ValueError, Exception) as e:
                sentry.captureException()
                metrics.send(
                    "get_ordered_certificates_pending_creation_error", "counter", 1
                )
                current_app.logger.error(
                    f"Unable to resolve pending cert: {pending_cert}", exc_info=True
                )

                error = e
                if globals().get("order") and order:
                    error += f" Order uri: {order.uri}"
                certs.append(
                    {"cert": False, "pending_cert": pending_cert, "last_error": e}
                )

        for entry in pending:
            try:
                entry["authorizations"] = self.acme.finalize_authorizations(
                    entry["acme_client"], entry["authorizations"]
                )
                pem_certificate, pem_certificate_chain = self.acme.request_certificate(
                    entry["acme_client"], entry["authorizations"], entry["order"]
                )

                cert = {
                    "body": "\n".join(str(pem_certificate).splitlines()),
                    "chain": "\n".join(str(pem_certificate_chain).splitlines()),
                    "external_id": str(entry["pending_cert"].external_id),
                }
                certs.append({"cert": cert, "pending_cert": entry["pending_cert"]})
            except (PollError, AcmeError, Exception) as e:
                sentry.captureException()
                metrics.send("get_ordered_certificates_resolution_error", "counter", 1)
                order_url = order.uri
                error = f"{e}. Order URI: {order_url}"
                current_app.logger.error(
                    f"Unable to resolve pending cert: {pending_cert}. "
                    f"Check out {order_url} for more information.",
                    exc_info=True,
                )
                certs.append(
                    {
                        "cert": False,
                        "pending_cert": entry["pending_cert"],
                        "last_error": error,
                    }
                )
                # Ensure DNS records get deleted
                self.acme_dns_challenge.cleanup(
                    entry["authorizations"], entry["acme_client"]
                )
        return certs