From 9ed04681f06852381fd5514b4e6ac23c2fa674b6 Mon Sep 17 00:00:00 2001 From: Lukas Piwowarski Date: Tue, 30 Sep 2025 17:02:30 +0200 Subject: [PATCH] Revert "[OSPRH-16305] Introduce OpenStackLightspeed" We're reverting the OpenStackLightspeed change for now. We need to ensure first that we have builds for the vector database image. This commit will be re-introduced after the FR4 branch has been created. This reverts commit 8362b1938d053aab4da07aecec9ed15334a0a5a1. --- Makefile | 2 +- PROJECT | 9 - ...ed.openstack.org_openstacklightspeeds.yaml | 96 ----- apis/lightspeed/v1beta1/conditions.go | 40 -- apis/lightspeed/v1beta1/groupversion_info.go | 36 -- .../v1beta1/openstacklightspeed_types.go | 124 ------ apis/lightspeed/v1beta1/webhook_suite_test.go | 28 -- .../v1beta1/zz_generated.deepcopy.go | 153 ------- bindata/crds/crds.yaml | 96 ----- bindata/rbac/rbac.yaml | 60 --- ...ed.openstack.org_openstacklightspeeds.yaml | 96 ----- config/crd/kustomization.yaml | 2 - ...on_in_lightspeed_openstacklightspeeds.yaml | 7 - ...nstack-operator.clusterserviceversion.yaml | 10 - config/operator/default_images.yaml | 2 - ...speed_openstacklightspeed_editor_role.yaml | 31 -- ...speed_openstacklightspeed_viewer_role.yaml | 27 -- config/rbac/role.yaml | 60 --- config/samples/kustomization.yaml | 1 - ...ightspeed_v1beta1_openstacklightspeed.yaml | 10 - .../openstacklightspeed_controller.go | 319 --------------- hack/export_related_images.sh | 1 - main.go | 14 - pkg/lightspeed/funcs.go | 383 ------------------ tests/functional/ctlplane/suite_test.go | 12 - 25 files changed, 1 insertion(+), 1618 deletions(-) delete mode 100644 apis/bases/lightspeed.openstack.org_openstacklightspeeds.yaml delete mode 100644 apis/lightspeed/v1beta1/conditions.go delete mode 100644 apis/lightspeed/v1beta1/groupversion_info.go delete mode 100644 apis/lightspeed/v1beta1/openstacklightspeed_types.go delete mode 100644 apis/lightspeed/v1beta1/webhook_suite_test.go delete mode 100644 apis/lightspeed/v1beta1/zz_generated.deepcopy.go delete mode 100644 config/crd/bases/lightspeed.openstack.org_openstacklightspeeds.yaml delete mode 100644 config/crd/patches/cainjection_in_lightspeed_openstacklightspeeds.yaml delete mode 100644 config/rbac/lightspeed_openstacklightspeed_editor_role.yaml delete mode 100644 config/rbac/lightspeed_openstacklightspeed_viewer_role.yaml delete mode 100644 config/samples/lightspeed_v1beta1_openstacklightspeed.yaml delete mode 100644 controllers/lightspeed/openstacklightspeed_controller.go delete mode 100644 pkg/lightspeed/funcs.go diff --git a/Makefile b/Makefile index 8f8ed2956..beaa11209 100644 --- a/Makefile +++ b/Makefile @@ -137,7 +137,7 @@ help: ## Display this help. manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects. mkdir -p config/operator/rbac && \ $(CONTROLLER_GEN) crd$(CRDDESC_OVERRIDE) output:crd:artifacts:config=config/crd/bases webhook paths="./..." && \ - $(CONTROLLER_GEN) rbac:roleName=manager-role paths="{./apis/lightspeed/...,./apis/client/...,./apis/core/...,./apis/dataplane/...,./controllers/lightspeed/...,./controllers/client/...,./controllers/core/...,./controllers/dataplane/...,./pkg/...}" output:dir=config/rbac && \ + $(CONTROLLER_GEN) rbac:roleName=manager-role paths="{./apis/client/...,./apis/core/...,./apis/dataplane/...,./controllers/client/...,./controllers/core/...,./controllers/dataplane/...,./pkg/...}" output:dir=config/rbac && \ $(CONTROLLER_GEN) rbac:roleName=operator-role paths="./controllers/operator/..." paths="./apis/operator/..." output:dir=config/operator/rbac && \ rm -f apis/bases/* && cp -a config/crd/bases apis/ diff --git a/PROJECT b/PROJECT index 3868e8653..3a611a529 100644 --- a/PROJECT +++ b/PROJECT @@ -86,13 +86,4 @@ resources: kind: OpenStack path: github.com/openstack-k8s-operators/openstack-operator/apis/operator/v1beta1 version: v1beta1 -- api: - crdVersion: v1 - namespaced: true - controller: true - domain: openstack.org - group: lightspeed - kind: OpenStackLightspeed - path: github.com/openstack-k8s-operators/openstack-operator/apis/lightspeed/v1beta1 - version: v1beta1 version: "3" diff --git a/apis/bases/lightspeed.openstack.org_openstacklightspeeds.yaml b/apis/bases/lightspeed.openstack.org_openstacklightspeeds.yaml deleted file mode 100644 index 104850713..000000000 --- a/apis/bases/lightspeed.openstack.org_openstacklightspeeds.yaml +++ /dev/null @@ -1,96 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.18.0 - name: openstacklightspeeds.lightspeed.openstack.org -spec: - group: lightspeed.openstack.org - names: - kind: OpenStackLightspeed - listKind: OpenStackLightspeedList - plural: openstacklightspeeds - singular: openstacklightspeed - scope: Namespaced - versions: - - additionalPrinterColumns: - - description: Status - jsonPath: .status.conditions[0].status - name: Status - type: string - - description: Message - jsonPath: .status.conditions[0].message - name: Message - type: string - name: v1beta1 - schema: - openAPIV3Schema: - properties: - apiVersion: - type: string - kind: - type: string - metadata: - type: object - spec: - properties: - llmCredentials: - type: string - llmEndpoint: - type: string - llmEndpointType: - enum: - - azure_openai - - bam - - openai - - watsonx - - rhoai_vllm - - rhelai_vllm - - fake_provider - type: string - modelName: - type: string - ragImage: - type: string - tlsCACertBundle: - type: string - required: - - llmCredentials - - llmEndpoint - - llmEndpointType - - modelName - type: object - status: - properties: - conditions: - items: - properties: - lastTransitionTime: - format: date-time - type: string - message: - type: string - reason: - type: string - severity: - type: string - status: - type: string - type: - type: string - required: - - lastTransitionTime - - status - - type - type: object - type: array - observedGeneration: - format: int64 - type: integer - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/apis/lightspeed/v1beta1/conditions.go b/apis/lightspeed/v1beta1/conditions.go deleted file mode 100644 index c19ecd23e..000000000 --- a/apis/lightspeed/v1beta1/conditions.go +++ /dev/null @@ -1,40 +0,0 @@ -/* -Copyright 2025. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1beta1 - -import ( - condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition" -) - -// OpenStackLightspeed Condition Types used by API objects. -const ( - // OpenStackLightspeedReadyCondition Status=True condition which indicates if OpenStackLightspeedReadyCondition - // is configured and operational - OpenStackLightspeedReadyCondition condition.Type = "OpenStackLightspeedReady" -) - -// Common Messages used by API objects. -const ( - // OpenStackLightspeedReadyInitMessage - OpenStackLightspeedReadyInitMessage = "OpenStack Lightspeed not started" - - // OpenStackLightspeedReadyMessage - OpenStackLightspeedReadyMessage = "OpenStack Lightspeed created" - - // OpenStackLightspeedWaitingVectorDBMessage - OpenStackLightspeedWaitingVectorDBMessage = "Waiting for OpenStackLightspeed vector DB pod to become ready" -) diff --git a/apis/lightspeed/v1beta1/groupversion_info.go b/apis/lightspeed/v1beta1/groupversion_info.go deleted file mode 100644 index aa206501c..000000000 --- a/apis/lightspeed/v1beta1/groupversion_info.go +++ /dev/null @@ -1,36 +0,0 @@ -/* -Copyright 2025. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package v1beta1 contains API Schema definitions for the lightspeed v1beta1 API group -// +kubebuilder:object:generate=true -// +groupName=lightspeed.openstack.org -package v1beta1 - -import ( - "k8s.io/apimachinery/pkg/runtime/schema" - "sigs.k8s.io/controller-runtime/pkg/scheme" -) - -var ( - // GroupVersion is group version used to register these objects - GroupVersion = schema.GroupVersion{Group: "lightspeed.openstack.org", Version: "v1beta1"} - - // SchemeBuilder is used to add go types to the GroupVersionKind scheme - SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} - - // AddToScheme adds the types in this group-version to the given scheme. - AddToScheme = SchemeBuilder.AddToScheme -) diff --git a/apis/lightspeed/v1beta1/openstacklightspeed_types.go b/apis/lightspeed/v1beta1/openstacklightspeed_types.go deleted file mode 100644 index c9250eec1..000000000 --- a/apis/lightspeed/v1beta1/openstacklightspeed_types.go +++ /dev/null @@ -1,124 +0,0 @@ -/* -Copyright 2025. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1beta1 - -import ( - "github.com/openstack-k8s-operators/lib-common/modules/common/condition" - "github.com/openstack-k8s-operators/lib-common/modules/common/util" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -const ( - // Container image fall-back defaults - - // OpenStackLightspeedContainerImage is the fall-back container image for OpenStackLightspeed - OpenStackLightspeedContainerImage = "quay.io/openstack-lightspeed/rag-content:os-docs-2024.2" -) - -// OpenStackLightspeedSpec defines the desired state of OpenStackLightspeed -type OpenStackLightspeedSpec struct { - OpenStackLightspeedCore `json:",inline"` - - // +kubebuilder:validation:Optional - // ContainerImage for the Openstack Lightspeed RAG container (will be set to environmental default if empty) - RAGImage string `json:"ragImage"` -} - -// OpenStackLightspeedCore defines the desired state of OpenStackLightspeed -type OpenStackLightspeedCore struct { - // +kubebuilder:validation:Required - // URL pointing to the LLM - LLMEndpoint string `json:"llmEndpoint"` - - // +kubebuilder:validation:Required - // +kubebuilder:validation:Enum=azure_openai;bam;openai;watsonx;rhoai_vllm;rhelai_vllm;fake_provider - // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Provider Type" - // Type of the provider serving the LLM - LLMEndpointType string `json:"llmEndpointType"` - - // +kubebuilder:validation:Required - // Name of the model to use at the API endpoint provided in LLMEndpoint - ModelName string `json:"modelName"` - - // +kubebuilder:validation:Required - // Secret name containing API token for the LLMEndpoint. The key for the field - // in the secret that holds the token should be "apitoken". - LLMCredentials string `json:"llmCredentials"` - - // +kubebuilder:validation:Optional - // Configmap name containing a CA Certificates bundle - TLSCACertBundle string `json:"tlsCACertBundle"` -} - -// OpenStackLightspeedStatus defines the observed state of OpenStackLightspeed -type OpenStackLightspeedStatus struct { - // Conditions - Conditions condition.Conditions `json:"conditions,omitempty" optional:"true"` - - // ObservedGeneration - the most recent generation observed for this object. - ObservedGeneration int64 `json:"observedGeneration,omitempty"` -} - -// +kubebuilder:object:root=true -// +kubebuilder:subresource:status -// +operator-sdk:csv:customresourcedefinitions:displayName="OpenStack Lightspeed" -// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[0].status",description="Status" -// +kubebuilder:printcolumn:name="Message",type="string",JSONPath=".status.conditions[0].message",description="Message" - -// OpenStackLightspeed is the Schema for the openstacklightspeeds API -type OpenStackLightspeed struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec OpenStackLightspeedSpec `json:"spec,omitempty"` - Status OpenStackLightspeedStatus `json:"status,omitempty"` -} - -//+kubebuilder:object:root=true - -// OpenStackLightspeedList contains a list of OpenStackLightspeed -type OpenStackLightspeedList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []OpenStackLightspeed `json:"items"` -} - -func init() { - SchemeBuilder.Register(&OpenStackLightspeed{}, &OpenStackLightspeedList{}) -} - -// IsReady - returns true if OpenStackLightspeed is reconciled successfully -func (instance OpenStackLightspeed) IsReady() bool { - return instance.Status.Conditions.IsTrue(OpenStackLightspeedReadyCondition) -} - -type OpenStackLightspeedDefaults struct { - RAGImageURL string -} - -var OpenStackLightspeedDefaultValues OpenStackLightspeedDefaults - -// SetupDefaults - initializes OpenStackLightspeedDefaultValues with default values from env vars -func SetupDefaults() { - // Acquire environmental defaults and initialize OpenStackLightspeed defaults with them - openStackLightspeedDefaults := OpenStackLightspeedDefaults{ - RAGImageURL: util.GetEnvVar( - "RELATED_IMAGE_OPENSTACK_LIGHTSPEED_IMAGE_URL_DEFAULT", OpenStackLightspeedContainerImage), - } - - OpenStackLightspeedDefaultValues = openStackLightspeedDefaults -} diff --git a/apis/lightspeed/v1beta1/webhook_suite_test.go b/apis/lightspeed/v1beta1/webhook_suite_test.go deleted file mode 100644 index cd57b7be3..000000000 --- a/apis/lightspeed/v1beta1/webhook_suite_test.go +++ /dev/null @@ -1,28 +0,0 @@ -/* -Copyright 2025. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1beta1 - -import ( - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "testing" -) - -func TestAPIs(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "LightSpeed v1beta1 Suite") -} diff --git a/apis/lightspeed/v1beta1/zz_generated.deepcopy.go b/apis/lightspeed/v1beta1/zz_generated.deepcopy.go deleted file mode 100644 index 571eb4232..000000000 --- a/apis/lightspeed/v1beta1/zz_generated.deepcopy.go +++ /dev/null @@ -1,153 +0,0 @@ -//go:build !ignore_autogenerated - -/* -Copyright 2022. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by controller-gen. DO NOT EDIT. - -package v1beta1 - -import ( - "github.com/openstack-k8s-operators/lib-common/modules/common/condition" - runtime "k8s.io/apimachinery/pkg/runtime" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *OpenStackLightspeed) DeepCopyInto(out *OpenStackLightspeed) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackLightspeed. -func (in *OpenStackLightspeed) DeepCopy() *OpenStackLightspeed { - if in == nil { - return nil - } - out := new(OpenStackLightspeed) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *OpenStackLightspeed) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *OpenStackLightspeedCore) DeepCopyInto(out *OpenStackLightspeedCore) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackLightspeedCore. -func (in *OpenStackLightspeedCore) DeepCopy() *OpenStackLightspeedCore { - if in == nil { - return nil - } - out := new(OpenStackLightspeedCore) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *OpenStackLightspeedDefaults) DeepCopyInto(out *OpenStackLightspeedDefaults) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackLightspeedDefaults. -func (in *OpenStackLightspeedDefaults) DeepCopy() *OpenStackLightspeedDefaults { - if in == nil { - return nil - } - out := new(OpenStackLightspeedDefaults) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *OpenStackLightspeedList) DeepCopyInto(out *OpenStackLightspeedList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]OpenStackLightspeed, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackLightspeedList. -func (in *OpenStackLightspeedList) DeepCopy() *OpenStackLightspeedList { - if in == nil { - return nil - } - out := new(OpenStackLightspeedList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *OpenStackLightspeedList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *OpenStackLightspeedSpec) DeepCopyInto(out *OpenStackLightspeedSpec) { - *out = *in - out.OpenStackLightspeedCore = in.OpenStackLightspeedCore -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackLightspeedSpec. -func (in *OpenStackLightspeedSpec) DeepCopy() *OpenStackLightspeedSpec { - if in == nil { - return nil - } - out := new(OpenStackLightspeedSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *OpenStackLightspeedStatus) DeepCopyInto(out *OpenStackLightspeedStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make(condition.Conditions, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackLightspeedStatus. -func (in *OpenStackLightspeedStatus) DeepCopy() *OpenStackLightspeedStatus { - if in == nil { - return nil - } - out := new(OpenStackLightspeedStatus) - in.DeepCopyInto(out) - return out -} diff --git a/bindata/crds/crds.yaml b/bindata/crds/crds.yaml index 6c5401402..b9482639c 100644 --- a/bindata/crds/crds.yaml +++ b/bindata/crds/crds.yaml @@ -17687,102 +17687,6 @@ spec: --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.18.0 - name: openstacklightspeeds.lightspeed.openstack.org -spec: - group: lightspeed.openstack.org - names: - kind: OpenStackLightspeed - listKind: OpenStackLightspeedList - plural: openstacklightspeeds - singular: openstacklightspeed - scope: Namespaced - versions: - - additionalPrinterColumns: - - description: Status - jsonPath: .status.conditions[0].status - name: Status - type: string - - description: Message - jsonPath: .status.conditions[0].message - name: Message - type: string - name: v1beta1 - schema: - openAPIV3Schema: - properties: - apiVersion: - type: string - kind: - type: string - metadata: - type: object - spec: - properties: - llmCredentials: - type: string - llmEndpoint: - type: string - llmEndpointType: - enum: - - azure_openai - - bam - - openai - - watsonx - - rhoai_vllm - - rhelai_vllm - - fake_provider - type: string - modelName: - type: string - ragImage: - type: string - tlsCACertBundle: - type: string - required: - - llmCredentials - - llmEndpoint - - llmEndpointType - - modelName - type: object - status: - properties: - conditions: - items: - properties: - lastTransitionTime: - format: date-time - type: string - message: - type: string - reason: - type: string - severity: - type: string - status: - type: string - type: - type: string - required: - - lastTransitionTime - - status - - type - type: object - type: array - observedGeneration: - format: int64 - type: integer - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.18.0 diff --git a/bindata/rbac/rbac.yaml b/bindata/rbac/rbac.yaml index 17b067e05..09a3fd41b 100644 --- a/bindata/rbac/rbac.yaml +++ b/bindata/rbac/rbac.yaml @@ -79,7 +79,6 @@ rules: - "" resources: - namespaces - - pods/log - projects verbs: - get @@ -394,32 +393,6 @@ rules: - patch - update - watch -- apiGroups: - - lightspeed.openstack.org - resources: - - openstacklightspeeds - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - lightspeed.openstack.org - resources: - - openstacklightspeeds/finalizers - verbs: - - update -- apiGroups: - - lightspeed.openstack.org - resources: - - openstacklightspeeds/status - verbs: - - get - - patch - - update - apiGroups: - machineconfiguration.openshift.io resources: @@ -538,32 +511,6 @@ rules: - patch - update - watch -- apiGroups: - - ols.openshift.io - resources: - - olsconfigs - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - ols.openshift.io - resources: - - olsconfigs/finalizers - verbs: - - update -- apiGroups: - - ols.openshift.io - resources: - - olsconfigs/status - verbs: - - get - - patch - - update - apiGroups: - operator.openshift.io resources: @@ -572,13 +519,6 @@ rules: - get - list - watch -- apiGroups: - - operators.coreos.com - resources: - - clusterserviceversions - verbs: - - get - - list - apiGroups: - ovn.openstack.org resources: diff --git a/config/crd/bases/lightspeed.openstack.org_openstacklightspeeds.yaml b/config/crd/bases/lightspeed.openstack.org_openstacklightspeeds.yaml deleted file mode 100644 index 104850713..000000000 --- a/config/crd/bases/lightspeed.openstack.org_openstacklightspeeds.yaml +++ /dev/null @@ -1,96 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.18.0 - name: openstacklightspeeds.lightspeed.openstack.org -spec: - group: lightspeed.openstack.org - names: - kind: OpenStackLightspeed - listKind: OpenStackLightspeedList - plural: openstacklightspeeds - singular: openstacklightspeed - scope: Namespaced - versions: - - additionalPrinterColumns: - - description: Status - jsonPath: .status.conditions[0].status - name: Status - type: string - - description: Message - jsonPath: .status.conditions[0].message - name: Message - type: string - name: v1beta1 - schema: - openAPIV3Schema: - properties: - apiVersion: - type: string - kind: - type: string - metadata: - type: object - spec: - properties: - llmCredentials: - type: string - llmEndpoint: - type: string - llmEndpointType: - enum: - - azure_openai - - bam - - openai - - watsonx - - rhoai_vllm - - rhelai_vllm - - fake_provider - type: string - modelName: - type: string - ragImage: - type: string - tlsCACertBundle: - type: string - required: - - llmCredentials - - llmEndpoint - - llmEndpointType - - modelName - type: object - status: - properties: - conditions: - items: - properties: - lastTransitionTime: - format: date-time - type: string - message: - type: string - reason: - type: string - severity: - type: string - status: - type: string - type: - type: string - required: - - lastTransitionTime - - status - - type - type: object - type: array - observedGeneration: - format: int64 - type: integer - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index 99115b878..d9616b021 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -9,7 +9,6 @@ resources: - bases/dataplane.openstack.org_openstackdataplaneservices.yaml - bases/dataplane.openstack.org_openstackdataplanedeployments.yaml #- bases/operator.openstack.org_openstacks.yaml -- bases/lightspeed.openstack.org_openstacklightspeeds.yaml #+kubebuilder:scaffold:crdkustomizeresource patches: @@ -27,7 +26,6 @@ patches: #- path: patches/cainjection_in_client_openstackclients.yaml #- path: patches/cainjection_in_core_openstackversions.yaml #- path: patches/cainjection_in_operator_openstacks.yaml -#- path: patches/cainjection_in_openstacklightspeeds.yaml #+kubebuilder:scaffold:crdkustomizecainjectionpatch # the following config is for teaching kustomize how to do kustomization for CRDs. diff --git a/config/crd/patches/cainjection_in_lightspeed_openstacklightspeeds.yaml b/config/crd/patches/cainjection_in_lightspeed_openstacklightspeeds.yaml deleted file mode 100644 index 4baf3e4af..000000000 --- a/config/crd/patches/cainjection_in_lightspeed_openstacklightspeeds.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# The following patch adds a directive for certmanager to inject CA into the CRD -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) - name: openstacklightspeeds.lightspeed.openstack.org diff --git a/config/manifests/bases/openstack-operator.clusterserviceversion.yaml b/config/manifests/bases/openstack-operator.clusterserviceversion.yaml index 4b159c1bb..a78a4a5da 100644 --- a/config/manifests/bases/openstack-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/openstack-operator.clusterserviceversion.yaml @@ -633,16 +633,6 @@ spec: x-descriptors: - urn:alm:descriptor:io.kubernetes.conditions version: v1beta1 - - description: OpenStackLightspeed is the Schema for the openstacklightspeeds - API - displayName: OpenStack Lightspeed - kind: OpenStackLightspeed - name: openstacklightspeeds.lightspeed.openstack.org - specDescriptors: - - description: Type of the provider serving the LLM - displayName: Provider Type - path: llmEndpointType - version: v1beta1 - description: OpenStack is the Schema for the openstacks API displayName: OpenStack kind: OpenStack diff --git a/config/operator/default_images.yaml b/config/operator/default_images.yaml index b768e9452..e67128b25 100644 --- a/config/operator/default_images.yaml +++ b/config/operator/default_images.yaml @@ -187,8 +187,6 @@ spec: value: quay.io/podified-master-centos9/openstack-watcher-applier:current-podified - name: RELATED_IMAGE_WATCHER_DECISION_ENGINE_IMAGE_URL_DEFAULT value: quay.io/podified-master-centos9/openstack-watcher-decision-engine:current-podified - - name: RELATED_IMAGE_OPENSTACK_LIGHTSPEED_IMAGE_URL_DEFAULT - value: quay.io/openstack-lightspeed/rag-content:os-docs-2024.2 # NOTE: TEST_ images below do not get released downstream. They should not be prefixed with RELATED - name: TEST_TOBIKO_IMAGE_URL_DEFAULT value: quay.io/podified-antelope-centos9/openstack-tobiko:current-podified diff --git a/config/rbac/lightspeed_openstacklightspeed_editor_role.yaml b/config/rbac/lightspeed_openstacklightspeed_editor_role.yaml deleted file mode 100644 index ee4963be5..000000000 --- a/config/rbac/lightspeed_openstacklightspeed_editor_role.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# permissions for end users to edit openstacklightspeeds. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: openstacklightspeed-editor-role - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: openstack-operator - app.kubernetes.io/part-of: openstack-operator - app.kubernetes.io/managed-by: kustomize - name: openstacklightspeed-editor-role -rules: -- apiGroups: - - lightspeed.openstack.org - resources: - - openstacklightspeeds - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - lightspeed.openstack.org - resources: - - openstacklightspeeds/status - verbs: - - get diff --git a/config/rbac/lightspeed_openstacklightspeed_viewer_role.yaml b/config/rbac/lightspeed_openstacklightspeed_viewer_role.yaml deleted file mode 100644 index 019e8a408..000000000 --- a/config/rbac/lightspeed_openstacklightspeed_viewer_role.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# permissions for end users to view openstacklightspeeds. -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/name: clusterrole - app.kubernetes.io/instance: openstacklightspeed-viewer-role - app.kubernetes.io/component: rbac - app.kubernetes.io/created-by: openstack-operator - app.kubernetes.io/part-of: openstack-operator - app.kubernetes.io/managed-by: kustomize - name: openstacklightspeed-viewer-role -rules: -- apiGroups: - - lightspeed.openstack.org - resources: - - openstacklightspeeds - verbs: - - get - - list - - watch -- apiGroups: - - lightspeed.openstack.org - resources: - - openstacklightspeeds/status - verbs: - - get diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index d970de4fc..7decfd254 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -36,7 +36,6 @@ rules: - "" resources: - namespaces - - pods/log - projects verbs: - get @@ -351,32 +350,6 @@ rules: - patch - update - watch -- apiGroups: - - lightspeed.openstack.org - resources: - - openstacklightspeeds - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - lightspeed.openstack.org - resources: - - openstacklightspeeds/finalizers - verbs: - - update -- apiGroups: - - lightspeed.openstack.org - resources: - - openstacklightspeeds/status - verbs: - - get - - patch - - update - apiGroups: - machineconfiguration.openshift.io resources: @@ -495,32 +468,6 @@ rules: - patch - update - watch -- apiGroups: - - ols.openshift.io - resources: - - olsconfigs - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - ols.openshift.io - resources: - - olsconfigs/finalizers - verbs: - - update -- apiGroups: - - ols.openshift.io - resources: - - olsconfigs/status - verbs: - - get - - patch - - update - apiGroups: - operator.openshift.io resources: @@ -529,13 +476,6 @@ rules: - get - list - watch -- apiGroups: - - operators.coreos.com - resources: - - clusterserviceversions - verbs: - - get - - list - apiGroups: - ovn.openstack.org resources: diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml index 966b2505e..138d15b6b 100644 --- a/config/samples/kustomization.yaml +++ b/config/samples/kustomization.yaml @@ -10,5 +10,4 @@ resources: #- dataplane_v1beta1_openstackdataplaneservice_empty.yaml #- dataplane_v1beta1_openstackdataplanedeployment_empty.yaml - operator_v1beta1_openstack.yaml -- lightspeed_v1beta1_openstacklightspeed.yaml #+kubebuilder:scaffold:manifestskustomizesamples diff --git a/config/samples/lightspeed_v1beta1_openstacklightspeed.yaml b/config/samples/lightspeed_v1beta1_openstacklightspeed.yaml deleted file mode 100644 index 6b0293801..000000000 --- a/config/samples/lightspeed_v1beta1_openstacklightspeed.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: lightspeed.openstack.org/v1beta1 -kind: OpenStackLightspeed -metadata: - name: openstacklightspeed-sample -spec: - llmEndpoint: - llmEndpointType: - llmCredentials: - modelName: - tlsCACertBundle: diff --git a/controllers/lightspeed/openstacklightspeed_controller.go b/controllers/lightspeed/openstacklightspeed_controller.go deleted file mode 100644 index 56b1dd726..000000000 --- a/controllers/lightspeed/openstacklightspeed_controller.go +++ /dev/null @@ -1,319 +0,0 @@ -/* -Copyright 2025. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package lightspeed implements the OpenStackLightspeed controller for managing OpenStack Lightspeed resources -package lightspeed - -import ( - "context" - "fmt" - "time" - - corev1beta1 "github.com/openstack-k8s-operators/openstack-operator/apis/core/v1beta1" - "sigs.k8s.io/controller-runtime/pkg/handler" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - "github.com/go-logr/logr" - "github.com/openstack-k8s-operators/lib-common/modules/common/condition" - common_helper "github.com/openstack-k8s-operators/lib-common/modules/common/helper" - lightspeedv1 "github.com/openstack-k8s-operators/openstack-operator/apis/lightspeed/v1beta1" - k8s_errors "k8s.io/apimachinery/pkg/api/errors" - uns "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/client-go/kubernetes" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "sigs.k8s.io/controller-runtime/pkg/log" - - "github.com/openstack-k8s-operators/openstack-operator/pkg/lightspeed" -) - -// OpenStackLightspeedReconciler reconciles a OpenStackLightspeed object -type OpenStackLightspeedReconciler struct { - client.Client - Scheme *runtime.Scheme - Kclient kubernetes.Interface -} - -// GetLogger returns a logger object with a prefix of "controller.name" and additional controller context fields -func (r *OpenStackLightspeedReconciler) GetLogger(ctx context.Context) logr.Logger { - return log.FromContext(ctx).WithName("Controllers").WithName("OpenStackLightspeed") -} - -// +kubebuilder:rbac:groups=lightspeed.openstack.org,resources=openstacklightspeeds,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=lightspeed.openstack.org,resources=openstacklightspeeds/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=lightspeed.openstack.org,resources=openstacklightspeeds/finalizers,verbs=update -// +kubebuilder:rbac:groups=ols.openshift.io,resources=olsconfigs,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=ols.openshift.io,resources=olsconfigs/status,verbs=get;update;patch -// +kubebuilder:rbac:groups=ols.openshift.io,resources=olsconfigs/finalizers,verbs=update -// +kubebuilder:rbac:groups=operators.coreos.com,resources=clusterserviceversions,verbs=get;list; -// +kubebuilder:rbac:groups=batch,resources=jobs,verbs=get;list;watch;create;update;patch;delete; -// +kubebuilder:rbac:groups="",resources=pods,verbs=create;delete;get;list;patch;update;watch -// +kubebuilder:rbac:groups="",resources=pods/log,verbs=get - -// Reconcile is part of the main kubernetes reconciliation loop which aims to -// move the current state of the cluster closer to the desired state. -// -// For more details, check Reconcile and its Result here: -// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.12.1/pkg/reconcile -func (r *OpenStackLightspeedReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - Log := r.GetLogger(ctx) - - instance := &lightspeedv1.OpenStackLightspeed{} - err := r.Get(ctx, req.NamespacedName, instance) - if err != nil { - if k8s_errors.IsNotFound(err) { - Log.Info("OpenStackLightspeed CR not found") - return ctrl.Result{}, nil - } - return ctrl.Result{}, err - } - - helper, err := common_helper.NewHelper( - instance, - r.Client, - r.Kclient, - r.Scheme, - Log, - ) - - // Save a copy of the conditions so that we can restore the LastTransitionTime - // when a condition's state doesn't change. - savedConditions := instance.Status.Conditions.DeepCopy() - - // Always patch the instance status when exiting this function so we can persist any changes. - defer func() { - // Don't update the status, if reconciler Panics - if r := recover(); r != nil { - Log.Info(fmt.Sprintf("panic during reconcile %v\n", r)) - panic(r) - } - - condition.RestoreLastTransitionTimes(&instance.Status.Conditions, savedConditions) - // update the Ready condition based on the sub conditions - if instance.Status.Conditions.AllSubConditionIsTrue() { - instance.Status.Conditions.MarkTrue( - condition.ReadyCondition, condition.ReadyMessage) - } else { - // something is not ready so reset the Ready condition - instance.Status.Conditions.MarkUnknown( - condition.ReadyCondition, condition.InitReason, condition.ReadyInitMessage) - // and recalculate it based on the state of the rest of the conditions - instance.Status.Conditions.Set( - instance.Status.Conditions.Mirror(condition.ReadyCondition)) - } - - err := helper.PatchInstance(ctx, instance) - if err != nil { - return - } - - }() - - cl := condition.CreateList( - condition.UnknownCondition( - lightspeedv1.OpenStackLightspeedReadyCondition, - condition.InitReason, - lightspeedv1.OpenStackLightspeedReadyInitMessage, - ), - ) - - instance.Status.Conditions.Init(&cl) - instance.Status.ObservedGeneration = instance.Generation - - if !instance.DeletionTimestamp.IsZero() { - return r.reconcileDelete(ctx, helper, instance) - } - - if instance.DeletionTimestamp.IsZero() && controllerutil.AddFinalizer(instance, helper.GetFinalizer()) { - return ctrl.Result{}, nil - } - - if instance.Spec.RAGImage == "" { - instance.Spec.RAGImage = lightspeedv1.OpenStackLightspeedDefaultValues.RAGImageURL - } - - OLSOperatorInstalled, err := lightspeed.IsOLSOperatorInstalled(ctx, helper) - if !OLSOperatorInstalled || err != nil { - errMsg := fmt.Errorf("installation of OpenShift LightSpeed not detected") - instance.Status.Conditions.Set(condition.FalseCondition( - lightspeedv1.OpenStackLightspeedReadyCondition, - condition.ErrorReason, - condition.SeverityWarning, - condition.DeploymentReadyErrorMessage, - errMsg)) - return ctrl.Result{}, errMsg - } - - // TODO(lpiwowar): Remove ResolveIndexID once OpenShift Lightspeed supports auto discovery of the indexID directly - // from the vector db image. - indexID, result, err := lightspeed.ResolveIndexID(ctx, helper, instance) - if err != nil { - instance.Status.Conditions.Set(condition.FalseCondition( - lightspeedv1.OpenStackLightspeedReadyCondition, - condition.ErrorReason, - condition.SeverityWarning, - condition.DeploymentReadyErrorMessage, - err.Error())) - return result, err - } else if (result != ctrl.Result{}) { - return result, nil - } - - // NOTE: We cannot consume the OLSConfig definition directly from the OLS operator's code due to - // a conflict in Go versions. When this comment was written, the min. required Go version for - // openstack-operator was 1.21 whereas OLS operator required at least Go version 1.23. Once the - // Go versions catch up with each other we should consider consuming OLSConfig directly from OLS - // operator and updating this code and any subsequent code that consumes this structure. - olsConfig := uns.Unstructured{} - olsConfigGVK := schema.GroupVersionKind{ - Group: "ols.openshift.io", - Version: "v1alpha1", - Kind: "OLSConfig", - } - - olsConfig.SetGroupVersionKind(olsConfigGVK) - olsConfig.SetName(lightspeed.OLSConfigName) - - _, err = controllerutil.CreateOrPatch(ctx, r.Client, &olsConfig, func() error { - // Check if the OpenStackLightspeed instance that is being processed owns the OLSConfig. If - // it is owned by other OpenStackLightspeed instance stop the reconciliation. - olsConfigLabels := olsConfig.GetLabels() - ownerLabel := "" - if val, ok := olsConfigLabels[lightspeed.OpenStackLightspeedOwnerIDLabel]; ok { - ownerLabel = val - } - - if ownerLabel != "" && ownerLabel != string(instance.GetObjectMeta().GetUID()) { - return fmt.Errorf("OLSConfig is managed by different OpenStackLightspeed instance") - } - - err = lightspeed.PatchOLSConfig(helper, instance, &olsConfig, indexID) - if err != nil { - return err - } - - return nil - }) - if err != nil { - instance.Status.Conditions.Set(condition.FalseCondition( - lightspeedv1.OpenStackLightspeedReadyCondition, - condition.ErrorReason, - condition.SeverityWarning, - condition.DeploymentReadyErrorMessage, - err.Error())) - return ctrl.Result{}, err - } - - OLSConfigReady, err := lightspeed.IsOLSConfigReady(ctx, helper) - if err != nil { - return ctrl.Result{}, err - } - - if OLSConfigReady { - instance.Status.Conditions.MarkTrue( - lightspeedv1.OpenStackLightspeedReadyCondition, - lightspeedv1.OpenStackLightspeedReadyMessage, - ) - } else { - Log.Info("OLSConfig is not ready yet. Waiting.") - return ctrl.Result{RequeueAfter: time.Second * time.Duration(5)}, nil - } - - return ctrl.Result{}, nil -} - -// reconcileDelete reconciles the deletion of OpenStackLightspeed instance -func (r *OpenStackLightspeedReconciler) reconcileDelete( - ctx context.Context, - helper *common_helper.Helper, - instance *lightspeedv1.OpenStackLightspeed, -) (ctrl.Result, error) { - Log := r.GetLogger(ctx) - - olsConfig, err := lightspeed.GetOLSConfig(ctx, helper) - if err != nil && k8s_errors.IsNotFound(err) { - controllerutil.RemoveFinalizer(instance, helper.GetFinalizer()) - return ctrl.Result{}, nil - } else if err != nil { - return ctrl.Result{}, err - } - - ownerLabel := olsConfig.GetLabels()[lightspeed.OpenStackLightspeedOwnerIDLabel] - if ownerLabel == "" || ownerLabel != string(instance.GetObjectMeta().GetUID()) { - Log.Info("Skipping OLSConfig deletion as it is not managed by the OpenStackLightspeed instance") - controllerutil.RemoveFinalizer(instance, helper.GetFinalizer()) - return ctrl.Result{}, nil - } - - _, err = controllerutil.CreateOrPatch(ctx, r.Client, &olsConfig, func() error { - if ok := controllerutil.RemoveFinalizer(&olsConfig, helper.GetFinalizer()); !ok { - return fmt.Errorf("remove finalizer failed") - } - - return nil - }) - if err != nil { - return ctrl.Result{}, err - } - - err = r.Delete(ctx, &olsConfig) - if err != nil { - return ctrl.Result{}, err - } - - controllerutil.RemoveFinalizer(instance, helper.GetFinalizer()) - - return ctrl.Result{}, nil -} - -// SetupWithManager sets up the controller with the Manager. -func (r *OpenStackLightspeedReconciler) SetupWithManager(mgr ctrl.Manager) error { - versionFunc := handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, o client.Object) []reconcile.Request { - Log := r.GetLogger(ctx) - versionList := &corev1beta1.OpenStackVersionList{} - - var result []reconcile.Request - - listOpts := []client.ListOption{ - client.InNamespace(o.GetNamespace()), - } - if err := r.List(ctx, versionList, listOpts...); err != nil { - Log.Error(err, "Unable to retrieve OpenStackVersion") - return nil - } - - for _, i := range versionList.Items { - name := client.ObjectKey{ - Namespace: o.GetNamespace(), - Name: i.Name, - } - result = append(result, reconcile.Request{NamespacedName: name}) - } - if len(result) > 0 { - Log.Info("Reconcile request for:", "result", result) - return result - } - return nil - }) - - return ctrl.NewControllerManagedBy(mgr). - For(&lightspeedv1.OpenStackLightspeed{}). - Watches(&corev1beta1.OpenStackVersion{}, versionFunc). - Complete(r) -} diff --git a/hack/export_related_images.sh b/hack/export_related_images.sh index f15a20155..096966d2e 100755 --- a/hack/export_related_images.sh +++ b/hack/export_related_images.sh @@ -90,7 +90,6 @@ export RELATED_IMAGE_TEST_TEMPEST_IMAGE_URL_DEFAULT=quay.io/podified-antelope-ce export RELATED_IMAGE_WATCHER_API_IMAGE_URL_DEFAULT=quay.io/podified-master-centos9/openstack-watcher-api:current-podified export RELATED_IMAGE_WATCHER_APPLIER_IMAGE_URL_DEFAULT=quay.io/podified-master-centos9/openstack-watcher-applier:current-podified export RELATED_IMAGE_WATCHER_DECISION_ENGINE_IMAGE_URL_DEFAULT=quay.io/podified-master-centos9/openstack-watcher-decision-engine:current-podified -export RELATED_IMAGE_OPENSTACK_LIGHTSPEED_IMAGE_URL_DEFAULT=quay.io/openstack-lightspeed/rag-content:os-docs-2024.2 #NOTE: TEST_ images below do not get released downstream. They should not be prefixed with RELATED export TEST_TOBIKO_IMAGE_URL_DEFAULT=quay.io/podified-antelope-centos9/openstack-tobiko:current-podified export TEST_ANSIBLETEST_IMAGE_URL_DEFAULT=quay.io/podified-antelope-centos9/openstack-ansible-tests:current-podified diff --git a/main.go b/main.go index 6e2516c53..bd0cbbf8a 100644 --- a/main.go +++ b/main.go @@ -86,11 +86,9 @@ import ( machineconfig "github.com/openshift/api/machineconfiguration/v1" ocp_image "github.com/openshift/api/operator/v1alpha1" - lightspeedv1beta1 "github.com/openstack-k8s-operators/openstack-operator/apis/lightspeed/v1beta1" clientcontrollers "github.com/openstack-k8s-operators/openstack-operator/controllers/client" corecontrollers "github.com/openstack-k8s-operators/openstack-operator/controllers/core" dataplanecontrollers "github.com/openstack-k8s-operators/openstack-operator/controllers/dataplane" - lightspeedcontrollers "github.com/openstack-k8s-operators/openstack-operator/controllers/lightspeed" "github.com/openstack-k8s-operators/openstack-operator/pkg/openstack" // +kubebuilder:scaffold:imports ) @@ -137,7 +135,6 @@ func init() { utilruntime.Must(operatorv1beta1.AddToScheme(scheme)) utilruntime.Must(topologyv1.AddToScheme(scheme)) utilruntime.Must(watcherv1.AddToScheme(scheme)) - utilruntime.Must(lightspeedv1beta1.AddToScheme(scheme)) // +kubebuilder:scaffold:scheme } @@ -280,9 +277,6 @@ func main() { // Defaults for OpenStackClient clientv1.SetupDefaults() - // Defaults for OpenStackLightspeed - lightspeedv1beta1.SetupDefaults() - // Defaults for Dataplane dataplanev1.SetupDefaults() @@ -320,14 +314,6 @@ func main() { checker = mgr.GetWebhookServer().StartedChecker() } - if err = (&lightspeedcontrollers.OpenStackLightspeedReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "OpenStackLightspeed") - os.Exit(1) - } - // +kubebuilder:scaffold:builder if err := mgr.AddHealthzCheck("healthz", checker); err != nil { setupLog.Error(err, "unable to set up health check") diff --git a/pkg/lightspeed/funcs.go b/pkg/lightspeed/funcs.go deleted file mode 100644 index ccab886fd..000000000 --- a/pkg/lightspeed/funcs.go +++ /dev/null @@ -1,383 +0,0 @@ -/* -Copyright 2025. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package lightspeed provides utilities and functions for OpenStack Lightspeed operations -package lightspeed - -import ( - "context" - "crypto/sha256" - "encoding/json" - "fmt" - "io" - "strings" - "time" - - "github.com/openstack-k8s-operators/lib-common/modules/common/condition" - batchv1 "k8s.io/api/batch/v1" - "k8s.io/client-go/kubernetes" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/config" - - common_helper "github.com/openstack-k8s-operators/lib-common/modules/common/helper" - lightspeedv1 "github.com/openstack-k8s-operators/openstack-operator/apis/lightspeed/v1beta1" - corev1 "k8s.io/api/core/v1" - k8s_errors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - uns "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime/schema" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" -) - -const ( - // OpenStackLightspeedDefaultProvider - contains default name for the provider created in OLSConfig - // by openstack-operator. - OpenStackLightspeedDefaultProvider = "openstack-lightspeed-provider" - - // OpenStackLightspeedOwnerIDLabel - name of a label that contains ID of OpenStackLightspeed instance - // that manages the OLSConfig. - OpenStackLightspeedOwnerIDLabel = "openstack.org/lightspeed-owner-id" - - // OpenStackLightspeedVectorDBPath - path inside of the container image where the vector DB are - // located - OpenStackLightspeedVectorDBPath = "/rag/vector_db/os_product_docs" - - // OpenStackLightspeedJobName - name of the pod that is used to discover environment variables inside of the RAG - // container image - OpenStackLightspeedJobName = "openstack-lightspeed" - - // OLSConfigName - OLS forbids other name for OLSConfig instance than OLSConfigName - OLSConfigName = "cluster" -) - -// GetOLSConfig returns OLSConfig if there is one present in the cluster. -func GetOLSConfig(ctx context.Context, helper *common_helper.Helper) (uns.Unstructured, error) { - OLSConfigGVR := schema.GroupVersionResource{ - Group: "ols.openshift.io", - Version: "v1alpha1", - Resource: "olsconfigs", - } - - OLSConfigList := &uns.UnstructuredList{} - OLSConfigList.SetGroupVersionKind(OLSConfigGVR.GroupVersion().WithKind("OLSConfig")) - err := helper.GetClient().List(ctx, OLSConfigList) - if err != nil { - return uns.Unstructured{}, err - } - - if len(OLSConfigList.Items) > 0 { - return OLSConfigList.Items[0], nil - } - - return uns.Unstructured{}, k8s_errors.NewNotFound( - schema.GroupResource{Group: "ols.openshifg.io", Resource: "olsconfigs"}, - "OLSConfig") -} - -// IsOLSOperatorInstalled checks whether OLS Operator is already running in the cluster. -func IsOLSOperatorInstalled(ctx context.Context, helper *common_helper.Helper) (bool, error) { - csvGVR := schema.GroupVersionResource{ - Group: "operators.coreos.com", - Version: "v1alpha1", - Resource: "clusterserviceversions", - } - - csvList := &uns.UnstructuredList{} - csvList.SetGroupVersionKind(csvGVR.GroupVersion().WithKind("clusterserviceversion")) - err := helper.GetClient().List(ctx, csvList) - if err != nil { - return false, err - } - - for _, csv := range csvList.Items { - if strings.HasPrefix(csv.GetName(), "lightspeed-operator") { - return true, nil - } - } - - return false, nil -} - -// PatchOLSConfig patches OLSConfig with information from OpenStackLightspeed instance. -func PatchOLSConfig( - helper *common_helper.Helper, - instance *lightspeedv1.OpenStackLightspeed, - olsConfig *uns.Unstructured, - indexID string, -) error { - // 1. Patch the Providers section - providersPatch := []interface{}{ - map[string]interface{}{ - "credentialsSecretRef": map[string]interface{}{ - "name": instance.Spec.LLMCredentials, - }, - "models": []interface{}{ - map[string]interface{}{ - "name": instance.Spec.ModelName, - "parameters": map[string]interface{}{}, - }, - }, - "name": OpenStackLightspeedDefaultProvider, - "type": instance.Spec.LLMEndpointType, - "url": instance.Spec.LLMEndpoint, - }, - } - if err := uns.SetNestedSlice(olsConfig.Object, providersPatch, "spec", "llm", "providers"); err != nil { - return err - } - - // 2. Patch the RAG section - openstackRAG := []interface{}{ - map[string]interface{}{ - "image": instance.Spec.RAGImage, - "indexID": indexID, - "indexPath": OpenStackLightspeedVectorDBPath, - }, - } - - if err := uns.SetNestedSlice(olsConfig.Object, openstackRAG, "spec", "ols", "rag"); err != nil { - return err - } - - if instance.Spec.TLSCACertBundle != "" { - tlsCaCertBundle := instance.Spec.TLSCACertBundle - err := uns.SetNestedField(olsConfig.Object, tlsCaCertBundle, "spec", "ols", "additionalCAConfigMapRef", "name") - if err != nil { - return err - } - } - - modelName := instance.Spec.ModelName - err := uns.SetNestedField(olsConfig.Object, modelName, "spec", "ols", "defaultModel") - if err != nil { - return err - } - - err = uns.SetNestedField(olsConfig.Object, OpenStackLightspeedDefaultProvider, "spec", "ols", "defaultProvider") - if err != nil { - return err - } - - // 3. Add info which OpenStackLightspeed instance owns the OLSConfig - labels := olsConfig.GetLabels() - updatedLabels := map[string]interface{}{ - OpenStackLightspeedOwnerIDLabel: string(instance.GetUID()), - } - for k, v := range labels { - updatedLabels[k] = v - } - - err = uns.SetNestedField(olsConfig.Object, updatedLabels, "metadata", "labels") - if err != nil { - return err - } - - // 4. Add OpenStack finalizers - if !controllerutil.AddFinalizer(olsConfig, helper.GetFinalizer()) && instance.Status.Conditions == nil { - return fmt.Errorf("cannot add finalizer") - } - - return nil -} - -// IsOLSConfigReady returns true if required conditions are true for OLSConfig -func IsOLSConfigReady(ctx context.Context, helper *common_helper.Helper) (bool, error) { - olsConfig, err := GetOLSConfig(ctx, helper) - if err != nil { - return false, err - } - - olsConfigStatusList, found, err := uns.NestedSlice(olsConfig.Object, "status", "conditions") - if !found { - return false, err - } - - jsonData, err := json.Marshal(olsConfigStatusList) - if err != nil { - return false, fmt.Errorf("failed to marshal OLSConfig status: %w", err) - } - - var OLSConfigConditions []metav1.Condition - err = json.Unmarshal(jsonData, &OLSConfigConditions) - if err != nil { - return false, fmt.Errorf("failed to unmarshal JSON containing condition.Conditions: %w", err) - } - - requiredConditionTypes := []string{"ConsolePluginReady", "CacheReady", "ApiReady", "Reconciled"} - for _, OLSConfigCondition := range OLSConfigConditions { - for _, requiredConditionType := range requiredConditionTypes { - if OLSConfigCondition.Type == requiredConditionType && OLSConfigCondition.Status != metav1.ConditionTrue { - return false, nil - } - } - } - - return true, nil -} - -// ResolveIndexID - returns index ID for the data stored in the vector DB container image. The discovery of the -// index ID is done through spawning a pod with the rag-content image and looking at the INDEX_NAME env variable value. -func ResolveIndexID( - ctx context.Context, - helper *common_helper.Helper, - instance *lightspeedv1.OpenStackLightspeed, -) (string, ctrl.Result, error) { - result, err := createOLSJob(ctx, helper, instance) - if err != nil { - return "", result, err - } - - podList := &corev1.PodList{} - labelSelector := client.MatchingLabels{"app": OpenStackLightspeedJobName} - if err := helper.GetClient().List(ctx, podList, client.InNamespace(instance.Namespace), labelSelector); err != nil { - return "", ctrl.Result{}, err - } - - var OLSPod *corev1.Pod - for _, pod := range podList.Items { - if pod.Spec.Containers[0].Image == instance.Spec.RAGImage { - OLSPod = &pod - break - } - } - if OLSPod == nil { - return requeueWaitingPod(helper, instance) - } - - switch OLSPod.Status.Phase { - case corev1.PodSucceeded: - indexName, err := extractEnvFromPodLogs(ctx, OLSPod, "INDEX_NAME") - if err != nil && k8s_errors.IsNotFound(err) { - return requeueWaitingPod(helper, instance) - } - return indexName, ctrl.Result{}, err - case corev1.PodFailed: - return "", ctrl.Result{}, fmt.Errorf("failed to start OpenStack Lightpseed RAG pod") - default: - return requeueWaitingPod(helper, instance) - } -} - -// extractEnvFromPodLogs - discovers an environment variable value from the pod logs. The pod must be started using -// createOLSJob. -func extractEnvFromPodLogs(ctx context.Context, pod *corev1.Pod, envVarName string) (string, error) { - cfg, err := config.GetConfig() - if err != nil { - return "", err - } - - k8sClient, err := kubernetes.NewForConfig(cfg) - if err != nil { - return "", err - } - - req := k8sClient.CoreV1().Pods(pod.Namespace).GetLogs(pod.Name, &corev1.PodLogOptions{}) - podLogs, err := req.Stream(ctx) - if err != nil { - return "", err - } - defer func() { _ = podLogs.Close() }() - - buf := new(strings.Builder) - _, err = io.Copy(buf, podLogs) - if err != nil { - return "", fmt.Errorf("error in copying logs: %w", err) - } - - logs := buf.String() - for _, envLine := range strings.Split(logs, "\n") { - parts := strings.Split(envLine, "=") - if len(parts) != 2 { - continue - } - - if parts[0] == envVarName { - return parts[1], nil - } - } - - return "", fmt.Errorf("env var not discovered: %s", envVarName) -} - -// createOLSJob - starts OLS pod with entrypoint that lists environment variables after the start of the pod. It used -// to discover INDEX_NAME value. -func createOLSJob( - ctx context.Context, - helper *common_helper.Helper, - instance *lightspeedv1.OpenStackLightspeed, -) (ctrl.Result, error) { - imageHash := sha256.Sum256([]byte(instance.Spec.RAGImage)) - imageHashStr := fmt.Sprintf("%x", imageHash) - imageHashStr = imageHashStr[len(imageHashStr)-9:] - imageName := fmt.Sprintf("%s-%s", OpenStackLightspeedJobName, imageHashStr) - - ttlSecondsAfterFinished := int32(600) // 10 mins - activeDeadlineSeconds := int64(1200) // 20 mins - OLSPod := &batchv1.Job{ - ObjectMeta: metav1.ObjectMeta{ - Name: imageName, - Namespace: instance.Namespace, - Labels: map[string]string{ - "app": OpenStackLightspeedJobName, - }, - }, - Spec: batchv1.JobSpec{ - TTLSecondsAfterFinished: &ttlSecondsAfterFinished, - ActiveDeadlineSeconds: &activeDeadlineSeconds, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{ - "app": OpenStackLightspeedJobName, - }, - }, - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Name: "rag-content", - Image: instance.Spec.RAGImage, - Command: []string{"/bin/sh", "-c"}, - Args: []string{"env"}, - }, - }, - RestartPolicy: corev1.RestartPolicyNever, - }, - }, - }, - } - - if err := controllerutil.SetControllerReference(instance, OLSPod, helper.GetScheme()); err != nil { - return ctrl.Result{}, err - } - - err := helper.GetClient().Create(ctx, OLSPod) - if err != nil && !k8s_errors.IsAlreadyExists(err) { - return ctrl.Result{}, err - } - - return ctrl.Result{}, nil -} - -func requeueWaitingPod(helper *common_helper.Helper, instance *lightspeedv1.OpenStackLightspeed) (string, ctrl.Result, error) { - instance.Status.Conditions.Set(condition.FalseCondition( - lightspeedv1.OpenStackLightspeedReadyCondition, - condition.RequestedReason, - condition.SeverityInfo, - lightspeedv1.OpenStackLightspeedWaitingVectorDBMessage, - )) - helper.GetLogger().Info(lightspeedv1.OpenStackLightspeedReadyMessage) - return "", ctrl.Result{RequeueAfter: 5 * time.Second}, nil -} diff --git a/tests/functional/ctlplane/suite_test.go b/tests/functional/ctlplane/suite_test.go index a4399871b..fd2cf9aba 100644 --- a/tests/functional/ctlplane/suite_test.go +++ b/tests/functional/ctlplane/suite_test.go @@ -51,7 +51,6 @@ import ( openstackclientv1 "github.com/openstack-k8s-operators/openstack-operator/apis/client/v1beta1" corev1 "github.com/openstack-k8s-operators/openstack-operator/apis/core/v1beta1" dataplanev1beta1 "github.com/openstack-k8s-operators/openstack-operator/apis/dataplane/v1beta1" - lightspeedv1 "github.com/openstack-k8s-operators/openstack-operator/apis/lightspeed/v1beta1" "github.com/openstack-k8s-operators/openstack-operator/pkg/openstack" ovnv1 "github.com/openstack-k8s-operators/ovn-operator/api/v1beta1" placementv1 "github.com/openstack-k8s-operators/placement-operator/api/v1beta1" @@ -61,7 +60,6 @@ import ( client_ctrl "github.com/openstack-k8s-operators/openstack-operator/controllers/client" core_ctrl "github.com/openstack-k8s-operators/openstack-operator/controllers/core" - lightspeed_ctrl "github.com/openstack-k8s-operators/openstack-operator/controllers/lightspeed" ocp_configv1 "github.com/openshift/api/config/v1" rabbitmqv1 "github.com/openstack-k8s-operators/infra-operator/apis/rabbitmq/v1beta1" @@ -229,8 +227,6 @@ var _ = BeforeSuite(func() { Expect(err).NotTo(HaveOccurred()) Expect(cfg).NotTo(BeNil()) - err = lightspeedv1.AddToScheme(scheme.Scheme) - Expect(err).NotTo(HaveOccurred()) err = openstackclientv1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) err = corev1.AddToScheme(scheme.Scheme) @@ -345,16 +341,8 @@ var _ = BeforeSuite(func() { core_ctrl.SetupVersionDefaults() openstack.SetupServiceOperatorDefaults() openstackclientv1.SetupDefaults() - lightspeedv1.SetupDefaults() corev1.SetupVersionDefaults() - err = (&lightspeed_ctrl.OpenStackLightspeedReconciler{ - Client: k8sManager.GetClient(), - Scheme: k8sManager.GetScheme(), - Kclient: kclient, - }).SetupWithManager(k8sManager) - Expect(err).ToNot(HaveOccurred()) - err = (&client_ctrl.OpenStackClientReconciler{ Client: k8sManager.GetClient(), Scheme: k8sManager.GetScheme(),