From 3988eb2fd0a7d29ffa7b7bbc59960ca91e50466e Mon Sep 17 00:00:00 2001 From: Alex Jones Date: Sat, 15 Apr 2023 18:05:14 +0100 Subject: [PATCH] feat: running in cluster Signed-off-by: Alex Jones --- Makefile | 12 +++++ cmd/serve/serve.go | 8 ++++ container/manifests/deployment.yaml | 5 +- container/manifests/role.yaml | 71 ++-------------------------- container/manifests/rolebinding.yaml | 13 +++++ container/manifests/sa.yaml | 5 ++ container/manifests/secret.yaml | 7 --- container/manifests/service.yaml | 13 +---- pkg/kubernetes/kubernetes.go | 33 +++++++------ 9 files changed, 64 insertions(+), 103 deletions(-) create mode 100644 container/manifests/rolebinding.yaml create mode 100644 container/manifests/sa.yaml delete mode 100644 container/manifests/secret.yaml diff --git a/Makefile b/Makefile index ee4a42b4fb..a5e3dd9107 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,16 @@ .PHONY: docker-build IMG ?= ghcr.io/k8sgpt-ai/k8sgpt:latest + +deploy: +ifndef SECRET + $(error SECRET environment variable is not set) +endif + kubectl create ns k8sgpt || true + kubectl create secret generic ai-backend-secret --from-literal=secret-key=$(SECRET) --namespace=k8sgpt || true + kubectl apply -f container/manifests +undeploy: + kubectl delete secret ai-backend-secret --namespace=k8sgpt + kubectl delete -f container/manifests + kubectl delete ns k8sgpt docker-build: docker buildx build --build-arg=VERSION="$$(git describe --tags --abbrev=0)" --build-arg=COMMIT="$$(git rev-parse --short HEAD)" --build-arg DATE="$$(date +%FT%TZ)" --platform="linux/amd64,linux/arm64" -t ${IMG} -f container/Dockerfile . --push \ No newline at end of file diff --git a/cmd/serve/serve.go b/cmd/serve/serve.go index e84984d219..89cbcc616d 100644 --- a/cmd/serve/serve.go +++ b/cmd/serve/serve.go @@ -42,6 +42,14 @@ var ServeCmd = &cobra.Command{ Password: password, Model: model, } + + configAI.Providers = append(configAI.Providers, *aiProvider) + + viper.Set("ai", configAI) + if err := viper.WriteConfig(); err != nil { + color.Red("Error writing config file: %s", err.Error()) + os.Exit(1) + } } else { color.Red("Error: AI provider not specified in configuration. Please run k8sgpt auth") os.Exit(1) diff --git a/container/manifests/deployment.yaml b/container/manifests/deployment.yaml index 38ad8d8410..86bbd121d3 100644 --- a/container/manifests/deployment.yaml +++ b/container/manifests/deployment.yaml @@ -2,6 +2,7 @@ apiVersion: apps/v1 kind: Deployment metadata: name: k8sgpt-deployment + namespace: k8sgpt labels: app: k8sgpt spec: @@ -14,9 +15,11 @@ spec: labels: app: k8sgpt spec: + serviceAccountName: k8sgpt containers: - name: k8sgpt-container - image: ghcr.io/k8sgpt-ai/k8sgpt:v0.2.2 #x-release-please-version + imagePullPolicy: Always + image: tibbar/test-k8sgpt:latest #x-release-please-version ports: - containerPort: 8080 args: ["serve"] diff --git a/container/manifests/role.yaml b/container/manifests/role.yaml index 82260364c5..ebdf1c254b 100644 --- a/container/manifests/role.yaml +++ b/container/manifests/role.yaml @@ -1,77 +1,12 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - name: k8sgpt-cluster-role + name: k8sgpt-cluster-role-all rules: - apiGroups: - - "" + - '*' resources: - - pods - - nodes - - persistentvolumeclaims - - namespaces - verbs: - - get - - list - - watch -- apiGroups: - - extensions - - apps - resources: - - deployments - - replicasets - - statefulsets - verbs: - - get - - list - - watch -- apiGroups: - - autoscaling - resources: - - horizontalpodautoscalers - verbs: - - get - - list - - watch -- apiGroups: - - networking.k8s.io - resources: - - networkpolicies - verbs: - - get - - list - - watch -- apiGroups: - - "" - resources: - - services - - endpoints - verbs: - - get - - list - - watch -- apiGroups: - - batch - resources: - - jobs - verbs: - - get - - list - - watch -- apiGroups: - - batch - - extensions - - batch.openshift.io - resources: - - cronjobs - verbs: - - get - - list - - watch -- apiGroups: - - "" - resources: - - events + - '*' verbs: - get - list diff --git a/container/manifests/rolebinding.yaml b/container/manifests/rolebinding.yaml new file mode 100644 index 0000000000..f103c15534 --- /dev/null +++ b/container/manifests/rolebinding.yaml @@ -0,0 +1,13 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: k8sgpt-rolebinding + namespace: k8sgpt +subjects: +- kind: ServiceAccount + name: k8sgpt + namespace: k8sgpt +roleRef: + kind: ClusterRole + name: k8sgpt-cluster-role-all + apiGroup: rbac.authorization.k8s.io \ No newline at end of file diff --git a/container/manifests/sa.yaml b/container/manifests/sa.yaml new file mode 100644 index 0000000000..09e7185bb0 --- /dev/null +++ b/container/manifests/sa.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: k8sgpt + namespace: k8sgpt \ No newline at end of file diff --git a/container/manifests/secret.yaml b/container/manifests/secret.yaml deleted file mode 100644 index a753b37872..0000000000 --- a/container/manifests/secret.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: ai-backend-secret -type: Opaque -data: - secret-key: diff --git a/container/manifests/service.yaml b/container/manifests/service.yaml index cfd9c04fd3..a2bb48d5f7 100644 --- a/container/manifests/service.yaml +++ b/container/manifests/service.yaml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: name: k8sgpt-service + namespace: k8sgpt spec: selector: app: k8sgpt @@ -10,15 +11,3 @@ spec: port: 8080 targetPort: 8080 type: ClusterIP ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: k8sgpt-rolebinding -subjects: -- kind: ServiceAccount - name: k8sgpt -roleRef: - kind: ClusterRole - name: k8sgpt-cluster-role - apiGroup: rbac.authorization.k8s.io \ No newline at end of file diff --git a/pkg/kubernetes/kubernetes.go b/pkg/kubernetes/kubernetes.go index 542c8afc69..f796c47325 100644 --- a/pkg/kubernetes/kubernetes.go +++ b/pkg/kubernetes/kubernetes.go @@ -28,26 +28,29 @@ func (c *Client) GetRestClient() rest.Interface { } func NewClient(kubecontext string, kubeconfig string) (*Client, error) { - - config := clientcmd.NewNonInteractiveDeferredLoadingClientConfig( - &clientcmd.ClientConfigLoadingRules{ExplicitPath: kubeconfig}, - &clientcmd.ConfigOverrides{ - CurrentContext: kubecontext, - }) - // create the clientset - c, err := config.ClientConfig() + var config *rest.Config + config, err := rest.InClusterConfig() if err != nil { - return nil, err + clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig( + &clientcmd.ClientConfigLoadingRules{ExplicitPath: kubeconfig}, + &clientcmd.ConfigOverrides{ + CurrentContext: kubecontext, + }) + // create the clientset + config, err = clientConfig.ClientConfig() + if err != nil { + return nil, err + } } - clientSet, err := kubernetes.NewForConfig(c) + clientSet, err := kubernetes.NewForConfig(config) if err != nil { return nil, err } - c.APIPath = "/api" - c.GroupVersion = &scheme.Scheme.PrioritizedVersionsForGroup("")[0] - c.NegotiatedSerializer = serializer.WithoutConversionCodecFactory{CodecFactory: scheme.Codecs} + config.APIPath = "/api" + config.GroupVersion = &scheme.Scheme.PrioritizedVersionsForGroup("")[0] + config.NegotiatedSerializer = serializer.WithoutConversionCodecFactory{CodecFactory: scheme.Codecs} - restClient, err := rest.RESTClientFor(c) + restClient, err := rest.RESTClientFor(config) if err != nil { return nil, err } @@ -55,6 +58,6 @@ func NewClient(kubecontext string, kubeconfig string) (*Client, error) { return &Client{ Client: clientSet, RestClient: restClient, - Config: c, + Config: config, }, nil }