diff --git a/api/v1alpha1/olsconfig_types.go b/api/v1alpha1/olsconfig_types.go index a58c720d5..b6ef0db97 100644 --- a/api/v1alpha1/olsconfig_types.go +++ b/api/v1alpha1/olsconfig_types.go @@ -105,6 +105,11 @@ type OLSSpec struct { // +kubebuilder:validation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Introspection Enabled",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} IntrospectionEnabled bool `json:"introspectionEnabled,omitempty"` + // Hide Lightspeed icon in the console UI for Users with no access to the OLS API + // +kubebuilder:validation:Optional + // +kubebuilder:default=false + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Hide Icon",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} + HideIcon bool `json:"hideIcon,omitempty"` // Proxy settings for connecting to external servers, such as LLM providers. // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Proxy Settings",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:advanced"} // +kubebuilder:validation:Optional diff --git a/bundle/manifests/lightspeed-operator.clusterserviceversion.yaml b/bundle/manifests/lightspeed-operator.clusterserviceversion.yaml index f5707c07f..7429ff476 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: "2025-08-28T16:37:51Z" + createdAt: "2025-09-15T01:15:30Z" features.operators.openshift.io/cnf: "false" features.operators.openshift.io/cni: "false" features.operators.openshift.io/csi: "false" @@ -258,6 +258,11 @@ spec: path: ols.deployment.replicas x-descriptors: - urn:alm:descriptor:com.tectonic.ui:podCount + - description: Hide Lightspeed icon in the console UI for Users with no access to the OLS API + displayName: Hide Icon + path: ols.hideIcon + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - description: Enable introspection features displayName: Introspection Enabled path: ols.introspectionEnabled diff --git a/bundle/manifests/ols.openshift.io_olsconfigs.yaml b/bundle/manifests/ols.openshift.io_olsconfigs.yaml index c684aea2f..1e74a8ea0 100644 --- a/bundle/manifests/ols.openshift.io_olsconfigs.yaml +++ b/bundle/manifests/ols.openshift.io_olsconfigs.yaml @@ -917,6 +917,10 @@ spec: minimum: 0 type: integer type: object + hideIcon: + default: false + description: Hide Lightspeed icon in the console UI for Users with no access to the OLS API + type: boolean introspectionEnabled: description: Enable introspection features type: boolean diff --git a/config/crd/bases/ols.openshift.io_olsconfigs.yaml b/config/crd/bases/ols.openshift.io_olsconfigs.yaml index fe94565bd..d76847327 100644 --- a/config/crd/bases/ols.openshift.io_olsconfigs.yaml +++ b/config/crd/bases/ols.openshift.io_olsconfigs.yaml @@ -917,6 +917,11 @@ spec: minimum: 0 type: integer type: object + hideIcon: + default: false + description: Hide Lightspeed icon in the console UI for Users + with no access to the OLS API + type: boolean introspectionEnabled: description: Enable introspection features type: boolean diff --git a/config/manifests/bases/lightspeed-operator.clusterserviceversion.yaml b/config/manifests/bases/lightspeed-operator.clusterserviceversion.yaml index ce29b77e5..d67fbd498 100644 --- a/config/manifests/bases/lightspeed-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/lightspeed-operator.clusterserviceversion.yaml @@ -228,6 +228,11 @@ spec: path: ols.deployment.replicas x-descriptors: - urn:alm:descriptor:com.tectonic.ui:podCount + - description: Hide Lightspeed icon in the console UI for Users with no access to the OLS API + displayName: Hide Icon + path: ols.hideIcon + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - description: Enable introspection features displayName: Introspection Enabled path: ols.introspectionEnabled diff --git a/internal/controller/ols_console_ui_assets.go b/internal/controller/ols_console_ui_assets.go index 8f8a73a1a..a933992a5 100644 --- a/internal/controller/ols_console_ui_assets.go +++ b/internal/controller/ols_console_ui_assets.go @@ -1,6 +1,8 @@ package controller import ( + "fmt" + consolev1 "github.com/openshift/api/console/v1" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -36,6 +38,17 @@ func getConsoleUIResources(cr *olsv1alpha1.OLSConfig) *corev1.ResourceRequiremen return defaultResources } +func getHideIconEnvVar(cr *olsv1alpha1.OLSConfig) corev1.EnvVar { + // The CRD has a default of false, so we can use the value directly + // If the field is not set, it will default to false + hideIcon := cr.Spec.OLSConfig.HideIcon + + return corev1.EnvVar{ + Name: "HIDE_ICON", + Value: fmt.Sprintf("%t", hideIcon), + } +} + func (r *OLSConfigReconciler) generateConsoleUIConfigMap(cr *olsv1alpha1.OLSConfig) (*corev1.ConfigMap, error) { nginxConfig := ` pid /tmp/nginx/nginx.pid; @@ -144,7 +157,7 @@ func (r *OLSConfigReconciler) generateConsoleUIDeployment(cr *olsv1alpha1.OLSCon ReadOnlyRootFilesystem: &[]bool{true}[0], }, ImagePullPolicy: corev1.PullAlways, - Env: getProxyEnvVars(), + Env: append(getProxyEnvVars(), getHideIconEnvVar(cr)), Resources: *resources, VolumeMounts: []corev1.VolumeMount{ { diff --git a/internal/controller/ols_console_ui_assets_test.go b/internal/controller/ols_console_ui_assets_test.go index 19db9c656..6cf5449dd 100644 --- a/internal/controller/ols_console_ui_assets_test.go +++ b/internal/controller/ols_console_ui_assets_test.go @@ -141,4 +141,111 @@ var _ = Describe("Console UI assets", func() { }) }) + + Context("hideIcon environment variable", func() { + BeforeEach(func() { + cr = getDefaultOLSConfigCR() + }) + + It("should set HIDE_ICON to false by default", func() { + dep, err := r.generateConsoleUIDeployment(cr) + Expect(err).NotTo(HaveOccurred()) + + // Find the HIDE_ICON environment variable + var hideIconEnv *corev1.EnvVar + for _, env := range dep.Spec.Template.Spec.Containers[0].Env { + if env.Name == "HIDE_ICON" { + hideIconEnv = &env + break + } + } + + Expect(hideIconEnv).NotTo(BeNil()) + Expect(hideIconEnv.Value).To(Equal("false")) + }) + + It("should set HIDE_ICON to true when HideIcon is true", func() { + cr.Spec.OLSConfig.HideIcon = true + dep, err := r.generateConsoleUIDeployment(cr) + Expect(err).NotTo(HaveOccurred()) + + // Find the HIDE_ICON environment variable + var hideIconEnv *corev1.EnvVar + for _, env := range dep.Spec.Template.Spec.Containers[0].Env { + if env.Name == "HIDE_ICON" { + hideIconEnv = &env + break + } + } + + Expect(hideIconEnv).NotTo(BeNil()) + Expect(hideIconEnv.Value).To(Equal("true")) + }) + + It("should set HIDE_ICON to false when HideIcon is false", func() { + cr.Spec.OLSConfig.HideIcon = false + dep, err := r.generateConsoleUIDeployment(cr) + Expect(err).NotTo(HaveOccurred()) + + // Find the HIDE_ICON environment variable + var hideIconEnv *corev1.EnvVar + for _, env := range dep.Spec.Template.Spec.Containers[0].Env { + if env.Name == "HIDE_ICON" { + hideIconEnv = &env + break + } + } + + Expect(hideIconEnv).NotTo(BeNil()) + Expect(hideIconEnv.Value).To(Equal("false")) + }) + }) + + Context("getHideIconEnvVar function", func() { + BeforeEach(func() { + cr = getDefaultOLSConfigCR() + }) + + It("should return HIDE_ICON=false by default", func() { + envVar := getHideIconEnvVar(cr) + Expect(envVar.Name).To(Equal("HIDE_ICON")) + Expect(envVar.Value).To(Equal("false")) + }) + + It("should return HIDE_ICON=true when HideIcon is true", func() { + cr.Spec.OLSConfig.HideIcon = true + envVar := getHideIconEnvVar(cr) + Expect(envVar.Name).To(Equal("HIDE_ICON")) + Expect(envVar.Value).To(Equal("true")) + }) + + It("should return HIDE_ICON=false when HideIcon is false", func() { + cr.Spec.OLSConfig.HideIcon = false + envVar := getHideIconEnvVar(cr) + Expect(envVar.Name).To(Equal("HIDE_ICON")) + Expect(envVar.Value).To(Equal("false")) + }) + }) + + Context("CRD validation", func() { + It("should have hideIcon field in the CRD", func() { + // This test verifies that the CRD contains the hideIcon field + cr := &olsv1alpha1.OLSConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-ols-config", + Namespace: "default", + }, + Spec: olsv1alpha1.OLSConfigSpec{ + OLSConfig: olsv1alpha1.OLSSpec{ + DefaultModel: "test-model", + DefaultProvider: "test-provider", + HideIcon: false, // This should be valid + }, + }, + } + Expect(cr.Spec.OLSConfig.HideIcon).To(BeFalse()) + cr.Spec.OLSConfig.HideIcon = true + Expect(cr.Spec.OLSConfig.HideIcon).To(BeTrue()) + }) + }) })