From 5e95b66264b5faea861d95b8828ce9dda97c70ce Mon Sep 17 00:00:00 2001 From: Alexandre Vilain Date: Sun, 28 Apr 2024 17:40:43 +0200 Subject: [PATCH] fix(mtls): dns name should contains service fqdn + add ability to add extra dns dns --- api/v1beta1/temporalcluster_types.go | 20 +++++++++---- api/v1beta1/zz_generated.deepcopy.go | 7 ++++- .../bases/temporal.io_temporalclusters.yaml | 28 ++++++++++++++++++- .../temporalclusterclient_controller.go | 2 +- docs/api/v1beta1.md | 13 +++++++++ .../cluster-mtls/02-temporal-cluster.yaml | 1 + internal/resource/config/configmap_builder.go | 6 ++-- internal/resource/mtls/certmanager/env.go | 2 +- .../mtls_frontend_certificate_builder.go | 7 ++++- .../mtls_internode_certificate_builder.go | 2 +- pkg/temporal/client.go | 2 +- 11 files changed, 75 insertions(+), 15 deletions(-) diff --git a/api/v1beta1/temporalcluster_types.go b/api/v1beta1/temporalcluster_types.go index 6038635d..e4282eee 100644 --- a/api/v1beta1/temporalcluster_types.go +++ b/api/v1beta1/temporalcluster_types.go @@ -604,11 +604,16 @@ type FrontendMTLSSpec struct { // Enabled defines if the operator should enable mTLS for cluster's public endpoints. // +optional Enabled bool `json:"enabled"` + // ExtraDNSNames is a list of additional DNS names associated with the TemporalCluster. + // These DNS names can be used for accessing the TemporalCluster from external services. + // The DNS names specified here will be added to the TLS certificate for secure communication. + // +nullable + ExtraDNSNames []string `json:"extraDnsNames,omitempty"` } // ServerName returns frontend servername for mTLS certificates. -func (FrontendMTLSSpec) ServerName(serverName string) string { - return fmt.Sprintf("frontend.%s", serverName) +func (FrontendMTLSSpec) ServerName(cluster *TemporalCluster) string { + return fmt.Sprintf("%s.%s", cluster.ChildResourceName("frontend"), cluster.FQDNSuffix()) } // GetIntermediateCACertificateMountPath returns the mount path for intermediate CA certificates. @@ -634,8 +639,8 @@ type InternodeMTLSSpec struct { } // ServerName returns internode servername for mTLS certificates. -func (InternodeMTLSSpec) ServerName(serverName string) string { - return fmt.Sprintf("internode.%s", serverName) +func (InternodeMTLSSpec) ServerName(cluster *TemporalCluster) string { + return fmt.Sprintf("%s.%s", cluster.ChildResourceName("internode"), cluster.FQDNSuffix()) } // GetIntermediateCACertificateMountPath returns the mount path for intermediate CA certificates. @@ -1142,7 +1147,12 @@ func (c *TemporalCluster) SelectorLabels() map[string]string { // ServerName returns cluster's server name. func (c *TemporalCluster) ServerName() string { - return fmt.Sprintf("%s.%s.svc.cluster.local", c.Name, c.Namespace) + return fmt.Sprintf("%s.%s", c.Name, c.FQDNSuffix()) +} + +// FQDNSuffix returns the cluster's FQDN suffix. +func (c *TemporalCluster) FQDNSuffix() string { + return fmt.Sprintf("%s.svc.cluster.local", c.Namespace) } // MTLSEnabled returns true if mTLS is enabled for internode or frontend using cert-manager. diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index 8e27c586..b7030c70 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -518,6 +518,11 @@ func (in *FilestoreArchiver) DeepCopy() *FilestoreArchiver { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *FrontendMTLSSpec) DeepCopyInto(out *FrontendMTLSSpec) { *out = *in + if in.ExtraDNSNames != nil { + in, out := &in.ExtraDNSNames, &out.ExtraDNSNames + *out = make([]string, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FrontendMTLSSpec. @@ -647,7 +652,7 @@ func (in *MTLSSpec) DeepCopyInto(out *MTLSSpec) { if in.Frontend != nil { in, out := &in.Frontend, &out.Frontend *out = new(FrontendMTLSSpec) - **out = **in + (*in).DeepCopyInto(*out) } if in.CertificatesDuration != nil { in, out := &in.CertificatesDuration, &out.CertificatesDuration diff --git a/config/crd/bases/temporal.io_temporalclusters.yaml b/config/crd/bases/temporal.io_temporalclusters.yaml index eee031d4..e018b5b9 100644 --- a/config/crd/bases/temporal.io_temporalclusters.yaml +++ b/config/crd/bases/temporal.io_temporalclusters.yaml @@ -479,6 +479,12 @@ spec: enabled: description: Enabled defines if the operator should enable mTLS for cluster's public endpoints. type: boolean + extraDnsNames: + description: ExtraDNSNames is a list of additional DNS names associated with the TemporalCluster. These DNS names can be used for accessing the TemporalCluster from external services. The DNS names specified here will be added to the TLS certificate for secure communication. + items: + type: string + nullable: true + type: array type: object internode: description: Internode allows configuration of the internode traffic encryption. Useless if mTLS provider is not cert-manager. @@ -619,6 +625,10 @@ spec: description: When set to true, Prometheus must have the `get` permission on the `Nodes` objects. type: boolean type: object + bodySizeLimit: + description: "When defined, bodySizeLimit specifies a job level limit on the size of uncompressed response body that will be accepted by Prometheus. \n It requires Prometheus >= v2.28.0." + pattern: (^0|([0-9]*[.])?[0-9]+((K|M|G|T|E|P)i?)?B)$ + type: string endpoints: description: List of endpoints part of this ServiceMonitor. items: @@ -939,7 +949,7 @@ spec: anyOf: - type: integer - type: string - description: "Name or number of the target port of the `Pod` object behind the Service, the port must be specified with container port property. \n Deprecated: use `port` instead." + description: Name or number of the target port of the `Pod` object behind the Service. The port must be specified with the container's port property. x-kubernetes-int-or-string: true tlsConfig: description: TLS configuration to use when scraping the target. @@ -1093,6 +1103,22 @@ spec: description: '`sampleLimit` defines a per-scrape limit on the number of scraped samples that will be accepted.' format: int64 type: integer + scrapeClass: + description: The scrape class to apply. + minLength: 1 + type: string + scrapeProtocols: + description: "`scrapeProtocols` defines the protocols to negotiate during a scrape. It tells clients the protocols supported by Prometheus in order of preference (from most to least preferred). \n If unset, Prometheus uses its default value. \n It requires Prometheus >= v2.49.0." + items: + description: 'ScrapeProtocol represents a protocol used by Prometheus for scraping metrics. Supported values are: * `OpenMetricsText0.0.1` * `OpenMetricsText1.0.0` * `PrometheusProto` * `PrometheusText0.0.4`' + enum: + - PrometheusProto + - OpenMetricsText0.0.1 + - OpenMetricsText1.0.0 + - PrometheusText0.0.4 + type: string + type: array + x-kubernetes-list-type: set selector: description: Label selector to select the Kubernetes `Endpoints` objects. properties: diff --git a/controllers/temporalclusterclient_controller.go b/controllers/temporalclusterclient_controller.go index 021eb2e8..6382a7fd 100644 --- a/controllers/temporalclusterclient_controller.go +++ b/controllers/temporalclusterclient_controller.go @@ -110,7 +110,7 @@ func (r *TemporalClusterClientReconciler) Reconcile(ctx context.Context, req ctr return reconcile.Result{Requeue: false}, errors.New("mTLS for frontend not enabled using cert-manager for the cluster, can't create a client") } - clusterClient.Status.ServerName = cluster.Spec.MTLS.Frontend.ServerName(cluster.ServerName()) + clusterClient.Status.ServerName = cluster.Spec.MTLS.Frontend.ServerName(cluster) if clusterClient.Status.SecretRef == nil { clusterClient.Status.SecretRef = &corev1.LocalObjectReference{ Name: "", diff --git a/docs/api/v1beta1.md b/docs/api/v1beta1.md index 758774ec..5e00e866 100644 --- a/docs/api/v1beta1.md +++ b/docs/api/v1beta1.md @@ -1972,6 +1972,19 @@ bool

Enabled defines if the operator should enable mTLS for cluster’s public endpoints.

+ + +extraDnsNames
+ +[]string + + + +

ExtraDNSNames is a list of additional DNS names associated with the TemporalCluster. +These DNS names can be used for accessing the TemporalCluster from external services. +The DNS names specified here will be added to the TLS certificate for secure communication.

+ + diff --git a/examples/cluster-mtls/02-temporal-cluster.yaml b/examples/cluster-mtls/02-temporal-cluster.yaml index 665fe0c8..0542822d 100644 --- a/examples/cluster-mtls/02-temporal-cluster.yaml +++ b/examples/cluster-mtls/02-temporal-cluster.yaml @@ -34,6 +34,7 @@ spec: enabled: true frontend: enabled: true + extraDnsNames: [] certificatesDuration: rootCACertificate: 2h intermediateCAsCertificates: 1h30m diff --git a/internal/resource/config/configmap_builder.go b/internal/resource/config/configmap_builder.go index c834ff18..1be97a63 100644 --- a/internal/resource/config/configmap_builder.go +++ b/internal/resource/config/configmap_builder.go @@ -365,7 +365,7 @@ func (b *ConfigmapBuilder) Update(object client.Object) error { internodeServerCertFilePath := path.Join(internodeMTLS.GetCertificateMountPath(), certmanager.TLSCert) internodeServerKeyFilePath := path.Join(internodeMTLS.GetCertificateMountPath(), certmanager.TLSKey) internodeClientTLS := config.ClientTLS{ - ServerName: internodeMTLS.ServerName(b.instance.ServerName()), + ServerName: internodeMTLS.ServerName(b.instance), DisableHostVerification: false, RootCAFiles: []string{internodeIntermediateCAFilePath}, ForceTLS: true, @@ -410,7 +410,7 @@ func (b *ConfigmapBuilder) Update(object client.Object) error { }, }, Client: config.ClientTLS{ - ServerName: frontendMTLS.ServerName(b.instance.ServerName()), + ServerName: frontendMTLS.ServerName(b.instance), DisableHostVerification: false, RootCAFiles: []string{frontendIntermediateCAFilePath}, ForceTLS: true, @@ -424,7 +424,7 @@ func (b *ConfigmapBuilder) Update(object client.Object) error { CertFile: path.Join(frontendMTLS.GetWorkerCertificateMountPath(), certmanager.TLSCert), KeyFile: path.Join(frontendMTLS.GetWorkerCertificateMountPath(), certmanager.TLSKey), Client: config.ClientTLS{ - ServerName: frontendMTLS.ServerName(b.instance.ServerName()), + ServerName: frontendMTLS.ServerName(b.instance), DisableHostVerification: false, RootCAFiles: []string{frontendIntermediateCAFilePath}, ForceTLS: true, diff --git a/internal/resource/mtls/certmanager/env.go b/internal/resource/mtls/certmanager/env.go index 2ddbf4fc..09d4c521 100644 --- a/internal/resource/mtls/certmanager/env.go +++ b/internal/resource/mtls/certmanager/env.go @@ -55,7 +55,7 @@ func GetTLSEnvironmentVariables(instance *v1beta1.TemporalCluster, envPrefix, ce }, { Name: addPrefix(envPrefix, "TLS_SERVER_NAME"), - Value: instance.Spec.MTLS.Frontend.ServerName(instance.ServerName()), + Value: instance.Spec.MTLS.Frontend.ServerName(instance), }, } } diff --git a/internal/resource/mtls/certmanager/mtls_frontend_certificate_builder.go b/internal/resource/mtls/certmanager/mtls_frontend_certificate_builder.go index b06e4c0e..4373bc57 100644 --- a/internal/resource/mtls/certmanager/mtls_frontend_certificate_builder.go +++ b/internal/resource/mtls/certmanager/mtls_frontend_certificate_builder.go @@ -73,7 +73,7 @@ func (b *MTLSFrontendCertificateBuilder) Update(object client.Object) error { Size: 4096, }, DNSNames: []string{ - b.instance.Spec.MTLS.Frontend.ServerName(b.instance.ServerName()), + b.instance.Spec.MTLS.Frontend.ServerName(b.instance), }, IssuerRef: certmanagermeta.ObjectReference{ Name: b.instance.ChildResourceName(frontendIntermediateCAIssuer), @@ -84,6 +84,11 @@ func (b *MTLSFrontendCertificateBuilder) Update(object client.Object) error { }, } + // Add user-supplied extra DNS names. + certificate.Spec.DNSNames = append(certificate.Spec.DNSNames, + b.instance.Spec.MTLS.Frontend.ExtraDNSNames..., + ) + if err := controllerutil.SetControllerReference(b.instance, certificate, b.scheme); err != nil { return fmt.Errorf("failed setting controller reference: %w", err) } diff --git a/internal/resource/mtls/certmanager/mtls_internode_certificate_builder.go b/internal/resource/mtls/certmanager/mtls_internode_certificate_builder.go index 1f359caf..d820dfba 100644 --- a/internal/resource/mtls/certmanager/mtls_internode_certificate_builder.go +++ b/internal/resource/mtls/certmanager/mtls_internode_certificate_builder.go @@ -73,7 +73,7 @@ func (b *MTLSInternodeCertificateBuilder) Update(object client.Object) error { Size: 4096, }, DNSNames: []string{ - b.instance.Spec.MTLS.Internode.ServerName(b.instance.ServerName()), + b.instance.Spec.MTLS.Internode.ServerName(b.instance), }, IssuerRef: certmanagermeta.ObjectReference{ Name: b.instance.ChildResourceName(internodeIntermediateCAIssuer), diff --git a/pkg/temporal/client.go b/pkg/temporal/client.go index 466e65a7..797bf9f6 100644 --- a/pkg/temporal/client.go +++ b/pkg/temporal/client.go @@ -86,7 +86,7 @@ func GetClusterClientTLSConfig(ctx context.Context, client client.Client, cluste return nil, err } - tlsConfig.ServerName = cluster.Spec.MTLS.Frontend.ServerName(cluster.ServerName()) + tlsConfig.ServerName = cluster.Spec.MTLS.Frontend.ServerName(cluster) return tlsConfig, nil }