From 419bba217739aa9b3fcba11f6725955581d65c3c Mon Sep 17 00:00:00 2001 From: Haoyu Sun Date: Tue, 17 Sep 2024 19:05:33 +0200 Subject: [PATCH] customizable TLS key and cert on application server side Signed-off-by: Haoyu Sun --- api/v1alpha1/olsconfig_types.go | 9 +++ api/v1alpha1/zz_generated.deepcopy.go | 21 +++++ ...tspeed-operator.clusterserviceversion.yaml | 15 +++- .../ols.openshift.io_olsconfigs.yaml | 23 ++++++ .../bases/ols.openshift.io_olsconfigs.yaml | 17 ++++ ...tspeed-operator.clusterserviceversion.yaml | 12 +++ internal/controller/ols_app_server_assets.go | 18 +++-- .../controller/ols_app_server_assets_test.go | 80 ++++++++++++++++++- .../controller/ols_app_server_deployment.go | 7 +- .../ols_app_server_reconciliator.go | 8 +- .../ols_app_server_reconciliator_test.go | 48 ++++++++++- .../controller/ols_console_reconciliator.go | 4 +- internal/controller/ols_console_ui_assets.go | 5 +- 13 files changed, 249 insertions(+), 18 deletions(-) diff --git a/api/v1alpha1/olsconfig_types.go b/api/v1alpha1/olsconfig_types.go index afaf2690..fa2574a0 100644 --- a/api/v1alpha1/olsconfig_types.go +++ b/api/v1alpha1/olsconfig_types.go @@ -80,6 +80,9 @@ type OLSSpec struct { // User data collection switches // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="User Data Collection" UserDataCollection UserDataCollectionSpec `json:"userDataCollection,omitempty"` + // TLS configuration of the Lightspeed backend's HTTPS endpoint + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="TLS Configuration" + TLSConfig *TLSConfig `json:"tlsConfig,omitempty"` } // DeploymentConfig defines the schema for overriding deployment of OLS instance. @@ -257,6 +260,12 @@ type OLSDataCollectorSpec struct { LogLevel string `json:"logLevel,omitempty"` } +type TLSConfig struct { + // KeySecretRef is the secret that holds the TLS key. + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Key Secret" + KeyCertSecretRef corev1.LocalObjectReference `json:"keyCertSecretRef,omitempty"` +} + // +kubebuilder:object:root=true // +kubebuilder:subresource:status // +kubebuilder:resource:scope=Cluster diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index e3880bff..8de52a25 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -332,6 +332,11 @@ func (in *OLSSpec) DeepCopyInto(out *OLSSpec) { copy(*out, *in) } out.UserDataCollection = in.UserDataCollection + if in.TLSConfig != nil { + in, out := &in.TLSConfig, &out.TLSConfig + *out = new(TLSConfig) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OLSSpec. @@ -400,6 +405,22 @@ func (in *RedisSpec) DeepCopy() *RedisSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TLSConfig) DeepCopyInto(out *TLSConfig) { + *out = *in + out.KeyCertSecretRef = in.KeyCertSecretRef +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSConfig. +func (in *TLSConfig) DeepCopy() *TLSConfig { + if in == nil { + return nil + } + out := new(TLSConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *UserDataCollectionSpec) DeepCopyInto(out *UserDataCollectionSpec) { *out = *in diff --git a/bundle/manifests/lightspeed-operator.clusterserviceversion.yaml b/bundle/manifests/lightspeed-operator.clusterserviceversion.yaml index e90e2353..405cd542 100644 --- a/bundle/manifests/lightspeed-operator.clusterserviceversion.yaml +++ b/bundle/manifests/lightspeed-operator.clusterserviceversion.yaml @@ -38,7 +38,7 @@ metadata: ] capabilities: Basic Install console.openshift.io/operator-monitoring-default: "true" - createdAt: "2024-08-30T09:59:16Z" + createdAt: "2024-09-17T17:01:48Z" features.operators.openshift.io/cnf: "false" features.operators.openshift.io/cni: "false" features.operators.openshift.io/csi: "false" @@ -156,6 +156,11 @@ spec: - description: Console container settings. displayName: Console Container path: ols.deployment.console + - description: Certificate Authority (CA) certificate used by the console proxy endpoint. + displayName: CA Certificate + path: ols.deployment.console.caCertificate + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:caCertificate - displayName: Node Selector path: ols.deployment.console.nodeSelector x-descriptors: @@ -195,6 +200,12 @@ spec: - description: Replacement for the matched pattern. displayName: Replace With path: ols.queryFilters[0].replaceWith + - description: TLS configuration of the Lightspeed backend's HTTPS endpoint + displayName: TLS Configuration + path: ols.tlsConfig + - description: KeySecretRef is the secret that holds the TLS key. + displayName: Key Secret + path: ols.tlsConfig.keyCertSecretRef - description: User data collection switches displayName: User Data Collection path: ols.userDataCollection @@ -530,8 +541,8 @@ spec: type: AllNamespaces keywords: - ai - - openshift - assistant + - openshift - llm links: - name: Lightspeed Operator diff --git a/bundle/manifests/ols.openshift.io_olsconfigs.yaml b/bundle/manifests/ols.openshift.io_olsconfigs.yaml index a7335875..7b0c3fbb 100644 --- a/bundle/manifests/ols.openshift.io_olsconfigs.yaml +++ b/bundle/manifests/ols.openshift.io_olsconfigs.yaml @@ -274,6 +274,12 @@ spec: console: description: Console container settings. properties: + caCertificate: + description: Certificate Authority (CA) certificate used + by the console proxy endpoint. + pattern: ^-----BEGIN CERTIFICATE-----([\s\S]*)-----END + CERTIFICATE-----\s?$ + type: string nodeSelector: additionalProperties: type: string @@ -471,6 +477,23 @@ spec: type: string type: object type: array + tlsConfig: + description: TLS configuration of the Lightspeed backend's HTTPS + endpoint + properties: + keyCertSecretRef: + description: KeySecretRef is the secret that holds the TLS + key. + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + type: object userDataCollection: description: User data collection switches properties: diff --git a/config/crd/bases/ols.openshift.io_olsconfigs.yaml b/config/crd/bases/ols.openshift.io_olsconfigs.yaml index 7b4365fe..6f86f8f0 100644 --- a/config/crd/bases/ols.openshift.io_olsconfigs.yaml +++ b/config/crd/bases/ols.openshift.io_olsconfigs.yaml @@ -477,6 +477,23 @@ spec: type: string type: object type: array + tlsConfig: + description: TLS configuration of the Lightspeed backend's HTTPS + endpoint + properties: + keyCertSecretRef: + description: KeySecretRef is the secret that holds the TLS + key. + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + type: object userDataCollection: description: User data collection switches properties: diff --git a/config/manifests/bases/lightspeed-operator.clusterserviceversion.yaml b/config/manifests/bases/lightspeed-operator.clusterserviceversion.yaml index dc832a0a..8e5bbfd5 100644 --- a/config/manifests/bases/lightspeed-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/lightspeed-operator.clusterserviceversion.yaml @@ -123,6 +123,12 @@ spec: - description: Console container settings. displayName: Console Container path: ols.deployment.console + - description: Certificate Authority (CA) certificate used by the console proxy + endpoint. + displayName: CA Certificate + path: ols.deployment.console.caCertificate + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:caCertificate - displayName: Node Selector path: ols.deployment.console.nodeSelector x-descriptors: @@ -163,6 +169,12 @@ spec: - description: Replacement for the matched pattern. displayName: Replace With path: ols.queryFilters[0].replaceWith + - description: TLS configuration of the Lightspeed backend's HTTPS endpoint + displayName: TLS Configuration + path: ols.tlsConfig + - description: KeySecretRef is the secret that holds the TLS key. + displayName: Key Secret + path: ols.tlsConfig.keyCertSecretRef - description: User data collection switches displayName: User Data Collection path: ols.userDataCollection diff --git a/internal/controller/ols_app_server_assets.go b/internal/controller/ols_app_server_assets.go index 26ec773b..73ff5208 100644 --- a/internal/controller/ols_app_server_assets.go +++ b/internal/controller/ols_app_server_assets.go @@ -189,6 +189,16 @@ func (r *OLSConfigReconciler) generateOLSConfigMap(ctx context.Context, cr *olsv dataCollectorEnabled, _ := r.dataCollectorEnabled(cr) + tlsConfig := TLSConfig{ + TLSCertificatePath: path.Join(OLSAppCertsMountRoot, OLSCertsSecretName, "tls.crt"), + TLSKeyPath: path.Join(OLSAppCertsMountRoot, OLSCertsSecretName, "tls.key"), + } + + if cr.Spec.OLSConfig.TLSConfig != nil && cr.Spec.OLSConfig.TLSConfig.KeyCertSecretRef.Name != "" { + tlsConfig.TLSCertificatePath = path.Join(OLSAppCertsMountRoot, cr.Spec.OLSConfig.TLSConfig.KeyCertSecretRef.Name, "tls.crt") + tlsConfig.TLSKeyPath = path.Join(OLSAppCertsMountRoot, cr.Spec.OLSConfig.TLSConfig.KeyCertSecretRef.Name, "tls.key") + } + olsConfig := OLSConfig{ DefaultModel: cr.Spec.OLSConfig.DefaultModel, DefaultProvider: cr.Spec.OLSConfig.DefaultProvider, @@ -198,10 +208,7 @@ func (r *OLSConfigReconciler) generateOLSConfigMap(ctx context.Context, cr *olsv UvicornLogLevel: cr.Spec.OLSConfig.LogLevel, }, ConversationCache: conversationCache, - TLSConfig: TLSConfig{ - TLSCertificatePath: path.Join(OLSAppCertsMountRoot, OLSCertsSecretName, "tls.crt"), - TLSKeyPath: path.Join(OLSAppCertsMountRoot, OLSCertsSecretName, "tls.key"), - }, + TLSConfig: tlsConfig, ReferenceContent: ReferenceContent{ ProductDocsIndexPath: "/app-root/vector_db/ocp_product_docs/" + major + "." + minor, ProductDocsIndexId: "ocp-product-docs-" + major + "_" + minor, @@ -285,8 +292,9 @@ func (r *OLSConfigReconciler) generateService(cr *olsv1alpha1.OLSConfig) (*corev // Let service-ca operator generate a TLS certificate if the user does not provide one if cr.Spec.OLSConfig.DeploymentConfig.ConsoleContainer.CAcertificate == "" { - // Add the service-served certs annotations only if the flag is not set annotations[ServingCertSecretAnnotationKey] = OLSCertsSecretName + } else { + delete(annotations, ServingCertSecretAnnotationKey) } service := corev1.Service{ diff --git a/internal/controller/ols_app_server_assets_test.go b/internal/controller/ols_app_server_assets_test.go index 01f637bf..17165206 100644 --- a/internal/controller/ols_app_server_assets_test.go +++ b/internal/controller/ols_app_server_assets_test.go @@ -3,8 +3,14 @@ package controller import ( "context" "crypto/rand" + "crypto/rsa" + "crypto/x509" + "crypto/x509/pkix" "encoding/base64" + "encoding/pem" + "math/big" "path" + "time" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -592,6 +598,43 @@ var _ = Describe("App server assets", func() { }, )) }) + + It("should use user provided TLS settings if user provided one", func() { + const tlsSecretName = "test-tls-secret" + cr.Spec.OLSConfig.TLSConfig = &olsv1alpha1.TLSConfig{ + KeyCertSecretRef: corev1.LocalObjectReference{ + Name: tlsSecretName, + }, + } + cm, err := r.generateOLSConfigMap(context.TODO(), cr) + Expect(err).NotTo(HaveOccurred()) + olsconfigGenerated := AppSrvConfigFile{} + err = yaml.Unmarshal([]byte(cm.Data[OLSConfigFilename]), &olsconfigGenerated) + Expect(err).NotTo(HaveOccurred()) + Expect(olsconfigGenerated.OLSConfig.TLSConfig.TLSCertificatePath).To(Equal(path.Join(OLSAppCertsMountRoot, tlsSecretName, "tls.crt"))) + Expect(olsconfigGenerated.OLSConfig.TLSConfig.TLSKeyPath).To(Equal(path.Join(OLSAppCertsMountRoot, tlsSecretName, "tls.key"))) + + deployment, err := r.generateOLSDeployment(cr) + Expect(err).NotTo(HaveOccurred()) + Expect(deployment.Spec.Template.Spec.Containers[0].VolumeMounts).To(ContainElement( + corev1.VolumeMount{ + Name: "secret-" + tlsSecretName, + MountPath: path.Join(OLSAppCertsMountRoot, tlsSecretName), + ReadOnly: true, + }, + )) + Expect(deployment.Spec.Template.Spec.Volumes).To(ContainElement( + corev1.Volume{ + Name: "secret-" + tlsSecretName, + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: tlsSecretName, + DefaultMode: &defaultVolumeMode, + }, + }, + }, + )) + }) }) Context("empty custom resource", func() { @@ -879,6 +922,38 @@ func generateRandomSecret() (*corev1.Secret, error) { // Encode the password to base64 encodedPassword := base64.StdEncoding.EncodeToString(randomPassword) passwordHash, _ := hashBytes([]byte(encodedPassword)) + + // Generate RSA key + privateKey, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + return nil, err + } + privateKeyPEM := pem.EncodeToMemory(&pem.Block{ + Type: "RSA PRIVATE KEY", + Bytes: x509.MarshalPKCS1PrivateKey(privateKey), + }) + + // Generate self-signed certificate + template := x509.Certificate{ + SerialNumber: big.NewInt(1), + Subject: pkix.Name{ + Organization: []string{"Test Org"}, + }, + NotBefore: time.Now(), + NotAfter: time.Now().Add(365 * 24 * time.Hour), + KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + BasicConstraintsValid: true, + } + certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &privateKey.PublicKey, privateKey) + if err != nil { + return nil, err + } + certPEM := pem.EncodeToMemory(&pem.Block{ + Type: "CERTIFICATE", + Bytes: certDER, + }) + secret := corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "test-secret", @@ -888,10 +963,11 @@ func generateRandomSecret() (*corev1.Secret, error) { }, Data: map[string][]byte{ "client_secret": []byte(passwordHash), - "tls.key": []byte("test tls key"), - "tls.crt": []byte("test tls crt"), + "tls.key": privateKeyPEM, + "tls.crt": certPEM, }, } + return &secret, nil } diff --git a/internal/controller/ols_app_server_deployment.go b/internal/controller/ols_app_server_deployment.go index aa63642c..91cdc51a 100644 --- a/internal/controller/ols_app_server_deployment.go +++ b/internal/controller/ols_app_server_deployment.go @@ -82,8 +82,11 @@ func (r *OLSConfigReconciler) generateOLSDeployment(cr *olsv1alpha1.OLSConfig) ( //secretMounts[redisSecretName] = redisCredentialsMountPath // TLS volume - tlsSecretNameMountPath := path.Join(OLSAppCertsMountRoot, OLSCertsSecretName) - secretMounts[OLSCertsSecretName] = tlsSecretNameMountPath + if cr.Spec.OLSConfig.TLSConfig != nil && cr.Spec.OLSConfig.TLSConfig.KeyCertSecretRef.Name != "" { + secretMounts[cr.Spec.OLSConfig.TLSConfig.KeyCertSecretRef.Name] = path.Join(OLSAppCertsMountRoot, cr.Spec.OLSConfig.TLSConfig.KeyCertSecretRef.Name) + } else { + secretMounts[OLSCertsSecretName] = path.Join(OLSAppCertsMountRoot, OLSCertsSecretName) + } // Container ports ports := []corev1.ContainerPort{ diff --git a/internal/controller/ols_app_server_reconciliator.go b/internal/controller/ols_app_server_reconciliator.go index 3652aac2..5a9a3dad 100644 --- a/internal/controller/ols_app_server_reconciliator.go +++ b/internal/controller/ols_app_server_reconciliator.go @@ -371,10 +371,14 @@ func (r *OLSConfigReconciler) reconcileTLSSecret(ctx context.Context, cr *olsv1a foundSecret := &corev1.Secret{} var err, lastErr error var secretValues map[string]string + secretName := OLSCertsSecretName + if cr.Spec.OLSConfig.TLSConfig != nil && cr.Spec.OLSConfig.TLSConfig.KeyCertSecretRef.Name != "" { + secretName = cr.Spec.OLSConfig.TLSConfig.KeyCertSecretRef.Name + } err = wait.PollUntilContextTimeout(ctx, 1*time.Second, ResourceCreationTimeout, true, func(ctx context.Context) (bool, error) { - secretValues, err = getSecretContent(r.Client, OLSCertsSecretName, r.Options.Namespace, []string{"tls.key", "tls.crt"}, foundSecret) + secretValues, err = getSecretContent(r.Client, secretName, r.Options.Namespace, []string{"tls.key", "tls.crt"}, foundSecret) if err != nil { - lastErr = fmt.Errorf("secret: %s does not have expected tls.key or tls.crt. error: %w", OLSCertsSecretName, err) + lastErr = fmt.Errorf("secret: %s does not have expected tls.key or tls.crt. error: %w", secretName, err) return false, nil } return true, nil diff --git a/internal/controller/ols_app_server_reconciliator_test.go b/internal/controller/ols_app_server_reconciliator_test.go index a2e6a9cd..dec653d4 100644 --- a/internal/controller/ols_app_server_reconciliator_test.go +++ b/internal/controller/ols_app_server_reconciliator_test.go @@ -20,6 +20,8 @@ var _ = Describe("App server reconciliator", Ordered, func() { Context("Creation logic", Ordered, func() { var secret *corev1.Secret var tlsSecret *corev1.Secret + var tlsUserSecret *corev1.Secret + const tlsUserSecretName = "tls-user-secret" BeforeEach(func() { By("create the provider secret") secret, _ = generateRandomSecret() @@ -34,7 +36,7 @@ var _ = Describe("App server reconciliator", Ordered, func() { secretCreationErr := reconciler.Create(ctx, secret) Expect(secretCreationErr).NotTo(HaveOccurred()) - By("create the tls secret") + By("create the default tls secret") tlsSecret, _ = generateRandomSecret() tlsSecret.Name = OLSCertsSecretName tlsSecret.SetOwnerReferences([]metav1.OwnerReference{ @@ -47,6 +49,13 @@ var _ = Describe("App server reconciliator", Ordered, func() { }) secretCreationErr = reconciler.Create(ctx, tlsSecret) Expect(secretCreationErr).NotTo(HaveOccurred()) + + By("create user provided tls secret") + tlsUserSecret, _ = generateRandomSecret() + tlsUserSecret.Name = tlsUserSecretName + secretCreationErr = reconciler.Create(ctx, tlsUserSecret) + Expect(secretCreationErr).NotTo(HaveOccurred()) + }) AfterEach(func() { @@ -57,6 +66,10 @@ var _ = Describe("App server reconciliator", Ordered, func() { By("Delete the tls secret") secretDeletionErr = reconciler.Delete(ctx, tlsSecret) Expect(secretDeletionErr).NotTo(HaveOccurred()) + + By("Delete the user provided tls secret") + secretDeletionErr = reconciler.Delete(ctx, tlsUserSecret) + Expect(secretDeletionErr).NotTo(HaveOccurred()) }) It("should reconcile from OLSConfig custom resource", func() { @@ -272,6 +285,39 @@ var _ = Describe("App server reconciliator", Ordered, func() { Expect(dep.Annotations[OLSAppTLSHashKey]).NotTo(Equal(oldHash)) }) + It("should update the deployment when switching to user provided tls secret", func() { + By("Get the old hash") + dep := &appsv1.Deployment{} + err := k8sClient.Get(ctx, types.NamespacedName{Name: OLSAppServerDeploymentName, Namespace: OLSNamespaceDefault}, dep) + Expect(err).NotTo(HaveOccurred()) + Expect(dep.Spec.Template.Annotations).NotTo(BeNil()) + oldHash := dep.Spec.Template.Annotations[OLSAppTLSHashKey] + Expect(oldHash).NotTo(BeEmpty()) + + By("Change OLSConfig to use user provided tls secret and reconcile") + olsConfig := cr.DeepCopy() + olsConfig.Spec.OLSConfig.TLSConfig = &olsv1alpha1.TLSConfig{ + KeyCertSecretRef: corev1.LocalObjectReference{ + Name: tlsUserSecretName, + }, + } + err = reconciler.reconcileAppServer(ctx, olsConfig) + Expect(err).NotTo(HaveOccurred()) + + By("Check new hash is updated") + dep = &appsv1.Deployment{} + err = k8sClient.Get(ctx, types.NamespacedName{Name: OLSAppServerDeploymentName, Namespace: OLSNamespaceDefault}, dep) + Expect(err).NotTo(HaveOccurred()) + bytesArr := make([]byte, len(tlsUserSecret.Data["tls.key"])+len(tlsUserSecret.Data["tls.crt"])) + copy(bytesArr, tlsUserSecret.Data["tls.key"]) + copy(bytesArr[len(tlsUserSecret.Data["tls.key"]):], tlsUserSecret.Data["tls.crt"]) + newHash, err := hashBytes(bytesArr) + Expect(err).NotTo(HaveOccurred()) + Expect(newHash).NotTo(Equal(oldHash)) + Expect(dep.Spec.Template.Annotations[OLSAppTLSHashKey]).To(Equal(newHash)) + + }) + It("should trigger rolling update of the deployment when changing LLM secret content", func() { By("Reconcile for LLM Provider Secrets") diff --git a/internal/controller/ols_console_reconciliator.go b/internal/controller/ols_console_reconciliator.go index e0ae72c2..c2a2dc51 100644 --- a/internal/controller/ols_console_reconciliator.go +++ b/internal/controller/ols_console_reconciliator.go @@ -19,7 +19,7 @@ import ( olsv1alpha1 "github.com/openshift/lightspeed-operator/api/v1alpha1" ) -func (r *OLSConfigReconciler) reconcileConsoleUI(ctx context.Context, cr *olsv1alpha1.OLSConfig) error { +func (r *OLSConfigReconciler) reconcileConsoleUI(ctx context.Context, olsconfig *olsv1alpha1.OLSConfig) error { r.logger.Info("reconcileConsoleUI starts") tasks := []ReconcileTask{ { @@ -49,7 +49,7 @@ func (r *OLSConfigReconciler) reconcileConsoleUI(ctx context.Context, cr *olsv1a } for _, task := range tasks { - err := task.Task(ctx, cr) + err := task.Task(ctx, olsconfig) if err != nil { r.logger.Error(err, "reconcileConsoleUI error", "task", task.Name) return fmt.Errorf("failed to %s: %w", task.Name, err) diff --git a/internal/controller/ols_console_ui_assets.go b/internal/controller/ols_console_ui_assets.go index 780512fc..2471258c 100644 --- a/internal/controller/ols_console_ui_assets.go +++ b/internal/controller/ols_console_ui_assets.go @@ -101,6 +101,7 @@ func (r *OLSConfigReconciler) generateConsoleUIService(cr *olsv1alpha1.OLSConfig } func (r *OLSConfigReconciler) generateConsoleUIDeployment(cr *olsv1alpha1.OLSConfig) (*appsv1.Deployment, error) { + const certVolumeName = "lightspeed-console-plugin-cert" replicas := int32(2) val_true := true volumeDefaultMode := int32(420) @@ -137,7 +138,7 @@ func (r *OLSConfigReconciler) generateConsoleUIDeployment(cr *olsv1alpha1.OLSCon Resources: *resources, VolumeMounts: []corev1.VolumeMount{ { - Name: "lightspeed-console-plugin-cert", + Name: certVolumeName, MountPath: "/var/cert", ReadOnly: true, }, @@ -152,7 +153,7 @@ func (r *OLSConfigReconciler) generateConsoleUIDeployment(cr *olsv1alpha1.OLSCon }, Volumes: []corev1.Volume{ { - Name: "lightspeed-console-plugin-cert", + Name: certVolumeName, VolumeSource: corev1.VolumeSource{ Secret: &corev1.SecretVolumeSource{ SecretName: ConsoleUIServiceCertSecretName,