mirror of
				https://github.com/TeaOSLab/EdgeAdmin.git
				synced 2025-11-04 05:00:25 +08:00 
			
		
		
		
	阶段性提交
This commit is contained in:
		
							
								
								
									
										2
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
									
									
									
									
								
							@@ -6,7 +6,7 @@ require (
 | 
			
		||||
	github.com/go-redis/redis v6.15.8+incompatible // indirect
 | 
			
		||||
	github.com/go-yaml/yaml v2.1.0+incompatible
 | 
			
		||||
	github.com/golang/protobuf v1.4.2
 | 
			
		||||
	github.com/iwind/TeaGo v0.0.0-20200816132655-f784df8e9c42
 | 
			
		||||
	github.com/iwind/TeaGo v0.0.0-20200822074248-b1cf7248c98a
 | 
			
		||||
	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 | 
			
		||||
	github.com/modern-go/reflect2 v1.0.1 // indirect
 | 
			
		||||
	github.com/pquerna/ffjson v0.0.0-20190930134022-aa0246cd15f7 // indirect
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.sum
									
									
									
									
									
								
							@@ -47,6 +47,8 @@ github.com/iwind/TeaGo v0.0.0-20200723131229-30dff10543ad h1:EVwLRNPYoCNCinN/J9F
 | 
			
		||||
github.com/iwind/TeaGo v0.0.0-20200723131229-30dff10543ad/go.mod h1:zjM7k+b+Jthhf0T0fKwuF0iy4TWb5SsU1gmKR2l+OmE=
 | 
			
		||||
github.com/iwind/TeaGo v0.0.0-20200816132655-f784df8e9c42 h1:X58QYxjoTstHR4sQEwx4ChAFRYtlWAfqwimQ3d2osT0=
 | 
			
		||||
github.com/iwind/TeaGo v0.0.0-20200816132655-f784df8e9c42/go.mod h1:KU4mS7QNiZ7QWEuDBk1zw0/Q2LrAPZv3tycEFBsuUwc=
 | 
			
		||||
github.com/iwind/TeaGo v0.0.0-20200822074248-b1cf7248c98a h1:VaWcMNOzHHT1y8MeTA2fWhG6GEfAdy6CwF2tW+KiY5Y=
 | 
			
		||||
github.com/iwind/TeaGo v0.0.0-20200822074248-b1cf7248c98a/go.mod h1:KU4mS7QNiZ7QWEuDBk1zw0/Q2LrAPZv3tycEFBsuUwc=
 | 
			
		||||
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
 | 
			
		||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 | 
			
		||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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
 | 
			
		||||
}
 | 
			
		||||
