mirror of
https://github.com/TeaOSLab/EdgeAPI.git
synced 2025-11-02 05:40:27 +08:00
阶段性提交
This commit is contained in:
11
build/build.sh
Executable file
11
build/build.sh
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
ROOT=`dirname $0`
|
||||
|
||||
# building installer
|
||||
architects=( "amd64" "386" )
|
||||
for arch in "${architects[@]}"
|
||||
do
|
||||
# TODO support arm, mips ...
|
||||
env GOOS=linux GOARCH=${arch} go build --ldflags="-s -w" -o $ROOT/installers/installer-helper-linux-${arch} $ROOT/../cmd/installer-helper/main.go
|
||||
done
|
||||
1
build/deploy/.gitignore
vendored
Normal file
1
build/deploy/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.zip
|
||||
@@ -18,6 +18,7 @@ pub ${ADMIN_PROJECT} node_cluster
|
||||
pub ${ADMIN_PROJECT} node_grant
|
||||
pub ${ADMIN_PROJECT} node_ip_address
|
||||
pub ${ADMIN_PROJECT} server
|
||||
pub ${ADMIN_PROJECT} api_node
|
||||
|
||||
cp ../internal/rpc/pb/model_*.go ${ADMIN_PROJECT}/internal/rpc/pb/
|
||||
|
||||
|
||||
1
build/installers/.gitignore
vendored
Normal file
1
build/installers/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
installer-*
|
||||
53
cmd/installer-helper/main.go
Normal file
53
cmd/installer-helper/main.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
cmd := ""
|
||||
flag.StringVar(&cmd, "cmd", "", "command name: [unzip]")
|
||||
|
||||
// unzip
|
||||
zipPath := ""
|
||||
targetPath := ""
|
||||
flag.StringVar(&zipPath, "zip", "", "zip path")
|
||||
flag.StringVar(&targetPath, "target", "", "target dir")
|
||||
|
||||
// parse
|
||||
flag.Parse()
|
||||
|
||||
if len(cmd) == 0 {
|
||||
stderr("need '-cmd=COMMAND' argument")
|
||||
} else if cmd == "unzip" { // 解压
|
||||
if len(zipPath) == 0 {
|
||||
stderr("ERROR: need '-zip=PATH' argument")
|
||||
return
|
||||
}
|
||||
if len(targetPath) == 0 {
|
||||
stderr("ERROR: need '-target=TARGET' argument")
|
||||
return
|
||||
}
|
||||
|
||||
unzip := utils.NewUnzip(zipPath, targetPath)
|
||||
err := unzip.Run()
|
||||
if err != nil {
|
||||
stderr("ERROR: " + err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
stdout("ok")
|
||||
} else {
|
||||
stderr("ERROR: not recognized command '" + cmd + "'")
|
||||
}
|
||||
}
|
||||
|
||||
func stdout(s string) {
|
||||
_, _ = os.Stdout.WriteString(s + "\n")
|
||||
}
|
||||
|
||||
func stderr(s string) {
|
||||
_, _ = os.Stderr.WriteString(s + "\n")
|
||||
}
|
||||
2
go.mod
2
go.mod
@@ -7,6 +7,8 @@ require (
|
||||
github.com/go-yaml/yaml v2.1.0+incompatible
|
||||
github.com/golang/protobuf v1.4.2
|
||||
github.com/iwind/TeaGo v0.0.0-20200727075925-7e7e67b44f2d
|
||||
github.com/pkg/sftp v1.12.0
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
|
||||
google.golang.org/grpc v1.30.0
|
||||
google.golang.org/protobuf v1.25.0
|
||||
)
|
||||
|
||||
20
go.sum
20
go.sum
@@ -4,6 +4,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
@@ -40,6 +42,8 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/iwind/TeaGo v0.0.0-20200727075925-7e7e67b44f2d h1:V7HA0wUOdmZbXJTVpiUEvSD4ARKHwMLMmiCccfkqf24=
|
||||
github.com/iwind/TeaGo v0.0.0-20200727075925-7e7e67b44f2d/go.mod h1:zjM7k+b+Jthhf0T0fKwuF0iy4TWb5SsU1gmKR2l+OmE=
|
||||
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
@@ -51,10 +55,22 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108
|
||||
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/sftp v1.12.0 h1:/f3b24xrDhkhddlaobPe2JgBqfdt+gC/NYl0QY9IOuI=
|
||||
github.com/pkg/sftp v1.12.0/go.mod h1:fUqqXB5vEgVCZ131L+9say31RAri6aF6KDViawhxKK8=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pquerna/ffjson v0.0.0-20190930134022-aa0246cd15f7 h1:xoIK0ctDddBMnc74udxJYBqlo9Ylnsp1waqjLsnef20=
|
||||
github.com/pquerna/ffjson v0.0.0-20190930134022-aa0246cd15f7/go.mod h1:YARuvh7BUWHNhzDq2OM5tzR2RiCcN2D7sapiKyCel/M=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM=
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
@@ -65,6 +81,7 @@ golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73r
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 h1:AeiKBIuRw3UomYXSbLy0Mc2dDLfdtbT/IVn4keq83P0=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
|
||||
@@ -76,6 +93,7 @@ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -124,5 +142,7 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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=
|
||||
|
||||
@@ -57,6 +57,7 @@ func (this *APINode) listenRPC() error {
|
||||
pb.RegisterNodeServiceServer(rpcServer, &services.NodeService{})
|
||||
pb.RegisterNodeClusterServiceServer(rpcServer, &services.NodeClusterService{})
|
||||
pb.RegisterNodeIPAddressServiceServer(rpcServer, &services.NodeIPAddressService{})
|
||||
pb.RegisterAPINodeServiceServer(rpcServer, &services.APINodeService{})
|
||||
err = rpcServer.Serve(listener)
|
||||
if err != nil {
|
||||
return errors.New("[API]start rpc failed: " + err.Error())
|
||||
|
||||
163
internal/db/models/api_node_dao.go
Normal file
163
internal/db/models/api_node_dao.go
Normal file
@@ -0,0 +1,163 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"errors"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"github.com/iwind/TeaGo/rands"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
)
|
||||
|
||||
const (
|
||||
APINodeStateEnabled = 1 // 已启用
|
||||
APINodeStateDisabled = 0 // 已禁用
|
||||
)
|
||||
|
||||
type APINodeDAO dbs.DAO
|
||||
|
||||
func NewAPINodeDAO() *APINodeDAO {
|
||||
return dbs.NewDAO(&APINodeDAO{
|
||||
DAOObject: dbs.DAOObject{
|
||||
DB: Tea.Env,
|
||||
Table: "edgeApiNodes",
|
||||
Model: new(APINode),
|
||||
PkName: "id",
|
||||
},
|
||||
}).(*APINodeDAO)
|
||||
}
|
||||
|
||||
var SharedAPINodeDAO = NewAPINodeDAO()
|
||||
|
||||
// 启用条目
|
||||
func (this *APINodeDAO) EnableAPINode(id int64) error {
|
||||
_, err := this.Query().
|
||||
Pk(id).
|
||||
Set("state", APINodeStateEnabled).
|
||||
Update()
|
||||
return err
|
||||
}
|
||||
|
||||
// 禁用条目
|
||||
func (this *APINodeDAO) DisableAPINode(id int64) error {
|
||||
_, err := this.Query().
|
||||
Pk(id).
|
||||
Set("state", APINodeStateDisabled).
|
||||
Update()
|
||||
return err
|
||||
}
|
||||
|
||||
// 查找启用中的条目
|
||||
func (this *APINodeDAO) FindEnabledAPINode(id int64) (*APINode, error) {
|
||||
result, err := this.Query().
|
||||
Pk(id).
|
||||
Attr("state", APINodeStateEnabled).
|
||||
Find()
|
||||
if result == nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.(*APINode), err
|
||||
}
|
||||
|
||||
// 根据主键查找名称
|
||||
func (this *APINodeDAO) FindAPINodeName(id int64) (string, error) {
|
||||
return this.Query().
|
||||
Pk(id).
|
||||
Result("name").
|
||||
FindStringCol("")
|
||||
}
|
||||
|
||||
// 创建API节点
|
||||
func (this *APINodeDAO) CreateAPINode(name string, description string, host string, port int) (nodeId int64, err error) {
|
||||
uniqueId, err := this.genUniqueId()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
secret := rands.String(32)
|
||||
err = SharedApiTokenDAO.CreateAPIToken(uniqueId, secret, NodeRoleAPI)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
op := NewAPINodeOperator()
|
||||
op.IsOn = true
|
||||
op.UniqueId = uniqueId
|
||||
op.Secret = secret
|
||||
op.Name = name
|
||||
op.Description = description
|
||||
op.Host = host
|
||||
op.Port = port
|
||||
op.State = NodeStateEnabled
|
||||
_, err = this.Save(op)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return types.Int64(op.Id), nil
|
||||
}
|
||||
|
||||
// 修改API节点
|
||||
func (this *APINodeDAO) UpdateAPINode(nodeId int64, name string, description string, host string, port int) error {
|
||||
if nodeId <= 0 {
|
||||
return errors.New("invalid nodeId")
|
||||
}
|
||||
|
||||
op := NewAPINodeOperator()
|
||||
op.Id = nodeId
|
||||
op.Name = name
|
||||
op.Description = description
|
||||
op.Host = host
|
||||
op.Port = port
|
||||
_, err := this.Save(op)
|
||||
return err
|
||||
}
|
||||
|
||||
// 列出所有可用API节点
|
||||
func (this *APINodeDAO) FindAllEnabledAPINodes() (result []*APINode, err error) {
|
||||
_, err = this.Query().
|
||||
Attr("clusterId", 0). // 非集群专用
|
||||
State(APINodeStateEnabled).
|
||||
Desc("order").
|
||||
AscPk().
|
||||
Slice(&result).
|
||||
FindAll()
|
||||
return
|
||||
}
|
||||
|
||||
// 计算API节点数量
|
||||
func (this *APINodeDAO) CountAllEnabledAPINodes() (int64, error) {
|
||||
return this.Query().
|
||||
State(APINodeStateEnabled).
|
||||
Count()
|
||||
}
|
||||
|
||||
// 列出单页的API节点
|
||||
func (this *APINodeDAO) ListEnabledAPINodes(offset int64, size int64) (result []*APINode, err error) {
|
||||
_, err = this.Query().
|
||||
Attr("clusterId", 0). // 非集群专用
|
||||
State(APINodeStateEnabled).
|
||||
Offset(offset).
|
||||
Limit(size).
|
||||
Desc("order").
|
||||
DescPk().
|
||||
Slice(&result).
|
||||
FindAll()
|
||||
return
|
||||
}
|
||||
|
||||
// 生成唯一ID
|
||||
func (this *APINodeDAO) genUniqueId() (string, error) {
|
||||
for {
|
||||
uniqueId := rands.HexString(32)
|
||||
ok, err := this.Query().
|
||||
Attr("uniqueId", uniqueId).
|
||||
Exist()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if ok {
|
||||
continue
|
||||
}
|
||||
return uniqueId, nil
|
||||
}
|
||||
}
|
||||
5
internal/db/models/api_node_dao_test.go
Normal file
5
internal/db/models/api_node_dao_test.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
)
|
||||
34
internal/db/models/api_node_model.go
Normal file
34
internal/db/models/api_node_model.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package models
|
||||
|
||||
//
|
||||
type APINode struct {
|
||||
Id uint32 `field:"id"` // ID
|
||||
IsOn uint8 `field:"isOn"` // 是否启用
|
||||
ClusterId uint32 `field:"clusterId"` // 专用集群ID
|
||||
UniqueId string `field:"uniqueId"` // 唯一ID
|
||||
Secret string `field:"secret"` // 密钥
|
||||
Name string `field:"name"` // 名称
|
||||
Description string `field:"description"` // 描述
|
||||
Host string `field:"host"` // 地址
|
||||
Port uint32 `field:"port"` // 端口
|
||||
Order uint32 `field:"order"` // 排序
|
||||
State uint8 `field:"state"` // 状态
|
||||
}
|
||||
|
||||
type APINodeOperator struct {
|
||||
Id interface{} // ID
|
||||
IsOn interface{} // 是否启用
|
||||
ClusterId interface{} // 专用集群ID
|
||||
UniqueId interface{} // 唯一ID
|
||||
Secret interface{} // 密钥
|
||||
Name interface{} // 名称
|
||||
Description interface{} // 描述
|
||||
Host interface{} // 地址
|
||||
Port interface{} // 端口
|
||||
Order interface{} // 排序
|
||||
State interface{} // 状态
|
||||
}
|
||||
|
||||
func NewAPINodeOperator() *APINodeOperator {
|
||||
return &APINodeOperator{}
|
||||
}
|
||||
1
internal/db/models/api_node_model_ext.go
Normal file
1
internal/db/models/api_node_model_ext.go
Normal file
@@ -0,0 +1 @@
|
||||
package models
|
||||
@@ -66,3 +66,14 @@ func (this *ApiTokenDAO) FindEnabledTokenWithNode(nodeId string) (*ApiToken, err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 保存API Token
|
||||
func (this *ApiTokenDAO) CreateAPIToken(nodeId string, secret string, role NodeRole) error {
|
||||
op := NewApiTokenOperator()
|
||||
op.NodeId = nodeId
|
||||
op.Secret = secret
|
||||
op.Role = role
|
||||
op.State = ApiTokenStateEnabled
|
||||
_, err := this.Save(op)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -83,6 +83,8 @@ func (this *NodeClusterDAO) CreateCluster(name string, grantId int64, installDir
|
||||
op.Name = name
|
||||
op.GrantId = grantId
|
||||
op.InstallDir = installDir
|
||||
op.UseAllAPINodes = 1
|
||||
op.ApiNodes = "[]"
|
||||
op.State = NodeClusterStateEnabled
|
||||
_, err = this.Save(op)
|
||||
if err != nil {
|
||||
|
||||
@@ -2,23 +2,27 @@ package models
|
||||
|
||||
// 节点集群
|
||||
type NodeCluster struct {
|
||||
Id uint32 `field:"id"` // ID
|
||||
Name string `field:"name"` // 名称
|
||||
InstallDir string `field:"installDir"` // 安装目录
|
||||
GrantId uint32 `field:"grantId"` // 默认认证方式
|
||||
Order uint32 `field:"order"` // 排序
|
||||
CreatedAt uint32 `field:"createdAt"` // 创建时间
|
||||
State uint8 `field:"state"` // 状态
|
||||
Id uint32 `field:"id"` // ID
|
||||
Name string `field:"name"` // 名称
|
||||
InstallDir string `field:"installDir"` // 安装目录
|
||||
GrantId uint32 `field:"grantId"` // 默认认证方式
|
||||
UseAllAPINodes uint8 `field:"useAllAPINodes"` // 是否使用所有API节点
|
||||
ApiNodes string `field:"apiNodes"` // 使用的API节点
|
||||
Order uint32 `field:"order"` // 排序
|
||||
CreatedAt uint32 `field:"createdAt"` // 创建时间
|
||||
State uint8 `field:"state"` // 状态
|
||||
}
|
||||
|
||||
type NodeClusterOperator struct {
|
||||
Id interface{} // ID
|
||||
Name interface{} // 名称
|
||||
InstallDir interface{} // 安装目录
|
||||
GrantId interface{} // 默认认证方式
|
||||
Order interface{} // 排序
|
||||
CreatedAt interface{} // 创建时间
|
||||
State interface{} // 状态
|
||||
Id interface{} // ID
|
||||
Name interface{} // 名称
|
||||
InstallDir interface{} // 安装目录
|
||||
GrantId interface{} // 默认认证方式
|
||||
UseAllAPINodes interface{} // 是否使用所有API节点
|
||||
ApiNodes interface{} // 使用的API节点
|
||||
Order interface{} // 排序
|
||||
CreatedAt interface{} // 创建时间
|
||||
State interface{} // 状态
|
||||
}
|
||||
|
||||
func NewNodeClusterOperator() *NodeClusterOperator {
|
||||
|
||||
@@ -74,10 +74,18 @@ func (this *NodeDAO) CreateNode(name string, clusterId int64) (nodeId int64, err
|
||||
return 0, err
|
||||
}
|
||||
|
||||
secret := rands.String(32)
|
||||
|
||||
// 保存API Token
|
||||
err = SharedApiTokenDAO.CreateAPIToken(uniqueId, secret, NodeRoleNode)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
op := NewNodeOperator()
|
||||
op.Name = name
|
||||
op.UniqueId = uniqueId
|
||||
op.Secret = rands.String(32)
|
||||
op.Secret = secret
|
||||
op.ClusterId = clusterId
|
||||
op.IsOn = 1
|
||||
op.State = NodeStateEnabled
|
||||
@@ -260,6 +268,15 @@ func (this *NodeDAO) UpdateNodeStatus(nodeId int64, statusJSON []byte) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// 设置节点安装状态
|
||||
func (this *NodeDAO) UpdateNodeIsInstalled(nodeId int64, isInstalled bool) error {
|
||||
_, err := this.Query().
|
||||
Pk(nodeId).
|
||||
Set("isInstalled", isInstalled).
|
||||
Update()
|
||||
return err
|
||||
}
|
||||
|
||||
// 生成唯一ID
|
||||
func (this *NodeDAO) genUniqueId() (string, error) {
|
||||
for {
|
||||
|
||||
15
internal/db/models/node_roles.go
Normal file
15
internal/db/models/node_roles.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package models
|
||||
|
||||
type NodeRole = string
|
||||
|
||||
const (
|
||||
NodeRoleAdmin NodeRole = "admin"
|
||||
NodeRoleUser NodeRole = "user"
|
||||
NodeRoleProvider NodeRole = "provider"
|
||||
NodeRoleAPI NodeRole = "api"
|
||||
NodeRoleDatabase NodeRole = "database"
|
||||
NodeRoleLog NodeRole = "log"
|
||||
NodeRoleDNS NodeRole = "dns"
|
||||
NodeRoleMonitor NodeRole = "monitor"
|
||||
NodeRoleNode NodeRole = "node"
|
||||
)
|
||||
9
internal/installers/credentials.go
Normal file
9
internal/installers/credentials.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package installers
|
||||
|
||||
type Credentials struct {
|
||||
Host string
|
||||
Port int
|
||||
Username string
|
||||
Password string
|
||||
PrivateKey string
|
||||
}
|
||||
7
internal/installers/env.go
Normal file
7
internal/installers/env.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package installers
|
||||
|
||||
type Env struct {
|
||||
OS string
|
||||
Arch string
|
||||
HelperName string
|
||||
}
|
||||
168
internal/installers/installer_base.go
Normal file
168
internal/installers/installer_base.go
Normal file
@@ -0,0 +1,168 @@
|
||||
package installers
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
stringutil "github.com/iwind/TeaGo/utils/string"
|
||||
"golang.org/x/crypto/ssh"
|
||||
"net"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type BaseInstaller struct {
|
||||
client *SSHClient
|
||||
}
|
||||
|
||||
// 登录SSH服务
|
||||
func (this *BaseInstaller) Login(credentials *Credentials) error {
|
||||
var hostKeyCallback ssh.HostKeyCallback = nil
|
||||
|
||||
// 检查参数
|
||||
if len(credentials.Host) == 0 {
|
||||
return errors.New("'host' should not be empty")
|
||||
}
|
||||
if credentials.Port <= 0 {
|
||||
return errors.New("'port' should be greater than 0")
|
||||
}
|
||||
if len(credentials.Password) == 0 && len(credentials.PrivateKey) == 0 {
|
||||
return errors.New("require user 'password' or 'privateKey'")
|
||||
}
|
||||
|
||||
// 不使用known_hosts
|
||||
if hostKeyCallback == nil {
|
||||
hostKeyCallback = func(hostname string, remote net.Addr, key ssh.PublicKey) error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// 认证
|
||||
methods := []ssh.AuthMethod{}
|
||||
if len(credentials.Password) > 0 {
|
||||
{
|
||||
authMethod := ssh.Password(credentials.Password)
|
||||
methods = append(methods, authMethod)
|
||||
}
|
||||
|
||||
{
|
||||
authMethod := ssh.KeyboardInteractive(func(user, instruction string, questions []string, echos []bool) (answers []string, err error) {
|
||||
if len(questions) == 0 {
|
||||
return []string{}, nil
|
||||
}
|
||||
return []string{credentials.Password}, nil
|
||||
})
|
||||
methods = append(methods, authMethod)
|
||||
}
|
||||
} else {
|
||||
signer, err := ssh.ParsePrivateKey([]byte(credentials.PrivateKey))
|
||||
if err != nil {
|
||||
return errors.New("parse private key: " + err.Error())
|
||||
}
|
||||
authMethod := ssh.PublicKeys(signer)
|
||||
methods = append(methods, authMethod)
|
||||
}
|
||||
|
||||
// SSH客户端
|
||||
config := &ssh.ClientConfig{
|
||||
User: credentials.Username,
|
||||
Auth: methods,
|
||||
HostKeyCallback: hostKeyCallback,
|
||||
Timeout: 5 * time.Second, // TODO 后期可以设置这个超时时间
|
||||
}
|
||||
|
||||
sshClient, err := ssh.Dial("tcp", credentials.Host+":"+strconv.Itoa(credentials.Port), config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client, err := NewSSHClient(sshClient)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
this.client = client
|
||||
return nil
|
||||
}
|
||||
|
||||
// 关闭SSH服务
|
||||
func (this *BaseInstaller) Close() error {
|
||||
if this.client != nil {
|
||||
return this.client.Close()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 查找最新的版本的文件
|
||||
func (this *BaseInstaller) LookupLatestInstaller(filePrefix string) (string, error) {
|
||||
matches, err := filepath.Glob(Tea.Root + Tea.DS + "deploy" + Tea.DS + "*.zip")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
pattern, err := regexp.Compile(filePrefix + `-v([\d.]+)\.zip`)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
lastVersion := ""
|
||||
result := ""
|
||||
for _, match := range matches {
|
||||
baseName := filepath.Base(match)
|
||||
if !pattern.MatchString(baseName) {
|
||||
continue
|
||||
}
|
||||
m := pattern.FindStringSubmatch(baseName)
|
||||
if len(m) < 2 {
|
||||
continue
|
||||
}
|
||||
version := m[1]
|
||||
if len(lastVersion) == 0 || stringutil.VersionCompare(version, lastVersion) > 0 {
|
||||
lastVersion = version
|
||||
result = match
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// 上传安装助手
|
||||
func (this *BaseInstaller) InstallHelper(targetDir string) (env *Env, err error) {
|
||||
uname, _, err := this.client.Exec("uname -a")
|
||||
if err != nil {
|
||||
return env, err
|
||||
}
|
||||
|
||||
osName := ""
|
||||
archName := ""
|
||||
if strings.Index(uname, "Darwin") > 0 {
|
||||
osName = "darwin"
|
||||
} else if strings.Index(uname, "Linux") >= 0 {
|
||||
osName = "linux"
|
||||
} else {
|
||||
// TODO 支持freebsd, aix ...
|
||||
return env, errors.New("installer not supported os '" + uname + "'")
|
||||
}
|
||||
|
||||
if strings.Index(uname, "x86_64") > 0 {
|
||||
archName = "amd64"
|
||||
} else {
|
||||
// TODO 支持ARM和MIPS等架构
|
||||
archName = "386"
|
||||
}
|
||||
|
||||
exeName := "installer-helper-" + osName + "-" + archName
|
||||
exePath := Tea.Root + "/installers/" + exeName
|
||||
|
||||
err = this.client.Copy(exePath, targetDir+"/"+exeName, 0777)
|
||||
if err != nil {
|
||||
return env, err
|
||||
}
|
||||
|
||||
env = &Env{
|
||||
OS: osName,
|
||||
Arch: archName,
|
||||
HelperName: exeName,
|
||||
}
|
||||
return env, nil
|
||||
}
|
||||
20
internal/installers/installer_base_test.go
Normal file
20
internal/installers/installer_base_test.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package installers
|
||||
|
||||
import (
|
||||
_ "github.com/iwind/TeaGo/bootstrap"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBaseInstaller_LookupLatest(t *testing.T) {
|
||||
installer := &BaseInstaller{}
|
||||
result, err := installer.LookupLatestInstaller("edge-node-linux-amd64")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(result) == 0 {
|
||||
t.Log("not found")
|
||||
return
|
||||
}
|
||||
|
||||
t.Log("result:", result)
|
||||
}
|
||||
12
internal/installers/installer_interface.go
Normal file
12
internal/installers/installer_interface.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package installers
|
||||
|
||||
type InstallerInterface interface {
|
||||
// 登录SSH服务
|
||||
Login(credentials *Credentials) error
|
||||
|
||||
// 安装
|
||||
Install(dir string, params interface{}) error
|
||||
|
||||
// 关闭连接的SSH服务
|
||||
Close() error
|
||||
}
|
||||
86
internal/installers/installer_node.go
Normal file
86
internal/installers/installer_node.go
Normal file
@@ -0,0 +1,86 @@
|
||||
package installers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type NodeInstaller struct {
|
||||
BaseInstaller
|
||||
}
|
||||
|
||||
func (this *NodeInstaller) Install(dir string, params interface{}) error {
|
||||
if params == nil {
|
||||
return errors.New("'params' required for node installation")
|
||||
}
|
||||
nodeParams, ok := params.(*NodeParams)
|
||||
if !ok {
|
||||
return errors.New("'params' should be *NodeParams")
|
||||
}
|
||||
err := nodeParams.Validate()
|
||||
if err != nil {
|
||||
return errors.New("params validation: " + err.Error())
|
||||
}
|
||||
|
||||
// 安装助手
|
||||
env, err := this.InstallHelper(dir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 上传安装文件
|
||||
filePrefix := "edge-node-" + env.OS + "-" + env.Arch
|
||||
zipFile, err := this.LookupLatestInstaller(filePrefix)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(zipFile) == 0 {
|
||||
return errors.New("can not find installer file for " + env.OS + "/" + env.Arch)
|
||||
}
|
||||
targetZip := dir + "/" + filepath.Base(zipFile)
|
||||
err = this.client.Copy(zipFile, targetZip, 0777)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 解压
|
||||
_, stderr, err := this.client.Exec(dir + "/" + env.HelperName + " -cmd=unzip -zip=\"" + targetZip + "\" -target=\"" + dir + "\"")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(stderr) > 0 {
|
||||
return errors.New("unzip installer failed: " + stderr)
|
||||
}
|
||||
|
||||
// 修改配置文件
|
||||
{
|
||||
templateFile := dir + "/edge-node/configs/api.template.yaml"
|
||||
configFile := dir + "/edge-node/configs/api.yaml"
|
||||
data, err := this.client.ReadFile(templateFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data = bytes.ReplaceAll(data, []byte("${endpoint}"), []byte(nodeParams.Endpoint))
|
||||
data = bytes.ReplaceAll(data, []byte("${nodeId}"), []byte(nodeParams.NodeId))
|
||||
data = bytes.ReplaceAll(data, []byte("${nodeSecret}"), []byte(nodeParams.Secret))
|
||||
|
||||
_, err = this.client.WriteFile(configFile, data)
|
||||
if err != nil {
|
||||
return errors.New("write 'configs/api.yaml': " + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// 启动
|
||||
_, stderr, err = this.client.Exec(dir + "/edge-node/bin/edge-node start")
|
||||
if err != nil {
|
||||
return errors.New("start edge node failed: " + err.Error())
|
||||
}
|
||||
|
||||
if len(stderr) > 0 {
|
||||
return errors.New("start edge node failed: " + stderr)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
35
internal/installers/installer_node_test.go
Normal file
35
internal/installers/installer_node_test.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package installers
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestNodeInstaller_Install(t *testing.T) {
|
||||
var installer InstallerInterface = &NodeInstaller{}
|
||||
err := installer.Login(&Credentials{
|
||||
Host: "192.168.2.30",
|
||||
Port: 22,
|
||||
Username: "root",
|
||||
Password: "123456",
|
||||
PrivateKey: "",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// 关闭连接
|
||||
defer func() {
|
||||
err := installer.Close()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}()
|
||||
|
||||
// 安装
|
||||
err = installer.Install("/opt/edge", &NodeParams{
|
||||
Endpoint: "192.168.2.40:8003",
|
||||
NodeId: "313fdb1b90d0a63c736f307b4d1ca358",
|
||||
Secret: "Pl3u5kYqBDZddp7raw6QfHiuGPRCWF54",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
22
internal/installers/params_node.go
Normal file
22
internal/installers/params_node.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package installers
|
||||
|
||||
import "errors"
|
||||
|
||||
type NodeParams struct {
|
||||
Endpoint string
|
||||
NodeId string
|
||||
Secret string
|
||||
}
|
||||
|
||||
func (this *NodeParams) Validate() error {
|
||||
if len(this.Endpoint) == 0 {
|
||||
return errors.New("'endpoint' should not be empty")
|
||||
}
|
||||
if len(this.NodeId) == 0 {
|
||||
return errors.New("'nodeId' should not be empty")
|
||||
}
|
||||
if len(this.Secret) == 0 {
|
||||
return errors.New("'secret' should not be empty")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
149
internal/installers/ssh_client.go
Normal file
149
internal/installers/ssh_client.go
Normal file
@@ -0,0 +1,149 @@
|
||||
package installers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/pkg/sftp"
|
||||
"golang.org/x/crypto/ssh"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type SSHClient struct {
|
||||
raw *ssh.Client
|
||||
sftp *sftp.Client
|
||||
}
|
||||
|
||||
func NewSSHClient(raw *ssh.Client) (*SSHClient, error) {
|
||||
c := &SSHClient{
|
||||
raw: raw,
|
||||
}
|
||||
|
||||
sftpClient, err := sftp.NewClient(raw)
|
||||
if err != nil {
|
||||
_ = c.Close()
|
||||
return nil, err
|
||||
}
|
||||
c.sftp = sftpClient
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// 执行shell命令
|
||||
func (this *SSHClient) Exec(cmd string) (stdout string, stderr string, err error) {
|
||||
session, err := this.raw.NewSession()
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
defer func() {
|
||||
_ = session.Close()
|
||||
}()
|
||||
|
||||
stdoutBuf := bytes.NewBuffer([]byte{})
|
||||
stderrBuf := bytes.NewBuffer([]byte{})
|
||||
session.Stdout = stdoutBuf
|
||||
session.Stderr = stderrBuf
|
||||
err = session.Run(cmd)
|
||||
if err != nil {
|
||||
return stdoutBuf.String(), stderrBuf.String(), err
|
||||
}
|
||||
return strings.TrimRight(stdoutBuf.String(), "\n"), stderrBuf.String(), nil
|
||||
}
|
||||
|
||||
func (this *SSHClient) Listen(network string, addr string) (net.Listener, error) {
|
||||
return this.raw.Listen(network, addr)
|
||||
}
|
||||
|
||||
func (this *SSHClient) Dial(network string, addr string) (net.Conn, error) {
|
||||
return this.raw.Dial(network, addr)
|
||||
}
|
||||
|
||||
func (this *SSHClient) Close() error {
|
||||
if this.sftp != nil {
|
||||
_ = this.sftp.Close()
|
||||
}
|
||||
return this.raw.Close()
|
||||
}
|
||||
|
||||
func (this *SSHClient) OpenFile(path string, flags int) (*sftp.File, error) {
|
||||
return this.sftp.OpenFile(path, flags)
|
||||
}
|
||||
|
||||
func (this *SSHClient) Stat(path string) (os.FileInfo, error) {
|
||||
return this.sftp.Stat(path)
|
||||
}
|
||||
|
||||
func (this *SSHClient) Mkdir(path string) error {
|
||||
return this.sftp.Mkdir(path)
|
||||
}
|
||||
|
||||
func (this *SSHClient) MkdirAll(path string) error {
|
||||
return this.sftp.MkdirAll(path)
|
||||
}
|
||||
|
||||
func (this *SSHClient) Chmod(path string, mode os.FileMode) error {
|
||||
return this.sftp.Chmod(path, mode)
|
||||
}
|
||||
|
||||
// 拷贝文件
|
||||
func (this *SSHClient) Copy(localPath string, remotePath string, mode os.FileMode) error {
|
||||
localFp, err := os.Open(localPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
_ = localFp.Close()
|
||||
}()
|
||||
remoteFp, err := this.sftp.OpenFile(remotePath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
_ = remoteFp.Close()
|
||||
}()
|
||||
_, err = io.Copy(remoteFp, localFp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return this.Chmod(remotePath, mode)
|
||||
}
|
||||
|
||||
// 获取新Session
|
||||
func (this *SSHClient) NewSession() (*ssh.Session, error) {
|
||||
return this.raw.NewSession()
|
||||
}
|
||||
|
||||
// 读取文件内容
|
||||
func (this *SSHClient) ReadFile(path string) ([]byte, error) {
|
||||
fp, err := this.sftp.OpenFile(path, 0444)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
_ = fp.Close()
|
||||
}()
|
||||
|
||||
buffer := bytes.NewBuffer([]byte{})
|
||||
_, err = io.Copy(buffer, fp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buffer.Bytes(), nil
|
||||
}
|
||||
|
||||
// 写入文件内容
|
||||
func (this *SSHClient) WriteFile(path string, data []byte) (n int, err error) {
|
||||
fp, err := this.sftp.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer func() {
|
||||
_ = fp.Close()
|
||||
}()
|
||||
|
||||
n, err = fp.Write(data)
|
||||
return
|
||||
}
|
||||
222
internal/rpc/pb/model_api_node.pb.go
Normal file
222
internal/rpc/pb/model_api_node.pb.go
Normal file
@@ -0,0 +1,222 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.25.0
|
||||
// protoc v3.12.3
|
||||
// source: model_api_node.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// This is a compile-time assertion that a sufficiently up-to-date version
|
||||
// of the legacy proto package is being used.
|
||||
const _ = proto.ProtoPackageIsVersion4
|
||||
|
||||
type APINode struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
IsOn bool `protobuf:"varint,2,opt,name=isOn,proto3" json:"isOn,omitempty"`
|
||||
ClusterId int64 `protobuf:"varint,3,opt,name=clusterId,proto3" json:"clusterId,omitempty"`
|
||||
UniqueId string `protobuf:"bytes,4,opt,name=uniqueId,proto3" json:"uniqueId,omitempty"`
|
||||
Secret string `protobuf:"bytes,5,opt,name=secret,proto3" json:"secret,omitempty"`
|
||||
Name string `protobuf:"bytes,6,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Description string `protobuf:"bytes,7,opt,name=description,proto3" json:"description,omitempty"`
|
||||
Host string `protobuf:"bytes,8,opt,name=host,proto3" json:"host,omitempty"`
|
||||
Port int32 `protobuf:"varint,9,opt,name=port,proto3" json:"port,omitempty"`
|
||||
}
|
||||
|
||||
func (x *APINode) Reset() {
|
||||
*x = APINode{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_model_api_node_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *APINode) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*APINode) ProtoMessage() {}
|
||||
|
||||
func (x *APINode) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_model_api_node_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use APINode.ProtoReflect.Descriptor instead.
|
||||
func (*APINode) Descriptor() ([]byte, []int) {
|
||||
return file_model_api_node_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *APINode) GetId() int64 {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *APINode) GetIsOn() bool {
|
||||
if x != nil {
|
||||
return x.IsOn
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *APINode) GetClusterId() int64 {
|
||||
if x != nil {
|
||||
return x.ClusterId
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *APINode) GetUniqueId() string {
|
||||
if x != nil {
|
||||
return x.UniqueId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *APINode) GetSecret() string {
|
||||
if x != nil {
|
||||
return x.Secret
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *APINode) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *APINode) GetDescription() string {
|
||||
if x != nil {
|
||||
return x.Description
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *APINode) GetHost() string {
|
||||
if x != nil {
|
||||
return x.Host
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *APINode) GetPort() int32 {
|
||||
if x != nil {
|
||||
return x.Port
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var File_model_api_node_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_model_api_node_proto_rawDesc = []byte{
|
||||
0x0a, 0x14, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x61, 0x70, 0x69, 0x5f, 0x6e, 0x6f, 0x64, 0x65,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x22, 0xdd, 0x01, 0x0a, 0x07, 0x41,
|
||||
0x50, 0x49, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x73, 0x4f, 0x6e, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x69, 0x73, 0x4f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c,
|
||||
0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63,
|
||||
0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x6e, 0x69, 0x71,
|
||||
0x75, 0x65, 0x49, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x6e, 0x69, 0x71,
|
||||
0x75, 0x65, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x05,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
|
||||
0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18,
|
||||
0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x09,
|
||||
0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x2f,
|
||||
0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_model_api_node_proto_rawDescOnce sync.Once
|
||||
file_model_api_node_proto_rawDescData = file_model_api_node_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_model_api_node_proto_rawDescGZIP() []byte {
|
||||
file_model_api_node_proto_rawDescOnce.Do(func() {
|
||||
file_model_api_node_proto_rawDescData = protoimpl.X.CompressGZIP(file_model_api_node_proto_rawDescData)
|
||||
})
|
||||
return file_model_api_node_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_model_api_node_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_model_api_node_proto_goTypes = []interface{}{
|
||||
(*APINode)(nil), // 0: pb.APINode
|
||||
}
|
||||
var file_model_api_node_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for method output_type
|
||||
0, // [0:0] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_model_api_node_proto_init() }
|
||||
func file_model_api_node_proto_init() {
|
||||
if File_model_api_node_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_model_api_node_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*APINode); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_model_api_node_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_model_api_node_proto_goTypes,
|
||||
DependencyIndexes: file_model_api_node_proto_depIdxs,
|
||||
MessageInfos: file_model_api_node_proto_msgTypes,
|
||||
}.Build()
|
||||
File_model_api_node_proto = out.File
|
||||
file_model_api_node_proto_rawDesc = nil
|
||||
file_model_api_node_proto_goTypes = nil
|
||||
file_model_api_node_proto_depIdxs = nil
|
||||
}
|
||||
1385
internal/rpc/pb/service_api_node.pb.go
Normal file
1385
internal/rpc/pb/service_api_node.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1066,6 +1066,100 @@ func (x *CountAllEnabledNodesMatchResponse) GetCount() int64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// 修改节点安装状态
|
||||
type UpdateNodeIsInstalledRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
NodeId int64 `protobuf:"varint,1,opt,name=nodeId,proto3" json:"nodeId,omitempty"`
|
||||
IsInstalled bool `protobuf:"varint,2,opt,name=isInstalled,proto3" json:"isInstalled,omitempty"`
|
||||
}
|
||||
|
||||
func (x *UpdateNodeIsInstalledRequest) Reset() {
|
||||
*x = UpdateNodeIsInstalledRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_service_node_proto_msgTypes[22]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *UpdateNodeIsInstalledRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*UpdateNodeIsInstalledRequest) ProtoMessage() {}
|
||||
|
||||
func (x *UpdateNodeIsInstalledRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_service_node_proto_msgTypes[22]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use UpdateNodeIsInstalledRequest.ProtoReflect.Descriptor instead.
|
||||
func (*UpdateNodeIsInstalledRequest) Descriptor() ([]byte, []int) {
|
||||
return file_service_node_proto_rawDescGZIP(), []int{22}
|
||||
}
|
||||
|
||||
func (x *UpdateNodeIsInstalledRequest) GetNodeId() int64 {
|
||||
if x != nil {
|
||||
return x.NodeId
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *UpdateNodeIsInstalledRequest) GetIsInstalled() bool {
|
||||
if x != nil {
|
||||
return x.IsInstalled
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type UpdateNodeIsInstalledResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *UpdateNodeIsInstalledResponse) Reset() {
|
||||
*x = UpdateNodeIsInstalledResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_service_node_proto_msgTypes[23]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *UpdateNodeIsInstalledResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*UpdateNodeIsInstalledResponse) ProtoMessage() {}
|
||||
|
||||
func (x *UpdateNodeIsInstalledResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_service_node_proto_msgTypes[23]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use UpdateNodeIsInstalledResponse.ProtoReflect.Descriptor instead.
|
||||
func (*UpdateNodeIsInstalledResponse) Descriptor() ([]byte, []int) {
|
||||
return file_service_node_proto_rawDescGZIP(), []int{23}
|
||||
}
|
||||
|
||||
var File_service_node_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_service_node_proto_rawDesc = []byte{
|
||||
@@ -1149,64 +1243,78 @@ var file_service_node_proto_rawDesc = []byte{
|
||||
0x41, 0x6c, 0x6c, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x4d,
|
||||
0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05,
|
||||
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75,
|
||||
0x6e, 0x74, 0x32, 0x88, 0x07, 0x0a, 0x0b, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69,
|
||||
0x63, 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65,
|
||||
0x12, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65,
|
||||
0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x59, 0x0a, 0x14, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x6c, 0x6c, 0x45, 0x6e, 0x61, 0x62, 0x6c,
|
||||
0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x1f, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x75,
|
||||
0x6e, 0x74, 0x41, 0x6c, 0x6c, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65,
|
||||
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f,
|
||||
0x6e, 0x74, 0x22, 0x58, 0x0a, 0x1c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65,
|
||||
0x49, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x03, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x73,
|
||||
0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52,
|
||||
0x0b, 0x69, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x22, 0x1f, 0x0a, 0x1d,
|
||||
0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x73, 0x49, 0x6e, 0x73, 0x74,
|
||||
0x61, 0x6c, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xe6, 0x07,
|
||||
0x0a, 0x0b, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3b, 0x0a,
|
||||
0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x15, 0x2e, 0x70, 0x62,
|
||||
0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x6f,
|
||||
0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x14, 0x63, 0x6f,
|
||||
0x75, 0x6e, 0x74, 0x41, 0x6c, 0x6c, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64,
|
||||
0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x68, 0x0a, 0x19, 0x63, 0x6f,
|
||||
0x65, 0x73, 0x12, 0x1f, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x6c, 0x6c,
|
||||
0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x6c,
|
||||
0x6c, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x68, 0x0a, 0x19, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x6c,
|
||||
0x6c, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x4d, 0x61, 0x74,
|
||||
0x63, 0x68, 0x12, 0x24, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x6c, 0x6c,
|
||||
0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x4d, 0x61, 0x74, 0x63,
|
||||
0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f,
|
||||
0x75, 0x6e, 0x74, 0x41, 0x6c, 0x6c, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64,
|
||||
0x65, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x24, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x75,
|
||||
0x6e, 0x74, 0x41, 0x6c, 0x6c, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65,
|
||||
0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e,
|
||||
0x70, 0x62, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x6c, 0x6c, 0x45, 0x6e, 0x61, 0x62, 0x6c,
|
||||
0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x15, 0x6c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x61, 0x62,
|
||||
0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x20, 0x2e,
|
||||
0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f,
|
||||
0x64, 0x65, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x21, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64,
|
||||
0x4e, 0x6f, 0x64, 0x65, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x64,
|
||||
0x65, 0x12, 0x16, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f,
|
||||
0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x44,
|
||||
0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65,
|
||||
0x12, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64,
|
||||
0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x4a, 0x0a, 0x0f, 0x66, 0x69, 0x6e, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f,
|
||||
0x64, 0x65, 0x12, 0x1a, 0x2e, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x45, 0x6e, 0x61, 0x62,
|
||||
0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b,
|
||||
0x2e, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e,
|
||||
0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x11, 0x63,
|
||||
0x65, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x5c, 0x0a, 0x15, 0x6c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f,
|
||||
0x64, 0x65, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x20, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69,
|
||||
0x73, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x4d, 0x61,
|
||||
0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x70, 0x62, 0x2e,
|
||||
0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73,
|
||||
0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a,
|
||||
0x0b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x2e, 0x70,
|
||||
0x62, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x70, 0x62, 0x2e, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c,
|
||||
0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a,
|
||||
0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x15, 0x2e, 0x70, 0x62,
|
||||
0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f,
|
||||
0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x0f, 0x66, 0x69,
|
||||
0x6e, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x1a, 0x2e,
|
||||
0x70, 0x62, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f,
|
||||
0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x70, 0x62, 0x2e, 0x46,
|
||||
0x69, 0x6e, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x73,
|
||||
0x65, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1c, 0x2e, 0x70, 0x62,
|
||||
0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66,
|
||||
0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x62, 0x2e, 0x43,
|
||||
0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||
0x12, 0x1c, 0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x65, 0x4e, 0x6f, 0x64,
|
||||
0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d,
|
||||
0x2e, 0x70, 0x62, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x43,
|
||||
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a,
|
||||
0x0a, 0x6e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x15, 0x2e, 0x70, 0x62,
|
||||
0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x16, 0x2e, 0x70, 0x62, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x72, 0x65,
|
||||
0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x12, 0x4d,
|
||||
0x0a, 0x10, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74,
|
||||
0x75, 0x73, 0x12, 0x1b, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f,
|
||||
0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x1c, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x53,
|
||||
0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a,
|
||||
0x1b, 0x73, 0x79, 0x6e, 0x63, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x57, 0x69, 0x74, 0x68, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x26, 0x2e, 0x70,
|
||||
0x62, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x57, 0x69, 0x74, 0x68, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4e, 0x6f,
|
||||
0x64, 0x65, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x57, 0x69, 0x74, 0x68, 0x43, 0x6c,
|
||||
0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x06, 0x5a,
|
||||
0x04, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x0a, 0x6e, 0x6f, 0x64, 0x65,
|
||||
0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x15, 0x2e, 0x70, 0x62, 0x2e, 0x4e, 0x6f, 0x64, 0x65,
|
||||
0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e,
|
||||
0x70, 0x62, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x12, 0x4d, 0x0a, 0x10, 0x75, 0x70, 0x64,
|
||||
0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1b, 0x2e,
|
||||
0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61,
|
||||
0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x70, 0x62, 0x2e,
|
||||
0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, 0x1b, 0x73, 0x79, 0x6e, 0x63,
|
||||
0x4e, 0x6f, 0x64, 0x65, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x57, 0x69, 0x74, 0x68,
|
||||
0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x26, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x79, 0x6e,
|
||||
0x63, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x57, 0x69, 0x74,
|
||||
0x68, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x27, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x56, 0x65,
|
||||
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x57, 0x69, 0x74, 0x68, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x15, 0x75, 0x70, 0x64, 0x61,
|
||||
0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65,
|
||||
0x64, 0x12, 0x20, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64,
|
||||
0x65, 0x49, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x70, 0x62, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e,
|
||||
0x6f, 0x64, 0x65, 0x49, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -1221,7 +1329,7 @@ func file_service_node_proto_rawDescGZIP() []byte {
|
||||
return file_service_node_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_service_node_proto_msgTypes = make([]protoimpl.MessageInfo, 22)
|
||||
var file_service_node_proto_msgTypes = make([]protoimpl.MessageInfo, 24)
|
||||
var file_service_node_proto_goTypes = []interface{}{
|
||||
(*CreateNodeRequest)(nil), // 0: pb.CreateNodeRequest
|
||||
(*CreateNodeResponse)(nil), // 1: pb.CreateNodeResponse
|
||||
@@ -1245,14 +1353,16 @@ var file_service_node_proto_goTypes = []interface{}{
|
||||
(*SyncNodesVersionWithClusterResponse)(nil), // 19: pb.SyncNodesVersionWithClusterResponse
|
||||
(*CountAllEnabledNodesMatchRequest)(nil), // 20: pb.CountAllEnabledNodesMatchRequest
|
||||
(*CountAllEnabledNodesMatchResponse)(nil), // 21: pb.CountAllEnabledNodesMatchResponse
|
||||
(*NodeLogin)(nil), // 22: pb.NodeLogin
|
||||
(*Node)(nil), // 23: pb.Node
|
||||
(*UpdateNodeIsInstalledRequest)(nil), // 22: pb.UpdateNodeIsInstalledRequest
|
||||
(*UpdateNodeIsInstalledResponse)(nil), // 23: pb.UpdateNodeIsInstalledResponse
|
||||
(*NodeLogin)(nil), // 24: pb.NodeLogin
|
||||
(*Node)(nil), // 25: pb.Node
|
||||
}
|
||||
var file_service_node_proto_depIdxs = []int32{
|
||||
22, // 0: pb.CreateNodeRequest.Login:type_name -> pb.NodeLogin
|
||||
23, // 1: pb.ListEnabledNodesMatchResponse.nodes:type_name -> pb.Node
|
||||
22, // 2: pb.UpdateNodeRequest.Login:type_name -> pb.NodeLogin
|
||||
23, // 3: pb.FindEnabledNodeResponse.node:type_name -> pb.Node
|
||||
24, // 0: pb.CreateNodeRequest.Login:type_name -> pb.NodeLogin
|
||||
25, // 1: pb.ListEnabledNodesMatchResponse.nodes:type_name -> pb.Node
|
||||
24, // 2: pb.UpdateNodeRequest.Login:type_name -> pb.NodeLogin
|
||||
25, // 3: pb.FindEnabledNodeResponse.node:type_name -> pb.Node
|
||||
0, // 4: pb.NodeService.createNode:input_type -> pb.CreateNodeRequest
|
||||
2, // 5: pb.NodeService.countAllEnabledNodes:input_type -> pb.CountAllEnabledNodesRequest
|
||||
20, // 6: pb.NodeService.countAllEnabledNodesMatch:input_type -> pb.CountAllEnabledNodesMatchRequest
|
||||
@@ -1264,19 +1374,21 @@ var file_service_node_proto_depIdxs = []int32{
|
||||
14, // 12: pb.NodeService.nodeStream:input_type -> pb.NodeStreamRequest
|
||||
16, // 13: pb.NodeService.updateNodeStatus:input_type -> pb.UpdateNodeStatusRequest
|
||||
18, // 14: pb.NodeService.syncNodesVersionWithCluster:input_type -> pb.SyncNodesVersionWithClusterRequest
|
||||
1, // 15: pb.NodeService.createNode:output_type -> pb.CreateNodeResponse
|
||||
3, // 16: pb.NodeService.countAllEnabledNodes:output_type -> pb.CountAllEnabledNodesResponse
|
||||
21, // 17: pb.NodeService.countAllEnabledNodesMatch:output_type -> pb.CountAllEnabledNodesMatchResponse
|
||||
5, // 18: pb.NodeService.listEnabledNodesMatch:output_type -> pb.ListEnabledNodesMatchResponse
|
||||
7, // 19: pb.NodeService.disableNode:output_type -> pb.DisableNodeResponse
|
||||
9, // 20: pb.NodeService.updateNode:output_type -> pb.UpdateNodeResponse
|
||||
11, // 21: pb.NodeService.findEnabledNode:output_type -> pb.FindEnabledNodeResponse
|
||||
13, // 22: pb.NodeService.composeNodeConfig:output_type -> pb.ComposeNodeConfigResponse
|
||||
15, // 23: pb.NodeService.nodeStream:output_type -> pb.NodeStreamResponse
|
||||
17, // 24: pb.NodeService.updateNodeStatus:output_type -> pb.UpdateNodeStatusResponse
|
||||
19, // 25: pb.NodeService.syncNodesVersionWithCluster:output_type -> pb.SyncNodesVersionWithClusterResponse
|
||||
15, // [15:26] is the sub-list for method output_type
|
||||
4, // [4:15] is the sub-list for method input_type
|
||||
22, // 15: pb.NodeService.updateNodeIsInstalled:input_type -> pb.UpdateNodeIsInstalledRequest
|
||||
1, // 16: pb.NodeService.createNode:output_type -> pb.CreateNodeResponse
|
||||
3, // 17: pb.NodeService.countAllEnabledNodes:output_type -> pb.CountAllEnabledNodesResponse
|
||||
21, // 18: pb.NodeService.countAllEnabledNodesMatch:output_type -> pb.CountAllEnabledNodesMatchResponse
|
||||
5, // 19: pb.NodeService.listEnabledNodesMatch:output_type -> pb.ListEnabledNodesMatchResponse
|
||||
7, // 20: pb.NodeService.disableNode:output_type -> pb.DisableNodeResponse
|
||||
9, // 21: pb.NodeService.updateNode:output_type -> pb.UpdateNodeResponse
|
||||
11, // 22: pb.NodeService.findEnabledNode:output_type -> pb.FindEnabledNodeResponse
|
||||
13, // 23: pb.NodeService.composeNodeConfig:output_type -> pb.ComposeNodeConfigResponse
|
||||
15, // 24: pb.NodeService.nodeStream:output_type -> pb.NodeStreamResponse
|
||||
17, // 25: pb.NodeService.updateNodeStatus:output_type -> pb.UpdateNodeStatusResponse
|
||||
19, // 26: pb.NodeService.syncNodesVersionWithCluster:output_type -> pb.SyncNodesVersionWithClusterResponse
|
||||
23, // 27: pb.NodeService.updateNodeIsInstalled:output_type -> pb.UpdateNodeIsInstalledResponse
|
||||
16, // [16:28] is the sub-list for method output_type
|
||||
4, // [4:16] is the sub-list for method input_type
|
||||
4, // [4:4] is the sub-list for extension type_name
|
||||
4, // [4:4] is the sub-list for extension extendee
|
||||
0, // [0:4] is the sub-list for field type_name
|
||||
@@ -1554,6 +1666,30 @@ func file_service_node_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_service_node_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*UpdateNodeIsInstalledRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_service_node_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*UpdateNodeIsInstalledResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
@@ -1561,7 +1697,7 @@ func file_service_node_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_service_node_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 22,
|
||||
NumMessages: 24,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
@@ -1609,6 +1745,8 @@ type NodeServiceClient interface {
|
||||
UpdateNodeStatus(ctx context.Context, in *UpdateNodeStatusRequest, opts ...grpc.CallOption) (*UpdateNodeStatusResponse, error)
|
||||
// 同步集群中的节点版本
|
||||
SyncNodesVersionWithCluster(ctx context.Context, in *SyncNodesVersionWithClusterRequest, opts ...grpc.CallOption) (*SyncNodesVersionWithClusterResponse, error)
|
||||
// 修改节点安装状态
|
||||
UpdateNodeIsInstalled(ctx context.Context, in *UpdateNodeIsInstalledRequest, opts ...grpc.CallOption) (*UpdateNodeIsInstalledResponse, error)
|
||||
}
|
||||
|
||||
type nodeServiceClient struct {
|
||||
@@ -1740,6 +1878,15 @@ func (c *nodeServiceClient) SyncNodesVersionWithCluster(ctx context.Context, in
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *nodeServiceClient) UpdateNodeIsInstalled(ctx context.Context, in *UpdateNodeIsInstalledRequest, opts ...grpc.CallOption) (*UpdateNodeIsInstalledResponse, error) {
|
||||
out := new(UpdateNodeIsInstalledResponse)
|
||||
err := c.cc.Invoke(ctx, "/pb.NodeService/updateNodeIsInstalled", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// NodeServiceServer is the server API for NodeService service.
|
||||
type NodeServiceServer interface {
|
||||
// 创建节点
|
||||
@@ -1764,6 +1911,8 @@ type NodeServiceServer interface {
|
||||
UpdateNodeStatus(context.Context, *UpdateNodeStatusRequest) (*UpdateNodeStatusResponse, error)
|
||||
// 同步集群中的节点版本
|
||||
SyncNodesVersionWithCluster(context.Context, *SyncNodesVersionWithClusterRequest) (*SyncNodesVersionWithClusterResponse, error)
|
||||
// 修改节点安装状态
|
||||
UpdateNodeIsInstalled(context.Context, *UpdateNodeIsInstalledRequest) (*UpdateNodeIsInstalledResponse, error)
|
||||
}
|
||||
|
||||
// UnimplementedNodeServiceServer can be embedded to have forward compatible implementations.
|
||||
@@ -1803,6 +1952,9 @@ func (*UnimplementedNodeServiceServer) UpdateNodeStatus(context.Context, *Update
|
||||
func (*UnimplementedNodeServiceServer) SyncNodesVersionWithCluster(context.Context, *SyncNodesVersionWithClusterRequest) (*SyncNodesVersionWithClusterResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method SyncNodesVersionWithCluster not implemented")
|
||||
}
|
||||
func (*UnimplementedNodeServiceServer) UpdateNodeIsInstalled(context.Context, *UpdateNodeIsInstalledRequest) (*UpdateNodeIsInstalledResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method UpdateNodeIsInstalled not implemented")
|
||||
}
|
||||
|
||||
func RegisterNodeServiceServer(s *grpc.Server, srv NodeServiceServer) {
|
||||
s.RegisterService(&_NodeService_serviceDesc, srv)
|
||||
@@ -2014,6 +2166,24 @@ func _NodeService_SyncNodesVersionWithCluster_Handler(srv interface{}, ctx conte
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _NodeService_UpdateNodeIsInstalled_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(UpdateNodeIsInstalledRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(NodeServiceServer).UpdateNodeIsInstalled(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/pb.NodeService/UpdateNodeIsInstalled",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(NodeServiceServer).UpdateNodeIsInstalled(ctx, req.(*UpdateNodeIsInstalledRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _NodeService_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "pb.NodeService",
|
||||
HandlerType: (*NodeServiceServer)(nil),
|
||||
@@ -2058,6 +2228,10 @@ var _NodeService_serviceDesc = grpc.ServiceDesc{
|
||||
MethodName: "syncNodesVersionWithCluster",
|
||||
Handler: _NodeService_SyncNodesVersionWithCluster_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "updateNodeIsInstalled",
|
||||
Handler: _NodeService_UpdateNodeIsInstalled_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
|
||||
16
internal/rpc/protos/model_api_node.proto
Normal file
16
internal/rpc/protos/model_api_node.proto
Normal file
@@ -0,0 +1,16 @@
|
||||
syntax = "proto3";
|
||||
option go_package = "./pb";
|
||||
|
||||
package pb;
|
||||
|
||||
message APINode {
|
||||
int64 id = 1;
|
||||
bool isOn = 2;
|
||||
int64 clusterId = 3;
|
||||
string uniqueId = 4;
|
||||
string secret = 5;
|
||||
string name = 6;
|
||||
string description = 7;
|
||||
string host = 8;
|
||||
int32 port = 9;
|
||||
}
|
||||
99
internal/rpc/protos/service_api_node.proto
Normal file
99
internal/rpc/protos/service_api_node.proto
Normal file
@@ -0,0 +1,99 @@
|
||||
syntax = "proto3";
|
||||
option go_package = "./pb";
|
||||
|
||||
package pb;
|
||||
import "model_api_node.proto";
|
||||
|
||||
service APINodeService {
|
||||
// 创建API节点
|
||||
rpc createAPINode (CreateAPINodeRequest) returns (CreateAPINodeResponse);
|
||||
|
||||
// 修改API节点
|
||||
rpc updateAPINode (UpdateAPINodeRequest) returns (UpdateAPINodeResponse);
|
||||
|
||||
// 删除API节点
|
||||
rpc deleteAPINode (DeleteAPINodeRequest) returns (DeleteAPINodeResponse);
|
||||
|
||||
// 列出所有可用API节点
|
||||
rpc findAllEnabledAPINodes (FindAllEnabledAPINodesRequest) returns (FindAllEnabledAPINodesResponse);
|
||||
|
||||
// 计算API节点数量
|
||||
rpc countAllEnabledAPINodes (CountAllEnabledAPINodesRequest) returns (CountAllEnabledAPINodesResponse);
|
||||
|
||||
// 列出单页的API节点
|
||||
rpc listEnabledAPINodes (ListEnabledAPINodesRequest) returns (ListEnabledAPINodesResponse);
|
||||
|
||||
// 根据ID查找节点
|
||||
rpc findEnabledAPINode (FindEnabledAPINodeRequest) returns (FindEnabledAPINodeResponse);
|
||||
}
|
||||
|
||||
// 创建API节点
|
||||
message CreateAPINodeRequest {
|
||||
string name = 1;
|
||||
string description = 2;
|
||||
string host = 3;
|
||||
int32 port = 4;
|
||||
}
|
||||
|
||||
message CreateAPINodeResponse {
|
||||
int64 nodeId = 1;
|
||||
}
|
||||
|
||||
// 修改API节点
|
||||
message UpdateAPINodeRequest {
|
||||
int64 nodeId = 1;
|
||||
string name = 2;
|
||||
string description = 3;
|
||||
string host = 4;
|
||||
int32 port = 5;
|
||||
}
|
||||
|
||||
message UpdateAPINodeResponse {
|
||||
|
||||
}
|
||||
|
||||
// 删除API节点
|
||||
message DeleteAPINodeRequest {
|
||||
int64 nodeId = 1;
|
||||
}
|
||||
|
||||
message DeleteAPINodeResponse {
|
||||
|
||||
}
|
||||
|
||||
// 列出所有可用API节点
|
||||
message FindAllEnabledAPINodesRequest {
|
||||
|
||||
}
|
||||
|
||||
message FindAllEnabledAPINodesResponse {
|
||||
repeated APINode nodes = 1;
|
||||
}
|
||||
|
||||
// 计算API节点数量
|
||||
message CountAllEnabledAPINodesRequest {
|
||||
|
||||
}
|
||||
|
||||
message CountAllEnabledAPINodesResponse {
|
||||
int64 count = 1;
|
||||
}
|
||||
|
||||
// 列出单页的API节点
|
||||
message ListEnabledAPINodesRequest {
|
||||
int64 offset = 1;
|
||||
int64 size = 2;
|
||||
}
|
||||
|
||||
message ListEnabledAPINodesResponse {
|
||||
repeated APINode nodes = 1;
|
||||
}
|
||||
|
||||
// 根据ID查找节点
|
||||
message FindEnabledAPINodeRequest {
|
||||
int64 nodeId = 1;
|
||||
}
|
||||
|
||||
message FindEnabledAPINodeResponse {
|
||||
APINode node = 1;
|
||||
}
|
||||
@@ -38,6 +38,9 @@ service NodeService {
|
||||
|
||||
// 同步集群中的节点版本
|
||||
rpc syncNodesVersionWithCluster (SyncNodesVersionWithClusterRequest) returns (SyncNodesVersionWithClusterResponse);
|
||||
|
||||
// 修改节点安装状态
|
||||
rpc updateNodeIsInstalled (UpdateNodeIsInstalledRequest) returns (UpdateNodeIsInstalledResponse);
|
||||
}
|
||||
|
||||
// 创建节点
|
||||
@@ -144,4 +147,14 @@ message CountAllEnabledNodesMatchRequest {
|
||||
|
||||
message CountAllEnabledNodesMatchResponse {
|
||||
int64 count = 1;
|
||||
}
|
||||
|
||||
// 修改节点安装状态
|
||||
message UpdateNodeIsInstalledRequest {
|
||||
int64 nodeId = 1;
|
||||
bool isInstalled = 2;
|
||||
}
|
||||
|
||||
message UpdateNodeIsInstalledResponse {
|
||||
|
||||
}
|
||||
161
internal/rpc/services/service_api_node.go
Normal file
161
internal/rpc/services/service_api_node.go
Normal file
@@ -0,0 +1,161 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/rpc/pb"
|
||||
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
|
||||
)
|
||||
|
||||
type APINodeService struct {
|
||||
}
|
||||
|
||||
// 创建API节点
|
||||
func (this *APINodeService) CreateAPINode(ctx context.Context, req *pb.CreateAPINodeRequest) (*pb.CreateAPINodeResponse, error) {
|
||||
_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nodeId, err := models.SharedAPINodeDAO.CreateAPINode(req.Name, req.Description, req.Host, int(req.Port))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.CreateAPINodeResponse{NodeId: nodeId}, nil
|
||||
}
|
||||
|
||||
// 修改API节点
|
||||
func (this *APINodeService) UpdateAPINode(ctx context.Context, req *pb.UpdateAPINodeRequest) (*pb.UpdateAPINodeResponse, error) {
|
||||
_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = models.SharedAPINodeDAO.UpdateAPINode(req.NodeId, req.Name, req.Description, req.Host, int(req.Port))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.UpdateAPINodeResponse{}, nil
|
||||
}
|
||||
|
||||
// 删除API节点
|
||||
func (this *APINodeService) DeleteAPINode(ctx context.Context, req *pb.DeleteAPINodeRequest) (*pb.DeleteAPINodeResponse, error) {
|
||||
_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = models.SharedAPINodeDAO.DisableAPINode(req.NodeId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.DeleteAPINodeResponse{}, nil
|
||||
}
|
||||
|
||||
// 列出所有可用API节点
|
||||
func (this *APINodeService) FindAllEnabledAPINodes(ctx context.Context, req *pb.FindAllEnabledAPINodesRequest) (*pb.FindAllEnabledAPINodesResponse, error) {
|
||||
_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nodes, err := models.SharedAPINodeDAO.FindAllEnabledAPINodes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := []*pb.APINode{}
|
||||
for _, node := range nodes {
|
||||
result = append(result, &pb.APINode{
|
||||
Id: int64(node.Id),
|
||||
IsOn: node.IsOn == 1,
|
||||
ClusterId: int64(node.ClusterId),
|
||||
UniqueId: node.UniqueId,
|
||||
Secret: node.Secret,
|
||||
Name: node.Name,
|
||||
Description: node.Description,
|
||||
Host: node.Host,
|
||||
Port: int32(node.Port),
|
||||
})
|
||||
}
|
||||
|
||||
return &pb.FindAllEnabledAPINodesResponse{Nodes: result}, nil
|
||||
}
|
||||
|
||||
// 计算API节点数量
|
||||
func (this *APINodeService) CountAllEnabledAPINodes(ctx context.Context, req *pb.CountAllEnabledAPINodesRequest) (*pb.CountAllEnabledAPINodesResponse, error) {
|
||||
_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
count, err := models.SharedAPINodeDAO.CountAllEnabledAPINodes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.CountAllEnabledAPINodesResponse{Count: count}, nil
|
||||
}
|
||||
|
||||
// 列出单页的API节点
|
||||
func (this *APINodeService) ListEnabledAPINodes(ctx context.Context, req *pb.ListEnabledAPINodesRequest) (*pb.ListEnabledAPINodesResponse, error) {
|
||||
_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nodes, err := models.SharedAPINodeDAO.ListEnabledAPINodes(req.Offset, req.Size)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := []*pb.APINode{}
|
||||
for _, node := range nodes {
|
||||
result = append(result, &pb.APINode{
|
||||
Id: int64(node.Id),
|
||||
IsOn: node.IsOn == 1,
|
||||
ClusterId: int64(node.ClusterId),
|
||||
UniqueId: node.UniqueId,
|
||||
Secret: node.Secret,
|
||||
Name: node.Name,
|
||||
Description: node.Description,
|
||||
Host: node.Host,
|
||||
Port: int32(node.Port),
|
||||
})
|
||||
}
|
||||
|
||||
return &pb.ListEnabledAPINodesResponse{Nodes: result}, nil
|
||||
}
|
||||
|
||||
// 根据ID查找节点
|
||||
func (this *APINodeService) FindEnabledAPINode(ctx context.Context, req *pb.FindEnabledAPINodeRequest) (*pb.FindEnabledAPINodeResponse, error) {
|
||||
_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
node, err := models.SharedAPINodeDAO.FindEnabledAPINode(req.NodeId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if node == nil {
|
||||
return &pb.FindEnabledAPINodeResponse{Node: nil}, nil
|
||||
}
|
||||
|
||||
result := &pb.APINode{
|
||||
Id: int64(node.Id),
|
||||
IsOn: node.IsOn == 1,
|
||||
ClusterId: int64(node.ClusterId),
|
||||
UniqueId: node.UniqueId,
|
||||
Secret: node.Secret,
|
||||
Name: node.Name,
|
||||
Description: node.Description,
|
||||
Host: node.Host,
|
||||
Port: int32(node.Port),
|
||||
}
|
||||
return &pb.FindEnabledAPINodeResponse{Node: result}, nil
|
||||
}
|
||||
@@ -308,3 +308,18 @@ func (this *NodeService) SyncNodesVersionWithCluster(ctx context.Context, req *p
|
||||
|
||||
return &pb.SyncNodesVersionWithClusterResponse{}, nil
|
||||
}
|
||||
|
||||
// 修改节点安装状态
|
||||
func (this *NodeService) UpdateNodeIsInstalled(ctx context.Context, req *pb.UpdateNodeIsInstalledRequest) (*pb.UpdateNodeIsInstalledResponse, error) {
|
||||
_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = models.SharedNodeDAO.UpdateNodeIsInstalled(req.NodeId, req.IsInstalled)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.UpdateNodeIsInstalledResponse{}, nil
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ func ValidateRequest(ctx context.Context, userTypes ...UserType) (userType UserT
|
||||
nodeId := nodeIds[0]
|
||||
|
||||
// 获取角色Node信息
|
||||
// TODO 缓存节点ID相关信息
|
||||
apiToken, err := models.SharedApiTokenDAO.FindEnabledTokenWithNode(nodeId)
|
||||
if err != nil {
|
||||
utils.PrintError(err)
|
||||
|
||||
91
internal/utils/unzip.go
Normal file
91
internal/utils/unzip.go
Normal file
@@ -0,0 +1,91 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Unzip struct {
|
||||
zipFile string
|
||||
targetDir string
|
||||
}
|
||||
|
||||
func NewUnzip(zipFile string, targetDir string) *Unzip {
|
||||
return &Unzip{
|
||||
zipFile: zipFile,
|
||||
targetDir: targetDir,
|
||||
}
|
||||
}
|
||||
|
||||
func (this *Unzip) Run() error {
|
||||
if len(this.zipFile) == 0 {
|
||||
return errors.New("zip file should not be empty")
|
||||
}
|
||||
if len(this.targetDir) == 0 {
|
||||
return errors.New("target dir should not be empty")
|
||||
}
|
||||
|
||||
reader, err := zip.OpenReader(this.zipFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
_ = reader.Close()
|
||||
}()
|
||||
|
||||
for _, file := range reader.File {
|
||||
info := file.FileInfo()
|
||||
target := this.targetDir + "/" + file.Name
|
||||
|
||||
// 目录
|
||||
if info.IsDir() {
|
||||
stat, err := os.Stat(target)
|
||||
if err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
return err
|
||||
} else {
|
||||
err = os.MkdirAll(target, info.Mode())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else if !stat.IsDir() {
|
||||
err = os.MkdirAll(target, info.Mode())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// 文件
|
||||
err := func(file *zip.File, target string) error {
|
||||
fileReader, err := file.Open()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
_ = fileReader.Close()
|
||||
}()
|
||||
|
||||
fileWriter, err := os.OpenFile(target, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, file.FileInfo().Mode())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
_ = fileWriter.Close()
|
||||
}()
|
||||
|
||||
_, err = io.Copy(fileWriter, fileReader)
|
||||
return err
|
||||
}(file, target)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
16
internal/utils/unzip_test.go
Normal file
16
internal/utils/unzip_test.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
_ "github.com/iwind/TeaGo/bootstrap"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestUnzip_Run(t *testing.T) {
|
||||
unzip := NewUnzip(Tea.Root+"/deploy/edge-node-v0.0.1.zip", Tea.Root+"/deploy/")
|
||||
err := unzip.Run()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log("OK")
|
||||
}
|
||||
Reference in New Issue
Block a user