Files
oneterm/backend/pkg/proto/ssh/tasks/task.go
2024-02-01 20:53:29 +08:00

94 lines
2.0 KiB
Go

package tasks
import (
"context"
"fmt"
"net"
"strconv"
"strings"
"sync"
"time"
"go.uber.org/zap"
"github.com/veops/oneterm/pkg/logger"
"github.com/veops/oneterm/pkg/proto/ssh/api"
"github.com/veops/oneterm/pkg/server/model"
)
func checkPort(server string, port int, timeout time.Duration) bool {
address := fmt.Sprintf("%s:%d", server, port)
conn, err := net.DialTimeout("tcp", address, timeout)
if err != nil {
return false
}
_ = conn.Close()
return true
}
func checkAssets(assets []*model.Asset) (result map[int]map[string]any, err error) {
type St struct {
Id int
State bool
}
result = map[int]map[string]any{}
statusChan := make(chan *St, len(assets))
var wg sync.WaitGroup
for i := range assets {
wg.Add(1)
go func(asset *model.Asset) {
defer wg.Done()
var connected bool
for _, protocol := range asset.Protocols {
tmp := strings.Split(protocol, ":")
port := 22
var er error
if len(tmp) == 2 {
port, er = strconv.Atoi(tmp[1])
if er != nil {
continue
}
}
connected = checkPort(asset.Ip, port, time.Second*5)
if connected {
break
}
}
statusChan <- &St{Id: asset.Id, State: connected}
}(assets[i])
}
wg.Wait()
for i := 0; i < len(statusChan); i++ {
v := <-statusChan
result[v.Id] = map[string]any{"connectable": v.State}
}
return
}
func LoopCheck(ctx context.Context, host, token string) {
assetServer := api.NewAssetServer(host, token)
ticker := time.NewTicker(time.Second)
for {
select {
case <-ticker.C:
ticker.Reset(time.Hour)
res, err := assetServer.AllAssets()
if err != nil {
logger.L.Error(err.Error(), zap.String("module", "LoopCheck"))
break
}
status, err := checkAssets(res)
if err != nil {
logger.L.Error(err.Error(), zap.String("module", "LoopCheck"))
}
err = assetServer.ChangeState(status)
if err != nil {
logger.L.Error(err.Error(), zap.String("module", "LoopCheck"))
}
case <-ctx.Done():
return
}
}
}