diff --git a/README.md b/README.md index 85bc0dbc..ef1a8d50 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,48 @@ you will be able to see the Results objects of the analysis after some minutes ( ## Remote Cache +
+ +Azure Blob storage + +1. Install the operator from the [Installation](#installation) section. + +2. Create secret: +```sh +kubectl create secret generic k8sgpt-sample-cache-secret --from-literal=azure_client_id= --from-literal=azure_tenant_id= --from-literal=azure_client_secret= -n k8sgpt- +operator-system +``` + +3. Apply the K8sGPT configuration object: +``` +kubectl apply -f - << EOF +apiVersion: core.k8sgpt.ai/v1alpha1 +kind: K8sGPT +metadata: + name: k8sgpt-sample + namespace: k8sgpt-operator-system +spec: + model: gpt-3.5-turbo + backend: openai + noCache: false + version: v0.3.0 + enableAI: true + secret: + name: k8sgpt-sample-secret + key: openai-api-key + remoteCache: + credentials: + name: k8sgpt-sample-cache-secret + azure: + # Storage account must already exist + storageAccount: "account_name" + containerName: "container_name" +EOF +``` + +
+ +
S3 @@ -111,9 +153,10 @@ spec: key: openai-api-key remoteCache: credentials: - name: k8sgpt-sample-cache-secret - bucketName: foo - region: us-west-1 + name: k8sgpt-sample-cache-secret + s3: + bucketName: foo + region: us-west-1 EOF ``` diff --git a/api/v1alpha1/k8sgpt_types.go b/api/v1alpha1/k8sgpt_types.go index 441012f2..a250a870 100644 --- a/api/v1alpha1/k8sgpt_types.go +++ b/api/v1alpha1/k8sgpt_types.go @@ -42,8 +42,18 @@ type CredentialsRef struct { type RemoteCacheRef struct { Credentials *CredentialsRef `json:"credentials,omitempty"` - BucketName string `json:"bucketName,omitempty"` - Region string `json:"region,omitempty"` + S3 *S3Backend `json:"s3,omitempty"` + Azure *AzureBackend `json:"azure,omitempty"` +} + +type S3Backend struct { + BucketName string `json:"bucketName,omitempty"` + Region string `json:"region,omitempty"` +} + +type AzureBackend struct { + StorageAccount string `json:"storageAccount,omitempty"` + ContainerName string `json:"containerName,omitempty"` } type WebhookRef struct { diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 3ef00f24..44f161fb 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -45,6 +45,21 @@ func (in *AISpec) DeepCopy() *AISpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AzureBackend) DeepCopyInto(out *AzureBackend) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AzureBackend. +func (in *AzureBackend) DeepCopy() *AzureBackend { + if in == nil { + return nil + } + out := new(AzureBackend) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Backstage) DeepCopyInto(out *Backstage) { *out = *in @@ -262,6 +277,16 @@ func (in *RemoteCacheRef) DeepCopyInto(out *RemoteCacheRef) { *out = new(CredentialsRef) **out = **in } + if in.S3 != nil { + in, out := &in.S3, &out.S3 + *out = new(S3Backend) + **out = **in + } + if in.Azure != nil { + in, out := &in.Azure, &out.Azure + *out = new(AzureBackend) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RemoteCacheRef. @@ -370,6 +395,21 @@ func (in *ResultStatus) DeepCopy() *ResultStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *S3Backend) DeepCopyInto(out *S3Backend) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new S3Backend. +func (in *S3Backend) DeepCopy() *S3Backend { + if in == nil { + return nil + } + out := new(S3Backend) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SecretRef) DeepCopyInto(out *SecretRef) { *out = *in diff --git a/chart/operator/templates/k8sgpt-crd.yaml b/chart/operator/templates/k8sgpt-crd.yaml index bfeaa5d2..62d9cb83 100644 --- a/chart/operator/templates/k8sgpt-crd.yaml +++ b/chart/operator/templates/k8sgpt-crd.yaml @@ -83,6 +83,28 @@ spec: type: array noCache: type: boolean + remoteCache: + properties: + azure: + properties: + containerName: + type: string + storageAccount: + type: string + type: object + credentials: + properties: + name: + type: string + type: object + s3: + properties: + bucketName: + type: string + region: + type: string + type: object + type: object sink: properties: type: diff --git a/config/crd/bases/core.k8sgpt.ai_k8sgpts.yaml b/config/crd/bases/core.k8sgpt.ai_k8sgpts.yaml index 9a536326..9acd2be4 100644 --- a/config/crd/bases/core.k8sgpt.ai_k8sgpts.yaml +++ b/config/crd/bases/core.k8sgpt.ai_k8sgpts.yaml @@ -97,15 +97,25 @@ spec: type: boolean remoteCache: properties: - bucketName: - type: string + azure: + properties: + containerName: + type: string + storageAccount: + type: string + type: object credentials: properties: name: type: string type: object - region: - type: string + s3: + properties: + bucketName: + type: string + region: + type: string + type: object type: object sink: properties: diff --git a/pkg/client/config.go b/pkg/client/config.go index 7d49d006..6b19306b 100644 --- a/pkg/client/config.go +++ b/pkg/client/config.go @@ -11,12 +11,19 @@ import ( func (c *Client) AddConfig(config *v1alpha1.K8sGPT) error { client := rpc.NewServerServiceClient(c.conn) - - req := &schemav1.AddConfigRequest{ - Cache: &schemav1.Cache{ - BucketName: config.Spec.RemoteCache.BucketName, - Region: config.Spec.RemoteCache.Region, - }, + req := &schemav1.AddConfigRequest{} + // If multiple caches are configured we pick S3 + // which emulates the behaviour of K8sGPT cli + if config.Spec.RemoteCache.S3 != nil { + req.Cache = &schemav1.Cache{ + BucketName: config.Spec.RemoteCache.S3.BucketName, + Region: config.Spec.RemoteCache.S3.Region, + } + } else if config.Spec.RemoteCache.Azure != nil { + req.Cache = &schemav1.Cache{ + StorageAccount: config.Spec.RemoteCache.Azure.StorageAccount, + ContainerName: config.Spec.RemoteCache.Azure.ContainerName, + } } _, err := client.AddConfig(context.Background(), req) @@ -31,10 +38,7 @@ func (c *Client) RemoveConfig(config *v1alpha1.K8sGPT) error { client := rpc.NewServerServiceClient(c.conn) req := &schemav1.RemoveConfigRequest{ - Cache: &schemav1.Cache{ - BucketName: config.Spec.RemoteCache.BucketName, - Region: config.Spec.RemoteCache.Region, - }, + Cache: &schemav1.Cache{}, } _, err := client.RemoveConfig(context.Background(), req) diff --git a/pkg/resources/k8sgpt.go b/pkg/resources/k8sgpt.go index 103fd727..bda75ca5 100644 --- a/pkg/resources/k8sgpt.go +++ b/pkg/resources/k8sgpt.go @@ -299,10 +299,16 @@ func GetDeployment(config v1alpha1.K8sGPT) (*appsv1.Deployment, error) { deployment.Spec.Template.Spec.Containers[0].Env, envVar, ) } - addRemoteCacheEnvVar("AWS_ACCESS_KEY_ID", "aws_access_key_id") - addRemoteCacheEnvVar("AWS_SECRET_ACCESS_KEY", "aws_secret_access_key") - + if config.Spec.RemoteCache.Azure != nil { + addRemoteCacheEnvVar("AZURE_CLIENT_ID", "azure_client_id") + addRemoteCacheEnvVar("AZURE_TENANT_ID", "azure_tenant_id") + addRemoteCacheEnvVar("AZURE_CLIENT_SECRET", "azure_client_secret") + } else if config.Spec.RemoteCache.S3 != nil { + addRemoteCacheEnvVar("AWS_ACCESS_KEY_ID", "aws_access_key_id") + addRemoteCacheEnvVar("AWS_SECRET_ACCESS_KEY", "aws_secret_access_key") + } } + if config.Spec.AI.BaseUrl != "" { baseUrl := corev1.EnvVar{ Name: "K8SGPT_BASEURL",