Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions test/e2e/cert_manager_deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import (
)

const (
PollInterval = time.Second
PollInterval = 5 * time.Second
TestTimeout = 10 * time.Minute
)

Expand All @@ -42,9 +42,9 @@ func TestSelfSignedCerts(t *testing.T) {
ctx := context.Background()
loader := library.NewDynamicResourceLoader(ctx, t)

ns, err := loader.CreateTestingNS("e2e-self-signed-cert")
ns, err := loader.CreateTestingNS("e2e-self-signed-cert", false)
require.NoError(t, err)
defer loader.DeleteTestingNS(ns.Name)
defer loader.DeleteTestingNS(ns.Name, t.Failed)
loader.CreateFromFile(testassets.ReadFile, filepath.Join("testdata", "self_signed", "cluster_issuer.yaml"), ns.Name)
defer loader.DeleteFromFile(testassets.ReadFile, filepath.Join("testdata", "self_signed", "cluster_issuer.yaml"), ns.Name)
loader.CreateFromFile(testassets.ReadFile, filepath.Join("testdata", "self_signed", "issuer.yaml"), ns.Name)
Expand Down Expand Up @@ -73,9 +73,9 @@ func TestACMECertsIngress(t *testing.T) {
config, err := library.GetConfigForTest(t)
require.NoError(t, err)

ns, err := loader.CreateTestingNS("e2e-acme-ingress-cert")
ns, err := loader.CreateTestingNS("e2e-acme-ingress-cert", false)
require.NoError(t, err)
defer loader.DeleteTestingNS(ns.Name)
defer loader.DeleteTestingNS(ns.Name, t.Failed)
loader.CreateFromFile(testassets.ReadFile, filepath.Join("testdata", "acme", "clusterissuer.yaml"), ns.Name)
defer loader.DeleteFromFile(testassets.ReadFile, filepath.Join("testdata", "acme", "clusterissuer.yaml"), ns.Name)
loader.CreateFromFile(testassets.ReadFile, filepath.Join("testdata", "acme", "deployment.yaml"), ns.Name)
Expand Down Expand Up @@ -159,9 +159,9 @@ func TestCertRenew(t *testing.T) {
config, err := library.GetConfigForTest(t)
require.NoErrorf(t, err, "failed to fetch host configuration: %v", err)

ns, err := loader.CreateTestingNS("e2e-cert-renew")
ns, err := loader.CreateTestingNS("e2e-cert-renew", false)
require.NoErrorf(t, err, "failed to create namespace: %v", err)
defer loader.DeleteTestingNS(ns.Name)
defer loader.DeleteTestingNS(ns.Name, t.Failed)
loader.CreateFromFile(testassets.ReadFile, filepath.Join("testdata", "self_signed", "cluster_issuer.yaml"), ns.Name)
defer loader.DeleteFromFile(testassets.ReadFile, filepath.Join("testdata", "self_signed", "cluster_issuer.yaml"), ns.Name)
loader.CreateFromFile(testassets.ReadFile, filepath.Join("testdata", "self_signed", "issuer.yaml"), ns.Name)
Expand Down
209 changes: 139 additions & 70 deletions test/e2e/certificates_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package e2e

import (
"context"
"fmt"
"os"
"path/filepath"
"time"
Expand Down Expand Up @@ -34,6 +35,7 @@ const (

var _ = Describe("ACME Certificate", Ordered, func() {
var ctx context.Context
var ns *corev1.Namespace
var appsDomain string
var baseDomain string

Expand Down Expand Up @@ -71,16 +73,20 @@ var _ = Describe("ACME Certificate", Ordered, func() {
certManagerCAInjectorDeploymentControllerName},
validOperatorStatusConditions)
Expect(err).NotTo(HaveOccurred(), "Operator is expected to be available")

By("creating a test namespace")
namespace, err := loader.CreateTestingNS("e2e-acme-certs", false)
Expect(err).NotTo(HaveOccurred())
ns = namespace

DeferCleanup(func() {
loader.DeleteTestingNS(ns.Name, func() bool { return CurrentSpecReport().Failed() })
})
})

Context("dns-01 challenge with AWS Route53", Label("Platform:AWS"), func() {
It("should obtain a valid LetsEncrypt certificate using explicit credentials", func() {

By("creating a test namespace")
ns, err := loader.CreateTestingNS("e2e-acme-explicit-dns01")
Expect(err).NotTo(HaveOccurred())
defer loader.DeleteTestingNS(ns.Name)

By("obtaining AWS credentials from kube-system namespace")
awsCredsSecret, err := loader.KubeClient.CoreV1().Secrets("kube-system").Get(ctx, "aws-creds", metav1.GetOptions{})
Expect(err).NotTo(HaveOccurred())
Expand Down Expand Up @@ -185,16 +191,11 @@ var _ = Describe("ACME Certificate", Ordered, func() {

It("should obtain a valid LetsEncrypt certificate using ambient credentials with ClusterIssuer", func() {

By("creating a test namespace")
ns, err := loader.CreateTestingNS("e2e-acme-ambient-dns01")
Expect(err).NotTo(HaveOccurred())
defer loader.DeleteTestingNS(ns.Name)

By("creating CredentialsRequest object")
loader.CreateFromFile(testassets.ReadFile, filepath.Join("testdata", "credentials", "credentialsrequest_aws.yaml"), "")

By("waiting for cloud secret to be available")
err = wait.PollImmediate(PollInterval, TestTimeout, func() (bool, error) {
err := wait.PollImmediate(PollInterval, TestTimeout, func() (bool, error) {
_, err := loader.KubeClient.CoreV1().Secrets("cert-manager").Get(ctx, "aws-creds", metav1.GetOptions{})
if err != nil {
return false, nil
Expand Down Expand Up @@ -282,16 +283,11 @@ var _ = Describe("ACME Certificate", Ordered, func() {

It("should obtain a valid LetsEncrypt certificate using ambient credentials with Issuer", func() {

By("creating a test namespace")
ns, err := loader.CreateTestingNS("e2e-acme-issuer-ambient-dns01-aws")
Expect(err).NotTo(HaveOccurred())
defer loader.DeleteTestingNS(ns.Name)

By("creating CredentialsRequest object")
loader.CreateFromFile(testassets.ReadFile, filepath.Join("testdata", "credentials", "credentialsrequest_aws.yaml"), "")

By("waiting for cloud secret to be available")
err = wait.PollImmediate(PollInterval, TestTimeout, func() (bool, error) {
err := wait.PollImmediate(PollInterval, TestTimeout, func() (bool, error) {
_, err := loader.KubeClient.CoreV1().Secrets("cert-manager").Get(ctx, "aws-creds", metav1.GetOptions{})
if err != nil {
return false, nil
Expand Down Expand Up @@ -381,20 +377,116 @@ var _ = Describe("ACME Certificate", Ordered, func() {
})

Context("dns-01 challenge with Google CloudDNS", Label("Platform:GCP"), func() {
It("should obtain a valid LetsEncrypt certificate using ambient credentials with ClusterIssuer", func() {
It("should obtain a valid LetsEncrypt certificate using explicit credentials with ClusterIssuer", func() {

By("Creating a test namespace")
ns, err := loader.CreateTestingNS("e2e-acme-ambient-dns01")
By("obtaining GCP credentials from kube-system namespace")
gcpCredsSecret, err := loader.KubeClient.CoreV1().Secrets("kube-system").Get(ctx, "gcp-credentials", metav1.GetOptions{})
Expect(err).NotTo(HaveOccurred())
defer loader.DeleteTestingNS(ns.Name)
gcpServiceAccount := gcpCredsSecret.Data["service_account.json"]

By("copying GCP secret service account to test namespace")
secretName := "gcp-secret"
secretKey := "gcp_service_account_key.json"
gcpSecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: secretName,
Namespace: ns.Name,
},
Data: map[string][]byte{
secretKey: gcpServiceAccount,
},
}
_, err = loader.KubeClient.CoreV1().Secrets(ns.Name).Create(ctx, gcpSecret, metav1.CreateOptions{})
Expect(err).NotTo(HaveOccurred())

By("getting GCP project ID from Infrastructure object")
infra, err := configClient.Infrastructures().Get(ctx, "cluster", metav1.GetOptions{})
Expect(err).NotTo(HaveOccurred())

gcpProjectID := infra.Status.PlatformStatus.GCP.ProjectID
Expect(gcpProjectID).NotTo(Equal(""))

By("creating new certificate Issuer")
issuerName := "letsencrypt-dns01"
issuer := &certmanagerv1.Issuer{
ObjectMeta: metav1.ObjectMeta{
Name: issuerName,
Namespace: ns.Name,
},
Spec: certmanagerv1.IssuerSpec{
IssuerConfig: certmanagerv1.IssuerConfig{
ACME: &v1.ACMEIssuer{
Server: "https://acme-staging-v02.api.letsencrypt.org/directory",
PrivateKey: certmanagermetav1.SecretKeySelector{
LocalObjectReference: certmanagermetav1.LocalObjectReference{
Name: "letsencrypt-dns01-issuer",
},
},
Solvers: []v1.ACMEChallengeSolver{
{
DNS01: &v1.ACMEChallengeSolverDNS01{
CloudDNS: &v1.ACMEIssuerDNS01ProviderCloudDNS{
Project: string(gcpProjectID),
ServiceAccount: &certmanagermetav1.SecretKeySelector{
LocalObjectReference: certmanagermetav1.LocalObjectReference{
Name: secretName,
},
Key: secretKey,
},
},
},
},
},
},
},
},
}
_, err = certmanagerClient.CertmanagerV1().Issuers(ns.Name).Create(ctx, issuer, metav1.CreateOptions{})
Expect(err).NotTo(HaveOccurred())
defer certmanagerClient.CertmanagerV1().Issuers(ns.Name).Delete(ctx, issuerName, metav1.DeleteOptions{})

By("creating new certificate")
randomString := randomStr(3)
certDomain := randomString + "." + appsDomain
certName := "letsencrypt-cert"
cert := &certmanagerv1.Certificate{
ObjectMeta: metav1.ObjectMeta{
Name: certName,
Namespace: ns.Name,
},
Spec: certmanagerv1.CertificateSpec{
IsCA: false,
CommonName: certDomain,
SecretName: certName,
DNSNames: []string{certDomain},
IssuerRef: certmanagermetav1.ObjectReference{
Name: issuerName,
Kind: "Issuer",
},
},
}
_, err = certmanagerClient.CertmanagerV1().Certificates(ns.Name).Create(ctx, cert, metav1.CreateOptions{})
Expect(err).NotTo(HaveOccurred())
defer certmanagerClient.CertmanagerV1().Certificates(ns.Name).Delete(ctx, certName, metav1.DeleteOptions{})

By("waiting for certificate to get ready")
err = waitForCertificateReadiness(ctx, certName, ns.Name)
Expect(err).NotTo(HaveOccurred())

By("checking for certificate validity from secret contents")
err = verifyCertificate(ctx, certName, ns.Name, certDomain)
Expect(err).NotTo(HaveOccurred())
})

It("should obtain a valid LetsEncrypt certificate using ambient credentials with ClusterIssuer", func() {

By("Creating CredentialsRequest object")
loader.CreateFromFile(testassets.ReadFile, filepath.Join("testdata", "credentials", "credentialsrequest_gcp.yaml"), "")

By("Waiting for cloud secret to be available")
// The name is defined cloud credential by the testdata YAML file.
credentialSecret := "gcp-credentials"
err = wait.PollImmediate(PollInterval, TestTimeout, func() (bool, error) {
err := wait.PollImmediate(PollInterval, TestTimeout, func() (bool, error) {
_, err := loader.KubeClient.CoreV1().Secrets("cert-manager").Get(ctx, credentialSecret, metav1.GetOptions{})
if err != nil {
return false, nil
Expand All @@ -417,29 +509,22 @@ var _ = Describe("ACME Certificate", Ordered, func() {
By("Creating new certificate ClusterIssuer")
// The name is defined by the testdata YAML file clusterissuer_gcp.yaml
clusterIssuerName := "acme-dns01-clouddns-ambient"
replaceStrMap := map[string]string{
"PROJECT_ID": gcpProjectId,
}
loadFileAndReplaceStr := func(fileName string) ([]byte, error) {
fileContentsStr, err := replaceStrInFile(replaceStrMap, fileName)
return []byte(fileContentsStr), err
}
loader.CreateFromFile(loadFileAndReplaceStr, filepath.Join("testdata", "acme", "clusterissuer_gcp.yaml"), "")
loader.CreateFromFile(AssetFunc(testassets.ReadFile).WithTemplateValues(
IssuerConfig{
GCPProjectID: gcpProjectId,
},
), filepath.Join("testdata", "acme", "clusterissuer_gcp.yaml"), "")
defer certmanagerClient.CertmanagerV1().ClusterIssuers().Delete(ctx, clusterIssuerName, metav1.DeleteOptions{})

By("Creating new certificate")
randomString := randomStr(3)
replaceStrMap = map[string]string{
"RANDOM_STR": randomString,
"DNS_NAME": baseDomain,
}
loadFileAndReplaceStr = func(fileName string) ([]byte, error) {
fileContentsStr, err := replaceStrInFile(replaceStrMap, fileName)
return []byte(fileContentsStr), err
}
// The name is defined by the testdata YAML file certificate_gcp.yaml
certName := "cert-with-acme-dns01-clouddns-ambient"
loader.CreateFromFile(loadFileAndReplaceStr, filepath.Join("testdata", "acme", "certificate_gcp.yaml"), ns.Name)
loader.CreateFromFile(AssetFunc(testassets.ReadFile).WithTemplateValues(
CertificateConfig{
DNSName: fmt.Sprintf("%s.%s", randomString, baseDomain),
},
), filepath.Join("testdata", "acme", "certificate_gcp.yaml"), ns.Name)

By("Waiting for certificate to get ready")
err = waitForCertificateReadiness(ctx, certName, ns.Name)
Expand All @@ -465,40 +550,29 @@ var _ = Describe("ACME Certificate", Ordered, func() {
Skip("skipping as the cluster does not use IBM Cloud CIS")
}

By("creating a test namespace")
ns, err := loader.CreateTestingNS("e2e-acme-explicit-dns01-ibmcloud")
Expect(err).NotTo(HaveOccurred())
defer loader.DeleteTestingNS(ns.Name)

By("creating new certificate ClusterIssuer with IBM Cloud CIS webhook solver")
randomString := randomStr(3)
clusterIssuerName := "letsencrypt-dns01-explicit-ic"
replaceStrMap := map[string]string{
"CIS_CRN": cisCRN,
}
loadFileAndReplaceStr := func(fileName string) ([]byte, error) {
fileContentsStr, err := replaceStrInFile(replaceStrMap, fileName)
return []byte(fileContentsStr), err
}
loader.CreateFromFile(loadFileAndReplaceStr, filepath.Join("testdata", "acme", "clusterissuer_ibmcis.yaml"), "")
loader.CreateFromFile(AssetFunc(testassets.ReadFile).WithTemplateValues(
IssuerConfig{
IBMCloudCISCRN: cisCRN,
},
), filepath.Join("testdata", "acme", "clusterissuer_ibmcis.yaml"), "")
defer certmanagerClient.CertmanagerV1().ClusterIssuers().Delete(ctx, clusterIssuerName, metav1.DeleteOptions{})

By("creating new certificate")
// The name is defined by the testdata YAML file certificate_ibmcis.yaml
certDomain := "adwie." + appsDomain // acronym for "ACME dns-01 ibmcloud Webhook Explicit", short naming to pass dns name validation
certName := "letsencrypt-cert-ic"
replaceStrMap = map[string]string{
"RANDOM_STR": randomString,
"DNS_NAME": certDomain,
}
loadFileAndReplaceStr = func(fileName string) ([]byte, error) {
fileContentsStr, err := replaceStrInFile(replaceStrMap, fileName)
return []byte(fileContentsStr), err
}
loader.CreateFromFile(loadFileAndReplaceStr, filepath.Join("testdata", "acme", "certificate_ibmcis.yaml"), ns.Name)
loader.CreateFromFile(
AssetFunc(testassets.ReadFile).WithTemplateValues(
CertificateConfig{
DNSName: certDomain,
},
), filepath.Join("testdata", "acme", "certificate_ibmcis.yaml"), ns.Name)

By("waiting for certificate to get ready")
err = waitForCertificateReadiness(ctx, certName, ns.Name)
err := waitForCertificateReadiness(ctx, certName, ns.Name)
Expect(err).NotTo(HaveOccurred())

By("checking for certificate validity from secret contents")
Expand All @@ -510,11 +584,6 @@ var _ = Describe("ACME Certificate", Ordered, func() {
Context("http-01 challenge using ingress", func() {
It("should obtain a valid LetsEncrypt certificate", func() {

By("creating a test namespace")
ns, err := loader.CreateTestingNS("e2e-acme-explicit-dns01")
Expect(err).NotTo(HaveOccurred())
defer loader.DeleteTestingNS(ns.Name)

By("creating a cluster issuer")
loader.CreateFromFile(testassets.ReadFile, filepath.Join("testdata", "acme", "clusterissuer.yaml"), ns.Name)
defer loader.DeleteFromFile(testassets.ReadFile, filepath.Join("testdata", "acme", "clusterissuer.yaml"), ns.Name)
Expand Down Expand Up @@ -567,7 +636,7 @@ var _ = Describe("ACME Certificate", Ordered, func() {
}},
},
}
ingress, err = loader.KubeClient.NetworkingV1().Ingresses(ingress.ObjectMeta.Namespace).Create(ctx, ingress, metav1.CreateOptions{})
ingress, err := loader.KubeClient.NetworkingV1().Ingresses(ingress.ObjectMeta.Namespace).Create(ctx, ingress, metav1.CreateOptions{})
Expect(err).NotTo(HaveOccurred())
defer loader.KubeClient.NetworkingV1().Ingresses(ingress.ObjectMeta.Namespace).Delete(ctx, ingress.ObjectMeta.Name, metav1.DeleteOptions{})

Expand Down Expand Up @@ -602,12 +671,12 @@ var _ = Describe("Self-signed Certificate", Ordered, func() {
ctx = context.Background()

By("creating a test namespace")
namespace, err := loader.CreateTestingNS("e2e-self-signed-certs")
namespace, err := loader.CreateTestingNS("e2e-self-signed-certs", false)
Expect(err).NotTo(HaveOccurred())
ns = namespace

DeferCleanup(func() {
loader.DeleteTestingNS(ns.Name)
loader.DeleteTestingNS(ns.Name, func() bool { return CurrentSpecReport().Failed() })
})
})

Expand Down
Loading