From eef701d38cb041b35ee2d1bebb3ff4a8b1c22cf9 Mon Sep 17 00:00:00 2001 From: Emanuele Libralato Date: Tue, 12 Nov 2019 22:55:15 +0100 Subject: [PATCH] fix: displaced/wrong logging when setting up cert-manager Fix the cert-manager logger appearing when the certManager.install property was set to "false". Bonus: fix triggering the creation of certificates when cert-manager is not installed even if no certificates managed by cert-manager are present in the config. --- docs/guides/cert-manager-integration.md | 1 + .../kubernetes/integrations/cert-manager.ts | 151 ++++++++++-------- 2 files changed, 83 insertions(+), 69 deletions(-) diff --git a/docs/guides/cert-manager-integration.md b/docs/guides/cert-manager-integration.md index aea90d2a9a..e54b2a5c30 100644 --- a/docs/guides/cert-manager-integration.md +++ b/docs/guides/cert-manager-integration.md @@ -48,6 +48,7 @@ To enable cert-manager, you'll need to configure it in the `kubernetes` provider ``` Unless you want to use your own installation of cert-manager, you will need to set the option `install: true`. Garden will then install cert-manager for you under the `cert-manager` namespace. +> Note: Garden will wait until all the pods required by cert-manager will be up and running. This might take more than 2 minutes depending on the cluster. If nothing is specified or `install: false`, Garden will assume you already have a valid and running cert-manager installation in the `cert-manager` namespace. diff --git a/garden-service/src/plugins/kubernetes/integrations/cert-manager.ts b/garden-service/src/plugins/kubernetes/integrations/cert-manager.ts index 9192aa7d8e..d9ef015a0a 100644 --- a/garden-service/src/plugins/kubernetes/integrations/cert-manager.ts +++ b/garden-service/src/plugins/kubernetes/integrations/cert-manager.ts @@ -197,81 +197,94 @@ export interface SetupCertManagerParams { * @param {SetupCertManagerParams} { ctx, provider, log, status } */ export async function setupCertManager({ ctx, provider, log, status }: SetupCertManagerParams) { - const entry = log.info({ - section: "cert-manager", - msg: `Installing to cert-manager namespace...`, - status: "active", - }) + const { systemCertManagerReady, systemManagedCertificatesReady } = status.detail + + if (!systemCertManagerReady || !systemManagedCertificatesReady) { + const entry = log.info({ + section: "cert-manager", + msg: `Verifying installation...`, + status: "active", + }) - if (!status.detail.systemCertManagerReady) { - const api = await KubeApi.factory(log, provider) - await ensureNamespace(api, "cert-manager") - const customResourcesPath = join(STATIC_DIR, "kubernetes", "system", "cert-manager", "cert-manager-crd.yaml") - const crd = await yaml.safeLoadAll((await readFile(customResourcesPath)).toString()).filter((x) => x) - entry.setState("Installing Custom Resources...") - await apply({ log, provider, manifests: crd, validate: false }) - - const waitForCertManagerPods: WaitForResourcesParams = { - ctx, - provider, - log, - resources: [], - resourcesType: "cert-manager pods", - predicate: checkForCertManagerPodsReady, + if (!systemCertManagerReady) { + entry.setState("Installing to cert-manager namespace...") + const api = await KubeApi.factory(log, provider) + await ensureNamespace(api, "cert-manager") + const customResourcesPath = join(STATIC_DIR, "kubernetes", "system", "cert-manager", "cert-manager-crd.yaml") + const crd = await yaml.safeLoadAll((await readFile(customResourcesPath)).toString()).filter((x) => x) + entry.setState("Installing Custom Resources...") + await apply({ log, provider, manifests: crd, validate: false }) + + const waitForCertManagerPods: WaitForResourcesParams = { + ctx, + provider, + log: entry, + resources: [], + resourcesType: "cert-manager pods", + predicate: checkForCertManagerPodsReady, + } + await waitForResourcesWith(waitForCertManagerPods) + entry.setState("Custom Resources installed.") } - await waitForResourcesWith(waitForCertManagerPods) - entry.setState("Custom Resources installed.") - } - if (!status.detail.systemManagedCertificatesReady) { - entry.setState("Creating Issuers...") - const issuers: any[] = [] - const certificates: any[] = [] - const secretNames: string[] = [] - const namespace = provider.config.namespace || ctx.projectName - provider.config.tlsCertificates - .filter((cert) => cert.managedBy === "cert-manager") - .map((cert) => { - const tlsManager = provider.config.certManager - if (tlsManager) { - const serverType = tlsManager.acmeServer || "letsencrypt-staging" - const issuerName = `${cert.name}-${serverType}` - - const issuerManifest = getClusterIssuerFromTls({ - name: issuerName, - tlsManager, - tlsCertificate: cert, - }) - issuers.push(issuerManifest) - - const certManifest = getCertificateFromTls({ tlsManager, tlsCertificate: cert, issuerName }) - certificates.push(certManifest) - - secretNames.push(cert.secretRef.name) - } + if (!systemManagedCertificatesReady) { + const certsLog = entry.info({ + symbol: "info", + section: "TLS certificates", + msg: `Processing certificates...`, + status: "active", }) - - await apply({ log, provider, manifests: issuers }) - entry.setState("Issuers created.") - - await apply({ log, provider, manifests: certificates, namespace }) - entry.setState("Creating certificates...") - - const certificateNames = certificates.map((cert) => cert.metadata.name) - const waitForCertificatesParams: WaitForResourcesParams = { - ctx, - provider, - log, - resources: certificateNames, - resourcesType: "Certificates", - predicate: checkCertificateStatusByName, + const issuers: any[] = [] + const certificates: any[] = [] + const secretNames: string[] = [] + const namespace = provider.config.namespace || ctx.projectName + provider.config.tlsCertificates + .filter((cert) => cert.managedBy === "cert-manager") + .map((cert) => { + const tlsManager = provider.config.certManager + if (tlsManager) { + const serverType = tlsManager.acmeServer || "letsencrypt-staging" + const issuerName = `${cert.name}-${serverType}` + + const issuerManifest = getClusterIssuerFromTls({ + name: issuerName, + tlsManager, + tlsCertificate: cert, + }) + issuers.push(issuerManifest) + + const certManifest = getCertificateFromTls({ tlsManager, tlsCertificate: cert, issuerName }) + certificates.push(certManifest) + + secretNames.push(cert.secretRef.name) + } + }) + + if (issuers.length > 0) { + certsLog.setState("Creating Issuers...") + await apply({ log, provider, manifests: issuers }) + certsLog.setState("Issuers created.") + + await apply({ log, provider, manifests: certificates, namespace }) + certsLog.setState("Creating Certificates...") + + const certificateNames = certificates.map((cert) => cert.metadata.name) + const waitForCertificatesParams: WaitForResourcesParams = { + ctx, + provider, + log, + resources: certificateNames, + resourcesType: "Certificates", + predicate: checkCertificateStatusByName, + } + await waitForResourcesWith(waitForCertificatesParams) + certsLog.setState('Certificates created and "Ready"') + } else { + certsLog.setState("No certificates found...") + } } - await waitForResourcesWith(waitForCertificatesParams) - - entry.setState('Certificates created and "Ready"') + entry.setSuccess({ msg: chalk.green(`Done (took ${entry.getDuration(1)} sec)`), append: true }) } - - entry.setSuccess({ msg: chalk.green(`Done (took ${entry.getDuration(1)} sec)`), append: true }) } /**