From 62ce0b4927c8ba81fad3a0dc9d47d2fb736df324 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wilson=20J=C3=BAnior?= Date: Thu, 15 Aug 2024 09:57:47 -0300 Subject: [PATCH] operator: create multiple cm.Certificate based on name --- api/v1alpha1/rpaasinstance.go | 41 ++++++- .../certificates/cert_manager_test.go | 116 +++++++++++++++++- 2 files changed, 150 insertions(+), 7 deletions(-) diff --git a/api/v1alpha1/rpaasinstance.go b/api/v1alpha1/rpaasinstance.go index ae233a7d8..267445af7 100644 --- a/api/v1alpha1/rpaasinstance.go +++ b/api/v1alpha1/rpaasinstance.go @@ -69,17 +69,37 @@ func (i *RpaasInstance) CertManagerRequests() (reqs []CertManager) { return } - uniqueCerts := make(map[string]*CertManager) + uniqueCertsByIssuer := make(map[string]*CertManager) + uniqueCertsByName := make(map[string]*CertManager) + if req := i.Spec.DynamicCertificates.CertManager; req != nil { r := req.DeepCopy() r.DNSNames = r.dnsNames(i) - uniqueCerts[r.Issuer] = r + + if req.Name != "" { + uniqueCertsByName[req.Name] = r + } else { + uniqueCertsByIssuer[r.Issuer] = r + } } for _, req := range i.Spec.DynamicCertificates.CertManagerRequests { - r, found := uniqueCerts[req.Issuer] + + if req.Name != "" { + r, found := uniqueCertsByName[req.Name] + if found { + r.DNSNames = append(r.DNSNames, req.dnsNames(i)...) + r.IPAddresses = append(r.IPAddresses, req.IPAddresses...) + } else { + uniqueCertsByName[req.Name] = req.DeepCopy() + } + + continue + } + + r, found := uniqueCertsByIssuer[req.Issuer] if !found { - uniqueCerts[req.Issuer] = req.DeepCopy() + uniqueCertsByIssuer[req.Issuer] = req.DeepCopy() continue } @@ -87,11 +107,20 @@ func (i *RpaasInstance) CertManagerRequests() (reqs []CertManager) { r.IPAddresses = append(r.IPAddresses, req.IPAddresses...) } - for _, v := range uniqueCerts { + for _, v := range uniqueCertsByName { + reqs = append(reqs, *v) + } + for _, v := range uniqueCertsByIssuer { reqs = append(reqs, *v) } - sort.Slice(reqs, func(i, j int) bool { return reqs[i].Issuer < reqs[j].Issuer }) + sort.Slice(reqs, func(i, j int) bool { + if reqs[i].Name != reqs[j].Name { + return reqs[i].Name < reqs[j].Name + } + + return reqs[i].Issuer < reqs[j].Issuer + }) return } diff --git a/internal/controllers/certificates/cert_manager_test.go b/internal/controllers/certificates/cert_manager_test.go index f4973bb88..67b0eeb3e 100644 --- a/internal/controllers/certificates/cert_manager_test.go +++ b/internal/controllers/certificates/cert_manager_test.go @@ -41,6 +41,17 @@ func Test_ReconcileCertManager(t *testing.T) { }, }, + &cmv1.Issuer{ + ObjectMeta: metav1.ObjectMeta{ + Name: "issuer-2", + Namespace: "rpaasv2", + }, + Spec: cmv1.IssuerSpec{ + IssuerConfig: cmv1.IssuerConfig{ + SelfSigned: &cmv1.SelfSignedIssuer{}, + }, + }, + }, &cmv1.ClusterIssuer{ ObjectMeta: metav1.ObjectMeta{ Name: "cluster-issuer-1", @@ -210,6 +221,108 @@ wg4cGbIbBPs= }, }, + "when many cert manager requests are set, should create certificates": { + instance: &v1alpha1.RpaasInstance{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-instance", + Namespace: "rpaasv2", + }, + Spec: v1alpha1.RpaasInstanceSpec{ + DynamicCertificates: &v1alpha1.DynamicCertificates{ + CertManagerRequests: []v1alpha1.CertManager{ + { + Name: "cert-01", + Issuer: "issuer-1", + DNSNames: []string{"my-instance.example.com"}, + }, + { + Name: "cert-02", + Issuer: "issuer-1", + DNSNames: []string{"my-instance2.example.com"}, + }, + { + Name: "cert-03", + Issuer: "issuer-2", + DNSNames: []string{"my-instance3.example.org"}, + }, + }, + }, + }, + }, + assert: func(t *testing.T, cli client.Client, instance *v1alpha1.RpaasInstance) { + var certList cmv1.CertificateList + + err := cli.List(context.TODO(), &certList) + require.NoError(t, err) + + certs := []cmv1.Certificate{} + for _, cert := range certList.Items { + if cert.Labels["rpaas.extensions.tsuru.io/instance-name"] == "my-instance" { + certs = append(certs, cert) + } + } + + require.Len(t, certs, 3) + + for _, cert := range certs { + assert.Equal(t, []metav1.OwnerReference{ + { + APIVersion: "extensions.tsuru.io/v1alpha1", + Kind: "RpaasInstance", + Name: "my-instance", + Controller: func(b bool) *bool { return &b }(true), + BlockOwnerDeletion: func(b bool) *bool { return &b }(true), + }, + }, cert.ObjectMeta.OwnerReferences) + } + + assert.Equal(t, map[string]string{ + "rpaas.extensions.tsuru.io/certificate-name": "cert-01", + "rpaas.extensions.tsuru.io/instance-name": "my-instance", + }, certs[0].Labels) + + assert.Equal(t, map[string]string{ + "rpaas.extensions.tsuru.io/certificate-name": "cert-02", + "rpaas.extensions.tsuru.io/instance-name": "my-instance", + }, certs[1].Labels) + + assert.Equal(t, map[string]string{ + "rpaas.extensions.tsuru.io/certificate-name": "cert-03", + "rpaas.extensions.tsuru.io/instance-name": "my-instance", + }, certs[2].Labels) + + assert.Equal(t, cmv1.CertificateSpec{ + IssuerRef: cmmeta.ObjectReference{ + Name: "issuer-1", + Group: "cert-manager.io", + Kind: "Issuer", + }, + SecretName: "my-instance-cert-01", + DNSNames: []string{"my-instance.example.com"}, + }, certs[0].Spec) + + assert.Equal(t, cmv1.CertificateSpec{ + IssuerRef: cmmeta.ObjectReference{ + Name: "issuer-1", + Group: "cert-manager.io", + Kind: "Issuer", + }, + SecretName: "my-instance-cert-02", + DNSNames: []string{"my-instance2.example.com"}, + }, certs[1].Spec) + + assert.Equal(t, cmv1.CertificateSpec{ + IssuerRef: cmmeta.ObjectReference{ + Name: "issuer-2", + Group: "cert-manager.io", + Kind: "Issuer", + }, + SecretName: "my-instance-cert-03", + DNSNames: []string{"my-instance3.example.org"}, + }, certs[2].Spec) + }, + }, + "when cert manager set to use DNS zone, should create certificate": { instance: &v1alpha1.RpaasInstance{ ObjectMeta: metav1.ObjectMeta{ @@ -420,7 +533,8 @@ wg4cGbIbBPs= for name, tt := range tests { t.Run(name, func(t *testing.T) { - allResources := append(resources, tt.instance) + allResources := append([]k8sruntime.Object{}, tt.instance) + allResources = append(allResources, resources...) cli := fake.NewClientBuilder(). WithScheme(runtime.NewScheme()).