Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: bedrock support #389

Merged
merged 4 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ In the scenario where you are testing an uncomitted or unreleased K8sGPT with yo
by running again `LOCAL_MODE=1 make run` and in your local K8sGPT clone you can run `k8sgpt serve` or simply ` go run main.go serve`
Note: You should always deploy a K8sGPT Custom Resource so the operator's reconcilaition can be triggered and you can set arbitrary values for the k8sgpt's version since you will bypass them.

### Testing with GRPCurl

It is possible to test the operator's GRPC API with the grpcurl tool.
This enables you to test the K8sGPT GRPC API without the need of the K8sGPT Operator.

Example:
```
grpcurl -plaintext -d '{ "backend": "amazonbedrock", "explain": true}' localhost:8080 schema.v1.ServerService/Analyze
```

For API details visit the spec on [buf](https://buf.build/k8sgpt-ai/k8sgpt)

## Help
Feel free to join our slack [channel](https://k8sgpt.slack.com) and open GH issues, so we can make the development experience better for all K8sGPT contributors

36 changes: 35 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ EOF

## Other AI Backend Examples


<details>

<summary>AzureOpenAI</summary>
Expand Down Expand Up @@ -277,6 +278,39 @@ EOF

<details>

<summary>Amazon Bedrock</summary>

</details>
1. Install the operator from the [Installation](#installation) section.

2. Create secret:
```sh
kubectl create secret generic bedrock-sample-secret --from-literal=AWS_ACCESS_KEY_ID="$(echo $AWS_ACCESS_KEY_ID)" --from-literal=AWS_ACCESS_KEY="$(echo $AWS_ACCESS_KEY)" -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:
ai:
enabled: true
secret:
name: bedrock-sample-secret
model: anthropic.claude-v2
region: eu-central-1
backend: amazonbedrock
noCache: false
repository: ghcr.io/k8sgpt-ai/k8sgpt
version: v0.3.29
EOF
```

<details>

<summary>LocalAI</summary>


Expand Down Expand Up @@ -305,7 +339,7 @@ EOF
```
Note: ensure that the value of `baseUrl` is a properly constructed [DNS name](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#services) for the LocalAI Service. It should take the form: `http://local-ai.<namespace_local_ai_was_installed_in>.svc.cluster.local:8080/v1`.

4. Same as step 4. in the example above.
1. Same as step 4. in the example above.

</details>

Expand Down
3 changes: 3 additions & 0 deletions api/v1alpha1/k8sgpt_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ type AISpec struct {
Backend string `json:"backend"`
BackOff *BackOff `json:"backOff,omitempty"`
BaseUrl string `json:"baseUrl,omitempty"`
Region string `json:"region,omitempty"`
// +kubebuilder:default:=gpt-3.5-turbo
Model string `json:"model,omitempty"`
Engine string `json:"engine,omitempty"`
Expand Down Expand Up @@ -140,6 +141,8 @@ const (
)

// K8sGPTStatus defines the observed state of K8sGPT
// show the current backend used
// +kubebuilder:printcolumn:name="Backend",type="string",JSONPath=".spec.ai.backend",description="The current backend used"
type K8sGPTStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
Expand Down
7 changes: 5 additions & 2 deletions chart/operator/templates/k8sgpt-crd.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
Expand Down Expand Up @@ -74,6 +75,8 @@ spec:
model:
default: gpt-3.5-turbo
type: string
region:
type: string
secret:
properties:
key:
Expand Down Expand Up @@ -194,7 +197,7 @@ spec:
type: string
type: object
status:
description: K8sGPTStatus defines the observed state of K8sGPT
description: K8sGPTStatus defines the observed state of K8sGPT show the current backend used
type: object
type: object
served: true
Expand All @@ -206,4 +209,4 @@ status:
kind: ""
plural: ""
conditions: []
storedVersions: []
storedVersions: []
5 changes: 4 additions & 1 deletion config/crd/bases/core.k8sgpt.ai_k8sgpts.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ spec:
model:
default: gpt-3.5-turbo
type: string
region:
type: string
secret:
properties:
key:
Expand Down Expand Up @@ -194,7 +196,8 @@ spec:
type: string
type: object
status:
description: K8sGPTStatus defines the observed state of K8sGPT
description: K8sGPTStatus defines the observed state of K8sGPT show the
current backend used
type: object
type: object
served: true
Expand Down
4 changes: 2 additions & 2 deletions config/manager/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
images:
- name: controller
newName: ghcr.io/k8sgpt-ai/k8sgpt-operator
newTag: feature-integration-support-4
newName: tibbar/k8sgpt-operator
AlexsJones marked this conversation as resolved.
Show resolved Hide resolved
newTag: tmp-010
8 changes: 5 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ module github.com/k8sgpt-ai/k8sgpt-operator
go 1.21

require (
buf.build/gen/go/k8sgpt-ai/k8sgpt/grpc/go v1.3.0-20240128172516-6bf6a55ff115.2
buf.build/gen/go/k8sgpt-ai/k8sgpt/protocolbuffers/go v1.32.0-20240128172516-6bf6a55ff115.1
buf.build/gen/go/k8sgpt-ai/k8sgpt/grpc/go v1.3.0-20240213144542-6e830f3fdf19.2
buf.build/gen/go/k8sgpt-ai/k8sgpt/protocolbuffers/go v1.33.0-20240213144542-6e830f3fdf19.1
github.com/onsi/ginkgo/v2 v2.16.0
github.com/onsi/gomega v1.32.0
github.com/prometheus/client_golang v1.19.0
Expand Down Expand Up @@ -91,7 +91,9 @@ require (
golang.org/x/time v0.3.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.3.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect
google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240125205218-1f4bbc51befe // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
Expand Down
22 changes: 14 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
buf.build/gen/go/k8sgpt-ai/k8sgpt/grpc/go v1.3.0-20240128172516-6bf6a55ff115.2 h1:wCvkSdoAF1di3X07+0za7cydd57yXe8Px8q8Gv5me1U=
buf.build/gen/go/k8sgpt-ai/k8sgpt/grpc/go v1.3.0-20240128172516-6bf6a55ff115.2/go.mod h1:RX8MKkcN5AzJMjQ649kSzZKyYo3imsJCMQjQHJKgRpQ=
buf.build/gen/go/k8sgpt-ai/k8sgpt/protocolbuffers/go v1.28.1-20240128172516-6bf6a55ff115.4/go.mod h1:i/s4ALHwKvjA1oGNKpoHg0FpEOTbufoOm/NdTE6YQAE=
buf.build/gen/go/k8sgpt-ai/k8sgpt/protocolbuffers/go v1.32.0-20240128172516-6bf6a55ff115.1 h1:Gmrk0ASd78N487ATP3++w6i4iZ4HyUTIdYpE4Ib0CPI=
buf.build/gen/go/k8sgpt-ai/k8sgpt/protocolbuffers/go v1.32.0-20240128172516-6bf6a55ff115.1/go.mod h1:IThjyuPqz3nkYBGZMUzrHTQhYDedkvBonqAgLcG7sHc=
buf.build/gen/go/grpc-ecosystem/grpc-gateway/grpc/go v1.3.0-20231027202514-3f42134f4c56.2/go.mod h1:FL988BzZirjg37E5k8AJR39eQ6/n/esl7iEEF63xniA=
buf.build/gen/go/grpc-ecosystem/grpc-gateway/protocolbuffers/go v1.28.1-20231027202514-3f42134f4c56.4/go.mod h1:92ejKVTiuvnKoAtRlpJpIxKfloI935DDqhs0NCRx+KM=
buf.build/gen/go/grpc-ecosystem/grpc-gateway/protocolbuffers/go v1.33.0-20231027202514-3f42134f4c56.1/go.mod h1:DBJo17ITWaACJE5Kqb+81Ekkq0BpTsNmgv7cX1tMVpY=
buf.build/gen/go/k8sgpt-ai/k8sgpt/grpc/go v1.3.0-20240213144542-6e830f3fdf19.2 h1:dHSIT1w+0rtb//msVrp/RwrgHIeflbaTMKuF9Lx9HBI=
buf.build/gen/go/k8sgpt-ai/k8sgpt/grpc/go v1.3.0-20240213144542-6e830f3fdf19.2/go.mod h1:EWMdFAEvu6GDt7jvAgoBS/WgXlyDsM7yist2SrcnS3s=
buf.build/gen/go/k8sgpt-ai/k8sgpt/protocolbuffers/go v1.28.1-20240213144542-6e830f3fdf19.4/go.mod h1:WyRj8OIsAABLNsAELw73BT16v7vvJdEVv771fxX9pJI=
buf.build/gen/go/k8sgpt-ai/k8sgpt/protocolbuffers/go v1.33.0-20240213144542-6e830f3fdf19.1 h1:ctQgUFe6yA9/XRmorc4tMPK1Z5ZSA7bB2mPvtn3ZT0I=
buf.build/gen/go/k8sgpt-ai/k8sgpt/protocolbuffers/go v1.33.0-20240213144542-6e830f3fdf19.1/go.mod h1:QwDvmBCDx7mFDbKgaR6mWS2+oUs8mPLV6tNk9kV+Ctk=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
Expand Down Expand Up @@ -1213,8 +1216,12 @@ google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZV
google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg=
google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE=
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 h1:AjyfHzEPEFp/NpvfN5g+KDla3EMojjhRVZc1i7cj+oM=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s=
google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 h1:KAeGQVN3M9nD0/bQXnr/ClcEMJ968gUXJQ9pwfSynuQ=
google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro=
google.golang.org/genproto/googleapis/api v0.0.0-20240125205218-1f4bbc51befe h1:0poefMBYvYbs7g5UkjS6HcxBPaTRAmznle9jnxYoAI8=
google.golang.org/genproto/googleapis/api v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:4jWUdICTdgc3Ibxmr8nAJiiLHwQBY0UI0XZcEMaFKaA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe h1:bQnxqljG/wqi4NTXu2+DJ3n7APcEA882QZ1JvhQAq9o=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
Expand Down Expand Up @@ -1271,7 +1278,6 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
56 changes: 52 additions & 4 deletions pkg/resources/k8sgpt.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,32 @@ const (
DestroyOp
)

func addSecretAsEnvToDeployment(secretName string, secretKey string,
config v1alpha1.K8sGPT, c client.Client,
deployment *appsv1.Deployment) error {
secret := &corev1.Secret{}
er := c.Get(context.Background(), types.NamespacedName{Name: secretName,
Namespace: config.Namespace}, secret)
if er != nil {
return err.New("secret does not exist, cannot add to env of deployment")
}
envVar := v1.EnvVar{
Name: secretKey,
ValueFrom: &v1.EnvVarSource{
SecretKeyRef: &v1.SecretKeySelector{
LocalObjectReference: v1.LocalObjectReference{
Name: secretName,
},
Key: secretKey,
},
},
}
deployment.Spec.Template.Spec.Containers[0].Env = append(
deployment.Spec.Template.Spec.Containers[0].Env, envVar,
)
return nil
}

// GetService Create service for K8sGPT
func GetService(config v1alpha1.K8sGPT) (*corev1.Service, error) {
// Create service
Expand Down Expand Up @@ -179,7 +205,7 @@ func GetClusterRole(config v1alpha1.K8sGPT) (*r1.ClusterRole, error) {
}

// GetDeployment Create deployment with the latest K8sGPT image
func GetDeployment(config v1alpha1.K8sGPT, outOfClusterMode bool) (*appsv1.Deployment, error) {
func GetDeployment(config v1alpha1.K8sGPT, outOfClusterMode bool, c client.Client) (*appsv1.Deployment, error) {

// Create deployment
image := config.Spec.Repository + ":" + config.Spec.Version
Expand Down Expand Up @@ -303,7 +329,8 @@ func GetDeployment(config v1alpha1.K8sGPT, outOfClusterMode bool) (*appsv1.Deplo
},
})
}
if config.Spec.AI.Secret != nil {
// This check is necessary for the simple OpenAI journey, let's keep it here and guard from breaking other types of backend
if config.Spec.AI.Secret != nil && config.Spec.AI.Backend != v1alpha1.AmazonBedrock {
password := corev1.EnvVar{
Name: "K8SGPT_PASSWORD",
ValueFrom: &corev1.EnvVarSource{
Expand Down Expand Up @@ -367,7 +394,28 @@ func GetDeployment(config v1alpha1.K8sGPT, outOfClusterMode bool) (*appsv1.Deplo
deployment.Spec.Template.Spec.Containers[0].Env, engine,
)
} else if config.Spec.AI.Engine != "" && config.Spec.AI.Backend != v1alpha1.AzureOpenAI {
return &appsv1.Deployment{}, err.New("Engine is supported only by azureopenai provider.")
return &appsv1.Deployment{}, err.New("engine is supported only by azureopenai provider")
}
// Add checks for amazonbedrock
if config.Spec.AI.Backend == v1alpha1.AmazonBedrock {
if config.Spec.AI.Secret == nil {
return &appsv1.Deployment{}, err.New("secret is required for amazonbedrock backend")
}
if err := addSecretAsEnvToDeployment(config.Spec.AI.Secret.Name, "AWS_ACCESS_KEY_ID", config, c, &deployment); err != nil {
return &appsv1.Deployment{}, err
}
if err := addSecretAsEnvToDeployment(config.Spec.AI.Secret.Name, "AWS_SECRET_ACCESS_KEY", config, c, &deployment); err != nil {
return &appsv1.Deployment{}, err
}
if config.Spec.AI.Region == "" {
return &appsv1.Deployment{}, err.New("default region is required for amazonbedrock backend")
}
deployment.Spec.Template.Spec.Containers[0].Env = append(
deployment.Spec.Template.Spec.Containers[0].Env, corev1.EnvVar{
Name: "AWS_DEFAULT_REGION",
Value: config.Spec.AI.Region,
},
)
}
return &deployment, nil
}
Expand Down Expand Up @@ -409,7 +457,7 @@ func Sync(ctx context.Context, c client.Client,

objs = append(objs, svc)

deployment, er := GetDeployment(config, outOfClusterMode)
deployment, er := GetDeployment(config, outOfClusterMode, c)
if er != nil {
return er
}
Expand Down