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
11 changes: 9 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ TRUST_MANAGER_VERSION ?= v0.20.3

# --- Test Versions ---

# OpenShift Service Mesh versions for IstioCSR ServiceMesh e2e tests.
# Keep servicemesh_helpers_test.go ossmDefault* constants in sync when bumping.
E2E_OSM_ISTIO_VERSION ?= v1.24.3
E2E_OSM_OPERATOR_VERSION ?= 3.2.5

# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
ENVTEST_K8S_VERSION ?= 1.32.0

Expand Down Expand Up @@ -188,7 +193,7 @@ E2E_TIMEOUT ?= 2h
# E2E_GINKGO_LABEL_FILTER is ginkgo label query for selecting tests.
# See https://onsi.github.io/ginkgo/#spec-labels
# The default is to run tests on the AWS platform.
E2E_GINKGO_LABEL_FILTER ?= Platform: isSubsetOf {AWS,Generic} && CredentialsMode: isSubsetOf {Mint}
E2E_GINKGO_LABEL_FILTER ?= Platform: isSubsetOf {AWS,Generic} && CredentialsMode: isSubsetOf {Mint} && !Feature:ServiceMesh

# ============================================================================
# Default Target
Expand Down Expand Up @@ -279,6 +284,8 @@ test-apis: $(SETUP_ENVTEST) $(GINKGO)
TEST ?=
.PHONY: test-e2e
test-e2e: test-e2e-wait-for-stable-state ## Run end-to-end tests.
E2E_OSM_ISTIO_VERSION=$(E2E_OSM_ISTIO_VERSION) \
E2E_OSM_OPERATOR_VERSION=$(E2E_OSM_OPERATOR_VERSION) \
go test -C $(PROJECT_ROOT)/test/e2e \
-timeout $(E2E_TIMEOUT) \
-count 1 -v -p 1 \
Expand Down Expand Up @@ -590,4 +597,4 @@ $(OPERATOR_SDK): ## Download operator-sdk locally if necessary.
hack/download-tools.sh operator-sdk $(OPERATOR_SDK)

$(OPM): ## Download opm locally if necessary.
hack/download-tools.sh opm $(OPM)
hack/download-tools.sh opm $(OPM)
70 changes: 70 additions & 0 deletions test/e2e/certmanager_resource_helpers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//go:build e2e
// +build e2e

package e2e