@@ -30,11 +30,16 @@ type Node struct {
 | 
			
		||||
	sizeCache     protoimpl.SizeCache
 | 
			
		||||
	unknownFields protoimpl.UnknownFields
 | 
			
		||||
 | 
			
		||||
	Id      int64        `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
 | 
			
		||||
	Name    string       `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
 | 
			
		||||
	Status  string       `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"`
 | 
			
		||||
	Cluster *NodeCluster `protobuf:"bytes,32,opt,name=cluster,proto3" json:"cluster,omitempty"`
 | 
			
		||||
	Login   *NodeLogin   `protobuf:"bytes,33,opt,name=login,proto3" json:"login,omitempty"`
 | 
			
		||||
	Id          int64        `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
 | 
			
		||||
	Name        string       `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
 | 
			
		||||
	Status      string       `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"`
 | 
			
		||||
	InstallDir  string       `protobuf:"bytes,4,opt,name=installDir,proto3" json:"installDir,omitempty"`
 | 
			
		||||
	IsInstalled bool         `protobuf:"varint,5,opt,name=isInstalled,proto3" json:"isInstalled,omitempty"`
 | 
			
		||||
	Code        string       `protobuf:"bytes,6,opt,name=code,proto3" json:"code,omitempty"`
 | 
			
		||||
	UniqueId    string       `protobuf:"bytes,7,opt,name=uniqueId,proto3" json:"uniqueId,omitempty"`
 | 
			
		||||
	Secret      string       `protobuf:"bytes,8,opt,name=secret,proto3" json:"secret,omitempty"`
 | 
			
		||||
	Cluster     *NodeCluster `protobuf:"bytes,32,opt,name=cluster,proto3" json:"cluster,omitempty"`
 | 
			
		||||
	Login       *NodeLogin   `protobuf:"bytes,33,opt,name=login,proto3" json:"login,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *Node) Reset() {
 | 
			
		||||
@@ -90,6 +95,41 @@ func (x *Node) GetStatus() string {
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *Node) GetInstallDir() string {
 | 
			
		||||
	if x != nil {
 | 
			
		||||
		return x.InstallDir
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *Node) GetIsInstalled() bool {
 | 
			
		||||
	if x != nil {
 | 
			
		||||
		return x.IsInstalled
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *Node) GetCode() string {
 | 
			
		||||
	if x != nil {
 | 
			
		||||
		return x.Code
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *Node) GetUniqueId() string {
 | 
			
		||||
	if x != nil {
 | 
			
		||||
		return x.UniqueId
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *Node) GetSecret() string {
 | 
			
		||||
	if x != nil {
 | 
			
		||||
		return x.Secret
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *Node) GetCluster() *NodeCluster {
 | 
			
		||||
	if x != nil {
 | 
			
		||||
		return x.Cluster
 | 
			
		||||
@@ -111,17 +151,26 @@ var file_model_node_proto_rawDesc = []byte{
 | 
			
		||||
	0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x1a, 0x18, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x6e, 0x6f,
 | 
			
		||||
	0x64, 0x65, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
 | 
			
		||||
	0x1a, 0x16, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6c, 0x6f, 0x67,
 | 
			
		||||
	0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x92, 0x01, 0x0a, 0x04, 0x4e, 0x6f, 0x64,
 | 
			
		||||
	0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9c, 0x02, 0x0a, 0x04, 0x4e, 0x6f, 0x64,
 | 
			
		||||
	0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69,
 | 
			
		||||
	0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
 | 
			
		||||
	0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18,
 | 
			
		||||
	0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x29, 0x0a,
 | 
			
		||||
	0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x20, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f,
 | 
			
		||||
	0x2e, 0x70, 0x62, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52,
 | 
			
		||||
	0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x05, 0x6c, 0x6f, 0x67, 0x69,
 | 
			
		||||
	0x6e, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x62, 0x2e, 0x4e, 0x6f, 0x64,
 | 
			
		||||
	0x65, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x05, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x42, 0x06, 0x5a,
 | 
			
		||||
	0x04, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 | 
			
		||||
	0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1e, 0x0a,
 | 
			
		||||
	0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x44, 0x69, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28,
 | 
			
		||||
	0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x44, 0x69, 0x72, 0x12, 0x20, 0x0a,
 | 
			
		||||
	0x0b, 0x69, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01,
 | 
			
		||||
	0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x12,
 | 
			
		||||
	0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63,
 | 
			
		||||
	0x6f, 0x64, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x49, 0x64, 0x18,
 | 
			
		||||
	0x07, 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, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52,
 | 
			
		||||
	0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x29, 0x0a, 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74,
 | 
			
		||||
	0x65, 0x72, 0x18, 0x20, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x62, 0x2e, 0x4e, 0x6f,
 | 
			
		||||
	0x64, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74,
 | 
			
		||||
	0x65, 0x72, 0x12, 0x23, 0x0a, 0x05, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x18, 0x21, 0x20, 0x01, 0x28,
 | 
			
		||||
	0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x62, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x6f, 0x67, 0x69, 0x6e,
 | 
			
		||||
	0x52, 0x05, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x2f, 0x70, 0x62, 0x62,
 | 
			
		||||
	0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
 
 | 
			
		||||
@@ -30,9 +30,11 @@ type NodeCluster struct {
 | 
			
		||||
	sizeCache     protoimpl.SizeCache
 | 
			
		||||
	unknownFields protoimpl.UnknownFields
 | 
			
		||||
 | 
			
		||||
	Id        int64  `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
 | 
			
		||||
	Name      string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
 | 
			
		||||
	CreatedAt int64  `protobuf:"varint,3,opt,name=createdAt,proto3" json:"createdAt,omitempty"`
 | 
			
		||||
	Id         int64  `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
 | 
			
		||||
	Name       string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
 | 
			
		||||
	CreatedAt  int64  `protobuf:"varint,3,opt,name=createdAt,proto3" json:"createdAt,omitempty"`
 | 
			
		||||
	GrantId    int64  `protobuf:"varint,4,opt,name=grantId,proto3" json:"grantId,omitempty"`
 | 
			
		||||
	InstallDir string `protobuf:"bytes,5,opt,name=installDir,proto3" json:"installDir,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *NodeCluster) Reset() {
 | 
			
		||||
@@ -88,17 +90,35 @@ func (x *NodeCluster) GetCreatedAt() int64 {
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *NodeCluster) GetGrantId() int64 {
 | 
			
		||||
	if x != nil {
 | 
			
		||||
		return x.GrantId
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *NodeCluster) GetInstallDir() string {
 | 
			
		||||
	if x != nil {
 | 
			
		||||
		return x.InstallDir
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var File_model_node_cluster_proto protoreflect.FileDescriptor
 | 
			
		||||
 | 
			
		||||
var file_model_node_cluster_proto_rawDesc = []byte{
 | 
			
		||||
	0x0a, 0x18, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x63, 0x6c, 0x75,
 | 
			
		||||
	0x73, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x22, 0x4f,
 | 
			
		||||
	0x0a, 0x0b, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x0e, 0x0a,
 | 
			
		||||
	0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a,
 | 
			
		||||
	0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,
 | 
			
		||||
	0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18, 0x03,
 | 
			
		||||
	0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x42,
 | 
			
		||||
	0x06, 0x5a, 0x04, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 | 
			
		||||
	0x73, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x02, 0x70, 0x62, 0x22, 0x89,
 | 
			
		||||
	0x01, 0x0a, 0x0b, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x0e,
 | 
			
		||||
	0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12,
 | 
			
		||||
	0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
 | 
			
		||||
	0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x18,
 | 
			
		||||
	0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74,
 | 
			
		||||
	0x12, 0x18, 0x0a, 0x07, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28,
 | 
			
		||||
	0x03, 0x52, 0x07, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x6e,
 | 
			
		||||
	0x73, 0x74, 0x61, 0x6c, 0x6c, 0x44, 0x69, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a,
 | 
			
		||||
	0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x44, 0x69, 0x72, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x2f,
 | 
			
		||||
	0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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
											
										
									
								
							@@ -227,17 +227,18 @@ func (x *CountAllEnabledNodesResponse) GetCount() int64 {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 列出单页节点
 | 
			
		||||
type ListEnabledNodesRequest struct {
 | 
			
		||||
type ListEnabledNodesMatchRequest struct {
 | 
			
		||||
	state         protoimpl.MessageState
 | 
			
		||||
	sizeCache     protoimpl.SizeCache
 | 
			
		||||
	unknownFields protoimpl.UnknownFields
 | 
			
		||||
 | 
			
		||||
	Offset int64 `protobuf:"varint,1,opt,name=offset,proto3" json:"offset,omitempty"`
 | 
			
		||||
	Size   int64 `protobuf:"varint,2,opt,name=size,proto3" json:"size,omitempty"`
 | 
			
		||||
	Offset    int64 `protobuf:"varint,1,opt,name=offset,proto3" json:"offset,omitempty"`
 | 
			
		||||
	Size      int64 `protobuf:"varint,2,opt,name=size,proto3" json:"size,omitempty"`
 | 
			
		||||
	ClusterId int64 `protobuf:"varint,3,opt,name=clusterId,proto3" json:"clusterId,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *ListEnabledNodesRequest) Reset() {
 | 
			
		||||
	*x = ListEnabledNodesRequest{}
 | 
			
		||||
func (x *ListEnabledNodesMatchRequest) Reset() {
 | 
			
		||||
	*x = ListEnabledNodesMatchRequest{}
 | 
			
		||||
	if protoimpl.UnsafeEnabled {
 | 
			
		||||
		mi := &file_service_node_proto_msgTypes[4]
 | 
			
		||||
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 | 
			
		||||
@@ -245,13 +246,13 @@ func (x *ListEnabledNodesRequest) Reset() {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *ListEnabledNodesRequest) String() string {
 | 
			
		||||
func (x *ListEnabledNodesMatchRequest) String() string {
 | 
			
		||||
	return protoimpl.X.MessageStringOf(x)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (*ListEnabledNodesRequest) ProtoMessage() {}
 | 
			
		||||
func (*ListEnabledNodesMatchRequest) ProtoMessage() {}
 | 
			
		||||
 | 
			
		||||
func (x *ListEnabledNodesRequest) ProtoReflect() protoreflect.Message {
 | 
			
		||||
func (x *ListEnabledNodesMatchRequest) ProtoReflect() protoreflect.Message {
 | 
			
		||||
	mi := &file_service_node_proto_msgTypes[4]
 | 
			
		||||
	if protoimpl.UnsafeEnabled && x != nil {
 | 
			
		||||
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 | 
			
		||||
@@ -263,26 +264,33 @@ func (x *ListEnabledNodesRequest) ProtoReflect() protoreflect.Message {
 | 
			
		||||
	return mi.MessageOf(x)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Deprecated: Use ListEnabledNodesRequest.ProtoReflect.Descriptor instead.
 | 
			
		||||
func (*ListEnabledNodesRequest) Descriptor() ([]byte, []int) {
 | 
			
		||||
// Deprecated: Use ListEnabledNodesMatchRequest.ProtoReflect.Descriptor instead.
 | 
			
		||||
func (*ListEnabledNodesMatchRequest) Descriptor() ([]byte, []int) {
 | 
			
		||||
	return file_service_node_proto_rawDescGZIP(), []int{4}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *ListEnabledNodesRequest) GetOffset() int64 {
 | 
			
		||||
func (x *ListEnabledNodesMatchRequest) GetOffset() int64 {
 | 
			
		||||
	if x != nil {
 | 
			
		||||
		return x.Offset
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *ListEnabledNodesRequest) GetSize() int64 {
 | 
			
		||||
func (x *ListEnabledNodesMatchRequest) GetSize() int64 {
 | 
			
		||||
	if x != nil {
 | 
			
		||||
		return x.Size
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ListEnabledNodesResponse struct {
 | 
			
		||||
func (x *ListEnabledNodesMatchRequest) GetClusterId() int64 {
 | 
			
		||||
	if x != nil {
 | 
			
		||||
		return x.ClusterId
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ListEnabledNodesMatchResponse struct {
 | 
			
		||||
	state         protoimpl.MessageState
 | 
			
		||||
	sizeCache     protoimpl.SizeCache
 | 
			
		||||
	unknownFields protoimpl.UnknownFields
 | 
			
		||||
@@ -290,8 +298,8 @@ type ListEnabledNodesResponse struct {
 | 
			
		||||
	Nodes []*Node `protobuf:"bytes,1,rep,name=nodes,proto3" json:"nodes,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *ListEnabledNodesResponse) Reset() {
 | 
			
		||||
	*x = ListEnabledNodesResponse{}
 | 
			
		||||
func (x *ListEnabledNodesMatchResponse) Reset() {
 | 
			
		||||
	*x = ListEnabledNodesMatchResponse{}
 | 
			
		||||
	if protoimpl.UnsafeEnabled {
 | 
			
		||||
		mi := &file_service_node_proto_msgTypes[5]
 | 
			
		||||
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 | 
			
		||||
@@ -299,13 +307,13 @@ func (x *ListEnabledNodesResponse) Reset() {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *ListEnabledNodesResponse) String() string {
 | 
			
		||||
func (x *ListEnabledNodesMatchResponse) String() string {
 | 
			
		||||
	return protoimpl.X.MessageStringOf(x)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (*ListEnabledNodesResponse) ProtoMessage() {}
 | 
			
		||||
func (*ListEnabledNodesMatchResponse) ProtoMessage() {}
 | 
			
		||||
 | 
			
		||||
func (x *ListEnabledNodesResponse) ProtoReflect() protoreflect.Message {
 | 
			
		||||
func (x *ListEnabledNodesMatchResponse) ProtoReflect() protoreflect.Message {
 | 
			
		||||
	mi := &file_service_node_proto_msgTypes[5]
 | 
			
		||||
	if protoimpl.UnsafeEnabled && x != nil {
 | 
			
		||||
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 | 
			
		||||
@@ -317,12 +325,12 @@ func (x *ListEnabledNodesResponse) ProtoReflect() protoreflect.Message {
 | 
			
		||||
	return mi.MessageOf(x)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Deprecated: Use ListEnabledNodesResponse.ProtoReflect.Descriptor instead.
 | 
			
		||||
func (*ListEnabledNodesResponse) Descriptor() ([]byte, []int) {
 | 
			
		||||
// Deprecated: Use ListEnabledNodesMatchResponse.ProtoReflect.Descriptor instead.
 | 
			
		||||
func (*ListEnabledNodesMatchResponse) Descriptor() ([]byte, []int) {
 | 
			
		||||
	return file_service_node_proto_rawDescGZIP(), []int{5}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *ListEnabledNodesResponse) GetNodes() []*Node {
 | 
			
		||||
func (x *ListEnabledNodesMatchResponse) GetNodes() []*Node {
 | 
			
		||||
	if x != nil {
 | 
			
		||||
		return x.Nodes
 | 
			
		||||
	}
 | 
			
		||||
@@ -963,6 +971,195 @@ func (*SyncNodesVersionWithClusterResponse) Descriptor() ([]byte, []int) {
 | 
			
		||||
	return file_service_node_proto_rawDescGZIP(), []int{19}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 计算匹配的节点数量
 | 
			
		||||
type CountAllEnabledNodesMatchRequest struct {
 | 
			
		||||
	state         protoimpl.MessageState
 | 
			
		||||
	sizeCache     protoimpl.SizeCache
 | 
			
		||||
	unknownFields protoimpl.UnknownFields
 | 
			
		||||
 | 
			
		||||
	ClusterId int64 `protobuf:"varint,1,opt,name=clusterId,proto3" json:"clusterId,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *CountAllEnabledNodesMatchRequest) Reset() {
 | 
			
		||||
	*x = CountAllEnabledNodesMatchRequest{}
 | 
			
		||||
	if protoimpl.UnsafeEnabled {
 | 
			
		||||
		mi := &file_service_node_proto_msgTypes[20]
 | 
			
		||||
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 | 
			
		||||
		ms.StoreMessageInfo(mi)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *CountAllEnabledNodesMatchRequest) String() string {
 | 
			
		||||
	return protoimpl.X.MessageStringOf(x)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (*CountAllEnabledNodesMatchRequest) ProtoMessage() {}
 | 
			
		||||
 | 
			
		||||
func (x *CountAllEnabledNodesMatchRequest) ProtoReflect() protoreflect.Message {
 | 
			
		||||
	mi := &file_service_node_proto_msgTypes[20]
 | 
			
		||||
	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 CountAllEnabledNodesMatchRequest.ProtoReflect.Descriptor instead.
 | 
			
		||||
func (*CountAllEnabledNodesMatchRequest) Descriptor() ([]byte, []int) {
 | 
			
		||||
	return file_service_node_proto_rawDescGZIP(), []int{20}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *CountAllEnabledNodesMatchRequest) GetClusterId() int64 {
 | 
			
		||||
	if x != nil {
 | 
			
		||||
		return x.ClusterId
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CountAllEnabledNodesMatchResponse struct {
 | 
			
		||||
	state         protoimpl.MessageState
 | 
			
		||||
	sizeCache     protoimpl.SizeCache
 | 
			
		||||
	unknownFields protoimpl.UnknownFields
 | 
			
		||||
 | 
			
		||||
	Count int64 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *CountAllEnabledNodesMatchResponse) Reset() {
 | 
			
		||||
	*x = CountAllEnabledNodesMatchResponse{}
 | 
			
		||||
	if protoimpl.UnsafeEnabled {
 | 
			
		||||
		mi := &file_service_node_proto_msgTypes[21]
 | 
			
		||||
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 | 
			
		||||
		ms.StoreMessageInfo(mi)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *CountAllEnabledNodesMatchResponse) String() string {
 | 
			
		||||
	return protoimpl.X.MessageStringOf(x)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (*CountAllEnabledNodesMatchResponse) ProtoMessage() {}
 | 
			
		||||
 | 
			
		||||
func (x *CountAllEnabledNodesMatchResponse) ProtoReflect() protoreflect.Message {
 | 
			
		||||
	mi := &file_service_node_proto_msgTypes[21]
 | 
			
		||||
	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 CountAllEnabledNodesMatchResponse.ProtoReflect.Descriptor instead.
 | 
			
		||||
func (*CountAllEnabledNodesMatchResponse) Descriptor() ([]byte, []int) {
 | 
			
		||||
	return file_service_node_proto_rawDescGZIP(), []int{21}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *CountAllEnabledNodesMatchResponse) GetCount() int64 {
 | 
			
		||||
	if x != nil {
 | 
			
		||||
		return x.Count
 | 
			
		||||
	}
 | 
			
		||||
	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{
 | 
			
		||||
@@ -985,57 +1182,75 @@ var file_service_node_proto_rawDesc = []byte{
 | 
			
		||||
	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, 0x14, 0x0a, 0x05, 0x63,
 | 
			
		||||
	0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e,
 | 
			
		||||
	0x74, 0x22, 0x45, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64,
 | 
			
		||||
	0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06,
 | 
			
		||||
	0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6f, 0x66,
 | 
			
		||||
	0x66, 0x73, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01,
 | 
			
		||||
	0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x3a, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74,
 | 
			
		||||
	0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70,
 | 
			
		||||
	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x01, 0x20,
 | 
			
		||||
	0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x70, 0x62, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x05, 0x6e,
 | 
			
		||||
	0x6f, 0x64, 0x65, 0x73, 0x22, 0x2c, 0x0a, 0x12, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4e,
 | 
			
		||||
	0x6f, 0x64, 0x65, 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, 0x22, 0x15, 0x0a, 0x13, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x64,
 | 
			
		||||
	0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x82, 0x01, 0x0a, 0x11, 0x55, 0x70,
 | 
			
		||||
	0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 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, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
 | 
			
		||||
	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 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, 0x23, 0x0a, 0x05, 0x4c, 0x6f, 0x67,
 | 
			
		||||
	0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x62, 0x2e, 0x4e, 0x6f,
 | 
			
		||||
	0x64, 0x65, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x22, 0x14,
 | 
			
		||||
	0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70,
 | 
			
		||||
	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x30, 0x0a, 0x16, 0x46, 0x69, 0x6e, 0x64, 0x45, 0x6e, 0x61, 0x62,
 | 
			
		||||
	0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 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, 0x22, 0x37, 0x0a, 0x17, 0x46, 0x69, 0x6e, 0x64, 0x45, 0x6e,
 | 
			
		||||
	0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
 | 
			
		||||
	0x65, 0x12, 0x1c, 0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
 | 
			
		||||
	0x08, 0x2e, 0x70, 0x62, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x22,
 | 
			
		||||
	0x1a, 0x0a, 0x18, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6f,
 | 
			
		||||
	0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3b, 0x0a, 0x19, 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, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x66,
 | 
			
		||||
	0x69, 0x67, 0x4a, 0x53, 0x4f, 0x4e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x63, 0x6f,
 | 
			
		||||
	0x6e, 0x66, 0x69, 0x67, 0x4a, 0x53, 0x4f, 0x4e, 0x22, 0x13, 0x0a, 0x11, 0x4e, 0x6f, 0x64, 0x65,
 | 
			
		||||
	0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x14, 0x0a,
 | 
			
		||||
	0x12, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f,
 | 
			
		||||
	0x6e, 0x73, 0x65, 0x22, 0x51, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64,
 | 
			
		||||
	0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 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, 0x1e, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
 | 
			
		||||
	0x4a, 0x53, 0x4f, 0x4e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74,
 | 
			
		||||
	0x75, 0x73, 0x4a, 0x53, 0x4f, 0x4e, 0x22, 0x1a, 0x0a, 0x18, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
 | 
			
		||||
	0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
 | 
			
		||||
	0x73, 0x65, 0x22, 0x42, 0x0a, 0x22, 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, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73,
 | 
			
		||||
	0x74, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x6c, 0x75,
 | 
			
		||||
	0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x22, 0x25, 0x0a, 0x23, 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, 0x32, 0x8f, 0x06,
 | 
			
		||||
	0x74, 0x22, 0x68, 0x0a, 0x1c, 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, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28,
 | 
			
		||||
	0x03, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a,
 | 
			
		||||
	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 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, 0x22, 0x3f, 0x0a, 0x1d, 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, 0x1e, 0x0a, 0x05,
 | 
			
		||||
	0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x70, 0x62,
 | 
			
		||||
	0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x22, 0x2c, 0x0a, 0x12,
 | 
			
		||||
	0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, 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, 0x22, 0x15, 0x0a, 0x13, 0x44, 0x69,
 | 
			
		||||
	0x73, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
 | 
			
		||||
	0x65, 0x22, 0x82, 0x01, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65,
 | 
			
		||||
	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,
 | 
			
		||||
	0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
 | 
			
		||||
	0x61, 0x6d, 0x65, 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, 0x23, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b,
 | 
			
		||||
	0x32, 0x0d, 0x2e, 0x70, 0x62, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52,
 | 
			
		||||
	0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x22, 0x14, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
 | 
			
		||||
	0x4e, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x30, 0x0a, 0x16,
 | 
			
		||||
	0x46, 0x69, 0x6e, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 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, 0x22, 0x37,
 | 
			
		||||
	0x0a, 0x17, 0x46, 0x69, 0x6e, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64,
 | 
			
		||||
	0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x04, 0x6e, 0x6f, 0x64,
 | 
			
		||||
	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x70, 0x62, 0x2e, 0x4e, 0x6f, 0x64,
 | 
			
		||||
	0x65, 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x22, 0x1a, 0x0a, 0x18, 0x43, 0x6f, 0x6d, 0x70, 0x6f,
 | 
			
		||||
	0x73, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75,
 | 
			
		||||
	0x65, 0x73, 0x74, 0x22, 0x3b, 0x0a, 0x19, 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, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4a, 0x53, 0x4f, 0x4e, 0x18, 0x01,
 | 
			
		||||
	0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4a, 0x53, 0x4f, 0x4e,
 | 
			
		||||
	0x22, 0x13, 0x0a, 0x11, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65,
 | 
			
		||||
	0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x14, 0x0a, 0x12, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x72,
 | 
			
		||||
	0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x51, 0x0a, 0x17, 0x55,
 | 
			
		||||
	0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 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, 0x1e,
 | 
			
		||||
	0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4a, 0x53, 0x4f, 0x4e, 0x18, 0x02, 0x20, 0x01,
 | 
			
		||||
	0x28, 0x0c, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4a, 0x53, 0x4f, 0x4e, 0x22, 0x1a,
 | 
			
		||||
	0x0a, 0x18, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74,
 | 
			
		||||
	0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x42, 0x0a, 0x22, 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,
 | 
			
		||||
	0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20,
 | 
			
		||||
	0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x22, 0x25,
 | 
			
		||||
	0x0a, 0x23, 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, 0x22, 0x40, 0x0a, 0x20, 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, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75,
 | 
			
		||||
	0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x6c,
 | 
			
		||||
	0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x22, 0x39, 0x0a, 0x21, 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, 0x14, 0x0a, 0x05,
 | 
			
		||||
	0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75,
 | 
			
		||||
	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,
 | 
			
		||||
@@ -1046,46 +1261,60 @@ var file_service_node_proto_rawDesc = []byte{
 | 
			
		||||
	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, 0x4d, 0x0a, 0x10, 0x6c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x61,
 | 
			
		||||
	0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x1b, 0x2e, 0x70, 0x62, 0x2e, 0x4c,
 | 
			
		||||
	0x69, 0x73, 0x74, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52,
 | 
			
		||||
	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x70, 0x62, 0x2e, 0x4c, 0x69, 0x73, 0x74,
 | 
			
		||||
	0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 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, 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,
 | 
			
		||||
	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, 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,
 | 
			
		||||
	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, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42,
 | 
			
		||||
	0x06, 0x5a, 0x04, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 | 
			
		||||
	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 (
 | 
			
		||||
@@ -1100,14 +1329,14 @@ func file_service_node_proto_rawDescGZIP() []byte {
 | 
			
		||||
	return file_service_node_proto_rawDescData
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var file_service_node_proto_msgTypes = make([]protoimpl.MessageInfo, 20)
 | 
			
		||||
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
 | 
			
		||||
	(*CountAllEnabledNodesRequest)(nil),         // 2: pb.CountAllEnabledNodesRequest
 | 
			
		||||
	(*CountAllEnabledNodesResponse)(nil),        // 3: pb.CountAllEnabledNodesResponse
 | 
			
		||||
	(*ListEnabledNodesRequest)(nil),             // 4: pb.ListEnabledNodesRequest
 | 
			
		||||
	(*ListEnabledNodesResponse)(nil),            // 5: pb.ListEnabledNodesResponse
 | 
			
		||||
	(*ListEnabledNodesMatchRequest)(nil),        // 4: pb.ListEnabledNodesMatchRequest
 | 
			
		||||
	(*ListEnabledNodesMatchResponse)(nil),       // 5: pb.ListEnabledNodesMatchResponse
 | 
			
		||||
	(*DisableNodeRequest)(nil),                  // 6: pb.DisableNodeRequest
 | 
			
		||||
	(*DisableNodeResponse)(nil),                 // 7: pb.DisableNodeResponse
 | 
			
		||||
	(*UpdateNodeRequest)(nil),                   // 8: pb.UpdateNodeRequest
 | 
			
		||||
@@ -1122,36 +1351,44 @@ var file_service_node_proto_goTypes = []interface{}{
 | 
			
		||||
	(*UpdateNodeStatusResponse)(nil),            // 17: pb.UpdateNodeStatusResponse
 | 
			
		||||
	(*SyncNodesVersionWithClusterRequest)(nil),  // 18: pb.SyncNodesVersionWithClusterRequest
 | 
			
		||||
	(*SyncNodesVersionWithClusterResponse)(nil), // 19: pb.SyncNodesVersionWithClusterResponse
 | 
			
		||||
	(*NodeLogin)(nil),                           // 20: pb.NodeLogin
 | 
			
		||||
	(*Node)(nil),                                // 21: pb.Node
 | 
			
		||||
	(*CountAllEnabledNodesMatchRequest)(nil),    // 20: pb.CountAllEnabledNodesMatchRequest
 | 
			
		||||
	(*CountAllEnabledNodesMatchResponse)(nil),   // 21: pb.CountAllEnabledNodesMatchResponse
 | 
			
		||||
	(*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{
 | 
			
		||||
	20, // 0: pb.CreateNodeRequest.Login:type_name -> pb.NodeLogin
 | 
			
		||||
	21, // 1: pb.ListEnabledNodesResponse.nodes:type_name -> pb.Node
 | 
			
		||||
	20, // 2: pb.UpdateNodeRequest.Login:type_name -> pb.NodeLogin
 | 
			
		||||
	21, // 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
 | 
			
		||||
	4,  // 6: pb.NodeService.listEnabledNodes:input_type -> pb.ListEnabledNodesRequest
 | 
			
		||||
	6,  // 7: pb.NodeService.disableNode:input_type -> pb.DisableNodeRequest
 | 
			
		||||
	8,  // 8: pb.NodeService.updateNode:input_type -> pb.UpdateNodeRequest
 | 
			
		||||
	10, // 9: pb.NodeService.findEnabledNode:input_type -> pb.FindEnabledNodeRequest
 | 
			
		||||
	12, // 10: pb.NodeService.composeNodeConfig:input_type -> pb.ComposeNodeConfigRequest
 | 
			
		||||
	14, // 11: pb.NodeService.nodeStream:input_type -> pb.NodeStreamRequest
 | 
			
		||||
	16, // 12: pb.NodeService.updateNodeStatus:input_type -> pb.UpdateNodeStatusRequest
 | 
			
		||||
	18, // 13: pb.NodeService.syncNodesVersionWithCluster:input_type -> pb.SyncNodesVersionWithClusterRequest
 | 
			
		||||
	1,  // 14: pb.NodeService.createNode:output_type -> pb.CreateNodeResponse
 | 
			
		||||
	3,  // 15: pb.NodeService.countAllEnabledNodes:output_type -> pb.CountAllEnabledNodesResponse
 | 
			
		||||
	5,  // 16: pb.NodeService.listEnabledNodes:output_type -> pb.ListEnabledNodesResponse
 | 
			
		||||
	7,  // 17: pb.NodeService.disableNode:output_type -> pb.DisableNodeResponse
 | 
			
		||||
	9,  // 18: pb.NodeService.updateNode:output_type -> pb.UpdateNodeResponse
 | 
			
		||||
	11, // 19: pb.NodeService.findEnabledNode:output_type -> pb.FindEnabledNodeResponse
 | 
			
		||||
	13, // 20: pb.NodeService.composeNodeConfig:output_type -> pb.ComposeNodeConfigResponse
 | 
			
		||||
	15, // 21: pb.NodeService.nodeStream:output_type -> pb.NodeStreamResponse
 | 
			
		||||
	17, // 22: pb.NodeService.updateNodeStatus:output_type -> pb.UpdateNodeStatusResponse
 | 
			
		||||
	19, // 23: pb.NodeService.syncNodesVersionWithCluster:output_type -> pb.SyncNodesVersionWithClusterResponse
 | 
			
		||||
	14, // [14:24] is the sub-list for method output_type
 | 
			
		||||
	4,  // [4:14] is the sub-list for method input_type
 | 
			
		||||
	20, // 6: pb.NodeService.countAllEnabledNodesMatch:input_type -> pb.CountAllEnabledNodesMatchRequest
 | 
			
		||||
	4,  // 7: pb.NodeService.listEnabledNodesMatch:input_type -> pb.ListEnabledNodesMatchRequest
 | 
			
		||||
	6,  // 8: pb.NodeService.disableNode:input_type -> pb.DisableNodeRequest
 | 
			
		||||
	8,  // 9: pb.NodeService.updateNode:input_type -> pb.UpdateNodeRequest
 | 
			
		||||
	10, // 10: pb.NodeService.findEnabledNode:input_type -> pb.FindEnabledNodeRequest
 | 
			
		||||
	12, // 11: pb.NodeService.composeNodeConfig:input_type -> pb.ComposeNodeConfigRequest
 | 
			
		||||
	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
 | 
			
		||||
	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
 | 
			
		||||
@@ -1214,7 +1451,7 @@ func file_service_node_proto_init() {
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		file_service_node_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
 | 
			
		||||
			switch v := v.(*ListEnabledNodesRequest); i {
 | 
			
		||||
			switch v := v.(*ListEnabledNodesMatchRequest); i {
 | 
			
		||||
			case 0:
 | 
			
		||||
				return &v.state
 | 
			
		||||
			case 1:
 | 
			
		||||
@@ -1226,7 +1463,7 @@ func file_service_node_proto_init() {
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		file_service_node_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
 | 
			
		||||
			switch v := v.(*ListEnabledNodesResponse); i {
 | 
			
		||||
			switch v := v.(*ListEnabledNodesMatchResponse); i {
 | 
			
		||||
			case 0:
 | 
			
		||||
				return &v.state
 | 
			
		||||
			case 1:
 | 
			
		||||
@@ -1405,6 +1642,54 @@ func file_service_node_proto_init() {
 | 
			
		||||
				return nil
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		file_service_node_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
 | 
			
		||||
			switch v := v.(*CountAllEnabledNodesMatchRequest); i {
 | 
			
		||||
			case 0:
 | 
			
		||||
				return &v.state
 | 
			
		||||
			case 1:
 | 
			
		||||
				return &v.sizeCache
 | 
			
		||||
			case 2:
 | 
			
		||||
				return &v.unknownFields
 | 
			
		||||
			default:
 | 
			
		||||
				return nil
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		file_service_node_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} {
 | 
			
		||||
			switch v := v.(*CountAllEnabledNodesMatchResponse); i {
 | 
			
		||||
			case 0:
 | 
			
		||||
				return &v.state
 | 
			
		||||
			case 1:
 | 
			
		||||
				return &v.sizeCache
 | 
			
		||||
			case 2:
 | 
			
		||||
				return &v.unknownFields
 | 
			
		||||
			default:
 | 
			
		||||
				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{
 | 
			
		||||
@@ -1412,7 +1697,7 @@ func file_service_node_proto_init() {
 | 
			
		||||
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 | 
			
		||||
			RawDescriptor: file_service_node_proto_rawDesc,
 | 
			
		||||
			NumEnums:      0,
 | 
			
		||||
			NumMessages:   20,
 | 
			
		||||
			NumMessages:   24,
 | 
			
		||||
			NumExtensions: 0,
 | 
			
		||||
			NumServices:   1,
 | 
			
		||||
		},
 | 
			
		||||
@@ -1442,8 +1727,10 @@ type NodeServiceClient interface {
 | 
			
		||||
	CreateNode(ctx context.Context, in *CreateNodeRequest, opts ...grpc.CallOption) (*CreateNodeResponse, error)
 | 
			
		||||
	// 节点数量
 | 
			
		||||
	CountAllEnabledNodes(ctx context.Context, in *CountAllEnabledNodesRequest, opts ...grpc.CallOption) (*CountAllEnabledNodesResponse, error)
 | 
			
		||||
	// 计算匹配的节点数量
 | 
			
		||||
	CountAllEnabledNodesMatch(ctx context.Context, in *CountAllEnabledNodesMatchRequest, opts ...grpc.CallOption) (*CountAllEnabledNodesMatchResponse, error)
 | 
			
		||||
	// 列出单页节点
 | 
			
		||||
	ListEnabledNodes(ctx context.Context, in *ListEnabledNodesRequest, opts ...grpc.CallOption) (*ListEnabledNodesResponse, error)
 | 
			
		||||
	ListEnabledNodesMatch(ctx context.Context, in *ListEnabledNodesMatchRequest, opts ...grpc.CallOption) (*ListEnabledNodesMatchResponse, error)
 | 
			
		||||
	// 禁用节点
 | 
			
		||||
	DisableNode(ctx context.Context, in *DisableNodeRequest, opts ...grpc.CallOption) (*DisableNodeResponse, error)
 | 
			
		||||
	// 修改节点
 | 
			
		||||
@@ -1458,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 {
 | 
			
		||||
@@ -1486,9 +1775,18 @@ func (c *nodeServiceClient) CountAllEnabledNodes(ctx context.Context, in *CountA
 | 
			
		||||
	return out, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *nodeServiceClient) ListEnabledNodes(ctx context.Context, in *ListEnabledNodesRequest, opts ...grpc.CallOption) (*ListEnabledNodesResponse, error) {
 | 
			
		||||
	out := new(ListEnabledNodesResponse)
 | 
			
		||||
	err := c.cc.Invoke(ctx, "/pb.NodeService/listEnabledNodes", in, out, opts...)
 | 
			
		||||
func (c *nodeServiceClient) CountAllEnabledNodesMatch(ctx context.Context, in *CountAllEnabledNodesMatchRequest, opts ...grpc.CallOption) (*CountAllEnabledNodesMatchResponse, error) {
 | 
			
		||||
	out := new(CountAllEnabledNodesMatchResponse)
 | 
			
		||||
	err := c.cc.Invoke(ctx, "/pb.NodeService/countAllEnabledNodesMatch", in, out, opts...)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return out, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *nodeServiceClient) ListEnabledNodesMatch(ctx context.Context, in *ListEnabledNodesMatchRequest, opts ...grpc.CallOption) (*ListEnabledNodesMatchResponse, error) {
 | 
			
		||||
	out := new(ListEnabledNodesMatchResponse)
 | 
			
		||||
	err := c.cc.Invoke(ctx, "/pb.NodeService/listEnabledNodesMatch", in, out, opts...)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
@@ -1580,14 +1878,25 @@ 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 {
 | 
			
		||||
	// 创建节点
 | 
			
		||||
	CreateNode(context.Context, *CreateNodeRequest) (*CreateNodeResponse, error)
 | 
			
		||||
	// 节点数量
 | 
			
		||||
	CountAllEnabledNodes(context.Context, *CountAllEnabledNodesRequest) (*CountAllEnabledNodesResponse, error)
 | 
			
		||||
	// 计算匹配的节点数量
 | 
			
		||||
	CountAllEnabledNodesMatch(context.Context, *CountAllEnabledNodesMatchRequest) (*CountAllEnabledNodesMatchResponse, error)
 | 
			
		||||
	// 列出单页节点
 | 
			
		||||
	ListEnabledNodes(context.Context, *ListEnabledNodesRequest) (*ListEnabledNodesResponse, error)
 | 
			
		||||
	ListEnabledNodesMatch(context.Context, *ListEnabledNodesMatchRequest) (*ListEnabledNodesMatchResponse, error)
 | 
			
		||||
	// 禁用节点
 | 
			
		||||
	DisableNode(context.Context, *DisableNodeRequest) (*DisableNodeResponse, error)
 | 
			
		||||
	// 修改节点
 | 
			
		||||
@@ -1602,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.
 | 
			
		||||
@@ -1614,8 +1925,11 @@ func (*UnimplementedNodeServiceServer) CreateNode(context.Context, *CreateNodeRe
 | 
			
		||||
func (*UnimplementedNodeServiceServer) CountAllEnabledNodes(context.Context, *CountAllEnabledNodesRequest) (*CountAllEnabledNodesResponse, error) {
 | 
			
		||||
	return nil, status.Errorf(codes.Unimplemented, "method CountAllEnabledNodes not implemented")
 | 
			
		||||
}
 | 
			
		||||
func (*UnimplementedNodeServiceServer) ListEnabledNodes(context.Context, *ListEnabledNodesRequest) (*ListEnabledNodesResponse, error) {
 | 
			
		||||
	return nil, status.Errorf(codes.Unimplemented, "method ListEnabledNodes not implemented")
 | 
			
		||||
func (*UnimplementedNodeServiceServer) CountAllEnabledNodesMatch(context.Context, *CountAllEnabledNodesMatchRequest) (*CountAllEnabledNodesMatchResponse, error) {
 | 
			
		||||
	return nil, status.Errorf(codes.Unimplemented, "method CountAllEnabledNodesMatch not implemented")
 | 
			
		||||
}
 | 
			
		||||
func (*UnimplementedNodeServiceServer) ListEnabledNodesMatch(context.Context, *ListEnabledNodesMatchRequest) (*ListEnabledNodesMatchResponse, error) {
 | 
			
		||||
	return nil, status.Errorf(codes.Unimplemented, "method ListEnabledNodesMatch not implemented")
 | 
			
		||||
}
 | 
			
		||||
func (*UnimplementedNodeServiceServer) DisableNode(context.Context, *DisableNodeRequest) (*DisableNodeResponse, error) {
 | 
			
		||||
	return nil, status.Errorf(codes.Unimplemented, "method DisableNode not implemented")
 | 
			
		||||
@@ -1638,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)
 | 
			
		||||
@@ -1679,20 +1996,38 @@ func _NodeService_CountAllEnabledNodes_Handler(srv interface{}, ctx context.Cont
 | 
			
		||||
	return interceptor(ctx, in, info, handler)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func _NodeService_ListEnabledNodes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
 | 
			
		||||
	in := new(ListEnabledNodesRequest)
 | 
			
		||||
func _NodeService_CountAllEnabledNodesMatch_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
 | 
			
		||||
	in := new(CountAllEnabledNodesMatchRequest)
 | 
			
		||||
	if err := dec(in); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if interceptor == nil {
 | 
			
		||||
		return srv.(NodeServiceServer).ListEnabledNodes(ctx, in)
 | 
			
		||||
		return srv.(NodeServiceServer).CountAllEnabledNodesMatch(ctx, in)
 | 
			
		||||
	}
 | 
			
		||||
	info := &grpc.UnaryServerInfo{
 | 
			
		||||
		Server:     srv,
 | 
			
		||||
		FullMethod: "/pb.NodeService/ListEnabledNodes",
 | 
			
		||||
		FullMethod: "/pb.NodeService/CountAllEnabledNodesMatch",
 | 
			
		||||
	}
 | 
			
		||||
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
 | 
			
		||||
		return srv.(NodeServiceServer).ListEnabledNodes(ctx, req.(*ListEnabledNodesRequest))
 | 
			
		||||
		return srv.(NodeServiceServer).CountAllEnabledNodesMatch(ctx, req.(*CountAllEnabledNodesMatchRequest))
 | 
			
		||||
	}
 | 
			
		||||
	return interceptor(ctx, in, info, handler)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func _NodeService_ListEnabledNodesMatch_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
 | 
			
		||||
	in := new(ListEnabledNodesMatchRequest)
 | 
			
		||||
	if err := dec(in); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if interceptor == nil {
 | 
			
		||||
		return srv.(NodeServiceServer).ListEnabledNodesMatch(ctx, in)
 | 
			
		||||
	}
 | 
			
		||||
	info := &grpc.UnaryServerInfo{
 | 
			
		||||
		Server:     srv,
 | 
			
		||||
		FullMethod: "/pb.NodeService/ListEnabledNodesMatch",
 | 
			
		||||
	}
 | 
			
		||||
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
 | 
			
		||||
		return srv.(NodeServiceServer).ListEnabledNodesMatch(ctx, req.(*ListEnabledNodesMatchRequest))
 | 
			
		||||
	}
 | 
			
		||||
	return interceptor(ctx, in, info, handler)
 | 
			
		||||
}
 | 
			
		||||
@@ -1831,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),
 | 
			
		||||
@@ -1844,8 +2197,12 @@ var _NodeService_serviceDesc = grpc.ServiceDesc{
 | 
			
		||||
			Handler:    _NodeService_CountAllEnabledNodes_Handler,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			MethodName: "listEnabledNodes",
 | 
			
		||||
			Handler:    _NodeService_ListEnabledNodes_Handler,
 | 
			
		||||
			MethodName: "countAllEnabledNodesMatch",
 | 
			
		||||
			Handler:    _NodeService_CountAllEnabledNodesMatch_Handler,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			MethodName: "listEnabledNodesMatch",
 | 
			
		||||
			Handler:    _NodeService_ListEnabledNodesMatch_Handler,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			MethodName: "disableNode",
 | 
			
		||||
@@ -1871,6 +2228,10 @@ var _NodeService_serviceDesc = grpc.ServiceDesc{
 | 
			
		||||
			MethodName: "syncNodesVersionWithCluster",
 | 
			
		||||
			Handler:    _NodeService_SyncNodesVersionWithCluster_Handler,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			MethodName: "updateNodeIsInstalled",
 | 
			
		||||
			Handler:    _NodeService_UpdateNodeIsInstalled_Handler,
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
	Streams: []grpc.StreamDesc{
 | 
			
		||||
		{
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										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;
 | 
			
		||||
}
 | 
			
		||||
@@ -12,8 +12,11 @@ service NodeService {
 | 
			
		||||
	// 节点数量
 | 
			
		||||
	rpc countAllEnabledNodes (CountAllEnabledNodesRequest) returns (CountAllEnabledNodesResponse);
 | 
			
		||||
 | 
			
		||||
	// 计算匹配的节点数量
 | 
			
		||||
	rpc countAllEnabledNodesMatch (CountAllEnabledNodesMatchRequest) returns (CountAllEnabledNodesMatchResponse);
 | 
			
		||||
 | 
			
		||||
	// 列出单页节点
 | 
			
		||||
	rpc listEnabledNodes (ListEnabledNodesRequest) returns (ListEnabledNodesResponse);
 | 
			
		||||
	rpc listEnabledNodesMatch (ListEnabledNodesMatchRequest) returns (ListEnabledNodesMatchResponse);
 | 
			
		||||
 | 
			
		||||
	// 禁用节点
 | 
			
		||||
	rpc disableNode (DisableNodeRequest) returns (DisableNodeResponse);
 | 
			
		||||
@@ -35,6 +38,9 @@ service NodeService {
 | 
			
		||||
 | 
			
		||||
	// 同步集群中的节点版本
 | 
			
		||||
	rpc syncNodesVersionWithCluster (SyncNodesVersionWithClusterRequest) returns (SyncNodesVersionWithClusterResponse);
 | 
			
		||||
 | 
			
		||||
	// 修改节点安装状态
 | 
			
		||||
	rpc updateNodeIsInstalled (UpdateNodeIsInstalledRequest) returns (UpdateNodeIsInstalledResponse);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 创建节点
 | 
			
		||||
@@ -58,12 +64,13 @@ message CountAllEnabledNodesResponse {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 列出单页节点
 | 
			
		||||
message ListEnabledNodesRequest {
 | 
			
		||||
message ListEnabledNodesMatchRequest {
 | 
			
		||||
	int64 offset = 1;
 | 
			
		||||
	int64 size = 2;
 | 
			
		||||
	int64 clusterId = 3;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
message ListEnabledNodesResponse {
 | 
			
		||||
message ListEnabledNodesMatchResponse {
 | 
			
		||||
	repeated Node nodes = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -131,4 +138,23 @@ message SyncNodesVersionWithClusterRequest {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
message SyncNodesVersionWithClusterResponse {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 计算匹配的节点数量
 | 
			
		||||
message CountAllEnabledNodesMatchRequest {
 | 
			
		||||
	int64 clusterId = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
message CountAllEnabledNodesMatchResponse {
 | 
			
		||||
	int64 count = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 修改节点安装状态
 | 
			
		||||
message UpdateNodeIsInstalledRequest {
 | 
			
		||||
	int64 nodeId = 1;
 | 
			
		||||
	bool isInstalled = 2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
message UpdateNodeIsInstalledResponse {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -5,11 +5,29 @@ package pb;
 | 
			
		||||
import "model_node_cluster.proto";
 | 
			
		||||
 | 
			
		||||
service NodeClusterService {
 | 
			
		||||
	// 创建集群
 | 
			
		||||
	rpc createNodeCluster (CreateNodeClusterRequest) returns (CreateNodeClusterResponse);
 | 
			
		||||
 | 
			
		||||
	// 修改集群
 | 
			
		||||
	rpc updateNodeCluster (UpdateNodeClusterRequest) returns (UpdateNodeClusterResponse);
 | 
			
		||||
 | 
			
		||||
	// 禁用集群
 | 
			
		||||
	rpc disableNodeCluster (DisableNodeClusterRequest) returns (DisableNodeClusterResponse);
 | 
			
		||||
 | 
			
		||||
	// 查找单个集群信息
 | 
			
		||||
	rpc findEnabledNodeCluster (FindEnabledNodeClusterRequest) returns (FindEnabledNodeClusterResponse);
 | 
			
		||||
 | 
			
		||||
	// 获取所有集群的信息
 | 
			
		||||
	rpc findAllEnabledClusters (FindAllEnabledNodeClustersRequest) returns (FindAllEnabledNodeClustersResponse);
 | 
			
		||||
	rpc findAllEnabledNodeClusters (FindAllEnabledNodeClustersRequest) returns (FindAllEnabledNodeClustersResponse);
 | 
			
		||||
 | 
			
		||||
	// 获取变更的集群
 | 
			
		||||
	rpc findAllChangedClusters (FindAllChangedClustersRequest) returns (FindAllChangedClustersResponse);
 | 
			
		||||
	rpc findAllChangedNodeClusters (FindAllChangedNodeClustersRequest) returns (FindAllChangedNodeClustersResponse);
 | 
			
		||||
 | 
			
		||||
	// 计算所有集群数量
 | 
			
		||||
	rpc countAllEnabledNodeClusters (CountAllEnabledNodeClustersRequest) returns (CountAllEnabledNodeClustersResponse);
 | 
			
		||||
 | 
			
		||||
	// 列出单页集群
 | 
			
		||||
	rpc listEnabledNodeClusters (ListEnabledNodeClustersRequest) returns (ListEnabledNodeClustersResponse);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 获取所有集群的信息
 | 
			
		||||
@@ -22,10 +40,70 @@ message FindAllEnabledNodeClustersResponse {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 获取变更的集群
 | 
			
		||||
message FindAllChangedClustersRequest {
 | 
			
		||||
message FindAllChangedNodeClustersRequest {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
message FindAllChangedClustersResponse {
 | 
			
		||||
message FindAllChangedNodeClustersResponse {
 | 
			
		||||
	repeated NodeCluster clusters = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 创建集群
 | 
			
		||||
message CreateNodeClusterRequest {
 | 
			
		||||
	string name = 1;
 | 
			
		||||
	int64 grantId = 2;
 | 
			
		||||
	string installDir = 3;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
message CreateNodeClusterResponse {
 | 
			
		||||
	int64 clusterId = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 修改集群
 | 
			
		||||
message UpdateNodeClusterRequest {
 | 
			
		||||
	int64 clusterId = 1;
 | 
			
		||||
	string name = 2;
 | 
			
		||||
	int64 grantId = 3;
 | 
			
		||||
	string installDir = 4;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
message UpdateNodeClusterResponse {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 禁用集群
 | 
			
		||||
message DisableNodeClusterRequest {
 | 
			
		||||
	int64 clusterId = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
message DisableNodeClusterResponse {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 查找单个集群信息
 | 
			
		||||
message FindEnabledNodeClusterRequest {
 | 
			
		||||
	int64 clusterId = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
message FindEnabledNodeClusterResponse {
 | 
			
		||||
	NodeCluster cluster = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 计算所有集群数量
 | 
			
		||||
message CountAllEnabledNodeClustersRequest {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
message CountAllEnabledNodeClustersResponse {
 | 
			
		||||
	int64 count = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 列出单页集群
 | 
			
		||||
message ListEnabledNodeClustersRequest {
 | 
			
		||||
	int64 offset = 1;
 | 
			
		||||
	int64 size = 2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
message ListEnabledNodeClustersResponse {
 | 
			
		||||
	repeated NodeCluster clusters = 1;
 | 
			
		||||
}
 | 
			
		||||
@@ -24,6 +24,7 @@ type RPCClient struct {
 | 
			
		||||
	nodeClusterClients   []pb.NodeClusterServiceClient
 | 
			
		||||
	nodeIPAddressClients []pb.NodeIPAddressServiceClient
 | 
			
		||||
	serverClients        []pb.ServerServiceClient
 | 
			
		||||
	apiNodeClients       []pb.APINodeServiceClient
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewRPCClient(apiConfig *configs.APIConfig) (*RPCClient, error) {
 | 
			
		||||
@@ -37,6 +38,7 @@ func NewRPCClient(apiConfig *configs.APIConfig) (*RPCClient, error) {
 | 
			
		||||
	nodeClusterClients := []pb.NodeClusterServiceClient{}
 | 
			
		||||
	nodeIPAddressClients := []pb.NodeIPAddressServiceClient{}
 | 
			
		||||
	serverClients := []pb.ServerServiceClient{}
 | 
			
		||||
	apiNodeClients := []pb.APINodeServiceClient{}
 | 
			
		||||
 | 
			
		||||
	conns := []*grpc.ClientConn{}
 | 
			
		||||
	for _, endpoint := range apiConfig.RPC.Endpoints {
 | 
			
		||||
@@ -58,6 +60,7 @@ func NewRPCClient(apiConfig *configs.APIConfig) (*RPCClient, error) {
 | 
			
		||||
		nodeClusterClients = append(nodeClusterClients, pb.NewNodeClusterServiceClient(conn))
 | 
			
		||||
		nodeIPAddressClients = append(nodeIPAddressClients, pb.NewNodeIPAddressServiceClient(conn))
 | 
			
		||||
		serverClients = append(serverClients, pb.NewServerServiceClient(conn))
 | 
			
		||||
		apiNodeClients = append(apiNodeClients, pb.NewAPINodeServiceClient(conn))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &RPCClient{
 | 
			
		||||
@@ -68,6 +71,7 @@ func NewRPCClient(apiConfig *configs.APIConfig) (*RPCClient, error) {
 | 
			
		||||
		nodeClusterClients:   nodeClusterClients,
 | 
			
		||||
		nodeIPAddressClients: nodeIPAddressClients,
 | 
			
		||||
		serverClients:        serverClients,
 | 
			
		||||
		apiNodeClients:       apiNodeClients,
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -113,6 +117,13 @@ func (this *RPCClient) ServerRPC() pb.ServerServiceClient {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *RPCClient) APINodeRPC() pb.APINodeServiceClient {
 | 
			
		||||
	if len(this.serverClients) > 0 {
 | 
			
		||||
		return this.apiNodeClients[rands.Int(0, len(this.apiNodeClients)-1)]
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *RPCClient) Context(adminId int64) context.Context {
 | 
			
		||||
	ctx := context.Background()
 | 
			
		||||
	m := maps.Map{
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										23
									
								
								internal/web/actions/default/api/helper.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								internal/web/actions/default/api/helper.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
package api
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Helper struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewHelper() *Helper {
 | 
			
		||||
	return &Helper{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Helper) BeforeAction(action *actions.ActionObject) {
 | 
			
		||||
	action.Data["teaMenu"] = "api"
 | 
			
		||||
 | 
			
		||||
	selectedTabbar, _ := action.Data["mainTab"]
 | 
			
		||||
 | 
			
		||||
	tabbar := actionutils.NewTabbar()
 | 
			
		||||
	tabbar.Add("API节点", "", "/api", "", selectedTabbar == "node")
 | 
			
		||||
	actionutils.SetTabbar(action, tabbar)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										51
									
								
								internal/web/actions/default/api/index.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								internal/web/actions/default/api/index.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
package api
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/rpc/pb"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type IndexAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) Init() {
 | 
			
		||||
	this.Nav("", "node", "index")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) RunGet(params struct{}) {
 | 
			
		||||
	countResp, err := this.RPC().APINodeRPC().CountAllEnabledAPINodes(this.AdminContext(), &pb.CountAllEnabledAPINodesRequest{})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	count := countResp.Count
 | 
			
		||||
	page := this.NewPage(count)
 | 
			
		||||
	this.Data["page"] = page.AsHTML()
 | 
			
		||||
 | 
			
		||||
	nodeMaps := []maps.Map{}
 | 
			
		||||
	if count > 0 {
 | 
			
		||||
		nodesResp, err := this.RPC().APINodeRPC().ListEnabledAPINodes(this.AdminContext(), &pb.ListEnabledAPINodesRequest{
 | 
			
		||||
			Offset: page.Offset,
 | 
			
		||||
			Size:   page.Size,
 | 
			
		||||
		})
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			this.ErrorPage(err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for _, node := range nodesResp.Nodes {
 | 
			
		||||
			nodeMaps = append(nodeMaps, maps.Map{
 | 
			
		||||
				"id":   node.Id,
 | 
			
		||||
				"isOn": node.IsOn,
 | 
			
		||||
				"name": node.Name,
 | 
			
		||||
				"host": node.Host,
 | 
			
		||||
				"port": node.Port,
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["nodes"] = nodeMaps
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										19
									
								
								internal/web/actions/default/api/init.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								internal/web/actions/default/api/init.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
package api
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/api/node"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
 | 
			
		||||
	"github.com/iwind/TeaGo"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	TeaGo.BeforeStart(func(server *TeaGo.Server) {
 | 
			
		||||
		server.
 | 
			
		||||
			Helper(helpers.NewUserMustAuth()).
 | 
			
		||||
			Helper(NewHelper()).
 | 
			
		||||
			Prefix("/api").
 | 
			
		||||
			Get("", new(IndexAction)).
 | 
			
		||||
			GetPost("/node/create", new(node.CreateAction)).
 | 
			
		||||
			EndAll()
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										50
									
								
								internal/web/actions/default/api/node/create.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								internal/web/actions/default/api/node/create.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
			
		||||
package node
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/rpc/pb"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type CreateAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *CreateAction) Init() {
 | 
			
		||||
	this.Nav("", "node", "create")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *CreateAction) RunGet(params struct{}) {
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *CreateAction) RunPost(params struct {
 | 
			
		||||
	Name        string
 | 
			
		||||
	Host        string
 | 
			
		||||
	Port        int
 | 
			
		||||
	Description string
 | 
			
		||||
 | 
			
		||||
	Must *actions.Must
 | 
			
		||||
}) {
 | 
			
		||||
	params.Must.
 | 
			
		||||
		Field("name", params.Name).
 | 
			
		||||
		Require("请输入API节点").
 | 
			
		||||
		Field("host", params.Host).
 | 
			
		||||
		Require("请输入主机地址").
 | 
			
		||||
		Field("port", params.Port).
 | 
			
		||||
		Gt(0, "端口不能小于1").
 | 
			
		||||
		Lte(65535, "端口不能大于65535")
 | 
			
		||||
 | 
			
		||||
	_, err := this.RPC().APINodeRPC().CreateAPINode(this.AdminContext(), &pb.CreateAPINodeRequest{
 | 
			
		||||
		Name:        params.Name,
 | 
			
		||||
		Description: params.Description,
 | 
			
		||||
		Host:        params.Host,
 | 
			
		||||
		Port:        int32(params.Port),
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										73
									
								
								internal/web/actions/default/api/node/helper.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								internal/web/actions/default/api/node/helper.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,73 @@
 | 
			
		||||
package node
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/rpc"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/rpc/pb"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
	"github.com/iwind/TeaGo/logs"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"strconv"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Helper struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewHelper() *Helper {
 | 
			
		||||
	return &Helper{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Helper) BeforeAction(action *actions.ActionObject) (goNext bool) {
 | 
			
		||||
	if action.Request.Method != http.MethodGet {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	action.Data["teaMenu"] = "api"
 | 
			
		||||
 | 
			
		||||
	nodeId := action.ParamInt64("nodeId")
 | 
			
		||||
	nodeIdString := strconv.FormatInt(nodeId, 10)
 | 
			
		||||
 | 
			
		||||
	// 节点信息
 | 
			
		||||
	rpcClient, err := rpc.SharedRPC()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logs.Error(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	nodeResp, err := rpcClient.APINodeRPC().FindEnabledAPINode(rpcClient.Context(action.Context.GetInt64("adminId")), &pb.FindEnabledAPINodeRequest{NodeId: nodeId})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		action.WriteString(err.Error())
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if nodeResp.Node == nil {
 | 
			
		||||
		action.WriteString("node not found")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	node := nodeResp.Node
 | 
			
		||||
 | 
			
		||||
	// 顶部Tab栏
 | 
			
		||||
	selectedTabbar, _ := action.Data["mainTab"]
 | 
			
		||||
	tabbar := actionutils.NewTabbar()
 | 
			
		||||
	tabbar.Add("当前节点:"+node.Name, "", "/api", "left long alternate arrow", false)
 | 
			
		||||
	tabbar.Add("设置", "", "/api/node/settings?nodeId="+nodeIdString, "setting", selectedTabbar == "setting")
 | 
			
		||||
	actionutils.SetTabbar(action, tabbar)
 | 
			
		||||
 | 
			
		||||
	// 左侧菜单栏
 | 
			
		||||
	secondMenuItem := action.Data.GetString("secondMenuItem")
 | 
			
		||||
	switch selectedTabbar {
 | 
			
		||||
	case "setting":
 | 
			
		||||
		action.Data["leftMenuItems"] = this.createSettingMenu(nodeIdString, secondMenuItem)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 设置相关菜单
 | 
			
		||||
func (this *Helper) createSettingMenu(nodeIdString string, selectedItem string) (items []maps.Map) {
 | 
			
		||||
	items = append(items, maps.Map{
 | 
			
		||||
		"name":     "基础设置",
 | 
			
		||||
		"url":      "/api/node/settings?nodeId=" + nodeIdString,
 | 
			
		||||
		"isActive": selectedItem == "basic",
 | 
			
		||||
	})
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								internal/web/actions/default/api/node/init.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								internal/web/actions/default/api/node/init.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
package node
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
 | 
			
		||||
	"github.com/iwind/TeaGo"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	TeaGo.BeforeStart(func(server *TeaGo.Server) {
 | 
			
		||||
		server.
 | 
			
		||||
			Helper(helpers.NewUserMustAuth()).
 | 
			
		||||
			Helper(NewHelper()).
 | 
			
		||||
			Prefix("/api/node").
 | 
			
		||||
 | 
			
		||||
			// 节点相关
 | 
			
		||||
			GetPost("/settings", new(SettingsAction)).
 | 
			
		||||
 | 
			
		||||
			EndAll()
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										78
									
								
								internal/web/actions/default/api/node/settings.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								internal/web/actions/default/api/node/settings.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
			
		||||
package node
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/rpc/pb"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type SettingsAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *SettingsAction) Init() {
 | 
			
		||||
	this.Nav("", "setting", "")
 | 
			
		||||
	this.SecondMenu("basic")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *SettingsAction) RunGet(params struct {
 | 
			
		||||
	NodeId int64
 | 
			
		||||
}) {
 | 
			
		||||
	nodeResp, err := this.RPC().APINodeRPC().FindEnabledAPINode(this.AdminContext(), &pb.FindEnabledAPINodeRequest{
 | 
			
		||||
		NodeId: params.NodeId,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	node := nodeResp.Node
 | 
			
		||||
	if node == nil {
 | 
			
		||||
		this.WriteString("要操作的节点不存在")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Data["node"] = maps.Map{
 | 
			
		||||
		"id":          node.Id,
 | 
			
		||||
		"name":        node.Name,
 | 
			
		||||
		"description": node.Description,
 | 
			
		||||
		"host":        node.Host,
 | 
			
		||||
		"port":        node.Port,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 保存基础设置
 | 
			
		||||
func (this *SettingsAction) RunPost(params struct {
 | 
			
		||||
	NodeId      int64
 | 
			
		||||
	Name        string
 | 
			
		||||
	Host        string
 | 
			
		||||
	Port        int
 | 
			
		||||
	Description string
 | 
			
		||||
 | 
			
		||||
	Must *actions.Must
 | 
			
		||||
}) {
 | 
			
		||||
	params.Must.
 | 
			
		||||
		Field("name", params.Name).
 | 
			
		||||
		Require("请输入API节点").
 | 
			
		||||
		Field("host", params.Host).
 | 
			
		||||
		Require("请输入主机地址").
 | 
			
		||||
		Field("port", params.Port).
 | 
			
		||||
		Gt(0, "端口不能小于1").
 | 
			
		||||
		Lte(65535, "端口不能大于65535")
 | 
			
		||||
 | 
			
		||||
	_, err := this.RPC().APINodeRPC().UpdateAPINode(this.AdminContext(), &pb.UpdateAPINodeRequest{
 | 
			
		||||
		NodeId:      params.NodeId,
 | 
			
		||||
		Name:        params.Name,
 | 
			
		||||
		Description: params.Description,
 | 
			
		||||
		Host:        params.Host,
 | 
			
		||||
		Port:        int32(params.Port),
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
package nodes
 | 
			
		||||
package cluster
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
@@ -16,11 +16,16 @@ type IndexAction struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) Init() {
 | 
			
		||||
	this.Nav("", "node", "index")
 | 
			
		||||
	this.Nav("", "node", "")
 | 
			
		||||
	this.SecondMenu("nodes")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) RunGet(params struct{}) {
 | 
			
		||||
	countResp, err := this.RPC().NodeRPC().CountAllEnabledNodes(this.AdminContext(), &pb.CountAllEnabledNodesRequest{})
 | 
			
		||||
func (this *IndexAction) RunGet(params struct {
 | 
			
		||||
	ClusterId int64
 | 
			
		||||
}) {
 | 
			
		||||
	countResp, err := this.RPC().NodeRPC().CountAllEnabledNodesMatch(this.AdminContext(), &pb.CountAllEnabledNodesMatchRequest{
 | 
			
		||||
		ClusterId: params.ClusterId,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
@@ -29,9 +34,10 @@ func (this *IndexAction) RunGet(params struct{}) {
 | 
			
		||||
	page := this.NewPage(countResp.Count)
 | 
			
		||||
	this.Data["page"] = page.AsHTML()
 | 
			
		||||
 | 
			
		||||
	nodesResp, err := this.RPC().NodeRPC().ListEnabledNodes(this.AdminContext(), &pb.ListEnabledNodesRequest{
 | 
			
		||||
		Offset: page.Offset,
 | 
			
		||||
		Size:   page.Size,
 | 
			
		||||
	nodesResp, err := this.RPC().NodeRPC().ListEnabledNodesMatch(this.AdminContext(), &pb.ListEnabledNodesMatchRequest{
 | 
			
		||||
		Offset:    page.Offset,
 | 
			
		||||
		Size:      page.Size,
 | 
			
		||||
		ClusterId: params.ClusterId,
 | 
			
		||||
	})
 | 
			
		||||
	nodeMaps := []maps.Map{}
 | 
			
		||||
	for _, node := range nodesResp.Nodes {
 | 
			
		||||
@@ -62,8 +68,9 @@ func (this *IndexAction) RunGet(params struct{}) {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		nodeMaps = append(nodeMaps, maps.Map{
 | 
			
		||||
			"id":   node.Id,
 | 
			
		||||
			"name": node.Name,
 | 
			
		||||
			"id":          node.Id,
 | 
			
		||||
			"name":        node.Name,
 | 
			
		||||
			"isInstalled": node.IsInstalled,
 | 
			
		||||
			"status": maps.Map{
 | 
			
		||||
				"isActive":     status.IsActive,
 | 
			
		||||
				"updatedAt":    status.UpdatedAt,
 | 
			
		||||
							
								
								
									
										26
									
								
								internal/web/actions/default/clusters/cluster/init.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								internal/web/actions/default/clusters/cluster/init.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
package cluster
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node"
 | 
			
		||||
	clusters "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/clusterutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
 | 
			
		||||
	"github.com/iwind/TeaGo"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	TeaGo.BeforeStart(func(server *TeaGo.Server) {
 | 
			
		||||
		server.
 | 
			
		||||
			Helper(helpers.NewUserMustAuth()).
 | 
			
		||||
			Helper(clusters.NewClusterHelper()).
 | 
			
		||||
			Prefix("/clusters/cluster").
 | 
			
		||||
			Get("", new(IndexAction)).
 | 
			
		||||
 | 
			
		||||
			// 节点相关
 | 
			
		||||
			Get("/node", new(node.NodeAction)).
 | 
			
		||||
			GetPost("/node/create", new(node.CreateAction)).
 | 
			
		||||
			GetPost("/node/update", new(node.UpdateAction)).
 | 
			
		||||
			GetPost("/node/install", new(node.InstallAction)).
 | 
			
		||||
			Post("/node/updateInstallStatus", new(node.UpdateInstallStatusAction)).
 | 
			
		||||
			EndAll()
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
package nodes
 | 
			
		||||
package node
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
@@ -13,28 +13,11 @@ type CreateAction struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *CreateAction) Init() {
 | 
			
		||||
	this.Nav("", "node", "create")
 | 
			
		||||
	this.Nav("", "node", "")
 | 
			
		||||
	this.SecondMenu("nodes")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *CreateAction) RunGet(params struct{}) {
 | 
			
		||||
	// 所有集群
 | 
			
		||||
	resp, err := this.RPC().NodeClusterRPC().FindAllEnabledClusters(this.AdminContext(), &pb.FindAllEnabledNodeClustersRequest{})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	clusterMaps := []maps.Map{}
 | 
			
		||||
	for _, cluster := range resp.Clusters {
 | 
			
		||||
		clusterMaps = append(clusterMaps, maps.Map{
 | 
			
		||||
			"id":   cluster.Id,
 | 
			
		||||
			"name": cluster.Name,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["clusters"] = clusterMaps
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,65 @@
 | 
			
		||||
package node
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/rpc/pb"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type InstallAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *InstallAction) Init() {
 | 
			
		||||
	this.Nav("", "node", "install")
 | 
			
		||||
	this.SecondMenu("nodes")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *InstallAction) RunGet(params struct {
 | 
			
		||||
	NodeId int64
 | 
			
		||||
}) {
 | 
			
		||||
	this.Data["nodeId"] = params.NodeId
 | 
			
		||||
 | 
			
		||||
	// 节点
 | 
			
		||||
	nodeResp, err := this.RPC().NodeRPC().FindEnabledNode(this.AdminContext(), &pb.FindEnabledNodeRequest{NodeId: params.NodeId})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	node := nodeResp.Node
 | 
			
		||||
	if node == nil {
 | 
			
		||||
		this.WriteString("找不到要操作的节点")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 集群
 | 
			
		||||
	var clusterMap maps.Map = nil
 | 
			
		||||
	if node.Cluster != nil {
 | 
			
		||||
		clusterId := node.Cluster.Id
 | 
			
		||||
		clusterResp, err := this.RPC().NodeClusterRPC().FindEnabledNodeCluster(this.AdminContext(), &pb.FindEnabledNodeClusterRequest{ClusterId: clusterId})
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			this.ErrorPage(err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		cluster := clusterResp.Cluster
 | 
			
		||||
		if cluster != nil {
 | 
			
		||||
			clusterMap = maps.Map{
 | 
			
		||||
				"id":         cluster.Id,
 | 
			
		||||
				"name":       cluster.Name,
 | 
			
		||||
				"installDir": cluster.InstallDir,
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Data["node"] = maps.Map{
 | 
			
		||||
		"id":          node.Id,
 | 
			
		||||
		"name":        node.Name,
 | 
			
		||||
		"installDir":  node.InstallDir,
 | 
			
		||||
		"isInstalled": node.IsInstalled,
 | 
			
		||||
		"uniqueId":    node.UniqueId,
 | 
			
		||||
		"secret":      node.Secret,
 | 
			
		||||
		"cluster":     clusterMap,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
package nodes
 | 
			
		||||
package node
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
@@ -13,7 +13,8 @@ type NodeAction struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *NodeAction) Init() {
 | 
			
		||||
	this.Nav("", "node", "index")
 | 
			
		||||
	this.Nav("", "node", "node")
 | 
			
		||||
	this.SecondMenu("nodes")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *NodeAction) RunGet(params struct {
 | 
			
		||||
@@ -34,9 +35,19 @@ func (this *NodeAction) RunGet(params struct {
 | 
			
		||||
 | 
			
		||||
	var clusterMap maps.Map = nil
 | 
			
		||||
	if node.Cluster != nil {
 | 
			
		||||
		clusterMap = maps.Map{
 | 
			
		||||
			"id":   node.Cluster.Id,
 | 
			
		||||
			"name": node.Cluster.Name,
 | 
			
		||||
		clusterId := node.Cluster.Id
 | 
			
		||||
		clusterResp, err := this.RPC().NodeClusterRPC().FindEnabledNodeCluster(this.AdminContext(), &pb.FindEnabledNodeClusterRequest{ClusterId: clusterId})
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			this.ErrorPage(err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		cluster := clusterResp.Cluster
 | 
			
		||||
		if cluster != nil {
 | 
			
		||||
			clusterMap = maps.Map{
 | 
			
		||||
				"id":         cluster.Id,
 | 
			
		||||
				"name":       cluster.Name,
 | 
			
		||||
				"installDir": cluster.InstallDir,
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -100,6 +111,10 @@ func (this *NodeAction) RunGet(params struct {
 | 
			
		||||
		"ipAddresses": ipAddressMaps,
 | 
			
		||||
		"cluster":     clusterMap,
 | 
			
		||||
		"login":       loginMap,
 | 
			
		||||
		"installDir":  node.InstallDir,
 | 
			
		||||
		"isInstalled": node.IsInstalled,
 | 
			
		||||
		"uniqueId":    node.UniqueId,
 | 
			
		||||
		"secret":      node.Secret,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
package nodes
 | 
			
		||||
package node
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
@@ -14,7 +14,8 @@ type UpdateAction struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *UpdateAction) Init() {
 | 
			
		||||
	this.Nav("", "node", "index")
 | 
			
		||||
	this.Nav("", "node", "update")
 | 
			
		||||
	this.SecondMenu("nodes")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *UpdateAction) RunGet(params struct {
 | 
			
		||||
@@ -104,7 +105,7 @@ func (this *UpdateAction) RunGet(params struct {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 所有集群
 | 
			
		||||
	resp, err := this.RPC().NodeClusterRPC().FindAllEnabledClusters(this.AdminContext(), &pb.FindAllEnabledNodeClustersRequest{})
 | 
			
		||||
	resp, err := this.RPC().NodeClusterRPC().FindAllEnabledNodeClusters(this.AdminContext(), &pb.FindAllEnabledNodeClustersRequest{})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
	}
 | 
			
		||||
@@ -0,0 +1,26 @@
 | 
			
		||||
package node
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/rpc/pb"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type UpdateInstallStatusAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *UpdateInstallStatusAction) RunPost(params struct {
 | 
			
		||||
	NodeId      int64
 | 
			
		||||
	IsInstalled bool
 | 
			
		||||
}) {
 | 
			
		||||
	_, err := this.RPC().NodeRPC().UpdateNodeIsInstalled(this.AdminContext(), &pb.UpdateNodeIsInstalledRequest{
 | 
			
		||||
		NodeId:      params.NodeId,
 | 
			
		||||
		IsInstalled: params.IsInstalled,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,89 @@
 | 
			
		||||
package settings
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/rpc/pb"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/nodes/grants/grantutils"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type IndexAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) Init() {
 | 
			
		||||
	this.Nav("", "setting", "")
 | 
			
		||||
	this.SecondMenu("basic")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) RunGet(params struct {
 | 
			
		||||
	ClusterId int64
 | 
			
		||||
}) {
 | 
			
		||||
	clusterResp, err := this.RPC().NodeClusterRPC().FindEnabledNodeCluster(this.AdminContext(), &pb.FindEnabledNodeClusterRequest{ClusterId: params.ClusterId})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	cluster := clusterResp.Cluster
 | 
			
		||||
	if cluster == nil {
 | 
			
		||||
		this.WriteString("not found cluster")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 认证
 | 
			
		||||
	var grantMap interface{} = nil
 | 
			
		||||
 | 
			
		||||
	if cluster.GrantId > 0 {
 | 
			
		||||
		grantResp, err := this.RPC().NodeGrantRPC().FindEnabledGrant(this.AdminContext(), &pb.FindEnabledGrantRequest{GrantId: cluster.GrantId})
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			this.ErrorPage(err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		grant := grantResp.Grant
 | 
			
		||||
		if grant != nil {
 | 
			
		||||
			grantMap = maps.Map{
 | 
			
		||||
				"id":         grant.Id,
 | 
			
		||||
				"name":       grant.Name,
 | 
			
		||||
				"method":     grant.Method,
 | 
			
		||||
				"methodName": grantutils.FindGrantMethodName(grant.Method),
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["grant"] = grantMap
 | 
			
		||||
 | 
			
		||||
	this.Data["cluster"] = maps.Map{
 | 
			
		||||
		"id":         cluster.Id,
 | 
			
		||||
		"name":       cluster.Name,
 | 
			
		||||
		"installDir": cluster.InstallDir,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 保存设置
 | 
			
		||||
func (this *IndexAction) RunPost(params struct {
 | 
			
		||||
	ClusterId  int64
 | 
			
		||||
	Name       string
 | 
			
		||||
	GrantId    int64
 | 
			
		||||
	InstallDir string
 | 
			
		||||
 | 
			
		||||
	Must *actions.Must
 | 
			
		||||
}) {
 | 
			
		||||
	params.Must.
 | 
			
		||||
		Field("name", params.Name).
 | 
			
		||||
		Require("请输入集群名称")
 | 
			
		||||
 | 
			
		||||
	_, err := this.RPC().NodeClusterRPC().UpdateNodeCluster(this.AdminContext(), &pb.UpdateNodeClusterRequest{
 | 
			
		||||
		ClusterId:  params.ClusterId,
 | 
			
		||||
		Name:       params.Name,
 | 
			
		||||
		GrantId:    params.GrantId,
 | 
			
		||||
		InstallDir: params.InstallDir,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,18 @@
 | 
			
		||||
package settings
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	clusters "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/clusterutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
 | 
			
		||||
	"github.com/iwind/TeaGo"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	TeaGo.BeforeStart(func(server *TeaGo.Server) {
 | 
			
		||||
		server.
 | 
			
		||||
			Helper(helpers.NewUserMustAuth()).
 | 
			
		||||
			Helper(clusters.NewClusterHelper()).
 | 
			
		||||
			Prefix("/clusters/cluster/settings").
 | 
			
		||||
			GetPost("", new(IndexAction)).
 | 
			
		||||
			EndAll()
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,84 @@
 | 
			
		||||
package clusters
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/rpc"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/rpc/pb"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
	"github.com/iwind/TeaGo/logs"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"strconv"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type ClusterHelper struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewClusterHelper() *ClusterHelper {
 | 
			
		||||
	return &ClusterHelper{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *ClusterHelper) BeforeAction(action *actions.ActionObject) {
 | 
			
		||||
	if action.Request.Method != http.MethodGet {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	action.Data["teaMenu"] = "clusters"
 | 
			
		||||
 | 
			
		||||
	selectedTabbar := action.Data.GetString("mainTab")
 | 
			
		||||
	clusterId := action.ParamInt64("clusterId")
 | 
			
		||||
	clusterIdString := strconv.FormatInt(clusterId, 10)
 | 
			
		||||
	action.Data["clusterId"] = clusterId
 | 
			
		||||
 | 
			
		||||
	rpcClient, err := rpc.SharedRPC()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logs.Error(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	clusterResp, err := rpcClient.NodeClusterRPC().FindEnabledNodeCluster(rpcClient.Context(action.Context.GetInt64("adminId")), &pb.FindEnabledNodeClusterRequest{ClusterId: clusterId})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logs.Error(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	cluster := clusterResp.Cluster
 | 
			
		||||
	if cluster == nil {
 | 
			
		||||
		action.WriteString("can not find cluster")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tabbar := actionutils.NewTabbar()
 | 
			
		||||
	tabbar.Add("当前集群:"+cluster.Name, "", "/clusters", "left long alternate arrow", false)
 | 
			
		||||
	tabbar.Add("节点", "", "/clusters/cluster?clusterId="+clusterIdString, "server", selectedTabbar == "node")
 | 
			
		||||
	tabbar.Add("设置", "", "/clusters/cluster/settings?clusterId="+clusterIdString, "setting", selectedTabbar == "setting")
 | 
			
		||||
	actionutils.SetTabbar(action, tabbar)
 | 
			
		||||
 | 
			
		||||
	// 左侧菜单
 | 
			
		||||
	secondMenuItem := action.Data.GetString("secondMenuItem")
 | 
			
		||||
	switch selectedTabbar {
 | 
			
		||||
	case "setting":
 | 
			
		||||
		action.Data["leftMenuItems"] = this.createSettingMenu(clusterIdString, secondMenuItem)
 | 
			
		||||
	case "node":
 | 
			
		||||
		action.Data["leftMenuItems"] = this.createNodeMenu(clusterIdString, secondMenuItem)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 节点菜单
 | 
			
		||||
func (this *ClusterHelper) createNodeMenu(clusterId string, selectedItem string) (items []maps.Map) {
 | 
			
		||||
	items = append(items, maps.Map{
 | 
			
		||||
		"name":     "节点列表",
 | 
			
		||||
		"url":      "/clusters/cluster?clusterId=" + clusterId,
 | 
			
		||||
		"isActive": selectedItem == "nodes",
 | 
			
		||||
	})
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 设置菜单
 | 
			
		||||
func (this *ClusterHelper) createSettingMenu(clusterId string, selectedItem string) (items []maps.Map) {
 | 
			
		||||
	items = append(items, maps.Map{
 | 
			
		||||
		"name":     "基础设置",
 | 
			
		||||
		"url":      "/clusters/cluster/settings?clusterId=" + clusterId,
 | 
			
		||||
		"isActive": selectedItem == "basic",
 | 
			
		||||
	})
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										43
									
								
								internal/web/actions/default/clusters/create.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								internal/web/actions/default/clusters/create.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
package clusters
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/rpc/pb"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type CreateAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *CreateAction) Init() {
 | 
			
		||||
	this.Nav("", "cluster", "create")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *CreateAction) RunGet(params struct{}) {
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *CreateAction) RunPost(params struct {
 | 
			
		||||
	Name       string
 | 
			
		||||
	GrantId    int64
 | 
			
		||||
	InstallDir string
 | 
			
		||||
 | 
			
		||||
	Must *actions.Must
 | 
			
		||||
}) {
 | 
			
		||||
	params.Must.
 | 
			
		||||
		Field("name", params.Name).
 | 
			
		||||
		Require("请输入集群名称")
 | 
			
		||||
 | 
			
		||||
	_, err := this.RPC().NodeClusterRPC().CreateNodeCluster(this.AdminContext(), &pb.CreateNodeClusterRequest{
 | 
			
		||||
		Name:       params.Name,
 | 
			
		||||
		GrantId:    params.GrantId,
 | 
			
		||||
		InstallDir: params.InstallDir,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										23
									
								
								internal/web/actions/default/clusters/helper.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								internal/web/actions/default/clusters/helper.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
package clusters
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Helper struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewHelper() *Helper {
 | 
			
		||||
	return &Helper{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Helper) BeforeAction(action *actions.ActionObject) {
 | 
			
		||||
	action.Data["teaMenu"] = "clusters"
 | 
			
		||||
 | 
			
		||||
	selectedTabbar, _ := action.Data["mainTab"]
 | 
			
		||||
 | 
			
		||||
	tabbar := actionutils.NewTabbar()
 | 
			
		||||
	tabbar.Add("集群", "", "/clusters", "", selectedTabbar == "cluster")
 | 
			
		||||
	actionutils.SetTabbar(action, tabbar)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										57
									
								
								internal/web/actions/default/clusters/index.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								internal/web/actions/default/clusters/index.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,57 @@
 | 
			
		||||
package clusters
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/rpc/pb"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type IndexAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) Init() {
 | 
			
		||||
	this.Nav("", "cluster", "index")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) RunGet(params struct{}) {
 | 
			
		||||
	countResp, err := this.RPC().NodeClusterRPC().CountAllEnabledNodeClusters(this.AdminContext(), &pb.CountAllEnabledNodeClustersRequest{})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	count := countResp.Count
 | 
			
		||||
	page := this.NewPage(count)
 | 
			
		||||
	this.Data["page"] = page.AsHTML()
 | 
			
		||||
 | 
			
		||||
	clusterMaps := []maps.Map{}
 | 
			
		||||
	if count > 0 {
 | 
			
		||||
		clustersResp, err := this.RPC().NodeClusterRPC().ListEnabledNodeClusters(this.AdminContext(), &pb.ListEnabledNodeClustersRequest{
 | 
			
		||||
			Offset: page.Offset,
 | 
			
		||||
			Size:   page.Size,
 | 
			
		||||
		})
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			this.ErrorPage(err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		for _, cluster := range clustersResp.Clusters {
 | 
			
		||||
			// 节点数量
 | 
			
		||||
			countNodesResp, err := this.RPC().NodeRPC().CountAllEnabledNodesMatch(this.AdminContext(), &pb.CountAllEnabledNodesMatchRequest{ClusterId: cluster.Id})
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				this.ErrorPage(err)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			clusterMaps = append(clusterMaps, maps.Map{
 | 
			
		||||
				"id":         cluster.Id,
 | 
			
		||||
				"name":       cluster.Name,
 | 
			
		||||
				"installDir": cluster.InstallDir,
 | 
			
		||||
				"hasGrant":   cluster.GrantId > 0,
 | 
			
		||||
				"countNodes": countNodesResp.Count,
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["clusters"] = clusterMaps
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										18
									
								
								internal/web/actions/default/clusters/init.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								internal/web/actions/default/clusters/init.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
			
		||||
package clusters
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
 | 
			
		||||
	"github.com/iwind/TeaGo"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	TeaGo.BeforeStart(func(server *TeaGo.Server) {
 | 
			
		||||
		server.
 | 
			
		||||
			Helper(helpers.NewUserMustAuth()).
 | 
			
		||||
			Helper(NewHelper()).
 | 
			
		||||
			Prefix("/clusters").
 | 
			
		||||
			Get("", new(IndexAction)).
 | 
			
		||||
			GetPost("/create", new(CreateAction)).
 | 
			
		||||
			EndAll()
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
@@ -15,7 +15,7 @@ func (this *ChangedClustersAction) Init() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *ChangedClustersAction) RunGet(params struct{}) {
 | 
			
		||||
	resp, err := this.RPC().NodeClusterRPC().FindAllChangedClusters(this.AdminContext(), &pb.FindAllChangedClustersRequest{})
 | 
			
		||||
	resp, err := this.RPC().NodeClusterRPC().FindAllChangedNodeClusters(this.AdminContext(), &pb.FindAllChangedNodeClustersRequest{})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@ func (this *SyncClustersAction) RunPost(params struct{}) {
 | 
			
		||||
	// TODO 将来可以单独选择某一个集群进行单独的同步
 | 
			
		||||
 | 
			
		||||
	// 所有有变化的集群
 | 
			
		||||
	clustersResp, err := this.RPC().NodeClusterRPC().FindAllChangedClusters(this.AdminContext(), &pb.FindAllChangedClustersRequest{})
 | 
			
		||||
	clustersResp, err := this.RPC().NodeClusterRPC().FindAllChangedNodeClusters(this.AdminContext(), &pb.FindAllChangedNodeClustersRequest{})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
 
 | 
			
		||||
@@ -13,11 +13,7 @@ func init() {
 | 
			
		||||
			Helper(new(helpers.UserMustAuth)).
 | 
			
		||||
			Helper(new(Helper)).
 | 
			
		||||
			Prefix("/nodes").
 | 
			
		||||
			Get("", new(IndexAction)).
 | 
			
		||||
			GetPost("/create", new(CreateAction)).
 | 
			
		||||
			Post("/delete", new(DeleteAction)).
 | 
			
		||||
			GetPost("/update", new(UpdateAction)).
 | 
			
		||||
			Get("/node", new(NodeAction)).
 | 
			
		||||
 | 
			
		||||
			// IP地址
 | 
			
		||||
			GetPost("/ipAddresses/createPopup", new(ipAddresses.CreatePopupAction)).
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ func (this *CreateAction) Init() {
 | 
			
		||||
 | 
			
		||||
func (this *CreateAction) RunGet(params struct{}) {
 | 
			
		||||
	// 所有集群
 | 
			
		||||
	resp, err := this.RPC().NodeClusterRPC().FindAllEnabledClusters(this.AdminContext(), &pb.FindAllEnabledNodeClustersRequest{})
 | 
			
		||||
	resp, err := this.RPC().NodeClusterRPC().FindAllEnabledNodeClusters(this.AdminContext(), &pb.FindAllEnabledNodeClustersRequest{})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -71,7 +71,7 @@ func (this *ServerHelper) createLeftMenu(action *actions.ActionObject) {
 | 
			
		||||
	// TABBAR
 | 
			
		||||
	selectedTabbar, _ := action.Data["mainTab"]
 | 
			
		||||
	tabbar := actionutils.NewTabbar()
 | 
			
		||||
	tabbar.Add("当前:"+serverConfig.Name, "", "/servers", "left long alternate arrow", false)
 | 
			
		||||
	tabbar.Add("当前服务:"+serverConfig.Name, "", "/servers", "left long alternate arrow", false)
 | 
			
		||||
	tabbar.Add("看板", "", "/servers/server/board?serverId="+serverIdString, "dashboard", selectedTabbar == "board")
 | 
			
		||||
	tabbar.Add("日志", "", "/servers/server/log?serverId="+serverIdString, "history", selectedTabbar == "log")
 | 
			
		||||
	tabbar.Add("统计", "", "/servers/server/stat?serverId="+serverIdString, "chart area", selectedTabbar == "stat")
 | 
			
		||||
 
 | 
			
		||||
@@ -67,13 +67,18 @@ func (this *UserMustAuth) BeforeAction(actionPtr actions.ActionWrapper, paramNam
 | 
			
		||||
	modules := []map[string]interface{}{
 | 
			
		||||
		{
 | 
			
		||||
			"code":     "servers",
 | 
			
		||||
			"menuName": "服务管理",
 | 
			
		||||
			"menuName": "代理服务",
 | 
			
		||||
			"icon":     "clone outsize",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"code":     "nodes",
 | 
			
		||||
			"menuName": "节点管理",
 | 
			
		||||
			"icon":     "server",
 | 
			
		||||
			"code":     "clusters",
 | 
			
		||||
			"menuName": "节点集群",
 | 
			
		||||
			"icon":     "cloud",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"code":     "api",
 | 
			
		||||
			"menuName": "API节点",
 | 
			
		||||
			"icon":     "exchange",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,11 @@
 | 
			
		||||
package web
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/api"
 | 
			
		||||
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/api/node"
 | 
			
		||||
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters"
 | 
			
		||||
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster"
 | 
			
		||||
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings"
 | 
			
		||||
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/common"
 | 
			
		||||
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/dashboard"
 | 
			
		||||
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/index"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								web/public/js/components/api-node/api-node-selector.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								web/public/js/components/api-node/api-node-selector.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
Vue.component("api-node-selector", {
 | 
			
		||||
	props: [],
 | 
			
		||||
	data: function () {
 | 
			
		||||
		return {}
 | 
			
		||||
	},
 | 
			
		||||
	template: `<div>
 | 
			
		||||
	暂未实现
 | 
			
		||||
</div>`
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										23
									
								
								web/public/js/components/common/inner-menu-item.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								web/public/js/components/common/inner-menu-item.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
/**
 | 
			
		||||
 * 菜单项
 | 
			
		||||
 */
 | 
			
		||||
Vue.component("inner-menu-item", {
 | 
			
		||||
	props: ["href", "active", "code"],
 | 
			
		||||
	data: function () {
 | 
			
		||||
		var active = this.active;
 | 
			
		||||
		if (typeof(active) =="undefined") {
 | 
			
		||||
			var itemCode = "";
 | 
			
		||||
			if (typeof (window.TEA.ACTION.data.firstMenuItem) != "undefined") {
 | 
			
		||||
				itemCode = window.TEA.ACTION.data.firstMenuItem;
 | 
			
		||||
			}
 | 
			
		||||
			active = (itemCode == this.code);
 | 
			
		||||
		}
 | 
			
		||||
		return {
 | 
			
		||||
			vHref: (this.href == null) ? "" : this.href,
 | 
			
		||||
			vActive: active
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	template: '\
 | 
			
		||||
		<a :href="vHref" class="item right" style="color:#4183c4" :class="{active:vActive}">[<slot></slot>]</a> \
 | 
			
		||||
		'
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										11
									
								
								web/public/js/components/common/inner-menu.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								web/public/js/components/common/inner-menu.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
/**
 | 
			
		||||
 * 二级菜单
 | 
			
		||||
 */
 | 
			
		||||
Vue.component("inner-menu", {
 | 
			
		||||
	template: `
 | 
			
		||||
		<div class="second-menu" style="width:80%;position: absolute;top:-8px;right:1em"> 
 | 
			
		||||
			<div class="ui menu text blue small">
 | 
			
		||||
				<slot></slot>
 | 
			
		||||
			</div> 
 | 
			
		||||
		</div>`
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										16
									
								
								web/public/js/components/common/page-box.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								web/public/js/components/common/page-box.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
Vue.component("page-box", {
 | 
			
		||||
	data: function () {
 | 
			
		||||
		return {
 | 
			
		||||
			page: ""
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	created: function () {
 | 
			
		||||
		let that = this;
 | 
			
		||||
		setTimeout(function () {
 | 
			
		||||
			that.page = Tea.Vue.page;
 | 
			
		||||
		})
 | 
			
		||||
	},
 | 
			
		||||
	template: `<div>
 | 
			
		||||
	<div class="page" v-html="page"></div>
 | 
			
		||||
</div>`
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										63
									
								
								web/public/js/components/grant/grant-selector.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								web/public/js/components/grant/grant-selector.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
			
		||||
Vue.component("grant-selector", {
 | 
			
		||||
	props: ["vGrant"],
 | 
			
		||||
	data: function () {
 | 
			
		||||
		return {
 | 
			
		||||
			grantId: (this.vGrant == null) ? 0 : this.vGrant.id,
 | 
			
		||||
			grant: this.vGrant
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		// 选择授权
 | 
			
		||||
		select: function () {
 | 
			
		||||
			let that = this;
 | 
			
		||||
			teaweb.popup("/nodes/grants/selectPopup", {
 | 
			
		||||
				callback: (resp) => {
 | 
			
		||||
					that.grantId = resp.data.grant.id;
 | 
			
		||||
					if (that.grantId > 0) {
 | 
			
		||||
						that.grant = resp.data.grant;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		// 创建授权
 | 
			
		||||
		create: function () {
 | 
			
		||||
			teaweb.popup("/nodes/grants/createPopup", {
 | 
			
		||||
				height: "31em",
 | 
			
		||||
				callback: (resp) => {
 | 
			
		||||
					this.grantId = resp.data.grant.id;
 | 
			
		||||
					if (this.grantId > 0) {
 | 
			
		||||
						this.grant = resp.data.grant;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		// 修改授权
 | 
			
		||||
		update: function () {
 | 
			
		||||
			if (this.grant == null) {
 | 
			
		||||
				window.location.reload();
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			teaweb.popup("/nodes/grants/updatePopup?grantId=" + this.grant.id, {
 | 
			
		||||
				height: "31em",
 | 
			
		||||
				callback: (resp) => {
 | 
			
		||||
					this.grant = resp.data.grant;
 | 
			
		||||
				}
 | 
			
		||||
			})
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		// 删除已选择授权
 | 
			
		||||
		remove: function () {
 | 
			
		||||
			this.grant = null;
 | 
			
		||||
			this.grantId = 0;
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	template: `<div>
 | 
			
		||||
	<input type="hidden" name="grantId" :value="grantId"/>
 | 
			
		||||
	<div class="ui label small" v-if="grant != null">{{grant.name}}<span class="small">({{grant.methodName}})</span> <a href="" title="修改" @click.prevent="update()"><i class="icon pencil small"></i></a> <a href="" title="删除" @click.prevent="remove()"><i class="icon remove"></i></a> </div>
 | 
			
		||||
	<div v-if="grant == null">
 | 
			
		||||
		<a href="" @click.prevent="select()">[选择已有认证]</a>     <a href="" @click.prevent="create()">[添加新认证]</a>
 | 
			
		||||
	</div>
 | 
			
		||||
</div>`
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										51
									
								
								web/public/js/components/node/node-ip-addresses-box.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								web/public/js/components/node/node-ip-addresses-box.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
Vue.component("node-ip-addresses-box", {
 | 
			
		||||
	props: ["vIpAddresses"],
 | 
			
		||||
	data: function () {
 | 
			
		||||
		return {
 | 
			
		||||
			ipAddresses: (this.vIpAddresses == null) ? [] : this.vIpAddresses
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		// 添加IP地址
 | 
			
		||||
		addIPAddress: function () {
 | 
			
		||||
			let that = this;
 | 
			
		||||
			teaweb.popup("/nodes/ipAddresses/createPopup", {
 | 
			
		||||
				callback: function (resp) {
 | 
			
		||||
					that.ipAddresses.push(resp.data.ipAddress);
 | 
			
		||||
				}
 | 
			
		||||
			})
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		// 修改地址
 | 
			
		||||
		updateIPAddress: function (index, address) {
 | 
			
		||||
			let that = this;
 | 
			
		||||
			teaweb.popup("/nodes/ipAddresses/updatePopup?addressId=" + address.id, {
 | 
			
		||||
				callback: function (resp) {
 | 
			
		||||
					Vue.set(that.ipAddresses, index, resp.data.ipAddress);
 | 
			
		||||
				}
 | 
			
		||||
			})
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		// 删除IP地址
 | 
			
		||||
		removeIPAddress: function (index) {
 | 
			
		||||
			this.ipAddresses.$remove(index);
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	template: `<div>
 | 
			
		||||
	<input type="hidden" name="ipAddresses" :value="JSON.stringify(ipAddresses)"/>
 | 
			
		||||
	<div v-if="ipAddresses.length > 0">
 | 
			
		||||
		<div>
 | 
			
		||||
			<div v-for="(address, index) in ipAddresses" class="ui label small">
 | 
			
		||||
				{{address.ip}}<span class="small" v-if="address.name.length > 0">({{address.name}})</span>
 | 
			
		||||
				<a href="" title="修改" @click.prevent="updateIPAddress(index, address)"><i class="icon pencil small"></i></a>
 | 
			
		||||
				<a href="" title="删除" @click.prevent="removeIPAddress(index)"><i class="icon remove"></i></a>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div class="ui divider"></div>
 | 
			
		||||
	</div>
 | 
			
		||||
	<div>
 | 
			
		||||
		<button class="ui button small" type="button" @click.prevent="addIPAddress()">+</button>
 | 
			
		||||
	</div>
 | 
			
		||||
	<p class="comment">添加已经绑定的IP地址,仅做记录用。</p>
 | 
			
		||||
</div>`
 | 
			
		||||
})
 | 
			
		||||
@@ -1,3 +1,54 @@
 | 
			
		||||
.left-box {
 | 
			
		||||
  width: 8em;
 | 
			
		||||
  position: fixed;
 | 
			
		||||
  top: 7.5em;
 | 
			
		||||
  bottom: 0.5em;
 | 
			
		||||
  overflow-y: auto;
 | 
			
		||||
  overflow-x: hidden;
 | 
			
		||||
  border-right: 1px #ddd solid;
 | 
			
		||||
}
 | 
			
		||||
.left-box .menu {
 | 
			
		||||
  width: 90% !important;
 | 
			
		||||
}
 | 
			
		||||
.left-box .menu .item {
 | 
			
		||||
  line-height: 1.2;
 | 
			
		||||
  position: relative;
 | 
			
		||||
  padding-left: 1em !important;
 | 
			
		||||
}
 | 
			
		||||
.left-box .menu .item .icon {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  top: 50%;
 | 
			
		||||
  left: 0;
 | 
			
		||||
  margin-top: -0.4em !important;
 | 
			
		||||
}
 | 
			
		||||
.left-box .menu .item.separator {
 | 
			
		||||
  border-bottom: 1px #eee solid !important;
 | 
			
		||||
  padding-top: 0;
 | 
			
		||||
  padding-bottom: 0;
 | 
			
		||||
  margin-top: 0 !important;
 | 
			
		||||
  margin-bottom: 0 !important;
 | 
			
		||||
}
 | 
			
		||||
.left-box .menu .header {
 | 
			
		||||
  border-bottom: 1px #ddd solid;
 | 
			
		||||
  padding-left: 0 !important;
 | 
			
		||||
  padding-bottom: 1em !important;
 | 
			
		||||
}
 | 
			
		||||
.left-box::-webkit-scrollbar {
 | 
			
		||||
  width: 4px;
 | 
			
		||||
}
 | 
			
		||||
.right-box {
 | 
			
		||||
  position: fixed;
 | 
			
		||||
  top: 7.5em;
 | 
			
		||||
  bottom: 0;
 | 
			
		||||
  right: 0;
 | 
			
		||||
  left: 18em;
 | 
			
		||||
  padding-right: 2em;
 | 
			
		||||
  padding-bottom: 1em;
 | 
			
		||||
  overflow-y: auto;
 | 
			
		||||
}
 | 
			
		||||
.right-box::-webkit-scrollbar {
 | 
			
		||||
  width: 4px;
 | 
			
		||||
}
 | 
			
		||||
/** 通用 **/
 | 
			
		||||
.clear {
 | 
			
		||||
  clear: both;
 | 
			
		||||
@@ -235,6 +286,7 @@ body.expanded .main {
 | 
			
		||||
.main h3 {
 | 
			
		||||
  font-weight: normal;
 | 
			
		||||
  margin-top: 1em !important;
 | 
			
		||||
  position: relative;
 | 
			
		||||
}
 | 
			
		||||
.main h3 span {
 | 
			
		||||
  font-size: 0.8em;
 | 
			
		||||
@@ -247,12 +299,6 @@ body.expanded .main {
 | 
			
		||||
  font-size: 14px !important;
 | 
			
		||||
  right: 1em;
 | 
			
		||||
}
 | 
			
		||||
.main h3 a::before {
 | 
			
		||||
  content: "[";
 | 
			
		||||
}
 | 
			
		||||
.main h3 a::after {
 | 
			
		||||
  content: "]";
 | 
			
		||||
}
 | 
			
		||||
.main h4 {
 | 
			
		||||
  font-weight: normal;
 | 
			
		||||
}
 | 
			
		||||
@@ -601,4 +647,7 @@ var.dash {
 | 
			
		||||
.swal2-cancel {
 | 
			
		||||
  margin-left: 2em !important;
 | 
			
		||||
}
 | 
			
		||||
form .fields {
 | 
			
		||||
  margin-bottom: 0 !important;
 | 
			
		||||
}
 | 
			
		||||
/*# sourceMappingURL=@layout.css.map */
 | 
			
		||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@@ -67,6 +67,14 @@ window.NotifySuccess = function (message, url, params) {
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
window.NotifyReloadSuccess = function (message) {
 | 
			
		||||
	return function () {
 | 
			
		||||
		teaweb.success(message, function () {
 | 
			
		||||
			window.location.reload()
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
window.NotifyDelete = function (message, url, params) {
 | 
			
		||||
	teaweb.confirm(message, function () {
 | 
			
		||||
		Tea.Vue.$post(url)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,5 @@
 | 
			
		||||
@import "./@left_menu";
 | 
			
		||||
 | 
			
		||||
/** 通用 **/
 | 
			
		||||
.clear {
 | 
			
		||||
	clear: both;
 | 
			
		||||
@@ -283,6 +285,7 @@ body.expanded .main {
 | 
			
		||||
.main h3 {
 | 
			
		||||
	font-weight: normal;
 | 
			
		||||
	margin-top: 1em !important;
 | 
			
		||||
	position: relative;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.main h3 span {
 | 
			
		||||
@@ -299,14 +302,6 @@ body.expanded .main {
 | 
			
		||||
	right: 1em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.main h3 a::before {
 | 
			
		||||
	content: "[";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.main h3 a::after {
 | 
			
		||||
	content: "]";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.main h4 {
 | 
			
		||||
	font-weight: normal;
 | 
			
		||||
}
 | 
			
		||||
@@ -725,3 +720,10 @@ var.dash {
 | 
			
		||||
.swal2-cancel {
 | 
			
		||||
	margin-left: 2em !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// fields
 | 
			
		||||
form {
 | 
			
		||||
	.fields {
 | 
			
		||||
		margin-bottom: 0 !important;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -48,5 +48,16 @@
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.right-box {
 | 
			
		||||
	margin-left: 9em;
 | 
			
		||||
	position: fixed;
 | 
			
		||||
	top: 7.5em;
 | 
			
		||||
	bottom: 0;
 | 
			
		||||
	right: 0;
 | 
			
		||||
	left: 18em;
 | 
			
		||||
	padding-right: 2em;
 | 
			
		||||
	padding-bottom: 1em;
 | 
			
		||||
	overflow-y: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.right-box::-webkit-scrollbar {
 | 
			
		||||
	width: 4px;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										4
									
								
								web/views/@default/api/@menu.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								web/views/@default/api/@menu.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
<first-menu>
 | 
			
		||||
	<menu-item href="/api" code="index">节点列表</menu-item>
 | 
			
		||||
	<menu-item href="/api/node/create" code="create">创建节点</menu-item>
 | 
			
		||||
</first-menu>
 | 
			
		||||
							
								
								
									
										26
									
								
								web/views/@default/api/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								web/views/@default/api/index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "menu"}
 | 
			
		||||
 | 
			
		||||
<p class="comment" v-if="nodes.length == 0">暂时还没有节点。</p>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<table class="ui table selectable" v-if="nodes.length > 0">
 | 
			
		||||
	<thead>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<th>节点名称</th>
 | 
			
		||||
			<th>主机地址</th>
 | 
			
		||||
			<th>端口</th>
 | 
			
		||||
			<th class="two op">操作</th>
 | 
			
		||||
		</tr>
 | 
			
		||||
	</thead>
 | 
			
		||||
	<tr v-for="node in nodes">
 | 
			
		||||
		<td>{{node.name}}</td>
 | 
			
		||||
		<td>{{node.host}}</td>
 | 
			
		||||
		<td>{{node.port}}</td>
 | 
			
		||||
		<td>
 | 
			
		||||
			<a :href="'/api/node/settings?nodeId=' + node.id">设置</a>
 | 
			
		||||
		</td>
 | 
			
		||||
	</tr>
 | 
			
		||||
</table>
 | 
			
		||||
 | 
			
		||||
<div class="page" v-html="page"></div>
 | 
			
		||||
							
								
								
									
										40
									
								
								web/views/@default/api/node/create.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								web/views/@default/api/node/create.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "../menu"}
 | 
			
		||||
<div class="margin"></div>
 | 
			
		||||
<form class="ui form" data-tea-action="$" data-tea-success="success">
 | 
			
		||||
	<table class="ui table selectable definition">
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td class="title">节点名称 *</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<input type="text" name="name" maxlength="100" ref="focus"/>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>主机地址 *</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<input type="text" name="host" maxlength="100"/>
 | 
			
		||||
				<p class="comment">IP地址或者域名。</p>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>端口 *</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<input type="text" name="port" maxlength="5" style="width:6em"/>
 | 
			
		||||
				<p class="comment">1-65535之间。</p>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td colspan="2"><more-options-indicator></more-options-indicator></td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tbody v-show="moreOptionsVisible">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td>描述</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<textarea name="description" maxlength="200" rows="3"></textarea>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
		</tbody>
 | 
			
		||||
	</table>
 | 
			
		||||
	<submit-btn></submit-btn>
 | 
			
		||||
</form>
 | 
			
		||||
							
								
								
									
										3
									
								
								web/views/@default/api/node/create.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								web/views/@default/api/node/create.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
	this.success = NotifySuccess("保存成功", "/api")
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										43
									
								
								web/views/@default/api/node/settings.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								web/views/@default/api/node/settings.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "/left_menu"}
 | 
			
		||||
 | 
			
		||||
<div class="right-box">
 | 
			
		||||
	<form class="ui form" data-tea-action="$" data-tea-success="success">
 | 
			
		||||
		<input type="hidden" name="nodeId" :value="node.id"/>
 | 
			
		||||
		<table class="ui table selectable definition">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td class="title">节点名称 *</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<input type="text" name="name" maxlength="100" ref="focus" v-model="node.name"/>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td>主机地址 *</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<input type="text" name="host" maxlength="100" v-model="node.host"/>
 | 
			
		||||
					<p class="comment">IP地址或者域名。</p>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td>端口 *</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<input type="text" name="port" maxlength="5" style="width:6em" v-model="node.port"/>
 | 
			
		||||
					<p class="comment">1-65535之间。</p>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td colspan="2"><more-options-indicator></more-options-indicator></td>
 | 
			
		||||
			</tr>
 | 
			
		||||
			<tbody v-show="moreOptionsVisible">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td>描述</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<textarea name="description" maxlength="200" rows="3" v-model="node.description"></textarea>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
			</tbody>
 | 
			
		||||
		</table>
 | 
			
		||||
		<submit-btn></submit-btn>
 | 
			
		||||
	</form>
 | 
			
		||||
</div>
 | 
			
		||||
							
								
								
									
										3
									
								
								web/views/@default/api/node/settings.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								web/views/@default/api/node/settings.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
	this.success = NotifySuccess("保存成功", "/api/node/settings?nodeId=" + this.node.id)
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										4
									
								
								web/views/@default/clusters/@menu.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								web/views/@default/clusters/@menu.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
<first-menu>
 | 
			
		||||
	<menu-item href="/clusters" code="index">集群列表</menu-item>
 | 
			
		||||
	<menu-item href="/clusters/create" code="create">创建集群</menu-item>
 | 
			
		||||
</first-menu>
 | 
			
		||||
							
								
								
									
										4
									
								
								web/views/@default/clusters/cluster/index.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								web/views/@default/clusters/cluster/index.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
.table .label {
 | 
			
		||||
  margin-bottom: 0.5em;
 | 
			
		||||
}
 | 
			
		||||
/*# sourceMappingURL=index.css.map */
 | 
			
		||||
@@ -1 +1 @@
 | 
			
		||||
{"version":3,"sources":["index.less"],"names":[],"mappings":"AAAA,YACC;EACC,cAAA;EACA,oBAAA","file":"index.css"}
 | 
			
		||||
{"version":3,"sources":["index.less"],"names":[],"mappings":"AAAA,MAAO;EACN,oBAAA","file":"index.css"}
 | 
			
		||||
							
								
								
									
										87
									
								
								web/views/@default/clusters/cluster/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								web/views/@default/clusters/cluster/index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "/left_menu"}
 | 
			
		||||
 | 
			
		||||
<div class="right-box">
 | 
			
		||||
	<second-menu>
 | 
			
		||||
		<menu-item :href="'/clusters/cluster/node/create?clusterId=' + clusterId">添加节点</menu-item>
 | 
			
		||||
		<menu-item>安装节点</menu-item>
 | 
			
		||||
	</second-menu>
 | 
			
		||||
 | 
			
		||||
	<h3>节点列表</h3>
 | 
			
		||||
 | 
			
		||||
	<p class="comment" v-if="nodes.length == 0">暂时还没有节点。</p>
 | 
			
		||||
 | 
			
		||||
	<div v-show="nodes.length > 0">
 | 
			
		||||
		<form class="ui form segment" action="/clusters/cluster">
 | 
			
		||||
			<input type="hidden" name="clusterId" :value="clusterId"/>
 | 
			
		||||
			<div class="ui fields inline">
 | 
			
		||||
				<div class="ui field">
 | 
			
		||||
					安装状态:
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="ui field">
 | 
			
		||||
					<select class="ui dropdown" name="installedState">
 | 
			
		||||
						<option value="0">[全部]</option>
 | 
			
		||||
						<option value="1">已安装</option>
 | 
			
		||||
						<option value="2">未安装</option>
 | 
			
		||||
					</select>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="ui field">
 | 
			
		||||
					<button class="ui button" type="submit">搜索</button>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
		</form>
 | 
			
		||||
	</div>
 | 
			
		||||
 | 
			
		||||
	<table class="ui table selectable" v-if="nodes.length > 0">
 | 
			
		||||
		<thead>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<th>ID</th>
 | 
			
		||||
			<th>节点名称</th>
 | 
			
		||||
			<th>主机名</th>
 | 
			
		||||
			<th>IP</th>
 | 
			
		||||
			<th>CPU</th>
 | 
			
		||||
			<th>内存</th>
 | 
			
		||||
			<!--<th>流量</th>
 | 
			
		||||
			<th>连接数</th>-->
 | 
			
		||||
			<th>状态</th>
 | 
			
		||||
			<th class="two op">操作</th>
 | 
			
		||||
		</tr>
 | 
			
		||||
		</thead>
 | 
			
		||||
		<tr v-for="node in nodes">
 | 
			
		||||
			<td>{{node.id}}</td>
 | 
			
		||||
			<td>{{node.name}}</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<span v-if="node.status.hostname != null && node.status.hostname.length > 0">{{node.status.hostname}}</span>
 | 
			
		||||
				<span v-else>-</span>
 | 
			
		||||
			</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<span v-if="node.ipAddresses.length == 0">-</span>
 | 
			
		||||
				<div v-else class="address-box">
 | 
			
		||||
					<div v-for="addr in node.ipAddresses" class="ui label small">{{addr.ip}} <span class="small">({{addr.name}})</span></div>
 | 
			
		||||
				</div>
 | 
			
		||||
			</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<span v-if="node.status.isActive" :class="{red:node.status.cpuUsage > 0.80}">{{node.status.cpuUsageText}}</span>
 | 
			
		||||
				<span v-else>-</span>
 | 
			
		||||
			</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<span v-if="node.status.isActive" :class="{red:node.status.memUsage > 0.80}">{{node.status.memUsageText}}</span>
 | 
			
		||||
				<span v-else>-</span>
 | 
			
		||||
			</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<div v-if="node.isInstalled">
 | 
			
		||||
					<span v-if="node.status.isActive"><span class="green">运行中</span></span>
 | 
			
		||||
					<span v-else-if="node.status.updatedAt > 0" class="red">已断开</span>
 | 
			
		||||
					<span v-else-if="node.status.updatedAt == 0" class="red">未连接</span>
 | 
			
		||||
				</div>
 | 
			
		||||
				<span v-else class="red">未安装</span>
 | 
			
		||||
			</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<a :href="'/clusters/cluster/node?clusterId=' + clusterId + '&nodeId=' + node.id">详情</a>   <a href="" @click.prevent="deleteNode(node.id)">删除</a>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
	</table>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	<div class="page" v-html="page"></div>
 | 
			
		||||
</div>
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
	this.deleteNode = function (nodeId) {
 | 
			
		||||
		teaweb.confirm("确定要删除这个节点吗?", function () {
 | 
			
		||||
			this.$post(".delete")
 | 
			
		||||
			this.$post("/nodes/delete")
 | 
			
		||||
				.params({
 | 
			
		||||
					nodeId: nodeId
 | 
			
		||||
				})
 | 
			
		||||
							
								
								
									
										3
									
								
								web/views/@default/clusters/cluster/index.less
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								web/views/@default/clusters/cluster/index.less
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
.table .label {
 | 
			
		||||
	margin-bottom: 0.5em;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										5
									
								
								web/views/@default/clusters/cluster/node/@node_menu.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								web/views/@default/clusters/cluster/node/@node_menu.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
<second-menu>
 | 
			
		||||
	<menu-item :href="'/clusters/cluster/node?clusterId=' + clusterId + '&nodeId=' + nodeId" code="node">节点详情</menu-item>
 | 
			
		||||
	<menu-item :href="'/clusters/cluster/node/update?clusterId=' + clusterId + '&nodeId=' + nodeId" code="update">修改节点</menu-item>
 | 
			
		||||
	<menu-item :href="'/clusters/cluster/node/install?clusterId=' + clusterId + '&nodeId=' + nodeId" code="install">安装节点</menu-item>
 | 
			
		||||
</second-menu>
 | 
			
		||||
							
								
								
									
										45
									
								
								web/views/@default/clusters/cluster/node/create.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								web/views/@default/clusters/cluster/node/create.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "/left_menu"}
 | 
			
		||||
 | 
			
		||||
<div class="right-box">
 | 
			
		||||
	<h3>添加节点</h3>
 | 
			
		||||
 | 
			
		||||
	<form class="ui form" data-tea-action="$" data-tea-success="success">
 | 
			
		||||
		<input type="hidden" name="clusterId" :value="clusterId"/>
 | 
			
		||||
		<table class="ui table definition selectable">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td class="title">节点名称 *</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<input type="text" name="name" maxlength="50" ref="focus"/>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td>IP地址</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<node-ip-addresses-box></node-ip-addresses-box>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td>SSH主机地址</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<input type="text" name="sshHost" maxlength="64"/>
 | 
			
		||||
					<p class="comment">比如192.168.1.100</p>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td>SSH主机端口</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<input type="text" name="sshPort" maxlength="5"/>
 | 
			
		||||
					<p class="comment">常见的比如22。</p>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td>SSH登录认证</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<grant-selector></grant-selector>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
		</table>
 | 
			
		||||
		<submit-btn></submit-btn>
 | 
			
		||||
	</form>
 | 
			
		||||
</div>
 | 
			
		||||
							
								
								
									
										3
									
								
								web/views/@default/clusters/cluster/node/create.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								web/views/@default/clusters/cluster/node/create.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
	this.success = NotifySuccess("保存成功", "/clusters/cluster?clusterId=" + this.clusterId);
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										37
									
								
								web/views/@default/clusters/cluster/node/install.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								web/views/@default/clusters/cluster/node/install.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "/left_menu"}
 | 
			
		||||
 | 
			
		||||
<div class="right-box">
 | 
			
		||||
	{$template "node_menu"}
 | 
			
		||||
 | 
			
		||||
	<!-- 已安装 -->
 | 
			
		||||
	<div v-if="node.isInstalled">
 | 
			
		||||
		<div class="ui message green">当前节点为已安装状态。</div>
 | 
			
		||||
		<a href="" @click.prevent="updateNodeIsInstalled(false)">[修改为未安装状态]</a>
 | 
			
		||||
	</div>
 | 
			
		||||
 | 
			
		||||
	<!-- 未安装 -->
 | 
			
		||||
	<div v-if="!node.isInstalled">
 | 
			
		||||
		<h3>方法1:自动安装</h3>
 | 
			
		||||
 | 
			
		||||
		<h3>方法2:手动安装</h3>
 | 
			
		||||
		<table class="ui table definition selectable">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td>配置文件<em>(configs/api.yaml)</em></td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<pre>rpc:
 | 
			
		||||
  endpoints: [ "${endpoint}" ]
 | 
			
		||||
nodeId: "{{node.uniqueId}}"
 | 
			
		||||
secret: "{{node.secret}}"</pre>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td class="title">安装目录</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<div v-if="node.installDir.length == 0">使用集群设置<span v-if="node.cluster != null && node.cluster.installDir.length > 0">({{node.cluster.installDir}})</span></div>
 | 
			
		||||
					<span v-else>{{node.installDir}}</span>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
		</table>
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
							
								
								
									
										12
									
								
								web/views/@default/clusters/cluster/node/install.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								web/views/@default/clusters/cluster/node/install.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
	this.updateNodeIsInstalled = function (isInstalled) {
 | 
			
		||||
		teaweb.confirm("确定要将当前节点修改为未安装状态?", function () {
 | 
			
		||||
			this.$post("/clusters/cluster/node/updateInstallStatus")
 | 
			
		||||
				.params({
 | 
			
		||||
					nodeId: this.nodeId,
 | 
			
		||||
					isInstalled: isInstalled ? 1 : 0
 | 
			
		||||
				})
 | 
			
		||||
				.refresh()
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										4
									
								
								web/views/@default/clusters/cluster/node/node.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								web/views/@default/clusters/cluster/node/node.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
a.underline {
 | 
			
		||||
  border-bottom: 1px #db2828 dashed;
 | 
			
		||||
}
 | 
			
		||||
/*# sourceMappingURL=node.css.map */
 | 
			
		||||
							
								
								
									
										1
									
								
								web/views/@default/clusters/cluster/node/node.css.map
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								web/views/@default/clusters/cluster/node/node.css.map
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
{"version":3,"sources":["node.less"],"names":[],"mappings":"AAAA,CAAC;EACA,iCAAA","file":"node.css"}
 | 
			
		||||
							
								
								
									
										90
									
								
								web/views/@default/clusters/cluster/node/node.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								web/views/@default/clusters/cluster/node/node.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,90 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "/left_menu"}
 | 
			
		||||
 | 
			
		||||
<div class="right-box">
 | 
			
		||||
	{$template "node_menu"}
 | 
			
		||||
 | 
			
		||||
	<h3>节点详情</h3>
 | 
			
		||||
	<table class="ui table definition selectable">
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td class="title">节点名称</td>
 | 
			
		||||
			<td>{{node.name}}</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>IP地址</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<div v-if="node.ipAddresses.length > 0">
 | 
			
		||||
					<div>
 | 
			
		||||
						<div v-for="(address, index) in node.ipAddresses" class="ui label small">
 | 
			
		||||
                            {{address.ip}}<span class="small">({{address.name}})</span>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div v-else>
 | 
			
		||||
					<span class="disabled">暂时还没有填写IP地址。</span>
 | 
			
		||||
				</div>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>SSH主机地址</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<div v-if="node.login != null && node.login.params != null && node.login.params.host != null">
 | 
			
		||||
					<span v-if="node.login.params.host.length > 0">{{node.login.params.host}}</span>
 | 
			
		||||
					<span v-else class="disabled">尚未设置</span>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div v-else class="disabled">
 | 
			
		||||
					尚未设置
 | 
			
		||||
				</div>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>SSH主机端口</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<div v-if="node.login != null && node.login.params != null && node.login.params.host != null">
 | 
			
		||||
					<span v-if="node.login.params.port > 0">{{node.login.params.port}}</span>
 | 
			
		||||
					<span v-else class="disabled">尚未设置</span>
 | 
			
		||||
				</div>
 | 
			
		||||
				<span v-else class="disabled">
 | 
			
		||||
					尚未设置
 | 
			
		||||
				</span>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>SSH登录认证</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<div v-if="node.login != null && node.login.grant != null && node.login.grant.id > 0">
 | 
			
		||||
                    {{node.login.grant.name}}<span class="small">({{node.login.grant.methodName}})</span>
 | 
			
		||||
				</div>
 | 
			
		||||
				<span v-else class="disabled">
 | 
			
		||||
					尚未设置
 | 
			
		||||
				</span>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
	</table>
 | 
			
		||||
 | 
			
		||||
	<h3>安装信息</h3>
 | 
			
		||||
	<table class="ui table definition selectable">
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>节点ID<em>(id)</em></td>
 | 
			
		||||
			<td>{{node.uniqueId}}</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>密钥<em>(secret)</em></td>
 | 
			
		||||
			<td>{{node.secret}}</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td class="title">安装目录</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<div v-if="node.installDir.length == 0">使用集群设置<span v-if="node.cluster != null && node.cluster.installDir.length > 0">({{node.cluster.installDir}})</span></div>
 | 
			
		||||
				<span v-else>{{node.installDir}}</span>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>是否已安装</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<span v-if="node.isInstalled" class="green">已安装</span>
 | 
			
		||||
				<a v-else :href="'/clusters/cluster/installNode?clusterId=' + clusterId + '&nodeId=' + nodeId" class="underline" title="点击进入安装界面"><span class="red">未安装</span></a>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
	</table>
 | 
			
		||||
</div>
 | 
			
		||||
							
								
								
									
										3
									
								
								web/views/@default/clusters/cluster/node/node.less
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								web/views/@default/clusters/cluster/node/node.less
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
a.underline {
 | 
			
		||||
	border-bottom: 1px #db2828 dashed;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										55
									
								
								web/views/@default/clusters/cluster/node/update.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								web/views/@default/clusters/cluster/node/update.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "/left_menu"}
 | 
			
		||||
 | 
			
		||||
<div class="right-box">
 | 
			
		||||
	{$template "node_menu"}
 | 
			
		||||
 | 
			
		||||
	<h3>修改节点</h3>
 | 
			
		||||
	<form class="ui form" data-tea-action="$" data-tea-success="success">
 | 
			
		||||
		<input type="hidden" name="nodeId" :value="node.id"/>
 | 
			
		||||
		<input type="hidden" name="loginId" :value="loginId"/>
 | 
			
		||||
		<table class="ui table definition selectable">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td class="title">节点名称 *</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<input type="text" name="name" maxlength="50" ref="focus" v-model="node.name"/>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td>IP地址</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<node-ip-addresses-box :v-ip-addresses="ipAddresses"></node-ip-addresses-box>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td>所属集群</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<select class="ui dropdown" name="clusterId" style="width:10em" v-model="clusterId">
 | 
			
		||||
						<option v-for="cluster in clusters" :value="cluster.id">{{cluster.name}}</option>
 | 
			
		||||
					</select>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td>SSH主机地址</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<input type="text" name="sshHost" maxlength="64" v-model="sshHost"/>
 | 
			
		||||
					<p class="comment">比如192.168.1.100</p>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td>SSH主机端口</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<input type="text" name="sshPort" maxlength="5" v-model="sshPort"/>
 | 
			
		||||
					<p class="comment">比如22。</p>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td>SSH登录认证</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<grant-selector :v-grant="grant"></grant-selector>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
		</table>
 | 
			
		||||
		<submit-btn></submit-btn>
 | 
			
		||||
	</form>
 | 
			
		||||
</div>
 | 
			
		||||
@@ -4,7 +4,7 @@ Tea.context(function () {
 | 
			
		||||
		this.clusterId = this.node.cluster.id;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.success = NotifySuccess("保存成功", "/nodes/node?nodeId=" + this.node.id);
 | 
			
		||||
	this.success = NotifySuccess("保存成功", "/clusters/cluster/node?clusterId=" + this.clusterId + "&nodeId=" + this.node.id);
 | 
			
		||||
 | 
			
		||||
	// IP地址相关
 | 
			
		||||
	this.ipAddresses = this.node.ipAddresses;
 | 
			
		||||
@@ -33,7 +33,6 @@ Tea.context(function () {
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	// 认证相关
 | 
			
		||||
	this.grantId = 0;
 | 
			
		||||
	this.grant = null;
 | 
			
		||||
 | 
			
		||||
	this.sshHost = "";
 | 
			
		||||
@@ -44,11 +43,12 @@ Tea.context(function () {
 | 
			
		||||
 | 
			
		||||
		if (this.node.login.params != null) {
 | 
			
		||||
			this.sshHost = this.node.login.params.host;
 | 
			
		||||
			this.sshPort = this.node.login.params.port;
 | 
			
		||||
			if (this.node.login.params.port > 0) {
 | 
			
		||||
				this.sshPort = this.node.login.params.port;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (this.node.login.grant != null) {
 | 
			
		||||
			this.grantId = this.node.login.grant.id;
 | 
			
		||||
		if (this.node.login.grant != null && typeof this.node.login.grant.id != "undefined") {
 | 
			
		||||
			this.grant = {
 | 
			
		||||
				id: this.node.login.grant.id,
 | 
			
		||||
				name: this.node.login.grant.name,
 | 
			
		||||
@@ -57,48 +57,4 @@ Tea.context(function () {
 | 
			
		||||
			};
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.selectGrant = function () {
 | 
			
		||||
		var that = this;
 | 
			
		||||
		teaweb.popup("/nodes/grants/selectPopup", {
 | 
			
		||||
			callback: function (resp) {
 | 
			
		||||
				that.grantId = resp.data.grant.id;
 | 
			
		||||
				if (that.grantId > 0) {
 | 
			
		||||
					that.grant = resp.data.grant;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	// 修改授权
 | 
			
		||||
	this.updateGrant = function () {
 | 
			
		||||
		if (this.grant == null) {
 | 
			
		||||
			window.location.reload();
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		teaweb.popup("/nodes/grants/updatePopup?grantId=" + this.grant.id, {
 | 
			
		||||
			height: "31em",
 | 
			
		||||
			callback: function (resp) {
 | 
			
		||||
				this.grant = resp.data.grant;
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	this.createGrant = function () {
 | 
			
		||||
		var that = this;
 | 
			
		||||
		teaweb.popup("/nodes/grants/createPopup", {
 | 
			
		||||
			height: "31em",
 | 
			
		||||
			callback: function (resp) {
 | 
			
		||||
				that.grantId = resp.data.grant.id;
 | 
			
		||||
				if (that.grantId > 0) {
 | 
			
		||||
					that.grant = resp.data.grant;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	this.removeGrant = function () {
 | 
			
		||||
		this.grant = null;
 | 
			
		||||
		this.grantId = 0;
 | 
			
		||||
	};
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										30
									
								
								web/views/@default/clusters/cluster/settings/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								web/views/@default/clusters/cluster/settings/index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "/left_menu"}
 | 
			
		||||
 | 
			
		||||
<div class="right-box">
 | 
			
		||||
	<h3>基础设置</h3>
 | 
			
		||||
	<form class="ui form" data-tea-action="$" data-tea-success="success">
 | 
			
		||||
		<input type="hidden" name="clusterId" :value="cluster.id"/>
 | 
			
		||||
		<table class="ui table selectable definition">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td class="title">集群名称 *</td>
 | 
			
		||||
				<td><input type="text" name="name" maxlength="50" ref="focus" v-model="cluster.name"/></td>
 | 
			
		||||
			</tr>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td>默认SSH登录方式</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<grant-selector :v-grant="grant"></grant-selector>
 | 
			
		||||
					<p class="comment">当节点没有单独设置SSH登录方式时,默认使用此设置。</p>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td>默认安装目录</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<input type="text" name="installDir" maxlength="100" v-model="cluster.installDir"/>
 | 
			
		||||
					<p class="comment">当节点没有单独设置安装目录时,默认使用此设置。如果集群和节点都没有设置安装目录,则使用<span class="ui label tiny">/$登录用户/edge-node</span> 目录。</p>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
		</table>
 | 
			
		||||
		<submit-btn></submit-btn>
 | 
			
		||||
	</form>
 | 
			
		||||
</div>
 | 
			
		||||
							
								
								
									
										3
									
								
								web/views/@default/clusters/cluster/settings/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								web/views/@default/clusters/cluster/settings/index.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
	this.success = NotifyReloadSuccess("保存成功")
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										28
									
								
								web/views/@default/clusters/create.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								web/views/@default/clusters/create.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "menu"}
 | 
			
		||||
 | 
			
		||||
<div class="margin"></div>
 | 
			
		||||
 | 
			
		||||
<form class="ui form" data-tea-action="$" data-tea-success="success">
 | 
			
		||||
	<table class="ui table selectable definition">
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td class="title">集群名称 *</td>
 | 
			
		||||
			<td><input type="text" name="name" maxlength="50" ref="focus"/></td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>默认SSH登录方式</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<grant-selector></grant-selector>
 | 
			
		||||
				<p class="comment">当节点没有单独设置SSH登录方式时,默认使用此设置。</p>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>默认安装目录</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<input type="text" name="installDir" maxlength="100"/>
 | 
			
		||||
				<p class="comment">当节点没有单独设置安装目录时,默认使用此设置。如果集群和节点都没有设置安装目录,则使用<span class="ui label tiny">/$登录用户/edge-node</span> 目录。</p>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
	</table>
 | 
			
		||||
	<submit-btn></submit-btn>
 | 
			
		||||
</form>
 | 
			
		||||
							
								
								
									
										3
									
								
								web/views/@default/clusters/create.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								web/views/@default/clusters/create.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
	this.success = NotifySuccess("保存成功", "/clusters")
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										28
									
								
								web/views/@default/clusters/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								web/views/@default/clusters/index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "menu"}
 | 
			
		||||
 | 
			
		||||
<p class="comment" v-if="clusters.length == 0">暂时还没有集群。</p>
 | 
			
		||||
 | 
			
		||||
<table class="ui table selectable" v-if="clusters.length > 0">
 | 
			
		||||
	<thead>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<th>集群名称</th>
 | 
			
		||||
			<th>节点数量</th>
 | 
			
		||||
			<th>默认认证</th>
 | 
			
		||||
			<th class="two op">操作</th>
 | 
			
		||||
		</tr>
 | 
			
		||||
	</thead>
 | 
			
		||||
	<tr v-for="cluster in clusters">
 | 
			
		||||
		<td>{{cluster.name}}</td>
 | 
			
		||||
		<td>{{cluster.countNodes}}</td>
 | 
			
		||||
		<td>
 | 
			
		||||
			<span v-if="cluster.hasGrant" class="green">Y</span>
 | 
			
		||||
			<span v-else class="disabled">N</span>
 | 
			
		||||
		</td>
 | 
			
		||||
		<td>
 | 
			
		||||
			<a :href="'/clusters/cluster?clusterId=' + cluster.id">详情</a>
 | 
			
		||||
		</td>
 | 
			
		||||
	</tr>
 | 
			
		||||
</table>
 | 
			
		||||
 | 
			
		||||
<page-box></page-box>
 | 
			
		||||
@@ -1,4 +0,0 @@
 | 
			
		||||
<first-menu>
 | 
			
		||||
	<menu-item href="/nodes" code="index">节点列表</menu-item>
 | 
			
		||||
	<menu-item href="/nodes/create" code="create">创建节点</menu-item>
 | 
			
		||||
</first-menu>
 | 
			
		||||
@@ -1,66 +0,0 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "menu"}
 | 
			
		||||
<div class="margin"></div>
 | 
			
		||||
<form class="ui form" data-tea-action="$" data-tea-success="success">
 | 
			
		||||
	<input type="hidden" name="grantId" :value="grantId"/>
 | 
			
		||||
	<table class="ui table definition selectable">
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td class="title">节点名称 *</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<input type="text" name="name" maxlength="50" ref="focus"/>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>IP地址</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<input type="hidden" name="ipAddresses" :value="JSON.stringify(ipAddresses)"/>
 | 
			
		||||
				<div v-if="ipAddresses.length > 0">
 | 
			
		||||
					<div>
 | 
			
		||||
						<div v-for="(address, index) in ipAddresses" class="ui label small">
 | 
			
		||||
							{{address.ip}}<span class="small">({{address.name}})</span>
 | 
			
		||||
							<a href="" title="修改" @click.prevent="updateIPAddress(index, address)"><i class="icon pencil small"></i></a>
 | 
			
		||||
							<a href="" title="删除" @click.prevent="removeIPAddress(index)"><i class="icon remove"></i></a>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
					<div class="ui divider"></div>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div>
 | 
			
		||||
					<button class="ui button small" type="button" @click.prevent="addIPAddress()">+</button>
 | 
			
		||||
				</div>
 | 
			
		||||
				<p class="comment">添加已经绑定的IP地址,仅做记录用。</p>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>所属集群</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<select class="ui dropdown" name="clusterId" style="width:10em">
 | 
			
		||||
					<option v-for="cluster in clusters" :value="cluster.id">{{cluster.name}}</option>
 | 
			
		||||
				</select>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>SSH主机地址</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<input type="text" name="sshHost" maxlength="64"/>
 | 
			
		||||
				<p class="comment">比如192.168.1.100</p>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>SSH主机端口</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<input type="text" name="sshPort" maxlength="5"/>
 | 
			
		||||
				<p class="comment">常见的比如22。</p>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>SSH登录认证</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<div class="ui label small" v-if="grant != null">{{grant.name}}<span class="small">({{grant.methodName}})</span> <a href="" title="修改" @click.prevent="updateGrant()"><i class="icon pencil small"></i></a> <a href="" title="删除" @click.prevent="removeGrant()"><i class="icon remove"></i></a> </div>
 | 
			
		||||
				<div v-if="grant == null">
 | 
			
		||||
					<a href="" @click.prevent="selectGrant()">[选择已有认证]</a>     <a href="" @click.prevent="createGrant()">[添加新认证]</a>
 | 
			
		||||
				</div>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
	</table>
 | 
			
		||||
	<submit-btn></submit-btn>
 | 
			
		||||
</form>
 | 
			
		||||
@@ -1,79 +0,0 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
	this.success = NotifySuccess("保存成功", "/nodes");
 | 
			
		||||
 | 
			
		||||
	// IP地址相关
 | 
			
		||||
	this.ipAddresses = [];
 | 
			
		||||
 | 
			
		||||
	// 添加IP地址
 | 
			
		||||
	this.addIPAddress = function () {
 | 
			
		||||
		teaweb.popup("/nodes/ipAddresses/createPopup", {
 | 
			
		||||
			callback: function (resp) {
 | 
			
		||||
				this.ipAddresses.push(resp.data.ipAddress);
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	// 修改地址
 | 
			
		||||
	this.updateIPAddress = function (index, address) {
 | 
			
		||||
		teaweb.popup("/nodes/ipAddresses/updatePopup?addressId=" + address.id, {
 | 
			
		||||
			callback: function (resp) {
 | 
			
		||||
				Vue.set(this.ipAddresses, index, resp.data.ipAddress);
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 删除IP地址
 | 
			
		||||
	this.removeIPAddress = function (index) {
 | 
			
		||||
		this.ipAddresses.$remove(index);
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	// 授权相关
 | 
			
		||||
	this.grantId = 0;
 | 
			
		||||
	this.grant = null;
 | 
			
		||||
 | 
			
		||||
	// 选择授权
 | 
			
		||||
	this.selectGrant = function () {
 | 
			
		||||
		var that = this;
 | 
			
		||||
		teaweb.popup("/nodes/grants/selectPopup", {
 | 
			
		||||
			callback: function (resp) {
 | 
			
		||||
				that.grantId = resp.data.grant.id;
 | 
			
		||||
				if (that.grantId > 0) {
 | 
			
		||||
					that.grant = resp.data.grant;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	// 创建授权
 | 
			
		||||
	this.createGrant = function () {
 | 
			
		||||
		teaweb.popup("/nodes/grants/createPopup", {
 | 
			
		||||
			height: "31em",
 | 
			
		||||
			callback: function (resp) {
 | 
			
		||||
				this.grantId = resp.data.grant.id;
 | 
			
		||||
				if (this.grantId > 0) {
 | 
			
		||||
					this.grant = resp.data.grant;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	// 修改授权
 | 
			
		||||
	this.updateGrant = function () {
 | 
			
		||||
		if (this.grant == null) {
 | 
			
		||||
			window.location.reload();
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		teaweb.popup("/nodes/grants/updatePopup?grantId=" + this.grant.id, {
 | 
			
		||||
			height: "31em",
 | 
			
		||||
			callback: function (resp) {
 | 
			
		||||
				this.grant = resp.data.grant;
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	// 删除已选择授权
 | 
			
		||||
	this.removeGrant = function () {
 | 
			
		||||
		this.grant = null;
 | 
			
		||||
		this.grantId = 0;
 | 
			
		||||
	};
 | 
			
		||||
});
 | 
			
		||||
@@ -6,7 +6,7 @@
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>名称 *</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<input type="text" name="name" maxlength="100" ref="focus" value="认证"/>
 | 
			
		||||
				<input type="text" name="name" maxlength="100" ref="focus" value=""/>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
.address-box .label {
 | 
			
		||||
  display: block;
 | 
			
		||||
  margin-bottom: 0.6em;
 | 
			
		||||
}
 | 
			
		||||
/*# sourceMappingURL=index.css.map */
 | 
			
		||||
@@ -1,56 +0,0 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "menu"}
 | 
			
		||||
 | 
			
		||||
<p class="comment" v-if="nodes.length == 0">暂时还没有节点。</p>
 | 
			
		||||
 | 
			
		||||
<table class="ui table selectable" v-if="nodes.length > 0">
 | 
			
		||||
	<thead>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<th>ID</th>
 | 
			
		||||
			<th>节点名称</th>
 | 
			
		||||
			<th>主机名</th>
 | 
			
		||||
			<th>IP</th>
 | 
			
		||||
			<th>所属集群</th>
 | 
			
		||||
			<th>状态</th>
 | 
			
		||||
			<th>CPU</th>
 | 
			
		||||
			<th>内存</th>
 | 
			
		||||
			<!--<th>流量</th>
 | 
			
		||||
			<th>连接数</th>-->
 | 
			
		||||
			<th class="two op">操作</th>
 | 
			
		||||
		</tr>
 | 
			
		||||
	</thead>
 | 
			
		||||
	<tr v-for="node in nodes">
 | 
			
		||||
		<td>{{node.id}}</td>
 | 
			
		||||
		<td>{{node.name}}</td>
 | 
			
		||||
		<td>
 | 
			
		||||
			<span v-if="node.status.hostname != null && node.status.hostname.length > 0">{{node.status.hostname}}</span>
 | 
			
		||||
			<span v-else>-</span>
 | 
			
		||||
		</td>
 | 
			
		||||
		<td>
 | 
			
		||||
			<span v-if="node.ipAddresses.length == 0">-</span>
 | 
			
		||||
			<div v-else class="address-box">
 | 
			
		||||
				<div v-for="addr in node.ipAddresses" class="ui label small">{{addr.ip}} <span class="small">({{addr.name}})</span></div>
 | 
			
		||||
			</div>
 | 
			
		||||
		</td>
 | 
			
		||||
		<td>{{node.cluster.name}}</td>
 | 
			
		||||
		<td>
 | 
			
		||||
			<span v-if="node.status.isActive"><span class="green">运行中</span></span>
 | 
			
		||||
			<span v-else-if="node.status.updatedAt > 0" class="red">已断开</span>
 | 
			
		||||
			<span v-else-if="node.status.updatedAt == 0" class="red">未连接</span>
 | 
			
		||||
		</td>
 | 
			
		||||
		<td>
 | 
			
		||||
			<span v-if="node.status.isActive" :class="{red:node.status.cpuUsage > 0.80}">{{node.status.cpuUsageText}}</span>
 | 
			
		||||
			<span v-else>-</span>
 | 
			
		||||
		</td>
 | 
			
		||||
		<td>
 | 
			
		||||
			<span v-if="node.status.isActive" :class="{red:node.status.memUsage > 0.80}">{{node.status.memUsageText}}</span>
 | 
			
		||||
			<span v-else>-</span>
 | 
			
		||||
		</td>
 | 
			
		||||
		<td>
 | 
			
		||||
			<a :href="'/nodes/node?nodeId=' + node.id">详情</a>   <a href="" @click.prevent="deleteNode(node.id)">删除</a>
 | 
			
		||||
		</td>
 | 
			
		||||
	</tr>
 | 
			
		||||
</table>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<div class="page" v-html="page"></div>
 | 
			
		||||
@@ -1,6 +0,0 @@
 | 
			
		||||
.address-box {
 | 
			
		||||
	.label {
 | 
			
		||||
		display: block;
 | 
			
		||||
		margin-bottom: 0.6em;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -11,7 +11,7 @@
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td class="title">简介</td>
 | 
			
		||||
			<td class="title">备注</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<input type="text" name="name" maxlength="50"/>
 | 
			
		||||
			</td>
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td class="title">简介</td>
 | 
			
		||||
			<td class="title">备注</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<input type="text" name="name" maxlength="50" v-model="address.name"/>
 | 
			
		||||
			</td>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,72 +0,0 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
 | 
			
		||||
<second-menu>
 | 
			
		||||
	<menu-item :href="'/nodes/node?nodeId=' + nodeId" active="true">详情</menu-item>
 | 
			
		||||
	<menu-item :href="'/nodes/update?nodeId=' + nodeId">修改</menu-item>
 | 
			
		||||
</second-menu>
 | 
			
		||||
 | 
			
		||||
<table class="ui table definition selectable">
 | 
			
		||||
	<tr>
 | 
			
		||||
		<td class="title">节点名称</td>
 | 
			
		||||
		<td>{{node.name}}</td>
 | 
			
		||||
	</tr>
 | 
			
		||||
	<tr>
 | 
			
		||||
		<td>IP地址</td>
 | 
			
		||||
		<td>
 | 
			
		||||
			<div v-if="node.ipAddresses.length > 0">
 | 
			
		||||
				<div>
 | 
			
		||||
					<div v-for="(address, index) in node.ipAddresses" class="ui label small">
 | 
			
		||||
                        {{address.ip}}<span class="small">({{address.name}})</span>
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
			<div v-else>
 | 
			
		||||
				<span class="disabled">暂时还没有填写IP地址。</span>
 | 
			
		||||
			</div>
 | 
			
		||||
		</td>
 | 
			
		||||
	</tr>
 | 
			
		||||
	<tr>
 | 
			
		||||
		<td>所属集群</td>
 | 
			
		||||
		<td>
 | 
			
		||||
			<span v-if="node.cluster == null">还没有设置集群。</span>
 | 
			
		||||
			<div v-if="node.cluster != null">
 | 
			
		||||
				{{node.cluster.name}}
 | 
			
		||||
			</div>
 | 
			
		||||
		</td>
 | 
			
		||||
	</tr>
 | 
			
		||||
	<tr>
 | 
			
		||||
		<td>SSH主机地址</td>
 | 
			
		||||
		<td>
 | 
			
		||||
			<div v-if="node.login != null && node.login.params != null && node.login.params.host != null">
 | 
			
		||||
				<span v-if="node.login.params.host.length > 0">{{node.login.params.host}}</span>
 | 
			
		||||
				<span v-if="node.login.params.host.length == 0">尚未设置</span>
 | 
			
		||||
			</div>
 | 
			
		||||
			<div v-if="!(node.login != null && node.login.params != null && node.login.params.host != null)">
 | 
			
		||||
				尚未设置
 | 
			
		||||
			</div>
 | 
			
		||||
		</td>
 | 
			
		||||
	</tr>
 | 
			
		||||
	<tr>
 | 
			
		||||
		<td>SSH主机端口</td>
 | 
			
		||||
		<td>
 | 
			
		||||
			<div v-if="node.login != null && node.login.params != null && node.login.params.host != null">
 | 
			
		||||
				<span v-if="node.login.params.port > 0">{{node.login.params.port}}</span>
 | 
			
		||||
				<span v-if="node.login.params.port <= 0">尚未设置</span>
 | 
			
		||||
			</div>
 | 
			
		||||
			<div v-if="!(node.login != null && node.login.params != null && node.login.params.port != null)">
 | 
			
		||||
				尚未设置
 | 
			
		||||
			</div>
 | 
			
		||||
		</td>
 | 
			
		||||
	</tr>
 | 
			
		||||
	<tr>
 | 
			
		||||
		<td>SSH登录认证</td>
 | 
			
		||||
		<td>
 | 
			
		||||
			<div v-if="node.login != null && node.login.grant != null && node.login.grant.id > 0">
 | 
			
		||||
				{{node.login.grant.name}}<span class="small">({{node.login.grant.methodName}})</span>
 | 
			
		||||
			</div>
 | 
			
		||||
			<div v-if="!(node.login != null && node.login.grant != null && node.login.grant.id > 0)">
 | 
			
		||||
				尚未设置
 | 
			
		||||
			</div>
 | 
			
		||||
		</td>
 | 
			
		||||
	</tr>
 | 
			
		||||
</table>
 | 
			
		||||
@@ -1,74 +0,0 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "menu"}
 | 
			
		||||
 | 
			
		||||
<second-menu>
 | 
			
		||||
	<menu-item :href="'/nodes/node?nodeId=' + nodeId">详情</menu-item>
 | 
			
		||||
	<menu-item :href="'/nodes/update?nodeId=' + nodeId" active="true">修改</menu-item>
 | 
			
		||||
</second-menu>
 | 
			
		||||
 | 
			
		||||
<div class="margin"></div>
 | 
			
		||||
<form class="ui form" data-tea-action="$" data-tea-success="success">
 | 
			
		||||
	<input type="hidden" name="nodeId" :value="node.id"/>
 | 
			
		||||
	<input type="hidden" name="loginId" :value="loginId"/>
 | 
			
		||||
	<input type="hidden" name="grantId" :value="grantId"/>
 | 
			
		||||
	<table class="ui table definition selectable">
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td class="title">节点名称 *</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<input type="text" name="name" maxlength="50" ref="focus" v-model="node.name"/>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>IP地址</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<input type="hidden" name="ipAddresses" :value="JSON.stringify(ipAddresses)"/>
 | 
			
		||||
				<div v-if="ipAddresses.length > 0">
 | 
			
		||||
					<div>
 | 
			
		||||
						<div v-for="(address, index) in ipAddresses" class="ui label small">
 | 
			
		||||
                            {{address.ip}}<span class="small">({{address.name}})</span>
 | 
			
		||||
							<a href="" title="修改" @click.prevent="updateIPAddress(index, address)"><i class="icon pencil small"></i></a>
 | 
			
		||||
							<a href="" title="删除" @click.prevent="removeIPAddress(index)"><i class="icon remove"></i></a>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
					<div class="ui divider"></div>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div>
 | 
			
		||||
					<button class="ui button small" type="button" @click.prevent="addIPAddress()">+</button>
 | 
			
		||||
				</div>
 | 
			
		||||
				<p class="comment">添加已经绑定的IP地址,仅做记录用。</p>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>所属集群</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<select class="ui dropdown" name="clusterId" style="width:10em" v-model="clusterId">
 | 
			
		||||
					<option v-for="cluster in clusters" :value="cluster.id">{{cluster.name}}</option>
 | 
			
		||||
				</select>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>SSH主机地址</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<input type="text" name="sshHost" maxlength="64" v-model="sshHost"/>
 | 
			
		||||
				<p class="comment">比如192.168.1.100</p>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>SSH主机端口</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<input type="text" name="sshPort" maxlength="5" v-model="sshPort"/>
 | 
			
		||||
				<p class="comment">比如22。</p>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td>SSH登录认证</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<div class="ui label small" v-if="grant != null && grant.id != null">{{grant.name}}<span class="small">({{grant.methodName}})</span> <a href="" title="修改" @click.prevent="updateGrant()"><i class="icon pencil small"></i></a> <a href="" title="删除" @click.prevent="removeGrant()"><i class="icon remove"></i></a> </div>
 | 
			
		||||
				<div v-else>
 | 
			
		||||
					<a href="" @click.prevent="selectGrant()">[选择已有认证]</a>     <a href="" @click.prevent="createGrant()">[添加新认证]</a>
 | 
			
		||||
				</div>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
	</table>
 | 
			
		||||
	<submit-btn></submit-btn>
 | 
			
		||||
</form>
 | 
			
		||||
@@ -1,45 +0,0 @@
 | 
			
		||||
.left-box {
 | 
			
		||||
  width: 8em;
 | 
			
		||||
  position: fixed;
 | 
			
		||||
  top: 7.5em;
 | 
			
		||||
  bottom: 0.5em;
 | 
			
		||||
  overflow-y: auto;
 | 
			
		||||
  overflow-x: hidden;
 | 
			
		||||
  border-right: 1px #ddd solid;
 | 
			
		||||
}
 | 
			
		||||
.left-box .menu {
 | 
			
		||||
  width: 90% !important;
 | 
			
		||||
}
 | 
			
		||||
.left-box .menu .item {
 | 
			
		||||
  line-height: 1.2;
 | 
			
		||||
  position: relative;
 | 
			
		||||
  padding-left: 1em !important;
 | 
			
		||||
}
 | 
			
		||||
.left-box .menu .item .icon {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  top: 50%;
 | 
			
		||||
  left: 0;
 | 
			
		||||
  margin-top: -0.4em !important;
 | 
			
		||||
}
 | 
			
		||||
.left-box .menu .item.separator {
 | 
			
		||||
  border-bottom: 1px #eee solid !important;
 | 
			
		||||
  padding-top: 0;
 | 
			
		||||
  padding-bottom: 0;
 | 
			
		||||
  margin-top: 0 !important;
 | 
			
		||||
  margin-bottom: 0 !important;
 | 
			
		||||
}
 | 
			
		||||
.left-box .menu .header {
 | 
			
		||||
  border-bottom: 1px #ddd solid;
 | 
			
		||||
  padding-left: 0 !important;
 | 
			
		||||
  padding-bottom: 1em !important;
 | 
			
		||||
}
 | 
			
		||||
.left-box::-webkit-scrollbar {
 | 
			
		||||
  width: 4px;
 | 
			
		||||
}
 | 
			
		||||
.right-box {
 | 
			
		||||
  margin-left: 9em;
 | 
			
		||||
}
 | 
			
		||||
.label em {
 | 
			
		||||
  font-style: italic !important;
 | 
			
		||||
}
 | 
			
		||||
/*# sourceMappingURL=index.css.map */
 | 
			
		||||
@@ -1 +1 @@
 | 
			
		||||
{"version":3,"sources":["/Users/liuxiangchao/Documents/projects/Edge/EdgeAdmin/web/views/@default/servers/server/@left_menu.less","index.less"],"names":[],"mappings":"AAAA;EACC,UAAA;EACA,eAAA;EACA,UAAA;EACA,aAAA;EACA,gBAAA;EACA,kBAAA;EACA,4BAAA;;AAPD,SASC;EACC,qBAAA;;AAVF,SASC,MAGC;EACC,gBAAA;EACA,kBAAA;EACA,4BAAA;;AAfH,SASC,MAGC,MAKC;EACC,kBAAA;EACA,QAAA;EACA,OAAA;EACA,kBAAA;;AArBJ,SASC,MAgBC,MAAK;EACJ,wCAAA;EACA,cAAA;EACA,iBAAA;EACA,wBAAA;EACA,2BAAA;;AA9BH,SASC,MAyBC;EACC,6BAAA;EACA,0BAAA;EACA,8BAAA;;AAQH,SAAS;EACR,UAAA;;AAGD;EACC,gBAAA;;AChDD,MAAO;EACN,6BAAA","file":"index.css"}
 | 
			
		||||
undefined
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
 | 
			
		||||
{$template "/servers/server/left_menu"}
 | 
			
		||||
{$template "/left_menu"}
 | 
			
		||||
<div class="right-box">
 | 
			
		||||
	<div class="ui message">此功能暂未开放,敬请期待。</div>
 | 
			
		||||
</div>
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
@import "../@left_menu";
 | 
			
		||||
 | 
			
		||||
.label em {
 | 
			
		||||
	font-style: italic !important;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,45 +0,0 @@
 | 
			
		||||
.left-box {
 | 
			
		||||
  width: 8em;
 | 
			
		||||
  position: fixed;
 | 
			
		||||
  top: 7.5em;
 | 
			
		||||
  bottom: 0.5em;
 | 
			
		||||
  overflow-y: auto;
 | 
			
		||||
  overflow-x: hidden;
 | 
			
		||||
  border-right: 1px #ddd solid;
 | 
			
		||||
}
 | 
			
		||||
.left-box .menu {
 | 
			
		||||
  width: 90% !important;
 | 
			
		||||
}
 | 
			
		||||
.left-box .menu .item {
 | 
			
		||||
  line-height: 1.2;
 | 
			
		||||
  position: relative;
 | 
			
		||||
  padding-left: 1em !important;
 | 
			
		||||
}
 | 
			
		||||
.left-box .menu .item .icon {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  top: 50%;
 | 
			
		||||
  left: 0;
 | 
			
		||||
  margin-top: -0.4em !important;
 | 
			
		||||
}
 | 
			
		||||
.left-box .menu .item.separator {
 | 
			
		||||
  border-bottom: 1px #eee solid !important;
 | 
			
		||||
  padding-top: 0;
 | 
			
		||||
  padding-bottom: 0;
 | 
			
		||||
  margin-top: 0 !important;
 | 
			
		||||
  margin-bottom: 0 !important;
 | 
			
		||||
}
 | 
			
		||||
.left-box .menu .header {
 | 
			
		||||
  border-bottom: 1px #ddd solid;
 | 
			
		||||
  padding-left: 0 !important;
 | 
			
		||||
  padding-bottom: 1em !important;
 | 
			
		||||
}
 | 
			
		||||
.left-box::-webkit-scrollbar {
 | 
			
		||||
  width: 4px;
 | 
			
		||||
}
 | 
			
		||||
.right-box {
 | 
			
		||||
  margin-left: 9em;
 | 
			
		||||
}
 | 
			
		||||
.label em {
 | 
			
		||||
  font-style: italic !important;
 | 
			
		||||
}
 | 
			
		||||
/*# sourceMappingURL=index.css.map */
 | 
			
		||||
@@ -1 +1 @@
 | 
			
		||||
{"version":3,"sources":["/Users/liuxiangchao/Documents/projects/Edge/EdgeAdmin/web/views/@default/servers/server/@left_menu.less","index.less"],"names":[],"mappings":"AAAA;EACC,UAAA;EACA,eAAA;EACA,UAAA;EACA,aAAA;EACA,gBAAA;EACA,kBAAA;EACA,4BAAA;;AAPD,SASC;EACC,qBAAA;;AAVF,SASC,MAGC;EACC,gBAAA;EACA,kBAAA;EACA,4BAAA;;AAfH,SASC,MAGC,MAKC;EACC,kBAAA;EACA,QAAA;EACA,OAAA;EACA,kBAAA;;AArBJ,SASC,MAgBC,MAAK;EACJ,wCAAA;EACA,cAAA;EACA,iBAAA;EACA,wBAAA;EACA,2BAAA;;AA9BH,SASC,MAyBC;EACC,6BAAA;EACA,0BAAA;EACA,8BAAA;;AAQH,SAAS;EACR,UAAA;;AAGD;EACC,gBAAA;;AChDD,MAAO;EACN,6BAAA","file":"index.css"}
 | 
			
		||||
undefined
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
 | 
			
		||||
{$template "/servers/server/left_menu"}
 | 
			
		||||
{$template "/left_menu"}
 | 
			
		||||
<div class="right-box">
 | 
			
		||||
	<div class="ui message">此功能暂未开放,敬请期待。</div>
 | 
			
		||||
</div>
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user