diff --git a/internal/controller/ca_bundle.go b/internal/controller/ca_bundle.go index 7c43a1d..7960796 100644 --- a/internal/controller/ca_bundle.go +++ b/internal/controller/ca_bundle.go @@ -170,7 +170,7 @@ func reconcileCABundleConfigMap(h *common_helper.Helper, ctx context.Context, in cm := &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ - Name: CABundleConfigMapName, + Name: CABundleConfigMapName(instance.Name), Namespace: h.GetBeforeObject().GetNamespace(), }, } diff --git a/internal/controller/ca_bundle_test.go b/internal/controller/ca_bundle_test.go index 5105ed3..ef1430c 100644 --- a/internal/controller/ca_bundle_test.go +++ b/internal/controller/ca_bundle_test.go @@ -480,7 +480,7 @@ func TestReconcileCABundle_MergesServiceCA(t *testing.T) { resultCM := &corev1.ConfigMap{} err = h.GetClient().Get(ctx, types.NamespacedName{ - Name: CABundleConfigMapName, + Name: CABundleConfigMapName("test-instance"), Namespace: "test-ns", }, resultCM) if err != nil { @@ -620,7 +620,7 @@ func TestReconcileCABundle_DeduplicatesAcrossSources(t *testing.T) { resultCM := &corev1.ConfigMap{} err = h.GetClient().Get(ctx, types.NamespacedName{ - Name: CABundleConfigMapName, + Name: CABundleConfigMapName("test-instance"), Namespace: "test-ns", }, resultCM) if err != nil { diff --git a/internal/controller/common.go b/internal/controller/common.go index c4b4d94..03e25cb 100644 --- a/internal/controller/common.go +++ b/internal/controller/common.go @@ -57,11 +57,10 @@ func getRawClient(helper *common_helper.Helper) (client.Client, error) { return rawClient, nil } -// generateAppServerSelectorLabels returns a map of labels used as selectors -// for the application server pods. -func generateAppServerSelectorLabels() map[string]string { +func generateAppServerSelectorLabels(instanceName string) map[string]string { return map[string]string{ "app.kubernetes.io/component": "app-server", + "app.kubernetes.io/instance": instanceName, "app.kubernetes.io/managed-by": "openstack-lightspeed-operator", "app.kubernetes.io/name": "openstack-lightspeed-app-server", "app.kubernetes.io/part-of": "openstack-lightspeed", @@ -92,10 +91,10 @@ func providerNameToEnvVarName(providerName string) string { return name } -// generatePostgresSelectorLabels returns selector labels for Postgres components. -func generatePostgresSelectorLabels() map[string]string { +func generatePostgresSelectorLabels(instanceName string) map[string]string { return map[string]string{ "app.kubernetes.io/component": "postgres-server", + "app.kubernetes.io/instance": instanceName, "app.kubernetes.io/managed-by": "openstack-lightspeed-operator", "app.kubernetes.io/name": "openstack-lightspeed-service-postgres", "app.kubernetes.io/part-of": "openstack-lightspeed", @@ -120,10 +119,10 @@ func isDeploymentReady(deploy *appsv1.Deployment) bool { deploy.Status.Replicas == replicas } -// generateOKPSelectorLabels returns selector labels for OKP components. -func generateOKPSelectorLabels() map[string]string { +func generateOKPSelectorLabels(instanceName string) map[string]string { return map[string]string{ "app.kubernetes.io/component": "okp-server", + "app.kubernetes.io/instance": instanceName, "app.kubernetes.io/managed-by": "openstack-lightspeed-operator", "app.kubernetes.io/name": "openstack-lightspeed-okp-server", "app.kubernetes.io/part-of": "openstack-lightspeed", diff --git a/internal/controller/console_deployment.go b/internal/controller/console_deployment.go index ba39845..663ef50 100644 --- a/internal/controller/console_deployment.go +++ b/internal/controller/console_deployment.go @@ -28,11 +28,10 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" ) -// generateConsoleSelectorLabels returns a map of labels used as selectors -// for the console plugin pods. -func generateConsoleSelectorLabels() map[string]string { +func generateConsoleSelectorLabels(instanceName string) map[string]string { return map[string]string{ "app.kubernetes.io/component": "console-plugin", + "app.kubernetes.io/instance": instanceName, "app.kubernetes.io/managed-by": "openstack-lightspeed-operator", "app.kubernetes.io/name": "lightspeed-console-plugin", "app.kubernetes.io/part-of": "openstack-lightspeed", @@ -48,10 +47,10 @@ const consoleLocalesPath = "/usr/share/nginx/html/locales/en/" + consoleLocalesF // buildConsoleDeploymentSpec builds the Deployment spec for the console plugin. // Includes an init container that rewrites OpenShift references to OpenStack // in the locales JSON file using an emptyDir volume. -func buildConsoleDeploymentSpec(consoleImage string) appsv1.DeploymentSpec { +func buildConsoleDeploymentSpec(instanceName string, consoleImage string) appsv1.DeploymentSpec { replicas := int32(1) volumeDefaultMode := VolumeDefaultMode - labels := generateConsoleSelectorLabels() + labels := generateConsoleSelectorLabels(instanceName) return appsv1.DeploymentSpec{ Replicas: &replicas, @@ -69,7 +68,7 @@ func buildConsoleDeploymentSpec(consoleImage string) appsv1.DeploymentSpec { Type: corev1.SeccompProfileTypeRuntimeDefault, }, }, - ServiceAccountName: ConsoleUIServiceAccountName, + ServiceAccountName: ConsoleUIServiceAccountName(instanceName), InitContainers: []corev1.Container{ { Name: "rewrite-locales", @@ -159,7 +158,7 @@ func buildConsoleDeploymentSpec(consoleImage string) appsv1.DeploymentSpec { Name: "lightspeed-console-plugin-cert", VolumeSource: corev1.VolumeSource{ Secret: &corev1.SecretVolumeSource{ - SecretName: ConsoleUIServiceCertSecretName, + SecretName: ConsoleUIServiceCertSecretName(instanceName), DefaultMode: &volumeDefaultMode, }, }, @@ -169,7 +168,7 @@ func buildConsoleDeploymentSpec(consoleImage string) appsv1.DeploymentSpec { VolumeSource: corev1.VolumeSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ LocalObjectReference: corev1.LocalObjectReference{ - Name: ConsoleUIConfigMapName, + Name: ConsoleUIConfigMapName(instanceName), }, DefaultMode: &volumeDefaultMode, }, @@ -194,11 +193,11 @@ func buildConsoleDeploymentSpec(consoleImage string) appsv1.DeploymentSpec { } // buildConsolePluginSpec builds the ConsolePlugin spec with backend and proxy configuration. -func buildConsolePluginSpec(namespace string) consolev1.ConsolePluginSpec { +func buildConsolePluginSpec(instanceName string, namespace string) consolev1.ConsolePluginSpec { return consolev1.ConsolePluginSpec{ Backend: consolev1.ConsolePluginBackend{ Service: &consolev1.ConsolePluginService{ - Name: ConsoleUIServiceName, + Name: ConsoleUIServiceName(instanceName), Namespace: namespace, Port: ConsoleUIHTTPSPort, BasePath: "/", @@ -215,7 +214,7 @@ func buildConsolePluginSpec(namespace string) consolev1.ConsolePluginSpec { Authorization: consolev1.UserToken, Endpoint: consolev1.ConsolePluginProxyEndpoint{ Service: &consolev1.ConsolePluginProxyServiceConfig{ - Name: OpenStackLightspeedAppServerServiceName, + Name: OpenStackLightspeedAppServerServiceName(instanceName), Namespace: namespace, Port: OpenStackLightspeedAppServerServicePort, }, @@ -232,10 +231,10 @@ func buildConsoleNginxConfig() string { } // buildConsoleNetworkPolicySpec builds the NetworkPolicy spec for the console plugin. -func buildConsoleNetworkPolicySpec() networkingv1.NetworkPolicySpec { +func buildConsoleNetworkPolicySpec(instanceName string) networkingv1.NetworkPolicySpec { return networkingv1.NetworkPolicySpec{ PodSelector: metav1.LabelSelector{ - MatchLabels: generateConsoleSelectorLabels(), + MatchLabels: generateConsoleSelectorLabels(instanceName), }, Ingress: []networkingv1.NetworkPolicyIngressRule{ { diff --git a/internal/controller/console_reconciler.go b/internal/controller/console_reconciler.go index 739f942..42704b1 100644 --- a/internal/controller/console_reconciler.go +++ b/internal/controller/console_reconciler.go @@ -69,12 +69,12 @@ func ReconcileConsoleDeployment(h *common_helper.Helper, ctx context.Context, in } // reconcileConsoleConfigMap ensures the console plugin nginx ConfigMap exists. -func reconcileConsoleConfigMap(h *common_helper.Helper, ctx context.Context, _ *apiv1beta1.OpenStackLightspeed) error { +func reconcileConsoleConfigMap(h *common_helper.Helper, ctx context.Context, instance *apiv1beta1.OpenStackLightspeed) error { logger := h.GetLogger() cm := &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ - Name: ConsoleUIConfigMapName, + Name: ConsoleUIConfigMapName(instance.Name), Namespace: h.GetBeforeObject().GetNamespace(), }, } @@ -95,18 +95,18 @@ func reconcileConsoleConfigMap(h *common_helper.Helper, ctx context.Context, _ * } // reconcileConsoleNetworkPolicy ensures the console plugin network policy exists. -func reconcileConsoleNetworkPolicy(h *common_helper.Helper, ctx context.Context, _ *apiv1beta1.OpenStackLightspeed) error { +func reconcileConsoleNetworkPolicy(h *common_helper.Helper, ctx context.Context, instance *apiv1beta1.OpenStackLightspeed) error { logger := h.GetLogger() np := &networkingv1.NetworkPolicy{ ObjectMeta: metav1.ObjectMeta{ - Name: ConsoleUINetworkPolicyName, + Name: ConsoleUINetworkPolicyName(instance.Name), Namespace: h.GetBeforeObject().GetNamespace(), }, } result, err := controllerutil.CreateOrPatch(ctx, h.GetClient(), np, func() error { - np.Spec = buildConsoleNetworkPolicySpec() + np.Spec = buildConsoleNetworkPolicySpec(instance.Name) return controllerutil.SetControllerReference(h.GetBeforeObject(), np, h.GetScheme()) }) @@ -119,12 +119,12 @@ func reconcileConsoleNetworkPolicy(h *common_helper.Helper, ctx context.Context, } // reconcileConsoleServiceAccount ensures the console plugin service account exists. -func reconcileConsoleServiceAccount(h *common_helper.Helper, ctx context.Context, _ *apiv1beta1.OpenStackLightspeed) error { +func reconcileConsoleServiceAccount(h *common_helper.Helper, ctx context.Context, instance *apiv1beta1.OpenStackLightspeed) error { logger := h.GetLogger() sa := &corev1.ServiceAccount{ ObjectMeta: metav1.ObjectMeta{ - Name: ConsoleUIServiceAccountName, + Name: ConsoleUIServiceAccountName(instance.Name), Namespace: h.GetBeforeObject().GetNamespace(), }, } @@ -181,20 +181,20 @@ func resolveConsoleImage(ctx context.Context, h *common_helper.Helper) string { } // reconcileConsoleDeploymentResource ensures the console plugin deployment exists. -func reconcileConsoleDeploymentResource(h *common_helper.Helper, ctx context.Context, _ *apiv1beta1.OpenStackLightspeed) error { +func reconcileConsoleDeploymentResource(h *common_helper.Helper, ctx context.Context, instance *apiv1beta1.OpenStackLightspeed) error { logger := h.GetLogger() consoleImage := resolveConsoleImage(ctx, h) deployment := &appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ - Name: ConsoleUIDeploymentName, + Name: ConsoleUIDeploymentName(instance.Name), Namespace: h.GetBeforeObject().GetNamespace(), }, } result, err := controllerutil.CreateOrPatch(ctx, h.GetClient(), deployment, func() error { - spec := buildConsoleDeploymentSpec(consoleImage) + spec := buildConsoleDeploymentSpec(instance.Name, consoleImage) deployment.Spec.Replicas = spec.Replicas deployment.Spec.Selector = spec.Selector deployment.Spec.Template = spec.Template @@ -210,18 +210,18 @@ func reconcileConsoleDeploymentResource(h *common_helper.Helper, ctx context.Con } // reconcileConsoleService ensures the console plugin service exists. -func reconcileConsoleService(h *common_helper.Helper, ctx context.Context, _ *apiv1beta1.OpenStackLightspeed) error { +func reconcileConsoleService(h *common_helper.Helper, ctx context.Context, instance *apiv1beta1.OpenStackLightspeed) error { logger := h.GetLogger() svc := &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ - Name: ConsoleUIServiceName, + Name: ConsoleUIServiceName(instance.Name), Namespace: h.GetBeforeObject().GetNamespace(), }, } result, err := controllerutil.CreateOrPatch(ctx, h.GetClient(), svc, func() error { - svc.Spec.Selector = generateConsoleSelectorLabels() + svc.Spec.Selector = generateConsoleSelectorLabels(instance.Name) svc.Spec.Ports = []corev1.ServicePort{ { Port: ConsoleUIHTTPSPort, @@ -235,7 +235,7 @@ func reconcileConsoleService(h *common_helper.Helper, ctx context.Context, _ *ap if svc.Annotations == nil { svc.Annotations = make(map[string]string) } - svc.Annotations[ServingCertSecretAnnotationKey] = ConsoleUIServiceCertSecretName + svc.Annotations[ServingCertSecretAnnotationKey] = ConsoleUIServiceCertSecretName(instance.Name) return controllerutil.SetControllerReference(h.GetBeforeObject(), svc, h.GetScheme()) }) @@ -250,12 +250,12 @@ func reconcileConsoleService(h *common_helper.Helper, ctx context.Context, _ *ap // reconcileConsoleTLSSecret waits for the console TLS secret to be populated by // the service-ca operator. -func reconcileConsoleTLSSecret(h *common_helper.Helper, ctx context.Context, _ *apiv1beta1.OpenStackLightspeed) error { +func reconcileConsoleTLSSecret(h *common_helper.Helper, ctx context.Context, instance *apiv1beta1.OpenStackLightspeed) error { logger := h.GetLogger() - logger.Info("waiting for console TLS secret", "name", ConsoleUIServiceCertSecretName) + logger.Info("waiting for console TLS secret", "name", ConsoleUIServiceCertSecretName(instance.Name)) secretKey := client.ObjectKey{ - Name: ConsoleUIServiceCertSecretName, + Name: ConsoleUIServiceCertSecretName(instance.Name), Namespace: h.GetBeforeObject().GetNamespace(), } @@ -275,23 +275,23 @@ func reconcileConsoleTLSSecret(h *common_helper.Helper, ctx context.Context, _ * return fmt.Errorf("%w: %v", ErrReconcileConsoleTLSSecret, err) } - logger.Info("Console TLS secret is ready", "name", ConsoleUIServiceCertSecretName) + logger.Info("Console TLS secret is ready", "name", ConsoleUIServiceCertSecretName(instance.Name)) return nil } // reconcileConsolePlugin ensures the ConsolePlugin CR exists. -func reconcileConsolePlugin(h *common_helper.Helper, ctx context.Context, _ *apiv1beta1.OpenStackLightspeed) error { +func reconcileConsolePlugin(h *common_helper.Helper, ctx context.Context, instance *apiv1beta1.OpenStackLightspeed) error { logger := h.GetLogger() namespace := h.GetBeforeObject().GetNamespace() plugin := &consolev1.ConsolePlugin{ ObjectMeta: metav1.ObjectMeta{ - Name: ConsoleUIPluginName, + Name: ConsoleUIPluginName(instance.Name), }, } result, err := controllerutil.CreateOrPatch(ctx, h.GetClient(), plugin, func() error { - plugin.Spec = buildConsolePluginSpec(namespace) + plugin.Spec = buildConsolePluginSpec(instance.Name, namespace) // ConsolePlugin is cluster-scoped, no owner reference return nil }) @@ -305,8 +305,9 @@ func reconcileConsolePlugin(h *common_helper.Helper, ctx context.Context, _ *api } // activateConsole adds the console plugin to the Console CR's plugin list. -func activateConsole(h *common_helper.Helper, ctx context.Context, _ *apiv1beta1.OpenStackLightspeed) error { +func activateConsole(h *common_helper.Helper, ctx context.Context, instance *apiv1beta1.OpenStackLightspeed) error { logger := h.GetLogger() + pluginName := ConsoleUIPluginName(instance.Name) err := retry.RetryOnConflict(retry.DefaultRetry, func() error { console := &openshiftv1.Console{} @@ -320,9 +321,9 @@ func activateConsole(h *common_helper.Helper, ctx context.Context, _ *apiv1beta1 } if console.Spec.Plugins == nil { - console.Spec.Plugins = []string{ConsoleUIPluginName} - } else if !slices.Contains(console.Spec.Plugins, ConsoleUIPluginName) { - console.Spec.Plugins = append(console.Spec.Plugins, ConsoleUIPluginName) + console.Spec.Plugins = []string{pluginName} + } else if !slices.Contains(console.Spec.Plugins, pluginName) { + console.Spec.Plugins = append(console.Spec.Plugins, pluginName) } else { return nil } @@ -338,8 +339,9 @@ func activateConsole(h *common_helper.Helper, ctx context.Context, _ *apiv1beta1 } // reconcileDeleteConsole deactivates the console plugin and deletes the ConsolePlugin CR. -func reconcileDeleteConsole(h *common_helper.Helper, ctx context.Context, _ *apiv1beta1.OpenStackLightspeed) error { +func reconcileDeleteConsole(h *common_helper.Helper, ctx context.Context, instance *apiv1beta1.OpenStackLightspeed) error { logger := h.GetLogger() + pluginName := ConsoleUIPluginName(instance.Name) // Deactivate: remove plugin from Console CR err := retry.RetryOnConflict(retry.DefaultRetry, func() error { @@ -356,12 +358,12 @@ func reconcileDeleteConsole(h *common_helper.Helper, ctx context.Context, _ *api if console.Spec.Plugins == nil { return nil } - if !slices.Contains(console.Spec.Plugins, ConsoleUIPluginName) { + if !slices.Contains(console.Spec.Plugins, pluginName) { return nil } console.Spec.Plugins = slices.DeleteFunc(console.Spec.Plugins, func(name string) bool { - return name == ConsoleUIPluginName + return name == pluginName }) return h.GetClient().Update(ctx, console) @@ -373,7 +375,7 @@ func reconcileDeleteConsole(h *common_helper.Helper, ctx context.Context, _ *api // Delete ConsolePlugin CR plugin := &consolev1.ConsolePlugin{} - err = h.GetClient().Get(ctx, client.ObjectKey{Name: ConsoleUIPluginName}, plugin) + err = h.GetClient().Get(ctx, client.ObjectKey{Name: pluginName}, plugin) if err != nil { if errors.IsNotFound(err) { logger.Info("ConsolePlugin not found, skip deletion") diff --git a/internal/controller/console_reconciler_test.go b/internal/controller/console_reconciler_test.go index 9e75c10..29f3ecf 100644 --- a/internal/controller/console_reconciler_test.go +++ b/internal/controller/console_reconciler_test.go @@ -34,10 +34,13 @@ var _ = Describe("Console Plugin", func() { apiv1beta1.SetupDefaults() }) + const testInstanceName = "test" + Describe("generateConsoleSelectorLabels", func() { It("should return the expected labels", func() { - labels := generateConsoleSelectorLabels() + labels := generateConsoleSelectorLabels(testInstanceName) Expect(labels).To(HaveKeyWithValue("app.kubernetes.io/component", "console-plugin")) + Expect(labels).To(HaveKeyWithValue("app.kubernetes.io/instance", testInstanceName)) Expect(labels).To(HaveKeyWithValue("app.kubernetes.io/managed-by", "openstack-lightspeed-operator")) Expect(labels).To(HaveKeyWithValue("app.kubernetes.io/name", "lightspeed-console-plugin")) Expect(labels).To(HaveKeyWithValue("app.kubernetes.io/part-of", "openstack-lightspeed")) @@ -48,7 +51,7 @@ var _ = Describe("Console Plugin", func() { var spec appsv1.DeploymentSpec BeforeEach(func() { - spec = buildConsoleDeploymentSpec(apiv1beta1.OpenStackLightspeedDefaultValues.ConsoleImagePF5URL) + spec = buildConsoleDeploymentSpec(testInstanceName, apiv1beta1.OpenStackLightspeedDefaultValues.ConsoleImagePF5URL) }) It("should have one replica", func() { @@ -57,7 +60,7 @@ var _ = Describe("Console Plugin", func() { }) It("should have correct selector labels", func() { - Expect(spec.Selector.MatchLabels).To(Equal(generateConsoleSelectorLabels())) + Expect(spec.Selector.MatchLabels).To(Equal(generateConsoleSelectorLabels(testInstanceName))) }) It("should have one container with the console image", func() { @@ -107,7 +110,7 @@ var _ = Describe("Console Plugin", func() { if v.Name == "lightspeed-console-plugin-cert" { found = true Expect(v.VolumeSource.Secret).NotTo(BeNil()) - Expect(v.VolumeSource.Secret.SecretName).To(Equal(ConsoleUIServiceCertSecretName)) + Expect(v.VolumeSource.Secret.SecretName).To(Equal(ConsoleUIServiceCertSecretName(testInstanceName))) } } Expect(found).To(BeTrue()) @@ -120,7 +123,7 @@ var _ = Describe("Console Plugin", func() { if v.Name == "nginx-config" { found = true Expect(v.VolumeSource.ConfigMap).NotTo(BeNil()) - Expect(v.VolumeSource.ConfigMap.Name).To(Equal(ConsoleUIConfigMapName)) + Expect(v.VolumeSource.ConfigMap.Name).To(Equal(ConsoleUIConfigMapName(testInstanceName))) } } Expect(found).To(BeTrue()) @@ -139,7 +142,7 @@ var _ = Describe("Console Plugin", func() { }) It("should use the console service account", func() { - Expect(spec.Template.Spec.ServiceAccountName).To(Equal(ConsoleUIServiceAccountName)) + Expect(spec.Template.Spec.ServiceAccountName).To(Equal(ConsoleUIServiceAccountName(testInstanceName))) }) It("should have a locales-rewrite emptyDir volume", func() { @@ -189,12 +192,12 @@ var _ = Describe("Console Plugin", func() { Describe("buildConsolePluginSpec", func() { const testNamespace = "test-ns" - var spec = buildConsolePluginSpec(testNamespace) + var spec = buildConsolePluginSpec(testInstanceName, testNamespace) It("should have service backend", func() { Expect(spec.Backend.Type).To(Equal(consolev1.Service)) Expect(spec.Backend.Service).NotTo(BeNil()) - Expect(spec.Backend.Service.Name).To(Equal(ConsoleUIServiceName)) + Expect(spec.Backend.Service.Name).To(Equal(ConsoleUIServiceName(testInstanceName))) Expect(spec.Backend.Service.Namespace).To(Equal(testNamespace)) Expect(spec.Backend.Service.Port).To(Equal(ConsoleUIHTTPSPort)) }) @@ -206,7 +209,7 @@ var _ = Describe("Console Plugin", func() { Expect(proxy.Authorization).To(Equal(consolev1.UserToken)) Expect(proxy.Endpoint.Type).To(Equal(consolev1.ProxyTypeService)) Expect(proxy.Endpoint.Service).NotTo(BeNil()) - Expect(proxy.Endpoint.Service.Name).To(Equal(OpenStackLightspeedAppServerServiceName)) + Expect(proxy.Endpoint.Service.Name).To(Equal(OpenStackLightspeedAppServerServiceName(testInstanceName))) Expect(proxy.Endpoint.Service.Namespace).To(Equal(testNamespace)) Expect(proxy.Endpoint.Service.Port).To(Equal(int32(OpenStackLightspeedAppServerServicePort))) }) @@ -227,10 +230,10 @@ var _ = Describe("Console Plugin", func() { }) Describe("buildConsoleNetworkPolicySpec", func() { - var spec = buildConsoleNetworkPolicySpec() + var spec = buildConsoleNetworkPolicySpec(testInstanceName) It("should select console plugin pods", func() { - Expect(spec.PodSelector.MatchLabels).To(Equal(generateConsoleSelectorLabels())) + Expect(spec.PodSelector.MatchLabels).To(Equal(generateConsoleSelectorLabels(testInstanceName))) }) It("should allow ingress from openshift-console namespace", func() { diff --git a/internal/controller/constants.go b/internal/controller/constants.go index 20b7403..b5ca924 100644 --- a/internal/controller/constants.go +++ b/internal/controller/constants.go @@ -26,15 +26,10 @@ const ( ResourceCreationTimeout = 60 * time.Second // Application Server - OpenStackLightspeedAppServerServiceAccountName = "lightspeed-app-server" - OpenStackLightspeedAppServerSARRoleName = OpenStackLightspeedAppServerServiceAccountName + "-sar-role" - OpenStackLightspeedAppServerSARRoleBindingName = OpenStackLightspeedAppServerSARRoleName + "-binding" - OpenStackLightspeedAppServerContainerPort = 8443 - OpenStackLightspeedAppServerServicePort = 8443 - OpenStackLightspeedAppServerServiceName = "lightspeed-app-server" - OpenStackLightspeedAppServerNetworkPolicyName = "lightspeed-app-server" - OpenStackLightspeedDefaultProvider = "openstack-lightspeed-provider" - OpenStackLightspeedVectorDBPath = "/rag/vector_db/os_product_docs" + OpenStackLightspeedAppServerContainerPort = 8443 + OpenStackLightspeedAppServerServicePort = 8443 + OpenStackLightspeedDefaultProvider = "openstack-lightspeed-provider" + OpenStackLightspeedVectorDBPath = "/rag/vector_db/os_product_docs" ServingCertSecretAnnotationKey = "service.beta.openshift.io/serving-cert-secret-name" @@ -43,12 +38,6 @@ const ( MetricsReaderServiceAccountName = "lightspeed-operator-metrics-reader" // Postgres - PostgresDeploymentName = "lightspeed-postgres-server" - PostgresServiceName = "lightspeed-postgres-server" - PostgresSecretName = "lightspeed-postgres-secret" - PostgresBootstrapSecretName = "lightspeed-postgres-bootstrap" - PostgresConfigMapName = "lightspeed-postgres-conf" - PostgresNetworkPolicyName = "lightspeed-postgres-server" PostgresServicePort = int32(5432) PostgresDefaultUser = "postgres" PostgresDefaultDbName = "postgres" @@ -61,7 +50,6 @@ const ( PostgresConfigVolumeMountPath = "/usr/share/pgsql/postgresql.conf.sample" PostgresDataVolume = "postgres-data" PostgresDataVolumeMountPath = "/var/lib/pgsql" - PostgresDataPVCName = "openstack-lightspeed-database" PostgresDataPVCDefaultSize = "1Gi" PostgresVarRunVolumeName = "lightspeed-postgres-var-run" PostgresVarRunVolumeMountPath = "/var/run/postgresql" @@ -69,10 +57,7 @@ const ( TmpVolumeMountPath = "/tmp" // LCore specific - LlamaStackContainerPort = int32(8321) - LlamaStackConfigCmName = "llama-stack-config" - LCoreConfigCmName = "lightspeed-stack-config" - LCoreDeploymentName = "lightspeed-stack-deployment" + LlamaStackContainerPort = int32(8321) LCoreConfigMountPath = "/app-root/lightspeed-stack.yaml" LCoreUserDataMountPath = "/tmp/data" ForceReloadAnnotationKey = "ols.openshift.io/force-reload" @@ -81,33 +66,23 @@ const ( ExporterConfigVolumeName = "exporter-config" ExporterConfigMountPath = "/etc/config" ExporterConfigFilename = "config.yaml" - ExporterConfigCmName = "lightspeed-exporter-config" DataverseExporterContainerName = "lightspeed-to-dataverse-exporter" UserDataVolumeName = "ols-user-data" RHOSOLightspeedOwnerIDLabel = "openstack.org/lightspeed-owner-id" ServiceIDRHOSO = "rhos-lightspeed" // OKP (Offline Knowledge Portal) - OKPContainerName = "okp" - OKPContainerPort = int32(8080) - OKPDeploymentName = "lightspeed-okp-server" - OKPServiceName = "lightspeed-okp-server" + OKPContainerName = "okp" + OKPContainerPort = int32(8080) OKPServicePort = int32(8080) OKPAccessKeySecretKey = "access_key" OKPDefaultChunkFilterQuery = "product:(*openstack* OR *openshift*)" ExternalProvidersDir = "/app-root/providers.d" // Console Plugin - ConsoleUIConfigMapName = "lightspeed-console-plugin" - ConsoleUIServiceCertSecretName = "lightspeed-console-plugin-cert" - ConsoleUIServiceName = "lightspeed-console-plugin" - ConsoleUIDeploymentName = "lightspeed-console-plugin" - ConsoleUIHTTPSPort = int32(9443) - ConsoleUIPluginName = "lightspeed-console-plugin" - ConsoleUIServiceAccountName = "lightspeed-console-plugin" - ConsoleCRName = "cluster" - ConsoleProxyAlias = "ols" - ConsoleUINetworkPolicyName = "lightspeed-console-plugin" + ConsoleUIHTTPSPort = int32(9443) + ConsoleCRName = "cluster" + ConsoleProxyAlias = "ols" // Azure AzureOpenAIType = "azure_openai" @@ -161,9 +136,6 @@ const ( // configuration is stored. LightspeedStackConfigCMKey = "lightspeed-stack.yaml" - // VectorDBScriptsConfigMapName is the name of the ConfigMap that contains the - // initialization scripts used by init containers to collect and build vector database data - VectorDBScriptsConfigMapName = "vector-db-scripts" // VectorDBScriptsVolumeName is the name of the volume that mounts the ConfigMap containing // vector database initialization scripts for use by init containers @@ -197,12 +169,6 @@ const ( VolumeRestrictedMode = int32(0600) VolumeExecutableMode = int32(0755) - // CABundleConfigMapName is the name of the ConfigMap that stores the - // CA certificate bundle. It aggregates certificates from three sources — - // operator system CAs, the OpenShift service serving CA (for in-cluster - // service-to-service TLS), and the OpenShift API server CA — along with - // any user-provided additional CAs. - CABundleConfigMapName = "openstack-lightspeed-ca-bundle" // CABundleKey is the key within the CA bundle ConfigMap under which // the PEM-encoded certificate data is stored. @@ -235,17 +201,6 @@ const ( // inside the lightspeed-service-api container, used to serve HTTPS. OpenStackLightspeedTLSKeyPath = OpenStackLightspeedAppCertsMountRoot + "/lightspeed-tls/tls.key" - // OpenStackLightspeedCertsSecretName is the name of the Secret auto-provisioned - // by the OpenShift service-ca operator when the lightspeed-app-server Service is - // annotated with service.beta.openshift.io/serving-cert-secret-name. Contains - // tls.crt and tls.key used by the lightspeed-service-api container to serve HTTPS. - OpenStackLightspeedCertsSecretName = "lightspeed-tls" - - // PostgresCertsSecretName is the name of the Secret auto-provisioned by the - // OpenShift service-ca operator when the lightspeed-postgres-server Service is - // annotated with service.beta.openshift.io/serving-cert-secret-name. Contains - // tls.crt and tls.key used by the postgres container to serve TLS connections. - PostgresCertsSecretName = "lightspeed-postgres-certs" // PostgresDefaultSSLMode is the sslmode used when connecting to PostgreSQL. // "verify-full" requires a valid server certificate and checks @@ -264,6 +219,108 @@ const ( OpenShiftServiceCAConfigMap = "openshift-service-ca.crt" ) +// Resource name functions — each returns a name scoped to the CR instance so +// multiple OpenStackLightspeed CRs can coexist in the same namespace. + +// Application Server +func OpenStackLightspeedAppServerServiceAccountName(instanceName string) string { + return instanceName + "-app-server" +} +func OpenStackLightspeedAppServerSARRoleName(instanceName string) string { + return OpenStackLightspeedAppServerServiceAccountName(instanceName) + "-sar-role" +} +func OpenStackLightspeedAppServerSARRoleBindingName(instanceName string) string { + return OpenStackLightspeedAppServerSARRoleName(instanceName) + "-binding" +} +func OpenStackLightspeedAppServerServiceName(instanceName string) string { + return instanceName + "-app-server" +} +func OpenStackLightspeedAppServerNetworkPolicyName(instanceName string) string { + return instanceName + "-app-server" +} +func OpenStackLightspeedCertsSecretName(instanceName string) string { + return instanceName + "-tls" +} + +// Postgres +func PostgresDeploymentName(instanceName string) string { + return instanceName + "-postgres-server" +} +func PostgresServiceName(instanceName string) string { + return instanceName + "-postgres-server" +} +func PostgresSecretName(instanceName string) string { + return instanceName + "-postgres-secret" +} +func PostgresBootstrapSecretName(instanceName string) string { + return instanceName + "-postgres-bootstrap" +} +func PostgresConfigMapName(instanceName string) string { + return instanceName + "-postgres-conf" +} +func PostgresNetworkPolicyName(instanceName string) string { + return instanceName + "-postgres-server" +} +func PostgresDataPVCName(instanceName string) string { + return instanceName + "-database" +} +func PostgresCertsSecretName(instanceName string) string { + return instanceName + "-postgres-certs" +} + +// LCore +func LlamaStackConfigCmName(instanceName string) string { + return instanceName + "-llama-stack-config" +} +func LCoreConfigCmName(instanceName string) string { + return instanceName + "-stack-config" +} +func LCoreDeploymentName(instanceName string) string { + return instanceName + "-stack-deployment" +} +func ExporterConfigCmName(instanceName string) string { + return instanceName + "-exporter-config" +} + +// OKP +func OKPDeploymentName(instanceName string) string { + return instanceName + "-okp-server" +} +func OKPServiceName(instanceName string) string { + return instanceName + "-okp-server" +} + +// Console Plugin +func ConsoleUIConfigMapName(instanceName string) string { + return instanceName + "-console-plugin" +} +func ConsoleUIServiceCertSecretName(instanceName string) string { + return instanceName + "-console-plugin-cert" +} +func ConsoleUIServiceName(instanceName string) string { + return instanceName + "-console-plugin" +} +func ConsoleUIDeploymentName(instanceName string) string { + return instanceName + "-console-plugin" +} +func ConsoleUIPluginName(instanceName string) string { + return instanceName + "-console-plugin" +} +func ConsoleUIServiceAccountName(instanceName string) string { + return instanceName + "-console-plugin" +} +func ConsoleUINetworkPolicyName(instanceName string) string { + return instanceName + "-console-plugin" +} + +// Other +func CABundleConfigMapName(instanceName string) string { + return instanceName + "-ca-bundle" +} +func VectorDBScriptsConfigMapName(instanceName string) string { + return instanceName + "-vector-db-scripts" +} + // PostgreSQL Bootstrap Script - creates database, extensions, and schemas // //go:embed assets/postgres_bootstrap.sh diff --git a/internal/controller/lcore_config.go b/internal/controller/lcore_config.go index ba46433..8e0f971 100644 --- a/internal/controller/lcore_config.go +++ b/internal/controller/lcore_config.go @@ -124,10 +124,10 @@ func buildLCoreInferenceConfig(_ *common_helper.Helper, instance *apiv1beta1.Ope } // buildLCoreDatabaseConfig configures persistent database storage (PostgreSQL) -func buildLCoreDatabaseConfig(h *common_helper.Helper, _ *apiv1beta1.OpenStackLightspeed) map[string]interface{} { +func buildLCoreDatabaseConfig(h *common_helper.Helper, instance *apiv1beta1.OpenStackLightspeed) map[string]interface{} { return map[string]interface{}{ "postgres": map[string]interface{}{ - "host": PostgresServiceName + "." + h.GetBeforeObject().GetNamespace() + ".svc", + "host": PostgresServiceName(instance.Name) + "." + h.GetBeforeObject().GetNamespace() + ".svc", "port": PostgresServicePort, "db": PostgresDefaultDbName, "user": PostgresDefaultUser, @@ -155,11 +155,11 @@ func buildLCoreCustomizationConfig() map[string]interface{} { } // buildLCoreConversationCacheConfig configures chat history caching (PostgreSQL) -func buildLCoreConversationCacheConfig(h *common_helper.Helper, _ *apiv1beta1.OpenStackLightspeed) map[string]interface{} { +func buildLCoreConversationCacheConfig(h *common_helper.Helper, instance *apiv1beta1.OpenStackLightspeed) map[string]interface{} { return map[string]interface{}{ "type": "postgres", "postgres": map[string]interface{}{ - "host": PostgresServiceName + "." + h.GetBeforeObject().GetNamespace() + ".svc", + "host": PostgresServiceName(instance.Name) + "." + h.GetBeforeObject().GetNamespace() + ".svc", "port": PostgresServicePort, "db": PostgresDefaultDbName, "user": PostgresDefaultUser, @@ -178,7 +178,7 @@ func isDataCollectionEnabled(instance *apiv1beta1.OpenStackLightspeed) bool { } // buildExporterConfigMap creates the ConfigMap for the dataverse exporter sidecar. -func buildExporterConfigMap(h *common_helper.Helper, _ *apiv1beta1.OpenStackLightspeed) *corev1.ConfigMap { +func buildExporterConfigMap(h *common_helper.Helper, instance *apiv1beta1.OpenStackLightspeed) *corev1.ConfigMap { exporterConfig := fmt.Sprintf(`service_id: "%s" ingress_server_url: "https://console.redhat.com/api/ingress/v1/upload" allowed_subdirs: @@ -192,9 +192,9 @@ ingress_connection_timeout: 30 return &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ - Name: ExporterConfigCmName, + Name: ExporterConfigCmName(instance.Name), Namespace: h.GetBeforeObject().GetNamespace(), - Labels: generateAppServerSelectorLabels(), + Labels: generateAppServerSelectorLabels(instance.Name), }, Data: map[string]string{ ExporterConfigFilename: exporterConfig, diff --git a/internal/controller/lcore_deployment.go b/internal/controller/lcore_deployment.go index e5ac3bb..6646d3e 100644 --- a/internal/controller/lcore_deployment.go +++ b/internal/controller/lcore_deployment.go @@ -38,15 +38,16 @@ import ( // This function is used by CreateOrPatch to generate the desired pod spec. func buildLCorePodTemplateSpec(h *common_helper.Helper, ctx context.Context, instance *apiv1beta1.OpenStackLightspeed) (corev1.PodTemplateSpec, error) { // Build shared volumes + instanceName := instance.Name volumes := []corev1.Volume{ - buildOGXConfigVolume(VolumeDefaultMode), - buildLightspeedStackConfigVolume(VolumeDefaultMode), - buildVectorDBScriptsVolume(), + buildOGXConfigVolume(instanceName, VolumeDefaultMode), + buildLightspeedStackConfigVolume(instanceName, VolumeDefaultMode), + buildVectorDBScriptsVolume(instanceName), } // Shared volumes - CA bundle covers all cluster CAs sharedMounts := []corev1.VolumeMount{} - addCABundleVolumesAndMounts(&volumes, &sharedMounts) + addCABundleVolumesAndMounts(instanceName, &volumes, &sharedMounts) addVectorDBDataVolumesAndMounts(&volumes, &sharedMounts) // Llama cache emptydir @@ -97,7 +98,7 @@ func buildLCorePodTemplateSpec(h *common_helper.Helper, ctx context.Context, ins // Data collection volumes (shared folder + exporter config) dataCollectionEnabled := isDataCollectionEnabled(instance) if dataCollectionEnabled { - addDataCollectorVolumes(&volumes, VolumeDefaultMode) + addDataCollectorVolumes(instanceName, &volumes, VolumeDefaultMode) } // Lightspeed Stack container mounts: its config + shared + TLS (only API container needs TLS) @@ -105,7 +106,7 @@ func buildLCorePodTemplateSpec(h *common_helper.Helper, ctx context.Context, ins lightspeedStackMounts = append(lightspeedStackMounts, sharedMounts...) tlsMounts := []corev1.VolumeMount{} - addTLSVolumesAndMounts(&volumes, &tlsMounts, VolumeDefaultMode) + addTLSVolumesAndMounts(instanceName, &volumes, &tlsMounts, VolumeDefaultMode) lightspeedStackMounts = append(lightspeedStackMounts, tlsMounts...) // Mount shared data folder on lightspeed-service-api for feedback/transcripts @@ -182,7 +183,7 @@ func buildLCorePodTemplateSpec(h *common_helper.Helper, ctx context.Context, ins } // Build configmap resource version annotations for change detection - annotations, err := buildConfigMapAnnotations(h, ctx) + annotations, err := buildConfigMapAnnotations(instanceName, h, ctx) if err != nil { return corev1.PodTemplateSpec{}, err } @@ -194,11 +195,11 @@ func buildLCorePodTemplateSpec(h *common_helper.Helper, ctx context.Context, ins return corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ - Labels: generateAppServerSelectorLabels(), + Labels: generateAppServerSelectorLabels(instanceName), Annotations: annotations, }, Spec: corev1.PodSpec{ - ServiceAccountName: OpenStackLightspeedAppServerServiceAccountName, + ServiceAccountName: OpenStackLightspeedAppServerServiceAccountName(instanceName), InitContainers: initContainers, Containers: containers, Volumes: volumes, @@ -310,13 +311,13 @@ func buildInitContainers( } // buildLightspeedStackConfigVolume returns the volume for the lightspeed-stack config. -func buildLightspeedStackConfigVolume(volumeDefaultMode int32) corev1.Volume { +func buildLightspeedStackConfigVolume(instanceName string, volumeDefaultMode int32) corev1.Volume { return corev1.Volume{ Name: LightspeedStackConfig, VolumeSource: corev1.VolumeSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ LocalObjectReference: corev1.LocalObjectReference{ - Name: LCoreConfigCmName, + Name: LCoreConfigCmName(instanceName), }, DefaultMode: toPtr(volumeDefaultMode), }, @@ -325,13 +326,13 @@ func buildLightspeedStackConfigVolume(volumeDefaultMode int32) corev1.Volume { } // buildOGXConfigVolume returns the volume for the OGX config. -func buildOGXConfigVolume(volumeDefaultMode int32) corev1.Volume { +func buildOGXConfigVolume(instanceName string, volumeDefaultMode int32) corev1.Volume { return corev1.Volume{ Name: OGXConfigVolumeName, VolumeSource: corev1.VolumeSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ LocalObjectReference: corev1.LocalObjectReference{ - Name: LlamaStackConfigCmName, + Name: LlamaStackConfigCmName(instanceName), }, DefaultMode: toPtr(volumeDefaultMode), }, @@ -340,13 +341,13 @@ func buildOGXConfigVolume(volumeDefaultMode int32) corev1.Volume { } // buildVectorDBScriptsVolume returns the volume for the Vector DB scripts. -func buildVectorDBScriptsVolume() corev1.Volume { +func buildVectorDBScriptsVolume(instanceName string) corev1.Volume { return corev1.Volume{ Name: VectorDBScriptsVolumeName, VolumeSource: corev1.VolumeSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ LocalObjectReference: corev1.LocalObjectReference{ - Name: VectorDBScriptsConfigMapName, + Name: VectorDBScriptsConfigMapName(instanceName), }, DefaultMode: toPtr(VolumeExecutableMode), }, @@ -369,12 +370,12 @@ func addVectorDBDataVolumesAndMounts(volumes *[]corev1.Volume, mounts *[]corev1. } // addTLSVolumesAndMounts adds the service-ca TLS certificate volume and mount. -func addTLSVolumesAndMounts(volumes *[]corev1.Volume, mounts *[]corev1.VolumeMount, volumeDefaultMode int32) { +func addTLSVolumesAndMounts(instanceName string, volumes *[]corev1.Volume, mounts *[]corev1.VolumeMount, volumeDefaultMode int32) { *volumes = append(*volumes, corev1.Volume{ Name: "tls-certs", VolumeSource: corev1.VolumeSource{ Secret: &corev1.SecretVolumeSource{ - SecretName: OpenStackLightspeedCertsSecretName, + SecretName: OpenStackLightspeedCertsSecretName(instanceName), DefaultMode: toPtr(volumeDefaultMode), }, }, @@ -401,7 +402,7 @@ func addLlamaCacheVolumesAndMounts(volumes *[]corev1.Volume, mounts *[]corev1.Vo } // addDataCollectorVolumes adds the shared data EmptyDir and exporter config volumes. -func addDataCollectorVolumes(volumes *[]corev1.Volume, volumeDefaultMode int32) { +func addDataCollectorVolumes(instanceName string, volumes *[]corev1.Volume, volumeDefaultMode int32) { *volumes = append(*volumes, corev1.Volume{ Name: UserDataVolumeName, VolumeSource: corev1.VolumeSource{ @@ -414,7 +415,7 @@ func addDataCollectorVolumes(volumes *[]corev1.Volume, volumeDefaultMode int32) VolumeSource: corev1.VolumeSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ LocalObjectReference: corev1.LocalObjectReference{ - Name: ExporterConfigCmName, + Name: ExporterConfigCmName(instanceName), }, DefaultMode: toPtr(volumeDefaultMode), }, @@ -425,13 +426,13 @@ func addDataCollectorVolumes(volumes *[]corev1.Volume, volumeDefaultMode int32) // addCABundleVolumesAndMounts adds the CA bundle volume and mount. // The CA bundle is always present (created by reconcileCABundleConfigMap) // and mounted at the RHEL system CA path so applications find it automatically. -func addCABundleVolumesAndMounts(volumes *[]corev1.Volume, mounts *[]corev1.VolumeMount) { +func addCABundleVolumesAndMounts(instanceName string, volumes *[]corev1.Volume, mounts *[]corev1.VolumeMount) { *volumes = append(*volumes, corev1.Volume{ Name: CABundleVolumeName, VolumeSource: corev1.VolumeSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ LocalObjectReference: corev1.LocalObjectReference{ - Name: CABundleConfigMapName, + Name: CABundleConfigMapName(instanceName), }, DefaultMode: toPtr(VolumeDefaultMode), }, @@ -547,7 +548,7 @@ func buildLlamaStackEnvVars(h *common_helper.Helper, ctx context.Context, instan } // Postgres password for ${env.POSTGRES_PASSWORD} substitution in llama-stack config - envVars = append(envVars, buildPostgresPasswordEnvVar()) + envVars = append(envVars, buildPostgresPasswordEnvVar(instance.Name)) // Logging configuration - set both for compatibility with llama-stack and OGX ogxLogLevel := getOGXLogLevel(instance) @@ -568,7 +569,7 @@ func buildLlamaStackEnvVars(h *common_helper.Helper, ctx context.Context, instan if isOKPEnabled(instance) { envVars = append(envVars, corev1.EnvVar{ Name: "RH_SERVER_OKP", - Value: fmt.Sprintf("http://%s.%s.svc:%d", OKPServiceName, instance.GetNamespace(), OKPServicePort), + Value: fmt.Sprintf("http://%s.%s.svc:%d", OKPServiceName(instance.Name), instance.GetNamespace(), OKPServicePort), }) // FIXME(lucasagomes): Llama-Stack expects HF_HOME to be set when OKP is enabled because it uses the // Hugging Face Hub client to fetch the embedding model for OKP. Ideally we would include the model it @@ -583,13 +584,13 @@ func buildLlamaStackEnvVars(h *common_helper.Helper, ctx context.Context, instan } // buildPostgresPasswordEnvVar returns the POSTGRES_PASSWORD env var sourced from the postgres secret. -func buildPostgresPasswordEnvVar() corev1.EnvVar { +func buildPostgresPasswordEnvVar(instanceName string) corev1.EnvVar { return corev1.EnvVar{ Name: "POSTGRES_PASSWORD", ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ - Name: PostgresSecretName, + Name: PostgresSecretName(instanceName), }, Key: OpenStackLightspeedComponentPasswordFileName, }, @@ -604,12 +605,12 @@ func buildLightspeedStackEnvVars(instance *apiv1beta1.OpenStackLightspeed) []cor Name: "LIGHTSPEED_STACK_LOG_LEVEL", Value: instance.Spec.Logging.LightspeedStackLogLevel, }, - buildPostgresPasswordEnvVar(), + buildPostgresPasswordEnvVar(instance.Name), } if isOKPEnabled(instance) { envVars = append(envVars, corev1.EnvVar{ Name: "RH_SERVER_OKP", - Value: fmt.Sprintf("http://%s.%s.svc:%d", OKPServiceName, instance.GetNamespace(), OKPServicePort), + Value: fmt.Sprintf("http://%s.%s.svc:%d", OKPServiceName(instance.Name), instance.GetNamespace(), OKPServicePort), }) } return envVars @@ -665,10 +666,10 @@ func getOGXLogLevel(instance *apiv1beta1.OpenStackLightspeed) string { // buildConfigMapAnnotations builds annotations with configmap resource versions // so that changes to the configmaps trigger a deployment rollout. -func buildConfigMapAnnotations(h *common_helper.Helper, ctx context.Context) (map[string]string, error) { +func buildConfigMapAnnotations(instanceName string, h *common_helper.Helper, ctx context.Context) (map[string]string, error) { annotations := make(map[string]string) - lcoreVersion, err := getConfigMapResourceVersion(ctx, h, LCoreConfigCmName, h.GetBeforeObject().GetNamespace()) + lcoreVersion, err := getConfigMapResourceVersion(ctx, h, LCoreConfigCmName(instanceName), h.GetBeforeObject().GetNamespace()) if err != nil { // ConfigMap may not exist yet during initial creation if !errors.IsNotFound(err) { @@ -678,7 +679,7 @@ func buildConfigMapAnnotations(h *common_helper.Helper, ctx context.Context) (ma annotations[LCoreConfigMapResourceVersionAnnotation] = lcoreVersion } - llamaVersion, err := getConfigMapResourceVersion(ctx, h, LlamaStackConfigCmName, h.GetBeforeObject().GetNamespace()) + llamaVersion, err := getConfigMapResourceVersion(ctx, h, LlamaStackConfigCmName(instanceName), h.GetBeforeObject().GetNamespace()) if err != nil { if !errors.IsNotFound(err) { return nil, fmt.Errorf("failed to get Llama Stack configmap resource version: %w", err) @@ -687,7 +688,7 @@ func buildConfigMapAnnotations(h *common_helper.Helper, ctx context.Context) (ma annotations[LlamaStackConfigMapResourceVersionAnnotation] = llamaVersion } - vectorDBScriptsVersion, err := getConfigMapResourceVersion(ctx, h, VectorDBScriptsConfigMapName, h.GetBeforeObject().GetNamespace()) + vectorDBScriptsVersion, err := getConfigMapResourceVersion(ctx, h, VectorDBScriptsConfigMapName(instanceName), h.GetBeforeObject().GetNamespace()) if err != nil { if !errors.IsNotFound(err) { return nil, fmt.Errorf("failed to get Vector DB scripts configmap resource version: %w", err) @@ -696,7 +697,7 @@ func buildConfigMapAnnotations(h *common_helper.Helper, ctx context.Context) (ma annotations[VectorDBScriptsConfigMapVersionAnnotation] = vectorDBScriptsVersion } - caBundleVersion, err := getConfigMapResourceVersion(ctx, h, CABundleConfigMapName, h.GetBeforeObject().GetNamespace()) + caBundleVersion, err := getConfigMapResourceVersion(ctx, h, CABundleConfigMapName(instanceName), h.GetBeforeObject().GetNamespace()) if err != nil { if !errors.IsNotFound(err) { return nil, fmt.Errorf("failed to get CA bundle configmap resource version: %w", err) diff --git a/internal/controller/lcore_reconciler.go b/internal/controller/lcore_reconciler.go index 71cc819..7dbe0e9 100644 --- a/internal/controller/lcore_reconciler.go +++ b/internal/controller/lcore_reconciler.go @@ -75,7 +75,7 @@ func reconcileServiceAccount(h *common_helper.Helper, ctx context.Context, insta sa := &corev1.ServiceAccount{ ObjectMeta: metav1.ObjectMeta{ - Name: OpenStackLightspeedAppServerServiceAccountName, + Name: OpenStackLightspeedAppServerServiceAccountName(instance.Name), Namespace: h.GetBeforeObject().GetNamespace(), }, } @@ -99,8 +99,8 @@ func reconcileSARRole(h *common_helper.Helper, ctx context.Context, instance *ap role := &rbacv1.ClusterRole{ ObjectMeta: metav1.ObjectMeta{ - Name: OpenStackLightspeedAppServerSARRoleName, - Labels: generateAppServerSelectorLabels(), + Name: OpenStackLightspeedAppServerSARRoleName(instance.Name), + Labels: generateAppServerSelectorLabels(instance.Name), }, } @@ -147,8 +147,8 @@ func reconcileSARRoleBinding(h *common_helper.Helper, ctx context.Context, insta rb := &rbacv1.ClusterRoleBinding{ ObjectMeta: metav1.ObjectMeta{ - Name: OpenStackLightspeedAppServerSARRoleBindingName, - Labels: generateAppServerSelectorLabels(), + Name: OpenStackLightspeedAppServerSARRoleBindingName(instance.Name), + Labels: generateAppServerSelectorLabels(instance.Name), }, } @@ -157,14 +157,14 @@ func reconcileSARRoleBinding(h *common_helper.Helper, ctx context.Context, insta rb.Subjects = []rbacv1.Subject{ { Kind: "ServiceAccount", - Name: OpenStackLightspeedAppServerServiceAccountName, + Name: OpenStackLightspeedAppServerServiceAccountName(instance.Name), Namespace: h.GetBeforeObject().GetNamespace(), }, } rb.RoleRef = rbacv1.RoleRef{ APIGroup: "rbac.authorization.k8s.io", Kind: "ClusterRole", - Name: OpenStackLightspeedAppServerSARRoleName, + Name: OpenStackLightspeedAppServerSARRoleName(instance.Name), } // Note: ClusterRoleBinding is cluster-scoped, no owner reference needed return nil @@ -190,7 +190,7 @@ func reconcileLlamaStackConfigMap(h *common_helper.Helper, ctx context.Context, cm := &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ - Name: LlamaStackConfigCmName, + Name: LlamaStackConfigCmName(instance.Name), Namespace: h.GetBeforeObject().GetNamespace(), }, } @@ -224,7 +224,7 @@ func reconcileLcoreConfigMap(h *common_helper.Helper, ctx context.Context, insta cm := &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ - Name: LCoreConfigCmName, + Name: LCoreConfigCmName(instance.Name), Namespace: h.GetBeforeObject().GetNamespace(), }, } @@ -253,7 +253,7 @@ func reconcileExporterConfigMap(h *common_helper.Helper, ctx context.Context, in if !isDataCollectionEnabled(instance) { cm := &corev1.ConfigMap{} - cm.Name = ExporterConfigCmName + cm.Name = ExporterConfigCmName(instance.Name) cm.Namespace = h.GetBeforeObject().GetNamespace() if err := h.GetClient().Delete(ctx, cm); err != nil && !errors.IsNotFound(err) { return fmt.Errorf("failed to delete exporter configmap: %w", err) @@ -263,7 +263,7 @@ func reconcileExporterConfigMap(h *common_helper.Helper, ctx context.Context, in cm := &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ - Name: ExporterConfigCmName, + Name: ExporterConfigCmName(instance.Name), Namespace: h.GetBeforeObject().GetNamespace(), }, } @@ -288,7 +288,7 @@ func reconcileVectorDBScriptsConfigMap(h *common_helper.Helper, ctx context.Cont logger := h.GetLogger() cm := &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ - Name: VectorDBScriptsConfigMapName, + Name: VectorDBScriptsConfigMapName(instance.Name), Namespace: h.GetBeforeObject().GetNamespace(), }, } @@ -323,7 +323,7 @@ func reconcileNetworkPolicy(h *common_helper.Helper, ctx context.Context, instan np := &networkingv1.NetworkPolicy{ ObjectMeta: metav1.ObjectMeta{ - Name: OpenStackLightspeedAppServerNetworkPolicyName, + Name: OpenStackLightspeedAppServerNetworkPolicyName(instance.Name), Namespace: h.GetBeforeObject().GetNamespace(), }, } @@ -332,7 +332,7 @@ func reconcileNetworkPolicy(h *common_helper.Helper, ctx context.Context, instan // Set Spec (wholesale replacement, same as before) np.Spec = networkingv1.NetworkPolicySpec{ PodSelector: metav1.LabelSelector{ - MatchLabels: generateAppServerSelectorLabels(), + MatchLabels: generateAppServerSelectorLabels(instance.Name), }, Ingress: []networkingv1.NetworkPolicyIngressRule{ { @@ -366,7 +366,7 @@ func reconcileDeployment(h *common_helper.Helper, ctx context.Context, instance deployment := &appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ - Name: LCoreDeploymentName, + Name: LCoreDeploymentName(instance.Name), Namespace: h.GetBeforeObject().GetNamespace(), }, } @@ -382,7 +382,7 @@ func reconcileDeployment(h *common_helper.Helper, ctx context.Context, instance replicas := int32(1) deployment.Spec.Replicas = &replicas deployment.Spec.Selector = &metav1.LabelSelector{ - MatchLabels: generateAppServerSelectorLabels(), + MatchLabels: generateAppServerSelectorLabels(instance.Name), } deployment.Spec.Template = podTemplateSpec @@ -405,14 +405,14 @@ func reconcileService(h *common_helper.Helper, ctx context.Context, instance *ap svc := &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ - Name: OpenStackLightspeedAppServerServiceName, + Name: OpenStackLightspeedAppServerServiceName(instance.Name), Namespace: h.GetBeforeObject().GetNamespace(), }, } result, err := controllerutil.CreateOrPatch(ctx, h.GetClient(), svc, func() error { // Selective field updates (preserves ClusterIP, ClusterIPs, etc.) - svc.Spec.Selector = generateAppServerSelectorLabels() + svc.Spec.Selector = generateAppServerSelectorLabels(instance.Name) svc.Spec.Ports = []corev1.ServicePort{ { Name: "https", @@ -427,7 +427,7 @@ func reconcileService(h *common_helper.Helper, ctx context.Context, instance *ap if svc.Annotations == nil { svc.Annotations = make(map[string]string) } - svc.Annotations[ServingCertSecretAnnotationKey] = OpenStackLightspeedCertsSecretName + svc.Annotations[ServingCertSecretAnnotationKey] = OpenStackLightspeedCertsSecretName(instance.Name) // Set owner reference return controllerutil.SetControllerReference(h.GetBeforeObject(), svc, h.GetScheme()) @@ -443,12 +443,12 @@ func reconcileService(h *common_helper.Helper, ctx context.Context, instance *ap // reconcileTLSSecret waits for the TLS secret to be populated by the service-ca // operator with tls.key and tls.crt data. -func reconcileTLSSecret(h *common_helper.Helper, ctx context.Context, _ *apiv1beta1.OpenStackLightspeed) error { +func reconcileTLSSecret(h *common_helper.Helper, ctx context.Context, instance *apiv1beta1.OpenStackLightspeed) error { logger := h.GetLogger() - logger.Info("waiting for TLS secret to be populated", "name", OpenStackLightspeedCertsSecretName) + logger.Info("waiting for TLS secret to be populated", "name", OpenStackLightspeedCertsSecretName(instance.Name)) secretKey := client.ObjectKey{ - Name: OpenStackLightspeedCertsSecretName, + Name: OpenStackLightspeedCertsSecretName(instance.Name), Namespace: h.GetBeforeObject().GetNamespace(), } @@ -468,15 +468,15 @@ func reconcileTLSSecret(h *common_helper.Helper, ctx context.Context, _ *apiv1be return fmt.Errorf("%w: %v", ErrGetTLSSecret, err) } - logger.Info("TLS secret is ready", "name", OpenStackLightspeedCertsSecretName) + logger.Info("TLS secret is ready", "name", OpenStackLightspeedCertsSecretName(instance.Name)) return nil } // reconcileDeleteClusterRoleBindingByLabels deletes ClusterRoleBinding resources by labels. -func reconcileDeleteClusterRoleBindingByLabels(h *common_helper.Helper, ctx context.Context, _ *apiv1beta1.OpenStackLightspeed) error { +func reconcileDeleteClusterRoleBindingByLabels(h *common_helper.Helper, ctx context.Context, instance *apiv1beta1.OpenStackLightspeed) error { logger := h.GetLogger() - labelSelector := labels.Set(generateAppServerSelectorLabels()).AsSelector() + labelSelector := labels.Set(generateAppServerSelectorLabels(instance.Name)).AsSelector() matchingLabels := client.MatchingLabelsSelector{Selector: labelSelector} deleteOptions := &client.DeleteAllOfOptions{ ListOptions: client.ListOptions{ @@ -493,10 +493,10 @@ func reconcileDeleteClusterRoleBindingByLabels(h *common_helper.Helper, ctx cont } // reconcileDeleteClusterRoleByLabels deletes ClusterRole resources by labels. -func reconcileDeleteClusterRoleByLabels(h *common_helper.Helper, ctx context.Context, _ *apiv1beta1.OpenStackLightspeed) error { +func reconcileDeleteClusterRoleByLabels(h *common_helper.Helper, ctx context.Context, instance *apiv1beta1.OpenStackLightspeed) error { logger := h.GetLogger() - labelSelector := labels.Set(generateAppServerSelectorLabels()).AsSelector() + labelSelector := labels.Set(generateAppServerSelectorLabels(instance.Name)).AsSelector() matchingLabels := client.MatchingLabelsSelector{Selector: labelSelector} deleteOptions := &client.DeleteAllOfOptions{ ListOptions: client.ListOptions{ diff --git a/internal/controller/llama_stack_config.go b/internal/controller/llama_stack_config.go index ed8153f..7f822ca 100644 --- a/internal/controller/llama_stack_config.go +++ b/internal/controller/llama_stack_config.go @@ -300,7 +300,7 @@ func buildLlamaStackStorage(_ *common_helper.Helper, instance *apiv1beta1.OpenSt }, "postgres_backend": map[string]interface{}{ "type": "sql_postgres", - "host": fmt.Sprintf("lightspeed-postgres-server.%s.svc", instance.GetNamespace()), + "host": fmt.Sprintf("%s.%s.svc", PostgresServiceName(instance.Name), instance.GetNamespace()), "port": PostgresServicePort, "user": "postgres", "password": "${env.POSTGRES_PASSWORD}", diff --git a/internal/controller/okp_reconciler.go b/internal/controller/okp_reconciler.go index 9e9e953..1790eeb 100644 --- a/internal/controller/okp_reconciler.go +++ b/internal/controller/okp_reconciler.go @@ -35,7 +35,7 @@ import ( // When OKP is disabled, it cleans up existing resources. func ReconcileOKPDeployment(h *common_helper.Helper, ctx context.Context, instance *apiv1beta1.OpenStackLightspeed) error { if !isOKPEnabled(instance) { - return cleanupOKPResources(h, ctx) + return cleanupOKPResources(h, ctx, instance) } tasks := []ReconcileTask{ @@ -45,19 +45,19 @@ func ReconcileOKPDeployment(h *common_helper.Helper, ctx context.Context, instan return ReconcileTasksFailFast(h, ctx, instance, tasks) } -func cleanupOKPResources(h *common_helper.Helper, ctx context.Context) error { +func cleanupOKPResources(h *common_helper.Helper, ctx context.Context, instance *apiv1beta1.OpenStackLightspeed) error { logger := h.GetLogger() ns := h.GetBeforeObject().GetNamespace() deploy := &appsv1.Deployment{} - deploy.Name = OKPDeploymentName + deploy.Name = OKPDeploymentName(instance.Name) deploy.Namespace = ns if err := h.GetClient().Delete(ctx, deploy); err != nil && !errors.IsNotFound(err) { return fmt.Errorf("%w: %v", ErrDeleteOKPDeployment, err) } svc := &corev1.Service{} - svc.Name = OKPServiceName + svc.Name = OKPServiceName(instance.Name) svc.Namespace = ns if err := h.GetClient().Delete(ctx, svc); err != nil && !errors.IsNotFound(err) { return fmt.Errorf("%w: %v", ErrDeleteOKPService, err) @@ -72,7 +72,7 @@ func reconcileOKPDeployment(h *common_helper.Helper, ctx context.Context, instan deployment := &appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ - Name: OKPDeploymentName, + Name: OKPDeploymentName(instance.Name), Namespace: h.GetBeforeObject().GetNamespace(), }, } @@ -83,7 +83,7 @@ func reconcileOKPDeployment(h *common_helper.Helper, ctx context.Context, instan replicas := int32(1) deployment.Spec.Replicas = &replicas deployment.Spec.Selector = &metav1.LabelSelector{ - MatchLabels: generateOKPSelectorLabels(), + MatchLabels: generateOKPSelectorLabels(instance.Name), } deployment.Spec.Template = podTemplateSpec @@ -98,18 +98,18 @@ func reconcileOKPDeployment(h *common_helper.Helper, ctx context.Context, instan return nil } -func reconcileOKPService(h *common_helper.Helper, ctx context.Context, _ *apiv1beta1.OpenStackLightspeed) error { +func reconcileOKPService(h *common_helper.Helper, ctx context.Context, instance *apiv1beta1.OpenStackLightspeed) error { logger := h.GetLogger() svc := &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ - Name: OKPServiceName, + Name: OKPServiceName(instance.Name), Namespace: h.GetBeforeObject().GetNamespace(), }, } result, err := controllerutil.CreateOrPatch(ctx, h.GetClient(), svc, func() error { - svc.Spec.Selector = generateOKPSelectorLabels() + svc.Spec.Selector = generateOKPSelectorLabels(instance.Name) svc.Spec.Ports = []corev1.ServicePort{ { Name: "http", @@ -149,7 +149,7 @@ func buildOKPPodTemplateSpec(instance *apiv1beta1.OpenStackLightspeed) corev1.Po return corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ - Labels: generateOKPSelectorLabels(), + Labels: generateOKPSelectorLabels(instance.Name), }, Spec: corev1.PodSpec{ Containers: []corev1.Container{ diff --git a/internal/controller/openstacklightspeed_controller.go b/internal/controller/openstacklightspeed_controller.go index 17f9be6..22eda6c 100644 --- a/internal/controller/openstacklightspeed_controller.go +++ b/internal/controller/openstacklightspeed_controller.go @@ -230,9 +230,9 @@ func (r *OpenStackLightspeedReconciler) reconcileStatus( instance *apiv1beta1.OpenStackLightspeed, ) (ctrl.Result, error) { deployments := []string{ - PostgresDeploymentName, - LCoreDeploymentName, - ConsoleUIDeploymentName, + PostgresDeploymentName(instance.Name), + LCoreDeploymentName(instance.Name), + ConsoleUIDeploymentName(instance.Name), } for _, deploymentName := range deployments { deployment, err := getDeployment(ctx, helper, deploymentName, instance.Namespace) diff --git a/internal/controller/postgres_deployment.go b/internal/controller/postgres_deployment.go index 94cfd46..daf9d00 100644 --- a/internal/controller/postgres_deployment.go +++ b/internal/controller/postgres_deployment.go @@ -26,7 +26,7 @@ import ( ) // buildPostgresPodTemplateSpec builds the pod template spec for the Postgres deployment. -func buildPostgresPodTemplateSpec() corev1.PodTemplateSpec { +func buildPostgresPodTemplateSpec(instanceName string) corev1.PodTemplateSpec { // Build volumes and volume mounts volumes := []corev1.Volume{} volumeMounts := []corev1.VolumeMount{} @@ -36,32 +36,32 @@ func buildPostgresPodTemplateSpec() corev1.PodTemplateSpec { // TLS certs volume (auto-provisioned by service-ca via the Service annotation) volumes = append(volumes, corev1.Volume{ - Name: "secret-" + PostgresCertsSecretName, + Name: "secret-" + PostgresCertsSecretName(instanceName), VolumeSource: corev1.VolumeSource{ Secret: &corev1.SecretVolumeSource{ - SecretName: PostgresCertsSecretName, + SecretName: PostgresCertsSecretName(instanceName), DefaultMode: &restrictedMode, }, }, }) volumeMounts = append(volumeMounts, corev1.VolumeMount{ - Name: "secret-" + PostgresCertsSecretName, + Name: "secret-" + PostgresCertsSecretName(instanceName), MountPath: OpenStackLightspeedAppCertsMountRoot, ReadOnly: true, }) // Bootstrap script volume volumes = append(volumes, corev1.Volume{ - Name: "secret-" + PostgresBootstrapSecretName, + Name: "secret-" + PostgresBootstrapSecretName(instanceName), VolumeSource: corev1.VolumeSource{ Secret: &corev1.SecretVolumeSource{ - SecretName: PostgresBootstrapSecretName, + SecretName: PostgresBootstrapSecretName(instanceName), DefaultMode: &restrictedMode, }, }, }) volumeMounts = append(volumeMounts, corev1.VolumeMount{ - Name: "secret-" + PostgresBootstrapSecretName, + Name: "secret-" + PostgresBootstrapSecretName(instanceName), MountPath: PostgresBootstrapVolumeMountPath, SubPath: PostgresExtensionScript, ReadOnly: true, @@ -69,16 +69,16 @@ func buildPostgresPodTemplateSpec() corev1.PodTemplateSpec { // Postgres config volume volumes = append(volumes, corev1.Volume{ - Name: PostgresConfigMapName, + Name: PostgresConfigMapName(instanceName), VolumeSource: corev1.VolumeSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{Name: PostgresConfigMapName}, + LocalObjectReference: corev1.LocalObjectReference{Name: PostgresConfigMapName(instanceName)}, DefaultMode: &defaultMode, }, }, }) volumeMounts = append(volumeMounts, corev1.VolumeMount{ - Name: PostgresConfigMapName, + Name: PostgresConfigMapName(instanceName), MountPath: PostgresConfigVolumeMountPath, SubPath: PostgresConfigKey, }) @@ -87,7 +87,7 @@ func buildPostgresPodTemplateSpec() corev1.PodTemplateSpec { Name: PostgresDataVolume, VolumeSource: corev1.VolumeSource{ PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ - ClaimName: PostgresDataPVCName, + ClaimName: PostgresDataPVCName(instanceName), }, }, }) @@ -122,13 +122,13 @@ func buildPostgresPodTemplateSpec() corev1.PodTemplateSpec { return corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ - Labels: generatePostgresSelectorLabels(), + Labels: generatePostgresSelectorLabels(instanceName), Annotations: make(map[string]string), }, Spec: corev1.PodSpec{ Containers: []corev1.Container{ { - Name: PostgresDeploymentName, + Name: PostgresDeploymentName(instanceName), Image: apiv1beta1.OpenStackLightspeedDefaultValues.PostgresImageURL, ImagePullPolicy: corev1.PullAlways, Ports: []corev1.ContainerPort{ @@ -174,7 +174,7 @@ func buildPostgresPodTemplateSpec() corev1.PodTemplateSpec { Name: "POSTGRESQL_ADMIN_PASSWORD", ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{Name: PostgresSecretName}, + LocalObjectReference: corev1.LocalObjectReference{Name: PostgresSecretName(instanceName)}, Key: OpenStackLightspeedComponentPasswordFileName, }, }, @@ -183,7 +183,7 @@ func buildPostgresPodTemplateSpec() corev1.PodTemplateSpec { Name: "POSTGRESQL_PASSWORD", ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{Name: PostgresSecretName}, + LocalObjectReference: corev1.LocalObjectReference{Name: PostgresSecretName(instanceName)}, Key: OpenStackLightspeedComponentPasswordFileName, }, }, diff --git a/internal/controller/postgres_reconciler.go b/internal/controller/postgres_reconciler.go index cfdadb3..a9ebde0 100644 --- a/internal/controller/postgres_reconciler.go +++ b/internal/controller/postgres_reconciler.go @@ -62,10 +62,10 @@ func ReconcilePostgresDeployment(h *common_helper.Helper, ctx context.Context, i return ReconcileTasksFailFast(h, ctx, instance, tasks) } -func reconcilePostgresConfigMap(h *common_helper.Helper, ctx context.Context, _ *apiv1beta1.OpenStackLightspeed) error { +func reconcilePostgresConfigMap(h *common_helper.Helper, ctx context.Context, instance *apiv1beta1.OpenStackLightspeed) error { cm := &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ - Name: PostgresConfigMapName, + Name: PostgresConfigMapName(instance.Name), Namespace: h.GetBeforeObject().GetNamespace(), }, } @@ -87,10 +87,10 @@ func reconcilePostgresConfigMap(h *common_helper.Helper, ctx context.Context, _ return nil } -func reconcilePostgresBootstrapSecret(h *common_helper.Helper, ctx context.Context, _ *apiv1beta1.OpenStackLightspeed) error { +func reconcilePostgresBootstrapSecret(h *common_helper.Helper, ctx context.Context, instance *apiv1beta1.OpenStackLightspeed) error { secret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ - Name: PostgresBootstrapSecretName, + Name: PostgresBootstrapSecretName(instance.Name), Namespace: h.GetBeforeObject().GetNamespace(), }, } @@ -112,11 +112,11 @@ func reconcilePostgresBootstrapSecret(h *common_helper.Helper, ctx context.Conte return nil } -func reconcilePostgresSecret(h *common_helper.Helper, ctx context.Context, _ *apiv1beta1.OpenStackLightspeed) error { +func reconcilePostgresSecret(h *common_helper.Helper, ctx context.Context, instance *apiv1beta1.OpenStackLightspeed) error { // Check if secret exists - if not, cleanup old secrets first checkSecret := &corev1.Secret{} secretKey := client.ObjectKey{ - Name: PostgresSecretName, + Name: PostgresSecretName(instance.Name), Namespace: h.GetBeforeObject().GetNamespace(), } err := h.GetClient().Get(ctx, secretKey, checkSecret) @@ -131,7 +131,7 @@ func reconcilePostgresSecret(h *common_helper.Helper, ctx context.Context, _ *ap secret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ - Name: PostgresSecretName, + Name: PostgresSecretName(instance.Name), Namespace: h.GetBeforeObject().GetNamespace(), }, } @@ -176,10 +176,10 @@ func deleteOldPostgresSecrets(h *common_helper.Helper, ctx context.Context) erro return nil } -func reconcilePostgresNetworkPolicy(h *common_helper.Helper, ctx context.Context, _ *apiv1beta1.OpenStackLightspeed) error { +func reconcilePostgresNetworkPolicy(h *common_helper.Helper, ctx context.Context, instance *apiv1beta1.OpenStackLightspeed) error { np := &networkingv1.NetworkPolicy{ ObjectMeta: metav1.ObjectMeta{ - Name: PostgresNetworkPolicyName, + Name: PostgresNetworkPolicyName(instance.Name), Namespace: h.GetBeforeObject().GetNamespace(), }, } @@ -189,14 +189,14 @@ func reconcilePostgresNetworkPolicy(h *common_helper.Helper, ctx context.Context // Restricts ingress to Postgres to only allow traffic from app server pods np.Spec = networkingv1.NetworkPolicySpec{ PodSelector: metav1.LabelSelector{ - MatchLabels: generatePostgresSelectorLabels(), + MatchLabels: generatePostgresSelectorLabels(instance.Name), }, Ingress: []networkingv1.NetworkPolicyIngressRule{ { From: []networkingv1.NetworkPolicyPeer{ { PodSelector: &metav1.LabelSelector{ - MatchLabels: generateAppServerSelectorLabels(), + MatchLabels: generateAppServerSelectorLabels(instance.Name), }, }, }, @@ -236,7 +236,7 @@ func reconcilePostgresPVC(h *common_helper.Helper, ctx context.Context, instance pvc := &corev1.PersistentVolumeClaim{} pvcKey := client.ObjectKey{ - Name: PostgresDataPVCName, + Name: PostgresDataPVCName(instance.Name), Namespace: h.GetBeforeObject().GetNamespace(), } @@ -259,7 +259,7 @@ func reconcilePostgresPVC(h *common_helper.Helper, ctx context.Context, instance // PVC does not exist, create it pvc = &corev1.PersistentVolumeClaim{ ObjectMeta: metav1.ObjectMeta{ - Name: PostgresDataPVCName, + Name: PostgresDataPVCName(instance.Name), Namespace: h.GetBeforeObject().GetNamespace(), }, } @@ -288,19 +288,19 @@ func reconcilePostgresPVC(h *common_helper.Helper, ctx context.Context, instance func reconcilePostgresDeploymentTask(h *common_helper.Helper, ctx context.Context, instance *apiv1beta1.OpenStackLightspeed) error { deployment := &appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ - Name: PostgresDeploymentName, + Name: PostgresDeploymentName(instance.Name), Namespace: h.GetBeforeObject().GetNamespace(), }, } result, err := controllerutil.CreateOrPatch(ctx, h.GetClient(), deployment, func() error { - currentConfigMapVersion, err := getConfigMapResourceVersion(ctx, h, PostgresConfigMapName, h.GetBeforeObject().GetNamespace()) + currentConfigMapVersion, err := getConfigMapResourceVersion(ctx, h, PostgresConfigMapName(instance.Name), h.GetBeforeObject().GetNamespace()) if err != nil && !errors.IsNotFound(err) { return fmt.Errorf("%w: %v", ErrGetPostgresConfigMap, err) } // Build the desired deployment pod spec - podTemplateSpec := buildPostgresPodTemplateSpec() + podTemplateSpec := buildPostgresPodTemplateSpec(instance.Name) // Initialize annotations map if needed if podTemplateSpec.Annotations == nil { @@ -315,7 +315,7 @@ func reconcilePostgresDeploymentTask(h *common_helper.Helper, ctx context.Contex replicas := int32(1) deployment.Spec.Replicas = &replicas deployment.Spec.Selector = &metav1.LabelSelector{ - MatchLabels: generatePostgresSelectorLabels(), + MatchLabels: generatePostgresSelectorLabels(instance.Name), } deployment.Spec.Template = podTemplateSpec @@ -335,17 +335,17 @@ func reconcilePostgresDeploymentTask(h *common_helper.Helper, ctx context.Contex return nil } -func reconcilePostgresServiceTask(h *common_helper.Helper, ctx context.Context, _ *apiv1beta1.OpenStackLightspeed) error { +func reconcilePostgresServiceTask(h *common_helper.Helper, ctx context.Context, instance *apiv1beta1.OpenStackLightspeed) error { svc := &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ - Name: PostgresServiceName, + Name: PostgresServiceName(instance.Name), Namespace: h.GetBeforeObject().GetNamespace(), }, } result, err := controllerutil.CreateOrPatch(ctx, h.GetClient(), svc, func() error { // Selective field updates (preserves ClusterIP, ClusterIPs, etc.) - svc.Spec.Selector = generatePostgresSelectorLabels() + svc.Spec.Selector = generatePostgresSelectorLabels(instance.Name) svc.Spec.Ports = []corev1.ServicePort{ { Port: PostgresServicePort, @@ -360,7 +360,7 @@ func reconcilePostgresServiceTask(h *common_helper.Helper, ctx context.Context, if svc.Annotations == nil { svc.Annotations = make(map[string]string) } - svc.Annotations[ServingCertSecretAnnotationKey] = PostgresCertsSecretName + svc.Annotations[ServingCertSecretAnnotationKey] = PostgresCertsSecretName(instance.Name) // Set owner reference return controllerutil.SetControllerReference(h.GetBeforeObject(), svc, h.GetScheme())