diff --git a/api/v1alpha1/k8sgpt_types.go b/api/v1alpha1/k8sgpt_types.go index 83ea91a9..400da6f7 100644 --- a/api/v1alpha1/k8sgpt_types.go +++ b/api/v1alpha1/k8sgpt_types.go @@ -32,7 +32,7 @@ type SecretRef struct { type K8sGPTSpec struct { // +kubebuilder:default:=openai // +kubebuilder:validation:Enum=openai;localai;azureopenai - Backend string `json:"backend,omitempty"` + Backend `json:"backend"` BaseUrl string `json:"baseUrl,omitempty"` // +kubebuilder:default:=gpt-3.5-turbo Model string `json:"model,omitempty"` @@ -44,6 +44,14 @@ type K8sGPTSpec struct { Filters []string `json:"filters,omitempty"` } +type Backend string + +const ( + OpenAI Backend = "openai" + AzureOpenAI Backend = "azureopenai" + LocalAI Backend = "localai" +) + // K8sGPTStatus defines the observed state of K8sGPT type K8sGPTStatus struct { // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster diff --git a/api/v1alpha1/k8sgpt_types_test.go b/api/v1alpha1/k8sgpt_types_test.go index cff99daf..81029b3b 100644 --- a/api/v1alpha1/k8sgpt_types_test.go +++ b/api/v1alpha1/k8sgpt_types_test.go @@ -34,29 +34,27 @@ var _ = Describe("The test cases for the K8sGPT CRDs", func() { Key: "k8s-gpt", } - Kind = "K8sGPT" - Backend = "gpt" - Backend2 = "gpt-2" - BaseUrl = "https://api.k8s-gpt.localhost" - Model = "345M" - Version = "v1alpha1" + kind = "K8sGPT" + baseUrl = "https://api.k8s-gpt.localhost" + model = "345M" + version = "v1alpha1" Namespace = "k8sGPT" k8sGPT = K8sGPT{ TypeMeta: metav1.TypeMeta{ - Kind: Kind, + Kind: kind, }, ObjectMeta: metav1.ObjectMeta{ Name: "k8s-gpt", Namespace: Namespace, }, Spec: K8sGPTSpec{ - Backend: Backend, - BaseUrl: BaseUrl, - Model: Model, + Backend: OpenAI, + BaseUrl: baseUrl, + Model: model, Secret: &secretRef, - Version: Version, + Version: version, EnableAI: true, NoCache: true, }, @@ -64,18 +62,18 @@ var _ = Describe("The test cases for the K8sGPT CRDs", func() { k8sGPT2 = K8sGPT{ TypeMeta: metav1.TypeMeta{ - Kind: Kind, + Kind: kind, }, ObjectMeta: metav1.ObjectMeta{ Name: "k8s-gpt-2", Namespace: Namespace, }, Spec: K8sGPTSpec{ - Backend: Backend2, - BaseUrl: BaseUrl, - Model: Model, + Backend: AzureOpenAI, + BaseUrl: baseUrl, + Model: model, Secret: &secretRef, - Version: Version, + Version: version, EnableAI: false, NoCache: false, }, diff --git a/api/v1alpha1/result_types.go b/api/v1alpha1/result_types.go index 8d17a526..c5734c95 100644 --- a/api/v1alpha1/result_types.go +++ b/api/v1alpha1/result_types.go @@ -32,8 +32,7 @@ type Sensitive struct { // ResultSpec defines the desired state of Result type ResultSpec struct { - // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster - // Important: Run "make" to regenerate code after modifying this file + Backend `json:"backend"` Kind string `json:"kind"` Name string `json:"name"` Error []Failure `json:"error"` @@ -49,6 +48,8 @@ type ResultStatus struct { //+kubebuilder:object:root=true //+kubebuilder:subresource:status +//+kubebuilder:printcolumn:name="Kind",type="string",JSONPath=".spec.kind",description="Kind" +//+kubebuilder:printcolumn:name="Backend",type="string",JSONPath=".spec.backend",description="Backend" // Result is the Schema for the results API type Result struct { diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 526af2ec..9c3b03b8 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -25,6 +25,21 @@ import ( 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 *Backend) DeepCopyInto(out *Backend) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Backend. +func (in *Backend) DeepCopy() *Backend { + if in == nil { + return nil + } + out := new(Backend) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Failure) DeepCopyInto(out *Failure) { *out = *in @@ -107,6 +122,7 @@ func (in *K8sGPTList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *K8sGPTSpec) DeepCopyInto(out *K8sGPTSpec) { *out = *in + out.Backend = in.Backend if in.Secret != nil { in, out := &in.Secret, &out.Secret *out = new(SecretRef) @@ -206,6 +222,7 @@ func (in *ResultList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ResultSpec) DeepCopyInto(out *ResultSpec) { *out = *in + out.Backend = in.Backend if in.Error != nil { in, out := &in.Error, &out.Error *out = make([]Failure, len(*in)) diff --git a/config/crd/bases/core.k8sgpt.ai_k8sgpts.yaml b/config/crd/bases/core.k8sgpt.ai_k8sgpts.yaml index bf82acce..b8931807 100644 --- a/config/crd/bases/core.k8sgpt.ai_k8sgpts.yaml +++ b/config/crd/bases/core.k8sgpt.ai_k8sgpts.yaml @@ -66,6 +66,8 @@ spec: type: object version: type: string + required: + - backend type: object status: description: K8sGPTStatus defines the observed state of K8sGPT diff --git a/config/crd/bases/core.k8sgpt.ai_results.yaml b/config/crd/bases/core.k8sgpt.ai_results.yaml index 4fc6d008..3e4a8ff6 100644 --- a/config/crd/bases/core.k8sgpt.ai_results.yaml +++ b/config/crd/bases/core.k8sgpt.ai_results.yaml @@ -15,7 +15,16 @@ spec: singular: result scope: Namespaced versions: - - name: v1alpha1 + - additionalPrinterColumns: + - description: Kind + jsonPath: .spec.kind + name: Kind + type: string + - description: Backend + jsonPath: .spec.backend + name: Backend + type: string + name: v1alpha1 schema: openAPIV3Schema: description: Result is the Schema for the results API @@ -35,6 +44,8 @@ spec: spec: description: ResultSpec defines the desired state of Result properties: + backend: + type: string details: type: string error: @@ -54,14 +65,13 @@ spec: type: object type: array kind: - description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster - Important: Run "make" to regenerate code after modifying this file' type: string name: type: string parentObject: type: string required: + - backend - details - error - kind diff --git a/config/samples/k8sgpt_localai.yaml b/config/samples/k8sgpt_localai.yaml new file mode 100644 index 00000000..40d28f62 --- /dev/null +++ b/config/samples/k8sgpt_localai.yaml @@ -0,0 +1,12 @@ +apiVersion: core.k8sgpt.ai/v1alpha1 +kind: K8sGPT +metadata: + name: k8sgpt-sample-localai + namespace: k8sgpt-operator-system +spec: + model: ggml-gpt4all-j-v1.3-groovy.bin + backend: localai + baseUrl: http://local-ai.local-ai.svc.cluster.local:8080/v1 + noCache: false + enableAI: true + version: v0.3.0 \ No newline at end of file diff --git a/controllers/k8sgpt_controller.go b/controllers/k8sgpt_controller.go index 80250e20..8a3a7306 100644 --- a/controllers/k8sgpt_controller.go +++ b/controllers/k8sgpt_controller.go @@ -192,6 +192,7 @@ func (r *K8sGPTReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr k8sgptNumberOfResults.Set(float64(len(response.Results))) rawResults := make(map[string]corev1alpha1.Result) for _, resultSpec := range response.Results { + resultSpec.Backend = k8sgptConfig.Spec.Backend name := strings.ReplaceAll(resultSpec.Name, "-", "") name = strings.ReplaceAll(name, "/", "") result := corev1alpha1.Result{ diff --git a/pkg/client/client.go b/pkg/client/client.go index 09f0796a..6382bcc0 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -50,7 +50,7 @@ func (c *Client) ProcessAnalysis(deployment v1.Deployment, config *v1alpha1.K8sG req := &schemav1.AnalyzeRequest{ Explain: config.Spec.EnableAI, Nocache: config.Spec.NoCache, - Backend: config.Spec.Backend, + Backend: string(config.Spec.Backend), Filters: config.Spec.Filters, } diff --git a/pkg/resources/k8sgpt.go b/pkg/resources/k8sgpt.go index fb962211..26e797d5 100644 --- a/pkg/resources/k8sgpt.go +++ b/pkg/resources/k8sgpt.go @@ -185,7 +185,7 @@ func GetDeployment(config v1alpha1.K8sGPT) (*appsv1.Deployment, error) { }, { Name: "K8SGPT_BACKEND", - Value: config.Spec.Backend, + Value: string(config.Spec.Backend), }, }, Ports: []v1.ContainerPort{ @@ -235,7 +235,7 @@ func GetDeployment(config v1alpha1.K8sGPT) (*appsv1.Deployment, error) { ) } // Engine is required only when azureopenai is the ai backend - if config.Spec.Engine != "" && config.Spec.Backend == "azureopenai" { + if config.Spec.Engine != "" && config.Spec.Backend == v1alpha1.AzureOpenAI { engine := v1.EnvVar{ Name: "K8SGPT_ENGINE", Value: config.Spec.Engine, @@ -243,7 +243,7 @@ func GetDeployment(config v1alpha1.K8sGPT) (*appsv1.Deployment, error) { deployment.Spec.Template.Spec.Containers[0].Env = append( deployment.Spec.Template.Spec.Containers[0].Env, engine, ) - } else if config.Spec.Engine != "" && config.Spec.Backend != "azureopenai" { + } else if config.Spec.Engine != "" && config.Spec.Backend != v1alpha1.AzureOpenAI { return &appsv1.Deployment{}, err.New("Engine is supported only by azureopenai provider.") } return &deployment, nil