diff --git a/controllers/k8sgpt_controller.go b/controllers/k8sgpt_controller.go index 47ec5f56..8625235d 100644 --- a/controllers/k8sgpt_controller.go +++ b/controllers/k8sgpt_controller.go @@ -17,8 +17,6 @@ package controllers import ( "context" "fmt" - "net" - "os" "strings" "time" @@ -31,7 +29,6 @@ import ( "github.com/k8sgpt-ai/k8sgpt-operator/pkg/utils" "github.com/prometheus/client_golang/prometheus" v1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -72,8 +69,6 @@ type K8sGPTReconciler struct { Integrations *integrations.Integrations SinkClient *sinks.Client K8sGPTClient *kclient.Client - // This is a map of clients for each deployment - k8sGPTClients map[string]*kclient.Client } // +kubebuilder:rbac:groups=core.k8sgpt.ai,resources=k8sgpts,verbs=get;list;watch;create;update;patch;delete @@ -158,44 +153,21 @@ func (r *K8sGPTReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr } // If the deployment is active, we will query it directly for analysis data - if _, ok := r.k8sGPTClients[k8sgptConfig.Name]; !ok { - // Create a new client - var address string - if os.Getenv("LOCAL_MODE") != "" { - address = "localhost:8080" - } else { - // Get service IP and port for k8sgpt-deployment - svc := &corev1.Service{} - err = r.Get(ctx, client.ObjectKey{Namespace: k8sgptConfig.Namespace, - Name: "k8sgpt"}, svc) - if err != nil { - k8sgptReconcileErrorCount.Inc() - return r.finishReconcile(err, false) - } - address = fmt.Sprintf("%s:%d", svc.Spec.ClusterIP, svc.Spec.Ports[0].Port) - } - - fmt.Printf("Creating new client for %s\n", address) - // Test if the port is open - conn, err := net.DialTimeout("tcp", address, 1*time.Second) - if err != nil { - k8sgptReconcileErrorCount.Inc() - return r.finishReconcile(err, false) - } - - fmt.Printf("Connection established between %s and localhost with time out of %d seconds.\n", address, int64(1)) - fmt.Printf("Remote Address : %s \n", conn.RemoteAddr().String()) - fmt.Printf("Local Address : %s \n", conn.LocalAddr().String()) + address, err := kclient.GenerateAddress(ctx, r.Client, k8sgptConfig) + if err != nil { + k8sgptReconcileErrorCount.Inc() + return r.finishReconcile(err, false) + } - k8sgptClient, err := kclient.NewClient(address) - if err != nil { - k8sgptReconcileErrorCount.Inc() - return r.finishReconcile(err, false) - } - r.k8sGPTClients[k8sgptConfig.Name] = k8sgptClient + k8sgptClient, err := kclient.NewClient(address) + if err != nil { + k8sgptReconcileErrorCount.Inc() + return r.finishReconcile(err, false) } - response, err := r.k8sGPTClients[k8sgptConfig.Name].ProcessAnalysis(deployment, k8sgptConfig) + defer k8sgptClient.Close() + + response, err := k8sgptClient.ProcessAnalysis(deployment, k8sgptConfig) if err != nil { k8sgptReconcileErrorCount.Inc() return r.finishReconcile(err, false) @@ -307,7 +279,6 @@ func (r *K8sGPTReconciler) SetupWithManager(mgr ctrl.Manager) error { For(&corev1alpha1.K8sGPT{}). Complete(r) - r.k8sGPTClients = make(map[string]*kclient.Client) metrics.Registry.MustRegister(k8sgptReconcileErrorCount, k8sgptNumberOfResults, k8sgptNumberOfResultsByType) return c diff --git a/go.mod b/go.mod index dbb82898..1b007321 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,8 @@ module github.com/k8sgpt-ai/k8sgpt-operator go 1.19 require ( - buf.build/gen/go/k8sgpt-ai/k8sgpt/grpc/go v1.3.0-20230515081240-6b5b845c638e.1 - buf.build/gen/go/k8sgpt-ai/k8sgpt/protocolbuffers/go v1.30.0-20230524215339-41d88e13ab7e.1 + buf.build/gen/go/k8sgpt-ai/k8sgpt/grpc/go v1.3.0-20230620082254-6f80f9533908.1 + buf.build/gen/go/k8sgpt-ai/k8sgpt/protocolbuffers/go v1.30.0-20230620082254-6f80f9533908.1 github.com/onsi/ginkgo/v2 v2.11.0 github.com/onsi/gomega v1.27.8 github.com/prometheus/client_golang v1.16.0 @@ -25,6 +25,7 @@ require ( ) require ( + buf.build/gen/go/k8sgpt-ai/k8sgpt/bufbuild/connect-go v1.8.0-20230620082254-6f80f9533908.1 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/beorn7/perks v1.0.1 // indirect diff --git a/go.sum b/go.sum index 137bf848..483d87cd 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,17 @@ +buf.build/gen/go/k8sgpt-ai/k8sgpt/bufbuild/connect-go v1.8.0-20230524215339-41d88e13ab7e.1 h1:7RSrwByMqFKjjpx4QO8ZxEYV3H/oW1VMUmI3xbkm2yU= +buf.build/gen/go/k8sgpt-ai/k8sgpt/bufbuild/connect-go v1.8.0-20230524215339-41d88e13ab7e.1/go.mod h1:P9jTXCmwBtjkW4wZDxkqpJj7FaCKlM+C4gV0AHGnoL4= +buf.build/gen/go/k8sgpt-ai/k8sgpt/bufbuild/connect-go v1.8.0-20230620082254-6f80f9533908.1 h1:9GY2k4cjPMieJSKYtpJPlAMLaMh+Hy8/Ia3S+hgP5Ys= +buf.build/gen/go/k8sgpt-ai/k8sgpt/bufbuild/connect-go v1.8.0-20230620082254-6f80f9533908.1/go.mod h1:Rvmr04OFqxFoURTWg9amY3483E0Rt3Hwnk8xBpFALRA= buf.build/gen/go/k8sgpt-ai/k8sgpt/grpc/go v1.3.0-20230515081240-6b5b845c638e.1 h1:u8CQODmTW0EYjXKt0ZSbA/FGuOkA+zRNicNCs97Ud/A= buf.build/gen/go/k8sgpt-ai/k8sgpt/grpc/go v1.3.0-20230515081240-6b5b845c638e.1/go.mod h1:EB1h/5OvQWTeT9JJ2x0NLaboeFOOm3fqkYWKp5ojO7o= +buf.build/gen/go/k8sgpt-ai/k8sgpt/grpc/go v1.3.0-20230620082254-6f80f9533908.1 h1:Z0zeGzAumjLyAb/24aiBNyAheT+SDBhlxPfcUy12nPI= +buf.build/gen/go/k8sgpt-ai/k8sgpt/grpc/go v1.3.0-20230620082254-6f80f9533908.1/go.mod h1:ydXSuYyk0CN76EA+cjFemhpz87XtuU310GdmkmXUUY8= buf.build/gen/go/k8sgpt-ai/k8sgpt/protocolbuffers/go v1.28.1-20230515081240-6b5b845c638e.4/go.mod h1:i/s4ALHwKvjA1oGNKpoHg0FpEOTbufoOm/NdTE6YQAE= +buf.build/gen/go/k8sgpt-ai/k8sgpt/protocolbuffers/go v1.28.1-20230620082254-6f80f9533908.4/go.mod h1:i/s4ALHwKvjA1oGNKpoHg0FpEOTbufoOm/NdTE6YQAE= buf.build/gen/go/k8sgpt-ai/k8sgpt/protocolbuffers/go v1.30.0-20230524215339-41d88e13ab7e.1 h1:Mx0Z+cXHStOU4lkemYYGhvNd40aU9g52sfS2W7D/gzA= buf.build/gen/go/k8sgpt-ai/k8sgpt/protocolbuffers/go v1.30.0-20230524215339-41d88e13ab7e.1/go.mod h1:karV92RruD5davytOQq20lDyAqBnai8ajNolo98nu94= +buf.build/gen/go/k8sgpt-ai/k8sgpt/protocolbuffers/go v1.30.0-20230620082254-6f80f9533908.1 h1:FNJYUdFjROTTKhIQ+VtJCzuWywQU430leJfnkStRRic= +buf.build/gen/go/k8sgpt-ai/k8sgpt/protocolbuffers/go v1.30.0-20230620082254-6f80f9533908.1/go.mod h1:karV92RruD5davytOQq20lDyAqBnai8ajNolo98nu94= 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= diff --git a/pkg/client/client.go b/pkg/client/client.go index 54c7cef5..a9189b5b 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -17,6 +17,7 @@ import ( "context" "encoding/json" "fmt" + "os" rpc "buf.build/gen/go/k8sgpt-ai/k8sgpt/grpc/go/schema/v1/schemav1grpc" schemav1 "buf.build/gen/go/k8sgpt-ai/k8sgpt/protocolbuffers/go/schema/v1" @@ -24,6 +25,8 @@ import ( "github.com/k8sgpt-ai/k8sgpt-operator/pkg/common" "google.golang.org/grpc" v1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "sigs.k8s.io/controller-runtime/pkg/client" ) // This is the client for communicating with the K8sGPT in cluster deployment @@ -31,6 +34,10 @@ type Client struct { conn *grpc.ClientConn } +func (c *Client) Close() error { + return c.conn.Close() +} + func NewClient(address string) (*Client, error) { // Connect to the K8sGPT server and create a new client conn, err := grpc.Dial(address, grpc.WithInsecure()) @@ -43,10 +50,26 @@ func NewClient(address string) (*Client, error) { return client, nil } -func (c *Client) ProcessAnalysis(deployment v1.Deployment, config *v1alpha1.K8sGPT) (*common.K8sGPTReponse, error) { +func GenerateAddress(ctx context.Context, cli client.Client, k8sgptConfig *v1alpha1.K8sGPT) (string, error) { + var address string + if os.Getenv("LOCAL_MODE") != "" { + address = "localhost:8080" + } else { + // Get service IP and port for k8sgpt-deployment + svc := &corev1.Service{} + err := cli.Get(ctx, client.ObjectKey{Namespace: k8sgptConfig.Namespace, + Name: "k8sgpt"}, svc) + if err != nil { + return "", nil + } + address = fmt.Sprintf("%s:%d", svc.Spec.ClusterIP, svc.Spec.Ports[0].Port) + } + return address, nil +} - client := rpc.NewServerClient(c.conn) +func (c *Client) ProcessAnalysis(deployment v1.Deployment, config *v1alpha1.K8sGPT) (*common.K8sGPTReponse, error) { + client := rpc.NewServerServiceClient(c.conn) req := &schemav1.AnalyzeRequest{ Explain: config.Spec.AI.Enabled, Nocache: config.Spec.NoCache,