diff --git a/e2e-tests/tests/gr-tls-cert-manager/04-assert.yaml b/e2e-tests/tests/gr-tls-cert-manager/04-assert.yaml index 85cc21415..2dcff75b7 100644 --- a/e2e-tests/tests/gr-tls-cert-manager/04-assert.yaml +++ b/e2e-tests/tests/gr-tls-cert-manager/04-assert.yaml @@ -36,11 +36,11 @@ spec: status: conditions: - message: Certificate is up to date and has not expired - observedGeneration: 1 + observedGeneration: 2 reason: Ready status: 'True' type: Ready - revision: 1 + revision: 2 --- apiVersion: apps/v1 kind: StatefulSet diff --git a/e2e-tests/tests/gr-tls-cert-manager/05-check-cert.yaml b/e2e-tests/tests/gr-tls-cert-manager/05-check-cert.yaml index 7a44e42ab..35ca29679 100644 --- a/e2e-tests/tests/gr-tls-cert-manager/05-check-cert.yaml +++ b/e2e-tests/tests/gr-tls-cert-manager/05-check-cert.yaml @@ -17,5 +17,6 @@ commands: "*.gr-tls-cert-manager-orchestrator.'"${NAMESPACE}"'.svc", "*.gr-tls-cert-manager-router", "*.gr-tls-cert-manager-router.'"${NAMESPACE}"'", - "*.gr-tls-cert-manager-router.'"${NAMESPACE}"'.svc" + "*.gr-tls-cert-manager-router.'"${NAMESPACE}"'.svc", + "mysql-1.example.com" ]' diff --git a/e2e-tests/tests/gr-tls-cert-manager/06-assert.yaml b/e2e-tests/tests/gr-tls-cert-manager/06-assert.yaml index 72f233b6d..25482b577 100644 --- a/e2e-tests/tests/gr-tls-cert-manager/06-assert.yaml +++ b/e2e-tests/tests/gr-tls-cert-manager/06-assert.yaml @@ -36,19 +36,19 @@ spec: status: conditions: - message: Certificate is up to date and has not expired - observedGeneration: 1 + observedGeneration: 2 reason: Ready status: 'True' type: Ready - revision: 2 + revision: 3 --- apiVersion: apps/v1 kind: StatefulSet metadata: - generation: 2 + generation: 3 name: gr-tls-cert-manager-mysql status: - observedGeneration: 2 + observedGeneration: 3 replicas: 3 readyReplicas: 3 --- @@ -64,7 +64,7 @@ metadata: app.kubernetes.io/part-of: percona-server app.kubernetes.io/version: v0.11.0 status: - observedGeneration: 2 + observedGeneration: 3 replicas: 3 updatedReplicas: 3 readyReplicas: 3 diff --git a/e2e-tests/tests/tls-cert-manager/04-assert.yaml b/e2e-tests/tests/tls-cert-manager/04-assert.yaml index 018e9cb3f..563c754d0 100644 --- a/e2e-tests/tests/tls-cert-manager/04-assert.yaml +++ b/e2e-tests/tests/tls-cert-manager/04-assert.yaml @@ -36,11 +36,11 @@ spec: status: conditions: - message: Certificate is up to date and has not expired - observedGeneration: 1 + observedGeneration: 2 reason: Ready status: 'True' type: Ready - revision: 1 + revision: 2 --- apiVersion: apps/v1 kind: StatefulSet diff --git a/e2e-tests/tests/tls-cert-manager/05-check-cert.yaml b/e2e-tests/tests/tls-cert-manager/05-check-cert.yaml index b65c07694..d1b5b786c 100644 --- a/e2e-tests/tests/tls-cert-manager/05-check-cert.yaml +++ b/e2e-tests/tests/tls-cert-manager/05-check-cert.yaml @@ -17,5 +17,6 @@ commands: "*.tls-cert-manager-orchestrator.'"${NAMESPACE}"'.svc", "*.tls-cert-manager-router", "*.tls-cert-manager-router.'"${NAMESPACE}"'", - "*.tls-cert-manager-router.'"${NAMESPACE}"'.svc" + "*.tls-cert-manager-router.'"${NAMESPACE}"'.svc", + "mysql-1.example.com" ]' diff --git a/e2e-tests/tests/tls-cert-manager/06-assert.yaml b/e2e-tests/tests/tls-cert-manager/06-assert.yaml index 6fea42802..d2589da27 100644 --- a/e2e-tests/tests/tls-cert-manager/06-assert.yaml +++ b/e2e-tests/tests/tls-cert-manager/06-assert.yaml @@ -36,29 +36,29 @@ spec: status: conditions: - message: Certificate is up to date and has not expired - observedGeneration: 1 + observedGeneration: 2 reason: Ready status: 'True' type: Ready - revision: 2 + revision: 3 --- apiVersion: apps/v1 kind: StatefulSet metadata: - generation: 2 + generation: 3 name: tls-cert-manager-mysql status: - observedGeneration: 2 + observedGeneration: 3 replicas: 3 readyReplicas: 3 --- apiVersion: apps/v1 kind: StatefulSet metadata: - generation: 2 + generation: 3 name: tls-cert-manager-orc status: - observedGeneration: 2 + observedGeneration: 3 replicas: 3 readyReplicas: 3 --- diff --git a/e2e-tests/tests/tls-cert-manager/06-renew-certs.yaml b/e2e-tests/tests/tls-cert-manager/06-renew-certs.yaml index b8f99ee20..77cd6fdad 100644 --- a/e2e-tests/tests/tls-cert-manager/06-renew-certs.yaml +++ b/e2e-tests/tests/tls-cert-manager/06-renew-certs.yaml @@ -14,7 +14,7 @@ commands: renew_certificate "tls-cert-manager-ssl" - sleep 10 + sleep 20 new_generation_mysql=$(kubectl -n ${NAMESPACE} get sts tls-cert-manager-mysql -o jsonpath='{.metadata.generation}') new_generation_haproxy=$(kubectl -n ${NAMESPACE} get sts tls-cert-manager-haproxy -o jsonpath='{.metadata.generation}') diff --git a/pkg/controller/ps/tls.go b/pkg/controller/ps/tls.go index ee8c71948..6fa2ae3d5 100644 --- a/pkg/controller/ps/tls.go +++ b/pkg/controller/ps/tls.go @@ -26,18 +26,19 @@ import ( func (r *PerconaServerMySQLReconciler) ensureTLSSecret(ctx context.Context, cr *apiv1alpha1.PerconaServerMySQL) error { log := logf.FromContext(ctx) - secretObj := corev1.Secret{} - err := r.Client.Get(context.TODO(), + secret := corev1.Secret{} + err := r.Get(ctx, types.NamespacedName{ Namespace: cr.Namespace, Name: cr.Spec.SSLSecretName, }, - &secretObj, + &secret, ) - - // don't create ssl secret if it is created by customer not by operator - if err == nil && !metav1.IsControlledBy(&secretObj, cr) { - return nil + if err == nil { + // don't create ssl secret if it is created by customer not by operator + if c, err := tls.IsSecretCreatedByUser(ctx, r.Client, cr, &secret); err != nil || c { + return err + } } err = r.ensureSSLByCertManager(ctx, cr) @@ -223,7 +224,7 @@ func (r *PerconaServerMySQLReconciler) ensureIssuer(ctx context.Context, cr *api IssuerConfig: IssuerConf, }, } - err := k8s.EnsureObjectWithHash(ctx, r.Client, nil, isr, r.Scheme) + err := k8s.EnsureObjectWithHash(ctx, r.Client, cr, isr, r.Scheme) if err != nil { return errors.Wrap(err, "create issuer") } diff --git a/pkg/tls/tls.go b/pkg/tls/tls.go index 99c41f43a..1b35a9074 100644 --- a/pkg/tls/tls.go +++ b/pkg/tls/tls.go @@ -2,6 +2,7 @@ package tls import ( "bytes" + "context" "crypto/rand" "crypto/rsa" "crypto/x509" @@ -12,7 +13,13 @@ import ( "sort" "time" + cm "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" "github.com/pkg/errors" + corev1 "k8s.io/api/core/v1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" apiv1alpha1 "github.com/percona/percona-server-mysql-operator/api/v1alpha1" ) @@ -155,3 +162,38 @@ func DNSNamesFromCert(data []byte) ([]string, error) { sort.Strings(names) return names, nil } + +func IsSecretCreatedByUser(ctx context.Context, c client.Client, cr *apiv1alpha1.PerconaServerMySQL, secret *corev1.Secret) (bool, error) { + if metav1.IsControlledBy(secret, cr) { + return false, nil + } + if secret.Labels[cm.PartOfCertManagerControllerLabelKey] == "true" { + return isCertManagerSecretCreatedByUser(ctx, c, cr, secret) + } + return true, nil +} + +func isCertManagerSecretCreatedByUser(ctx context.Context, c client.Client, cr *apiv1alpha1.PerconaServerMySQL, secret *corev1.Secret) (bool, error) { + if metav1.IsControlledBy(secret, cr) { + return false, nil + } + + issuerName := secret.Annotations[cm.IssuerNameAnnotationKey] + if secret.Annotations[cm.IssuerKindAnnotationKey] != cm.IssuerKind || issuerName == "" { + return true, nil + } + issuer := new(cm.Issuer) + if err := c.Get(ctx, types.NamespacedName{ + Name: issuerName, + Namespace: secret.Namespace, + }, issuer); err != nil { + if k8serrors.IsNotFound(err) { + return true, nil + } + return true, errors.Wrap(err, "failed to get issuer") + } + if metav1.IsControlledBy(issuer, cr) { + return false, nil + } + return true, nil +}