import (
"context"

certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
certmanagerclientset "github.com/cert-manager/cert-manager/pkg/client/clientset/versioned"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func ensureClusterIssuer(ctx context.Context, client certmanagerclientset.Interface, issuer *certmanagerv1.ClusterIssuer) error {
_, err := client.CertmanagerV1().ClusterIssuers().Create(ctx, issuer, metav1.CreateOptions{})
if err == nil {
return nil
}
if !apierrors.IsAlreadyExists(err) {
return err
}

existing, getErr := client.CertmanagerV1().ClusterIssuers().Get(ctx, issuer.Name, metav1.GetOptions{})
if getErr != nil {
return getErr
}

issuer.ResourceVersion = existing.ResourceVersion
_, err = client.CertmanagerV1().ClusterIssuers().Update(ctx, issuer, metav1.UpdateOptions{})
return err
}

func ensureIssuer(ctx context.Context, client certmanagerclientset.Interface, issuer *certmanagerv1.Issuer) error {
_, err := client.CertmanagerV1().Issuers(issuer.Namespace).Create(ctx, issuer, metav1.CreateOptions{})
if err == nil {
return nil
}
if !apierrors.IsAlreadyExists(err) {
return err
}

existing, getErr := client.CertmanagerV1().Issuers(issuer.Namespace).Get(ctx, issuer.Name, metav1.GetOptions{})
if getErr != nil {
return getErr
}

issuer.ResourceVersion = existing.ResourceVersion
_, err = client.CertmanagerV1().Issuers(issuer.Namespace).Update(ctx, issuer, metav1.UpdateOptions{})
return err
}

func ensureCertificate(ctx context.Context, client certmanagerclientset.Interface, certificate *certmanagerv1.Certificate) error {
_, err := client.CertmanagerV1().Certificates(certificate.Namespace).Create(ctx, certificate, metav1.CreateOptions{})
if err == nil {
return nil
}
if !apierrors.IsAlreadyExists(err) {
return err
}

existing, getErr := client.CertmanagerV1().Certificates(certificate.Namespace).Get(ctx, certificate.Name, metav1.GetOptions{})
if getErr != nil {
return getErr
}

certificate.ResourceVersion = existing.ResourceVersion
_, err = client.CertmanagerV1().Certificates(certificate.Namespace).Update(ctx, certificate, metav1.UpdateOptions{})
return err
}
42 changes: 42 additions & 0 deletions test/e2e/config_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ type IstioCSRGRPCurlJobConfig struct {
IstioCSRStatus v1alpha1.IstioCSRStatus
ClusterID string
JobName string
ProtoConfigMapName string
ServiceAccountName string
}

// ServiceMonitorConfig customizes fields in the ServiceMonitor spec
Expand All @@ -37,6 +39,46 @@ type ServiceMonitorConfig struct {
ComponentName string
}

// OSSMv3Config customizes OpenShift Service Mesh v3 install manifests.
type OSSMv3Config struct {
OperatorVersion string
IstioVersion string
ClusterID string
CAAddress string
}

const (
istioCSRProfileMinimal = "minimal"
istioCSRProfileOSSM = "ossm"
istioCSROperandManifest = "testdata/istio/istio_csr_template.yaml"
)

// IstioCSRConfig customizes the IstioCSR operand manifest.
// Profile is "minimal" (default) for isolated IstioCSR tests or "ossm" for Service Mesh smoke.
// IstioNamespace is spec.istioCSRConfig.istio.namespace; for the minimal profile it must match
// the test namespace where the istio-ca Issuer is created.
type IstioCSRConfig struct {
Namespace string
IstioNamespace string
ClusterID string
IstioDataPlaneNamespaceSelector string
Profile string
IssuerName string
}

func istioCSRConfigForNS(namespace string, overrides IstioCSRConfig) IstioCSRConfig {
if overrides.Namespace == "" {
overrides.Namespace = namespace
}
if overrides.IstioNamespace == "" {
overrides.IstioNamespace = namespace
}
if overrides.Profile == "" {
overrides.Profile = istioCSRProfileMinimal
}
return overrides
}

// replaceWithTemplate puts field values from a template struct
func replaceWithTemplate(sourceFileContents string, templatedValues any) ([]byte, error) {
tmpl, err := template.New("template").Option("missingkey=error").Parse(sourceFileContents)
Expand Down
20 changes: 7 additions & 13 deletions test/e2e/issuer_acme_dns01_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,7 @@ var _ = Describe("ACME Issuer DNS01 solver", Ordered, func() {
},
},
}
_, err = loader.KubeClient.CoreV1().ConfigMaps("cert-manager").Create(ctx, trustedCA, metav1.CreateOptions{})
Expect(err).NotTo(HaveOccurred())
Expect(library.UpsertConfigMap(ctx, loader.KubeClient, trustedCA)).NotTo(HaveOccurred())

DeferCleanup(func(cleanupCtx context.Context) {
loader.KubeClient.CoreV1().ConfigMaps("cert-manager").Delete(cleanupCtx, "trusted-ca", metav1.DeleteOptions{})
Expand Down Expand Up @@ -272,8 +271,7 @@ var _ = Describe("ACME Issuer DNS01 solver", Ordered, func() {
secretKey: secretAccessKey,
},
}
_, err := loader.KubeClient.CoreV1().Secrets(namespace).Create(ctx, awsSecret, metav1.CreateOptions{})
Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("failed to create secret %s", secretName))
Expect(library.UpsertSecret(ctx, loader.KubeClient, awsSecret)).NotTo(HaveOccurred(), fmt.Sprintf("failed to create secret %s", secretName))
}

// setupAmbientAWSCredentials sets up ambient AWS credentials via CredentialsRequest and subscription patch
Expand Down Expand Up @@ -343,8 +341,7 @@ var _ = Describe("ACME Issuer DNS01 solver", Ordered, func() {
secretKey: serviceAccount,
},
}
_, err := loader.KubeClient.CoreV1().Secrets(namespace).Create(ctx, gcpSecret, metav1.CreateOptions{})
Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("failed to create secret %s", secretName))
Expect(library.UpsertSecret(ctx, loader.KubeClient, gcpSecret)).NotTo(HaveOccurred(), fmt.Sprintf("failed to create secret %s", secretName))
}

