Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b81ffd074 | ||
|
|
eff3c77551 | ||
|
|
2089bac52f | ||
|
|
67760a53ba | ||
|
|
d4d7b1fff7 | ||
|
|
d121bc86a0 | ||
|
|
7a1bd29f6f | ||
|
|
f1af151080 | ||
|
|
f39d106bef | ||
|
|
d9c092cd31 | ||
|
|
7d1d138e42 | ||
|
|
89bd70819f | ||
|
|
15156b68e3 | ||
|
|
92a3b8f375 | ||
|
|
6a152b7775 | ||
|
|
ea915582c1 | ||
|
|
51b938b9c7 | ||
|
|
c2f559d48e | ||
|
|
a96c1434b6 | ||
|
|
d135442a52 | ||
|
|
0b8501a724 | ||
|
|
7fcc2b7dba | ||
|
|
1ea7fe0213 | ||
|
|
838d33648f | ||
|
|
6cf4a8ea3e | ||
|
|
15c40d6c96 |
@@ -9,28 +9,32 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type DNSProvider struct {
|
type DNSProvider struct {
|
||||||
raw dnsclients.ProviderInterface
|
raw dnsclients.ProviderInterface
|
||||||
|
dnsDomain string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDNSProvider(raw dnsclients.ProviderInterface) *DNSProvider {
|
func NewDNSProvider(raw dnsclients.ProviderInterface, dnsDomain string) *DNSProvider {
|
||||||
return &DNSProvider{raw: raw}
|
return &DNSProvider{
|
||||||
|
raw: raw,
|
||||||
|
dnsDomain: dnsDomain,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DNSProvider) Present(domain, token, keyAuth string) error {
|
func (this *DNSProvider) Present(domain, token, keyAuth string) error {
|
||||||
fqdn, value := dns01.GetRecord(domain, keyAuth)
|
fqdn, value := dns01.GetRecord(domain, keyAuth)
|
||||||
|
|
||||||
// 设置记录
|
// 设置记录
|
||||||
index := strings.Index(fqdn, "."+domain)
|
index := strings.Index(fqdn, "."+this.dnsDomain)
|
||||||
if index < 0 {
|
if index < 0 {
|
||||||
return errors.New("invalid fqdn value")
|
return errors.New("invalid fqdn value")
|
||||||
}
|
}
|
||||||
recordName := fqdn[:index]
|
recordName := fqdn[:index]
|
||||||
record, err := this.raw.QueryRecord(domain, recordName, dnstypes.RecordTypeTXT)
|
record, err := this.raw.QueryRecord(this.dnsDomain, recordName, dnstypes.RecordTypeTXT)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("query DNS record failed: " + err.Error())
|
return errors.New("query DNS record failed: " + err.Error())
|
||||||
}
|
}
|
||||||
if record == nil {
|
if record == nil {
|
||||||
err = this.raw.AddRecord(domain, &dnstypes.Record{
|
err = this.raw.AddRecord(this.dnsDomain, &dnstypes.Record{
|
||||||
Id: "",
|
Id: "",
|
||||||
Name: recordName,
|
Name: recordName,
|
||||||
Type: dnstypes.RecordTypeTXT,
|
Type: dnstypes.RecordTypeTXT,
|
||||||
@@ -41,7 +45,7 @@ func (this *DNSProvider) Present(domain, token, keyAuth string) error {
|
|||||||
return errors.New("create DNS record failed: " + err.Error())
|
return errors.New("create DNS record failed: " + err.Error())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
err = this.raw.UpdateRecord(domain, record, &dnstypes.Record{
|
err = this.raw.UpdateRecord(this.dnsDomain, record, &dnstypes.Record{
|
||||||
Name: recordName,
|
Name: recordName,
|
||||||
Type: dnstypes.RecordTypeTXT,
|
Type: dnstypes.RecordTypeTXT,
|
||||||
Value: value,
|
Value: value,
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ func (this *Request) runDNS() (certData []byte, keyData []byte, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = client.Challenge.SetDNS01Provider(NewDNSProvider(this.task.DNSProvider))
|
err = client.Challenge.SetDNS01Provider(NewDNSProvider(this.task.DNSProvider, this.task.DNSDomain))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ func TestRequest_Run_DNS(t *testing.T) {
|
|||||||
AuthType: AuthTypeDNS,
|
AuthType: AuthTypeDNS,
|
||||||
DNSProvider: dnsProvider,
|
DNSProvider: dnsProvider,
|
||||||
DNSDomain: "yun4s.cn",
|
DNSDomain: "yun4s.cn",
|
||||||
Domains: []string{"yun4s.cn"},
|
Domains: []string{"www.yun4s.cn"},
|
||||||
})
|
})
|
||||||
certData, keyData, err := req.Run()
|
certData, keyData, err := req.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package teaconst
|
package teaconst
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Version = "0.3.0"
|
Version = "0.3.1"
|
||||||
|
|
||||||
ProductName = "Edge API"
|
ProductName = "Edge API"
|
||||||
ProcessName = "edge-api"
|
ProcessName = "edge-api"
|
||||||
@@ -18,9 +18,10 @@ const (
|
|||||||
|
|
||||||
// 其他节点版本号,用来检测是否有需要升级的节点
|
// 其他节点版本号,用来检测是否有需要升级的节点
|
||||||
|
|
||||||
NodeVersion = "0.3.0"
|
NodeVersion = "0.3.1"
|
||||||
UserNodeVersion = "0.0.10"
|
UserNodeVersion = "0.0.10"
|
||||||
AuthorityNodeVersion = "0.0.2"
|
AuthorityNodeVersion = "0.0.2"
|
||||||
MonitorNodeVersion = "0.0.3"
|
MonitorNodeVersion = "0.0.3"
|
||||||
DNSNodeVersion = "0.2.0"
|
DNSNodeVersion = "0.2.0"
|
||||||
|
ReportNodeVersion = "0.1.0"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -94,8 +94,12 @@ func (this *DNSTaskDAO) FindAllDoingTasks(tx *dbs.Tx) (result []*DNSTask, err er
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FindAllDoingOrErrorTasks 查找正在执行的和错误的任务
|
// FindAllDoingOrErrorTasks 查找正在执行的和错误的任务
|
||||||
func (this *DNSTaskDAO) FindAllDoingOrErrorTasks(tx *dbs.Tx) (result []*DNSTask, err error) {
|
func (this *DNSTaskDAO) FindAllDoingOrErrorTasks(tx *dbs.Tx, nodeClusterId int64) (result []*DNSTask, err error) {
|
||||||
_, err = this.Query(tx).
|
var query = this.Query(tx)
|
||||||
|
if nodeClusterId > 0 {
|
||||||
|
query.Attr("clusterId", nodeClusterId)
|
||||||
|
}
|
||||||
|
_, err = query.
|
||||||
Where("(isDone=0 OR (isDone=1 AND isOk=0))").
|
Where("(isDone=0 OR (isDone=1 AND isOk=0))").
|
||||||
AscPk().
|
AscPk().
|
||||||
Slice(&result).
|
Slice(&result).
|
||||||
|
|||||||
@@ -287,7 +287,7 @@ func (this *HTTPLocationDAO) FindEnabledLocationIdWithWebId(tx *dbs.Tx, webId in
|
|||||||
FindInt64Col(0)
|
FindInt64Col(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindEnabledLocationIdWithReverseProxyId 查找包含某个反向代理的Server
|
// FindEnabledLocationIdWithReverseProxyId 查找包含某个反向代理的路由规则
|
||||||
func (this *HTTPLocationDAO) FindEnabledLocationIdWithReverseProxyId(tx *dbs.Tx, reverseProxyId int64) (serverId int64, err error) {
|
func (this *HTTPLocationDAO) FindEnabledLocationIdWithReverseProxyId(tx *dbs.Tx, reverseProxyId int64) (serverId int64, err error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
State(ServerStateEnabled).
|
State(ServerStateEnabled).
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ const (
|
|||||||
|
|
||||||
MessageTypeReportNodeInactive MessageType = "ReportNodeInactive" // 区域监控节点节点不活跃
|
MessageTypeReportNodeInactive MessageType = "ReportNodeInactive" // 区域监控节点节点不活跃
|
||||||
MessageTypeReportNodeActive MessageType = "ReportNodeActive" // 区域监控节点活跃
|
MessageTypeReportNodeActive MessageType = "ReportNodeActive" // 区域监控节点活跃
|
||||||
|
MessageTypeConnectivity MessageType = "Connectivity"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MessageDAO dbs.DAO
|
type MessageDAO dbs.DAO
|
||||||
@@ -118,21 +119,23 @@ func (this *MessageDAO) CreateClusterMessage(tx *dbs.Tx, role string, clusterId
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateNodeMessage 创建节点消息
|
// CreateNodeMessage 创建节点消息
|
||||||
func (this *MessageDAO) CreateNodeMessage(tx *dbs.Tx, role string, clusterId int64, nodeId int64, messageType MessageType, level string, subject string, body string, paramsJSON []byte) error {
|
func (this *MessageDAO) CreateNodeMessage(tx *dbs.Tx, role string, clusterId int64, nodeId int64, messageType MessageType, level string, subject string, body string, paramsJSON []byte, force bool) error {
|
||||||
// 检查N分钟内是否已经发送过
|
// 检查N分钟内是否已经发送过
|
||||||
hash := this.calHash(role, clusterId, nodeId, subject, body, paramsJSON)
|
hash := this.calHash(role, clusterId, nodeId, subject, body, paramsJSON)
|
||||||
exists, err := this.Query(tx).
|
if !force {
|
||||||
Attr("hash", hash).
|
exists, err := this.Query(tx).
|
||||||
Gt("createdAt", time.Now().Unix()-10*60). // 10分钟
|
Attr("hash", hash).
|
||||||
Exist()
|
Gt("createdAt", time.Now().Unix()-10*60). // 10分钟
|
||||||
if err != nil {
|
Exist()
|
||||||
return err
|
if err != nil {
|
||||||
}
|
return err
|
||||||
if exists {
|
}
|
||||||
return nil
|
if exists {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = this.createMessage(tx, role, clusterId, nodeId, messageType, level, subject, body, paramsJSON)
|
_, err := this.createMessage(tx, role, clusterId, nodeId, messageType, level, subject, body, paramsJSON)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,12 +5,13 @@ import (
|
|||||||
_ "github.com/iwind/TeaGo/bootstrap"
|
_ "github.com/iwind/TeaGo/bootstrap"
|
||||||
"github.com/iwind/TeaGo/rands"
|
"github.com/iwind/TeaGo/rands"
|
||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
|
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewMetricStatDAO_InsertMany(t *testing.T) {
|
func TestNewMetricStatDAO_InsertMany(t *testing.T) {
|
||||||
for i := 0; i <= 10_000_000; i++ {
|
for i := 0; i <= 10_000_000; i++ {
|
||||||
err := NewMetricStatDAO().CreateStat(nil, types.String(i)+"_v1", 18, int64(rands.Int(0, 10000)), int64(rands.Int(0, 10000)), int64(rands.Int(0, 100)), []string{"/html" + types.String(i)}, 1, "20210830", 0)
|
err := NewMetricStatDAO().CreateStat(nil, types.String(i)+"_v1", 18, int64(rands.Int(0, 10000)), int64(rands.Int(0, 10000)), int64(rands.Int(0, 100)), []string{"/html" + types.String(i)}, 1, timeutil.Format("Ymd"), 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,6 +141,8 @@ func (this *NodeClusterDAO) CreateCluster(tx *dbs.Tx, adminId int64, name string
|
|||||||
dnsConfig := &dnsconfigs.ClusterDNSConfig{
|
dnsConfig := &dnsconfigs.ClusterDNSConfig{
|
||||||
NodesAutoSync: true,
|
NodesAutoSync: true,
|
||||||
ServersAutoSync: true,
|
ServersAutoSync: true,
|
||||||
|
CNameRecords: []string{},
|
||||||
|
TTL: 0,
|
||||||
}
|
}
|
||||||
dnsJSON, err := json.Marshal(dnsConfig)
|
dnsJSON, err := json.Marshal(dnsConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -436,7 +438,7 @@ func (this *NodeClusterDAO) ExistClusterDNSName(tx *dbs.Tx, dnsName string, excl
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpdateClusterDNS 修改集群DNS相关信息
|
// UpdateClusterDNS 修改集群DNS相关信息
|
||||||
func (this *NodeClusterDAO) UpdateClusterDNS(tx *dbs.Tx, clusterId int64, dnsName string, dnsDomainId int64, nodesAutoSync bool, serversAutoSync bool) error {
|
func (this *NodeClusterDAO) UpdateClusterDNS(tx *dbs.Tx, clusterId int64, dnsName string, dnsDomainId int64, nodesAutoSync bool, serversAutoSync bool, cnameRecords []string, ttl int32) error {
|
||||||
if clusterId <= 0 {
|
if clusterId <= 0 {
|
||||||
return errors.New("invalid clusterId")
|
return errors.New("invalid clusterId")
|
||||||
}
|
}
|
||||||
@@ -445,9 +447,15 @@ func (this *NodeClusterDAO) UpdateClusterDNS(tx *dbs.Tx, clusterId int64, dnsNam
|
|||||||
op.DnsName = dnsName
|
op.DnsName = dnsName
|
||||||
op.DnsDomainId = dnsDomainId
|
op.DnsDomainId = dnsDomainId
|
||||||
|
|
||||||
|
if len(cnameRecords) == 0 {
|
||||||
|
cnameRecords = []string{}
|
||||||
|
}
|
||||||
|
|
||||||
dnsConfig := &dnsconfigs.ClusterDNSConfig{
|
dnsConfig := &dnsconfigs.ClusterDNSConfig{
|
||||||
NodesAutoSync: nodesAutoSync,
|
NodesAutoSync: nodesAutoSync,
|
||||||
ServersAutoSync: serversAutoSync,
|
ServersAutoSync: serversAutoSync,
|
||||||
|
CNameRecords: cnameRecords,
|
||||||
|
TTL: ttl,
|
||||||
}
|
}
|
||||||
dnsJSON, err := json.Marshal(dnsConfig)
|
dnsJSON, err := json.Marshal(dnsConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -792,6 +800,17 @@ func (this *NodeClusterDAO) FindEnabledNodeClustersWithIds(tx *dbs.Tx, clusterId
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExistsEnabledCluster 检查集群是否存在
|
||||||
|
func (this *NodeClusterDAO) ExistsEnabledCluster(tx *dbs.Tx, clusterId int64) (bool, error) {
|
||||||
|
if clusterId <= 0 {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return this.Query(tx).
|
||||||
|
Pk(clusterId).
|
||||||
|
State(NodeClusterStateEnabled).
|
||||||
|
Exist()
|
||||||
|
}
|
||||||
|
|
||||||
// NotifyUpdate 通知更新
|
// NotifyUpdate 通知更新
|
||||||
func (this *NodeClusterDAO) NotifyUpdate(tx *dbs.Tx, clusterId int64) error {
|
func (this *NodeClusterDAO) NotifyUpdate(tx *dbs.Tx, clusterId int64) error {
|
||||||
return SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleNode, clusterId, NodeTaskTypeConfigChanged)
|
return SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleNode, clusterId, NodeTaskTypeConfigChanged)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"github.com/TeaOSLab/EdgeCommon/pkg/dnsconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/dnsconfigs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 解析DNS配置
|
// DecodeDNSConfig 解析DNS配置
|
||||||
func (this *NodeCluster) DecodeDNSConfig() (*dnsconfigs.ClusterDNSConfig, error) {
|
func (this *NodeCluster) DecodeDNSConfig() (*dnsconfigs.ClusterDNSConfig, error) {
|
||||||
if len(this.Dns) == 0 || this.Dns == "null" {
|
if len(this.Dns) == 0 || this.Dns == "null" {
|
||||||
// 一定要返回一个默认的值,防止产生nil
|
// 一定要返回一个默认的值,防止产生nil
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ func (this *NodeDAO) FindEnabledBasicNode(tx *dbs.Tx, nodeId int64) (*Node, erro
|
|||||||
one, err := this.Query(tx).
|
one, err := this.Query(tx).
|
||||||
State(NodeStateEnabled).
|
State(NodeStateEnabled).
|
||||||
Pk(nodeId).
|
Pk(nodeId).
|
||||||
Result("id", "name", "clusterId", "isOn", "isUp").
|
Result("id", "name", "clusterId", "groupId", "isOn", "isUp").
|
||||||
Find()
|
Find()
|
||||||
if one == nil {
|
if one == nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -190,7 +190,7 @@ func (this *NodeDAO) CreateNode(tx *dbs.Tx, adminId int64, name string, clusterI
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpdateNode 修改节点
|
// UpdateNode 修改节点
|
||||||
func (this *NodeDAO) UpdateNode(tx *dbs.Tx, nodeId int64, name string, clusterId int64, secondaryClusterIds []int64, groupId int64, regionId int64, maxCPU int32, isOn bool, maxCacheDiskCapacityJSON []byte, maxCacheMemoryCapacityJSON []byte) error {
|
func (this *NodeDAO) UpdateNode(tx *dbs.Tx, nodeId int64, name string, clusterId int64, secondaryClusterIds []int64, groupId int64, regionId int64, isOn bool) error {
|
||||||
if nodeId <= 0 {
|
if nodeId <= 0 {
|
||||||
return errors.New("invalid nodeId")
|
return errors.New("invalid nodeId")
|
||||||
}
|
}
|
||||||
@@ -226,14 +226,7 @@ func (this *NodeDAO) UpdateNode(tx *dbs.Tx, nodeId int64, name string, clusterId
|
|||||||
op.GroupId = groupId
|
op.GroupId = groupId
|
||||||
op.RegionId = regionId
|
op.RegionId = regionId
|
||||||
op.LatestVersion = dbs.SQL("latestVersion+1")
|
op.LatestVersion = dbs.SQL("latestVersion+1")
|
||||||
op.MaxCPU = maxCPU
|
|
||||||
op.IsOn = isOn
|
op.IsOn = isOn
|
||||||
if len(maxCacheDiskCapacityJSON) > 0 {
|
|
||||||
op.MaxCacheDiskCapacity = maxCacheDiskCapacityJSON
|
|
||||||
}
|
|
||||||
if len(maxCacheMemoryCapacityJSON) > 0 {
|
|
||||||
op.MaxCacheMemoryCapacity = maxCacheMemoryCapacityJSON
|
|
||||||
}
|
|
||||||
err = this.Save(tx, op)
|
err = this.Save(tx, op)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -500,9 +493,9 @@ func (this *NodeDAO) FindAllInactiveNodesWithClusterId(tx *dbs.Tx, clusterId int
|
|||||||
_, err = this.Query(tx).
|
_, err = this.Query(tx).
|
||||||
State(NodeStateEnabled).
|
State(NodeStateEnabled).
|
||||||
Attr("clusterId", clusterId).
|
Attr("clusterId", clusterId).
|
||||||
Attr("isOn", true). // 只监控启用的节点
|
Attr("isOn", true). // 只监控启用的节点
|
||||||
Attr("isInstalled", true). // 只监控已经安装的节点
|
Attr("isInstalled", true). // 只监控已经安装的节点
|
||||||
Attr("isActive", true). // 当前已经在线的
|
Attr("isActive", true). // 当前已经在线的
|
||||||
Where("(status IS NULL OR (JSON_EXTRACT(status, '$.isActive')=false AND UNIX_TIMESTAMP()-JSON_EXTRACT(status, '$.updatedAt')>10) OR UNIX_TIMESTAMP()-JSON_EXTRACT(status, '$.updatedAt')>120)").
|
Where("(status IS NULL OR (JSON_EXTRACT(status, '$.isActive')=false AND UNIX_TIMESTAMP()-JSON_EXTRACT(status, '$.updatedAt')>10) OR UNIX_TIMESTAMP()-JSON_EXTRACT(status, '$.updatedAt')>120)").
|
||||||
Result("id", "name").
|
Result("id", "name").
|
||||||
Slice(&result).
|
Slice(&result).
|
||||||
@@ -1113,6 +1106,41 @@ func (this *NodeDAO) UpdateNodeDNS(tx *dbs.Tx, nodeId int64, routes map[int64][]
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateNodeSystem 设置系统信息
|
||||||
|
func (this *NodeDAO) UpdateNodeSystem(tx *dbs.Tx, nodeId int64, maxCPU int32) error {
|
||||||
|
if nodeId <= 0 {
|
||||||
|
return errors.New("invalid nodeId")
|
||||||
|
}
|
||||||
|
var op = NewNodeOperator()
|
||||||
|
op.Id = nodeId
|
||||||
|
op.MaxCPU = maxCPU
|
||||||
|
err := this.Save(tx, op)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return this.NotifyUpdate(tx, nodeId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateNodeCache 设置缓存相关
|
||||||
|
func (this *NodeDAO) UpdateNodeCache(tx *dbs.Tx, nodeId int64, maxCacheDiskCapacityJSON []byte, maxCacheMemoryCapacityJSON []byte) error {
|
||||||
|
if nodeId <= 0 {
|
||||||
|
return errors.New("invalid nodeId")
|
||||||
|
}
|
||||||
|
var op = NewNodeOperator()
|
||||||
|
op.Id = nodeId
|
||||||
|
if len(maxCacheDiskCapacityJSON) > 0 {
|
||||||
|
op.MaxCacheDiskCapacity = maxCacheDiskCapacityJSON
|
||||||
|
}
|
||||||
|
if len(maxCacheMemoryCapacityJSON) > 0 {
|
||||||
|
op.MaxCacheMemoryCapacity = maxCacheMemoryCapacityJSON
|
||||||
|
}
|
||||||
|
err := this.Save(tx, op)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return this.NotifyUpdate(tx, nodeId)
|
||||||
|
}
|
||||||
|
|
||||||
// UpdateNodeUpCount 计算节点上线|下线状态
|
// UpdateNodeUpCount 计算节点上线|下线状态
|
||||||
func (this *NodeDAO) UpdateNodeUpCount(tx *dbs.Tx, nodeId int64, isUp bool, maxUp int, maxDown int) (changed bool, err error) {
|
func (this *NodeDAO) UpdateNodeUpCount(tx *dbs.Tx, nodeId int64, isUp bool, maxUp int, maxDown int) (changed bool, err error) {
|
||||||
if nodeId <= 0 {
|
if nodeId <= 0 {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models/dns"
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models/dns"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
||||||
@@ -102,7 +103,7 @@ func (this *NodeIPAddressDAO) FindAddressName(tx *dbs.Tx, id int64) (string, err
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateAddress 创建IP地址
|
// CreateAddress 创建IP地址
|
||||||
func (this *NodeIPAddressDAO) CreateAddress(tx *dbs.Tx, adminId int64, nodeId int64, role nodeconfigs.NodeRole, name string, ip string, canAccess bool, thresholdsJSON []byte) (addressId int64, err error) {
|
func (this *NodeIPAddressDAO) CreateAddress(tx *dbs.Tx, adminId int64, nodeId int64, role nodeconfigs.NodeRole, name string, ip string, canAccess bool, isUp bool) (addressId int64, err error) {
|
||||||
if len(role) == 0 {
|
if len(role) == 0 {
|
||||||
role = nodeconfigs.NodeRoleNode
|
role = nodeconfigs.NodeRoleNode
|
||||||
}
|
}
|
||||||
@@ -113,12 +114,7 @@ func (this *NodeIPAddressDAO) CreateAddress(tx *dbs.Tx, adminId int64, nodeId in
|
|||||||
op.Name = name
|
op.Name = name
|
||||||
op.Ip = ip
|
op.Ip = ip
|
||||||
op.CanAccess = canAccess
|
op.CanAccess = canAccess
|
||||||
|
op.IsUp = isUp
|
||||||
if len(thresholdsJSON) > 0 {
|
|
||||||
op.Thresholds = thresholdsJSON
|
|
||||||
} else {
|
|
||||||
op.Thresholds = "[]"
|
|
||||||
}
|
|
||||||
|
|
||||||
op.State = NodeIPAddressStateEnabled
|
op.State = NodeIPAddressStateEnabled
|
||||||
addressId, err = this.SaveInt64(tx, op)
|
addressId, err = this.SaveInt64(tx, op)
|
||||||
@@ -141,7 +137,7 @@ func (this *NodeIPAddressDAO) CreateAddress(tx *dbs.Tx, adminId int64, nodeId in
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpdateAddress 修改IP地址
|
// UpdateAddress 修改IP地址
|
||||||
func (this *NodeIPAddressDAO) UpdateAddress(tx *dbs.Tx, adminId int64, addressId int64, name string, ip string, canAccess bool, isOn bool, thresholdsJSON []byte) (err error) {
|
func (this *NodeIPAddressDAO) UpdateAddress(tx *dbs.Tx, adminId int64, addressId int64, name string, ip string, canAccess bool, isOn bool, isUp bool) (err error) {
|
||||||
if addressId <= 0 {
|
if addressId <= 0 {
|
||||||
return errors.New("invalid addressId")
|
return errors.New("invalid addressId")
|
||||||
}
|
}
|
||||||
@@ -152,12 +148,7 @@ func (this *NodeIPAddressDAO) UpdateAddress(tx *dbs.Tx, adminId int64, addressId
|
|||||||
op.Ip = ip
|
op.Ip = ip
|
||||||
op.CanAccess = canAccess
|
op.CanAccess = canAccess
|
||||||
op.IsOn = isOn
|
op.IsOn = isOn
|
||||||
|
op.IsUp = isUp
|
||||||
if len(thresholdsJSON) > 0 {
|
|
||||||
op.Thresholds = thresholdsJSON
|
|
||||||
} else {
|
|
||||||
op.Thresholds = "[]"
|
|
||||||
}
|
|
||||||
|
|
||||||
op.State = NodeIPAddressStateEnabled // 恢复状态
|
op.State = NodeIPAddressStateEnabled // 恢复状态
|
||||||
err = this.Save(tx, op)
|
err = this.Save(tx, op)
|
||||||
@@ -234,6 +225,8 @@ func (this *NodeIPAddressDAO) FindFirstNodeAccessIPAddress(tx *dbs.Tx, nodeId in
|
|||||||
Attr("role", role).
|
Attr("role", role).
|
||||||
State(NodeIPAddressStateEnabled).
|
State(NodeIPAddressStateEnabled).
|
||||||
Attr("canAccess", true).
|
Attr("canAccess", true).
|
||||||
|
Attr("isOn", true).
|
||||||
|
Attr("isUp", true).
|
||||||
Desc("order").
|
Desc("order").
|
||||||
AscPk().
|
AscPk().
|
||||||
Result("ip").
|
Result("ip").
|
||||||
@@ -250,6 +243,8 @@ func (this *NodeIPAddressDAO) FindFirstNodeAccessIPAddressId(tx *dbs.Tx, nodeId
|
|||||||
Attr("role", role).
|
Attr("role", role).
|
||||||
State(NodeIPAddressStateEnabled).
|
State(NodeIPAddressStateEnabled).
|
||||||
Attr("canAccess", true).
|
Attr("canAccess", true).
|
||||||
|
Attr("isOn", true).
|
||||||
|
Attr("isUp", true).
|
||||||
Desc("order").
|
Desc("order").
|
||||||
AscPk().
|
AscPk().
|
||||||
Result("id").
|
Result("id").
|
||||||
@@ -346,12 +341,13 @@ func (this *NodeIPAddressDAO) ListEnabledIPAddresses(tx *dbs.Tx, role string, no
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindAllEnabledAndOnIPAddressesWithClusterId 列出所有的正在启用的IP地址
|
// FindAllAccessibleIPAddressesWithClusterId 列出所有的正在启用的IP地址
|
||||||
func (this *NodeIPAddressDAO) FindAllEnabledAndOnIPAddressesWithClusterId(tx *dbs.Tx, role string, clusterId int64) (result []*NodeIPAddress, err error) {
|
func (this *NodeIPAddressDAO) FindAllAccessibleIPAddressesWithClusterId(tx *dbs.Tx, role string, clusterId int64) (result []*NodeIPAddress, err error) {
|
||||||
_, err = this.Query(tx).
|
_, err = this.Query(tx).
|
||||||
State(NodeIPAddressStateEnabled).
|
State(NodeIPAddressStateEnabled).
|
||||||
Attr("role", role).
|
Attr("role", role).
|
||||||
Attr("isOn", true).
|
Attr("isOn", true).
|
||||||
|
Attr("canAccess", true).
|
||||||
Where("nodeId IN (SELECT id FROM "+SharedNodeDAO.Table+" WHERE state=1 AND clusterId=:clusterId)").
|
Where("nodeId IN (SELECT id FROM "+SharedNodeDAO.Table+" WHERE state=1 AND clusterId=:clusterId)").
|
||||||
Param("clusterId", clusterId).
|
Param("clusterId", clusterId).
|
||||||
Slice(&result).
|
Slice(&result).
|
||||||
@@ -359,6 +355,74 @@ func (this *NodeIPAddressDAO) FindAllEnabledAndOnIPAddressesWithClusterId(tx *db
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CountAllAccessibleIPAddressesWithClusterId 计算集群中的可用IP地址数量
|
||||||
|
func (this *NodeIPAddressDAO) CountAllAccessibleIPAddressesWithClusterId(tx *dbs.Tx, role string, clusterId int64) (count int64, err error) {
|
||||||
|
return this.Query(tx).
|
||||||
|
State(NodeIPAddressStateEnabled).
|
||||||
|
Attr("role", role).
|
||||||
|
Attr("isOn", true).
|
||||||
|
Attr("canAccess", true).
|
||||||
|
Where("nodeId IN (SELECT id FROM "+SharedNodeDAO.Table+" WHERE state=1 AND clusterId=:clusterId)").
|
||||||
|
Param("clusterId", clusterId).
|
||||||
|
Count()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListAccessibleIPAddressesWithClusterId 列出单页集群中的可用IP地址
|
||||||
|
func (this *NodeIPAddressDAO) ListAccessibleIPAddressesWithClusterId(tx *dbs.Tx, role string, clusterId int64, offset int64, size int64) (result []*NodeIPAddress, err error) {
|
||||||
|
_, err = this.Query(tx).
|
||||||
|
State(NodeIPAddressStateEnabled).
|
||||||
|
Attr("role", role).
|
||||||
|
Attr("isOn", true).
|
||||||
|
Attr("canAccess", true).
|
||||||
|
Where("nodeId IN (SELECT id FROM "+SharedNodeDAO.Table+" WHERE state=1 AND clusterId=:clusterId)").
|
||||||
|
Param("clusterId", clusterId).
|
||||||
|
Offset(offset).
|
||||||
|
Limit(size).
|
||||||
|
Slice(&result).
|
||||||
|
FindAll()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateAddressConnectivity 设置连通性数据
|
||||||
|
func (this *NodeIPAddressDAO) UpdateAddressConnectivity(tx *dbs.Tx, addrId int64, connectivity *nodeconfigs.Connectivity) error {
|
||||||
|
connectivityJSON, err := json.Marshal(connectivity)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return this.Query(tx).
|
||||||
|
Pk(addrId).
|
||||||
|
Set("connectivity", connectivityJSON).
|
||||||
|
UpdateQuickly()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateAddressIsUp 设置IP地址在线状态
|
||||||
|
func (this *NodeIPAddressDAO) UpdateAddressIsUp(tx *dbs.Tx, addressId int64, isUp bool) error {
|
||||||
|
var err = this.Query(tx).
|
||||||
|
Pk(addressId).
|
||||||
|
Set("isUp", isUp).
|
||||||
|
UpdateQuickly()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return this.NotifyUpdate(tx, addressId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateAddressBackupIP 设置备用IP
|
||||||
|
func (this *NodeIPAddressDAO) UpdateAddressBackupIP(tx *dbs.Tx, addressId int64, thresholdId int64, ip string) error {
|
||||||
|
if addressId <= 0 {
|
||||||
|
return errors.New("invalid addressId")
|
||||||
|
}
|
||||||
|
var op = NewNodeIPAddressOperator()
|
||||||
|
op.Id = addressId
|
||||||
|
op.BackupThresholdId = thresholdId
|
||||||
|
op.BackupIP = ip
|
||||||
|
err := this.Save(tx, op)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return this.NotifyUpdate(tx, addressId)
|
||||||
|
}
|
||||||
|
|
||||||
// NotifyUpdate 通知更新
|
// NotifyUpdate 通知更新
|
||||||
func (this *NodeIPAddressDAO) NotifyUpdate(tx *dbs.Tx, addressId int64) error {
|
func (this *NodeIPAddressDAO) NotifyUpdate(tx *dbs.Tx, addressId int64) error {
|
||||||
address, err := this.Query(tx).
|
address, err := this.Query(tx).
|
||||||
|
|||||||
@@ -1,5 +1,42 @@
|
|||||||
|
//go:build plus
|
||||||
|
// +build plus
|
||||||
|
|
||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
|
"github.com/iwind/TeaGo/dbs"
|
||||||
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestNodeIPAddressDAO_FireThresholds(t *testing.T) {
|
||||||
|
dbs.NotifyReady()
|
||||||
|
|
||||||
|
var tx *dbs.Tx
|
||||||
|
var nodeId int64 = 126
|
||||||
|
node, err := SharedNodeDAO.FindEnabledNode(tx, nodeId)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if node == nil {
|
||||||
|
t.Log("node not found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = SharedNodeIPAddressDAO.FireThresholds(tx, nodeconfigs.NodeRoleNode, nodeId)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log("ok")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNodeIPAddressDAO_LoopTasks(t *testing.T) {
|
||||||
|
dbs.NotifyReady()
|
||||||
|
|
||||||
|
var tx *dbs.Tx
|
||||||
|
err := SharedNodeIPAddressDAO.loopTask(tx, nodeconfigs.NodeRoleNode)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log("ok")
|
||||||
|
}
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ func (this *NodeIPAddressLogDAO) CreateLog(tx *dbs.Tx, adminId int64, addrId int
|
|||||||
op.CanAccess = addr.CanAccess
|
op.CanAccess = addr.CanAccess
|
||||||
op.IsOn = addr.IsOn
|
op.IsOn = addr.IsOn
|
||||||
op.IsUp = addr.IsUp
|
op.IsUp = addr.IsUp
|
||||||
|
op.BackupIP = addr.BackupIP
|
||||||
op.Day = timeutil.Format("Ymd")
|
op.Day = timeutil.Format("Ymd")
|
||||||
return this.Save(tx, op)
|
return this.Save(tx, op)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,14 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
_ "github.com/iwind/TeaGo/bootstrap"
|
_ "github.com/iwind/TeaGo/bootstrap"
|
||||||
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestNodeIPAddressDAO_FindFirstNodeAccessIPAddress(t *testing.T) {
|
||||||
|
var dao = NewNodeIPAddressDAO()
|
||||||
|
t.Log(dao.FindFirstNodeAccessIPAddress(nil, 48, nodeconfigs.NodeRoleNode))
|
||||||
|
t.Log(dao.FindFirstNodeAccessIPAddressId(nil, 48, nodeconfigs.NodeRoleNode))
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ type NodeIPAddressLog struct {
|
|||||||
IsOn uint8 `field:"isOn"` // 是否启用
|
IsOn uint8 `field:"isOn"` // 是否启用
|
||||||
CanAccess uint8 `field:"canAccess"` // 是否可访问
|
CanAccess uint8 `field:"canAccess"` // 是否可访问
|
||||||
Day string `field:"day"` // YYYYMMDD,用来清理
|
Day string `field:"day"` // YYYYMMDD,用来清理
|
||||||
|
BackupIP string `field:"backupIP"` // 备用IP
|
||||||
}
|
}
|
||||||
|
|
||||||
type NodeIPAddressLogOperator struct {
|
type NodeIPAddressLogOperator struct {
|
||||||
@@ -23,6 +24,7 @@ type NodeIPAddressLogOperator struct {
|
|||||||
IsOn interface{} // 是否启用
|
IsOn interface{} // 是否启用
|
||||||
CanAccess interface{} // 是否可访问
|
CanAccess interface{} // 是否可访问
|
||||||
Day interface{} // YYYYMMDD,用来清理
|
Day interface{} // YYYYMMDD,用来清理
|
||||||
|
BackupIP interface{} // 备用IP
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNodeIPAddressLogOperator() *NodeIPAddressLogOperator {
|
func NewNodeIPAddressLogOperator() *NodeIPAddressLogOperator {
|
||||||
|
|||||||
@@ -2,33 +2,39 @@ package models
|
|||||||
|
|
||||||
// NodeIPAddress 节点IP地址
|
// NodeIPAddress 节点IP地址
|
||||||
type NodeIPAddress struct {
|
type NodeIPAddress struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id uint32 `field:"id"` // ID
|
||||||
NodeId uint32 `field:"nodeId"` // 节点ID
|
NodeId uint32 `field:"nodeId"` // 节点ID
|
||||||
Role string `field:"role"` // 节点角色
|
Role string `field:"role"` // 节点角色
|
||||||
Name string `field:"name"` // 名称
|
Name string `field:"name"` // 名称
|
||||||
Ip string `field:"ip"` // IP地址
|
Ip string `field:"ip"` // IP地址
|
||||||
Description string `field:"description"` // 描述
|
Description string `field:"description"` // 描述
|
||||||
State uint8 `field:"state"` // 状态
|
State uint8 `field:"state"` // 状态
|
||||||
Order uint32 `field:"order"` // 排序
|
Order uint32 `field:"order"` // 排序
|
||||||
CanAccess uint8 `field:"canAccess"` // 是否可以访问
|
CanAccess uint8 `field:"canAccess"` // 是否可以访问
|
||||||
IsOn uint8 `field:"isOn"` // 是否启用
|
IsOn uint8 `field:"isOn"` // 是否启用
|
||||||
IsUp uint8 `field:"isUp"` // 是否上线
|
IsUp uint8 `field:"isUp"` // 是否上线
|
||||||
Thresholds string `field:"thresholds"` // 上线阈值
|
Thresholds string `field:"thresholds"` // 上线阈值
|
||||||
|
Connectivity string `field:"connectivity"` // 连通性状态
|
||||||
|
BackupIP string `field:"backupIP"` // 备用IP
|
||||||
|
BackupThresholdId uint32 `field:"backupThresholdId"` // 触发备用IP的阈值
|
||||||
}
|
}
|
||||||
|
|
||||||
type NodeIPAddressOperator struct {
|
type NodeIPAddressOperator struct {
|
||||||
Id interface{} // ID
|
Id interface{} // ID
|
||||||
NodeId interface{} // 节点ID
|
NodeId interface{} // 节点ID
|
||||||
Role interface{} // 节点角色
|
Role interface{} // 节点角色
|
||||||
Name interface{} // 名称
|
Name interface{} // 名称
|
||||||
Ip interface{} // IP地址
|
Ip interface{} // IP地址
|
||||||
Description interface{} // 描述
|
Description interface{} // 描述
|
||||||
State interface{} // 状态
|
State interface{} // 状态
|
||||||
Order interface{} // 排序
|
Order interface{} // 排序
|
||||||
CanAccess interface{} // 是否可以访问
|
CanAccess interface{} // 是否可以访问
|
||||||
IsOn interface{} // 是否启用
|
IsOn interface{} // 是否启用
|
||||||
IsUp interface{} // 是否上线
|
IsUp interface{} // 是否上线
|
||||||
Thresholds interface{} // 上线阈值
|
Thresholds interface{} // 上线阈值
|
||||||
|
Connectivity interface{} // 连通性状态
|
||||||
|
BackupIP interface{} // 备用IP
|
||||||
|
BackupThresholdId interface{} // 触发备用IP的阈值
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNodeIPAddressOperator() *NodeIPAddressOperator {
|
func NewNodeIPAddressOperator() *NodeIPAddressOperator {
|
||||||
|
|||||||
@@ -2,19 +2,43 @@ package models
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
"github.com/iwind/TeaGo/logs"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (this *NodeIPAddress) DecodeThresholds() []*nodeconfigs.NodeValueThresholdConfig {
|
// DecodeConnectivity 解析联通数值
|
||||||
var result = []*nodeconfigs.NodeValueThresholdConfig{}
|
func (this *NodeIPAddress) DecodeConnectivity() *nodeconfigs.Connectivity {
|
||||||
if len(this.Thresholds) == 0 {
|
var connectivity = &nodeconfigs.Connectivity{}
|
||||||
return result
|
if len(this.Connectivity) > 0 {
|
||||||
|
err := json.Unmarshal([]byte(this.Connectivity), connectivity)
|
||||||
|
if err != nil {
|
||||||
|
remotelogs.Error("NodeIPAddress.DecodeConnectivity", "decode failed: "+err.Error())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
err := json.Unmarshal([]byte(this.Thresholds), &result)
|
return connectivity
|
||||||
if err != nil {
|
}
|
||||||
// 不处理错误
|
|
||||||
logs.Error(err)
|
// DNSIP 获取当前DNS可以使用的IP
|
||||||
}
|
func (this *NodeIPAddress) DNSIP() string {
|
||||||
return result
|
var backupIP = this.DecodeBackupIP()
|
||||||
|
if len(backupIP) > 0 {
|
||||||
|
return backupIP
|
||||||
|
}
|
||||||
|
return this.Ip
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeBackupIP 获取备用IP
|
||||||
|
func (this *NodeIPAddress) DecodeBackupIP() string {
|
||||||
|
if this.BackupThresholdId > 0 && len(this.BackupIP) > 0 {
|
||||||
|
// 阈值是否存在
|
||||||
|
b, err := SharedNodeIPAddressThresholdDAO.ExistsEnabledThreshold(nil, int64(this.BackupThresholdId))
|
||||||
|
if err != nil {
|
||||||
|
remotelogs.Error("NodeIPAddress.DNSIP", "check enabled threshold failed: "+err.Error())
|
||||||
|
} else {
|
||||||
|
if b {
|
||||||
|
return this.BackupIP
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
|
|||||||
252
internal/db/models/node_ip_address_threshold_dao.go
Normal file
252
internal/db/models/node_ip_address_threshold_dao.go
Normal file
@@ -0,0 +1,252 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
|
_ "github.com/go-sql-driver/mysql"
|
||||||
|
"github.com/iwind/TeaGo/Tea"
|
||||||
|
"github.com/iwind/TeaGo/dbs"
|
||||||
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
NodeIPAddressThresholdStateEnabled = 1 // 已启用
|
||||||
|
NodeIPAddressThresholdStateDisabled = 0 // 已禁用
|
||||||
|
)
|
||||||
|
|
||||||
|
type NodeIPAddressThresholdDAO dbs.DAO
|
||||||
|
|
||||||
|
func NewNodeIPAddressThresholdDAO() *NodeIPAddressThresholdDAO {
|
||||||
|
return dbs.NewDAO(&NodeIPAddressThresholdDAO{
|
||||||
|
DAOObject: dbs.DAOObject{
|
||||||
|
DB: Tea.Env,
|
||||||
|
Table: "edgeNodeIPAddressThresholds",
|
||||||
|
Model: new(NodeIPAddressThreshold),
|
||||||
|
PkName: "id",
|
||||||
|
},
|
||||||
|
}).(*NodeIPAddressThresholdDAO)
|
||||||
|
}
|
||||||
|
|
||||||
|
var SharedNodeIPAddressThresholdDAO *NodeIPAddressThresholdDAO
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
dbs.OnReady(func() {
|
||||||
|
SharedNodeIPAddressThresholdDAO = NewNodeIPAddressThresholdDAO()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnableNodeIPAddressThreshold 启用条目
|
||||||
|
func (this *NodeIPAddressThresholdDAO) EnableNodeIPAddressThreshold(tx *dbs.Tx, id uint64) error {
|
||||||
|
_, err := this.Query(tx).
|
||||||
|
Pk(id).
|
||||||
|
Set("state", NodeIPAddressThresholdStateEnabled).
|
||||||
|
Update()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisableNodeIPAddressThreshold 禁用条目
|
||||||
|
func (this *NodeIPAddressThresholdDAO) DisableNodeIPAddressThreshold(tx *dbs.Tx, id int64) error {
|
||||||
|
_, err := this.Query(tx).
|
||||||
|
Pk(id).
|
||||||
|
Set("state", NodeIPAddressThresholdStateDisabled).
|
||||||
|
Update()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindEnabledNodeIPAddressThreshold 查找启用中的条目
|
||||||
|
func (this *NodeIPAddressThresholdDAO) FindEnabledNodeIPAddressThreshold(tx *dbs.Tx, id uint64) (*NodeIPAddressThreshold, error) {
|
||||||
|
result, err := this.Query(tx).
|
||||||
|
Pk(id).
|
||||||
|
Attr("state", NodeIPAddressThresholdStateEnabled).
|
||||||
|
Find()
|
||||||
|
if result == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return result.(*NodeIPAddressThreshold), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindAllEnabledThresholdsWithAddrId 查找所有阈值
|
||||||
|
func (this *NodeIPAddressThresholdDAO) FindAllEnabledThresholdsWithAddrId(tx *dbs.Tx, addrId int64) (result []*NodeIPAddressThreshold, err error) {
|
||||||
|
_, err = this.Query(tx).
|
||||||
|
Attr("addressId", addrId).
|
||||||
|
State(NodeIPAddressThresholdStateEnabled).
|
||||||
|
AscPk().
|
||||||
|
Desc("order").
|
||||||
|
Slice(&result).
|
||||||
|
FindAll()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 过滤参数
|
||||||
|
for _, threshold := range result {
|
||||||
|
err := this.formatThreshold(tx, threshold)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// CountAllEnabledThresholdsWithAddrId 计算所有阈值数量
|
||||||
|
func (this *NodeIPAddressThresholdDAO) CountAllEnabledThresholdsWithAddrId(tx *dbs.Tx, addrId int64) (int64, error) {
|
||||||
|
return this.Query(tx).
|
||||||
|
Attr("addressId", addrId).
|
||||||
|
State(NodeIPAddressThresholdStateEnabled).
|
||||||
|
Count()
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindThresholdNotifiedAt 查找上次通知时间
|
||||||
|
func (this *NodeIPAddressThresholdDAO) FindThresholdNotifiedAt(tx *dbs.Tx, thresholdId int64) (int64, error) {
|
||||||
|
return this.Query(tx).
|
||||||
|
Pk(thresholdId).
|
||||||
|
Result("notifiedAt").
|
||||||
|
FindInt64Col(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateThresholdNotifiedAt 设置上次通知时间
|
||||||
|
func (this *NodeIPAddressThresholdDAO) UpdateThresholdNotifiedAt(tx *dbs.Tx, thresholdId int64, timestamp int64) error {
|
||||||
|
return this.Query(tx).
|
||||||
|
Pk(thresholdId).
|
||||||
|
Set("notifiedAt", timestamp).
|
||||||
|
UpdateQuickly()
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateThreshold 创建阈值
|
||||||
|
func (this *NodeIPAddressThresholdDAO) CreateThreshold(tx *dbs.Tx, addressId int64, items []*nodeconfigs.IPAddressThresholdItemConfig, actions []*nodeconfigs.IPAddressThresholdActionConfig, order int) (int64, error) {
|
||||||
|
if addressId <= 0 {
|
||||||
|
return 0, errors.New("invalid addressId")
|
||||||
|
}
|
||||||
|
var op = NewNodeIPAddressThresholdOperator()
|
||||||
|
op.Order = order
|
||||||
|
op.AddressId = addressId
|
||||||
|
|
||||||
|
if len(items) > 0 {
|
||||||
|
itemsJSON, err := json.Marshal(items)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
op.Items = itemsJSON
|
||||||
|
} else {
|
||||||
|
op.Items = "[]"
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(actions) > 0 {
|
||||||
|
actionsJSON, err := json.Marshal(actions)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
op.Actions = actionsJSON
|
||||||
|
} else {
|
||||||
|
op.Actions = "[]"
|
||||||
|
}
|
||||||
|
|
||||||
|
op.State = NodeIPAddressThresholdStateEnabled
|
||||||
|
return this.SaveInt64(tx, op)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateThreshold 修改阈值
|
||||||
|
func (this *NodeIPAddressThresholdDAO) UpdateThreshold(tx *dbs.Tx, thresholdId int64, items []*nodeconfigs.IPAddressThresholdItemConfig, actions []*nodeconfigs.IPAddressThresholdActionConfig, order int) error {
|
||||||
|
if thresholdId <= 0 {
|
||||||
|
return errors.New("invalid thresholdId")
|
||||||
|
}
|
||||||
|
var op = NewNodeIPAddressThresholdOperator()
|
||||||
|
|
||||||
|
op.State = NodeIPAddressThresholdStateEnabled // 恢复状态
|
||||||
|
if order >= 0 {
|
||||||
|
op.Order = order
|
||||||
|
}
|
||||||
|
|
||||||
|
op.Id = thresholdId
|
||||||
|
|
||||||
|
if len(items) > 0 {
|
||||||
|
itemsJSON, err := json.Marshal(items)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
op.Items = itemsJSON
|
||||||
|
} else {
|
||||||
|
op.Items = "[]"
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(actions) > 0 {
|
||||||
|
actionsJSON, err := json.Marshal(actions)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
op.Actions = actionsJSON
|
||||||
|
} else {
|
||||||
|
op.Actions = "[]"
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.Save(tx, op)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisableAllThresholdsWithAddrId 禁用所有阈值
|
||||||
|
func (this *NodeIPAddressThresholdDAO) DisableAllThresholdsWithAddrId(tx *dbs.Tx, addrId int64) error {
|
||||||
|
return this.Query(tx).
|
||||||
|
Attr("addressId", addrId).
|
||||||
|
Set("state", NodeIPAddressThresholdStateDisabled).
|
||||||
|
UpdateQuickly()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格式化阈值
|
||||||
|
func (this *NodeIPAddressThresholdDAO) formatThreshold(tx *dbs.Tx, threshold *NodeIPAddressThreshold) error {
|
||||||
|
if len(threshold.Items) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var items = threshold.DecodeItems()
|
||||||
|
for _, item := range items {
|
||||||
|
if item.Item == nodeconfigs.IPAddressThresholdItemConnectivity {
|
||||||
|
if item.Options == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var groups = item.Options.GetSlice("groups")
|
||||||
|
if len(groups) > 0 {
|
||||||
|
var newGroups = []maps.Map{}
|
||||||
|
for _, groupOne := range groups {
|
||||||
|
var groupMap = maps.NewMap(groupOne)
|
||||||
|
var groupId = groupMap.GetInt64("id")
|
||||||
|
group, err := SharedReportNodeGroupDAO.FindEnabledReportNodeGroup(tx, groupId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if group == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
newGroups = append(newGroups, maps.Map{
|
||||||
|
"id": group.Id,
|
||||||
|
"name": group.Name,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
item.Options["groups"] = newGroups
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
itemsJSON, err := json.Marshal(items)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
threshold.Items = string(itemsJSON)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExistsEnabledThreshold 检查阈值是否可以使用
|
||||||
|
func (this *NodeIPAddressThresholdDAO) ExistsEnabledThreshold(tx *dbs.Tx, thresholdId int64) (bool, error) {
|
||||||
|
return this.Query(tx).
|
||||||
|
Pk(thresholdId).
|
||||||
|
State(NodeIPAddressThresholdStateEnabled).
|
||||||
|
Exist()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateThresholdIsMatched 设置是否匹配
|
||||||
|
func (this *NodeIPAddressThresholdDAO) UpdateThresholdIsMatched(tx *dbs.Tx, thresholdId int64, isMatched bool) error {
|
||||||
|
return this.Query(tx).
|
||||||
|
Pk(thresholdId).
|
||||||
|
Set("isMatched", isMatched).
|
||||||
|
UpdateQuickly()
|
||||||
|
}
|
||||||
6
internal/db/models/node_ip_address_threshold_dao_test.go
Normal file
6
internal/db/models/node_ip_address_threshold_dao_test.go
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "github.com/go-sql-driver/mysql"
|
||||||
|
_ "github.com/iwind/TeaGo/bootstrap"
|
||||||
|
)
|
||||||
28
internal/db/models/node_ip_address_threshold_model.go
Normal file
28
internal/db/models/node_ip_address_threshold_model.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
// NodeIPAddressThreshold IP地址阈值
|
||||||
|
type NodeIPAddressThreshold struct {
|
||||||
|
Id uint64 `field:"id"` // ID
|
||||||
|
AddressId uint64 `field:"addressId"` // IP地址ID
|
||||||
|
Items string `field:"items"` // 阈值条目
|
||||||
|
Actions string `field:"actions"` // 动作
|
||||||
|
NotifiedAt uint64 `field:"notifiedAt"` // 上次通知时间
|
||||||
|
IsMatched uint8 `field:"isMatched"` // 上次是否匹配
|
||||||
|
State uint8 `field:"state"` // 状态
|
||||||
|
Order uint32 `field:"order"` // 排序
|
||||||
|
}
|
||||||
|
|
||||||
|
type NodeIPAddressThresholdOperator struct {
|
||||||
|
Id interface{} // ID
|
||||||
|
AddressId interface{} // IP地址ID
|
||||||
|
Items interface{} // 阈值条目
|
||||||
|
Actions interface{} // 动作
|
||||||
|
NotifiedAt interface{} // 上次通知时间
|
||||||
|
IsMatched interface{} // 上次是否匹配
|
||||||
|
State interface{} // 状态
|
||||||
|
Order interface{} // 排序
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewNodeIPAddressThresholdOperator() *NodeIPAddressThresholdOperator {
|
||||||
|
return &NodeIPAddressThresholdOperator{}
|
||||||
|
}
|
||||||
31
internal/db/models/node_ip_address_threshold_model_ext.go
Normal file
31
internal/db/models/node_ip_address_threshold_model_ext.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (this *NodeIPAddressThreshold) DecodeItems() (result []*nodeconfigs.IPAddressThresholdItemConfig) {
|
||||||
|
if len(this.Items) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err := json.Unmarshal([]byte(this.Items), &result)
|
||||||
|
if err != nil {
|
||||||
|
remotelogs.Error("NodeIPAddressThreshold", "decode items: "+err.Error())
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *NodeIPAddressThreshold) DecodeActions() (result []*nodeconfigs.IPAddressThresholdActionConfig) {
|
||||||
|
if len(this.Actions) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err := json.Unmarshal([]byte(this.Actions), &result)
|
||||||
|
if err != nil {
|
||||||
|
remotelogs.Error("NodeIPAddressThreshold", "decode actions: "+err.Error())
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ package models
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -65,6 +66,11 @@ func (this *Node) DNSRouteCodesForDomainId(dnsDomainId int64) ([]string, error)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
domainRoutes, _ := routes[dnsDomainId]
|
domainRoutes, _ := routes[dnsDomainId]
|
||||||
|
|
||||||
|
if len(domainRoutes) > 0 {
|
||||||
|
sort.Strings(domainRoutes)
|
||||||
|
}
|
||||||
|
|
||||||
return domainRoutes, nil
|
return domainRoutes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ func (this *NodeThresholdDAO) FireNodeThreshold(tx *dbs.Tx, role string, nodeId
|
|||||||
if len(threshold.Param) == 0 || threshold.Duration <= 0 {
|
if len(threshold.Param) == 0 || threshold.Duration <= 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
paramValue, err := SharedNodeValueDAO.SumValues(tx, role, nodeId, item, threshold.Param, threshold.SumMethod, types.Int32(threshold.Duration), threshold.DurationUnit)
|
paramValue, err := SharedNodeValueDAO.SumNodeValues(tx, role, nodeId, item, threshold.Param, threshold.SumMethod, types.Int32(threshold.Duration), threshold.DurationUnit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -252,7 +252,7 @@ func (this *NodeThresholdDAO) FireNodeThreshold(tx *dbs.Tx, role string, nodeId
|
|||||||
body = strings.Replace(body, "${item.name}", itemName, -1)
|
body = strings.Replace(body, "${item.name}", itemName, -1)
|
||||||
body = strings.Replace(body, "${value}", fmt.Sprintf("%.2f", paramValue), -1)
|
body = strings.Replace(body, "${value}", fmt.Sprintf("%.2f", paramValue), -1)
|
||||||
}
|
}
|
||||||
err = SharedMessageDAO.CreateNodeMessage(tx, role, clusterId, nodeId, MessageTypeThresholdSatisfied, MessageLevelWarning, subject, body, maps.Map{}.AsJSON())
|
err = SharedMessageDAO.CreateNodeMessage(tx, role, clusterId, nodeId, MessageTypeThresholdSatisfied, MessageLevelWarning, subject, body, maps.Map{}.AsJSON(), true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -173,8 +173,8 @@ func (this *NodeValueDAO) ListValuesForNSNodes(tx *dbs.Tx, item string, key stri
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// SumValues 计算某项参数值
|
// SumNodeValues 计算节点的某项参数值
|
||||||
func (this *NodeValueDAO) SumValues(tx *dbs.Tx, role string, nodeId int64, item string, param string, method nodeconfigs.NodeValueSumMethod, duration int32, durationUnit nodeconfigs.NodeValueDurationUnit) (float64, error) {
|
func (this *NodeValueDAO) SumNodeValues(tx *dbs.Tx, role string, nodeId int64, item string, param string, method nodeconfigs.NodeValueSumMethod, duration int32, durationUnit nodeconfigs.NodeValueDurationUnit) (float64, error) {
|
||||||
if duration <= 0 {
|
if duration <= 0 {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
@@ -202,6 +202,65 @@ func (this *NodeValueDAO) SumValues(tx *dbs.Tx, role string, nodeId int64, item
|
|||||||
return query.FindFloat64Col(0)
|
return query.FindFloat64Col(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SumNodeGroupValues 计算节点分组的某项参数值
|
||||||
|
func (this *NodeValueDAO) SumNodeGroupValues(tx *dbs.Tx, role string, groupId int64, item string, param string, method nodeconfigs.NodeValueSumMethod, duration int32, durationUnit nodeconfigs.NodeValueDurationUnit) (float64, error) {
|
||||||
|
if duration <= 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
query := this.Query(tx).
|
||||||
|
Attr("role", role).
|
||||||
|
Where("nodeId IN (SELECT id FROM "+SharedNodeDAO.Table+" WHERE groupId=:groupId AND state=1)").
|
||||||
|
Param("groupId", groupId).
|
||||||
|
Attr("item", item)
|
||||||
|
switch method {
|
||||||
|
case nodeconfigs.NodeValueSumMethodAvg:
|
||||||
|
query.Result("AVG(JSON_EXTRACT(value, '$." + param + "'))")
|
||||||
|
case nodeconfigs.NodeValueSumMethodSum:
|
||||||
|
query.Result("SUM(JSON_EXTRACT(value, '$." + param + "'))")
|
||||||
|
default:
|
||||||
|
query.Result("AVG(JSON_EXTRACT(value, '$." + param + "'))")
|
||||||
|
}
|
||||||
|
switch durationUnit {
|
||||||
|
case nodeconfigs.NodeValueDurationUnitMinute:
|
||||||
|
fromMinute := timeutil.FormatTime("YmdHi", time.Now().Unix()-int64(duration*60))
|
||||||
|
query.Gte("minute", fromMinute)
|
||||||
|
default:
|
||||||
|
fromMinute := timeutil.FormatTime("YmdHi", time.Now().Unix()-int64(duration*60))
|
||||||
|
query.Gte("minute", fromMinute)
|
||||||
|
}
|
||||||
|
return query.FindFloat64Col(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SumNodeClusterValues 计算节点集群的某项参数值
|
||||||
|
func (this *NodeValueDAO) SumNodeClusterValues(tx *dbs.Tx, role string, clusterId int64, item string, param string, method nodeconfigs.NodeValueSumMethod, duration int32, durationUnit nodeconfigs.NodeValueDurationUnit) (float64, error) {
|
||||||
|
if duration <= 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
query := this.Query(tx).
|
||||||
|
Attr("role", role).
|
||||||
|
Attr("clusterId", clusterId).
|
||||||
|
Attr("item", item)
|
||||||
|
switch method {
|
||||||
|
case nodeconfigs.NodeValueSumMethodAvg:
|
||||||
|
query.Result("AVG(JSON_EXTRACT(value, '$." + param + "'))")
|
||||||
|
case nodeconfigs.NodeValueSumMethodSum:
|
||||||
|
query.Result("SUM(JSON_EXTRACT(value, '$." + param + "'))")
|
||||||
|
default:
|
||||||
|
query.Result("AVG(JSON_EXTRACT(value, '$." + param + "'))")
|
||||||
|
}
|
||||||
|
switch durationUnit {
|
||||||
|
case nodeconfigs.NodeValueDurationUnitMinute:
|
||||||
|
fromMinute := timeutil.FormatTime("YmdHi", time.Now().Unix()-int64(duration*60))
|
||||||
|
query.Gte("minute", fromMinute)
|
||||||
|
default:
|
||||||
|
fromMinute := timeutil.FormatTime("YmdHi", time.Now().Unix()-int64(duration*60))
|
||||||
|
query.Gte("minute", fromMinute)
|
||||||
|
}
|
||||||
|
return query.FindFloat64Col(0)
|
||||||
|
}
|
||||||
|
|
||||||
// FindLatestNodeValue 获取最近一条数据
|
// FindLatestNodeValue 获取最近一条数据
|
||||||
func (this *NodeValueDAO) FindLatestNodeValue(tx *dbs.Tx, role string, nodeId int64, item string) (*NodeValue, error) {
|
func (this *NodeValueDAO) FindLatestNodeValue(tx *dbs.Tx, role string, nodeId int64, item string) (*NodeValue, error) {
|
||||||
one, err := this.Query(tx).
|
one, err := this.Query(tx).
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ func (this *OriginDAO) FindOriginName(tx *dbs.Tx, id int64) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateOrigin 创建源站
|
// CreateOrigin 创建源站
|
||||||
func (this *OriginDAO) CreateOrigin(tx *dbs.Tx, adminId int64, userId int64, name string, addrJSON string, description string, weight int32, isOn bool, connTimeout *shared.TimeDuration, readTimeout *shared.TimeDuration, idleTimeout *shared.TimeDuration, maxConns int32, maxIdleConns int32) (originId int64, err error) {
|
func (this *OriginDAO) CreateOrigin(tx *dbs.Tx, adminId int64, userId int64, name string, addrJSON string, description string, weight int32, isOn bool, connTimeout *shared.TimeDuration, readTimeout *shared.TimeDuration, idleTimeout *shared.TimeDuration, maxConns int32, maxIdleConns int32, domains []string) (originId int64, err error) {
|
||||||
op := NewOriginOperator()
|
op := NewOriginOperator()
|
||||||
op.AdminId = adminId
|
op.AdminId = adminId
|
||||||
op.UserId = userId
|
op.UserId = userId
|
||||||
@@ -132,6 +132,17 @@ func (this *OriginDAO) CreateOrigin(tx *dbs.Tx, adminId int64, userId int64, nam
|
|||||||
weight = 0
|
weight = 0
|
||||||
}
|
}
|
||||||
op.Weight = weight
|
op.Weight = weight
|
||||||
|
|
||||||
|
if len(domains) > 0 {
|
||||||
|
domainsJSON, err := json.Marshal(domains)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
op.Domains = domainsJSON
|
||||||
|
} else {
|
||||||
|
op.Domains = "[]"
|
||||||
|
}
|
||||||
|
|
||||||
op.State = OriginStateEnabled
|
op.State = OriginStateEnabled
|
||||||
err = this.Save(tx, op)
|
err = this.Save(tx, op)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -141,7 +152,7 @@ func (this *OriginDAO) CreateOrigin(tx *dbs.Tx, adminId int64, userId int64, nam
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpdateOrigin 修改源站
|
// UpdateOrigin 修改源站
|
||||||
func (this *OriginDAO) UpdateOrigin(tx *dbs.Tx, originId int64, name string, addrJSON string, description string, weight int32, isOn bool, connTimeout *shared.TimeDuration, readTimeout *shared.TimeDuration, idleTimeout *shared.TimeDuration, maxConns int32, maxIdleConns int32) error {
|
func (this *OriginDAO) UpdateOrigin(tx *dbs.Tx, originId int64, name string, addrJSON string, description string, weight int32, isOn bool, connTimeout *shared.TimeDuration, readTimeout *shared.TimeDuration, idleTimeout *shared.TimeDuration, maxConns int32, maxIdleConns int32, domains []string) error {
|
||||||
if originId <= 0 {
|
if originId <= 0 {
|
||||||
return errors.New("invalid originId")
|
return errors.New("invalid originId")
|
||||||
}
|
}
|
||||||
@@ -189,6 +200,17 @@ func (this *OriginDAO) UpdateOrigin(tx *dbs.Tx, originId int64, name string, add
|
|||||||
|
|
||||||
op.IsOn = isOn
|
op.IsOn = isOn
|
||||||
op.Version = dbs.SQL("version+1")
|
op.Version = dbs.SQL("version+1")
|
||||||
|
|
||||||
|
if len(domains) > 0 {
|
||||||
|
domainsJSON, err := json.Marshal(domains)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
op.Domains = domainsJSON
|
||||||
|
} else {
|
||||||
|
op.Domains = "[]"
|
||||||
|
}
|
||||||
|
|
||||||
err := this.Save(tx, op)
|
err := this.Save(tx, op)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -229,6 +251,7 @@ func (this *OriginDAO) ComposeOriginConfig(tx *dbs.Tx, originId int64, cacheMap
|
|||||||
MaxIdleConns: int(origin.MaxIdleConns),
|
MaxIdleConns: int(origin.MaxIdleConns),
|
||||||
RequestURI: origin.HttpRequestURI,
|
RequestURI: origin.HttpRequestURI,
|
||||||
RequestHost: origin.Host,
|
RequestHost: origin.Host,
|
||||||
|
Domains: origin.DecodeDomains(),
|
||||||
}
|
}
|
||||||
|
|
||||||
if IsNotNull(origin.Addr) {
|
if IsNotNull(origin.Addr) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
// 源站
|
// Origin 源站
|
||||||
type Origin struct {
|
type Origin struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id uint32 `field:"id"` // ID
|
||||||
AdminId uint32 `field:"adminId"` // 管理员ID
|
AdminId uint32 `field:"adminId"` // 管理员ID
|
||||||
@@ -26,6 +26,7 @@ type Origin struct {
|
|||||||
Cert string `field:"cert"` // 证书设置
|
Cert string `field:"cert"` // 证书设置
|
||||||
Ftp string `field:"ftp"` // FTP相关设置
|
Ftp string `field:"ftp"` // FTP相关设置
|
||||||
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
||||||
|
Domains string `field:"domains"` // 所属域名
|
||||||
State uint8 `field:"state"` // 状态
|
State uint8 `field:"state"` // 状态
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,6 +55,7 @@ type OriginOperator struct {
|
|||||||
Cert interface{} // 证书设置
|
Cert interface{} // 证书设置
|
||||||
Ftp interface{} // FTP相关设置
|
Ftp interface{} // FTP相关设置
|
||||||
CreatedAt interface{} // 创建时间
|
CreatedAt interface{} // 创建时间
|
||||||
|
Domains interface{} // 所属域名
|
||||||
State interface{} // 状态
|
State interface{} // 状态
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,11 @@ package models
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 解析地址
|
// DecodeAddr 解析地址
|
||||||
func (this *Origin) DecodeAddr() (*serverconfigs.NetworkAddressConfig, error) {
|
func (this *Origin) DecodeAddr() (*serverconfigs.NetworkAddressConfig, error) {
|
||||||
if len(this.Addr) == 0 || this.Addr == "null" {
|
if len(this.Addr) == 0 || this.Addr == "null" {
|
||||||
return nil, errors.New("addr is empty")
|
return nil, errors.New("addr is empty")
|
||||||
@@ -15,3 +16,14 @@ func (this *Origin) DecodeAddr() (*serverconfigs.NetworkAddressConfig, error) {
|
|||||||
err := json.Unmarshal([]byte(this.Addr), addr)
|
err := json.Unmarshal([]byte(this.Addr), addr)
|
||||||
return addr, err
|
return addr, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *Origin) DecodeDomains() []string {
|
||||||
|
var result = []string{}
|
||||||
|
if len(this.Domains) > 0 {
|
||||||
|
err := json.Unmarshal([]byte(this.Domains), &result)
|
||||||
|
if err != nil {
|
||||||
|
remotelogs.Error("Origin.DecodeDomains", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,12 +3,14 @@ package models
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/reporterconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/reporterconfigs"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"github.com/iwind/TeaGo/Tea"
|
"github.com/iwind/TeaGo/Tea"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
"github.com/iwind/TeaGo/rands"
|
"github.com/iwind/TeaGo/rands"
|
||||||
|
"github.com/iwind/TeaGo/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -76,7 +78,7 @@ func (this *ReportNodeDAO) FindReportNodeName(tx *dbs.Tx, id int64) (string, err
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateReportNode 创建终端
|
// CreateReportNode 创建终端
|
||||||
func (this *ReportNodeDAO) CreateReportNode(tx *dbs.Tx, name string, location string, isp string, allowIPs []string) (int64, error) {
|
func (this *ReportNodeDAO) CreateReportNode(tx *dbs.Tx, name string, location string, isp string, allowIPs []string, groupIds []int64) (int64, error) {
|
||||||
uniqueId, err := this.GenUniqueId(tx)
|
uniqueId, err := this.GenUniqueId(tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@@ -107,13 +109,23 @@ func (this *ReportNodeDAO) CreateReportNode(tx *dbs.Tx, name string, location st
|
|||||||
op.AllowIPs = "[]"
|
op.AllowIPs = "[]"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(groupIds) > 0 {
|
||||||
|
groupIdsJSON, err := json.Marshal(groupIds)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
op.GroupIds = groupIdsJSON
|
||||||
|
} else {
|
||||||
|
op.GroupIds = "[]"
|
||||||
|
}
|
||||||
|
|
||||||
op.IsOn = true
|
op.IsOn = true
|
||||||
op.State = ReportNodeStateEnabled
|
op.State = ReportNodeStateEnabled
|
||||||
return this.SaveInt64(tx, op)
|
return this.SaveInt64(tx, op)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateReportNode 修改终端
|
// UpdateReportNode 修改终端
|
||||||
func (this *ReportNodeDAO) UpdateReportNode(tx *dbs.Tx, nodeId int64, name string, location string, isp string, allowIPs []string, isOn bool) error {
|
func (this *ReportNodeDAO) UpdateReportNode(tx *dbs.Tx, nodeId int64, name string, location string, isp string, allowIPs []string, groupIds []int64, isOn bool) error {
|
||||||
if nodeId <= 0 {
|
if nodeId <= 0 {
|
||||||
return errors.New("invalid nodeId")
|
return errors.New("invalid nodeId")
|
||||||
}
|
}
|
||||||
@@ -134,14 +146,27 @@ func (this *ReportNodeDAO) UpdateReportNode(tx *dbs.Tx, nodeId int64, name strin
|
|||||||
op.AllowIPs = "[]"
|
op.AllowIPs = "[]"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(groupIds) > 0 {
|
||||||
|
groupIdsJSON, err := json.Marshal(groupIds)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
op.GroupIds = groupIdsJSON
|
||||||
|
} else {
|
||||||
|
op.GroupIds = "[]"
|
||||||
|
}
|
||||||
|
|
||||||
op.IsOn = isOn
|
op.IsOn = isOn
|
||||||
return this.Save(tx, op)
|
return this.Save(tx, op)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CountAllEnabledReportNodes 计算终端数量
|
// CountAllEnabledReportNodes 计算终端数量
|
||||||
func (this *ReportNodeDAO) CountAllEnabledReportNodes(tx *dbs.Tx, keyword string) (int64, error) {
|
func (this *ReportNodeDAO) CountAllEnabledReportNodes(tx *dbs.Tx, groupId int64, keyword string) (int64, error) {
|
||||||
var query = this.Query(tx).
|
var query = this.Query(tx).
|
||||||
State(ReportNodeStateEnabled)
|
State(ReportNodeStateEnabled)
|
||||||
|
if groupId > 0 {
|
||||||
|
query.JSONContains("groupIds", types.String(groupId))
|
||||||
|
}
|
||||||
if len(keyword) > 0 {
|
if len(keyword) > 0 {
|
||||||
query.Where("(name LIKE :keyword OR location LIKE :keyword OR isp LIKE :keyword OR allowIPs LIKE :keyword OR (status IS NOT NULL AND JSON_EXTRACT(status, 'ip') LIKE :keyword))")
|
query.Where("(name LIKE :keyword OR location LIKE :keyword OR isp LIKE :keyword OR allowIPs LIKE :keyword OR (status IS NOT NULL AND JSON_EXTRACT(status, 'ip') LIKE :keyword))")
|
||||||
query.Param("keyword", "%"+keyword+"%")
|
query.Param("keyword", "%"+keyword+"%")
|
||||||
@@ -149,10 +174,21 @@ func (this *ReportNodeDAO) CountAllEnabledReportNodes(tx *dbs.Tx, keyword string
|
|||||||
return query.Count()
|
return query.Count()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CountAllEnabledAndOnReportNodes 计算可用的终端数量
|
||||||
|
func (this *ReportNodeDAO) CountAllEnabledAndOnReportNodes(tx *dbs.Tx) (int64, error) {
|
||||||
|
var query = this.Query(tx).
|
||||||
|
Attr("isOn", true).
|
||||||
|
State(ReportNodeStateEnabled)
|
||||||
|
return query.Count()
|
||||||
|
}
|
||||||
|
|
||||||
// ListEnabledReportNodes 列出单页终端
|
// ListEnabledReportNodes 列出单页终端
|
||||||
func (this *ReportNodeDAO) ListEnabledReportNodes(tx *dbs.Tx, keyword string, offset int64, size int64) (result []*ReportNode, err error) {
|
func (this *ReportNodeDAO) ListEnabledReportNodes(tx *dbs.Tx, groupId int64, keyword string, offset int64, size int64) (result []*ReportNode, err error) {
|
||||||
var query = this.Query(tx).
|
var query = this.Query(tx).
|
||||||
State(ReportNodeStateEnabled)
|
State(ReportNodeStateEnabled)
|
||||||
|
if groupId > 0 {
|
||||||
|
query.JSONContains("groupIds", types.String(groupId))
|
||||||
|
}
|
||||||
if len(keyword) > 0 {
|
if len(keyword) > 0 {
|
||||||
query.Where(`(
|
query.Where(`(
|
||||||
name LIKE :keyword
|
name LIKE :keyword
|
||||||
@@ -267,3 +303,13 @@ func (this *ReportNodeDAO) FindNodeAllowIPs(tx *dbs.Tx, nodeId int64) ([]string,
|
|||||||
}
|
}
|
||||||
return node.(*ReportNode).DecodeAllowIPs(), nil
|
return node.(*ReportNode).DecodeAllowIPs(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CountAllLowerVersionNodes 计算所有节点中低于某个版本的节点数量
|
||||||
|
func (this *ReportNodeDAO) CountAllLowerVersionNodes(tx *dbs.Tx, version string) (int64, error) {
|
||||||
|
return this.Query(tx).
|
||||||
|
State(ReportNodeStateEnabled).
|
||||||
|
Where("status IS NOT NULL").
|
||||||
|
Where("(JSON_EXTRACT(status, '$.buildVersionCode') IS NULL OR JSON_EXTRACT(status, '$.buildVersionCode')<:version)").
|
||||||
|
Param("version", utils.VersionToLong(version)).
|
||||||
|
Count()
|
||||||
|
}
|
||||||
|
|||||||
109
internal/db/models/report_node_group_dao.go
Normal file
109
internal/db/models/report_node_group_dao.go
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||||
|
_ "github.com/go-sql-driver/mysql"
|
||||||
|
"github.com/iwind/TeaGo/Tea"
|
||||||
|
"github.com/iwind/TeaGo/dbs"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ReportNodeGroupStateEnabled = 1 // 已启用
|
||||||
|
ReportNodeGroupStateDisabled = 0 // 已禁用
|
||||||
|
)
|
||||||
|
|
||||||
|
type ReportNodeGroupDAO dbs.DAO
|
||||||
|
|
||||||
|
func NewReportNodeGroupDAO() *ReportNodeGroupDAO {
|
||||||
|
return dbs.NewDAO(&ReportNodeGroupDAO{
|
||||||
|
DAOObject: dbs.DAOObject{
|
||||||
|
DB: Tea.Env,
|
||||||
|
Table: "edgeReportNodeGroups",
|
||||||
|
Model: new(ReportNodeGroup),
|
||||||
|
PkName: "id",
|
||||||
|
},
|
||||||
|
}).(*ReportNodeGroupDAO)
|
||||||
|
}
|
||||||
|
|
||||||
|
var SharedReportNodeGroupDAO *ReportNodeGroupDAO
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
dbs.OnReady(func() {
|
||||||
|
SharedReportNodeGroupDAO = NewReportNodeGroupDAO()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnableReportNodeGroup 启用条目
|
||||||
|
func (this *ReportNodeGroupDAO) EnableReportNodeGroup(tx *dbs.Tx, id uint32) error {
|
||||||
|
_, err := this.Query(tx).
|
||||||
|
Pk(id).
|
||||||
|
Set("state", ReportNodeGroupStateEnabled).
|
||||||
|
Update()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisableReportNodeGroup 禁用条目
|
||||||
|
func (this *ReportNodeGroupDAO) DisableReportNodeGroup(tx *dbs.Tx, id int64) error {
|
||||||
|
_, err := this.Query(tx).
|
||||||
|
Pk(id).
|
||||||
|
Set("state", ReportNodeGroupStateDisabled).
|
||||||
|
Update()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindEnabledReportNodeGroup 查找启用中的条目
|
||||||
|
func (this *ReportNodeGroupDAO) FindEnabledReportNodeGroup(tx *dbs.Tx, id int64) (*ReportNodeGroup, error) {
|
||||||
|
result, err := this.Query(tx).
|
||||||
|
Pk(id).
|
||||||
|
Attr("state", ReportNodeGroupStateEnabled).
|
||||||
|
Find()
|
||||||
|
if result == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return result.(*ReportNodeGroup), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindReportNodeGroupName 根据主键查找名称
|
||||||
|
func (this *ReportNodeGroupDAO) FindReportNodeGroupName(tx *dbs.Tx, id int64) (string, error) {
|
||||||
|
return this.Query(tx).
|
||||||
|
Pk(id).
|
||||||
|
Result("name").
|
||||||
|
FindStringCol("")
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateGroup 创建
|
||||||
|
func (this *ReportNodeGroupDAO) CreateGroup(tx *dbs.Tx, name string) (int64, error) {
|
||||||
|
var op = NewReportNodeGroupOperator()
|
||||||
|
op.Name = name
|
||||||
|
op.IsOn = true
|
||||||
|
op.State = ReportNodeGroupStateEnabled
|
||||||
|
return this.SaveInt64(tx, op)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateGroup 修改
|
||||||
|
func (this *ReportNodeGroupDAO) UpdateGroup(tx *dbs.Tx, groupId int64, name string) error {
|
||||||
|
if groupId <= 0 {
|
||||||
|
return errors.New("invalid groupId")
|
||||||
|
}
|
||||||
|
var op = NewReportNodeGroupOperator()
|
||||||
|
op.Id = groupId
|
||||||
|
op.Name = name
|
||||||
|
return this.Save(tx, op)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindAllEnabledGroups 查找所有可用的分组
|
||||||
|
func (this *ReportNodeGroupDAO) FindAllEnabledGroups(tx *dbs.Tx) (result []*ReportNodeGroup, err error) {
|
||||||
|
_, err = this.Query(tx).
|
||||||
|
State(ReportNodeGroupStateEnabled).
|
||||||
|
AscPk().
|
||||||
|
Slice(&result).
|
||||||
|
FindAll()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// CountAllEnabledGroups 查找所有分组的数量
|
||||||
|
func (this *ReportNodeGroupDAO) CountAllEnabledGroups(tx *dbs.Tx) (int64, error) {
|
||||||
|
return this.Query(tx).
|
||||||
|
State(ReportNodeGroupStateEnabled).
|
||||||
|
Count()
|
||||||
|
}
|
||||||
6
internal/db/models/report_node_group_dao_test.go
Normal file
6
internal/db/models/report_node_group_dao_test.go
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "github.com/go-sql-driver/mysql"
|
||||||
|
_ "github.com/iwind/TeaGo/bootstrap"
|
||||||
|
)
|
||||||
20
internal/db/models/report_node_group_model.go
Normal file
20
internal/db/models/report_node_group_model.go
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
// ReportNodeGroup 监控终端区域
|
||||||
|
type ReportNodeGroup struct {
|
||||||
|
Id uint32 `field:"id"` // ID
|
||||||
|
Name string `field:"name"` // 名称
|
||||||
|
State uint8 `field:"state"` // 状态
|
||||||
|
IsOn uint8 `field:"isOn"` // 是否启用
|
||||||
|
}
|
||||||
|
|
||||||
|
type ReportNodeGroupOperator struct {
|
||||||
|
Id interface{} // ID
|
||||||
|
Name interface{} // 名称
|
||||||
|
State interface{} // 状态
|
||||||
|
IsOn interface{} // 是否启用
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewReportNodeGroupOperator() *ReportNodeGroupOperator {
|
||||||
|
return &ReportNodeGroupOperator{}
|
||||||
|
}
|
||||||
1
internal/db/models/report_node_group_model_ext.go
Normal file
1
internal/db/models/report_node_group_model_ext.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package models
|
||||||
@@ -14,6 +14,7 @@ type ReportNode struct {
|
|||||||
Status string `field:"status"` // 状态
|
Status string `field:"status"` // 状态
|
||||||
State uint8 `field:"state"` // 状态
|
State uint8 `field:"state"` // 状态
|
||||||
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
||||||
|
GroupIds string `field:"groupIds"` // 分组ID
|
||||||
}
|
}
|
||||||
|
|
||||||
type ReportNodeOperator struct {
|
type ReportNodeOperator struct {
|
||||||
@@ -29,6 +30,7 @@ type ReportNodeOperator struct {
|
|||||||
Status interface{} // 状态
|
Status interface{} // 状态
|
||||||
State interface{} // 状态
|
State interface{} // 状态
|
||||||
CreatedAt interface{} // 创建时间
|
CreatedAt interface{} // 创建时间
|
||||||
|
GroupIds interface{} // 分组ID
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewReportNodeOperator() *ReportNodeOperator {
|
func NewReportNodeOperator() *ReportNodeOperator {
|
||||||
|
|||||||
@@ -1,12 +1,28 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import "encoding/json"
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||||
|
)
|
||||||
|
|
||||||
func (this *ReportNode) DecodeAllowIPs() []string {
|
func (this *ReportNode) DecodeAllowIPs() []string {
|
||||||
var result = []string{}
|
var result = []string{}
|
||||||
if len(this.AllowIPs) > 0 {
|
if len(this.AllowIPs) > 0 {
|
||||||
// 忽略错误
|
err := json.Unmarshal([]byte(this.AllowIPs), &result)
|
||||||
_ = json.Unmarshal([]byte(this.AllowIPs), &result)
|
if err != nil {
|
||||||
|
remotelogs.Error("ReportNode.DecodeGroupIds", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *ReportNode) DecodeGroupIds() []int64 {
|
||||||
|
var result = []int64{}
|
||||||
|
if len(this.GroupIds) > 0 {
|
||||||
|
err := json.Unmarshal([]byte(this.GroupIds), &result)
|
||||||
|
if err != nil {
|
||||||
|
remotelogs.Error("ReportNode.DecodeGroupIds", err.Error())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,12 @@ package models
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/reporterconfigs"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"github.com/iwind/TeaGo/Tea"
|
"github.com/iwind/TeaGo/Tea"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
"github.com/iwind/TeaGo/maps"
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
"github.com/iwind/TeaGo/types"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -31,7 +33,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpdateResult 创建结果
|
// UpdateResult 创建结果
|
||||||
func (this *ReportResultDAO) UpdateResult(tx *dbs.Tx, taskType string, targetId int64, targetDesc string, reportNodeId int64, isOk bool, costMs float64, errString string) error {
|
func (this *ReportResultDAO) UpdateResult(tx *dbs.Tx, taskType string, targetId int64, targetDesc string, reportNodeId int64, level reporterconfigs.ReportLevel, isOk bool, costMs float64, errString string) error {
|
||||||
var countUp interface{} = 0
|
var countUp interface{} = 0
|
||||||
var countDown interface{} = 0
|
var countDown interface{} = 0
|
||||||
if isOk {
|
if isOk {
|
||||||
@@ -52,6 +54,7 @@ func (this *ReportResultDAO) UpdateResult(tx *dbs.Tx, taskType string, targetId
|
|||||||
"error": errString,
|
"error": errString,
|
||||||
"countUp": countUp,
|
"countUp": countUp,
|
||||||
"countDown": countDown,
|
"countDown": countDown,
|
||||||
|
"level": level,
|
||||||
}, maps.Map{
|
}, maps.Map{
|
||||||
"targetDesc": targetDesc,
|
"targetDesc": targetDesc,
|
||||||
"updatedAt": time.Now().Unix(),
|
"updatedAt": time.Now().Unix(),
|
||||||
@@ -60,11 +63,12 @@ func (this *ReportResultDAO) UpdateResult(tx *dbs.Tx, taskType string, targetId
|
|||||||
"error": errString,
|
"error": errString,
|
||||||
"countUp": countUp,
|
"countUp": countUp,
|
||||||
"countDown": countDown,
|
"countDown": countDown,
|
||||||
|
"level": level,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// CountAllResults 计算结果数量
|
// CountAllResults 计算结果数量
|
||||||
func (this *ReportResultDAO) CountAllResults(tx *dbs.Tx, reportNodeId int64, okState configutils.BoolState) (int64, error) {
|
func (this *ReportResultDAO) CountAllResults(tx *dbs.Tx, reportNodeId int64, level reporterconfigs.ReportLevel, okState configutils.BoolState) (int64, error) {
|
||||||
var query = this.Query(tx).
|
var query = this.Query(tx).
|
||||||
Attr("reportNodeId", reportNodeId)
|
Attr("reportNodeId", reportNodeId)
|
||||||
switch okState {
|
switch okState {
|
||||||
@@ -73,12 +77,16 @@ func (this *ReportResultDAO) CountAllResults(tx *dbs.Tx, reportNodeId int64, okS
|
|||||||
case configutils.BoolStateNo:
|
case configutils.BoolStateNo:
|
||||||
query.Attr("isOk", 0)
|
query.Attr("isOk", 0)
|
||||||
}
|
}
|
||||||
|
if len(level) > 0 {
|
||||||
|
query.Attr("level", level)
|
||||||
|
}
|
||||||
return query.
|
return query.
|
||||||
|
Gt("updatedAt", time.Now().Unix()-600).
|
||||||
Count()
|
Count()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListResults 列出单页结果
|
// ListResults 列出单页结果
|
||||||
func (this *ReportResultDAO) ListResults(tx *dbs.Tx, reportNodeId int64, okState configutils.BoolState, offset int64, size int64) (result []*ReportResult, err error) {
|
func (this *ReportResultDAO) ListResults(tx *dbs.Tx, reportNodeId int64, okState configutils.BoolState, level reporterconfigs.ReportLevel, offset int64, size int64) (result []*ReportResult, err error) {
|
||||||
var query = this.Query(tx).
|
var query = this.Query(tx).
|
||||||
Attr("reportNodeId", reportNodeId)
|
Attr("reportNodeId", reportNodeId)
|
||||||
switch okState {
|
switch okState {
|
||||||
@@ -87,8 +95,11 @@ func (this *ReportResultDAO) ListResults(tx *dbs.Tx, reportNodeId int64, okState
|
|||||||
case configutils.BoolStateNo:
|
case configutils.BoolStateNo:
|
||||||
query.Attr("isOk", 0)
|
query.Attr("isOk", 0)
|
||||||
}
|
}
|
||||||
|
if len(level) > 0 {
|
||||||
|
query.Attr("level", level)
|
||||||
|
}
|
||||||
_, err = query.
|
_, err = query.
|
||||||
Attr("reportNodeId", reportNodeId).
|
Gt("updatedAt", time.Now().Unix()-600).
|
||||||
Offset(offset).
|
Offset(offset).
|
||||||
Limit(size).
|
Limit(size).
|
||||||
Desc("targetId").
|
Desc("targetId").
|
||||||
@@ -96,3 +107,116 @@ func (this *ReportResultDAO) ListResults(tx *dbs.Tx, reportNodeId int64, okState
|
|||||||
FindAll()
|
FindAll()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindAllResults 列出所有结果
|
||||||
|
func (this *ReportResultDAO) FindAllResults(tx *dbs.Tx, taskType string, targetId int64) (result []*ReportResult, err error) {
|
||||||
|
_, err = this.Query(tx).
|
||||||
|
Attr("type", taskType).
|
||||||
|
Attr("targetId", targetId).
|
||||||
|
Gt("updatedAt", time.Now().Unix()-600).
|
||||||
|
Desc("isOk").
|
||||||
|
Asc("costMs").
|
||||||
|
Slice(&result).
|
||||||
|
FindAll()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindAvgCostMsWithTarget 获取某个对象的平均耗时
|
||||||
|
func (this *ReportResultDAO) FindAvgCostMsWithTarget(tx *dbs.Tx, taskType reporterconfigs.TaskType, targetId int64) (float64, error) {
|
||||||
|
return this.Query(tx).
|
||||||
|
Attr("type", taskType).
|
||||||
|
Attr("targetId", targetId).
|
||||||
|
Where("reportNodeId IN (SELECT id FROM "+SharedReportNodeDAO.Table+" WHERE state=1 AND isOn=1)").
|
||||||
|
Attr("isOk", true).
|
||||||
|
Gt("updatedAt", time.Now().Unix()-600).
|
||||||
|
Avg("costMs", 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindAvgLevelWithTarget 获取某个对象的平均级别
|
||||||
|
func (this *ReportResultDAO) FindAvgLevelWithTarget(tx *dbs.Tx, taskType reporterconfigs.TaskType, targetId int64) (string, error) {
|
||||||
|
ones, _, err := this.Query(tx).
|
||||||
|
Result("COUNT(*) AS c, level").
|
||||||
|
Attr("type", taskType).
|
||||||
|
Attr("targetId", targetId).
|
||||||
|
Where("reportNodeId IN (SELECT id FROM "+SharedReportNodeDAO.Table+" WHERE state=1 AND isOn=1)").
|
||||||
|
Gt("updatedAt", time.Now().Unix()-600).
|
||||||
|
Group("level").
|
||||||
|
FindOnes()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(ones) == 0 {
|
||||||
|
return reporterconfigs.ReportLevelNormal, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var total = 0
|
||||||
|
var levelMap = map[string]int{} // code => count
|
||||||
|
for _, one := range ones {
|
||||||
|
var c = one.GetInt("c")
|
||||||
|
total += c
|
||||||
|
levelMap[one.GetString("level")] = c
|
||||||
|
}
|
||||||
|
if total == 0 {
|
||||||
|
return reporterconfigs.ReportLevelNormal, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var half = total / 2
|
||||||
|
for _, def := range reporterconfigs.FindAllReportLevels() {
|
||||||
|
c, ok := levelMap[def.Code]
|
||||||
|
if ok {
|
||||||
|
half -= c
|
||||||
|
if half <= 0 {
|
||||||
|
return def.Code, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindConnectivityWithTargetPercent 获取某个对象的连通率
|
||||||
|
// 返回值在0-100
|
||||||
|
func (this *ReportResultDAO) FindConnectivityWithTargetPercent(tx *dbs.Tx, taskType reporterconfigs.TaskType, targetId int64, groupId int64) (float64, error) {
|
||||||
|
var query = this.Query(tx).
|
||||||
|
Attr("type", taskType).
|
||||||
|
Attr("targetId", targetId)
|
||||||
|
if groupId > 0 {
|
||||||
|
query.Where("reportNodeId IN (SELECT id FROM "+SharedReportNodeDAO.Table+" WHERE state=1 AND isOn=1 AND JSON_CONTAINS(groupIds, :groupIdString))").
|
||||||
|
Param("groupIdString", types.String(groupId))
|
||||||
|
} else {
|
||||||
|
query.Where("reportNodeId IN (SELECT id FROM " + SharedReportNodeDAO.Table + " WHERE state=1 AND isOn=1)")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 已汇报数据的数量
|
||||||
|
total, err := query.
|
||||||
|
Gt("updatedAt", time.Now().Unix()-600).
|
||||||
|
Count()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if total == 0 {
|
||||||
|
return 100, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 连通的数量
|
||||||
|
var connectedQuery = this.Query(tx).
|
||||||
|
Attr("type", taskType).
|
||||||
|
Attr("targetId", targetId)
|
||||||
|
|
||||||
|
if groupId > 0 {
|
||||||
|
connectedQuery.Where("reportNodeId IN (SELECT id FROM "+SharedReportNodeDAO.Table+" WHERE state=1 AND isOn=1 AND JSON_CONTAINS(groupIds, :groupIdString))").
|
||||||
|
Param("groupIdString", types.String(groupId))
|
||||||
|
} else {
|
||||||
|
connectedQuery.Where("reportNodeId IN (SELECT id FROM " + SharedReportNodeDAO.Table + " WHERE state=1 AND isOn=1)")
|
||||||
|
}
|
||||||
|
|
||||||
|
countConnected, err := connectedQuery.
|
||||||
|
Attr("isOk", true).
|
||||||
|
Gt("updatedAt", time.Now().Unix()-600).
|
||||||
|
Count()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return float64(countConnected) * 100 / float64(total), nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ type ReportResult struct {
|
|||||||
UpdatedAt uint64 `field:"updatedAt"` // 更新时间
|
UpdatedAt uint64 `field:"updatedAt"` // 更新时间
|
||||||
ReportNodeId uint32 `field:"reportNodeId"` // 监控节点ID
|
ReportNodeId uint32 `field:"reportNodeId"` // 监控节点ID
|
||||||
IsOk uint8 `field:"isOk"` // 是否可连接
|
IsOk uint8 `field:"isOk"` // 是否可连接
|
||||||
|
Level string `field:"level"` // 级别
|
||||||
CostMs float64 `field:"costMs"` // 单次连接花费的时间
|
CostMs float64 `field:"costMs"` // 单次连接花费的时间
|
||||||
Error string `field:"error"` // 产生的错误信息
|
Error string `field:"error"` // 产生的错误信息
|
||||||
CountUp uint32 `field:"countUp"` // 连续上线次数
|
CountUp uint32 `field:"countUp"` // 连续上线次数
|
||||||
@@ -23,6 +24,7 @@ type ReportResultOperator struct {
|
|||||||
UpdatedAt interface{} // 更新时间
|
UpdatedAt interface{} // 更新时间
|
||||||
ReportNodeId interface{} // 监控节点ID
|
ReportNodeId interface{} // 监控节点ID
|
||||||
IsOk interface{} // 是否可连接
|
IsOk interface{} // 是否可连接
|
||||||
|
Level interface{} // 级别
|
||||||
CostMs interface{} // 单次连接花费的时间
|
CostMs interface{} // 单次连接花费的时间
|
||||||
Error interface{} // 产生的错误信息
|
Error interface{} // 产生的错误信息
|
||||||
CountUp interface{} // 连续上线次数
|
CountUp interface{} // 连续上线次数
|
||||||
|
|||||||
@@ -406,5 +406,14 @@ func (this *ReverseProxyDAO) NotifyUpdate(tx *dbs.Tx, reverseProxyId int64) erro
|
|||||||
return SharedHTTPLocationDAO.NotifyUpdate(tx, locationId)
|
return SharedHTTPLocationDAO.NotifyUpdate(tx, locationId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// group
|
||||||
|
groupId, err := SharedServerGroupDAO.FindEnabledGroupIdWithReverseProxyId(tx, reverseProxyId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if groupId > 0 {
|
||||||
|
return SharedServerGroupDAO.NotifyUpdate(tx, groupId)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -713,6 +713,44 @@ func (this *ServerDAO) FindAllEnabledServerIdsWithUserId(tx *dbs.Tx, userId int6
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindAllEnabledServerIdsWithGroupId 获取某个分组下的所有的服务ID
|
||||||
|
func (this *ServerDAO) FindAllEnabledServerIdsWithGroupId(tx *dbs.Tx, groupId int64) (serverIds []int64, err error) {
|
||||||
|
ones, err := this.Query(tx).
|
||||||
|
State(ServerStateEnabled).
|
||||||
|
Where("JSON_CONTAINS(groupIds, :groupId)").
|
||||||
|
Param("groupId", numberutils.FormatInt64(groupId)).
|
||||||
|
AscPk().
|
||||||
|
ResultPk().
|
||||||
|
FindAll()
|
||||||
|
for _, one := range ones {
|
||||||
|
serverIds = append(serverIds, int64(one.(*Server).Id))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindServerGroupIds 获取服务的分组ID
|
||||||
|
func (this *ServerDAO) FindServerGroupIds(tx *dbs.Tx, serverId int64) ([]int64, error) {
|
||||||
|
if serverId <= 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
groupIdsString, err := this.Query(tx).
|
||||||
|
Pk(serverId).
|
||||||
|
Result("groupIds").
|
||||||
|
FindStringCol("")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(groupIdsString) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
var result = []int64{}
|
||||||
|
err = json.Unmarshal([]byte(groupIdsString), &result)
|
||||||
|
if err != nil {
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
// FindServerNodeFilters 查找服务的搜索条件
|
// FindServerNodeFilters 查找服务的搜索条件
|
||||||
func (this *ServerDAO) FindServerNodeFilters(tx *dbs.Tx, serverId int64) (isOk bool, clusterId int64, err error) {
|
func (this *ServerDAO) FindServerNodeFilters(tx *dbs.Tx, serverId int64) (isOk bool, clusterId int64, err error) {
|
||||||
one, err := this.Query(tx).
|
one, err := this.Query(tx).
|
||||||
@@ -760,6 +798,20 @@ func (this *ServerDAO) ComposeServerConfig(tx *dbs.Tx, server *Server, cacheMap
|
|||||||
config.Name = server.Name
|
config.Name = server.Name
|
||||||
config.Description = server.Description
|
config.Description = server.Description
|
||||||
|
|
||||||
|
var groupConfig *serverconfigs.ServerGroupConfig
|
||||||
|
for _, groupId := range server.DecodeGroupIds() {
|
||||||
|
groupConfig1, err := SharedServerGroupDAO.ComposeGroupConfig(tx, groupId, cacheMap)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if groupConfig1 == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
groupConfig = groupConfig1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
config.Group = groupConfig
|
||||||
|
|
||||||
// ServerNames
|
// ServerNames
|
||||||
if len(server.ServerNames) > 0 && server.ServerNames != "null" {
|
if len(server.ServerNames) > 0 && server.ServerNames != "null" {
|
||||||
serverNames := []*serverconfigs.ServerNameConfig{}
|
serverNames := []*serverconfigs.ServerNameConfig{}
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"github.com/iwind/TeaGo/Tea"
|
"github.com/iwind/TeaGo/Tea"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
|
"github.com/iwind/TeaGo/maps"
|
||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -34,7 +37,7 @@ func init() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 启用条目
|
// EnableServerGroup 启用条目
|
||||||
func (this *ServerGroupDAO) EnableServerGroup(tx *dbs.Tx, id int64) error {
|
func (this *ServerGroupDAO) EnableServerGroup(tx *dbs.Tx, id int64) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Pk(id).
|
Pk(id).
|
||||||
@@ -43,7 +46,7 @@ func (this *ServerGroupDAO) EnableServerGroup(tx *dbs.Tx, id int64) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 禁用条目
|
// DisableServerGroup 禁用条目
|
||||||
func (this *ServerGroupDAO) DisableServerGroup(tx *dbs.Tx, id int64) error {
|
func (this *ServerGroupDAO) DisableServerGroup(tx *dbs.Tx, id int64) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Pk(id).
|
Pk(id).
|
||||||
@@ -52,7 +55,7 @@ func (this *ServerGroupDAO) DisableServerGroup(tx *dbs.Tx, id int64) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查找启用中的条目
|
// FindEnabledServerGroup 查找启用中的条目
|
||||||
func (this *ServerGroupDAO) FindEnabledServerGroup(tx *dbs.Tx, id int64) (*ServerGroup, error) {
|
func (this *ServerGroupDAO) FindEnabledServerGroup(tx *dbs.Tx, id int64) (*ServerGroup, error) {
|
||||||
result, err := this.Query(tx).
|
result, err := this.Query(tx).
|
||||||
Pk(id).
|
Pk(id).
|
||||||
@@ -64,7 +67,7 @@ func (this *ServerGroupDAO) FindEnabledServerGroup(tx *dbs.Tx, id int64) (*Serve
|
|||||||
return result.(*ServerGroup), err
|
return result.(*ServerGroup), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据主键查找名称
|
// FindServerGroupName 根据主键查找名称
|
||||||
func (this *ServerGroupDAO) FindServerGroupName(tx *dbs.Tx, id int64) (string, error) {
|
func (this *ServerGroupDAO) FindServerGroupName(tx *dbs.Tx, id int64) (string, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Pk(id).
|
Pk(id).
|
||||||
@@ -72,11 +75,12 @@ func (this *ServerGroupDAO) FindServerGroupName(tx *dbs.Tx, id int64) (string, e
|
|||||||
FindStringCol("")
|
FindStringCol("")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建分组
|
// CreateGroup 创建分组
|
||||||
func (this *ServerGroupDAO) CreateGroup(tx *dbs.Tx, name string) (groupId int64, err error) {
|
func (this *ServerGroupDAO) CreateGroup(tx *dbs.Tx, name string) (groupId int64, err error) {
|
||||||
op := NewServerGroupOperator()
|
op := NewServerGroupOperator()
|
||||||
op.State = ServerGroupStateEnabled
|
op.State = ServerGroupStateEnabled
|
||||||
op.Name = name
|
op.Name = name
|
||||||
|
op.IsOn = true
|
||||||
err = this.Save(tx, op)
|
err = this.Save(tx, op)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@@ -84,7 +88,7 @@ func (this *ServerGroupDAO) CreateGroup(tx *dbs.Tx, name string) (groupId int64,
|
|||||||
return types.Int64(op.Id), nil
|
return types.Int64(op.Id), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 修改分组
|
// UpdateGroup 修改分组
|
||||||
func (this *ServerGroupDAO) UpdateGroup(tx *dbs.Tx, groupId int64, name string) error {
|
func (this *ServerGroupDAO) UpdateGroup(tx *dbs.Tx, groupId int64, name string) error {
|
||||||
if groupId <= 0 {
|
if groupId <= 0 {
|
||||||
return errors.New("invalid groupId")
|
return errors.New("invalid groupId")
|
||||||
@@ -96,7 +100,7 @@ func (this *ServerGroupDAO) UpdateGroup(tx *dbs.Tx, groupId int64, name string)
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查找所有分组
|
// FindAllEnabledGroups 查找所有分组
|
||||||
func (this *ServerGroupDAO) FindAllEnabledGroups(tx *dbs.Tx) (result []*ServerGroup, err error) {
|
func (this *ServerGroupDAO) FindAllEnabledGroups(tx *dbs.Tx) (result []*ServerGroup, err error) {
|
||||||
_, err = this.Query(tx).
|
_, err = this.Query(tx).
|
||||||
State(ServerGroupStateEnabled).
|
State(ServerGroupStateEnabled).
|
||||||
@@ -107,7 +111,7 @@ func (this *ServerGroupDAO) FindAllEnabledGroups(tx *dbs.Tx) (result []*ServerGr
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 修改分组排序
|
// UpdateGroupOrders 修改分组排序
|
||||||
func (this *ServerGroupDAO) UpdateGroupOrders(tx *dbs.Tx, groupIds []int64) error {
|
func (this *ServerGroupDAO) UpdateGroupOrders(tx *dbs.Tx, groupIds []int64) error {
|
||||||
for index, groupId := range groupIds {
|
for index, groupId := range groupIds {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
@@ -120,3 +124,221 @@ func (this *ServerGroupDAO) UpdateGroupOrders(tx *dbs.Tx, groupIds []int64) erro
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindHTTPReverseProxyRef 根据条件获取HTTP反向代理配置
|
||||||
|
func (this *ServerGroupDAO) FindHTTPReverseProxyRef(tx *dbs.Tx, groupId int64) (*serverconfigs.ReverseProxyRef, error) {
|
||||||
|
reverseProxy, err := this.Query(tx).
|
||||||
|
Pk(groupId).
|
||||||
|
Result("httpReverseProxy").
|
||||||
|
FindStringCol("")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(reverseProxy) == 0 || reverseProxy == "null" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
config := &serverconfigs.ReverseProxyRef{}
|
||||||
|
err = json.Unmarshal([]byte(reverseProxy), config)
|
||||||
|
return config, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindTCPReverseProxyRef 根据条件获取TCP反向代理配置
|
||||||
|
func (this *ServerGroupDAO) FindTCPReverseProxyRef(tx *dbs.Tx, groupId int64) (*serverconfigs.ReverseProxyRef, error) {
|
||||||
|
reverseProxy, err := this.Query(tx).
|
||||||
|
Pk(groupId).
|
||||||
|
Result("tcpReverseProxy").
|
||||||
|
FindStringCol("")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(reverseProxy) == 0 || reverseProxy == "null" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
config := &serverconfigs.ReverseProxyRef{}
|
||||||
|
err = json.Unmarshal([]byte(reverseProxy), config)
|
||||||
|
return config, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindUDPReverseProxyRef 根据条件获取UDP反向代理配置
|
||||||
|
func (this *ServerGroupDAO) FindUDPReverseProxyRef(tx *dbs.Tx, groupId int64) (*serverconfigs.ReverseProxyRef, error) {
|
||||||
|
reverseProxy, err := this.Query(tx).
|
||||||
|
Pk(groupId).
|
||||||
|
Result("udpReverseProxy").
|
||||||
|
FindStringCol("")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(reverseProxy) == 0 || reverseProxy == "null" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
config := &serverconfigs.ReverseProxyRef{}
|
||||||
|
err = json.Unmarshal([]byte(reverseProxy), config)
|
||||||
|
return config, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateHTTPReverseProxy 修改HTTP反向代理配置
|
||||||
|
func (this *ServerGroupDAO) UpdateHTTPReverseProxy(tx *dbs.Tx, groupId int64, config []byte) error {
|
||||||
|
if groupId <= 0 {
|
||||||
|
return errors.New("groupId should not be smaller than 0")
|
||||||
|
}
|
||||||
|
op := NewServerGroupOperator()
|
||||||
|
op.Id = groupId
|
||||||
|
op.HttpReverseProxy = JSONBytes(config)
|
||||||
|
err := this.Save(tx, op)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.NotifyUpdate(tx, groupId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateTCPReverseProxy 修改TCP反向代理配置
|
||||||
|
func (this *ServerGroupDAO) UpdateTCPReverseProxy(tx *dbs.Tx, groupId int64, config []byte) error {
|
||||||
|
if groupId <= 0 {
|
||||||
|
return errors.New("groupId should not be smaller than 0")
|
||||||
|
}
|
||||||
|
op := NewServerGroupOperator()
|
||||||
|
op.Id = groupId
|
||||||
|
op.TcpReverseProxy = JSONBytes(config)
|
||||||
|
err := this.Save(tx, op)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.NotifyUpdate(tx, groupId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateUDPReverseProxy 修改UDP反向代理配置
|
||||||
|
func (this *ServerGroupDAO) UpdateUDPReverseProxy(tx *dbs.Tx, groupId int64, config []byte) error {
|
||||||
|
if groupId <= 0 {
|
||||||
|
return errors.New("groupId should not be smaller than 0")
|
||||||
|
}
|
||||||
|
op := NewServerGroupOperator()
|
||||||
|
op.Id = groupId
|
||||||
|
op.UdpReverseProxy = JSONBytes(config)
|
||||||
|
err := this.Save(tx, op)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.NotifyUpdate(tx, groupId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ComposeGroupConfig 组合配置
|
||||||
|
func (this *ServerGroupDAO) ComposeGroupConfig(tx *dbs.Tx, groupId int64, cacheMap maps.Map) (*serverconfigs.ServerGroupConfig, error) {
|
||||||
|
if cacheMap == nil {
|
||||||
|
cacheMap = maps.Map{}
|
||||||
|
}
|
||||||
|
|
||||||
|
var cacheKey = this.Table + ":config:" + types.String(groupId)
|
||||||
|
var cacheConfig = cacheMap.Get(cacheKey)
|
||||||
|
if cacheConfig != nil {
|
||||||
|
// 克隆,防止分解后的Server配置相互受到影响
|
||||||
|
configJSON, err := json.Marshal(cacheConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var clonedConfig = &serverconfigs.ServerGroupConfig{}
|
||||||
|
err = json.Unmarshal(configJSON, clonedConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return clonedConfig, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
group, err := this.FindEnabledServerGroup(tx, groupId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if group == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var config = &serverconfigs.ServerGroupConfig{
|
||||||
|
Id: int64(group.Id),
|
||||||
|
Name: group.Name,
|
||||||
|
IsOn: group.IsOn == 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(group.HttpReverseProxy) > 0 {
|
||||||
|
reverseProxyRef := &serverconfigs.ReverseProxyRef{}
|
||||||
|
err := json.Unmarshal([]byte(group.HttpReverseProxy), reverseProxyRef)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
config.HTTPReverseProxyRef = reverseProxyRef
|
||||||
|
|
||||||
|
reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, cacheMap)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if reverseProxyConfig != nil {
|
||||||
|
config.HTTPReverseProxy = reverseProxyConfig
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(group.TcpReverseProxy) > 0 {
|
||||||
|
reverseProxyRef := &serverconfigs.ReverseProxyRef{}
|
||||||
|
err := json.Unmarshal([]byte(group.TcpReverseProxy), reverseProxyRef)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
config.TCPReverseProxyRef = reverseProxyRef
|
||||||
|
|
||||||
|
reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, cacheMap)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if reverseProxyConfig != nil {
|
||||||
|
config.TCPReverseProxy = reverseProxyConfig
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(group.UdpReverseProxy) > 0 {
|
||||||
|
reverseProxyRef := &serverconfigs.ReverseProxyRef{}
|
||||||
|
err := json.Unmarshal([]byte(group.UdpReverseProxy), reverseProxyRef)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
config.UDPReverseProxyRef = reverseProxyRef
|
||||||
|
|
||||||
|
reverseProxyConfig, err := SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, cacheMap)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if reverseProxyConfig != nil {
|
||||||
|
config.UDPReverseProxy = reverseProxyConfig
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cacheMap[cacheKey] = config
|
||||||
|
|
||||||
|
return config, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindEnabledGroupIdWithReverseProxyId 查找包含某个反向代理的服务分组
|
||||||
|
func (this *ServerGroupDAO) FindEnabledGroupIdWithReverseProxyId(tx *dbs.Tx, reverseProxyId int64) (serverId int64, err error) {
|
||||||
|
return this.Query(tx).
|
||||||
|
State(ServerStateEnabled).
|
||||||
|
Where("(JSON_CONTAINS(httpReverseProxy, :jsonQuery) OR JSON_CONTAINS(tcpReverseProxy, :jsonQuery) OR JSON_CONTAINS(udpReverseProxy, :jsonQuery))").
|
||||||
|
Param("jsonQuery", maps.Map{"reverseProxyId": reverseProxyId}.AsJSON()).
|
||||||
|
ResultPk().
|
||||||
|
FindInt64Col(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// NotifyUpdate 通知更新
|
||||||
|
func (this *ServerGroupDAO) NotifyUpdate(tx *dbs.Tx, groupId int64) error {
|
||||||
|
serverIds, err := SharedServerDAO.FindAllEnabledServerIdsWithGroupId(tx, groupId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, serverId := range serverIds {
|
||||||
|
err = SharedServerDAO.NotifyUpdate(tx, serverId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,24 +1,34 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
// 服务分组
|
// ServerGroup 服务分组
|
||||||
type ServerGroup struct {
|
type ServerGroup struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id uint32 `field:"id"` // ID
|
||||||
AdminId uint32 `field:"adminId"` // 管理员ID
|
AdminId uint32 `field:"adminId"` // 管理员ID
|
||||||
UserId uint32 `field:"userId"` // 用户ID
|
UserId uint32 `field:"userId"` // 用户ID
|
||||||
Name string `field:"name"` // 名称
|
IsOn uint8 `field:"isOn"` // 是否启用
|
||||||
Order uint32 `field:"order"` // 排序
|
Name string `field:"name"` // 名称
|
||||||
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
Order uint32 `field:"order"` // 排序
|
||||||
State uint8 `field:"state"` // 状态
|
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
||||||
|
State uint8 `field:"state"` // 状态
|
||||||
|
HttpReverseProxy string `field:"httpReverseProxy"` // 反向代理设置
|
||||||
|
TcpReverseProxy string `field:"tcpReverseProxy"` // TCP反向代理
|
||||||
|
UdpReverseProxy string `field:"udpReverseProxy"` // UDP反向代理
|
||||||
|
WebId uint32 `field:"webId"` // Web配置ID
|
||||||
}
|
}
|
||||||
|
|
||||||
type ServerGroupOperator struct {
|
type ServerGroupOperator struct {
|
||||||
Id interface{} // ID
|
Id interface{} // ID
|
||||||
AdminId interface{} // 管理员ID
|
AdminId interface{} // 管理员ID
|
||||||
UserId interface{} // 用户ID
|
UserId interface{} // 用户ID
|
||||||
Name interface{} // 名称
|
IsOn interface{} // 是否启用
|
||||||
Order interface{} // 排序
|
Name interface{} // 名称
|
||||||
CreatedAt interface{} // 创建时间
|
Order interface{} // 排序
|
||||||
State interface{} // 状态
|
CreatedAt interface{} // 创建时间
|
||||||
|
State interface{} // 状态
|
||||||
|
HttpReverseProxy interface{} // 反向代理设置
|
||||||
|
TcpReverseProxy interface{} // TCP反向代理
|
||||||
|
UdpReverseProxy interface{} // UDP反向代理
|
||||||
|
WebId interface{} // Web配置ID
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServerGroupOperator() *ServerGroupOperator {
|
func NewServerGroupOperator() *ServerGroupOperator {
|
||||||
|
|||||||
@@ -1 +1,21 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DecodeGroupIds 解析服务所属分组ID
|
||||||
|
func (this *Server) DecodeGroupIds() []int64 {
|
||||||
|
if len(this.GroupIds) == 0 {
|
||||||
|
return []int64{}
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = []int64{}
|
||||||
|
err := json.Unmarshal([]byte(this.GroupIds), &result)
|
||||||
|
if err != nil {
|
||||||
|
remotelogs.Error("Server.DecodeGroupIds", err.Error())
|
||||||
|
// 忽略错误
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,7 +8,11 @@ import (
|
|||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
"github.com/iwind/TeaGo/maps"
|
"github.com/iwind/TeaGo/maps"
|
||||||
"github.com/iwind/TeaGo/rands"
|
"github.com/iwind/TeaGo/rands"
|
||||||
|
"github.com/iwind/TeaGo/types"
|
||||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -48,12 +52,40 @@ func init() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PartitionTable 获取分区表格名称
|
||||||
|
func (this *ServerDomainHourlyStatDAO) PartitionTable(domain string) string {
|
||||||
|
if len(domain) == 0 {
|
||||||
|
return this.Table + "_0"
|
||||||
|
}
|
||||||
|
if (domain[0] >= '0' && domain[0] <= '9') || (domain[0] >= 'a' && domain[0] <= 'z') || (domain[0] >= 'A' && domain[0] <= 'Z') {
|
||||||
|
return this.Table + "_" + strings.ToLower(string(domain[0]))
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.Table + "_0"
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindAllPartitionTables 获取所有表格名称
|
||||||
|
func (this *ServerDomainHourlyStatDAO) FindAllPartitionTables() []string {
|
||||||
|
var tables = []string{}
|
||||||
|
for i := '0'; i <= '9'; i++ {
|
||||||
|
tables = append(tables, this.Table+"_"+string(i))
|
||||||
|
}
|
||||||
|
for i := 'a'; i <= 'z'; i++ {
|
||||||
|
tables = append(tables, this.Table+"_"+string(i))
|
||||||
|
}
|
||||||
|
return tables
|
||||||
|
}
|
||||||
|
|
||||||
// IncreaseHourlyStat 增加统计数据
|
// IncreaseHourlyStat 增加统计数据
|
||||||
func (this *ServerDomainHourlyStatDAO) IncreaseHourlyStat(tx *dbs.Tx, clusterId int64, nodeId int64, serverId int64, domain string, hour string, bytes int64, cachedBytes int64, countRequests int64, countCachedRequests int64, countAttackRequests int64, attackBytes int64) error {
|
func (this *ServerDomainHourlyStatDAO) IncreaseHourlyStat(tx *dbs.Tx, clusterId int64, nodeId int64, serverId int64, domain string, hour string, bytes int64, cachedBytes int64, countRequests int64, countCachedRequests int64, countAttackRequests int64, attackBytes int64) error {
|
||||||
if len(hour) != 10 {
|
if len(hour) != 10 {
|
||||||
return errors.New("invalid hour '" + hour + "'")
|
return errors.New("invalid hour '" + hour + "'")
|
||||||
}
|
}
|
||||||
|
if len(domain) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
err := this.Query(tx).
|
err := this.Query(tx).
|
||||||
|
Table(this.PartitionTable(domain)).
|
||||||
Param("bytes", bytes).
|
Param("bytes", bytes).
|
||||||
Param("cachedBytes", cachedBytes).
|
Param("cachedBytes", cachedBytes).
|
||||||
Param("countRequests", countRequests).
|
Param("countRequests", countRequests).
|
||||||
@@ -87,69 +119,212 @@ func (this *ServerDomainHourlyStatDAO) IncreaseHourlyStat(tx *dbs.Tx, clusterId
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FindTopDomainStats 取得一定时间内的域名排行数据
|
// FindTopDomainStats 取得一定时间内的域名排行数据
|
||||||
func (this *ServerDomainHourlyStatDAO) FindTopDomainStats(tx *dbs.Tx, hourFrom string, hourTo string, size int64) (result []*ServerDomainHourlyStat, err error) {
|
func (this *ServerDomainHourlyStatDAO) FindTopDomainStats(tx *dbs.Tx, hourFrom string, hourTo string, size int64) (result []*ServerDomainHourlyStat, resultErr error) {
|
||||||
// TODO 节点如果已经被删除,则忽略
|
var tables = this.FindAllPartitionTables()
|
||||||
_, err = this.Query(tx).
|
var wg = sync.WaitGroup{}
|
||||||
Between("hour", hourFrom, hourTo).
|
wg.Add(len(tables))
|
||||||
Result("domain, MIN(serverId) AS serverId, SUM(bytes) AS bytes, SUM(cachedBytes) AS cachedBytes, SUM(countRequests) AS countRequests, SUM(countCachedRequests) AS countCachedRequests, SUM(countAttackRequests) AS countAttackRequests, SUM(attackBytes) AS attackBytes").
|
var locker = sync.Mutex{}
|
||||||
Group("domain").
|
|
||||||
Desc("countRequests").
|
for _, table := range tables {
|
||||||
Limit(size).
|
go func(table string) {
|
||||||
Slice(&result).
|
defer wg.Done()
|
||||||
FindAll()
|
|
||||||
|
var topResults = []*ServerDomainHourlyStat{}
|
||||||
|
|
||||||
|
// TODO 节点如果已经被删除,则忽略
|
||||||
|
_, err := this.Query(tx).
|
||||||
|
Table(table).
|
||||||
|
Between("hour", hourFrom, hourTo).
|
||||||
|
Result("domain, MIN(serverId) AS serverId, SUM(bytes) AS bytes, SUM(cachedBytes) AS cachedBytes, SUM(countRequests) AS countRequests, SUM(countCachedRequests) AS countCachedRequests, SUM(countAttackRequests) AS countAttackRequests, SUM(attackBytes) AS attackBytes").
|
||||||
|
Group("domain").
|
||||||
|
Desc("countRequests").
|
||||||
|
Limit(size).
|
||||||
|
Slice(&topResults).
|
||||||
|
FindAll()
|
||||||
|
if err != nil {
|
||||||
|
resultErr = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(topResults) > 0 {
|
||||||
|
locker.Lock()
|
||||||
|
result = append(result, topResults...)
|
||||||
|
locker.Unlock()
|
||||||
|
}
|
||||||
|
}(table)
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
sort.Slice(result, func(i, j int) bool {
|
||||||
|
return result[i].CountRequests > result[j].CountRequests
|
||||||
|
})
|
||||||
|
|
||||||
|
if len(result) > types.Int(size) {
|
||||||
|
result = result[:types.Int(size)]
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindTopDomainStatsWithClusterId 取得集群上的一定时间内的域名排行数据
|
// FindTopDomainStatsWithClusterId 取得集群上的一定时间内的域名排行数据
|
||||||
func (this *ServerDomainHourlyStatDAO) FindTopDomainStatsWithClusterId(tx *dbs.Tx, clusterId int64, hourFrom string, hourTo string, size int64) (result []*ServerDomainHourlyStat, err error) {
|
func (this *ServerDomainHourlyStatDAO) FindTopDomainStatsWithClusterId(tx *dbs.Tx, clusterId int64, hourFrom string, hourTo string, size int64) (result []*ServerDomainHourlyStat, resultErr error) {
|
||||||
// TODO 节点如果已经被删除,则忽略
|
var tables = this.FindAllPartitionTables()
|
||||||
_, err = this.Query(tx).
|
var wg = sync.WaitGroup{}
|
||||||
Attr("clusterId", clusterId).
|
wg.Add(len(tables))
|
||||||
Between("hour", hourFrom, hourTo).
|
var locker = sync.Mutex{}
|
||||||
Result("domain, MIN(serverId) AS serverId, SUM(bytes) AS bytes, SUM(cachedBytes) AS cachedBytes, SUM(countRequests) AS countRequests, SUM(countCachedRequests) AS countCachedRequests, SUM(countAttackRequests) AS countAttackRequests, SUM(attackBytes) AS attackBytes").
|
|
||||||
Group("domain").
|
for _, table := range tables {
|
||||||
Desc("countRequests").
|
go func(table string) {
|
||||||
Limit(size).
|
defer wg.Done()
|
||||||
Slice(&result).
|
|
||||||
FindAll()
|
var topResults = []*ServerDomainHourlyStat{}
|
||||||
|
|
||||||
|
// TODO 节点如果已经被删除,则忽略
|
||||||
|
_, err := this.Query(tx).
|
||||||
|
Table(table).
|
||||||
|
Attr("clusterId", clusterId).
|
||||||
|
Between("hour", hourFrom, hourTo).
|
||||||
|
UseIndex("hour").
|
||||||
|
Result("domain, MIN(serverId) AS serverId, SUM(bytes) AS bytes, SUM(cachedBytes) AS cachedBytes, SUM(countRequests) AS countRequests, SUM(countCachedRequests) AS countCachedRequests, SUM(countAttackRequests) AS countAttackRequests, SUM(attackBytes) AS attackBytes").
|
||||||
|
Group("domain").
|
||||||
|
Desc("countRequests").
|
||||||
|
Limit(size).
|
||||||
|
Slice(&topResults).
|
||||||
|
FindAll()
|
||||||
|
if err != nil {
|
||||||
|
resultErr = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(topResults) > 0 {
|
||||||
|
locker.Lock()
|
||||||
|
result = append(result, topResults...)
|
||||||
|
locker.Unlock()
|
||||||
|
}
|
||||||
|
}(table)
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
sort.Slice(result, func(i, j int) bool {
|
||||||
|
return result[i].CountRequests > result[j].CountRequests
|
||||||
|
})
|
||||||
|
|
||||||
|
if len(result) > types.Int(size) {
|
||||||
|
result = result[:types.Int(size)]
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindTopDomainStatsWithNodeId 取得节点上的一定时间内的域名排行数据
|
// FindTopDomainStatsWithNodeId 取得节点上的一定时间内的域名排行数据
|
||||||
func (this *ServerDomainHourlyStatDAO) FindTopDomainStatsWithNodeId(tx *dbs.Tx, nodeId int64, hourFrom string, hourTo string, size int64) (result []*ServerDomainHourlyStat, err error) {
|
func (this *ServerDomainHourlyStatDAO) FindTopDomainStatsWithNodeId(tx *dbs.Tx, nodeId int64, hourFrom string, hourTo string, size int64) (result []*ServerDomainHourlyStat, resultErr error) {
|
||||||
// TODO 节点如果已经被删除,则忽略
|
var tables = this.FindAllPartitionTables()
|
||||||
_, err = this.Query(tx).
|
var wg = sync.WaitGroup{}
|
||||||
Attr("nodeId", nodeId).
|
wg.Add(len(tables))
|
||||||
Between("hour", hourFrom, hourTo).
|
var locker = sync.Mutex{}
|
||||||
Result("domain, MIN(serverId) AS serverId, SUM(bytes) AS bytes, SUM(cachedBytes) AS cachedBytes, SUM(countRequests) AS countRequests, SUM(countCachedRequests) AS countCachedRequests, SUM(countAttackRequests) AS countAttackRequests, SUM(attackBytes) AS attackBytes").
|
|
||||||
Group("domain").
|
for _, table := range tables {
|
||||||
Desc("countRequests").
|
go func(table string) {
|
||||||
Limit(size).
|
defer wg.Done()
|
||||||
Slice(&result).
|
|
||||||
FindAll()
|
var topResults = []*ServerDomainHourlyStat{}
|
||||||
|
|
||||||
|
// TODO 节点如果已经被删除,则忽略
|
||||||
|
_, err := this.Query(tx).
|
||||||
|
Table(table).
|
||||||
|
Attr("nodeId", nodeId).
|
||||||
|
Between("hour", hourFrom, hourTo).
|
||||||
|
UseIndex("hour").
|
||||||
|
Result("domain, MIN(serverId) AS serverId, SUM(bytes) AS bytes, SUM(cachedBytes) AS cachedBytes, SUM(countRequests) AS countRequests, SUM(countCachedRequests) AS countCachedRequests, SUM(countAttackRequests) AS countAttackRequests, SUM(attackBytes) AS attackBytes").
|
||||||
|
Group("domain").
|
||||||
|
Desc("countRequests").
|
||||||
|
Limit(size).
|
||||||
|
Slice(&topResults).
|
||||||
|
FindAll()
|
||||||
|
if err != nil {
|
||||||
|
resultErr = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(topResults) > 0 {
|
||||||
|
locker.Lock()
|
||||||
|
result = append(result, topResults...)
|
||||||
|
locker.Unlock()
|
||||||
|
}
|
||||||
|
}(table)
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
sort.Slice(result, func(i, j int) bool {
|
||||||
|
return result[i].CountRequests > result[j].CountRequests
|
||||||
|
})
|
||||||
|
|
||||||
|
if len(result) > types.Int(size) {
|
||||||
|
result = result[:types.Int(size)]
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindTopDomainStatsWithServerId 取得某个服务的一定时间内的域名排行数据
|
// FindTopDomainStatsWithServerId 取得某个服务的一定时间内的域名排行数据
|
||||||
func (this *ServerDomainHourlyStatDAO) FindTopDomainStatsWithServerId(tx *dbs.Tx, serverId int64, hourFrom string, hourTo string, size int64) (result []*ServerDomainHourlyStat, err error) {
|
func (this *ServerDomainHourlyStatDAO) FindTopDomainStatsWithServerId(tx *dbs.Tx, serverId int64, hourFrom string, hourTo string, size int64) (result []*ServerDomainHourlyStat, resultErr error) {
|
||||||
// TODO 节点如果已经被删除,则忽略
|
var tables = this.FindAllPartitionTables()
|
||||||
_, err = this.Query(tx).
|
var wg = sync.WaitGroup{}
|
||||||
Attr("serverId", serverId).
|
wg.Add(len(tables))
|
||||||
Between("hour", hourFrom, hourTo).
|
var locker = sync.Mutex{}
|
||||||
Result("domain, MIN(serverId) AS serverId, SUM(bytes) AS bytes, SUM(cachedBytes) AS cachedBytes, SUM(countRequests) AS countRequests, SUM(countCachedRequests) AS countCachedRequests, SUM(countAttackRequests) AS countAttackRequests, SUM(attackBytes) AS attackBytes").
|
|
||||||
Group("domain").
|
for _, table := range tables {
|
||||||
Desc("countRequests").
|
go func(table string) {
|
||||||
Limit(size).
|
defer wg.Done()
|
||||||
Slice(&result).
|
|
||||||
FindAll()
|
var topResults = []*ServerDomainHourlyStat{}
|
||||||
|
|
||||||
|
// TODO 节点如果已经被删除,则忽略
|
||||||
|
_, err := this.Query(tx).
|
||||||
|
Table(table).
|
||||||
|
Attr("serverId", serverId).
|
||||||
|
Between("hour", hourFrom, hourTo).
|
||||||
|
UseIndex("hour").
|
||||||
|
Result("domain, MIN(serverId) AS serverId, SUM(bytes) AS bytes, SUM(cachedBytes) AS cachedBytes, SUM(countRequests) AS countRequests, SUM(countCachedRequests) AS countCachedRequests, SUM(countAttackRequests) AS countAttackRequests, SUM(attackBytes) AS attackBytes").
|
||||||
|
Group("domain").
|
||||||
|
Desc("countRequests").
|
||||||
|
Limit(size).
|
||||||
|
Slice(&topResults).
|
||||||
|
FindAll()
|
||||||
|
if err != nil {
|
||||||
|
resultErr = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(topResults) > 0 {
|
||||||
|
locker.Lock()
|
||||||
|
result = append(result, topResults...)
|
||||||
|
locker.Unlock()
|
||||||
|
}
|
||||||
|
}(table)
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
sort.Slice(result, func(i, j int) bool {
|
||||||
|
return result[i].CountRequests > result[j].CountRequests
|
||||||
|
})
|
||||||
|
|
||||||
|
if len(result) > types.Int(size) {
|
||||||
|
result = result[:types.Int(size)]
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean 清理历史数据
|
// Clean 清理历史数据
|
||||||
func (this *ServerDomainHourlyStatDAO) Clean(tx *dbs.Tx, days int) error {
|
func (this *ServerDomainHourlyStatDAO) Clean(tx *dbs.Tx, days int) error {
|
||||||
var hour = timeutil.Format("Ymd00", time.Now().AddDate(0, 0, -days))
|
var hour = timeutil.Format("Ymd00", time.Now().AddDate(0, 0, -days))
|
||||||
_, err := this.Query(tx).
|
for _, table := range this.FindAllPartitionTables() {
|
||||||
Lt("hour", hour).
|
_, err := this.Query(tx).
|
||||||
Delete()
|
Table(table).
|
||||||
return err
|
Lt("hour", hour).
|
||||||
|
Delete()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,77 @@
|
|||||||
package stats
|
package stats
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
|
"github.com/iwind/TeaGo/assert"
|
||||||
_ "github.com/iwind/TeaGo/bootstrap"
|
_ "github.com/iwind/TeaGo/bootstrap"
|
||||||
|
"github.com/iwind/TeaGo/dbs"
|
||||||
|
"github.com/iwind/TeaGo/rands"
|
||||||
|
"github.com/iwind/TeaGo/types"
|
||||||
|
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestServerDomainHourlyStatDAO_PartitionTable(t *testing.T) {
|
||||||
|
var a = assert.NewAssertion(t)
|
||||||
|
|
||||||
|
var dao = NewServerDomainHourlyStatDAO()
|
||||||
|
a.IsTrue(dao.PartitionTable("") == "edgeServerDomainHourlyStats_0")
|
||||||
|
a.IsTrue(dao.PartitionTable("a1") == "edgeServerDomainHourlyStats_a")
|
||||||
|
a.IsTrue(dao.PartitionTable("Y1") == "edgeServerDomainHourlyStats_y")
|
||||||
|
a.IsTrue(dao.PartitionTable("z1") == "edgeServerDomainHourlyStats_z")
|
||||||
|
a.IsTrue(dao.PartitionTable("A1") == "edgeServerDomainHourlyStats_a")
|
||||||
|
a.IsTrue(dao.PartitionTable("Z1") == "edgeServerDomainHourlyStats_z")
|
||||||
|
a.IsTrue(dao.PartitionTable("中国") == "edgeServerDomainHourlyStats_0")
|
||||||
|
a.IsTrue(dao.PartitionTable("_") == "edgeServerDomainHourlyStats_0")
|
||||||
|
a.IsTrue(dao.PartitionTable(" ") == "edgeServerDomainHourlyStats_0")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestServerDomainHourlyStatDAO_FindAllPartitionTables(t *testing.T) {
|
||||||
|
var dao = NewServerDomainHourlyStatDAO()
|
||||||
|
t.Log(dao.FindAllPartitionTables())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestServerDomainHourlyStatDAO_IncreaseHourlyStat(t *testing.T) {
|
||||||
|
dbs.NotifyReady()
|
||||||
|
|
||||||
|
for i := 0; i < 1_000_000; i++ {
|
||||||
|
var f = string([]rune{int32(rands.Int('0', '9'))})
|
||||||
|
if i % 30 > 0 {
|
||||||
|
f = string([]rune{int32(rands.Int('a', 'z'))})
|
||||||
|
}
|
||||||
|
|
||||||
|
err := NewServerDomainHourlyStatDAO().IncreaseHourlyStat(nil, 18, 48, 23, f+"rand"+types.String(i%500_000)+".com", timeutil.Format("Ymd")+fmt.Sprintf("%02d", rands.Int(0, 23)), 1, 1, 1, 1, 1, 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if i%10000 == 0 {
|
||||||
|
t.Log(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestServerDomainHourlyStatDAO_FindTopDomainStats(t *testing.T) {
|
||||||
|
var dao = NewServerDomainHourlyStatDAO()
|
||||||
|
var before = time.Now()
|
||||||
|
defer func() {
|
||||||
|
t.Log(time.Since(before).Seconds()*1000, "ms")
|
||||||
|
}()
|
||||||
|
stats, err := dao.FindTopDomainStats(nil, timeutil.Format("Ymd00"), timeutil.Format("Ymd23"), 10)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
for _, stat := range stats {
|
||||||
|
t.Log(stat.Domain, stat.CountRequests)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestServerDomainHourlyStatDAO_Clean(t *testing.T) {
|
||||||
|
var dao = NewServerDomainHourlyStatDAO()
|
||||||
|
err := dao.Clean(nil, 10)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log("ok")
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ func TestTrafficHourlyStatDAO_IncreaseDayBytes(t *testing.T) {
|
|||||||
dbs.NotifyReady()
|
dbs.NotifyReady()
|
||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
err := SharedTrafficHourlyStatDAO.IncreaseHourlyBytes(nil, timeutil.Format("YmdH"), 1)
|
err := SharedTrafficHourlyStatDAO.IncreaseHourlyStat(nil, timeutil.Format("YmdH"), 1, 1, 1, 1, 1, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ func init() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置配置
|
// UpdateSetting 设置配置
|
||||||
func (this *SysSettingDAO) UpdateSetting(tx *dbs.Tx, codeFormat string, valueJSON []byte, codeFormatArgs ...interface{}) error {
|
func (this *SysSettingDAO) UpdateSetting(tx *dbs.Tx, codeFormat string, valueJSON []byte, codeFormatArgs ...interface{}) error {
|
||||||
if len(codeFormatArgs) > 0 {
|
if len(codeFormatArgs) > 0 {
|
||||||
codeFormat = fmt.Sprintf(codeFormat, codeFormatArgs...)
|
codeFormat = fmt.Sprintf(codeFormat, codeFormatArgs...)
|
||||||
@@ -77,7 +77,7 @@ func (this *SysSettingDAO) UpdateSetting(tx *dbs.Tx, codeFormat string, valueJSO
|
|||||||
return lastErr
|
return lastErr
|
||||||
}
|
}
|
||||||
|
|
||||||
// 读取配置
|
// ReadSetting 读取配置
|
||||||
func (this *SysSettingDAO) ReadSetting(tx *dbs.Tx, code string, codeFormatArgs ...interface{}) (valueJSON []byte, err error) {
|
func (this *SysSettingDAO) ReadSetting(tx *dbs.Tx, code string, codeFormatArgs ...interface{}) (valueJSON []byte, err error) {
|
||||||
if len(codeFormatArgs) > 0 {
|
if len(codeFormatArgs) > 0 {
|
||||||
code = fmt.Sprintf(code, codeFormatArgs...)
|
code = fmt.Sprintf(code, codeFormatArgs...)
|
||||||
@@ -89,7 +89,7 @@ func (this *SysSettingDAO) ReadSetting(tx *dbs.Tx, code string, codeFormatArgs .
|
|||||||
return []byte(col), err
|
return []byte(col), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 对比配置中的数字大小
|
// CompareInt64Setting 对比配置中的数字大小
|
||||||
func (this *SysSettingDAO) CompareInt64Setting(tx *dbs.Tx, code string, anotherValue int64) (int8, error) {
|
func (this *SysSettingDAO) CompareInt64Setting(tx *dbs.Tx, code string, anotherValue int64) (int8, error) {
|
||||||
valueJSON, err := this.ReadSetting(tx, code)
|
valueJSON, err := this.ReadSetting(tx, code)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -105,7 +105,7 @@ func (this *SysSettingDAO) CompareInt64Setting(tx *dbs.Tx, code string, anotherV
|
|||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 读取全局配置
|
// ReadGlobalConfig 读取全局配置
|
||||||
func (this *SysSettingDAO) ReadGlobalConfig(tx *dbs.Tx) (*serverconfigs.GlobalConfig, error) {
|
func (this *SysSettingDAO) ReadGlobalConfig(tx *dbs.Tx) (*serverconfigs.GlobalConfig, error) {
|
||||||
globalConfigData, err := this.ReadSetting(tx, systemconfigs.SettingCodeServerGlobalConfig)
|
globalConfigData, err := this.ReadSetting(tx, systemconfigs.SettingCodeServerGlobalConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -15,4 +15,5 @@ type Record struct {
|
|||||||
Type RecordType `json:"type"`
|
Type RecordType `json:"type"`
|
||||||
Value string `json:"value"`
|
Value string `json:"value"`
|
||||||
Route string `json:"route"`
|
Route string `json:"route"`
|
||||||
|
TTL int32 `json:"ttl"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
|
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
|
||||||
"github.com/aliyun/alibaba-cloud-sdk-go/services/alidns"
|
"github.com/aliyun/alibaba-cloud-sdk-go/services/alidns"
|
||||||
"github.com/iwind/TeaGo/maps"
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
"github.com/iwind/TeaGo/types"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -87,6 +88,7 @@ func (this *AliDNSProvider) GetRecords(domain string) (records []*dnstypes.Recor
|
|||||||
Type: record.Type,
|
Type: record.Type,
|
||||||
Value: record.Value,
|
Value: record.Value,
|
||||||
Route: record.Line,
|
Route: record.Line,
|
||||||
|
TTL: types.Int32(record.TTL),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,6 +143,10 @@ func (this *AliDNSProvider) AddRecord(domain string, newRecord *dnstypes.Record)
|
|||||||
req.DomainName = domain
|
req.DomainName = domain
|
||||||
req.Line = newRecord.Route
|
req.Line = newRecord.Route
|
||||||
|
|
||||||
|
if newRecord.TTL > 0 {
|
||||||
|
req.TTL = requests.NewInteger(types.Int(newRecord.TTL))
|
||||||
|
}
|
||||||
|
|
||||||
resp := alidns.CreateAddDomainRecordResponse()
|
resp := alidns.CreateAddDomainRecordResponse()
|
||||||
err := this.doAPI(req, resp)
|
err := this.doAPI(req, resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -162,6 +168,10 @@ func (this *AliDNSProvider) UpdateRecord(domain string, record *dnstypes.Record,
|
|||||||
req.Value = newRecord.Value
|
req.Value = newRecord.Value
|
||||||
req.Line = newRecord.Route
|
req.Line = newRecord.Route
|
||||||
|
|
||||||
|
if newRecord.TTL > 0 {
|
||||||
|
req.TTL = requests.NewInteger(types.Int(newRecord.TTL))
|
||||||
|
}
|
||||||
|
|
||||||
resp := alidns.CreateUpdateDomainRecordResponse()
|
resp := alidns.CreateUpdateDomainRecordResponse()
|
||||||
err := this.doAPI(req, resp)
|
err := this.doAPI(req, resp)
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients/dnstypes"
|
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients/dnstypes"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||||
"github.com/iwind/TeaGo/maps"
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
"github.com/iwind/TeaGo/types"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -158,6 +159,7 @@ func (this *CloudFlareProvider) QueryRecord(domain string, name string, recordTy
|
|||||||
Name: record.Name,
|
Name: record.Name,
|
||||||
Type: record.Type,
|
Type: record.Type,
|
||||||
Value: record.Content,
|
Value: record.Content,
|
||||||
|
TTL: types.Int32(record.Ttl),
|
||||||
Route: CloudFlareDefaultRoute,
|
Route: CloudFlareDefaultRoute,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@@ -170,11 +172,17 @@ func (this *CloudFlareProvider) AddRecord(domain string, newRecord *dnstypes.Rec
|
|||||||
}
|
}
|
||||||
|
|
||||||
resp := new(cloudflare.CreateDNSRecordResponse)
|
resp := new(cloudflare.CreateDNSRecordResponse)
|
||||||
|
|
||||||
|
var ttl = newRecord.TTL
|
||||||
|
if ttl <= 0 {
|
||||||
|
ttl = 1 // 自动默认
|
||||||
|
}
|
||||||
|
|
||||||
err = this.doAPI(http.MethodPost, "zones/"+zoneId+"/dns_records", nil, maps.Map{
|
err = this.doAPI(http.MethodPost, "zones/"+zoneId+"/dns_records", nil, maps.Map{
|
||||||
"type": newRecord.Type,
|
"type": newRecord.Type,
|
||||||
"name": newRecord.Name + "." + domain,
|
"name": newRecord.Name + "." + domain,
|
||||||
"content": newRecord.Value,
|
"content": newRecord.Value,
|
||||||
"ttl": 1,
|
"ttl": ttl,
|
||||||
}, resp)
|
}, resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -189,12 +197,17 @@ func (this *CloudFlareProvider) UpdateRecord(domain string, record *dnstypes.Rec
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ttl = newRecord.TTL
|
||||||
|
if ttl <= 0 {
|
||||||
|
ttl = 1 // 自动默认
|
||||||
|
}
|
||||||
|
|
||||||
resp := new(cloudflare.UpdateDNSRecordResponse)
|
resp := new(cloudflare.UpdateDNSRecordResponse)
|
||||||
return this.doAPI(http.MethodPut, "zones/"+zoneId+"/dns_records/"+record.Id, nil, maps.Map{
|
return this.doAPI(http.MethodPut, "zones/"+zoneId+"/dns_records/"+record.Id, nil, maps.Map{
|
||||||
"type": newRecord.Type,
|
"type": newRecord.Type,
|
||||||
"name": newRecord.Name + "." + domain,
|
"name": newRecord.Name + "." + domain,
|
||||||
"content": newRecord.Value,
|
"content": newRecord.Value,
|
||||||
"ttl": 1,
|
"ttl": ttl,
|
||||||
}, resp)
|
}, resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ func TestCloudFlareProvider_AddRecord(t *testing.T) {
|
|||||||
Type: dnstypes.RecordTypeA,
|
Type: dnstypes.RecordTypeA,
|
||||||
Value: "182.92.212.46",
|
Value: "182.92.212.46",
|
||||||
Route: "",
|
Route: "",
|
||||||
|
TTL: 300,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
|||||||
@@ -13,6 +13,10 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
DNSPodMaxTTL int32 = 604800
|
||||||
|
)
|
||||||
|
|
||||||
// DNSPodProvider DNSPod服务商
|
// DNSPodProvider DNSPod服务商
|
||||||
type DNSPodProvider struct {
|
type DNSPodProvider struct {
|
||||||
BaseProvider
|
BaseProvider
|
||||||
@@ -94,6 +98,7 @@ func (this *DNSPodProvider) GetRecords(domain string) (records []*dnstypes.Recor
|
|||||||
Type: recordMap.GetString("type"),
|
Type: recordMap.GetString("type"),
|
||||||
Value: recordMap.GetString("value"),
|
Value: recordMap.GetString("value"),
|
||||||
Route: recordMap.GetString("line"),
|
Route: recordMap.GetString("line"),
|
||||||
|
TTL: recordMap.GetInt32("ttl"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,13 +170,18 @@ func (this *DNSPodProvider) AddRecord(domain string, newRecord *dnstypes.Record)
|
|||||||
if newRecord.Type == dnstypes.RecordTypeCNAME && !strings.HasSuffix(newRecord.Value, ".") {
|
if newRecord.Type == dnstypes.RecordTypeCNAME && !strings.HasSuffix(newRecord.Value, ".") {
|
||||||
newRecord.Value += "."
|
newRecord.Value += "."
|
||||||
}
|
}
|
||||||
_, err := this.post("/Record.Create", map[string]string{
|
|
||||||
|
var args = map[string]string{
|
||||||
"domain": domain,
|
"domain": domain,
|
||||||
"sub_domain": newRecord.Name,
|
"sub_domain": newRecord.Name,
|
||||||
"record_type": newRecord.Type,
|
"record_type": newRecord.Type,
|
||||||
"value": newRecord.Value,
|
"value": newRecord.Value,
|
||||||
"record_line": newRecord.Route,
|
"record_line": newRecord.Route,
|
||||||
})
|
}
|
||||||
|
if newRecord.TTL > 0 && newRecord.TTL <= DNSPodMaxTTL {
|
||||||
|
args["ttl"] = types.String(newRecord.TTL)
|
||||||
|
}
|
||||||
|
_, err := this.post("/Record.Create", args)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,14 +198,19 @@ func (this *DNSPodProvider) UpdateRecord(domain string, record *dnstypes.Record,
|
|||||||
if newRecord.Type == dnstypes.RecordTypeCNAME && !strings.HasSuffix(newRecord.Value, ".") {
|
if newRecord.Type == dnstypes.RecordTypeCNAME && !strings.HasSuffix(newRecord.Value, ".") {
|
||||||
newRecord.Value += "."
|
newRecord.Value += "."
|
||||||
}
|
}
|
||||||
_, err := this.post("/Record.Modify", map[string]string{
|
|
||||||
|
var args = map[string]string{
|
||||||
"domain": domain,
|
"domain": domain,
|
||||||
"record_id": record.Id,
|
"record_id": record.Id,
|
||||||
"sub_domain": newRecord.Name,
|
"sub_domain": newRecord.Name,
|
||||||
"record_type": newRecord.Type,
|
"record_type": newRecord.Type,
|
||||||
"value": newRecord.Value,
|
"value": newRecord.Value,
|
||||||
"record_line": newRecord.Route,
|
"record_line": newRecord.Route,
|
||||||
})
|
}
|
||||||
|
if newRecord.TTL > 0 && newRecord.TTL <= DNSPodMaxTTL {
|
||||||
|
args["ttl"] = types.String(newRecord.TTL)
|
||||||
|
}
|
||||||
|
_, err := this.post("/Record.Modify", args)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ func TestDNSPodProvider_AddRecord(t *testing.T) {
|
|||||||
Name: "hello-forward",
|
Name: "hello-forward",
|
||||||
Value: "hello.yun4s.cn",
|
Value: "hello.yun4s.cn",
|
||||||
Route: "联通",
|
Route: "联通",
|
||||||
|
TTL: 300,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ var huaweiDNSHTTPClient = &http.Client{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HuaweiDNSProvider 华为云DNS
|
||||||
|
// 相关文档链接:https://support.huaweicloud.com/api-dns/dns_api_62001.html
|
||||||
type HuaweiDNSProvider struct {
|
type HuaweiDNSProvider struct {
|
||||||
BaseProvider
|
BaseProvider
|
||||||
|
|
||||||
@@ -100,6 +102,7 @@ func (this *HuaweiDNSProvider) GetRecords(domain string) (records []*dnstypes.Re
|
|||||||
Type: recordSet.Type,
|
Type: recordSet.Type,
|
||||||
Value: value,
|
Value: value,
|
||||||
Route: recordSet.Line,
|
Route: recordSet.Line,
|
||||||
|
TTL: types.Int32(recordSet.Ttl),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1320,6 +1323,7 @@ func (this *HuaweiDNSProvider) QueryRecord(domain string, name string, recordTyp
|
|||||||
Type: recordType,
|
Type: recordType,
|
||||||
Value: recordSet.Records[0],
|
Value: recordSet.Records[0],
|
||||||
Route: recordSet.Line,
|
Route: recordSet.Line,
|
||||||
|
TTL: types.Int32(recordSet.Ttl),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1331,12 +1335,17 @@ func (this *HuaweiDNSProvider) AddRecord(domain string, newRecord *dnstypes.Reco
|
|||||||
}
|
}
|
||||||
|
|
||||||
var resp = new(huaweidns.ZonesCreateRecordSetResponse)
|
var resp = new(huaweidns.ZonesCreateRecordSetResponse)
|
||||||
|
var ttl = newRecord.TTL
|
||||||
|
if ttl <= 0 {
|
||||||
|
ttl = 300
|
||||||
|
}
|
||||||
err = this.doAPI(http.MethodPost, "/v2.1/zones/"+zoneId+"/recordsets", map[string]string{}, maps.Map{
|
err = this.doAPI(http.MethodPost, "/v2.1/zones/"+zoneId+"/recordsets", map[string]string{}, maps.Map{
|
||||||
"name": newRecord.Name + "." + domain + ".",
|
"name": newRecord.Name + "." + domain + ".",
|
||||||
"description": "CDN系统自动创建",
|
"description": "CDN系统自动创建",
|
||||||
"type": newRecord.Type,
|
"type": newRecord.Type,
|
||||||
"records": []string{newRecord.Value},
|
"records": []string{newRecord.Value},
|
||||||
"line": newRecord.Route,
|
"line": newRecord.Route,
|
||||||
|
"ttl": ttl,
|
||||||
}, resp)
|
}, resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -1362,6 +1371,11 @@ func (this *HuaweiDNSProvider) UpdateRecord(domain string, record *dnstypes.Reco
|
|||||||
recordId = record.Id
|
recordId = record.Id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ttl = newRecord.TTL
|
||||||
|
if ttl <= 0 {
|
||||||
|
ttl = 300
|
||||||
|
}
|
||||||
|
|
||||||
var resp = new(huaweidns.ZonesUpdateRecordSetResponse)
|
var resp = new(huaweidns.ZonesUpdateRecordSetResponse)
|
||||||
err = this.doAPI(http.MethodPut, "/v2.1/zones/"+zoneId+"/recordsets/"+recordId, map[string]string{}, maps.Map{
|
err = this.doAPI(http.MethodPut, "/v2.1/zones/"+zoneId+"/recordsets/"+recordId, map[string]string{}, maps.Map{
|
||||||
"name": newRecord.Name + "." + domain + ".",
|
"name": newRecord.Name + "." + domain + ".",
|
||||||
@@ -1369,6 +1383,7 @@ func (this *HuaweiDNSProvider) UpdateRecord(domain string, record *dnstypes.Reco
|
|||||||
"type": newRecord.Type,
|
"type": newRecord.Type,
|
||||||
"records": []string{newRecord.Value},
|
"records": []string{newRecord.Value},
|
||||||
"line": newRecord.Route, // TODO 华为云此API无法修改线路,API地址:https://support.huaweicloud.com/api-dns/dns_api_65006.html
|
"line": newRecord.Route, // TODO 华为云此API无法修改线路,API地址:https://support.huaweicloud.com/api-dns/dns_api_65006.html
|
||||||
|
"ttl": ttl,
|
||||||
}, resp)
|
}, resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ func TestHuaweiDNSProvider_AddRecord(t *testing.T) {
|
|||||||
Type: "A",
|
Type: "A",
|
||||||
Value: "192.168.2.40",
|
Value: "192.168.2.40",
|
||||||
Route: "Beijing",
|
Route: "Beijing",
|
||||||
|
TTL: 120,
|
||||||
}
|
}
|
||||||
err = provider.AddRecord("yun4s.cn", record)
|
err = provider.AddRecord("yun4s.cn", record)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ func (this *LocalEdgeDNSProvider) GetRecords(domain string) (records []*dnstypes
|
|||||||
Type: record.Type,
|
Type: record.Type,
|
||||||
Value: record.Value,
|
Value: record.Value,
|
||||||
Route: routeIds[0],
|
Route: routeIds[0],
|
||||||
|
TTL: types.Int32(record.Ttl),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,6 +184,7 @@ func (this *LocalEdgeDNSProvider) QueryRecord(domain string, name string, record
|
|||||||
Type: record.Type,
|
Type: record.Type,
|
||||||
Value: record.Value,
|
Value: record.Value,
|
||||||
Route: routeIdString,
|
Route: routeIdString,
|
||||||
|
TTL: types.Int32(record.Ttl),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,7 +204,10 @@ func (this *LocalEdgeDNSProvider) AddRecord(domain string, newRecord *dnstypes.R
|
|||||||
routeIds = append(routeIds, newRecord.Route)
|
routeIds = append(routeIds, newRecord.Route)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = nameservers.SharedNSRecordDAO.CreateRecord(tx, domainId, "", newRecord.Name, newRecord.Type, newRecord.Value, this.ttl, routeIds)
|
if newRecord.TTL <= 0 {
|
||||||
|
newRecord.TTL = this.ttl
|
||||||
|
}
|
||||||
|
_, err = nameservers.SharedNSRecordDAO.CreateRecord(tx, domainId, "", newRecord.Name, newRecord.Type, newRecord.Value, newRecord.TTL, routeIds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -226,8 +231,12 @@ func (this *LocalEdgeDNSProvider) UpdateRecord(domain string, record *dnstypes.R
|
|||||||
routeIds = append(routeIds, newRecord.Route)
|
routeIds = append(routeIds, newRecord.Route)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if newRecord.TTL <= 0 {
|
||||||
|
newRecord.TTL = this.ttl
|
||||||
|
}
|
||||||
|
|
||||||
if len(record.Id) > 0 {
|
if len(record.Id) > 0 {
|
||||||
err = nameservers.SharedNSRecordDAO.UpdateRecord(tx, types.Int64(record.Id), "", newRecord.Name, newRecord.Type, newRecord.Value, this.ttl, routeIds, true)
|
err = nameservers.SharedNSRecordDAO.UpdateRecord(tx, types.Int64(record.Id), "", newRecord.Name, newRecord.Type, newRecord.Value, newRecord.TTL, routeIds, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -237,7 +246,7 @@ func (this *LocalEdgeDNSProvider) UpdateRecord(domain string, record *dnstypes.R
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if realRecord != nil {
|
if realRecord != nil {
|
||||||
err = nameservers.SharedNSRecordDAO.UpdateRecord(tx, types.Int64(realRecord.Id), "", newRecord.Name, newRecord.Type, newRecord.Value, this.ttl, routeIds, true)
|
err = nameservers.SharedNSRecordDAO.UpdateRecord(tx, types.Int64(realRecord.Id), "", newRecord.Name, newRecord.Type, newRecord.Value, newRecord.TTL, routeIds, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ func TestLocalEdgeDNSProvider_AddRecord(t *testing.T) {
|
|||||||
Type: dnstypes.RecordTypeA,
|
Type: dnstypes.RecordTypeA,
|
||||||
Value: "10.0.0.1",
|
Value: "10.0.0.1",
|
||||||
Route: "id:7",
|
Route: "id:7",
|
||||||
|
TTL: 300,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
|||||||
@@ -53,6 +53,11 @@ func (this *APINode) registerServices(server *grpc.Server) {
|
|||||||
pb.RegisterNodeIPAddressLogServiceServer(server, instance)
|
pb.RegisterNodeIPAddressLogServiceServer(server, instance)
|
||||||
this.rest(instance)
|
this.rest(instance)
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
instance := this.serviceInstance(&services.NodeIPAddressThresholdService{}).(*services.NodeIPAddressThresholdService)
|
||||||
|
pb.RegisterNodeIPAddressThresholdServiceServer(server, instance)
|
||||||
|
this.rest(instance)
|
||||||
|
}
|
||||||
{
|
{
|
||||||
instance := this.serviceInstance(&services.APINodeService{}).(*services.APINodeService)
|
instance := this.serviceInstance(&services.APINodeService{}).(*services.APINodeService)
|
||||||
pb.RegisterAPINodeServiceServer(server, instance)
|
pb.RegisterAPINodeServiceServer(server, instance)
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ func (this *NSNodeService) NsNodeStream(server pb.NSNodeService_NsNodeStreamServ
|
|||||||
}
|
}
|
||||||
subject := "DNS节点\"" + nodeName + "\"已经恢复在线"
|
subject := "DNS节点\"" + nodeName + "\"已经恢复在线"
|
||||||
msg := "DNS节点\"" + nodeName + "\"已经恢复在线"
|
msg := "DNS节点\"" + nodeName + "\"已经恢复在线"
|
||||||
err = models.SharedMessageDAO.CreateNodeMessage(tx, nodeconfigs.NodeRoleDNS, clusterId, nodeId, models.MessageTypeNSNodeActive, models.MessageLevelSuccess, subject, msg, nil)
|
err = models.SharedMessageDAO.CreateNodeMessage(tx, nodeconfigs.NodeRoleDNS, clusterId, nodeId, models.MessageTypeNSNodeActive, models.MessageLevelSuccess, subject, msg, nil, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -569,7 +569,7 @@ func (this *AdminService) ComposeAdminDashboard(ctx context.Context, req *pb.Com
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 是否是企业版
|
// 是否是商业版
|
||||||
isPlus, err := authority.SharedAuthorityKeyDAO.IsPlus(tx)
|
isPlus, err := authority.SharedAuthorityKeyDAO.IsPlus(tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -657,20 +657,31 @@ func (this *AdminService) ComposeAdminDashboard(ctx context.Context, req *pb.Com
|
|||||||
result.NsNodeUpgradeInfo = upgradeInfo
|
result.NsNodeUpgradeInfo = upgradeInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
// 域名排行
|
// Report节点升级信息
|
||||||
if isPlus {
|
if isPlus {
|
||||||
topDomainStats, err := stats.SharedServerDomainHourlyStatDAO.FindTopDomainStats(tx, hourFrom, hourTo, 10)
|
upgradeInfo := &pb.ComposeAdminDashboardResponse_UpgradeInfo{
|
||||||
|
NewVersion: teaconst.ReportNodeVersion,
|
||||||
|
}
|
||||||
|
countNodes, err := models.SharedReportNodeDAO.CountAllLowerVersionNodes(tx, upgradeInfo.NewVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for _, stat := range topDomainStats {
|
upgradeInfo.CountNodes = countNodes
|
||||||
result.TopDomainStats = append(result.TopDomainStats, &pb.ComposeAdminDashboardResponse_DomainStat{
|
result.ReportNodeUpgradeInfo = upgradeInfo
|
||||||
ServerId: int64(stat.ServerId),
|
}
|
||||||
Domain: stat.Domain,
|
|
||||||
CountRequests: int64(stat.CountRequests),
|
// 域名排行
|
||||||
Bytes: int64(stat.Bytes),
|
topDomainStats, err := stats.SharedServerDomainHourlyStatDAO.FindTopDomainStats(tx, hourFrom, hourTo, 10)
|
||||||
})
|
if err != nil {
|
||||||
}
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, stat := range topDomainStats {
|
||||||
|
result.TopDomainStats = append(result.TopDomainStats, &pb.ComposeAdminDashboardResponse_DomainStat{
|
||||||
|
ServerId: int64(stat.ServerId),
|
||||||
|
Domain: stat.Domain,
|
||||||
|
CountRequests: int64(stat.CountRequests),
|
||||||
|
Bytes: int64(stat.Bytes),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 节点排行
|
// 节点排行
|
||||||
|
|||||||
@@ -402,6 +402,19 @@ func (this *DNSDomainService) findClusterDNSChanges(cluster *models.NodeCluster,
|
|||||||
|
|
||||||
tx := this.NullTx()
|
tx := this.NullTx()
|
||||||
|
|
||||||
|
// 自动设置的cname记录
|
||||||
|
var cnameRecords = []string{}
|
||||||
|
var ttl int32
|
||||||
|
if len(cluster.Dns) > 0 {
|
||||||
|
dnsConfig, _ := cluster.DecodeDNSConfig()
|
||||||
|
if dnsConfig != nil {
|
||||||
|
cnameRecords = dnsConfig.CNameRecords
|
||||||
|
if dnsConfig.TTL > 0 {
|
||||||
|
ttl = dnsConfig.TTL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 节点域名
|
// 节点域名
|
||||||
nodes, err := models.SharedNodeDAO.FindAllEnabledNodesDNSWithClusterId(tx, clusterId, true)
|
nodes, err := models.SharedNodeDAO.FindAllEnabledNodesDNSWithClusterId(tx, clusterId, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -441,7 +454,7 @@ func (this *DNSDomainService) findClusterDNSChanges(cluster *models.NodeCluster,
|
|||||||
}
|
}
|
||||||
for _, route := range routeCodes {
|
for _, route := range routeCodes {
|
||||||
for _, ipAddress := range ipAddresses {
|
for _, ipAddress := range ipAddresses {
|
||||||
ip := ipAddress.Ip
|
ip := ipAddress.DNSIP()
|
||||||
if len(ip) == 0 {
|
if len(ip) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -464,6 +477,7 @@ func (this *DNSDomainService) findClusterDNSChanges(cluster *models.NodeCluster,
|
|||||||
Type: recordType,
|
Type: recordType,
|
||||||
Value: ip,
|
Value: ip,
|
||||||
Route: route,
|
Route: route,
|
||||||
|
TTL: ttl,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
nodesChanged = true
|
nodesChanged = true
|
||||||
@@ -520,6 +534,29 @@ func (this *DNSDomainService) findClusterDNSChanges(cluster *models.NodeCluster,
|
|||||||
Type: dnstypes.RecordTypeCNAME,
|
Type: dnstypes.RecordTypeCNAME,
|
||||||
Value: clusterDomain + ".",
|
Value: clusterDomain + ".",
|
||||||
Route: "", // 注意这里为空,需要在执行过程中获取默认值
|
Route: "", // 注意这里为空,需要在执行过程中获取默认值
|
||||||
|
TTL: ttl,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
doneServerRecords = append(doneServerRecords, record)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 自动设置的CNAME
|
||||||
|
for _, cnameRecord := range cnameRecords {
|
||||||
|
serverDNSNames = append(serverDNSNames, cnameRecord)
|
||||||
|
record, ok := serverRecordsMap[cnameRecord]
|
||||||
|
if !ok {
|
||||||
|
serversChanged = true
|
||||||
|
result = append(result, maps.Map{
|
||||||
|
"action": "create",
|
||||||
|
"record": &dnstypes.Record{
|
||||||
|
Id: "",
|
||||||
|
Name: cnameRecord,
|
||||||
|
Type: dnstypes.RecordTypeCNAME,
|
||||||
|
Value: clusterDomain + ".",
|
||||||
|
Route: "", // 注意这里为空,需要在执行过程中获取默认值
|
||||||
|
TTL: ttl,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ import (
|
|||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DNS同步相关任务
|
// DNSTaskService DNS同步相关任务
|
||||||
type DNSTaskService struct {
|
type DNSTaskService struct {
|
||||||
BaseService
|
BaseService
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查是否有正在执行的任务
|
// ExistsDNSTasks 检查是否有正在执行的任务
|
||||||
func (this *DNSTaskService) ExistsDNSTasks(ctx context.Context, req *pb.ExistsDNSTasksRequest) (*pb.ExistsDNSTasksResponse, error) {
|
func (this *DNSTaskService) ExistsDNSTasks(ctx context.Context, req *pb.ExistsDNSTasksRequest) (*pb.ExistsDNSTasksResponse, error) {
|
||||||
_, err := this.ValidateAdmin(ctx, 0)
|
_, err := this.ValidateAdmin(ctx, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -37,7 +37,7 @@ func (this *DNSTaskService) ExistsDNSTasks(ctx context.Context, req *pb.ExistsDN
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查找正在执行的所有任务
|
// FindAllDoingDNSTasks 查找正在执行的所有任务
|
||||||
func (this *DNSTaskService) FindAllDoingDNSTasks(ctx context.Context, req *pb.FindAllDoingDNSTasksRequest) (*pb.FindAllDoingDNSTasksResponse, error) {
|
func (this *DNSTaskService) FindAllDoingDNSTasks(ctx context.Context, req *pb.FindAllDoingDNSTasksRequest) (*pb.FindAllDoingDNSTasksResponse, error) {
|
||||||
_, err := this.ValidateAdmin(ctx, 0)
|
_, err := this.ValidateAdmin(ctx, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -45,7 +45,7 @@ func (this *DNSTaskService) FindAllDoingDNSTasks(ctx context.Context, req *pb.Fi
|
|||||||
}
|
}
|
||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
tasks, err := dns.SharedDNSTaskDAO.FindAllDoingOrErrorTasks(tx)
|
tasks, err := dns.SharedDNSTaskDAO.FindAllDoingOrErrorTasks(tx, req.NodeClusterId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -104,7 +104,7 @@ func (this *DNSTaskService) FindAllDoingDNSTasks(ctx context.Context, req *pb.Fi
|
|||||||
return &pb.FindAllDoingDNSTasksResponse{DnsTasks: pbTasks}, nil
|
return &pb.FindAllDoingDNSTasksResponse{DnsTasks: pbTasks}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除任务
|
// DeleteDNSTask 删除任务
|
||||||
func (this *DNSTaskService) DeleteDNSTask(ctx context.Context, req *pb.DeleteDNSTaskRequest) (*pb.RPCSuccess, error) {
|
func (this *DNSTaskService) DeleteDNSTask(ctx context.Context, req *pb.DeleteDNSTaskRequest) (*pb.RPCSuccess, error) {
|
||||||
_, err := this.ValidateAdmin(ctx, 0)
|
_, err := this.ValidateAdmin(ctx, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -409,79 +409,11 @@ func (this *NodeService) UpdateNode(ctx context.Context, req *pb.UpdateNodeReque
|
|||||||
|
|
||||||
tx := this.NullTx()
|
tx := this.NullTx()
|
||||||
|
|
||||||
var maxCacheDiskCapacityJSON []byte
|
err = models.SharedNodeDAO.UpdateNode(tx, req.NodeId, req.Name, req.NodeClusterId, req.SecondaryNodeClusterIds, req.NodeGroupId, req.NodeRegionId, req.IsOn)
|
||||||
if req.MaxCacheDiskCapacity != nil {
|
|
||||||
maxCacheDiskCapacityJSON, err = json.Marshal(&shared.SizeCapacity{
|
|
||||||
Count: req.MaxCacheDiskCapacity.Count,
|
|
||||||
Unit: req.MaxCacheDiskCapacity.Unit,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var maxCacheMemoryCapacityJSON []byte
|
|
||||||
if req.MaxCacheMemoryCapacity != nil {
|
|
||||||
maxCacheMemoryCapacityJSON, err = json.Marshal(&shared.SizeCapacity{
|
|
||||||
Count: req.MaxCacheMemoryCapacity.Count,
|
|
||||||
Unit: req.MaxCacheMemoryCapacity.Unit,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = models.SharedNodeDAO.UpdateNode(tx, req.NodeId, req.Name, req.NodeClusterId, req.SecondaryNodeClusterIds, req.NodeGroupId, req.NodeRegionId, req.MaxCPU, req.IsOn, maxCacheDiskCapacityJSON, maxCacheMemoryCapacityJSON)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 登录信息
|
|
||||||
if req.NodeLogin == nil {
|
|
||||||
err = models.SharedNodeLoginDAO.DisableNodeLogins(tx, nodeconfigs.NodeRoleNode, req.NodeId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if req.NodeLogin.Id > 0 {
|
|
||||||
err = models.SharedNodeLoginDAO.UpdateNodeLogin(tx, req.NodeLogin.Id, req.NodeLogin.Name, req.NodeLogin.Type, req.NodeLogin.Params)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_, err = models.SharedNodeLoginDAO.CreateNodeLogin(tx, nodeconfigs.NodeRoleNode, req.NodeId, req.NodeLogin.Name, req.NodeLogin.Type, req.NodeLogin.Params)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 保存DNS相关
|
|
||||||
nodeDNS, err := models.SharedNodeDAO.FindEnabledNodeDNS(tx, req.NodeId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if nodeDNS != nil {
|
|
||||||
var routesMap = nodeDNS.DNSRouteCodes()
|
|
||||||
var m = map[int64][]string{} // domainId => codes
|
|
||||||
for _, route := range req.DnsRoutes {
|
|
||||||
var pieces = strings.SplitN(route, "@", 2)
|
|
||||||
if len(pieces) != 2 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
var code = pieces[0]
|
|
||||||
var domainId = types.Int64(pieces[1])
|
|
||||||
m[domainId] = append(m[domainId], code)
|
|
||||||
}
|
|
||||||
for domainId, codes := range m {
|
|
||||||
routesMap[domainId] = codes
|
|
||||||
}
|
|
||||||
err = models.SharedNodeDAO.UpdateNodeDNS(tx, req.NodeId, routesMap)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.Success()
|
return this.Success()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1262,7 +1194,7 @@ func (this *NodeService) FindAllEnabledNodesDNSWithNodeClusterId(ctx context.Con
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, ipAddress := range ipAddresses {
|
for _, ipAddress := range ipAddresses {
|
||||||
ip := ipAddress.Ip
|
ip := ipAddress.DNSIP()
|
||||||
if len(ip) == 0 {
|
if len(ip) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -1377,22 +1309,43 @@ func (this *NodeService) UpdateNodeDNS(ctx context.Context, req *pb.UpdateNodeDN
|
|||||||
}
|
}
|
||||||
|
|
||||||
routeCodeMap := node.DNSRouteCodes()
|
routeCodeMap := node.DNSRouteCodes()
|
||||||
if req.DnsDomainId > 0 && len(req.Routes) > 0 {
|
if req.DnsDomainId > 0 {
|
||||||
var m = map[int64][]string{} // domainId => codes
|
if len(req.Routes) > 0 {
|
||||||
for _, route := range req.Routes {
|
var m = map[int64][]string{} // domainId => codes
|
||||||
var pieces = strings.SplitN(route, "@", 2)
|
for _, route := range req.Routes {
|
||||||
if len(pieces) != 2 {
|
var pieces = strings.SplitN(route, "@", 2)
|
||||||
continue
|
if len(pieces) != 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var code = pieces[0]
|
||||||
|
var domainId = types.Int64(pieces[1])
|
||||||
|
m[domainId] = append(m[domainId], code)
|
||||||
}
|
}
|
||||||
var code = pieces[0]
|
for domainId, codes := range m {
|
||||||
var domainId = types.Int64(pieces[1])
|
routeCodeMap[domainId] = codes
|
||||||
m[domainId] = append(m[domainId], code)
|
}
|
||||||
}
|
} else {
|
||||||
for domainId, codes := range m {
|
delete(routeCodeMap, req.DnsDomainId)
|
||||||
routeCodeMap[domainId] = codes
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
delete(routeCodeMap, req.DnsDomainId)
|
if len(req.Routes) > 0 {
|
||||||
|
var m = map[int64][]string{} // domainId => codes
|
||||||
|
for _, route := range req.Routes {
|
||||||
|
var pieces = strings.SplitN(route, "@", 2)
|
||||||
|
if len(pieces) != 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var code = pieces[0]
|
||||||
|
var domainId = types.Int64(pieces[1])
|
||||||
|
m[domainId] = append(m[domainId], code)
|
||||||
|
}
|
||||||
|
for domainId, codes := range m {
|
||||||
|
routeCodeMap[domainId] = codes
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 清空
|
||||||
|
routeCodeMap = map[int64][]string{}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = models.SharedNodeDAO.UpdateNodeDNS(tx, req.NodeId, routeCodeMap)
|
err = models.SharedNodeDAO.UpdateNodeDNS(tx, req.NodeId, routeCodeMap)
|
||||||
@@ -1412,7 +1365,7 @@ func (this *NodeService) UpdateNodeDNS(ctx context.Context, req *pb.UpdateNodeDN
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_, err = models.SharedNodeIPAddressDAO.CreateAddress(tx, adminId, req.NodeId, nodeconfigs.NodeRoleNode, "DNS IP", req.IpAddr, true, nil)
|
_, err = models.SharedNodeIPAddressDAO.CreateAddress(tx, adminId, req.NodeId, nodeconfigs.NodeRoleNode, "DNS IP", req.IpAddr, true, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -1532,3 +1485,57 @@ func (this *NodeService) DownloadNodeInstallationFile(ctx context.Context, req *
|
|||||||
Filename: filepath.Base(file.Path),
|
Filename: filepath.Base(file.Path),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateNodeSystem 修改节点系统信息
|
||||||
|
func (this *NodeService) UpdateNodeSystem(ctx context.Context, req *pb.UpdateNodeSystemRequest) (*pb.RPCSuccess, error) {
|
||||||
|
_, err := this.ValidateAdmin(ctx, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
err = models.SharedNodeDAO.UpdateNodeSystem(tx, req.NodeId, req.MaxCPU)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return this.Success()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateNodeCache 修改节点缓存设置
|
||||||
|
func (this *NodeService) UpdateNodeCache(ctx context.Context, req *pb.UpdateNodeCacheRequest) (*pb.RPCSuccess, error) {
|
||||||
|
_, err := this.ValidateAdmin(ctx, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
|
||||||
|
var maxCacheDiskCapacityJSON []byte
|
||||||
|
if req.MaxCacheDiskCapacity != nil {
|
||||||
|
maxCacheDiskCapacityJSON, err = json.Marshal(&shared.SizeCapacity{
|
||||||
|
Count: req.MaxCacheDiskCapacity.Count,
|
||||||
|
Unit: req.MaxCacheDiskCapacity.Unit,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var maxCacheMemoryCapacityJSON []byte
|
||||||
|
if req.MaxCacheMemoryCapacity != nil {
|
||||||
|
maxCacheMemoryCapacityJSON, err = json.Marshal(&shared.SizeCapacity{
|
||||||
|
Count: req.MaxCacheMemoryCapacity.Count,
|
||||||
|
Unit: req.MaxCacheMemoryCapacity.Unit,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = models.SharedNodeDAO.UpdateNodeCache(tx, req.NodeId, maxCacheDiskCapacityJSON, maxCacheMemoryCapacityJSON)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.Success()
|
||||||
|
}
|
||||||
|
|||||||
@@ -446,6 +446,8 @@ func (this *NodeClusterService) FindEnabledNodeClusterDNS(ctx context.Context, r
|
|||||||
Provider: nil,
|
Provider: nil,
|
||||||
NodesAutoSync: dnsConfig.NodesAutoSync,
|
NodesAutoSync: dnsConfig.NodesAutoSync,
|
||||||
ServersAutoSync: dnsConfig.ServersAutoSync,
|
ServersAutoSync: dnsConfig.ServersAutoSync,
|
||||||
|
CnameRecords: dnsConfig.CNameRecords,
|
||||||
|
Ttl: dnsConfig.TTL,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -502,6 +504,8 @@ func (this *NodeClusterService) FindEnabledNodeClusterDNS(ctx context.Context, r
|
|||||||
Provider: pbProvider,
|
Provider: pbProvider,
|
||||||
NodesAutoSync: dnsConfig.NodesAutoSync,
|
NodesAutoSync: dnsConfig.NodesAutoSync,
|
||||||
ServersAutoSync: dnsConfig.ServersAutoSync,
|
ServersAutoSync: dnsConfig.ServersAutoSync,
|
||||||
|
CnameRecords: dnsConfig.CNameRecords,
|
||||||
|
Ttl: dnsConfig.TTL,
|
||||||
DefaultRoute: defaultRoute,
|
DefaultRoute: defaultRoute,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@@ -595,7 +599,7 @@ func (this *NodeClusterService) UpdateNodeClusterDNS(ctx context.Context, req *p
|
|||||||
|
|
||||||
tx := this.NullTx()
|
tx := this.NullTx()
|
||||||
|
|
||||||
err = models.SharedNodeClusterDAO.UpdateClusterDNS(tx, req.NodeClusterId, req.DnsName, req.DnsDomainId, req.NodesAutoSync, req.ServersAutoSync)
|
err = models.SharedNodeClusterDAO.UpdateClusterDNS(tx, req.NodeClusterId, req.DnsName, req.DnsDomainId, req.NodesAutoSync, req.ServersAutoSync, req.CnameRecords, req.Ttl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ func (this *NodeIPAddressService) CreateNodeIPAddress(ctx context.Context, req *
|
|||||||
|
|
||||||
tx := this.NullTx()
|
tx := this.NullTx()
|
||||||
|
|
||||||
addressId, err := models.SharedNodeIPAddressDAO.CreateAddress(tx, adminId, req.NodeId, req.Role, req.Name, req.Ip, req.CanAccess, req.ThresholdsJSON)
|
addressId, err := models.SharedNodeIPAddressDAO.CreateAddress(tx, adminId, req.NodeId, req.Role, req.Name, req.Ip, req.CanAccess, req.IsUp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,7 @@ func (this *NodeIPAddressService) UpdateNodeIPAddress(ctx context.Context, req *
|
|||||||
|
|
||||||
tx := this.NullTx()
|
tx := this.NullTx()
|
||||||
|
|
||||||
err = models.SharedNodeIPAddressDAO.UpdateAddress(tx, adminId, req.NodeIPAddressId, req.Name, req.Ip, req.CanAccess, req.IsOn, req.ThresholdsJSON)
|
err = models.SharedNodeIPAddressDAO.UpdateAddress(tx, adminId, req.NodeIPAddressId, req.Name, req.Ip, req.CanAccess, req.IsOn, req.IsUp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -83,8 +83,8 @@ func (this *NodeIPAddressService) DisableNodeIPAddress(ctx context.Context, req
|
|||||||
return &pb.DisableNodeIPAddressResponse{}, nil
|
return &pb.DisableNodeIPAddressResponse{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DisableAllIPAddressesWithNodeId 禁用某个节点的IP地址
|
// DisableAllNodeIPAddressesWithNodeId 禁用某个节点的IP地址
|
||||||
func (this *NodeIPAddressService) DisableAllIPAddressesWithNodeId(ctx context.Context, req *pb.DisableAllIPAddressesWithNodeIdRequest) (*pb.DisableAllIPAddressesWithNodeIdResponse, error) {
|
func (this *NodeIPAddressService) DisableAllNodeIPAddressesWithNodeId(ctx context.Context, req *pb.DisableAllNodeIPAddressesWithNodeIdRequest) (*pb.DisableAllNodeIPAddressesWithNodeIdResponse, error) {
|
||||||
// 校验请求
|
// 校验请求
|
||||||
_, err := this.ValidateAdmin(ctx, 0)
|
_, err := this.ValidateAdmin(ctx, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -98,7 +98,7 @@ func (this *NodeIPAddressService) DisableAllIPAddressesWithNodeId(ctx context.Co
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &pb.DisableAllIPAddressesWithNodeIdResponse{}, nil
|
return &pb.DisableAllNodeIPAddressesWithNodeIdResponse{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindEnabledNodeIPAddress 查找单个IP地址
|
// FindEnabledNodeIPAddress 查找单个IP地址
|
||||||
@@ -119,26 +119,26 @@ func (this *NodeIPAddressService) FindEnabledNodeIPAddress(ctx context.Context,
|
|||||||
var result *pb.NodeIPAddress = nil
|
var result *pb.NodeIPAddress = nil
|
||||||
if address != nil {
|
if address != nil {
|
||||||
result = &pb.NodeIPAddress{
|
result = &pb.NodeIPAddress{
|
||||||
Id: int64(address.Id),
|
Id: int64(address.Id),
|
||||||
NodeId: int64(address.NodeId),
|
NodeId: int64(address.NodeId),
|
||||||
Role: address.Role,
|
Role: address.Role,
|
||||||
Name: address.Name,
|
Name: address.Name,
|
||||||
Ip: address.Ip,
|
Ip: address.Ip,
|
||||||
Description: address.Description,
|
Description: address.Description,
|
||||||
State: int64(address.State),
|
State: int64(address.State),
|
||||||
Order: int64(address.Order),
|
Order: int64(address.Order),
|
||||||
CanAccess: address.CanAccess == 1,
|
CanAccess: address.CanAccess == 1,
|
||||||
IsOn: address.IsOn == 1,
|
IsOn: address.IsOn == 1,
|
||||||
IsUp: address.IsUp == 1,
|
IsUp: address.IsUp == 1,
|
||||||
ThresholdsJSON: []byte(address.Thresholds),
|
BackupIP: address.DecodeBackupIP(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &pb.FindEnabledNodeIPAddressResponse{NodeIPAddress: result}, nil
|
return &pb.FindEnabledNodeIPAddressResponse{NodeIPAddress: result}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindAllEnabledIPAddressesWithNodeId 查找节点的所有地址
|
// FindAllEnabledNodeIPAddressesWithNodeId 查找节点的所有地址
|
||||||
func (this *NodeIPAddressService) FindAllEnabledIPAddressesWithNodeId(ctx context.Context, req *pb.FindAllEnabledIPAddressesWithNodeIdRequest) (*pb.FindAllEnabledIPAddressesWithNodeIdResponse, error) {
|
func (this *NodeIPAddressService) FindAllEnabledNodeIPAddressesWithNodeId(ctx context.Context, req *pb.FindAllEnabledNodeIPAddressesWithNodeIdRequest) (*pb.FindAllEnabledNodeIPAddressesWithNodeIdResponse, error) {
|
||||||
// 校验请求
|
// 校验请求
|
||||||
_, err := this.ValidateAdmin(ctx, 0)
|
_, err := this.ValidateAdmin(ctx, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -155,26 +155,26 @@ func (this *NodeIPAddressService) FindAllEnabledIPAddressesWithNodeId(ctx contex
|
|||||||
result := []*pb.NodeIPAddress{}
|
result := []*pb.NodeIPAddress{}
|
||||||
for _, address := range addresses {
|
for _, address := range addresses {
|
||||||
result = append(result, &pb.NodeIPAddress{
|
result = append(result, &pb.NodeIPAddress{
|
||||||
Id: int64(address.Id),
|
Id: int64(address.Id),
|
||||||
NodeId: int64(address.NodeId),
|
NodeId: int64(address.NodeId),
|
||||||
Role: address.Role,
|
Role: address.Role,
|
||||||
Name: address.Name,
|
Name: address.Name,
|
||||||
Ip: address.Ip,
|
Ip: address.Ip,
|
||||||
Description: address.Description,
|
Description: address.Description,
|
||||||
State: int64(address.State),
|
State: int64(address.State),
|
||||||
Order: int64(address.Order),
|
Order: int64(address.Order),
|
||||||
CanAccess: address.CanAccess == 1,
|
CanAccess: address.CanAccess == 1,
|
||||||
IsOn: address.IsOn == 1,
|
IsOn: address.IsOn == 1,
|
||||||
IsUp: address.IsUp == 1,
|
IsUp: address.IsUp == 1,
|
||||||
ThresholdsJSON: []byte(address.Thresholds),
|
BackupIP: address.DecodeBackupIP(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return &pb.FindAllEnabledIPAddressesWithNodeIdResponse{Addresses: result}, nil
|
return &pb.FindAllEnabledNodeIPAddressesWithNodeIdResponse{NodeIPAddresses: result}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CountAllEnabledIPAddresses 计算IP地址数量
|
// CountAllEnabledNodeIPAddresses 计算IP地址数量
|
||||||
func (this *NodeIPAddressService) CountAllEnabledIPAddresses(ctx context.Context, req *pb.CountAllEnabledIPAddressesRequest) (*pb.RPCCountResponse, error) {
|
func (this *NodeIPAddressService) CountAllEnabledNodeIPAddresses(ctx context.Context, req *pb.CountAllEnabledNodeIPAddressesRequest) (*pb.RPCCountResponse, error) {
|
||||||
// 校验请求
|
// 校验请求
|
||||||
_, err := this.ValidateAdmin(ctx, 0)
|
_, err := this.ValidateAdmin(ctx, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -191,7 +191,7 @@ func (this *NodeIPAddressService) CountAllEnabledIPAddresses(ctx context.Context
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ListEnabledIPAddresses 列出单页IP地址
|
// ListEnabledIPAddresses 列出单页IP地址
|
||||||
func (this *NodeIPAddressService) ListEnabledIPAddresses(ctx context.Context, req *pb.ListEnabledIPAddressesRequest) (*pb.ListEnabledIPAddressesResponse, error) {
|
func (this *NodeIPAddressService) ListEnabledNodeIPAddresses(ctx context.Context, req *pb.ListEnabledNodeIPAddressesRequest) (*pb.ListEnabledNodeIPAddressesResponse, error) {
|
||||||
// 校验请求
|
// 校验请求
|
||||||
_, err := this.ValidateAdmin(ctx, 0)
|
_, err := this.ValidateAdmin(ctx, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -207,17 +207,67 @@ func (this *NodeIPAddressService) ListEnabledIPAddresses(ctx context.Context, re
|
|||||||
var pbAddrs = []*pb.NodeIPAddress{}
|
var pbAddrs = []*pb.NodeIPAddress{}
|
||||||
for _, addr := range addresses {
|
for _, addr := range addresses {
|
||||||
pbAddrs = append(pbAddrs, &pb.NodeIPAddress{
|
pbAddrs = append(pbAddrs, &pb.NodeIPAddress{
|
||||||
Id: int64(addr.Id),
|
Id: int64(addr.Id),
|
||||||
NodeId: int64(addr.NodeId),
|
NodeId: int64(addr.NodeId),
|
||||||
Role: addr.Role,
|
Role: addr.Role,
|
||||||
Name: addr.Name,
|
Name: addr.Name,
|
||||||
Ip: addr.Ip,
|
Ip: addr.Ip,
|
||||||
Description: addr.Description,
|
Description: addr.Description,
|
||||||
CanAccess: addr.CanAccess == 1,
|
CanAccess: addr.CanAccess == 1,
|
||||||
IsOn: addr.IsOn == 1,
|
IsOn: addr.IsOn == 1,
|
||||||
IsUp: addr.IsUp == 1,
|
IsUp: addr.IsUp == 1,
|
||||||
ThresholdsJSON: []byte(addr.Thresholds),
|
BackupIP: addr.DecodeBackupIP(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return &pb.ListEnabledIPAddressesResponse{NodeIPAddresses: pbAddrs}, nil
|
return &pb.ListEnabledNodeIPAddressesResponse{NodeIPAddresses: pbAddrs}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateNodeIPAddressIsUp 设置上下线状态
|
||||||
|
func (this *NodeIPAddressService) UpdateNodeIPAddressIsUp(ctx context.Context, req *pb.UpdateNodeIPAddressIsUpRequest) (*pb.RPCSuccess, error) {
|
||||||
|
// 校验请求
|
||||||
|
adminId, err := this.ValidateAdmin(ctx, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
err = models.SharedNodeIPAddressDAO.UpdateAddressIsUp(tx, req.NodeIPAddressId, req.IsUp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 增加日志
|
||||||
|
if req.IsUp {
|
||||||
|
err = models.SharedNodeIPAddressLogDAO.CreateLog(tx, adminId, req.NodeIPAddressId, "手动上线")
|
||||||
|
} else {
|
||||||
|
err = models.SharedNodeIPAddressLogDAO.CreateLog(tx, adminId, req.NodeIPAddressId, "手动下线")
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.Success()
|
||||||
|
}
|
||||||
|
|
||||||
|
// RestoreNodeIPAddressBackupIP 还原备用IP状态
|
||||||
|
func (this *NodeIPAddressService) RestoreNodeIPAddressBackupIP(ctx context.Context, req *pb.RestoreNodeIPAddressBackupIPRequest) (*pb.RPCSuccess, error) {
|
||||||
|
// 校验请求
|
||||||
|
adminId, err := this.ValidateAdmin(ctx, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
err = models.SharedNodeIPAddressDAO.UpdateAddressBackupIP(tx, req.NodeIPAddressId, 0, "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 增加日志
|
||||||
|
err = models.SharedNodeIPAddressLogDAO.CreateLog(tx, adminId, req.NodeIPAddressId, "恢复IP状态")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.Success()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ func (this *NodeIPAddressLogService) ListNodeIPAddressLogs(ctx context.Context,
|
|||||||
IsOn: log.IsOn == 1,
|
IsOn: log.IsOn == 1,
|
||||||
IsUp: log.IsUp == 1,
|
IsUp: log.IsUp == 1,
|
||||||
CanAccess: log.CanAccess == 1,
|
CanAccess: log.CanAccess == 1,
|
||||||
|
BackupIP: log.BackupIP,
|
||||||
NodeIPAddress: pbAddr,
|
NodeIPAddress: pbAddr,
|
||||||
Admin: pbAdmin,
|
Admin: pbAdmin,
|
||||||
})
|
})
|
||||||
|
|||||||
171
internal/rpc/services/service_node_ip_address_threshold.go
Normal file
171
internal/rpc/services/service_node_ip_address_threshold.go
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||||
|
|
||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NodeIPAddressThresholdService IP阈值相关服务
|
||||||
|
type NodeIPAddressThresholdService struct {
|
||||||
|
BaseService
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateNodeIPAddressThreshold 创建阈值
|
||||||
|
func (this *NodeIPAddressThresholdService) CreateNodeIPAddressThreshold(ctx context.Context, req *pb.CreateNodeIPAddressThresholdRequest) (*pb.CreateNodeIPAddressThresholdResponse, error) {
|
||||||
|
_, err := this.ValidateAdmin(ctx, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
var items = []*nodeconfigs.IPAddressThresholdItemConfig{}
|
||||||
|
if len(req.ItemsJSON) > 0 {
|
||||||
|
err = json.Unmarshal(req.ItemsJSON, &items)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("decode items failed: " + err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var actions = []*nodeconfigs.IPAddressThresholdActionConfig{}
|
||||||
|
if len(req.ActionsJSON) > 0 {
|
||||||
|
err = json.Unmarshal(req.ActionsJSON, &actions)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("decode actions failed: " + err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
thresholdId, err := models.SharedNodeIPAddressThresholdDAO.CreateThreshold(tx, req.NodeIPAddressId, items, actions, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &pb.CreateNodeIPAddressThresholdResponse{NodeIPAddressThresholdId: thresholdId}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateNodeIPAddressThreshold 修改阈值
|
||||||
|
func (this *NodeIPAddressThresholdService) UpdateNodeIPAddressThreshold(ctx context.Context, req *pb.UpdateNodeIPAddressThresholdRequest) (*pb.RPCSuccess, error) {
|
||||||
|
_, err := this.ValidateAdmin(ctx, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
var items = []*nodeconfigs.IPAddressThresholdItemConfig{}
|
||||||
|
if len(req.ItemsJSON) > 0 {
|
||||||
|
err = json.Unmarshal(req.ItemsJSON, &items)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("decode items failed: " + err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var actions = []*nodeconfigs.IPAddressThresholdActionConfig{}
|
||||||
|
if len(req.ActionsJSON) > 0 {
|
||||||
|
err = json.Unmarshal(req.ActionsJSON, &actions)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("decode actions failed: " + err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = models.SharedNodeIPAddressThresholdDAO.UpdateThreshold(tx, req.NodeIPAddressThresholdId, items, actions, -1)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return this.Success()
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteNodeIPAddressThreshold 删除阈值
|
||||||
|
func (this *NodeIPAddressThresholdService) DeleteNodeIPAddressThreshold(ctx context.Context, req *pb.DeleteNodeIPAddressThresholdRequest) (*pb.RPCSuccess, error) {
|
||||||
|
_, err := this.ValidateAdmin(ctx, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
err = models.SharedNodeIPAddressThresholdDAO.DisableNodeIPAddressThreshold(tx, req.NodeIPAddressThresholdId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return this.Success()
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindAllEnabledNodeIPAddressThresholds 查找IP的所有阈值
|
||||||
|
func (this *NodeIPAddressThresholdService) FindAllEnabledNodeIPAddressThresholds(ctx context.Context, req *pb.FindAllEnabledNodeIPAddressThresholdsRequest) (*pb.FindAllEnabledNodeIPAddressThresholdsResponse, error) {
|
||||||
|
_, err := this.ValidateAdmin(ctx, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
thresholds, err := models.SharedNodeIPAddressThresholdDAO.FindAllEnabledThresholdsWithAddrId(tx, req.NodeIPAddressId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var pbThresholds = []*pb.NodeIPAddressThreshold{}
|
||||||
|
for _, threshold := range thresholds {
|
||||||
|
pbThresholds = append(pbThresholds, &pb.NodeIPAddressThreshold{
|
||||||
|
Id: int64(threshold.Id),
|
||||||
|
ItemsJSON: []byte(threshold.Items),
|
||||||
|
ActionsJSON: []byte(threshold.Actions),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return &pb.FindAllEnabledNodeIPAddressThresholdsResponse{NodeIPAddressThresholds: pbThresholds}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CountAllEnabledNodeIPAddressThresholds 计算IP阈值的数量
|
||||||
|
func (this *NodeIPAddressThresholdService) CountAllEnabledNodeIPAddressThresholds(ctx context.Context, req *pb.CountAllEnabledNodeIPAddressThresholdsRequest) (*pb.RPCCountResponse, error) {
|
||||||
|
_, err := this.ValidateAdmin(ctx, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
count, err := models.SharedNodeIPAddressThresholdDAO.CountAllEnabledThresholdsWithAddrId(tx, req.NodeIPAddressId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return this.SuccessCount(count)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateAllNodeIPAddressThresholds 批量更新阈值
|
||||||
|
func (this *NodeIPAddressThresholdService) UpdateAllNodeIPAddressThresholds(ctx context.Context, req *pb.UpdateAllNodeIPAddressThresholdsRequest) (*pb.RPCSuccess, error) {
|
||||||
|
_, err := this.ValidateAdmin(ctx, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
|
||||||
|
var thresholds = []*nodeconfigs.IPAddressThresholdConfig{}
|
||||||
|
err = json.Unmarshal(req.NodeIPAddressThresholdsJSON, &thresholds)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("decode thresholds failed: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
err = models.SharedNodeIPAddressThresholdDAO.DisableAllThresholdsWithAddrId(tx, req.NodeIPAddressId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(thresholds) == 0 {
|
||||||
|
return this.Success()
|
||||||
|
}
|
||||||
|
|
||||||
|
var count = len(thresholds)
|
||||||
|
for index, threshold := range thresholds {
|
||||||
|
var order = count - index
|
||||||
|
if threshold.Id > 0 {
|
||||||
|
err = models.SharedNodeIPAddressThresholdDAO.UpdateThreshold(tx, threshold.Id, threshold.Items, threshold.Actions, order)
|
||||||
|
} else {
|
||||||
|
_, err = models.SharedNodeIPAddressThresholdDAO.CreateThreshold(tx, req.NodeIPAddressId, threshold.Items, threshold.Actions, order)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.Success()
|
||||||
|
}
|
||||||
@@ -120,7 +120,7 @@ func (this *NodeService) NodeStream(server pb.NodeService_NodeStreamServer) erro
|
|||||||
}
|
}
|
||||||
subject := "节点\"" + nodeName + "\"已经恢复在线"
|
subject := "节点\"" + nodeName + "\"已经恢复在线"
|
||||||
msg := "节点\"" + nodeName + "\"已经恢复在线"
|
msg := "节点\"" + nodeName + "\"已经恢复在线"
|
||||||
err = models.SharedMessageDAO.CreateNodeMessage(tx, nodeconfigs.NodeRoleNode, clusterId, nodeId, models.MessageTypeNodeActive, models.MessageLevelSuccess, subject, msg, nil)
|
err = models.SharedMessageDAO.CreateNodeMessage(tx, nodeconfigs.NodeRoleNode, clusterId, nodeId, models.MessageTypeNodeActive, models.MessageLevelSuccess, subject, msg, nil, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ package services
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
|
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
@@ -46,15 +45,6 @@ func (this *NodeValueService) CreateNodeValue(ctx context.Context, req *pb.Creat
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 触发IP阈值
|
|
||||||
// 企业版专有
|
|
||||||
if teaconst.IsPlus {
|
|
||||||
err = models.SharedNodeIPAddressDAO.FireThresholds(tx, role, nodeId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.Success()
|
return this.Success()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,12 +10,12 @@ import (
|
|||||||
"github.com/iwind/TeaGo/maps"
|
"github.com/iwind/TeaGo/maps"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 源站相关管理
|
// OriginService 源站相关管理
|
||||||
type OriginService struct {
|
type OriginService struct {
|
||||||
BaseService
|
BaseService
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建源站
|
// CreateOrigin 创建源站
|
||||||
func (this *OriginService) CreateOrigin(ctx context.Context, req *pb.CreateOriginRequest) (*pb.CreateOriginResponse, error) {
|
func (this *OriginService) CreateOrigin(ctx context.Context, req *pb.CreateOriginRequest) (*pb.CreateOriginResponse, error) {
|
||||||
adminId, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
|
adminId, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -58,7 +58,7 @@ func (this *OriginService) CreateOrigin(ctx context.Context, req *pb.CreateOrigi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
originId, err := models.SharedOriginDAO.CreateOrigin(tx, adminId, userId, req.Name, string(addrMap.AsJSON()), req.Description, req.Weight, req.IsOn, connTimeout, readTimeout, idleTimeout, req.MaxConns, req.MaxIdleConns)
|
originId, err := models.SharedOriginDAO.CreateOrigin(tx, adminId, userId, req.Name, string(addrMap.AsJSON()), req.Description, req.Weight, req.IsOn, connTimeout, readTimeout, idleTimeout, req.MaxConns, req.MaxIdleConns, req.Domains)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ func (this *OriginService) CreateOrigin(ctx context.Context, req *pb.CreateOrigi
|
|||||||
return &pb.CreateOriginResponse{OriginId: originId}, nil
|
return &pb.CreateOriginResponse{OriginId: originId}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 修改源站
|
// UpdateOrigin 修改源站
|
||||||
func (this *OriginService) UpdateOrigin(ctx context.Context, req *pb.UpdateOriginRequest) (*pb.RPCSuccess, error) {
|
func (this *OriginService) UpdateOrigin(ctx context.Context, req *pb.UpdateOriginRequest) (*pb.RPCSuccess, error) {
|
||||||
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
|
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -112,7 +112,7 @@ func (this *OriginService) UpdateOrigin(ctx context.Context, req *pb.UpdateOrigi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = models.SharedOriginDAO.UpdateOrigin(tx, req.OriginId, req.Name, string(addrMap.AsJSON()), req.Description, req.Weight, req.IsOn, connTimeout, readTimeout, idleTimeout, req.MaxConns, req.MaxIdleConns)
|
err = models.SharedOriginDAO.UpdateOrigin(tx, req.OriginId, req.Name, string(addrMap.AsJSON()), req.Description, req.Weight, req.IsOn, connTimeout, readTimeout, idleTimeout, req.MaxConns, req.MaxIdleConns, req.Domains)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -120,7 +120,7 @@ func (this *OriginService) UpdateOrigin(ctx context.Context, req *pb.UpdateOrigi
|
|||||||
return this.Success()
|
return this.Success()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查找单个源站信息
|
// FindEnabledOrigin 查找单个源站信息
|
||||||
func (this *OriginService) FindEnabledOrigin(ctx context.Context, req *pb.FindEnabledOriginRequest) (*pb.FindEnabledOriginResponse, error) {
|
func (this *OriginService) FindEnabledOrigin(ctx context.Context, req *pb.FindEnabledOriginRequest) (*pb.FindEnabledOriginResponse, error) {
|
||||||
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
|
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -157,11 +157,12 @@ func (this *OriginService) FindEnabledOrigin(ctx context.Context, req *pb.FindEn
|
|||||||
PortRange: addr.PortRange,
|
PortRange: addr.PortRange,
|
||||||
},
|
},
|
||||||
Description: origin.Description,
|
Description: origin.Description,
|
||||||
|
Domains: origin.DecodeDomains(),
|
||||||
}
|
}
|
||||||
return &pb.FindEnabledOriginResponse{Origin: result}, nil
|
return &pb.FindEnabledOriginResponse{Origin: result}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查找源站配置
|
// FindEnabledOriginConfig 查找源站配置
|
||||||
func (this *OriginService) FindEnabledOriginConfig(ctx context.Context, req *pb.FindEnabledOriginConfigRequest) (*pb.FindEnabledOriginConfigResponse, error) {
|
func (this *OriginService) FindEnabledOriginConfig(ctx context.Context, req *pb.FindEnabledOriginConfigRequest) (*pb.FindEnabledOriginConfigResponse, error) {
|
||||||
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
|
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ package services
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ServerGroupService 服务分组相关服务
|
// ServerGroupService 服务分组相关服务
|
||||||
@@ -132,3 +134,295 @@ func (this *ServerGroupService) FindEnabledServerGroup(ctx context.Context, req
|
|||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindAndInitServerGroupHTTPReverseProxyConfig 查找HTTP反向代理设置
|
||||||
|
func (this *ServerGroupService) FindAndInitServerGroupHTTPReverseProxyConfig(ctx context.Context, req *pb.FindAndInitServerGroupHTTPReverseProxyConfigRequest) (*pb.FindAndInitServerGroupHTTPReverseProxyConfigResponse, error) {
|
||||||
|
// 校验请求
|
||||||
|
adminId, err := this.ValidateAdmin(ctx, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tx := this.NullTx()
|
||||||
|
|
||||||
|
reverseProxyRef, err := models.SharedServerGroupDAO.FindHTTPReverseProxyRef(tx, req.ServerGroupId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if reverseProxyRef == nil {
|
||||||
|
reverseProxyId, err := models.SharedReverseProxyDAO.CreateReverseProxy(tx, adminId, 0, nil, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
reverseProxyRef = &serverconfigs.ReverseProxyRef{
|
||||||
|
IsOn: false,
|
||||||
|
ReverseProxyId: reverseProxyId,
|
||||||
|
}
|
||||||
|
refJSON, err := json.Marshal(reverseProxyRef)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = models.SharedServerGroupDAO.UpdateHTTPReverseProxy(tx, req.ServerGroupId, refJSON)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reverseProxyConfig, err := models.SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
configJSON, err := json.Marshal(reverseProxyConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
refJSON, err := json.Marshal(reverseProxyRef)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pb.FindAndInitServerGroupHTTPReverseProxyConfigResponse{ReverseProxyJSON: configJSON, ReverseProxyRefJSON: refJSON}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindAndInitServerGroupTCPReverseProxyConfig 查找反向代理设置
|
||||||
|
func (this *ServerGroupService) FindAndInitServerGroupTCPReverseProxyConfig(ctx context.Context, req *pb.FindAndInitServerGroupTCPReverseProxyConfigRequest) (*pb.FindAndInitServerGroupTCPReverseProxyConfigResponse, error) {
|
||||||
|
// 校验请求
|
||||||
|
adminId, err := this.ValidateAdmin(ctx, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tx := this.NullTx()
|
||||||
|
|
||||||
|
reverseProxyRef, err := models.SharedServerGroupDAO.FindTCPReverseProxyRef(tx, req.ServerGroupId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if reverseProxyRef == nil {
|
||||||
|
reverseProxyId, err := models.SharedReverseProxyDAO.CreateReverseProxy(tx, adminId, 0, nil, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
reverseProxyRef = &serverconfigs.ReverseProxyRef{
|
||||||
|
IsOn: false,
|
||||||
|
ReverseProxyId: reverseProxyId,
|
||||||
|
}
|
||||||
|
refJSON, err := json.Marshal(reverseProxyRef)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = models.SharedServerGroupDAO.UpdateTCPReverseProxy(tx, req.ServerGroupId, refJSON)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reverseProxyConfig, err := models.SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
configJSON, err := json.Marshal(reverseProxyConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
refJSON, err := json.Marshal(reverseProxyRef)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pb.FindAndInitServerGroupTCPReverseProxyConfigResponse{ReverseProxyJSON: configJSON, ReverseProxyRefJSON: refJSON}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindAndInitServerGroupUDPReverseProxyConfig 查找反向代理设置
|
||||||
|
func (this *ServerGroupService) FindAndInitServerGroupUDPReverseProxyConfig(ctx context.Context, req *pb.FindAndInitServerGroupUDPReverseProxyConfigRequest) (*pb.FindAndInitServerGroupUDPReverseProxyConfigResponse, error) {
|
||||||
|
// 校验请求
|
||||||
|
adminId, err := this.ValidateAdmin(ctx, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tx := this.NullTx()
|
||||||
|
|
||||||
|
reverseProxyRef, err := models.SharedServerGroupDAO.FindUDPReverseProxyRef(tx, req.ServerGroupId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if reverseProxyRef == nil {
|
||||||
|
reverseProxyId, err := models.SharedReverseProxyDAO.CreateReverseProxy(tx, adminId, 0, nil, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
reverseProxyRef = &serverconfigs.ReverseProxyRef{
|
||||||
|
IsOn: false,
|
||||||
|
ReverseProxyId: reverseProxyId,
|
||||||
|
}
|
||||||
|
refJSON, err := json.Marshal(reverseProxyRef)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = models.SharedServerGroupDAO.UpdateUDPReverseProxy(tx, req.ServerGroupId, refJSON)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reverseProxyConfig, err := models.SharedReverseProxyDAO.ComposeReverseProxyConfig(tx, reverseProxyRef.ReverseProxyId, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
configJSON, err := json.Marshal(reverseProxyConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
refJSON, err := json.Marshal(reverseProxyRef)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pb.FindAndInitServerGroupUDPReverseProxyConfigResponse{ReverseProxyJSON: configJSON, ReverseProxyRefJSON: refJSON}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateServerGroupHTTPReverseProxy 修改服务的反向代理设置
|
||||||
|
func (this *ServerGroupService) UpdateServerGroupHTTPReverseProxy(ctx context.Context, req *pb.UpdateServerGroupHTTPReverseProxyRequest) (*pb.RPCSuccess, error) {
|
||||||
|
// 校验请求
|
||||||
|
_, err := this.ValidateAdmin(ctx, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tx := this.NullTx()
|
||||||
|
|
||||||
|
// 修改配置
|
||||||
|
err = models.SharedServerGroupDAO.UpdateHTTPReverseProxy(tx, req.ServerGroupId, req.ReverseProxyJSON)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.Success()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateServerGroupTCPReverseProxy 修改服务的反向代理设置
|
||||||
|
func (this *ServerGroupService) UpdateServerGroupTCPReverseProxy(ctx context.Context, req *pb.UpdateServerGroupTCPReverseProxyRequest) (*pb.RPCSuccess, error) {
|
||||||
|
// 校验请求
|
||||||
|
_, err := this.ValidateAdmin(ctx, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tx := this.NullTx()
|
||||||
|
|
||||||
|
// 修改配置
|
||||||
|
err = models.SharedServerGroupDAO.UpdateTCPReverseProxy(tx, req.ServerGroupId, req.ReverseProxyJSON)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.Success()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateServerGroupUDPReverseProxy 修改服务的反向代理设置
|
||||||
|
func (this *ServerGroupService) UpdateServerGroupUDPReverseProxy(ctx context.Context, req *pb.UpdateServerGroupUDPReverseProxyRequest) (*pb.RPCSuccess, error) {
|
||||||
|
// 校验请求
|
||||||
|
_, err := this.ValidateAdmin(ctx, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tx := this.NullTx()
|
||||||
|
|
||||||
|
// 修改配置
|
||||||
|
err = models.SharedServerGroupDAO.UpdateUDPReverseProxy(tx, req.ServerGroupId, req.ReverseProxyJSON)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.Success()
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindEnabledServerGroupConfigInfo 取得分组的配置概要信息
|
||||||
|
func (this *ServerGroupService) FindEnabledServerGroupConfigInfo(ctx context.Context, req *pb.FindEnabledServerGroupConfigInfoRequest) (*pb.FindEnabledServerGroupConfigInfoResponse, error) {
|
||||||
|
// 校验请求
|
||||||
|
_, err := this.ValidateAdmin(ctx, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tx := this.NullTx()
|
||||||
|
|
||||||
|
var group *models.ServerGroup
|
||||||
|
if req.ServerGroupId > 0 {
|
||||||
|
group, err = models.SharedServerGroupDAO.FindEnabledServerGroup(tx, req.ServerGroupId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else if req.ServerId > 0 {
|
||||||
|
groupIds, err := models.SharedServerDAO.FindServerGroupIds(tx, req.ServerId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(groupIds) > 0 {
|
||||||
|
for _, groupId := range groupIds {
|
||||||
|
group, err = models.SharedServerGroupDAO.FindEnabledServerGroup(tx, groupId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if group != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if group == nil {
|
||||||
|
return &pb.FindEnabledServerGroupConfigInfoResponse{
|
||||||
|
HasHTTPReverseProxy: false,
|
||||||
|
HasTCPReverseProxy: false,
|
||||||
|
HasUDPReverseProxy: false,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = &pb.FindEnabledServerGroupConfigInfoResponse{
|
||||||
|
ServerGroupId: int64(group.Id),
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(group.HttpReverseProxy) > 0 {
|
||||||
|
var ref = &serverconfigs.ReverseProxyRef{}
|
||||||
|
err = json.Unmarshal([]byte(group.HttpReverseProxy), ref)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
result.HasHTTPReverseProxy = ref.IsPrior
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(group.TcpReverseProxy) > 0 {
|
||||||
|
var ref = &serverconfigs.ReverseProxyRef{}
|
||||||
|
err = json.Unmarshal([]byte(group.TcpReverseProxy), ref)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
result.HasTCPReverseProxy = ref.IsPrior
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(group.UdpReverseProxy) > 0 {
|
||||||
|
var ref = &serverconfigs.ReverseProxyRef{}
|
||||||
|
err = json.Unmarshal([]byte(group.UdpReverseProxy), ref)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
result.HasUDPReverseProxy = ref.IsPrior
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -221,7 +221,15 @@ func (this *SQLExecutor) checkCluster(db *dbs.DB) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 创建默认集群
|
// 创建默认集群
|
||||||
_, err = db.Exec("INSERT INTO edgeNodeClusters (name, useAllAPINodes, state, uniqueId, secret) VALUES (?, ?, ?, ?, ?)", "默认集群", 1, 1, rands.HexString(32), rands.String(32))
|
var uniqueId = rands.HexString(32)
|
||||||
|
var secret = rands.String(32)
|
||||||
|
_, err = db.Exec("INSERT INTO edgeNodeClusters (name, useAllAPINodes, state, uniqueId, secret) VALUES (?, ?, ?, ?, ?)", "默认集群", 1, 1, uniqueId, secret)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建APIToken
|
||||||
|
_, err = db.Exec("INSERT INTO edgeAPITokens (nodeId, secret, role, state) VALUES (?, ?, 'cluster', 1)", uniqueId, secret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,9 @@ var upgradeFuncs = []*upgradeVersion{
|
|||||||
{
|
{
|
||||||
"0.3.0", upgradeV0_3_0,
|
"0.3.0", upgradeV0_3_0,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"0.3.1", upgradeV0_3_1,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpgradeSQLData 升级SQL数据
|
// UpgradeSQLData 升级SQL数据
|
||||||
@@ -361,3 +364,32 @@ func upgradeV0_3_0(db *dbs.DB) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// v0.3.1
|
||||||
|
func upgradeV0_3_1(db *dbs.DB) error {
|
||||||
|
// 清空域名统计,已使用分表代替
|
||||||
|
// 因为可能有权限问题,所以我们忽略错误
|
||||||
|
_, _ = db.Exec("TRUNCATE table edgeServerDomainHourlyStats")
|
||||||
|
|
||||||
|
// 升级APIToken
|
||||||
|
ones, _, err := db.FindOnes("SELECT uniqueId,secret FROM edgeNodeClusters")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, one := range ones {
|
||||||
|
var uniqueId = one.GetString("uniqueId")
|
||||||
|
var secret = one.GetString("secret")
|
||||||
|
tokenOne, err := db.FindOne("SELECT id FROM edgeAPITokens WHERE nodeId=? LIMIT 1", uniqueId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(tokenOne) == 0 {
|
||||||
|
_, err = db.Exec("INSERT INTO edgeAPITokens (nodeId, secret, role, state) VALUES (?, ?, 'cluster', 1)", uniqueId, secret)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -20,3 +20,20 @@ func TestUpgradeSQLData(t *testing.T) {
|
|||||||
}
|
}
|
||||||
t.Log("ok")
|
t.Log("ok")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func TestUpgradeSQLData_v1_3_1(t *testing.T) {
|
||||||
|
db, err := dbs.NewInstanceFromConfig(&dbs.DBConfig{
|
||||||
|
Driver: "mysql",
|
||||||
|
Dsn: "root:123456@tcp(127.0.0.1:3306)/db_edge_new?charset=utf8mb4&timeout=30s",
|
||||||
|
Prefix: "edge",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
err = upgradeV0_3_1(db)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log("ok")
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients/dnstypes"
|
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients/dnstypes"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/dnsconfigs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
"github.com/iwind/TeaGo/lists"
|
"github.com/iwind/TeaGo/lists"
|
||||||
@@ -125,7 +126,7 @@ func (this *DNSTaskExecutor) doServer(taskId int64, serverId int64) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
manager, domainId, domain, clusterDNSName, err := this.findDNSManager(tx, int64(serverDNS.ClusterId))
|
manager, domainId, domain, clusterDNSName, dnsConfig, err := this.findDNSManager(tx, int64(serverDNS.ClusterId))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -133,6 +134,10 @@ func (this *DNSTaskExecutor) doServer(taskId int64, serverId int64) error {
|
|||||||
isOk = true
|
isOk = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
var ttl int32 = 0
|
||||||
|
if dnsConfig != nil {
|
||||||
|
ttl = dnsConfig.TTL
|
||||||
|
}
|
||||||
|
|
||||||
recordName := serverDNS.DnsName
|
recordName := serverDNS.DnsName
|
||||||
recordValue := clusterDNSName + "." + domain + "."
|
recordValue := clusterDNSName + "." + domain + "."
|
||||||
@@ -196,6 +201,7 @@ func (this *DNSTaskExecutor) doServer(taskId int64, serverId int64) error {
|
|||||||
Type: recordType,
|
Type: recordType,
|
||||||
Value: recordValue,
|
Value: recordValue,
|
||||||
Route: recordRoute,
|
Route: recordRoute,
|
||||||
|
TTL: ttl,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -264,7 +270,7 @@ func (this *DNSTaskExecutor) doCluster(taskId int64, clusterId int64) error {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
var tx *dbs.Tx
|
var tx *dbs.Tx
|
||||||
manager, domainId, domain, clusterDNSName, err := this.findDNSManager(tx, clusterId)
|
manager, domainId, domain, clusterDNSName, dnsConfig, err := this.findDNSManager(tx, clusterId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -273,17 +279,29 @@ func (this *DNSTaskExecutor) doCluster(taskId int64, clusterId int64) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var clusterDomain = clusterDNSName + "." + domain
|
||||||
|
|
||||||
|
var ttl int32 = 0
|
||||||
|
if dnsConfig != nil {
|
||||||
|
ttl = dnsConfig.TTL
|
||||||
|
}
|
||||||
|
|
||||||
// 以前的节点记录
|
// 以前的节点记录
|
||||||
records, err := manager.GetRecords(domain)
|
records, err := manager.GetRecords(domain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
oldRecordsMap := map[string]*dnstypes.Record{} // route@value => record
|
var oldRecordsMap = map[string]*dnstypes.Record{} // route@value => record
|
||||||
|
var oldCnameRecordsMap = map[string]*dnstypes.Record{} // cname => record
|
||||||
for _, record := range records {
|
for _, record := range records {
|
||||||
if (record.Type == dnstypes.RecordTypeA || record.Type == dnstypes.RecordTypeAAAA) && record.Name == clusterDNSName {
|
if (record.Type == dnstypes.RecordTypeA || record.Type == dnstypes.RecordTypeAAAA) && record.Name == clusterDNSName {
|
||||||
key := record.Route + "@" + record.Value
|
key := record.Route + "@" + record.Value
|
||||||
oldRecordsMap[key] = record
|
oldRecordsMap[key] = record
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if record.Type == dnstypes.RecordTypeCNAME {
|
||||||
|
oldCnameRecordsMap[record.Name] = record
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 当前的节点记录
|
// 当前的节点记录
|
||||||
@@ -311,7 +329,7 @@ func (this *DNSTaskExecutor) doCluster(taskId int64, clusterId int64) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for _, ipAddress := range ipAddresses {
|
for _, ipAddress := range ipAddresses {
|
||||||
ip := ipAddress.Ip
|
ip := ipAddress.DNSIP()
|
||||||
if len(ip) == 0 || ipAddress.CanAccess == 0 || ipAddress.IsUp == 0 || ipAddress.IsOn == 0 {
|
if len(ip) == 0 || ipAddress.CanAccess == 0 || ipAddress.IsUp == 0 || ipAddress.IsOn == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -336,6 +354,7 @@ func (this *DNSTaskExecutor) doCluster(taskId int64, clusterId int64) error {
|
|||||||
Type: recordType,
|
Type: recordType,
|
||||||
Value: ip,
|
Value: ip,
|
||||||
Route: route,
|
Route: route,
|
||||||
|
TTL: ttl,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -357,6 +376,80 @@ func (this *DNSTaskExecutor) doCluster(taskId int64, clusterId int64) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 服务域名
|
||||||
|
servers, err := models.SharedServerDAO.FindAllServersDNSWithClusterId(tx, clusterId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
serverRecords := []*dnstypes.Record{} // 之所以用数组再存一遍,是因为dnsName可能会重复
|
||||||
|
serverRecordsMap := map[string]*dnstypes.Record{} // dnsName => *Record
|
||||||
|
for _, record := range records {
|
||||||
|
if record.Type == dnstypes.RecordTypeCNAME && record.Value == clusterDomain+"." {
|
||||||
|
serverRecords = append(serverRecords, record)
|
||||||
|
serverRecordsMap[record.Name] = record
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增的域名
|
||||||
|
serverDNSNames := []string{}
|
||||||
|
for _, server := range servers {
|
||||||
|
dnsName := server.DnsName
|
||||||
|
if len(dnsName) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
serverDNSNames = append(serverDNSNames, dnsName)
|
||||||
|
_, ok := serverRecordsMap[dnsName]
|
||||||
|
if !ok {
|
||||||
|
isChanged = true
|
||||||
|
err = manager.AddRecord(domain, &dnstypes.Record{
|
||||||
|
Id: "",
|
||||||
|
Name: dnsName,
|
||||||
|
Type: dnstypes.RecordTypeCNAME,
|
||||||
|
Value: clusterDomain + ".",
|
||||||
|
Route: "", // 注意这里为空,需要在执行过程中获取默认值
|
||||||
|
TTL: ttl,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 自动设置的CNAME
|
||||||
|
var cnameRecords = []string{}
|
||||||
|
if dnsConfig != nil {
|
||||||
|
cnameRecords = dnsConfig.CNameRecords
|
||||||
|
}
|
||||||
|
for _, cnameRecord := range cnameRecords {
|
||||||
|
serverDNSNames = append(serverDNSNames, cnameRecord)
|
||||||
|
_, ok := serverRecordsMap[cnameRecord]
|
||||||
|
if !ok {
|
||||||
|
isChanged = true
|
||||||
|
err = manager.AddRecord(domain, &dnstypes.Record{
|
||||||
|
Id: "",
|
||||||
|
Name: cnameRecord,
|
||||||
|
Type: dnstypes.RecordTypeCNAME,
|
||||||
|
Value: clusterDomain + ".",
|
||||||
|
Route: "", // 注意这里为空,需要在执行过程中获取默认值
|
||||||
|
TTL: ttl,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 多余的域名
|
||||||
|
for _, record := range serverRecords {
|
||||||
|
if !lists.ContainsString(serverDNSNames, record.Name) {
|
||||||
|
isChanged = true
|
||||||
|
err = manager.DeleteRecord(domain, record)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 通知更新域名
|
// 通知更新域名
|
||||||
if isChanged {
|
if isChanged {
|
||||||
err = dnsmodels.SharedDNSTaskDAO.CreateDomainTask(tx, domainId, dnsmodels.DNSTaskTypeDomainChange)
|
err = dnsmodels.SharedDNSTaskDAO.CreateDomainTask(tx, domainId, dnsmodels.DNSTaskTypeDomainChange)
|
||||||
@@ -436,47 +529,53 @@ func (this *DNSTaskExecutor) doDomain(taskId int64, domainId int64) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DNSTaskExecutor) findDNSManager(tx *dbs.Tx, clusterId int64) (manager dnsclients.ProviderInterface, domainId int64, domain string, clusterDNSName string, err error) {
|
func (this *DNSTaskExecutor) findDNSManager(tx *dbs.Tx, clusterId int64) (manager dnsclients.ProviderInterface, domainId int64, domain string, clusterDNSName string, dnsConfig *dnsconfigs.ClusterDNSConfig, err error) {
|
||||||
clusterDNS, err := models.SharedNodeClusterDAO.FindClusterDNSInfo(tx, clusterId, nil)
|
clusterDNS, err := models.SharedNodeClusterDAO.FindClusterDNSInfo(tx, clusterId, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, "", "", err
|
return nil, 0, "", "", nil, err
|
||||||
}
|
}
|
||||||
if clusterDNS == nil || len(clusterDNS.DnsName) == 0 || clusterDNS.DnsDomainId <= 0 {
|
if clusterDNS == nil || len(clusterDNS.DnsName) == 0 || clusterDNS.DnsDomainId <= 0 {
|
||||||
return nil, 0, "", "", nil
|
return nil, 0, "", "", nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
dnsConfig, err = clusterDNS.DecodeDNSConfig()
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, "", "", nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
dnsDomain, err := dnsmodels.SharedDNSDomainDAO.FindEnabledDNSDomain(tx, int64(clusterDNS.DnsDomainId), nil)
|
dnsDomain, err := dnsmodels.SharedDNSDomainDAO.FindEnabledDNSDomain(tx, int64(clusterDNS.DnsDomainId), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, "", "", err
|
return nil, 0, "", "", nil, err
|
||||||
}
|
}
|
||||||
if dnsDomain == nil {
|
if dnsDomain == nil {
|
||||||
return nil, 0, "", "", nil
|
return nil, 0, "", "", nil, nil
|
||||||
}
|
}
|
||||||
providerId := int64(dnsDomain.ProviderId)
|
providerId := int64(dnsDomain.ProviderId)
|
||||||
if providerId <= 0 {
|
if providerId <= 0 {
|
||||||
return nil, 0, "", "", nil
|
return nil, 0, "", "", nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
provider, err := dnsmodels.SharedDNSProviderDAO.FindEnabledDNSProvider(tx, providerId)
|
provider, err := dnsmodels.SharedDNSProviderDAO.FindEnabledDNSProvider(tx, providerId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, "", "", err
|
return nil, 0, "", "", nil, err
|
||||||
}
|
}
|
||||||
if provider == nil {
|
if provider == nil {
|
||||||
return nil, 0, "", "", nil
|
return nil, 0, "", "", nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
manager = dnsclients.FindProvider(provider.Type)
|
manager = dnsclients.FindProvider(provider.Type)
|
||||||
if manager == nil {
|
if manager == nil {
|
||||||
remotelogs.Error("DNSTaskExecutor", "unsupported dns provider type '"+provider.Type+"'")
|
remotelogs.Error("DNSTaskExecutor", "unsupported dns provider type '"+provider.Type+"'")
|
||||||
return nil, 0, "", "", nil
|
return nil, 0, "", "", nil, nil
|
||||||
}
|
}
|
||||||
params, err := provider.DecodeAPIParams()
|
params, err := provider.DecodeAPIParams()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, "", "", err
|
return nil, 0, "", "", nil, err
|
||||||
}
|
}
|
||||||
err = manager.Auth(params)
|
err = manager.Auth(params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, "", "", err
|
return nil, 0, "", "", nil, err
|
||||||
}
|
}
|
||||||
return manager, int64(dnsDomain.Id), dnsDomain.Name, clusterDNS.DnsName, nil
|
|
||||||
|
return manager, int64(dnsDomain.Id), dnsDomain.Name, clusterDNS.DnsName, dnsConfig, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
"github.com/iwind/TeaGo/lists"
|
"github.com/iwind/TeaGo/lists"
|
||||||
@@ -139,10 +140,10 @@ func (this *HealthCheckExecutor) Run() ([]*HealthCheckResult, error) {
|
|||||||
// 通知恢复或下线
|
// 通知恢复或下线
|
||||||
if result.IsOk {
|
if result.IsOk {
|
||||||
message := "健康检查成功,节点\"" + result.Node.Name + "\"已恢复上线"
|
message := "健康检查成功,节点\"" + result.Node.Name + "\"已恢复上线"
|
||||||
err = models.NewMessageDAO().CreateNodeMessage(nil, nodeconfigs.NodeRoleNode, this.clusterId, int64(result.Node.Id), models.MessageTypeHealthCheckNodeUp, models.MessageLevelSuccess, message, message, nil)
|
err = models.NewMessageDAO().CreateNodeMessage(nil, nodeconfigs.NodeRoleNode, this.clusterId, int64(result.Node.Id), models.MessageTypeHealthCheckNodeUp, models.MessageLevelSuccess, message, message, nil, false)
|
||||||
} else {
|
} else {
|
||||||
message := "健康检查失败,节点\"" + result.Node.Name + "\"已自动下线"
|
message := "健康检查失败,节点\"" + result.Node.Name + "\"已自动下线"
|
||||||
err = models.NewMessageDAO().CreateNodeMessage(nil, nodeconfigs.NodeRoleNode, this.clusterId, int64(result.Node.Id), models.MessageTypeHealthCheckNodeDown, models.MessageLevelError, message, message, nil)
|
err = models.NewMessageDAO().CreateNodeMessage(nil, nodeconfigs.NodeRoleNode, this.clusterId, int64(result.Node.Id), models.MessageTypeHealthCheckNodeDown, models.MessageLevelError, message, message, nil, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -185,11 +186,11 @@ func (this *HealthCheckExecutor) checkNode(healthCheckConfig *serverconfigs.Heal
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
conn, err := net.Dial(network, result.NodeAddr+":"+port)
|
conn, err := net.Dial(network, configutils.QuoteIP(result.NodeAddr)+":"+port)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return conn, nil
|
return conn, nil
|
||||||
}
|
}
|
||||||
return net.DialTimeout(network, result.NodeAddr+":"+port, timeout)
|
return net.DialTimeout(network, configutils.QuoteIP(result.NodeAddr)+":"+port, timeout)
|
||||||
},
|
},
|
||||||
MaxIdleConns: 1,
|
MaxIdleConns: 1,
|
||||||
MaxIdleConnsPerHost: 1,
|
MaxIdleConnsPerHost: 1,
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ func (this *NodeMonitorTask) monitorCluster(cluster *models.NodeCluster) error {
|
|||||||
for _, node := range inactiveNodes {
|
for _, node := range inactiveNodes {
|
||||||
subject := "节点\"" + node.Name + "\"已处于离线状态"
|
subject := "节点\"" + node.Name + "\"已处于离线状态"
|
||||||
msg := "节点\"" + node.Name + "\"已处于离线状态"
|
msg := "节点\"" + node.Name + "\"已处于离线状态"
|
||||||
err = models.SharedMessageDAO.CreateNodeMessage(nil, nodeconfigs.NodeRoleNode, clusterId, int64(node.Id), models.MessageTypeNodeInactive, models.LevelError, subject, msg, nil)
|
err = models.SharedMessageDAO.CreateNodeMessage(nil, nodeconfigs.NodeRoleNode, clusterId, int64(node.Id), models.MessageTypeNodeInactive, models.LevelError, subject, msg, nil, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ func (this *NSNodeMonitorTask) monitorCluster(cluster *models.NSCluster) error {
|
|||||||
for _, node := range inactiveNodes {
|
for _, node := range inactiveNodes {
|
||||||
subject := "DNS节点\"" + node.Name + "\"已处于离线状态"
|
subject := "DNS节点\"" + node.Name + "\"已处于离线状态"
|
||||||
msg := "DNS节点\"" + node.Name + "\"已处于离线状态"
|
msg := "DNS节点\"" + node.Name + "\"已处于离线状态"
|
||||||
err = models.SharedMessageDAO.CreateNodeMessage(nil, nodeconfigs.NodeRoleDNS, clusterId, int64(node.Id), models.MessageTypeNSNodeInactive, models.LevelError, subject, msg, nil)
|
err = models.SharedMessageDAO.CreateNodeMessage(nil, nodeconfigs.NodeRoleDNS, clusterId, int64(node.Id), models.MessageTypeNSNodeInactive, models.LevelError, subject, msg, nil, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user