Skip to content

Commit c4a2225

Browse files
Demch1kIvan Sokoryanhorsgkechpooknull
authored
K8SPSMDB-1387 certmanager --enable-certificate-owner-ref option causes no startup of any mongodb clusters (#1850)
* fixed * improve the fix To fix the issue, we only need to modify the `WaitForCert` method by adding a check to see if the secret has a controller reference to a certificate * create `Certificate` interface * add e2e test --------- Co-authored-by: Ivan Sokoryan <i.sokoryan@robo.cash> Co-authored-by: Viacheslav Sarzhan <slava.sarzhan@percona.com> Co-authored-by: George Kechagias <geo.kechagias@gmail.com> Co-authored-by: Andrii Dema <a.dema@jazzserve.com> Co-authored-by: Ege Güneş <ege.gunes@percona.com>
1 parent 65f5c6f commit c4a2225

File tree

7 files changed

+178
-117
lines changed

7 files changed

+178
-117
lines changed

e2e-tests/arbiter/run

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ check_cr_config() {
7171

7272
main() {
7373
create_infra $namespace
74-
deploy_cert_manager
74+
deploy_cert_manager "--enable-certificate-owner-ref"
7575

7676
desc 'create secrets and start client'
7777
kubectl_bin apply \

e2e-tests/functions

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1251,6 +1251,10 @@ deploy_cert_manager() {
12511251
kubectl_bin create namespace cert-manager || :
12521252
kubectl_bin label namespace cert-manager certmanager.k8s.io/disable-validation=true || :
12531253
kubectl_bin apply -f "https://github.com/cert-manager/cert-manager/releases/download/v${CERT_MANAGER_VER}/cert-manager.yaml" --validate=false || : 2>/dev/null
1254+
for arg in "$@"; do
1255+
kubectl_bin patch deployment cert-manager -n cert-manager --type='json' \
1256+
-p='[{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"'"$arg"'"}]'
1257+
done
12541258
kubectl_bin -n cert-manager wait pod -l app.kubernetes.io/instance=cert-manager --for=condition=ready
12551259
sleep 120
12561260
}

pkg/controller/perconaservermongodb/ssl.go

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ func (r *ReconcilePerconaServerMongoDB) createSSLByCertManager(ctx context.Conte
191191
return nil
192192
}
193193

194-
caSecret, err := r.getSecret(ctx, cr, tls.CACertificateSecretName(cr))
194+
caSecret, err := r.getSecret(ctx, cr, tls.CertificateCA(cr).SecretName())
195195
if err != nil {
196196
if k8serr.IsNotFound(err) {
197197
return nil
@@ -393,14 +393,15 @@ func (r *ReconcilePerconaServerMongoDB) applyCertManagerCertificates(ctx context
393393
return "", errors.Wrap(err, "apply ca issuer")
394394
}
395395

396+
caCert := tls.CertificateCA(cr)
396397
err = applyFunc(func() (util.ApplyStatus, error) {
397-
return c.ApplyCACertificate(ctx, cr)
398+
return c.ApplyCertificate(ctx, cr, caCert)
398399
})
399400
if err != nil {
400401
return "", errors.Wrap(err, "create ca certificate")
401402
}
402403

403-
err = c.WaitForCerts(ctx, cr, tls.CACertificateSecretName(cr))
404+
err = c.WaitForCerts(ctx, cr, caCert)
404405
if err != nil {
405406
return "", errors.Wrap(err, "failed to wait for ca cert")
406407
}
@@ -413,26 +414,27 @@ func (r *ReconcilePerconaServerMongoDB) applyCertManagerCertificates(ctx context
413414
return "", errors.Wrap(err, "create issuer")
414415
}
415416

417+
tlsCert := tls.CertificateTLS(cr, false)
416418
err = applyFunc(func() (util.ApplyStatus, error) {
417-
return c.ApplyCertificate(ctx, cr, false)
419+
return c.ApplyCertificate(ctx, cr, tlsCert)
418420
})
419421
if err != nil {
420422
return "", errors.Wrap(err, "create certificate")
421423
}
422424

423-
secretNames := []string{tls.CertificateSecretName(cr, false)}
425+
certificates := []tls.Certificate{tlsCert}
424426

425-
if tls.CertificateSecretName(cr, false) != tls.CertificateSecretName(cr, true) {
427+
if internalCert := tls.CertificateTLS(cr, true); tlsCert.SecretName() != internalCert.SecretName() {
426428
err = applyFunc(func() (util.ApplyStatus, error) {
427-
return c.ApplyCertificate(ctx, cr, true)
429+
return c.ApplyCertificate(ctx, cr, internalCert)
428430
})
429431
if err != nil {
430432
return "", errors.Wrap(err, "create certificate")
431433
}
432-
secretNames = append(secretNames, tls.CertificateSecretName(cr, true))
434+
certificates = append(certificates, internalCert)
433435
}
434436

435-
err = c.WaitForCerts(ctx, cr, secretNames...)
437+
err = c.WaitForCerts(ctx, cr, certificates...)
436438
if err != nil {
437439
return "", errors.Wrap(err, "failed to wait for certs")
438440
}

pkg/psmdb/tls/certificate.go

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
package tls
2+
3+
import (
4+
"time"
5+
6+
cm "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
7+
cmmeta "github.com/cert-manager/cert-manager/pkg/apis/meta/v1"
8+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
9+
10+
api "github.com/percona/percona-server-mongodb-operator/pkg/apis/psmdb/v1"
11+
"github.com/percona/percona-server-mongodb-operator/pkg/naming"
12+
)
13+
14+
type Certificate interface {
15+
Name() string
16+
SecretName() string
17+
Object() *cm.Certificate
18+
}
19+
20+
type caCert struct {
21+
cr *api.PerconaServerMongoDB
22+
}
23+
24+
func CertificateCA(cr *api.PerconaServerMongoDB) Certificate {
25+
return &caCert{
26+
cr: cr,
27+
}
28+
}
29+
30+
func (c *caCert) Name() string {
31+
return c.cr.Name + "-ca-cert"
32+
}
33+
34+
func (c *caCert) SecretName() string {
35+
return c.Name()
36+
}
37+
38+
func (c *caCert) Object() *cm.Certificate {
39+
cr := c.cr
40+
41+
labels := naming.ClusterLabels(cr)
42+
if cr.CompareVersion("1.17.0") < 0 {
43+
labels = nil
44+
}
45+
return &cm.Certificate{
46+
ObjectMeta: metav1.ObjectMeta{
47+
Name: c.Name(),
48+
Namespace: cr.Namespace,
49+
Labels: labels,
50+
},
51+
Spec: cm.CertificateSpec{
52+
SecretName: c.SecretName(),
53+
CommonName: cr.Name + "-ca",
54+
IsCA: true,
55+
IssuerRef: cmmeta.ObjectReference{
56+
Name: caIssuerName(cr),
57+
Kind: cm.IssuerKind,
58+
},
59+
Duration: &metav1.Duration{Duration: time.Hour * 24 * 365},
60+
RenewBefore: &metav1.Duration{Duration: 730 * time.Hour},
61+
},
62+
}
63+
}
64+
65+
type tlsCert struct {
66+
cr *api.PerconaServerMongoDB
67+
68+
internal bool
69+
}
70+
71+
func CertificateTLS(cr *api.PerconaServerMongoDB, internal bool) Certificate {
72+
return &tlsCert{
73+
cr: cr,
74+
internal: internal,
75+
}
76+
}
77+
78+
func (c *tlsCert) Name() string {
79+
if c.internal {
80+
return c.cr.Name + "-ssl-internal"
81+
}
82+
return c.cr.Name + "-ssl"
83+
}
84+
85+
func (c *tlsCert) SecretName() string {
86+
if c.internal {
87+
return api.SSLInternalSecretName(c.cr)
88+
}
89+
90+
return api.SSLSecretName(c.cr)
91+
}
92+
93+
func (c *tlsCert) Object() *cm.Certificate {
94+
cr := c.cr
95+
96+
issuerKind := cm.IssuerKind
97+
issuerGroup := ""
98+
if cr.CompareVersion("1.16.0") >= 0 && cr.Spec.TLS != nil && cr.Spec.TLS.IssuerConf != nil {
99+
issuerKind = cr.Spec.TLS.IssuerConf.Kind
100+
issuerGroup = cr.Spec.TLS.IssuerConf.Group
101+
102+
}
103+
isCA := false
104+
if cr.CompareVersion("1.15.0") < 0 {
105+
isCA = true
106+
}
107+
108+
labels := naming.ClusterLabels(cr)
109+
if cr.CompareVersion("1.17.0") < 0 {
110+
labels = nil
111+
}
112+
113+
return &cm.Certificate{
114+
ObjectMeta: metav1.ObjectMeta{
115+
Name: c.Name(),
116+
Namespace: cr.Namespace,
117+
Labels: labels,
118+
},
119+
Spec: cm.CertificateSpec{
120+
Subject: &cm.X509Subject{
121+
Organizations: []string{"PSMDB"},
122+
},
123+
CommonName: cr.Name,
124+
SecretName: c.SecretName(),
125+
DNSNames: GetCertificateSans(cr),
126+
IsCA: isCA,
127+
Duration: &cr.Spec.TLS.CertValidityDuration,
128+
IssuerRef: cmmeta.ObjectReference{
129+
Name: issuerName(cr),
130+
Kind: issuerKind,
131+
Group: issuerGroup,
132+
},
133+
},
134+
}
135+
}

0 commit comments

Comments
 (0)