diff --git a/.gitignore b/.gitignore index b7233b3..a228c8c 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # +log +cache +.vscode .DS_Store output dist diff --git a/conf/api_server.toml b/conf/api_server.toml index 98965f9..f4f8334 100644 --- a/conf/api_server.toml +++ b/conf/api_server.toml @@ -49,6 +49,17 @@ MaxIdleConns = 100 ConnMaxIdleTimeMs = 500000 ConnMaxLifetimeMs = 5000000 +# --------------------------------- +# NacosRegsiter Config +# see https://github.com/nacos-group/nacos-sdk-go/blob/master/README.md +# see https://github.com/nacos-group/nacos-sdk-go/blob/master/README_CN.md +#[NacosRegsiter] +# [NacosRegsiter.ClientConfig] +# NamespaceId = "{NamespaceId}" + +# [[NacosRegsiter.ServerConfig]] +# IpAddr = "127.0.0.1" +# Port = 8848 # --------------------------------- # Dependence Config diff --git a/docs/zh_cn/config_param.md b/docs/zh_cn/config_param.md index 4f9b88c..e7419e3 100644 --- a/docs/zh_cn/config_param.md +++ b/docs/zh_cn/config_param.md @@ -62,6 +62,18 @@ MaxIdleConns = 100 ConnMaxIdleTimeMs = 50000 ConnMaxLifetimeMs = 50000 +# --------------------------------- +# NacosRegsiter Config +# see https://github.com/nacos-group/nacos-sdk-go/blob/master/README.md +# see https://github.com/nacos-group/nacos-sdk-go/blob/master/README_CN.md +[NacosRegsiter] +[NacosRegsiter.ClientConfig] +NamespaceId = "test-dev" + +[[NacosRegsiter.ServerConfig]] +IpAddr = "127.0.0.1" +Port = 8848 + # --------------------------------- # Dependence Config diff --git a/endpoints/openapi_v1/bfe_pool/create.go b/endpoints/openapi_v1/bfe_pool/create.go index b793ed8..102b336 100644 --- a/endpoints/openapi_v1/bfe_pool/create.go +++ b/endpoints/openapi_v1/bfe_pool/create.go @@ -41,7 +41,7 @@ var _ xreq.Handler = CreateAction // CreateAction action // AUTO GEN BY ctrl, MODIFY AS U NEED func CreateAction(req *http.Request) (interface{}, error) { - param, err := product_pool.NewUpsertParam(req) + param, err := product_pool.NewCreateParam(req) if err != nil { return nil, err } @@ -54,12 +54,19 @@ func CreateAction(req *http.Request) (interface{}, error) { } oneData, err := container.PoolManager.CreateBFEPool(req.Context(), &icluster_conf.PoolParam{ - Name: param.Name, + Name: param.Name, + Type: param.Type, + }, &icluster_conf.InstancePool{ Instances: product_pool.Instancesc2i(param.Instances), }) if err != nil { return nil, err } - return product_pool.NewOneData(oneData), nil + manager, err := container.InstancePoolManager.BatchFetchInstances(req.Context(), []*icluster_conf.Pool{oneData}) + if err != nil { + return nil, err + } + + return product_pool.NewOneData(oneData, manager[oneData.Name]), nil } diff --git a/endpoints/openapi_v1/bfe_pool/delete.go b/endpoints/openapi_v1/bfe_pool/delete.go index 2308147..e079261 100644 --- a/endpoints/openapi_v1/bfe_pool/delete.go +++ b/endpoints/openapi_v1/bfe_pool/delete.go @@ -20,6 +20,7 @@ import ( "github.com/bfenetworks/api-server/endpoints/openapi_v1/product_pool" "github.com/bfenetworks/api-server/lib/xreq" "github.com/bfenetworks/api-server/model/iauth" + "github.com/bfenetworks/api-server/model/icluster_conf" "github.com/bfenetworks/api-server/stateful/container" ) @@ -46,5 +47,10 @@ func DeleteAction(req *http.Request) (interface{}, error) { return nil, err } - return product_pool.NewOneData(oldOne), nil + manager, err := container.InstancePoolManager.BatchFetchInstances(req.Context(), []*icluster_conf.Pool{oldOne}) + if err != nil { + return nil, err + } + + return product_pool.NewOneData(oldOne, manager[oldOne.Name]), nil } diff --git a/endpoints/openapi_v1/bfe_pool/one.go b/endpoints/openapi_v1/bfe_pool/one.go index 23107d8..ae05b0e 100644 --- a/endpoints/openapi_v1/bfe_pool/one.go +++ b/endpoints/openapi_v1/bfe_pool/one.go @@ -21,6 +21,7 @@ import ( "github.com/bfenetworks/api-server/lib/xerror" "github.com/bfenetworks/api-server/lib/xreq" "github.com/bfenetworks/api-server/model/iauth" + "github.com/bfenetworks/api-server/model/icluster_conf" "github.com/bfenetworks/api-server/stateful/container" ) @@ -51,6 +52,10 @@ func OneAction(req *http.Request) (interface{}, error) { return nil, xerror.WrapRecordNotExist("Instance Pool") } - return product_pool.NewOneData(one), nil + manager, err := container.InstancePoolManager.BatchFetchInstances(req.Context(), []*icluster_conf.Pool{one}) + if err != nil { + return nil, err + } + return product_pool.NewOneData(one, manager[one.Name]), nil } diff --git a/endpoints/openapi_v1/bfe_pool/update.go b/endpoints/openapi_v1/bfe_pool/update.go index 8f2b156..0c72c7a 100644 --- a/endpoints/openapi_v1/bfe_pool/update.go +++ b/endpoints/openapi_v1/bfe_pool/update.go @@ -39,7 +39,7 @@ var _ xreq.Handler = UpdateAction // UpdateAction action // AUTO GEN BY ctrl, MODIFY AS U NEED func UpdateAction(req *http.Request) (interface{}, error) { - param, err := product_pool.NewUpsertParam(req) + param, err := product_pool.NewUpdateParam(req) if err != nil { return nil, err } @@ -52,11 +52,14 @@ func UpdateAction(req *http.Request) (interface{}, error) { return nil, xerror.WrapRecordNotExist("Instance Pool") } - err = container.PoolManager.UpdateBFEPool(req.Context(), one, &icluster_conf.PoolParam{ + p := &icluster_conf.InstancePool{ + Name: one.Name, Instances: product_pool.Instancesc2i(param.Instances), - }) - - one.Instances = product_pool.Instancesc2i(param.Instances) + } + err = container.InstancePoolManager.UpdateInstances(req.Context(), one, p) + if err != nil { + return nil, err + } - return product_pool.NewOneData(one), err + return product_pool.NewOneData(one, p), err } diff --git a/endpoints/openapi_v1/product_pool/create.go b/endpoints/openapi_v1/product_pool/create.go index d33f994..3ef372a 100644 --- a/endpoints/openapi_v1/product_pool/create.go +++ b/endpoints/openapi_v1/product_pool/create.go @@ -18,6 +18,7 @@ import ( "net/http" "strings" + "github.com/bfenetworks/api-server/lib" "github.com/bfenetworks/api-server/lib/xerror" "github.com/bfenetworks/api-server/lib/xreq" "github.com/bfenetworks/api-server/model/iauth" @@ -26,13 +27,6 @@ import ( "github.com/bfenetworks/api-server/stateful/container" ) -// UpsertParam Request Param -// AUTO GEN BY ctrl, MODIFY AS U NEED -type UpsertParam struct { - Name *string `json:"name" uri:"instance_pool_name" validate:"required,min=2"` - Instances []*Instance `json:"instances" uri:"instances" validate:"min=1,dive"` -} - // CreateRoute route // AUTO GEN BY ctrl, MODIFY AS U NEED var CreateEndpoint = &xreq.Endpoint{ @@ -42,9 +36,19 @@ var CreateEndpoint = &xreq.Endpoint{ Authorizer: iauth.FAP(iauth.FeatureProductPool, iauth.ActionCreate), } +// CreateParam Request Param +// AUTO GEN BY ctrl, MODIFY AS U NEED +type CreateParam struct { + Name *string `json:"name" validate:"required,min=2"` + Type *int8 `json:"type" validate:"oneof=1"` + Instances []*Instance `json:"instances" validate:"min=1,dive"` +} + // AUTO GEN BY ctrl, MODIFY AS U NEED -func NewUpsertParam(req *http.Request) (*UpsertParam, error) { - param := &UpsertParam{} +func NewCreateParam(req *http.Request) (*CreateParam, error) { + param := &CreateParam{ + Type: lib.PInt8(icluster_conf.InstancePoolTypeRDB), + } err := xreq.Bind(req, param) if err != nil { return nil, err @@ -58,7 +62,7 @@ var _ xreq.Handler = CreateAction // CreateAction action // AUTO GEN BY ctrl, MODIFY AS U NEED func CreateAction(req *http.Request) (interface{}, error) { - param, err := NewUpsertParam(req) + param, err := NewCreateParam(req) if err != nil { return nil, err } @@ -80,7 +84,12 @@ func CreateAction(req *http.Request) (interface{}, error) { return nil, err } - return NewOneData(oneData), nil + manager, err := container.InstancePoolManager.BatchFetchInstances(req.Context(), []*icluster_conf.Pool{oneData}) + if err != nil { + return nil, err + } + + return NewOneData(oneData, manager[oneData.Name]), nil } func Instancesc2i(is []*Instance) []icluster_conf.Instance { @@ -103,9 +112,11 @@ func Instancesc2i(is []*Instance) []icluster_conf.Instance { return rst } -func CreateProcess(req *http.Request, product *ibasic.Product, param *UpsertParam) (*icluster_conf.Pool, error) { +func CreateProcess(req *http.Request, product *ibasic.Product, param *CreateParam) (*icluster_conf.Pool, error) { return container.PoolManager.CreateProductPool(req.Context(), product, &icluster_conf.PoolParam{ - Name: param.Name, + Name: param.Name, + Type: param.Type, + }, &icluster_conf.InstancePool{ Instances: Instancesc2i(param.Instances), }) } diff --git a/endpoints/openapi_v1/product_pool/delete.go b/endpoints/openapi_v1/product_pool/delete.go index 6396eb6..7e413a5 100644 --- a/endpoints/openapi_v1/product_pool/delete.go +++ b/endpoints/openapi_v1/product_pool/delete.go @@ -20,6 +20,7 @@ import ( "github.com/bfenetworks/api-server/lib/xreq" "github.com/bfenetworks/api-server/model/iauth" "github.com/bfenetworks/api-server/model/ibasic" + "github.com/bfenetworks/api-server/model/icluster_conf" "github.com/bfenetworks/api-server/stateful/container" ) @@ -52,5 +53,10 @@ func DeleteAction(req *http.Request) (interface{}, error) { return nil, err } - return NewOneData(oldOne), nil + manager, err := container.InstancePoolManager.BatchFetchInstances(req.Context(), []*icluster_conf.Pool{oldOne}) + if err != nil { + return nil, err + } + + return NewOneData(oldOne, manager[oldOne.Name]), nil } diff --git a/endpoints/openapi_v1/product_pool/one.go b/endpoints/openapi_v1/product_pool/one.go index bff725b..206e505 100644 --- a/endpoints/openapi_v1/product_pool/one.go +++ b/endpoints/openapi_v1/product_pool/one.go @@ -48,16 +48,18 @@ type OneData struct { Instances []*Instance `json:"instances" uri:"instances"` } -func NewOneData(pool *icluster_conf.Pool) *OneData { +func NewOneData(pool *icluster_conf.Pool, pis *icluster_conf.InstancePool) *OneData { is := []*Instance{} - for _, one := range pool.Instances { - is = append(is, &Instance{ - Hostname: one.HostName, - IP: one.IP, - Weight: one.Weight, - Ports: one.Ports, - Tags: one.Tags, - }) + if pis != nil { + for _, one := range pis.Instances { + is = append(is, &Instance{ + Hostname: one.HostName, + IP: one.IP, + Weight: one.Weight, + Ports: one.Ports, + Tags: one.Tags, + }) + } } return &OneData{ @@ -105,5 +107,9 @@ func OneAction(req *http.Request) (interface{}, error) { return nil, xerror.WrapRecordNotExist("Instance Pool") } - return NewOneData(one), nil + manager, err := container.InstancePoolManager.BatchFetchInstances(req.Context(), []*icluster_conf.Pool{one}) + if err != nil { + return nil, err + } + return NewOneData(one, manager[one.Name]), nil } diff --git a/endpoints/openapi_v1/product_pool/update.go b/endpoints/openapi_v1/product_pool/update.go index 1030122..47766c9 100644 --- a/endpoints/openapi_v1/product_pool/update.go +++ b/endpoints/openapi_v1/product_pool/update.go @@ -25,6 +25,24 @@ import ( "github.com/bfenetworks/api-server/stateful/container" ) +// UpdateParam Request Param +// AUTO GEN BY ctrl, MODIFY AS U NEED +type UpdateParam struct { + Name *string `uri:"instance_pool_name" validate:"required,min=2"` + Instances []*Instance `json:"instances" validate:"min=1,dive"` +} + +// AUTO GEN BY ctrl, MODIFY AS U NEED +func NewUpdateParam(req *http.Request) (*UpdateParam, error) { + param := &UpdateParam{} + err := xreq.Bind(req, param) + if err != nil { + return nil, err + } + + return param, err +} + // UpdateRoute route // AUTO GEN BY ctrl, MODIFY AS U NEED var UpdateEndpoint = &xreq.Endpoint{ @@ -39,7 +57,7 @@ var _ xreq.Handler = UpdateAction // UpdateAction action // AUTO GEN BY ctrl, MODIFY AS U NEED func UpdateAction(req *http.Request) (interface{}, error) { - param, err := NewUpsertParam(req) + param, err := NewCreateParam(req) if err != nil { return nil, err } @@ -56,11 +74,14 @@ func UpdateAction(req *http.Request) (interface{}, error) { return nil, xerror.WrapRecordNotExist("Instance Pool") } - err = container.PoolManager.UpdateProductPool(req.Context(), product, one, &icluster_conf.PoolParam{ + pi := &icluster_conf.InstancePool{ + Name: one.Name, Instances: Instancesc2i(param.Instances), - }) - - one.Instances = Instancesc2i(param.Instances) + } + err = container.InstancePoolManager.UpdateInstances(req.Context(), one, pi) + if err != nil { + return nil, err + } - return NewOneData(one), err + return NewOneData(one, pi), nil } diff --git a/go.mod b/go.mod index e10991e..41e3fe0 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,7 @@ require ( github.com/go-playground/validator/v10 v10.9.0 github.com/go-sql-driver/mysql v1.6.0 github.com/gorilla/mux v1.8.0 + github.com/nacos-group/nacos-sdk-go v1.0.9 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.11.0 github.com/rs/cors v1.8.0 diff --git a/go.sum b/go.sum index eed9338..3da2808 100644 --- a/go.sum +++ b/go.sum @@ -12,6 +12,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/aliyun/alibaba-cloud-sdk-go v1.61.18 h1:zOVTBdCKFd9JbCKz9/nt+FovbjPFmb7mUnp8nH9fQBA= +github.com/aliyun/alibaba-cloud-sdk-go v1.61.18/go.mod h1:v8ESoHo4SyHmuB4b1tJqDHxfTGEciD+yhvOU/5s1Rfk= github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= @@ -27,6 +29,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bfenetworks/bfe v1.3.0 h1:7szMiiINJv2mXWNIBTJzn5sKQwKxR5ggeBq9QmKxzAg= github.com/bfenetworks/bfe v1.3.0/go.mod h1:Zn1EtyNZRo2e+q3EGgPSCDN/J0O4EwVDEYP7uvhVHFk= +github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23 h1:D21IyuvjDCshj1/qq+pCNd3VZOAEI9jy6Bi131YlXgI= +github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chris-ramon/douceur v0.2.0/go.mod h1:wDW5xjJdeoMm1mRt4sD4c/LbF/mWdEpRXQKjTR8nIBE= @@ -47,9 +51,13 @@ github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFP github.com/elastic/go-sysinfo v1.1.1/go.mod h1:i1ZYdU10oLNfRzq4vq62BEwD2fH8KaWh6eh0ikPT9F0= github.com/elastic/go-windows v1.0.0/go.mod h1:TsU0Nrp7/y3+VwE82FoZF8gC/XFg/Elz6CcloAxnPgU= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= +github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 h1:Ghm4eQYC0nEPnSJdVkTrXpu9KtoVCSo1hg7mtI7G9KU= +github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239/go.mod h1:Gdwt2ce0yfBxPvZrHkprdPPTTS3N5rwmLE8T22KBXlw= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do= +github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= @@ -72,9 +80,12 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -96,6 +107,9 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= @@ -106,27 +120,43 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 h1:IPJ3dvxmJ4uczJe5YQdrYB16oTJlGSC/OyZDqUk9xX4= github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869/go.mod h1:cJ6Cj7dQo+O6GJNiMx+Pa94qKj+TG8ONdKHgMNIyyag= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak= +github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= +github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570 h1:0iQektZGS248WXmGIYOwRXSQhD4qn3icjMpuxwO7qlo= +github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570/go.mod h1:BLt8L9ld7wVsvEWQbuLrUZnCMnUmLZ+CGDzKtclrTlE= +github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f h1:sgUSP4zdTUZYZgAGGtN5Lxk92rK+JUFOwf+FT99EEI4= +github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f/go.mod h1:UGmTpUd3rjbtfIpwAPrcfmGf/Z1HS95TATB+m57TPB8= +github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042 h1:Bvq8AziQ5jFF4BHGAEDSqwPW1NJS3XshxbRCxtjFAZc= +github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042/go.mod h1:TPpsiPUEh0zFL1Snz4crhMlBe60PYxRHr5oFF3rRYg0= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= @@ -141,6 +171,8 @@ github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nacos-group/nacos-sdk-go v1.0.9 h1:sMvrp6tZj4LdhuHRsS4GCqASB81k3pjmT2ykDQQpwt0= +github.com/nacos-group/nacos-sdk-go v1.0.9/go.mod h1:hlAPn3UdzlxIlSILAyOXKxjFSvDJ9oLzTJ9hLAK1KzA= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -181,7 +213,9 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rs/cors v1.8.0 h1:P2KMzcFwrPoSjkF1WLRPsp3UMLyql8L4v9hQpVeK5so= github.com/rs/cors v1.8.0/go.mod h1:EBwu+T5AvHOcXwvZIkQFjUN6s8Czyqw12GL/Y0tUyRM= @@ -191,6 +225,10 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs= +github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= @@ -199,11 +237,16 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/tebeka/strftime v0.1.3 h1:5HQXOqWKYRFfNyBMNVc9z5+QzuBtIXy03psIhtdJYto= +github.com/tebeka/strftime v0.1.3/go.mod h1:7wJm3dZlpr4l/oVK0t1HYIc4rMzQ2XJlOMIUJUJH6XQ= github.com/tjfoc/gmsm v1.3.2 h1:7JVkAn5bvUJ7HtU08iW6UiD+UTmJTIToHCfeFzkcCxM= github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w= +github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3 h1:kF/7m/ZU+0D4Jj5eZ41Zm3IH/J8OElK1Qtd7tVKAwLk= +github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3/go.mod h1:QDlpd3qS71vYtakd2hmdpqhJ9nwv6mD6A30bQ1BPBFE= github.com/uber/jaeger-client-go v2.22.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= @@ -218,19 +261,30 @@ go.elastic.co/apm/module/apmhttp v1.7.2/go.mod h1:sTFWiWejnhSdZv6+dMgxGec2Nxe/ZK go.elastic.co/apm/module/apmot v1.7.2/go.mod h1:VD2nUkebUPrP1hqIarimIEsoM9xyuK0lO83fCx6l/Z8= go.elastic.co/fastjson v1.0.0/go.mod h1:PmeUOMMtLHQr9ZS9J9owrAVg0FkaZDRZJEFTTGHtchs= go.elastic.co/fastjson v1.1.0/go.mod h1:boNGISWMjQsUPy/t6yqt2/1Wx4YNPSe+mZjlyw9vKKI= +go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/automaxprocs v1.4.0/go.mod h1:/mTEdr7LvHhs0v7mjdxDreTz1OG5zdZGqgOnhWiR/+Q= +go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM= +go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -288,11 +342,16 @@ golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200509030707-2212a7e161a5/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -316,6 +375,7 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -323,6 +383,8 @@ gopkg.in/gcfg.v1 v1.2.3 h1:m8OOJ4ccYHnx2f4gQwpno8nAX5OGOh7RLaaz0pj3Ogs= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= +gopkg.in/ini.v1 v1.42.0 h1:7N3gPTt50s8GuLortA00n8AqRTk75qOP98+mTPpgzRk= +gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/square/go-jose.v2 v2.4.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/tylerb/graceful.v1 v1.2.15 h1:1JmOyhKqAyX3BgTXMI84LwT6FOJ4tP2N9e2kwTCM0nQ= @@ -339,4 +401,6 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= diff --git a/main.go b/main.go index 3cdef6b..136718e 100644 --- a/main.go +++ b/main.go @@ -83,9 +83,11 @@ func main() { if err := config.InitDB(); err != nil { stateful.Exit("config.InitDB", err, -1) } - + err := config.InitNacos() + if err != nil { + stateful.Exit("config.InitNacos", err, -1) + } rdb.Init() - serverStartUp() } diff --git a/model/icluster_conf/cluster.go b/model/icluster_conf/cluster.go index ac64793..483abc3 100644 --- a/model/icluster_conf/cluster.go +++ b/model/icluster_conf/cluster.go @@ -236,6 +236,7 @@ func ClusterList2MapByID(list []*Cluster) map[int64]*Cluster { func NewClusterManager(txn itxn.TxnStorager, storager ClusterStorager, subClusterStorager SubClusterStorager, bfeClusterStorager ibasic.BFEClusterStorager, + instancePoolManager *InstancePoolManager, versionControlManager *iversion_control.VersionControlManager, deleteCheckers map[string]func(context.Context, *ibasic.Product, *Cluster) error) *ClusterManager { @@ -244,6 +245,7 @@ func NewClusterManager(txn itxn.TxnStorager, storager ClusterStorager, storager: storager, subClusterStorager: subClusterStorager, bfeClusterStorager: bfeClusterStorager, + instancePoolManager: instancePoolManager, versionControlManager: versionControlManager, deleteCheckers: deleteCheckers, @@ -266,6 +268,7 @@ type ClusterManager struct { subClusterStorager SubClusterStorager bfeClusterStorager ibasic.BFEClusterStorager + instancePoolManager *InstancePoolManager versionControlManager *iversion_control.VersionControlManager deleteCheckers map[string]func(context.Context, *ibasic.Product, *Cluster) error diff --git a/model/icluster_conf/exporter.go b/model/icluster_conf/exporter.go index 98bf92e..467f530 100644 --- a/model/icluster_conf/exporter.go +++ b/model/icluster_conf/exporter.go @@ -45,17 +45,37 @@ func (rm *ClusterManager) clusterTableConfGenerator(ctx context.Context) (*ivers return nil, err } + pools := map[string]*Pool{} + for _, cluster := range clusters { + for _, subcluster := range cluster.SubClusters { + if subcluster.InstancePool != nil { + pools[subcluster.InstancePool.Name] = subcluster.InstancePool + } + } + } + + // maybe rpc in db transaction + piMap, err := rm.instancePoolManager.BatchFetchInstances(ctx, PoolMap2List(pools)) + if err != nil { + return nil, err + } + allClusters := cluster_table_conf.AllClusterBackend{} for _, cluster := range clusters { clusterBackend := map[string]cluster_table_conf.SubClusterBackend{} for _, subCluster := range cluster.SubClusters { - if subCluster.InstancePool == nil || len(subCluster.InstancePool.Instances) == 0 { + if subCluster.InstancePool == nil { + continue + } + + pi := piMap[subCluster.InstancePool.Name] + if pi == nil || len(pi.Instances) == 0 { continue } - subClusterBackend := make(cluster_table_conf.SubClusterBackend, 0, len(subCluster.InstancePool.Instances)) - for _, instance := range subCluster.InstancePool.Instances { + subClusterBackend := make(cluster_table_conf.SubClusterBackend, 0, len(pi.Instances)) + for _, instance := range pi.Instances { subClusterBackend = append(subClusterBackend, &cluster_table_conf.BackendConf{ Name: lib.PString(instance.HostName), Addr: lib.PString(instance.IP), diff --git a/model/icluster_conf/pool.go b/model/icluster_conf/pool.go index 340b381..7d44376 100644 --- a/model/icluster_conf/pool.go +++ b/model/icluster_conf/pool.go @@ -16,12 +16,7 @@ package icluster_conf import ( "context" - "fmt" - "strings" - - "github.com/bfenetworks/api-server/lib/xerror" "github.com/bfenetworks/api-server/model/ibasic" - "github.com/bfenetworks/api-server/model/itxn" ) var ( @@ -40,39 +35,33 @@ type PoolParam struct { ID *int64 Name *string ProductID *int64 - Instances []Instance - - Tag *int8 + Type *int8 + Tag *int8 } type Pool struct { - ID int64 - Name string - Ready bool - Product *ibasic.Product - Instances []Instance - Tag int8 + ID int64 + Name string + Type int8 + Ready bool + Tag int8 + Product *ibasic.Product + + instances []Instance } -type Instance struct { - HostName string `json:"Name"` - IP string `json:"Addr"` - Port int `json:"Port"` - Ports map[string]int `json:"Ports,omitempty"` - Tags map[string]string `json:"tags,omitempty"` - Weight int64 `json:"Weight"` - Disable bool `json:"Disable"` +func (p *Pool) SetDefaultInstances(is []Instance) { + p.instances = is } -func (i *Instance) IPWithPort() string { - if i.Port == 0 { - i.Port = i.Ports["Default"] +func (p *Pool) GetDefaultPool() *InstancePool { + return &InstancePool{ + Name: p.Name, + Instances: p.instances, } - - return fmt.Sprintf("%s:%d", i.IP, i.Port) } -type PoolStorager interface { +type PoolStorage interface { FetchPool(ctx context.Context, name string) (*Pool, error) FetchPools(ctx context.Context, param *PoolFilter) ([]*Pool, error) @@ -80,199 +69,3 @@ type PoolStorager interface { UpdatePool(ctx context.Context, oldData *Pool, diff *PoolParam) error DeletePool(ctx context.Context, pool *Pool) error } - -type PoolManager struct { - storager PoolStorager - bfeClusterStorager ibasic.BFEClusterStorager - subClusterStorager SubClusterStorager - txn itxn.TxnStorager -} - -func NewPoolManager(txn itxn.TxnStorager, storager PoolStorager, - bfeClusterStorager ibasic.BFEClusterStorager, subClusterStorager SubClusterStorager) *PoolManager { - - return &PoolManager{ - txn: txn, - storager: storager, - bfeClusterStorager: bfeClusterStorager, - subClusterStorager: subClusterStorager, - } -} - -func (rppm *PoolManager) FetchPoolByName(ctx context.Context, name string) (one *Pool, err error) { - err = rppm.txn.AtomExecute(ctx, func(ctx context.Context) error { - one, err = rppm.storager.FetchPool(ctx, name) - return err - }) - - return -} - -func (rppm *PoolManager) FetchBFEPool(ctx context.Context, name string) (one *Pool, err error) { - return rppm.FetchProductPool(ctx, ibasic.BuildinProduct, name) -} - -func (rppm *PoolManager) FetchProductPool(ctx context.Context, product *ibasic.Product, name string) (one *Pool, err error) { - name, err = poolNameJudger(product.Name, name) - if err != nil { - return - } - - err = rppm.txn.AtomExecute(ctx, func(ctx context.Context) error { - one, err = rppm.storager.FetchPool(ctx, name) - return err - }) - - return -} - -func (rppm *PoolManager) FetchBFEPools(ctx context.Context) (list []*Pool, err error) { - return rppm.FetchProductPools(ctx, ibasic.BuildinProduct) -} - -func (rppm *PoolManager) FetchProductPools(ctx context.Context, product *ibasic.Product) (list []*Pool, err error) { - err = rppm.txn.AtomExecute(ctx, func(ctx context.Context) error { - list, err = rppm.storager.FetchPools(ctx, &PoolFilter{ - ProductID: &product.ID, - }) - return err - }) - - return -} - -func poolNameJudger(productName string, poolName string) (realName string, err error) { - ss := strings.SplitN(poolName, ".", 2) - if len(ss) == 2 { - if ss[0] != productName { - return "", xerror.WrapParamErrorWithMsg("Pool Name Must Use Product Name as Prefix") - } - - return poolName, nil - } - - return productName + "." + poolName, nil -} - -// CanDelete check whether pool can be deleted, Check Logic: -// 1. Not BFE Cluster Refer To -// 2. Not SubCluster Refer To -func (rppm *PoolManager) CanDelete(ctx context.Context, pool *Pool) error { - bfeClusters, err := rppm.bfeClusterStorager.FetchBFEClusters(ctx, &ibasic.BFEClusterFilter{ - Pool: &pool.Name, - }) - if err != nil { - return err - } - if len(bfeClusters) != 0 { - return xerror.WrapModelErrorWithMsg("BFECluster %s Refer To This Pool", bfeClusters[0].Name) - } - - subClusters, err := rppm.subClusterStorager.FetchSubClusterList(ctx, &SubClusterFilter{ - InstancePool: pool, - }) - if err != nil { - return err - } - if len(subClusters) != 0 { - return xerror.WrapModelErrorWithMsg("SubCluster %s Refer To This Pool", subClusters[0].Name) - } - - return nil -} - -func (rppm *PoolManager) DeleteBFEPool(ctx context.Context, name string) (one *Pool, err error) { - return rppm.DeleteProductPool(ctx, ibasic.BuildinProduct, name) -} - -func (rppm *PoolManager) DeleteProductPool(ctx context.Context, product *ibasic.Product, name string) (one *Pool, err error) { - name, err = poolNameJudger(product.Name, name) - if err != nil { - return - } - - err = rppm.txn.AtomExecute(ctx, func(ctx context.Context) error { - one, err = rppm.storager.FetchPool(ctx, name) - if err != nil { - return err - } - - if one == nil { - return xerror.WrapRecordNotExist("Pool") - } - - if err = rppm.CanDelete(ctx, one); err != nil { - return err - } - - return rppm.storager.DeletePool(ctx, one) - }) - - return -} - -func (rppm *PoolManager) CreateBFEPool(ctx context.Context, pool *PoolParam) (one *Pool, err error) { - pool.Tag = &PoolTagBFE - return rppm.CreateProductPool(ctx, ibasic.BuildinProduct, pool) -} - -func (rppm *PoolManager) CreateProductPool(ctx context.Context, product *ibasic.Product, pool *PoolParam) (one *Pool, err error) { - var pN string - pN, err = poolNameJudger(product.Name, *pool.Name) - if err != nil { - return - } - pool.Name = &pN - if pool.Tag == nil { - pool.Tag = &PoolTagProduct - } - - err = rppm.txn.AtomExecute(ctx, func(ctx context.Context) error { - old, err := rppm.storager.FetchPool(ctx, *pool.Name) - if err != nil { - return err - } - if old != nil { - return xerror.WrapRecordExisted() - } - - one, err = rppm.storager.CreatePool(ctx, product, pool) - return err - }) - - return -} - -func (rppm *PoolManager) UpdateBFEPool(ctx context.Context, pool *Pool, diff *PoolParam) (err error) { - return rppm.UpdateProductPool(ctx, ibasic.BuildinProduct, pool, diff) -} - -func (rppm *PoolManager) UpdateProductPool(ctx context.Context, product *ibasic.Product, pool *Pool, diff *PoolParam) (err error) { - err = rppm.txn.AtomExecute(ctx, func(ctx context.Context) error { - return rppm.storager.UpdatePool(ctx, pool, diff) - }) - - return -} - -func PoolList2Map(list []*Pool) map[int64]*Pool { - m := map[int64]*Pool{} - for _, one := range list { - m[one.ID] = one - } - - return m -} - -func (rppm *PoolManager) GetPoolByName(ctx context.Context, poolName *string) (pool *Pool, err error) { - err = rppm.txn.AtomExecute(ctx, func(ctx context.Context) error { - if poolName == nil || *poolName == "" { - return xerror.WrapParamErrorWithMsg("Pool Name Illegal") - } - - pool, err = rppm.storager.FetchPool(ctx, *poolName) - return err - }) - - return -} diff --git a/model/icluster_conf/pool_instance.go b/model/icluster_conf/pool_instance.go new file mode 100644 index 0000000..6d4d4dd --- /dev/null +++ b/model/icluster_conf/pool_instance.go @@ -0,0 +1,113 @@ +// Copyright (c) 2021 The BFE Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package icluster_conf + +import ( + "context" + "fmt" + + "github.com/bfenetworks/api-server/lib/xerror" +) + +type Instance struct { + HostName string `json:"Name"` + IP string `json:"Addr"` + Port int `json:"Port"` + Ports map[string]int `json:"Ports,omitempty"` + Tags map[string]string `json:"tags,omitempty"` + Weight int64 `json:"Weight"` + Disable bool `json:"Disable"` +} + +func (i *Instance) IPWithPort() string { + if i.Port == 0 { + i.Port = i.Ports["Default"] + } + + return fmt.Sprintf("%s:%d", i.IP, i.Port) +} + +type InstancePool struct { + Name string + Instances []Instance +} + +const ( + InstancePoolTypeRDB int8 = 1 + InstancePoolTypeNacos int8 = 2 +) + +type InstancePoolStorage interface { + UpdateInstances(context.Context, *Pool, *InstancePool) error + + BatchFetchInstances(context.Context, []*Pool) (map[string]*InstancePool, error) +} + +type InstancePoolManager struct { + instancePoolStorages map[int8]InstancePoolStorage +} + +func NewInstancePoolManager(instancePoolStorages map[int8]InstancePoolStorage) *InstancePoolManager { + return &InstancePoolManager{ + instancePoolStorages: instancePoolStorages, + } +} + +func (m *InstancePoolManager) BatchFetchInstances(ctx context.Context, pools []*Pool) (map[string]*InstancePool, error) { + type2PoolList := map[int8][]*Pool{} + for _, one := range pools { + type2PoolList[one.Type] = append(type2PoolList[one.Type], one) + } + + for type2 := range type2PoolList { + _, ok := m.instancePoolStorages[type2] + if !ok { + return nil, xerror.WrapModelErrorWithMsg("Type %d not register Storager", type2) + } + } + + rst := map[string]*InstancePool{} + for type2, pisList := range type2PoolList { + storager := m.instancePoolStorages[type2] + r, err := storager.BatchFetchInstances(ctx, pisList) + if err != nil { + return nil, err + } + + for name, pis := range r { + rst[name] = pis + } + } + + return rst, nil +} + +func (m *InstancePoolManager) UpdateInstances(ctx context.Context, pool *Pool, pis *InstancePool) error { + storager, ok := m.instancePoolStorages[pool.Type] + if !ok { + return xerror.WrapModelErrorWithMsg("Type %d not register Storager", pool.Type) + } + + return storager.UpdateInstances(ctx, pool, pis) +} + +func PoolMap2List(m map[string]*Pool) []*Pool { + var r []*Pool + for _, one := range m { + r = append(r, one) + } + + return r +} diff --git a/model/icluster_conf/pool_manager.go b/model/icluster_conf/pool_manager.go new file mode 100644 index 0000000..2c5f6a6 --- /dev/null +++ b/model/icluster_conf/pool_manager.go @@ -0,0 +1,232 @@ +// Copyright (c) 2021 The BFE Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package icluster_conf + +import ( + "context" + "strings" + + "github.com/bfenetworks/api-server/lib/xerror" + "github.com/bfenetworks/api-server/model/ibasic" + "github.com/bfenetworks/api-server/model/itxn" +) + +type PoolManager struct { + storage PoolStorage + bfeClusterStorager ibasic.BFEClusterStorager + subClusterStorager SubClusterStorager + txn itxn.TxnStorager + + instancePoolManager *InstancePoolManager +} + +func NewPoolManager(txn itxn.TxnStorager, storage PoolStorage, + bfeClusterStorager ibasic.BFEClusterStorager, subClusterStorager SubClusterStorager, + instancePoolManager *InstancePoolManager) *PoolManager { + + return &PoolManager{ + txn: txn, + storage: storage, + bfeClusterStorager: bfeClusterStorager, + subClusterStorager: subClusterStorager, + + instancePoolManager: instancePoolManager, + } +} + +func (m *PoolManager) FetchPoolByName(ctx context.Context, name string) (one *Pool, err error) { + err = m.txn.AtomExecute(ctx, func(ctx context.Context) error { + one, err = m.storage.FetchPool(ctx, name) + return err + }) + + return +} + +func (m *PoolManager) FetchBFEPool(ctx context.Context, name string) (one *Pool, err error) { + return m.FetchProductPool(ctx, ibasic.BuildinProduct, name) +} + +func (m *PoolManager) FetchProductPool(ctx context.Context, product *ibasic.Product, name string) (one *Pool, err error) { + name, err = poolNameJudger(product.Name, name) + if err != nil { + return + } + + err = m.txn.AtomExecute(ctx, func(ctx context.Context) error { + one, err = m.storage.FetchPool(ctx, name) + return err + }) + + return +} + +func (m *PoolManager) FetchBFEPools(ctx context.Context) (list []*Pool, err error) { + return m.FetchProductPools(ctx, ibasic.BuildinProduct) +} + +func (m *PoolManager) FetchProductPools(ctx context.Context, product *ibasic.Product) (list []*Pool, err error) { + err = m.txn.AtomExecute(ctx, func(ctx context.Context) error { + list, err = m.storage.FetchPools(ctx, &PoolFilter{ + ProductID: &product.ID, + }) + return err + }) + + return +} + +func poolNameJudger(productName string, poolName string) (realName string, err error) { + ss := strings.SplitN(poolName, ".", 2) + if len(ss) == 2 { + if ss[0] != productName { + return "", xerror.WrapParamErrorWithMsg("Pool Name Must Use Product Name as Prefix") + } + + return poolName, nil + } + + return productName + "." + poolName, nil +} + +// CanDelete check whether pool can be deleted, Check Logic: +// 1. Not BFE Cluster Refer To +// 2. Not SubCluster Refer To +func (m *PoolManager) CanDelete(ctx context.Context, pool *Pool) error { + bfeClusters, err := m.bfeClusterStorager.FetchBFEClusters(ctx, &ibasic.BFEClusterFilter{ + Pool: &pool.Name, + }) + if err != nil { + return err + } + if len(bfeClusters) != 0 { + return xerror.WrapModelErrorWithMsg("BFECluster %s Refer To This Pool", bfeClusters[0].Name) + } + + subClusters, err := m.subClusterStorager.FetchSubClusterList(ctx, &SubClusterFilter{ + InstancePool: pool, + }) + if err != nil { + return err + } + if len(subClusters) != 0 { + return xerror.WrapModelErrorWithMsg("SubCluster %s Refer To This Pool", subClusters[0].Name) + } + + return nil +} + +func (m *PoolManager) DeleteBFEPool(ctx context.Context, name string) (one *Pool, err error) { + return m.DeleteProductPool(ctx, ibasic.BuildinProduct, name) +} + +func (m *PoolManager) DeleteProductPool(ctx context.Context, product *ibasic.Product, name string) (one *Pool, err error) { + name, err = poolNameJudger(product.Name, name) + if err != nil { + return + } + + err = m.txn.AtomExecute(ctx, func(ctx context.Context) error { + one, err = m.storage.FetchPool(ctx, name) + if err != nil { + return err + } + + if one == nil { + return xerror.WrapRecordNotExist("Pool") + } + + if err = m.CanDelete(ctx, one); err != nil { + return err + } + + return m.storage.DeletePool(ctx, one) + }) + + return +} + +func (m *PoolManager) CreateBFEPool(ctx context.Context, pool *PoolParam, pis *InstancePool) (one *Pool, err error) { + pool.Tag = &PoolTagBFE + return m.CreateProductPool(ctx, ibasic.BuildinProduct, pool, pis) +} + +func (m *PoolManager) CreateProductPool(ctx context.Context, product *ibasic.Product, param *PoolParam, pool *InstancePool) (one *Pool, err error) { + var pN string + pN, err = poolNameJudger(product.Name, *param.Name) + if err != nil { + return + } + param.Name = &pN + if param.Tag == nil { + param.Tag = &PoolTagProduct + } + + err = m.txn.AtomExecute(ctx, func(ctx context.Context) error { + old, err := m.storage.FetchPool(ctx, *param.Name) + if err != nil { + return err + } + if old != nil { + return xerror.WrapRecordExisted() + } + + one, err = m.storage.CreatePool(ctx, product, param) + if err != nil { + return err + } + + if pool != nil { + err = m.instancePoolManager.UpdateInstances(ctx, one, pool) + } + return err + }) + + return +} + +func (m *PoolManager) UpdateBFEPool(ctx context.Context, pool *Pool, diff *PoolParam) (err error) { + return m.UpdateProductPool(ctx, ibasic.BuildinProduct, pool, diff) +} + +func (m *PoolManager) UpdateProductPool(ctx context.Context, product *ibasic.Product, pool *Pool, diff *PoolParam) (err error) { + err = m.txn.AtomExecute(ctx, func(ctx context.Context) error { + return m.storage.UpdatePool(ctx, pool, diff) + }) + + return +} + +func PoolList2Map(list []*Pool) map[int64]*Pool { + m := map[int64]*Pool{} + for _, one := range list { + m[one.ID] = one + } + + return m +} + +func (m *PoolManager) GetPoolByName(ctx context.Context, poolName *string) (pool *Pool, err error) { + err = m.txn.AtomExecute(ctx, func(ctx context.Context) error { + if poolName == nil || *poolName == "" { + return xerror.WrapParamErrorWithMsg("Pool Name Illegal") + } + + pool, err = m.storage.FetchPool(ctx, *poolName) + return err + }) + + return +} diff --git a/model/icluster_conf/sub_cluster.go b/model/icluster_conf/sub_cluster.go index 7d7cd43..e5100ea 100644 --- a/model/icluster_conf/sub_cluster.go +++ b/model/icluster_conf/sub_cluster.go @@ -81,18 +81,18 @@ type SubClusterManager struct { storager SubClusterStorager productStorager ibasic.ProductStorager - poolStorager PoolStorager + poolStorage PoolStorage clusterStorager ClusterStorager } func NewSubClusterManager(txn itxn.TxnStorager, storager SubClusterStorager, - productStorager ibasic.ProductStorager, poolStorager PoolStorager, + productStorager ibasic.ProductStorager, poolStorage PoolStorage, clusterStorager ClusterStorager) *SubClusterManager { return &SubClusterManager{ txn: txn, storager: storager, productStorager: productStorager, - poolStorager: poolStorager, + poolStorage: poolStorage, clusterStorager: clusterStorager, } } @@ -180,7 +180,7 @@ func (scm *SubClusterManager) CreateSubCluster(ctx context.Context, product *iba return xerror.WrapRecordExisted("SubCluster") } - pool, err := scm.poolStorager.FetchPool(ctx, *param.PoolName) + pool, err := scm.poolStorage.FetchPool(ctx, *param.PoolName) if err != nil { return err } diff --git a/stateful/config.go b/stateful/config.go index 59f63fc..1b193e8 100644 --- a/stateful/config.go +++ b/stateful/config.go @@ -38,15 +38,15 @@ type RunTimeConfig struct { } type Config struct { - Server ServerConfig - Loggers map[string]*LoggerConfig `validate:"dive"` - Databases map[string]*DbConfig `validate:"dive"` - Depends DependsConfig - RunTime RunTimeConfig - - Vars map[string]string - LogDir string - ConfigDir string + Server ServerConfig + Loggers map[string]*LoggerConfig `validate:"dive"` + Databases map[string]*DbConfig `validate:"dive"` + Depends DependsConfig + RunTime RunTimeConfig + NacosRegsiter *NacosRegisterConfig + Vars map[string]string + LogDir string + ConfigDir string } var DefaultConfig *Config diff --git a/stateful/config_register.go b/stateful/config_register.go new file mode 100644 index 0000000..193c234 --- /dev/null +++ b/stateful/config_register.go @@ -0,0 +1,61 @@ +// Copyright (c) 2021 The BFE Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package stateful + +import ( + "github.com/nacos-group/nacos-sdk-go/clients" + "github.com/nacos-group/nacos-sdk-go/clients/naming_client" + "github.com/nacos-group/nacos-sdk-go/common/constant" + "github.com/nacos-group/nacos-sdk-go/vo" +) + +type NacosRegisterConfig struct { + ServerConfig []constant.ServerConfig + ClientConfig constant.ClientConfig +} + +var NacosClient naming_client.INamingClient + +func (d *Config) InitNacos() error { + if d.NacosRegsiter == nil { + AccessLogger.Info("The configuration is not sound and naocs will not be started") + return nil + } + client, err := clients.NewNamingClient( + vo.NacosClientParam{ + ClientConfig: &d.NacosRegsiter.ClientConfig, + ServerConfigs: d.NacosRegsiter.ServerConfig, + }, + ) + + if err != nil { + return err + } + + service, err := client.GetService(vo.GetServiceParam{ + ServiceName: "ping", + }) + if err != nil { + return err + } + + AccessLogger.Info("nacos start success", service.Name) + NacosClient = client + return nil +} + +func GetNacosClient() (naming_client.INamingClient, error) { + return NacosClient, nil +} diff --git a/stateful/container/components.go b/stateful/container/components.go index 2b96061..997244a 100644 --- a/stateful/container/components.go +++ b/stateful/container/components.go @@ -32,7 +32,7 @@ var ( BFEClusterStoragerSingleton ibasic.BFEClusterStorager DomainStoragerSingleton iroute_conf.DomainStorager ClusterStoragerSingleton icluster_conf.ClusterStorager - PoolStoragerSingleton icluster_conf.PoolStorager + PoolStoragerSingleton icluster_conf.PoolStorage SubClusterStoragerSingleton icluster_conf.SubClusterStorager CertificateStoragerSingleton iprotocol.CertificateStorager AuthenticateStoragerSingleton iauth.AuthenticateStorager @@ -51,4 +51,5 @@ var ( AuthenticateManager *iauth.AuthenticateManager AuthorizeManager *iauth.AuthorizeManager PoolManager *icluster_conf.PoolManager + InstancePoolManager *icluster_conf.InstancePoolManager ) diff --git a/stateful/container/rdb/components.go b/stateful/container/rdb/components.go index 5ee443a..c3251f6 100644 --- a/stateful/container/rdb/components.go +++ b/stateful/container/rdb/components.go @@ -7,6 +7,7 @@ // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software + // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and @@ -25,6 +26,7 @@ import ( "github.com/bfenetworks/api-server/model/iversion_control" "github.com/bfenetworks/api-server/stateful" "github.com/bfenetworks/api-server/stateful/container" + nacos_cluster_conf "github.com/bfenetworks/api-server/storage/nacos/cluster_conf" "github.com/bfenetworks/api-server/storage/rdb/auth" "github.com/bfenetworks/api-server/storage/rdb/basic" "github.com/bfenetworks/api-server/storage/rdb/cluster_conf" @@ -42,7 +44,7 @@ func Init() { container.VersionControlStoragerSingleton) container.ProductStoragerSingleton = basic.NewProductManager(stateful.NewBFEDBContext) container.BFEClusterStoragerSingleton = basic.NewRDBBFEClusterStorager(stateful.NewBFEDBContext) - container.PoolStoragerSingleton = cluster_conf.NewRDBPoolStorager( + container.PoolStoragerSingleton = cluster_conf.NewRDBPoolStorage( stateful.NewBFEDBContext, container.ProductStoragerSingleton) container.SubClusterStoragerSingleton = cluster_conf.NewRDBSubClusterStorager( @@ -88,11 +90,18 @@ func Init() { container.VersionControlManager, container.DomainStoragerSingleton) + nacosClient, _ := stateful.GetNacosClient() + container.InstancePoolManager = icluster_conf.NewInstancePoolManager(map[int8]icluster_conf.InstancePoolStorage{ + icluster_conf.InstancePoolTypeRDB: cluster_conf.NewRDBInstancePoolStorage(stateful.NewBFEDBContext), + icluster_conf.InstancePoolTypeNacos: nacos_cluster_conf.NewNacosInstancePoolStorage(nacosClient), + }) + container.ClusterManager = icluster_conf.NewClusterManager( container.TxnStoragerSingleton, container.ClusterStoragerSingleton, container.SubClusterStoragerSingleton, container.BFEClusterStoragerSingleton, + container.InstancePoolManager, container.VersionControlManager, map[string]func(context.Context, *ibasic.Product, *icluster_conf.Cluster) error{ "rules": container.RouteRuleManager.ClusterDeleteChecker, @@ -123,5 +132,6 @@ func Init() { container.TxnStoragerSingleton, container.PoolStoragerSingleton, container.BFEClusterStoragerSingleton, - container.SubClusterStoragerSingleton) + container.SubClusterStoragerSingleton, + container.InstancePoolManager) } diff --git a/storage/nacos/cluster_conf/pool_instance.go b/storage/nacos/cluster_conf/pool_instance.go new file mode 100644 index 0000000..3db0e0a --- /dev/null +++ b/storage/nacos/cluster_conf/pool_instance.go @@ -0,0 +1,82 @@ +// Copyright (c) 2021 The BFE Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cluster_conf + +import ( + "context" + "strings" + + "github.com/bfenetworks/api-server/model/icluster_conf" + "github.com/nacos-group/nacos-sdk-go/clients/naming_client" + "github.com/nacos-group/nacos-sdk-go/model" + "github.com/nacos-group/nacos-sdk-go/vo" +) + +type NacosPoolInstanceStorage struct { + client naming_client.INamingClient +} + +func NewNacosInstancePoolStorage(client naming_client.INamingClient) *NacosPoolInstanceStorage { + return &NacosPoolInstanceStorage{ + client: client, + } +} + +func (rpps *NacosPoolInstanceStorage) UpdateInstances(ctx context.Context, pool *icluster_conf.Pool, pis *icluster_conf.InstancePool) error { + + return nil +} + +func (rpps *NacosPoolInstanceStorage) BatchFetchInstances(ctx context.Context, poolList []*icluster_conf.Pool) (map[string]*icluster_conf.InstancePool, error) { + m := map[string]*icluster_conf.InstancePool{} + for _, one := range poolList { + pi, err := rpps.GetInstance(one.Name[strings.Index(one.Name, ".")+1:]) + pi.Name = one.Name + if err != nil { + return nil, err + } + m[pi.Name] = pi + } + + return m, nil +} + +func (rpps *NacosPoolInstanceStorage) GetInstance(name string) (*icluster_conf.InstancePool, error) { + selectInstancesParam := vo.SelectInstancesParam{ + ServiceName: name, + HealthyOnly: true, + } + instances, err := rpps.client.SelectInstances(selectInstancesParam) + if err != nil { + return nil, err + } + bfeInstances := make([]icluster_conf.Instance, len(instances)) + for index, instance := range instances { + bfeInstances[index] = newBFEInstance(instance) + } + + return &icluster_conf.InstancePool{Name: name, Instances: bfeInstances}, nil +} + +func newBFEInstance(instance model.Instance) icluster_conf.Instance { + bfeInstance := icluster_conf.Instance{ + IP: instance.Ip, + Ports: map[string]int{"Default": int(instance.Port)}, + Weight: int64(instance.Weight), + HostName: instance.ServiceName, + Tags: instance.Metadata, + } + return bfeInstance +} diff --git a/storage/rdb/cluster_conf/pool.go b/storage/rdb/cluster_conf/pool.go index 63e3bc1..a9ff5ca 100644 --- a/storage/rdb/cluster_conf/pool.go +++ b/storage/rdb/cluster_conf/pool.go @@ -25,22 +25,22 @@ import ( "github.com/bfenetworks/api-server/storage/rdb/internal/dao" ) -type RDBPoolStorager struct { +type RDBPoolStorage struct { dbCtxFactory lib.DBContextFactory productStorager ibasic.ProductStorager } -func NewRDBPoolStorager(dbCtxFactory lib.DBContextFactory, - productStorager ibasic.ProductStorager) *RDBPoolStorager { +func NewRDBPoolStorage(dbCtxFactory lib.DBContextFactory, + productStorager ibasic.ProductStorager) *RDBPoolStorage { - return &RDBPoolStorager{ + return &RDBPoolStorage{ dbCtxFactory: dbCtxFactory, productStorager: productStorager, } } -var _ icluster_conf.PoolStorager = &RDBPoolStorager{} +var _ icluster_conf.PoolStorage = &RDBPoolStorage{} func poolFilter2Param(filter *icluster_conf.PoolFilter) *dao.TPoolsParam { if filter == nil { @@ -60,26 +60,16 @@ func poolParami2d(data *icluster_conf.PoolParam) (*dao.TPoolsParam, error) { return nil, nil } - var detail *string - if data.Instances != nil { - bs, err := json.Marshal(data.Instances) - if err != nil { - return nil, xerror.WrapParamErrorWithMsg("Instances Marshal, err: %s", err) - } - - detail = lib.PString(string(bs)) - } - return &dao.TPoolsParam{ - Id: data.ID, - Name: data.Name, - ProductID: data.ProductID, - InstanceDetail: detail, - Tag: data.Tag, + Id: data.ID, + Name: data.Name, + ProductID: data.ProductID, + Type: data.Type, + Tag: data.Tag, }, nil } -func (rpps *RDBPoolStorager) CreatePool(ctx context.Context, product *ibasic.Product, +func (rpps *RDBPoolStorage) CreatePool(ctx context.Context, product *ibasic.Product, data *icluster_conf.PoolParam) (*icluster_conf.Pool, error) { data.ProductID = &product.ID @@ -93,19 +83,16 @@ func (rpps *RDBPoolStorager) CreatePool(ctx context.Context, product *ibasic.Pro return nil, err } - newID, err := dao.TPoolsCreate(dbCtx, param) + _, err = dao.TPoolsCreate(dbCtx, param) if err != nil { return nil, err } - return &icluster_conf.Pool{ - ID: newID, - Name: *data.Name, - Instances: data.Instances, - }, nil + return rpps.FetchPool(ctx, *param.Name) + } -func (rpps *RDBPoolStorager) FetchPool(ctx context.Context, name string) (*icluster_conf.Pool, error) { +func (rpps *RDBPoolStorage) FetchPool(ctx context.Context, name string) (*icluster_conf.Pool, error) { list, err := rpps.FetchPools(ctx, &icluster_conf.PoolFilter{ Name: &name, }) @@ -121,26 +108,29 @@ func (rpps *RDBPoolStorager) FetchPool(ctx context.Context, name string) (*iclus func newPool(pp *dao.TPools, product *ibasic.Product) (*icluster_conf.Pool, error) { data := &icluster_conf.Pool{ - ID: pp.Id, - Name: pp.Name, - Ready: pp.Ready, - + ID: pp.Id, + Name: pp.Name, + Ready: pp.Ready, + Type: pp.Type, Product: product, Tag: pp.Tag, } + // get default instance list if pp.InstanceDetail == "" || pp.InstanceDetail == "NULL" { pp.InstanceDetail = "[]" } - if err := json.Unmarshal([]byte(pp.InstanceDetail), &data.Instances); err != nil { + is := []icluster_conf.Instance{} + if err := json.Unmarshal([]byte(pp.InstanceDetail), &is); err != nil { return nil, xerror.WrapDirtyDataErrorWithMsg("pool %s, raw: %s, err: %v", pp.Name, pp.InstanceDetail, err) } + data.SetDefaultInstances(is) return data, nil } -func (rpps *RDBPoolStorager) FetchPools(ctx context.Context, filter *icluster_conf.PoolFilter) ([]*icluster_conf.Pool, error) { +func (rpps *RDBPoolStorage) FetchPools(ctx context.Context, filter *icluster_conf.PoolFilter) ([]*icluster_conf.Pool, error) { dbCtx, err := rpps.dbCtxFactory(ctx) if err != nil { return nil, err @@ -177,11 +167,12 @@ func (rpps *RDBPoolStorager) FetchPools(ctx context.Context, filter *icluster_co } rst = append(rst, p) } + // rpps.registerServier.GetRegisteredInstance(rst) return rst, nil } -func (rpps *RDBPoolStorager) UpdatePool(ctx context.Context, oldData *icluster_conf.Pool, +func (rpps *RDBPoolStorage) UpdatePool(ctx context.Context, oldData *icluster_conf.Pool, diff *icluster_conf.PoolParam) error { p, err := poolParami2d(diff) @@ -201,7 +192,7 @@ func (rpps *RDBPoolStorager) UpdatePool(ctx context.Context, oldData *icluster_c return err } -func (rpps *RDBPoolStorager) DeletePool(ctx context.Context, pool *icluster_conf.Pool) error { +func (rpps *RDBPoolStorage) DeletePool(ctx context.Context, pool *icluster_conf.Pool) error { dbCtx, err := rpps.dbCtxFactory(ctx) if err != nil { return nil diff --git a/storage/rdb/cluster_conf/pool_instance.go b/storage/rdb/cluster_conf/pool_instance.go new file mode 100644 index 0000000..73f4b5c --- /dev/null +++ b/storage/rdb/cluster_conf/pool_instance.go @@ -0,0 +1,77 @@ +// Copyright (c) 2021 The BFE Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cluster_conf + +import ( + "context" + "encoding/json" + + "github.com/bfenetworks/api-server/lib" + "github.com/bfenetworks/api-server/lib/xerror" + "github.com/bfenetworks/api-server/model/icluster_conf" + "github.com/bfenetworks/api-server/storage/rdb/internal/dao" +) + +type RDBInstancePoolStorage struct { + dbCtxFactory lib.DBContextFactory +} + +func NewRDBInstancePoolStorage(dbCtxFactory lib.DBContextFactory) *RDBInstancePoolStorage { + return &RDBInstancePoolStorage{ + dbCtxFactory: dbCtxFactory, + } +} + +var _ icluster_conf.InstancePoolStorage = &RDBInstancePoolStorage{} + +func (rpps *RDBInstancePoolStorage) UpdateInstances(ctx context.Context, pool *icluster_conf.Pool, + pis *icluster_conf.InstancePool) error { + + var detail *string + if pis.Instances != nil { + bs, err := json.Marshal(pis.Instances) + if err != nil { + return xerror.WrapParamErrorWithMsg("Instances Marshal, err: %s", err) + } + + detail = lib.PString(string(bs)) + } + + dbCtx, err := rpps.dbCtxFactory(ctx) + if err != nil { + return err + } + _, err = dao.TPoolsUpdate(dbCtx, &dao.TPoolsParam{ + InstanceDetail: detail, + }, &dao.TPoolsParam{ + Id: &pool.ID, + }) + + return err +} + +func (rpps *RDBInstancePoolStorage) BatchFetchInstances(ctx context.Context, + poolList []*icluster_conf.Pool) (map[string]*icluster_conf.InstancePool, error) { + + m := map[string]*icluster_conf.InstancePool{} + for _, one := range poolList { + // because of RDBPoolStorage.FetchPools will get pool list + // it's trick + pi := one.GetDefaultPool() + m[pi.Name] = pi + } + + return m, nil +} diff --git a/storage/rdb/cluster_conf/sub_cluster.go b/storage/rdb/cluster_conf/sub_cluster.go index 70ebc74..0577a87 100644 --- a/storage/rdb/cluster_conf/sub_cluster.go +++ b/storage/rdb/cluster_conf/sub_cluster.go @@ -26,11 +26,11 @@ import ( type RDBSubClusterStorager struct { dbCtxFactory lib.DBContextFactory - poolStorage icluster_conf.PoolStorager + poolStorage icluster_conf.PoolStorage productStorager ibasic.ProductStorager } -func NewRDBSubClusterStorager(dbCtxFactory lib.DBContextFactory, poolStorage icluster_conf.PoolStorager, +func NewRDBSubClusterStorager(dbCtxFactory lib.DBContextFactory, poolStorage icluster_conf.PoolStorage, productStorager ibasic.ProductStorager) *RDBSubClusterStorager { return &RDBSubClusterStorager{