From e51458e1742e45c865333a427223fb4b0adbeb9e Mon Sep 17 00:00:00 2001 From: Abdhesh Nayak Date: Mon, 8 Apr 2024 17:32:49 +0530 Subject: [PATCH 1/3] :construction: Wip --- .../internal/app/process-error-on-apply.go | 12 +++ .../internal/app/process-resource-updates.go | 13 +++ apps/infra/internal/domain/api.go | 4 + apps/infra/internal/domain/cluster-conn.go | 16 ++++ .../internal/entities/cluster-connection.go | 59 ++++++++++++ apps/infra/internal/entities/cluster-group.go | 90 +++++++++++++++++++ go.mod | 7 +- go.sum | 28 +++--- 8 files changed, 208 insertions(+), 21 deletions(-) create mode 100644 apps/infra/internal/domain/cluster-conn.go create mode 100644 apps/infra/internal/entities/cluster-connection.go create mode 100644 apps/infra/internal/entities/cluster-group.go diff --git a/apps/infra/internal/app/process-error-on-apply.go b/apps/infra/internal/app/process-error-on-apply.go index 3c54e5c35..6c8d3c48a 100644 --- a/apps/infra/internal/app/process-error-on-apply.go +++ b/apps/infra/internal/app/process-error-on-apply.go @@ -52,6 +52,18 @@ func ProcessErrorOnApply(consumer ErrorOnApplyConsumer, logger logging.Logger, d gvkstr := obj.GroupVersionKind().String() switch gvkstr { + case clusterConnGVK.String(): + { + cc, err := fn.JsonConvert[entities.ClusterConnection](obj.Object) + if err != nil { + return err + } + + if errObj.Action == t.ActionApply { + return d.OnClusterConnApplyError(dctx, errObj.ClusterName, obj.GetName(), errObj.Error, opts) + } + return d.OnClusterConnDeleteMessage(dctx, errObj.ClusterName, cc) + } case nodepoolGVK.String(): { nodepool, err := fn.JsonConvert[entities.NodePool](obj.Object) diff --git a/apps/infra/internal/app/process-resource-updates.go b/apps/infra/internal/app/process-resource-updates.go index 28c9d0ac1..f64e8ef53 100644 --- a/apps/infra/internal/app/process-resource-updates.go +++ b/apps/infra/internal/app/process-resource-updates.go @@ -33,6 +33,7 @@ func gvk(obj client.Object) string { var ( clusterGVK = fn.GVK("clusters.kloudlite.io/v1", "Cluster") + clusterConnGVK = fn.GVK("wireguard.kloudlite.io/v1", "ClusterConnection") nodepoolGVK = fn.GVK("clusters.kloudlite.io/v1", "NodePool") helmreleaseGVK = fn.GVK("crds.kloudlite.io/v1", "HelmChart") pvcGVK = fn.GVK("v1", "PersistentVolumeClaim") @@ -109,6 +110,18 @@ func processResourceUpdates(consumer ReceiveResourceUpdatesConsumer, d domain.Do } return d.OnClusterUpdateMessage(dctx, clus, resStatus, domain.UpdateAndDeleteOpts{MessageTimestamp: msg.Timestamp}) } + case clusterConnGVK.String(): + { + var np entities.ClusterConnection + if err := fn.JsonConversion(su.Object, &np); err != nil { + return errors.NewE(err) + } + + if resStatus == types.ResourceStatusDeleted { + return d.OnClusterConnDeleteMessage(dctx, su.ClusterName, np) + } + return d.OnClusterConnUpdateMessage(dctx, su.ClusterName, np, resStatus, domain.UpdateAndDeleteOpts{MessageTimestamp: msg.Timestamp}) + } case nodepoolGVK.String(): { var np entities.NodePool diff --git a/apps/infra/internal/domain/api.go b/apps/infra/internal/domain/api.go index 88072f83b..dd14dbf45 100644 --- a/apps/infra/internal/domain/api.go +++ b/apps/infra/internal/domain/api.go @@ -94,6 +94,10 @@ type Domain interface { OnNodePoolUpdateMessage(ctx InfraContext, clusterName string, nodePool entities.NodePool, status types.ResourceStatus, opts UpdateAndDeleteOpts) error OnNodepoolApplyError(ctx InfraContext, clusterName string, name string, errMsg string, opts UpdateAndDeleteOpts) error + OnClusterConnDeleteMessage(ctx InfraContext, clusterName string, clusterConn entities.ClusterConnection) error + OnClusterConnUpdateMessage(ctx InfraContext, clusterName string, clusterConn entities.ClusterConnection, status types.ResourceStatus, opts UpdateAndDeleteOpts) error + OnClusterConnApplyError(ctx InfraContext, clusterName string, name string, errMsg string, opts UpdateAndDeleteOpts) error + ListNodes(ctx InfraContext, clusterName string, search map[string]repos.MatchFilter, pagination repos.CursorPagination) (*repos.PaginatedRecord[*entities.Node], error) GetNode(ctx InfraContext, clusterName string, nodeName string) (*entities.Node, error) diff --git a/apps/infra/internal/domain/cluster-conn.go b/apps/infra/internal/domain/cluster-conn.go new file mode 100644 index 000000000..8d27e1c40 --- /dev/null +++ b/apps/infra/internal/domain/cluster-conn.go @@ -0,0 +1,16 @@ +package domain + +import ( + "github.com/kloudlite/api/apps/infra/internal/entities" + "github.com/kloudlite/operator/operators/resource-watcher/types" +) + +func (d *domain) OnClusterConnDeleteMessage(ctx InfraContext, clusterName string, clusterConn entities.ClusterConnection) error { + panic("implement me") +} +func (d *domain) OnClusterConnUpdateMessage(ctx InfraContext, clusterName string, clusterConn entities.ClusterConnection, status types.ResourceStatus, opts UpdateAndDeleteOpts) error { + panic("implement me") +} +func (d *domain) OnClusterConnApplyError(ctx InfraContext, clusterName string, name string, errMsg string, opts UpdateAndDeleteOpts) error { + panic("implement me") +} diff --git a/apps/infra/internal/entities/cluster-connection.go b/apps/infra/internal/entities/cluster-connection.go new file mode 100644 index 000000000..ced0bf254 --- /dev/null +++ b/apps/infra/internal/entities/cluster-connection.go @@ -0,0 +1,59 @@ +package entities + +import ( + "github.com/kloudlite/api/common" + "github.com/kloudlite/api/pkg/repos" + t "github.com/kloudlite/api/pkg/types" + wgv1 "github.com/kloudlite/operator/apis/wireguard/v1" + "github.com/kloudlite/operator/pkg/operator" +) + +type ClusterConnection struct { + repos.BaseEntity `json:",inline" graphql:"noinput"` + + wgv1.ClusterConnection `json:",inline"` + + common.ResourceMetadata `json:",inline"` + + AccountName string `json:"accountName" graphql:"noinput"` + ClusterName string `json:"clusterName" graphql:"noinput"` + + SyncStatus t.SyncStatus `json:"syncStatus" graphql:"noinput"` +} + +func (c *ClusterConnection) GetDisplayName() string { + return c.ResourceMetadata.DisplayName +} + +func (c *ClusterConnection) GetStatus() operator.Status { + return c.ClusterConnection.Status +} + +var ClusterConnIndices = []repos.IndexField{ + { + Field: []repos.IndexKey{ + {Key: "id", Value: repos.IndexAsc}, + }, + Unique: true, + }, + { + Field: []repos.IndexKey{ + {Key: "metadata.name", Value: repos.IndexAsc}, + {Key: "accountName", Value: repos.IndexAsc}, + {Key: "clusterName", Value: repos.IndexAsc}, + }, + Unique: true, + }, + { + Field: []repos.IndexKey{ + {Key: "accountName", Value: repos.IndexAsc}, + {Key: "spec.id", Value: repos.IndexAsc}, + }, + Unique: true, + }, + { + Field: []repos.IndexKey{ + {Key: "accountName", Value: repos.IndexAsc}, + }, + }, +} diff --git a/apps/infra/internal/entities/cluster-group.go b/apps/infra/internal/entities/cluster-group.go new file mode 100644 index 000000000..2204ed207 --- /dev/null +++ b/apps/infra/internal/entities/cluster-group.go @@ -0,0 +1,90 @@ +package entities + +import ( + "fmt" + + "github.com/kloudlite/api/common" + "github.com/kloudlite/api/pkg/functions" + "github.com/kloudlite/api/pkg/repos" + t "github.com/kloudlite/api/pkg/types" + "github.com/kloudlite/operator/pkg/operator" +) + +const ( + wgIpIndex = 16 + clusterPodIndex = 13 +) + +func GetCidrRanges(index int) (*string, error) { + switch index { + case wgIpIndex, clusterPodIndex: + return nil, fmt.Errorf("it can't be %d or %d", wgIpIndex, clusterPodIndex) + } + + if index < 0 || index > 255 { + return nil, fmt.Errorf("ip range can only be between 0 and 255") + } + + return functions.New(fmt.Sprintf("10.%d.0.0/16", index)), nil +} + +type Peers struct { + Name string `json:"name" graphql:"noinput"` + Namespace string `json:"namespace" graphql:"noinput"` + + Id int `json:"id" graphql:"noinput"` + PubKey string `json:"pubKey" graphql:"noinput"` + AllowedIps string `json:"allowedIps" graphql:"noinput"` +} + +type ClusterGroup struct { + repos.BaseEntity `json:",inline" graphql:"noinput"` + + common.ResourceMetadata `json:",inline"` + + Peers []Peers `json:"peers" graphql:"noinput"` + + AccountName string `json:"accountName" graphql:"noinput"` + ClusterName string `json:"clusterName" graphql:"noinput"` + + SyncStatus t.SyncStatus `json:"syncStatus" graphql:"noinput"` +} + +func (c *ClusterGroup) GetDisplayName() string { + return c.ResourceMetadata.DisplayName +} + +func (c *ClusterGroup) GetStatus() operator.Status { + return operator.Status{ + IsReady: true, + } +} + +var ClusterGroupIndices = []repos.IndexField{ + { + Field: []repos.IndexKey{ + {Key: "id", Value: repos.IndexAsc}, + }, + Unique: true, + }, + { + Field: []repos.IndexKey{ + {Key: "metadata.name", Value: repos.IndexAsc}, + {Key: "accountName", Value: repos.IndexAsc}, + {Key: "clusterName", Value: repos.IndexAsc}, + }, + Unique: true, + }, + { + Field: []repos.IndexKey{ + {Key: "accountName", Value: repos.IndexAsc}, + {Key: "spec.id", Value: repos.IndexAsc}, + }, + Unique: true, + }, + { + Field: []repos.IndexKey{ + {Key: "accountName", Value: repos.IndexAsc}, + }, + }, +} diff --git a/go.mod b/go.mod index 12ca00a1f..81fa488cd 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/go-redis/redis/v8 v8.11.5 github.com/gobuffalo/flect v1.0.2 github.com/gofiber/adaptor/v2 v2.1.23 - github.com/gofiber/fiber/v2 v2.52.1 + github.com/gofiber/fiber/v2 v2.52.2 github.com/gofiber/websocket/v2 v2.0.21 github.com/google/go-github/v43 v43.0.0 github.com/google/go-github/v45 v45.2.0 @@ -42,11 +42,11 @@ require ( require ( github.com/kloudlite/container-registry-authorizer v0.0.0-20231021122509-161dc30fde55 - github.com/kloudlite/operator v1.0.4-0.20240326121100-7a59627e6d54 + github.com/kloudlite/operator v1.0.4-0.20240408115241-4bc90f5d3986 github.com/nats-io/nats.go v1.31.0 github.com/onsi/ginkgo/v2 v2.12.0 github.com/onsi/gomega v1.27.10 - github.com/shamaton/msgpack/v2 v2.2.0 + github.com/seancfoley/ipaddress-go v1.5.4 github.com/stretchr/testify v1.9.0 github.com/ztrue/tracerr v0.4.0 golang.org/x/exp v0.0.0-20230905200255-921286631fa9 @@ -67,6 +67,7 @@ require ( github.com/nats-io/nuid v1.0.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rivo/uniseg v0.4.7 // indirect + github.com/seancfoley/bintree v1.2.1 // indirect github.com/sosodev/duration v1.2.0 // indirect github.com/stretchr/objx v0.5.2 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c // indirect diff --git a/go.sum b/go.sum index 8ca962893..f09873913 100644 --- a/go.sum +++ b/go.sum @@ -15,8 +15,6 @@ github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVb github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= -github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= @@ -82,10 +80,8 @@ github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x github.com/gofiber/adaptor/v2 v2.1.23 h1:VG0yAPnB2EJZjxy4Ul+Ra9e92PnqwXE97SUVuPGuoAA= github.com/gofiber/adaptor/v2 v2.1.23/go.mod h1:hnYEQBPF2x1JaBHygutJJF5d0+J2eYnKKsUMCSsfxKk= github.com/gofiber/fiber/v2 v2.32.0/go.mod h1:CMy5ZLiXkn6qwthrl03YMyW1NLfj0rhxz2LKl4t7ZTY= -github.com/gofiber/fiber/v2 v2.51.0 h1:JNACcZy5e2tGApWB2QrRpenTWn0fq0hkFm6k0C86gKQ= -github.com/gofiber/fiber/v2 v2.51.0/go.mod h1:xaQRZQJGqnKOQnbQw+ltvku3/h8QxvNi8o6JiJ7Ll0U= -github.com/gofiber/fiber/v2 v2.52.1 h1:1RoU2NS+b98o1L77sdl5mboGPiW+0Ypsi5oLmcYlgHI= -github.com/gofiber/fiber/v2 v2.52.1/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ= +github.com/gofiber/fiber/v2 v2.52.2 h1:b0rYH6b06Df+4NyrbdptQL8ifuxw/Tf2DgfkZkDaxEo= +github.com/gofiber/fiber/v2 v2.52.2/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ= github.com/gofiber/utils v0.1.2 h1:1SH2YEz4RlNS0tJlMJ0bGwO0JkqPqvq6TbHK9tXZKtk= github.com/gofiber/utils v0.1.2/go.mod h1:pacRFtghAE3UoknMOUiXh2Io/nLWSUHtQCi/3QASsOc= github.com/gofiber/websocket/v2 v2.0.21 h1:mQEiLXBqFsNNlJc5dzFgSGeoqoEXYvIcdBQzAZBdbL0= @@ -161,16 +157,14 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.14.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM= -github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/kloudlite/container-registry-authorizer v0.0.0-20231021122509-161dc30fde55 h1:YnZh3TL6AG4EfoInx1/L5zcPHd2QxgLKseJB1KtHjdQ= github.com/kloudlite/container-registry-authorizer v0.0.0-20231021122509-161dc30fde55/go.mod h1:GZj3wZmIw/qCciclRhgQTgmGiqe8wxoVzMXQjbOfnbc= -github.com/kloudlite/operator v1.0.4-0.20240320190031-57397d040302 h1:5oHaEVzE7gTnrVjbmpIWq9fIail31FRzqsPR4aqBtv0= -github.com/kloudlite/operator v1.0.4-0.20240320190031-57397d040302/go.mod h1:CnMPlG0NFL1KyhoKJj2ABdNeFF+yR3R+dzPFk3S9E3A= -github.com/kloudlite/operator v1.0.4-0.20240326121100-7a59627e6d54 h1:nsyBYLUAOQC3KETaDlGF7faAbudfDtMvVUmV21XCrGc= -github.com/kloudlite/operator v1.0.4-0.20240326121100-7a59627e6d54/go.mod h1:CnMPlG0NFL1KyhoKJj2ABdNeFF+yR3R+dzPFk3S9E3A= +github.com/kloudlite/operator v1.0.4-0.20240408092517-1f1fda928e08 h1:Vq7mx7UGpn8C8+DyxmVENPOyLy03Db3rpkD7iyVNSDI= +github.com/kloudlite/operator v1.0.4-0.20240408092517-1f1fda928e08/go.mod h1:ozyCDuQNCcMRu2XYZz4OtWr38IwRZ50ZCOcBsobj60c= +github.com/kloudlite/operator v1.0.4-0.20240408115241-4bc90f5d3986 h1:W/cN97IOzWAIjkUfri+eFxf8xZGat+L7mu1/XWIfxGU= +github.com/kloudlite/operator v1.0.4-0.20240408115241-4bc90f5d3986/go.mod h1:ozyCDuQNCcMRu2XYZz4OtWr38IwRZ50ZCOcBsobj60c= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -241,8 +235,6 @@ github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI= github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8= -github.com/rivo/uniseg v0.4.2/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= @@ -256,14 +248,16 @@ github.com/sanity-io/litter v1.5.5 h1:iE+sBxPBzoK6uaEP5Lt3fHNgpKcHXc/A2HGETy0uJQ github.com/sanity-io/litter v1.5.5/go.mod h1:9gzJgR2i4ZpjZHsKvUXIRQVk7P+yM3e+jAF7bU2UI5U= github.com/savsgio/gotils v0.0.0-20211223103454-d0aaa54c5899 h1:Orn7s+r1raRTBKLSc9DmbktTT04sL+vkzsbRD2Q8rOI= github.com/savsgio/gotils v0.0.0-20211223103454-d0aaa54c5899/go.mod h1:oejLrk1Y/5zOF+c/aHtXqn3TFlzzbAgPWg8zBiAHDas= +github.com/seancfoley/bintree v1.2.1 h1:Z/iNjRKkXnn0CTW7jDQYtjW5fz2GH1yWvOTJ4MrMvdo= +github.com/seancfoley/bintree v1.2.1/go.mod h1:hIUabL8OFYyFVTQ6azeajbopogQc2l5C/hiXMcemWNU= +github.com/seancfoley/ipaddress-go v1.5.4 h1:ZdjewWC1J2y5ruQjWHwK6rA1tInWB6mz1ftz6uTm+Uw= +github.com/seancfoley/ipaddress-go v1.5.4/go.mod h1:fpvVPC+Jso+YEhNcNiww8HQmBgKP8T4T6BTp1SLxxIo= github.com/sendgrid/rest v2.6.9+incompatible h1:1EyIcsNdn9KIisLW50MKwmSRSK+ekueiEMJ7NEoxJo0= github.com/sendgrid/rest v2.6.9+incompatible/go.mod h1:kXX7q3jZtJXK5c5qK83bSGMdV6tsOE70KbHoqJls4lE= github.com/sendgrid/sendgrid-go v3.11.1+incompatible h1:ai0+woZ3r/+tKLQExznak5XerOFoD6S7ePO0lMV8WXo= github.com/sendgrid/sendgrid-go v3.11.1+incompatible/go.mod h1:QRQt+LX/NmgVEvmdRw0VT/QgUn499+iza2FnDca9fg8= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= -github.com/shamaton/msgpack/v2 v2.2.0 h1:IP1m01pHwCrMa6ZccP9B3bqxEMKMSmMVAVKk54g3L/Y= -github.com/shamaton/msgpack/v2 v2.2.0/go.mod h1:6khjYnkx73f7VQU7wjcFS9DFjs+59naVWJv1TB7qdOI= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= @@ -297,8 +291,6 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.33.0/go.mod h1:KJRK/MXx0J+yd0c5hlR+s1tIHD72sniU8ZJjl97LIw4= github.com/valyala/fasthttp v1.35.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I= -github.com/valyala/fasthttp v1.50.0 h1:H7fweIlBm0rXLs2q0XbalvJ6r0CUPFWK3/bB4N13e9M= -github.com/valyala/fasthttp v1.50.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA= github.com/valyala/fasthttp v1.52.0 h1:wqBQpxH71XW0e2g+Og4dzQM8pk34aFYlA1Ga8db7gU0= github.com/valyala/fasthttp v1.52.0/go.mod h1:hf5C4QnVMkNXMspnsUlfM3WitlgYflyhHYoKol/szxQ= github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= From e14ebb82106f126bbbf4ab9a25879d64e8ab9636 Mon Sep 17 00:00:00 2001 From: Abdhesh Nayak Date: Mon, 8 Apr 2024 18:42:18 +0530 Subject: [PATCH 2/3] :construction: Wip --- apps/infra/internal/app/app.go | 2 + apps/infra/internal/domain/api.go | 1 + apps/infra/internal/domain/cluster-conn.go | 87 +++++++++++++++++++++- apps/infra/internal/domain/domain.go | 7 ++ 4 files changed, 94 insertions(+), 3 deletions(-) diff --git a/apps/infra/internal/app/app.go b/apps/infra/internal/app/app.go index 7504e5142..8172fd3ae 100644 --- a/apps/infra/internal/app/app.go +++ b/apps/infra/internal/app/app.go @@ -44,6 +44,8 @@ type ( var Module = fx.Module( "app", repos.NewFxMongoRepo[*entities.Cluster]("clusters", "clus", entities.ClusterIndices), + repos.NewFxMongoRepo[*entities.ClusterConnection]("cluster-connections", "clus-cn", entities.ClusterConnIndices), + repos.NewFxMongoRepo[*entities.ClusterGroup]("cluster-groups", "clus-grp", entities.ClusterGroupIndices), // repos.NewFxMongoRepo[*entities.BYOKCluster]("byok_clusters", "byok", entities.BYOKClusterIndices), repos.NewFxMongoRepo[*entities.BYOKCluster]("clusters", "byok", entities.BYOKClusterIndices), repos.NewFxMongoRepo[*entities.ClusterManagedService]("cmsvcs", "cmsvcs", entities.ClusterManagedServiceIndices), diff --git a/apps/infra/internal/domain/api.go b/apps/infra/internal/domain/api.go index dd14dbf45..92eaf621e 100644 --- a/apps/infra/internal/domain/api.go +++ b/apps/infra/internal/domain/api.go @@ -43,6 +43,7 @@ const ( ResourceTypeDomainEntries ResourceType = "domain_entries" ResourceTypeHelmRelease ResourceType = "helm_release" ResourceTypeNodePool ResourceType = "nodepool" + ResourceTypeClusterConnection ResourceType = "cluster_connection" ResourceTypePVC ResourceType = "persistance_volume_claim" ResourceTypePV ResourceType = "persistance_volume" ResourceTypeVolumeAttachment ResourceType = "volume_attachment" diff --git a/apps/infra/internal/domain/cluster-conn.go b/apps/infra/internal/domain/cluster-conn.go index 8d27e1c40..96c9dd5e8 100644 --- a/apps/infra/internal/domain/cluster-conn.go +++ b/apps/infra/internal/domain/cluster-conn.go @@ -2,15 +2,96 @@ package domain import ( "github.com/kloudlite/api/apps/infra/internal/entities" + "github.com/kloudlite/api/common" + "github.com/kloudlite/api/common/fields" + "github.com/kloudlite/api/pkg/errors" + "github.com/kloudlite/api/pkg/repos" "github.com/kloudlite/operator/operators/resource-watcher/types" ) +func (d *domain) findClusterConn(ctx InfraContext, clusterName string, connName string) (*entities.ClusterConnection, error) { + cc, err := d.clusterConnRepo.FindOne(ctx, repos.Filter{ + fields.AccountName: ctx.AccountName, + fields.ClusterName: clusterName, + fields.MetadataName: connName, + }) + if err != nil { + return nil, errors.NewE(err) + } + if cc == nil { + return nil, errors.Newf("cluster connection with name %q not found", clusterName) + } + return cc, nil +} + func (d *domain) OnClusterConnDeleteMessage(ctx InfraContext, clusterName string, clusterConn entities.ClusterConnection) error { - panic("implement me") + err := d.clusterConnRepo.DeleteOne( + ctx, + repos.Filter{ + fields.AccountName: ctx.AccountName, + fields.ClusterName: clusterName, + fields.MetadataName: clusterConn.Name, + }, + ) + if err != nil { + return errors.NewE(err) + } + d.resourceEventPublisher.PublishResourceEvent(ctx, clusterName, ResourceTypeClusterConnection, clusterConn.Name, PublishDelete) + return err } + func (d *domain) OnClusterConnUpdateMessage(ctx InfraContext, clusterName string, clusterConn entities.ClusterConnection, status types.ResourceStatus, opts UpdateAndDeleteOpts) error { - panic("implement me") + xnp, err := d.findClusterConn(ctx, clusterName, clusterConn.Name) + if err != nil { + return errors.NewE(err) + } + + if xnp == nil { + return errors.Newf("no cluster connection found") + } + + if _, err := d.matchRecordVersion(clusterConn.Annotations, xnp.RecordVersion); err != nil { + return d.resyncToTargetCluster(ctx, xnp.SyncStatus.Action, clusterName, &xnp.ClusterConnection, xnp.RecordVersion) + } + + recordVersion, err := d.matchRecordVersion(clusterConn.Annotations, xnp.RecordVersion) + if err != nil { + return errors.NewE(err) + } + + unp, err := d.clusterConnRepo.PatchById( + ctx, + xnp.Id, + common.PatchForSyncFromAgent(&clusterConn, + recordVersion, status, + common.PatchOpts{ + MessageTimestamp: opts.MessageTimestamp, + })) + if err != nil { + return errors.NewE(err) + } + + d.resourceEventPublisher.PublishResourceEvent(ctx, clusterName, ResourceTypeClusterConnection, unp.GetName(), PublishUpdate) + return nil } func (d *domain) OnClusterConnApplyError(ctx InfraContext, clusterName string, name string, errMsg string, opts UpdateAndDeleteOpts) error { - panic("implement me") + unp, err := d.clusterConnRepo.Patch( + ctx, + repos.Filter{ + fields.AccountName: ctx.AccountName, + fields.ClusterName: clusterName, + fields.MetadataName: name, + }, + common.PatchForErrorFromAgent( + errMsg, + common.PatchOpts{ + MessageTimestamp: opts.MessageTimestamp, + }, + ), + ) + if err != nil { + return errors.NewE(err) + } + d.resourceEventPublisher.PublishResourceEvent(ctx, clusterName, ResourceTypeClusterConnection, unp.Name, PublishUpdate) + return errors.NewE(err) } diff --git a/apps/infra/internal/domain/domain.go b/apps/infra/internal/domain/domain.go index 72216ffc0..5acf2aace 100644 --- a/apps/infra/internal/domain/domain.go +++ b/apps/infra/internal/domain/domain.go @@ -37,6 +37,8 @@ type domain struct { helmReleaseRepo repos.DbRepo[*entities.HelmRelease] nodeRepo repos.DbRepo[*entities.Node] nodePoolRepo repos.DbRepo[*entities.NodePool] + clusterConnRepo repos.DbRepo[*entities.ClusterConnection] + clusterGroupRepo repos.DbRepo[*entities.ClusterGroup] domainEntryRepo repos.DbRepo[*entities.DomainEntry] secretRepo repos.DbRepo[*entities.CloudProviderSecret] pvcRepo repos.DbRepo[*entities.PersistentVolumeClaim] @@ -160,6 +162,9 @@ var Module = fx.Module("domain", resourceDispatcher ResourceDispatcher, helmReleaseRepo repos.DbRepo[*entities.HelmRelease], + clusterConnRepo repos.DbRepo[*entities.ClusterConnection], + clusterGroupRepo repos.DbRepo[*entities.ClusterGroup], + pvcRepo repos.DbRepo[*entities.PersistentVolumeClaim], pvRepo repos.DbRepo[*entities.PersistentVolume], namespaceRepo repos.DbRepo[*entities.Namespace], @@ -206,6 +211,8 @@ var Module = fx.Module("domain", logger: logger, env: env, clusterRepo: clusterRepo, + clusterConnRepo: clusterConnRepo, + clusterGroupRepo: clusterGroupRepo, byokClusterRepo: byokClusterRepo, clusterManagedServiceRepo: clustermanagedserviceRepo, nodeRepo: nodeRepo, From 7305abd71c4d49717069340a4c10d13093c34efd Mon Sep 17 00:00:00 2001 From: Abdhesh Nayak Date: Tue, 9 Apr 2024 13:28:22 +0530 Subject: [PATCH 3/3] :sparkles: Implemented cluster-connection watch and update --- apps/infra/internal/domain/cluster-conn.go | 94 +++++++++++++++++-- apps/infra/internal/domain/cluster-group.go | 1 + apps/infra/internal/domain/clusters.go | 2 + .../internal/entities/cluster-connection.go | 8 +- apps/infra/internal/entities/cluster-group.go | 13 +-- apps/infra/internal/entities/cluster.go | 5 +- .../field-constants/generated_constants.go | 35 +++++++ 7 files changed, 139 insertions(+), 19 deletions(-) create mode 100644 apps/infra/internal/domain/cluster-group.go diff --git a/apps/infra/internal/domain/cluster-conn.go b/apps/infra/internal/domain/cluster-conn.go index 96c9dd5e8..52fcbf470 100644 --- a/apps/infra/internal/domain/cluster-conn.go +++ b/apps/infra/internal/domain/cluster-conn.go @@ -1,14 +1,74 @@ package domain import ( + "fmt" + "github.com/kloudlite/api/apps/infra/internal/entities" + fc "github.com/kloudlite/api/apps/infra/internal/entities/field-constants" "github.com/kloudlite/api/common" "github.com/kloudlite/api/common/fields" "github.com/kloudlite/api/pkg/errors" "github.com/kloudlite/api/pkg/repos" + wgv1 "github.com/kloudlite/operator/apis/wireguard/v1" "github.com/kloudlite/operator/operators/resource-watcher/types" ) +func (d *domain) reconClusterConns(ctx InfraContext, clusterGroup string) error { + conns, err := d.clusterConnRepo.Find(ctx, repos.Query{ + Filter: repos.Filter{fields.AccountName: ctx.AccountName, fc.ClusterClusterGroupName: clusterGroup}, + }) + + if err != nil { + return errors.NewE(err) + } + + peers := make([]wgv1.Peer, 0) + + for _, c := range conns { + if c.Spec.PublicKey == nil { + continue + } + + peers = append(peers, wgv1.Peer{ + PublicKey: *c.Spec.PublicKey, + Endpoint: c.Endpoint, + Id: c.Spec.Id, + AllowedIPs: []string{c.CIDR}, + }) + } + + for _, xcc := range conns { + if fmt.Sprintf("%#v", xcc.Spec.Peers) == fmt.Sprintf("%#v", peers) { + continue + } + + xcc.Spec.Peers = peers + unp, err := d.clusterConnRepo.Patch( + ctx, + repos.Filter{ + fields.AccountName: ctx.AccountName, + fields.ClusterName: xcc.ClusterName, + fields.MetadataName: xcc.Name, + }, + common.PatchForUpdate(ctx, xcc, common.PatchOpts{XPatch: map[string]any{fc.ClusterConnectionSpecPeers: peers}}), + ) + + if err != nil { + return errors.NewE(err) + } + + if err := d.resDispatcher.ApplyToTargetCluster(ctx, + unp.ClusterName, + &unp.ClusterConnection, + unp.RecordVersion, + ); err != nil { + return errors.NewE(err) + } + } + + return nil +} + func (d *domain) findClusterConn(ctx InfraContext, clusterName string, connName string) (*entities.ClusterConnection, error) { cc, err := d.clusterConnRepo.FindOne(ctx, repos.Filter{ fields.AccountName: ctx.AccountName, @@ -24,6 +84,20 @@ func (d *domain) findClusterConn(ctx InfraContext, clusterName string, connName return cc, nil } +func (d *domain) findClusterConns(ctx InfraContext, clusterGroup string) ([]*entities.ClusterConnection, error) { + cc, err := d.clusterConnRepo.Find(ctx, repos.Query{ + Filter: repos.Filter{ + fields.AccountName: ctx.AccountName, + fc.ClusterClusterGroupName: clusterGroup, + }, + }) + if err != nil { + return nil, errors.NewE(err) + } + + return cc, nil +} + func (d *domain) OnClusterConnDeleteMessage(ctx InfraContext, clusterName string, clusterConn entities.ClusterConnection) error { err := d.clusterConnRepo.DeleteOne( ctx, @@ -36,32 +110,33 @@ func (d *domain) OnClusterConnDeleteMessage(ctx InfraContext, clusterName string if err != nil { return errors.NewE(err) } + d.resourceEventPublisher.PublishResourceEvent(ctx, clusterName, ResourceTypeClusterConnection, clusterConn.Name, PublishDelete) return err } func (d *domain) OnClusterConnUpdateMessage(ctx InfraContext, clusterName string, clusterConn entities.ClusterConnection, status types.ResourceStatus, opts UpdateAndDeleteOpts) error { - xnp, err := d.findClusterConn(ctx, clusterName, clusterConn.Name) + xconn, err := d.findClusterConn(ctx, clusterName, clusterConn.Name) if err != nil { return errors.NewE(err) } - if xnp == nil { + if xconn == nil { return errors.Newf("no cluster connection found") } - if _, err := d.matchRecordVersion(clusterConn.Annotations, xnp.RecordVersion); err != nil { - return d.resyncToTargetCluster(ctx, xnp.SyncStatus.Action, clusterName, &xnp.ClusterConnection, xnp.RecordVersion) + if _, err := d.matchRecordVersion(clusterConn.Annotations, xconn.RecordVersion); err != nil { + return d.resyncToTargetCluster(ctx, xconn.SyncStatus.Action, clusterName, &xconn.ClusterConnection, xconn.RecordVersion) } - recordVersion, err := d.matchRecordVersion(clusterConn.Annotations, xnp.RecordVersion) + recordVersion, err := d.matchRecordVersion(clusterConn.Annotations, xconn.RecordVersion) if err != nil { return errors.NewE(err) } unp, err := d.clusterConnRepo.PatchById( ctx, - xnp.Id, + xconn.Id, common.PatchForSyncFromAgent(&clusterConn, recordVersion, status, common.PatchOpts{ @@ -71,9 +146,14 @@ func (d *domain) OnClusterConnUpdateMessage(ctx InfraContext, clusterName string return errors.NewE(err) } - d.resourceEventPublisher.PublishResourceEvent(ctx, clusterName, ResourceTypeClusterConnection, unp.GetName(), PublishUpdate) + if err := d.reconClusterConns(ctx, xconn.ClusterGroupName); err != nil { + return errors.NewE(err) + } + + d.resourceEventPublisher.PublishResourceEvent(ctx, clusterName, ResourceTypeClusterConnection, unp.Name, PublishUpdate) return nil } + func (d *domain) OnClusterConnApplyError(ctx InfraContext, clusterName string, name string, errMsg string, opts UpdateAndDeleteOpts) error { unp, err := d.clusterConnRepo.Patch( ctx, diff --git a/apps/infra/internal/domain/cluster-group.go b/apps/infra/internal/domain/cluster-group.go new file mode 100644 index 000000000..4188b5afd --- /dev/null +++ b/apps/infra/internal/domain/cluster-group.go @@ -0,0 +1 @@ +package domain diff --git a/apps/infra/internal/domain/clusters.go b/apps/infra/internal/domain/clusters.go index 2328f87af..b46286371 100644 --- a/apps/infra/internal/domain/clusters.go +++ b/apps/infra/internal/domain/clusters.go @@ -98,6 +98,8 @@ func (d *domain) GetClusterAdminKubeconfig(ctx InfraContext, clusterName string) func (d *domain) applyCluster(ctx InfraContext, cluster *entities.Cluster) error { addTrackingId(&cluster.Cluster, cluster.Id) return d.applyK8sResource(ctx, &cluster.Cluster, cluster.RecordVersion) + + // TODO: create cluster connection and apply to target cluster } func (d *domain) CreateCluster(ctx InfraContext, cluster entities.Cluster) (*entities.Cluster, error) { diff --git a/apps/infra/internal/entities/cluster-connection.go b/apps/infra/internal/entities/cluster-connection.go index ced0bf254..e58d6e890 100644 --- a/apps/infra/internal/entities/cluster-connection.go +++ b/apps/infra/internal/entities/cluster-connection.go @@ -15,8 +15,12 @@ type ClusterConnection struct { common.ResourceMetadata `json:",inline"` - AccountName string `json:"accountName" graphql:"noinput"` - ClusterName string `json:"clusterName" graphql:"noinput"` + AccountName string `json:"accountName" graphql:"noinput"` + ClusterName string `json:"clusterName" graphql:"noinput"` + ClusterGroupName string `json:"clusterGroupName" graphql:"noinput"` + + CIDR string `json:"cidr" graphql:"noinput"` + Endpoint string `json:"endpoint" graphql:"noinput"` SyncStatus t.SyncStatus `json:"syncStatus" graphql:"noinput"` } diff --git a/apps/infra/internal/entities/cluster-group.go b/apps/infra/internal/entities/cluster-group.go index 2204ed207..0d154cbc5 100644 --- a/apps/infra/internal/entities/cluster-group.go +++ b/apps/infra/internal/entities/cluster-group.go @@ -28,13 +28,10 @@ func GetCidrRanges(index int) (*string, error) { return functions.New(fmt.Sprintf("10.%d.0.0/16", index)), nil } -type Peers struct { - Name string `json:"name" graphql:"noinput"` - Namespace string `json:"namespace" graphql:"noinput"` - - Id int `json:"id" graphql:"noinput"` - PubKey string `json:"pubKey" graphql:"noinput"` - AllowedIps string `json:"allowedIps" graphql:"noinput"` +type Peer struct { + Id int `json:"id" graphql:"noinput"` + PubKey string `json:"pubKey" graphql:"noinput"` + AllowedIps []string `json:"allowedIps" graphql:"noinput"` } type ClusterGroup struct { @@ -42,7 +39,7 @@ type ClusterGroup struct { common.ResourceMetadata `json:",inline"` - Peers []Peers `json:"peers" graphql:"noinput"` + // Peers []Peer `json:"peers" graphql:"noinput"` AccountName string `json:"accountName" graphql:"noinput"` ClusterName string `json:"clusterName" graphql:"noinput"` diff --git a/apps/infra/internal/entities/cluster.go b/apps/infra/internal/entities/cluster.go index 87f61ed88..0781f2acd 100644 --- a/apps/infra/internal/entities/cluster.go +++ b/apps/infra/internal/entities/cluster.go @@ -15,8 +15,9 @@ type Cluster struct { common.ResourceMetadata `json:",inline"` - AccountName string `json:"accountName" graphql:"noinput"` - SyncStatus t.SyncStatus `json:"syncStatus" graphql:"noinput"` + ClusterGroupName *string `json:"clusterGroupName"` + AccountName string `json:"accountName" graphql:"noinput"` + SyncStatus t.SyncStatus `json:"syncStatus" graphql:"noinput"` } func (c *Cluster) GetDisplayName() string { diff --git a/apps/infra/internal/entities/field-constants/generated_constants.go b/apps/infra/internal/entities/field-constants/generated_constants.go index 3e498024d..a8180b85f 100644 --- a/apps/infra/internal/entities/field-constants/generated_constants.go +++ b/apps/infra/internal/entities/field-constants/generated_constants.go @@ -101,6 +101,7 @@ const ( // constant vars generated for struct Cluster const ( + ClusterClusterGroupName = "clusterGroupName" ClusterSpec = "spec" ClusterSpecAccountId = "spec.accountId" ClusterSpecAccountName = "spec.accountName" @@ -147,6 +148,32 @@ const ( ClusterSpecTaintMasterNodes = "spec.taintMasterNodes" ) +// constant vars generated for struct ClusterConnection +const ( + ClusterConnectionClusterGroupName = "clusterGroupName" + ClusterConnectionSpec = "spec" + ClusterConnectionSpecAgentsResources = "spec.agentsResources" + ClusterConnectionSpecAgentsResourcesClaims = "spec.agentsResources.claims" + ClusterConnectionSpecAgentsResourcesLimits = "spec.agentsResources.limits" + ClusterConnectionSpecAgentsResourcesRequests = "spec.agentsResources.requests" + ClusterConnectionSpecDnsServer = "spec.dnsServer" + ClusterConnectionSpecGatewayResources = "spec.gatewayResources" + ClusterConnectionSpecGatewayResourcesClaims = "spec.gatewayResources.claims" + ClusterConnectionSpecGatewayResourcesLimits = "spec.gatewayResources.limits" + ClusterConnectionSpecGatewayResourcesRequests = "spec.gatewayResources.requests" + ClusterConnectionSpecId = "spec.id" + ClusterConnectionSpecInterface = "spec.interface" + ClusterConnectionSpecIpAddress = "spec.ipAddress" + ClusterConnectionSpecNodeport = "spec.nodeport" + ClusterConnectionSpecPeers = "spec.peers" + ClusterConnectionSpecPublicKey = "spec.publicKey" +) + +// constant vars generated for struct ClusterGroup +const ( + ClusterGroupPeers = "peers" +) + // constant vars generated for struct ClusterManagedService const ( ClusterManagedServiceOutput = "output" @@ -323,6 +350,14 @@ const ( OutputFieldName = "name" ) +// constant vars generated for struct Peers +const ( + PeersAllowedIps = "allowedIps" + PeersName = "name" + PeersNamespace = "namespace" + PeersPubKey = "pubKey" +) + // constant vars generated for struct PersistentVolume const ( PersistentVolumeSpec = "spec"