diff --git a/config/crd/bases/pxc.percona.com_perconaxtradbclusters.yaml b/config/crd/bases/pxc.percona.com_perconaxtradbclusters.yaml index 08fb3ea8c6..278738c3f7 100644 --- a/config/crd/bases/pxc.percona.com_perconaxtradbclusters.yaml +++ b/config/crd/bases/pxc.percona.com_perconaxtradbclusters.yaml @@ -10410,6 +10410,8 @@ spec: items: type: string type: array + certValidityDuration: + type: string enabled: type: boolean issuerConf: diff --git a/deploy/bundle.yaml b/deploy/bundle.yaml index bcb6e342ee..2224d2258a 100644 --- a/deploy/bundle.yaml +++ b/deploy/bundle.yaml @@ -11377,6 +11377,8 @@ spec: items: type: string type: array + certValidityDuration: + type: string enabled: type: boolean issuerConf: diff --git a/deploy/cr.yaml b/deploy/cr.yaml index 0839210856..3606d9d148 100644 --- a/deploy/cr.yaml +++ b/deploy/cr.yaml @@ -37,6 +37,8 @@ spec: # enableCRValidationWebhook: true tls: enabled: true +# # 90 days in hours +# certValidityDuration: 2160h # SANs: # - pxc-1.example.com # - pxc-2.example.com diff --git a/deploy/crd.yaml b/deploy/crd.yaml index 17a2f736ec..08803d6704 100644 --- a/deploy/crd.yaml +++ b/deploy/crd.yaml @@ -11377,6 +11377,8 @@ spec: items: type: string type: array + certValidityDuration: + type: string enabled: type: boolean issuerConf: diff --git a/deploy/cw-bundle.yaml b/deploy/cw-bundle.yaml index 02354b97b5..8a74ddbea5 100644 --- a/deploy/cw-bundle.yaml +++ b/deploy/cw-bundle.yaml @@ -11377,6 +11377,8 @@ spec: items: type: string type: array + certValidityDuration: + type: string enabled: type: boolean issuerConf: diff --git a/e2e-tests/tls-issue-cert-manager/compare/certificate_some-name-tls-issue-ssl.yml b/e2e-tests/tls-issue-cert-manager/compare/certificate_some-name-tls-issue-ssl.yml index ca8b28c4ff..6f91cbfb09 100644 --- a/e2e-tests/tls-issue-cert-manager/compare/certificate_some-name-tls-issue-ssl.yml +++ b/e2e-tests/tls-issue-cert-manager/compare/certificate_some-name-tls-issue-ssl.yml @@ -16,6 +16,7 @@ spec: - '*.some-name-tls-issue-pxc' - '*.some-name-tls-issue-proxysql' - test.com + duration: 2160h0m0s issuerRef: kind: Issuer name: some-name-tls-issue-pxc-issuer diff --git a/e2e-tests/tls-issue-cert-manager/conf/some-name-tls-issue-haproxy.yml b/e2e-tests/tls-issue-cert-manager/conf/some-name-tls-issue-haproxy.yml index 6df30dd9a7..895bf0854c 100644 --- a/e2e-tests/tls-issue-cert-manager/conf/some-name-tls-issue-haproxy.yml +++ b/e2e-tests/tls-issue-cert-manager/conf/some-name-tls-issue-haproxy.yml @@ -6,6 +6,7 @@ metadata: - percona.com/delete-pxc-pods-in-order spec: tls: + certValidityDuration: 2160h SANs: - test.com secretsName: my-cluster-secrets diff --git a/e2e-tests/tls-issue-cert-manager/conf/some-name-tls-issue.yml b/e2e-tests/tls-issue-cert-manager/conf/some-name-tls-issue.yml index 1f05d871d6..a7b0a38b4b 100644 --- a/e2e-tests/tls-issue-cert-manager/conf/some-name-tls-issue.yml +++ b/e2e-tests/tls-issue-cert-manager/conf/some-name-tls-issue.yml @@ -6,6 +6,7 @@ metadata: - percona.com/delete-pxc-pods-in-order spec: tls: + certValidityDuration: 2160h SANs: - test.com secretsName: my-cluster-secrets diff --git a/pkg/apis/pxc/v1/pxc_types.go b/pkg/apis/pxc/v1/pxc_types.go index 24163a17d3..9104d562f5 100644 --- a/pkg/apis/pxc/v1/pxc_types.go +++ b/pkg/apis/pxc/v1/pxc_types.go @@ -151,6 +151,7 @@ type TLSSpec struct { Enabled *bool `json:"enabled,omitempty"` SANs []string `json:"SANs,omitempty"` IssuerConf *cmmeta.ObjectReference `json:"issuerConf,omitempty"` + Duration *metav1.Duration `json:"certValidityDuration",omitempty` } const ( diff --git a/pkg/apis/pxc/v1/zz_generated.deepcopy.go b/pkg/apis/pxc/v1/zz_generated.deepcopy.go index 43718a16b5..4a2f34eb32 100644 --- a/pkg/apis/pxc/v1/zz_generated.deepcopy.go +++ b/pkg/apis/pxc/v1/zz_generated.deepcopy.go @@ -1371,6 +1371,11 @@ func (in *TLSSpec) DeepCopyInto(out *TLSSpec) { *out = new(apismetav1.ObjectReference) **out = **in } + if in.Duration != nil { + in, out := &in.Duration, &out.Duration + *out = new(metav1.Duration) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSSpec. diff --git a/pkg/controller/pxc/tls.go b/pkg/controller/pxc/tls.go index be2a20e0f0..d111816087 100644 --- a/pkg/controller/pxc/tls.go +++ b/pkg/controller/pxc/tls.go @@ -56,12 +56,12 @@ func (r *ReconcilePerconaXtraDBCluster) reconcileSSL(ctx context.Context, cr *ap if errSecret == nil && !metav1.IsControlledBy(&secretObj, cr) { return nil } - err := r.createSSLByCertManager(cr) + err := r.createSSLByCertManager(ctx, cr) if err != nil { if cr.Spec.TLS != nil && cr.Spec.TLS.IssuerConf != nil { return fmt.Errorf("create ssl with cert manager %w", err) } - err = r.createSSLManualy(cr) + err = r.createSSLManualy(ctx, cr) if err != nil { return fmt.Errorf("create ssl internally: %v", err) } @@ -69,17 +69,22 @@ func (r *ReconcilePerconaXtraDBCluster) reconcileSSL(ctx context.Context, cr *ap return nil } -func (r *ReconcilePerconaXtraDBCluster) createSSLByCertManager(cr *api.PerconaXtraDBCluster) error { +func (r *ReconcilePerconaXtraDBCluster) createSSLByCertManager(ctx context.Context, cr *api.PerconaXtraDBCluster) error { issuerName := cr.Name + "-pxc-issuer" caIssuerName := cr.Name + "-pxc-ca-issuer" issuerKind := "Issuer" issuerGroup := "" + duration := &metav1.Duration{Duration: pxctls.DefaultValidity} + if cr.Spec.TLS != nil && cr.Spec.TLS.Duration != nil { + duration = cr.Spec.TLS.Duration + } + if cr.Spec.TLS != nil && cr.Spec.TLS.IssuerConf != nil { issuerKind = cr.Spec.TLS.IssuerConf.Kind issuerName = cr.Spec.TLS.IssuerConf.Name issuerGroup = cr.Spec.TLS.IssuerConf.Group } else { - if err := r.createIssuer(cr, caIssuerName, ""); err != nil { + if err := r.createIssuer(ctx, cr, caIssuerName, ""); err != nil { return err } @@ -97,7 +102,7 @@ func (r *ReconcilePerconaXtraDBCluster) createSSLByCertManager(cr *api.PerconaXt Kind: issuerKind, Group: issuerGroup, }, - Duration: &metav1.Duration{Duration: pxctls.DefaultValidity}, + Duration: duration, RenewBefore: &metav1.Duration{Duration: 730 * time.Hour}, }, } @@ -105,16 +110,16 @@ func (r *ReconcilePerconaXtraDBCluster) createSSLByCertManager(cr *api.PerconaXt caCert.Labels = naming.LabelsCluster(cr) } - err := r.client.Create(context.TODO(), caCert) + err := r.client.Create(ctx, caCert) if err != nil && !k8serr.IsAlreadyExists(err) { return fmt.Errorf("create CA certificate: %v", err) } - if err := r.waitForCerts(cr.Namespace, caCert.Spec.SecretName); err != nil { + if err := r.waitForCerts(ctx, cr.Namespace, caCert.Spec.SecretName); err != nil { return err } - if err := r.createIssuer(cr, issuerName, caCert.Spec.SecretName); err != nil { + if err := r.createIssuer(ctx, cr, issuerName, caCert.Spec.SecretName); err != nil { return err } } @@ -146,14 +151,17 @@ func (r *ReconcilePerconaXtraDBCluster) createSSLByCertManager(cr *api.PerconaXt if cr.Spec.TLS != nil && len(cr.Spec.TLS.SANs) > 0 { kubeCert.Spec.DNSNames = append(kubeCert.Spec.DNSNames, cr.Spec.TLS.SANs...) } + if cr.CompareVersionWith("1.19.0") >= 0 { + kubeCert.Spec.Duration = duration + } - err := r.client.Create(context.TODO(), kubeCert) + err := r.client.Create(ctx, kubeCert) if err != nil && !k8serr.IsAlreadyExists(err) { return fmt.Errorf("create certificate: %v", err) } if cr.Spec.PXC.SSLSecretName == cr.Spec.PXC.SSLInternalSecretName { - return r.waitForCerts(cr.Namespace, cr.Spec.PXC.SSLSecretName) + return r.waitForCerts(ctx, cr.Namespace, cr.Spec.PXC.SSLSecretName) } kubeCert = &cm.Certificate{ @@ -187,15 +195,18 @@ func (r *ReconcilePerconaXtraDBCluster) createSSLByCertManager(cr *api.PerconaXt if cr.CompareVersionWith("1.16.0") >= 0 { kubeCert.Labels = naming.LabelsCluster(cr) } - err = r.client.Create(context.TODO(), kubeCert) + if cr.CompareVersionWith("1.19.0") >= 0 { + kubeCert.Spec.Duration = duration + } + err = r.client.Create(ctx, kubeCert) if err != nil && !k8serr.IsAlreadyExists(err) { return fmt.Errorf("create internal certificate: %v", err) } - return r.waitForCerts(cr.Namespace, cr.Spec.PXC.SSLSecretName, cr.Spec.PXC.SSLInternalSecretName) + return r.waitForCerts(ctx, cr.Namespace, cr.Spec.PXC.SSLSecretName, cr.Spec.PXC.SSLInternalSecretName) } -func (r *ReconcilePerconaXtraDBCluster) waitForCerts(namespace string, secretsList ...string) error { +func (r *ReconcilePerconaXtraDBCluster) waitForCerts(ctx context.Context, namespace string, secretsList ...string) error { ticker := time.NewTicker(3 * time.Second) timeoutTimer := time.NewTimer(30 * time.Second) defer timeoutTimer.Stop() @@ -208,7 +219,7 @@ func (r *ReconcilePerconaXtraDBCluster) waitForCerts(namespace string, secretsLi sucessCount := 0 for _, secretName := range secretsList { secret := &corev1.Secret{} - err := r.client.Get(context.TODO(), types.NamespacedName{ + err := r.client.Get(ctx, types.NamespacedName{ Name: secretName, Namespace: namespace, }, secret) @@ -225,7 +236,7 @@ func (r *ReconcilePerconaXtraDBCluster) waitForCerts(namespace string, secretsLi } } -func (r *ReconcilePerconaXtraDBCluster) createIssuer(cr *api.PerconaXtraDBCluster, issuer string, caCertSecret string) error { +func (r *ReconcilePerconaXtraDBCluster) createIssuer(ctx context.Context, cr *api.PerconaXtraDBCluster, issuer string, caCertSecret string) error { spec := cm.IssuerSpec{} if caCertSecret == "" { @@ -246,7 +257,7 @@ func (r *ReconcilePerconaXtraDBCluster) createIssuer(cr *api.PerconaXtraDBCluste if cr.CompareVersionWith("1.16.0") >= 0 { ls = naming.LabelsCluster(cr) } - err := r.client.Create(context.TODO(), &cm.Issuer{ + err := r.client.Create(ctx, &cm.Issuer{ ObjectMeta: metav1.ObjectMeta{ Name: issuer, Namespace: cr.Namespace, @@ -260,7 +271,7 @@ func (r *ReconcilePerconaXtraDBCluster) createIssuer(cr *api.PerconaXtraDBCluste return nil } -func (r *ReconcilePerconaXtraDBCluster) createSSLManualy(cr *api.PerconaXtraDBCluster) error { +func (r *ReconcilePerconaXtraDBCluster) createSSLManualy(ctx context.Context, cr *api.PerconaXtraDBCluster) error { data := make(map[string][]byte) proxyHosts := []string{ cr.Name + "-pxc", @@ -292,7 +303,7 @@ func (r *ReconcilePerconaXtraDBCluster) createSSLManualy(cr *api.PerconaXtraDBCl if cr.CompareVersionWith("1.16.0") >= 0 { secretObj.Labels = naming.LabelsCluster(cr) } - err = r.client.Create(context.TODO(), &secretObj) + err = r.client.Create(ctx, &secretObj) if err != nil && !k8serr.IsAlreadyExists(err) { return fmt.Errorf("create TLS secret: %v", err) } @@ -327,7 +338,7 @@ func (r *ReconcilePerconaXtraDBCluster) createSSLManualy(cr *api.PerconaXtraDBCl if cr.CompareVersionWith("1.16.0") >= 0 { secretObjInternal.Labels = naming.LabelsCluster(cr) } - err = r.client.Create(context.TODO(), &secretObjInternal) + err = r.client.Create(ctx, &secretObjInternal) if err != nil && !k8serr.IsAlreadyExists(err) { return fmt.Errorf("create TLS internal secret: %v", err) }