You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
256 lines
5.9 KiB
256 lines
5.9 KiB
package service |
|
|
|
import ( |
|
"bytes" |
|
"context" |
|
"encoding/json" |
|
"fmt" |
|
"strings" |
|
|
|
"go-common/app/admin/main/cache/conf" |
|
"go-common/app/admin/main/cache/dao" |
|
"go-common/app/admin/main/cache/model" |
|
"go-common/library/ecode" |
|
|
|
"github.com/BurntSushi/toml" |
|
) |
|
|
|
// Service struct |
|
type Service struct { |
|
c *conf.Config |
|
dao *dao.Dao |
|
|
|
opsMcs []*model.OpsCacheMemcache |
|
opsRds []*model.OpsCacheRedis |
|
} |
|
|
|
// New init |
|
func New(c *conf.Config) (s *Service) { |
|
s = &Service{ |
|
c: c, |
|
dao: dao.New(c), |
|
} |
|
go s.loadOpsproc() |
|
return s |
|
} |
|
|
|
// Ping Service |
|
func (s *Service) Ping(c context.Context) (err error) { |
|
return |
|
} |
|
|
|
// Close Service |
|
func (s *Service) Close() { |
|
s.dao.Close() |
|
} |
|
|
|
func (s *Service) appids(c context.Context, cookie, appid string) (appids []string, err error) { |
|
msg, err := s.dao.Auth(c, cookie) |
|
if err != nil { |
|
err = ecode.AccessDenied |
|
return |
|
} |
|
tmp, ok := msg["token"] |
|
if !ok { |
|
err = ecode.NothingFound |
|
return |
|
} |
|
token, ok := tmp.(string) |
|
if !ok { |
|
err = ecode.NothingFound |
|
return |
|
} |
|
nodes, err := s.dao.Role(c, token) |
|
if err != nil { |
|
return |
|
} |
|
if appid == "" { |
|
for _, node := range nodes.Data { |
|
appids = append(appids, node.Path) |
|
} |
|
} else { |
|
for _, node := range nodes.Data { |
|
if appid == node.Path { |
|
appids = []string{appid} |
|
break |
|
} |
|
} |
|
} |
|
return |
|
} |
|
|
|
func (s *Service) treeid(c context.Context, cookie, appid string) (treeid int64, err error) { |
|
if appid == "" { |
|
err = ecode.AccessDenied |
|
return |
|
} |
|
msg, err := s.dao.Auth(c, cookie) |
|
if err != nil { |
|
err = ecode.AccessDenied |
|
return |
|
} |
|
tmp, ok := msg["token"] |
|
if !ok { |
|
err = ecode.NothingFound |
|
return |
|
} |
|
token, ok := tmp.(string) |
|
if !ok { |
|
err = ecode.NothingFound |
|
return |
|
} |
|
nodes, err := s.dao.Role(c, token) |
|
if err != nil { |
|
return |
|
} |
|
for _, node := range nodes.Data { |
|
if appid == node.Path { |
|
treeid = node.ID |
|
return |
|
} |
|
} |
|
return |
|
} |
|
|
|
// Clusters get clusters. |
|
func (s *Service) Clusters(c context.Context, req *model.ClusterReq) (resp *model.ClusterResp, err error) { |
|
appids, err := s.appids(c, req.Cookie, req.AppID) |
|
if err != nil { |
|
err = ecode.AccessDenied |
|
return |
|
} |
|
resp = new(model.ClusterResp) |
|
if len(appids) == 0 { |
|
return |
|
} |
|
if err = s.dao.DB.Where("appids in (?) AND zone=? AND type=?", appids, req.Zone, req.Type).Order("id").Offset((req.PN - 1) * req.PS).Limit(req.PS).Find(&resp.Clusters).Error; err != nil { |
|
return |
|
} |
|
var count int64 |
|
s.dao.DB.Model(&model.Cluster{}).Where("appids in (?) AND zone=? AND type=?", appids, req.Zone, req.Type).Count(&count) |
|
resp.Total = count |
|
return |
|
} |
|
|
|
// AddCluster add new cluster. |
|
func (s *Service) AddCluster(c context.Context, req *model.AddClusterReq) (resp *model.EmpResp, err error) { |
|
cluster := &model.Cluster{ |
|
Name: req.Name, |
|
Type: req.Type, |
|
AppID: req.AppID, |
|
Zone: req.Zone, |
|
HashMethod: req.HashMethod, |
|
HashDistribution: req.HashDistribution, |
|
HashTag: req.HashTag, |
|
DailTimeout: req.DailTimeout, |
|
ReadTimeout: req.ReadTimeout, |
|
WriteTimeout: req.WriteTimeout, |
|
NodeConn: req.NodeConn, |
|
ListenAddr: req.ListenAddr, |
|
ListenProto: req.ListenProto, |
|
PingFailLimit: req.PingFailLimit, |
|
PingAutoEject: req.PingAutoEject, |
|
} |
|
|
|
if req.ID == 0 { |
|
err = s.dao.DB.Create(cluster).Error |
|
} else { |
|
cluster.ID = req.ID |
|
s.dao.DB.Save(cluster) |
|
} |
|
return |
|
} |
|
|
|
// DelCluster del cluster of req id. |
|
func (s *Service) DelCluster(c context.Context, req *model.DelClusterReq) (resp *model.EmpResp, err error) { |
|
err = s.dao.DB.Exec("DELETE FROM cluster where id= ?", req.ID).Error |
|
if err != nil { |
|
return |
|
} |
|
err = s.dao.DB.Exec("DELETE FROM nodes where cid= ?", req.ID).Error |
|
return |
|
} |
|
|
|
// Cluster search cluster by appid or cluster name. |
|
func (s *Service) Cluster(c context.Context, req *model.ClusterReq) (resp []*model.Cluster, err error) { |
|
if req.Type != "" { |
|
err = s.dao.DB.Where("appids=? AND zone=? AND type=?", req.AppID, req.Zone, req.Type).Find(&resp).Error |
|
} else { |
|
err = s.dao.DB.Where("appids=? AND zone=?", req.AppID, req.Zone).Find(&resp).Error |
|
} |
|
if err != nil { |
|
return |
|
} |
|
for _, clu := range resp { |
|
err = s.dao.DB.Where("cid = ?", clu.ID).Find(&clu.Nodes).Error |
|
if err != nil { |
|
return nil, err |
|
} |
|
} |
|
return |
|
} |
|
|
|
// ModifyCluster add or del cluster nodes. |
|
func (s *Service) ModifyCluster(c context.Context, req *model.ModifyClusterReq) (resp *model.EmpResp, err error) { |
|
var nodes []*model.NodeDtl |
|
err = json.Unmarshal([]byte(req.Nodes), &nodes) |
|
if err != nil { |
|
return |
|
} |
|
var id = req.ID |
|
if req.Name != "" { |
|
var cluster = &model.Cluster{} |
|
err = s.dao.DB.Where("name = ?", req.Name).First(cluster).Error |
|
if err != nil { |
|
return |
|
} |
|
id = cluster.ID |
|
} |
|
if req.Action == 2 { |
|
var alias []string |
|
for _, ali := range nodes { |
|
alias = append(alias, ali.Alias) |
|
} |
|
//err = s.dao.DB.Delete(&nodes).Error |
|
err = s.dao.DB.Exec("DELETE FROM nodes WHERE alias in (?) ", strings.Join(alias, ",")).Error |
|
return |
|
} else if req.Action == 1 { |
|
// var nodes []*model.NodeDtl |
|
for _, node := range nodes { |
|
node.Cid = id |
|
err = s.dao.DB.Create(node).Error |
|
} |
|
return |
|
} |
|
return |
|
} |
|
|
|
// ClusterDtl get cluster detail about nodes info. |
|
func (s *Service) ClusterDtl(c context.Context, req *model.ClusterDtlReq) (resp *model.ClusterDtlResp, err error) { |
|
resp = new(model.ClusterDtlResp) |
|
err = s.dao.DB.Where("cid = ?", req.ID).Find(&resp.Nodes).Error |
|
// TODO(lintanghui):get node info |
|
return |
|
} |
|
|
|
// Toml return a toml file of cluster infos. |
|
func (s *Service) Toml(c context.Context, req *model.ClusterReq) (resp []byte, err error) { |
|
clusters, err := s.Cluster(c, req) |
|
if err != nil { |
|
return |
|
} |
|
for _, cluster := range clusters { |
|
for _, node := range cluster.Nodes { |
|
cluster.Servers = append(cluster.Servers, fmt.Sprintf("%s:%d %s", node.Addr, node.Weight, node.Alias)) |
|
} |
|
} |
|
buf := bytes.NewBuffer(resp) |
|
t := struct { |
|
Clusters []*model.Cluster `toml:"clusters"` |
|
}{ |
|
Clusters: clusters, |
|
} |
|
err = toml.NewEncoder(buf).Encode(t) |
|
resp = buf.Bytes() |
|
return |
|
}
|
|
|