// setupAmbientGCPCredentials sets up ambient GCP credentials via CredentialsRequest and subscription patch
Expand Down Expand Up @@ -532,8 +529,7 @@ var _ = Describe("ACME Issuer DNS01 solver", Ordered, func() {
secretKey: clientSecret,
},
}
_, err := loader.KubeClient.CoreV1().Secrets(namespace).Create(ctx, azureSecret, metav1.CreateOptions{})
Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("failed to create secret %s", secretName))
Expect(library.UpsertSecret(ctx, loader.KubeClient, azureSecret)).NotTo(HaveOccurred(), fmt.Sprintf("failed to create secret %s", secretName))
}

Context("with AWS Route53", Label("Platform:AWS", "CredentialsMode:Mint"), func() {
Expand Down Expand Up @@ -978,8 +974,7 @@ var _ = Describe("ACME Issuer DNS01 solver", Ordered, func() {
"credentials": credContent,
},
}
_, err := loader.KubeClient.CoreV1().Secrets("cert-manager").Create(ctx, stsSecret, metav1.CreateOptions{})
Expect(err).NotTo(HaveOccurred(), "failed to create STS credential secret")
Expect(library.UpsertSecret(ctx, loader.KubeClient, stsSecret)).NotTo(HaveOccurred(), "failed to create STS credential secret")

DeferCleanup(func(ctx context.Context) {
By("Deleting manually created STS credential secret")
Expand All @@ -990,7 +985,7 @@ var _ = Describe("ACME Issuer DNS01 solver", Ordered, func() {
})

By("patching subscription to inject 'CLOUD_CREDENTIALS_SECRET_NAME' env var")
err = patchSubscriptionWithEnvVars(ctx, loader, map[string]string{
err := patchSubscriptionWithEnvVars(ctx, loader, map[string]string{
"CLOUD_CREDENTIALS_SECRET_NAME": secretName,
})
Expect(err).NotTo(HaveOccurred(), "failed to patch subscription with 'CLOUD_CREDENTIALS_SECRET_NAME'")
Expand Down Expand Up @@ -1243,8 +1238,7 @@ var _ = Describe("ACME Issuer DNS01 solver", Ordered, func() {
"service_account.json": credContent,
},
}
_, err = loader.KubeClient.CoreV1().Secrets("cert-manager").Create(ctx, stsSecret, metav1.CreateOptions{})
Expect(err).NotTo(HaveOccurred(), "failed to create GCP STS credentials secret")
Expect(library.UpsertSecret(ctx, loader.KubeClient, stsSecret)).NotTo(HaveOccurred(), "failed to create GCP STS credentials secret")

DeferCleanup(func(ctx context.Context, namespace, name string) {
By("Deleting GCP STS credentials secret")
Expand Down
31 changes: 18 additions & 13 deletions test/e2e/issuer_acme_http01_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@ import (
. "github.com/onsi/gomega"
)

// acmeHTTP01OpenShiftIngressClass is required on OpenShift so HTTP-01 challenge Ingresses get Routes.
const acmeHTTP01OpenShiftIngressClass = "openshift-default"

func acmeHTTP01OpenShiftIngress() *acmev1.ACMEChallengeSolverHTTP01Ingress {
ingressClass := acmeHTTP01OpenShiftIngressClass
return &acmev1.ACMEChallengeSolverHTTP01Ingress{
IngressClassName: &ingressClass,
}
}

var _ = Describe("ACME Issuer HTTP01 solver", Label("Platform:Generic"), Ordered, func() {
var ctx context.Context
var cancel context.CancelFunc
Expand Down Expand Up @@ -68,8 +78,7 @@ var _ = Describe("ACME Issuer HTTP01 solver", Label("Platform:Generic"), Ordered
},
},
}
_, err = loader.KubeClient.CoreV1().ConfigMaps("cert-manager").Create(ctx, trustedCA, metav1.CreateOptions{})
Expect(err).NotTo(HaveOccurred())
Expect(library.UpsertConfigMap(ctx, loader.KubeClient, trustedCA)).NotTo(HaveOccurred())

DeferCleanup(func(cleanupCtx context.Context) {
loader.KubeClient.CoreV1().ConfigMaps("cert-manager").Delete(cleanupCtx, "trusted-ca", metav1.DeleteOptions{})
Expand Down Expand Up @@ -126,7 +135,6 @@ var _ = Describe("ACME Issuer HTTP01 solver", Label("Platform:Generic"), Ordered

BeforeEach(func() {
clusterIssuerName := "letsencrypt-http01"
ingressClassName := "openshift-default"
secretName = "ingress-http01-secret"

By("creating a cluster issuer")
Expand All @@ -146,9 +154,7 @@ var _ = Describe("ACME Issuer HTTP01 solver", Label("Platform:Generic"), Ordered
Solvers: []acmev1.ACMEChallengeSolver{
{
HTTP01: &acmev1.ACMEChallengeSolverHTTP01{
Ingress: &acmev1.ACMEChallengeSolverHTTP01Ingress{
IngressClassName: &ingressClassName,
},
Ingress: acmeHTTP01OpenShiftIngress(),
},
},
},
Expand All @@ -172,6 +178,7 @@ var _ = Describe("ACME Issuer HTTP01 solver", Label("Platform:Generic"), Ordered
By("creating Ingress object")
ingressHost = fmt.Sprintf("ahi-%s.%s", randomStr(3), appsDomain) // acronym for "ACME http-01 Ingress"
pathType := networkingv1.PathTypePrefix
ingressClassName := acmeHTTP01OpenShiftIngressClass
ingress := &networkingv1.Ingress{
ObjectMeta: metav1.ObjectMeta{
Name: "ingress-http01",
Expand Down Expand Up @@ -311,7 +318,7 @@ var _ = Describe("ACME Issuer HTTP01 solver", Label("Platform:Generic"), Ordered
Solvers: []acmev1.ACMEChallengeSolver{
{
HTTP01: &acmev1.ACMEChallengeSolverHTTP01{
Ingress: &acmev1.ACMEChallengeSolverHTTP01Ingress{},
Ingress: acmeHTTP01OpenShiftIngress(),
},
},
},
Expand Down Expand Up @@ -369,8 +376,7 @@ var _ = Describe("ACME Issuer HTTP01 solver", Label("Platform:Generic"), Ordered
"client-secret": "dummy-client-secret",
},
}
_, err := loader.KubeClient.CoreV1().Secrets("cert-manager").Create(ctx, azureDNSSecret, metav1.CreateOptions{})
Expect(err).NotTo(HaveOccurred(), "failed to create Azure DNS secret")
Expect(library.UpsertSecret(ctx, loader.KubeClient, azureDNSSecret)).NotTo(HaveOccurred(), "failed to create Azure DNS secret")

DeferCleanup(func(ctx context.Context) {
err := loader.KubeClient.CoreV1().Secrets("cert-manager").Delete(ctx, azureDNSSecretName, metav1.DeleteOptions{})
Expand All @@ -389,8 +395,7 @@ var _ = Describe("ACME Issuer HTTP01 solver", Label("Platform:Generic"), Ordered
"secret-access-key": "dummy-secret-key",
},
}
_, err = loader.KubeClient.CoreV1().Secrets("cert-manager").Create(ctx, route53Secret, metav1.CreateOptions{})
Expect(err).NotTo(HaveOccurred(), "failed to create Route53 secret")
Expect(library.UpsertSecret(ctx, loader.KubeClient, route53Secret)).NotTo(HaveOccurred(), "failed to create Route53 secret")

DeferCleanup(func(ctx context.Context) {
err := loader.KubeClient.CoreV1().Secrets("cert-manager").Delete(ctx, route53SecretName, metav1.DeleteOptions{})
Expand Down Expand Up @@ -423,7 +428,7 @@ var _ = Describe("ACME Issuer HTTP01 solver", Label("Platform:Generic"), Ordered
DNSZones: []string{testDomain},
},
HTTP01: &acmev1.ACMEChallengeSolverHTTP01{
Ingress: &acmev1.ACMEChallengeSolverHTTP01Ingress{},
Ingress: acmeHTTP01OpenShiftIngress(),
},
},
// Solver 2: DNS-01 (Azure) with specific dnsNames selector
Expand Down Expand Up @@ -470,7 +475,7 @@ var _ = Describe("ACME Issuer HTTP01 solver", Label("Platform:Generic"), Ordered
},
},
}
_, err = certmanagerClient.CertmanagerV1().ClusterIssuers().Create(ctx, clusterIssuer, metav1.CreateOptions{})
_, err := certmanagerClient.CertmanagerV1().ClusterIssuers().Create(ctx, clusterIssuer, metav1.CreateOptions{})
Expect(err).NotTo(HaveOccurred(), "failed to create ClusterIssuer")

DeferCleanup(func(ctx context.Context) {
Expand Down
Loading