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.
357 lines
9.5 KiB
357 lines
9.5 KiB
package service |
|
|
|
import ( |
|
"context" |
|
"fmt" |
|
"strings" |
|
|
|
"go-common/app/admin/ep/merlin/model" |
|
"go-common/library/ecode" |
|
"go-common/library/log" |
|
) |
|
|
|
// GenMachines create multiple machines. |
|
func (s *Service) GenMachines(c context.Context, gmr *model.GenMachinesRequest, u string) (err error) { |
|
var ( |
|
ins []*model.CreateInstance |
|
cluster *model.Cluster |
|
hasMachine bool |
|
ms []*model.Machine |
|
) |
|
if hasMachine, err = s.dao.HasMachine(gmr.Name); err != nil { |
|
return |
|
} |
|
if hasMachine { |
|
err = ecode.MerlinDuplicateMachineNameErr |
|
return |
|
} |
|
if cluster, err = s.dao.QueryCluster(c, gmr.NetworkID); err != nil { |
|
return |
|
} |
|
if cluster == nil { |
|
err = ecode.MerlinInvalidClusterErr |
|
return |
|
} |
|
if err = cluster.Verify(); err != nil { |
|
return |
|
} |
|
pgmr := gmr.ToPaasGenMachineRequest(s.c.Paas.MachineLimitRatio) |
|
if ms, err = s.dao.InsertMachinesV2(u, gmr, pgmr); err != nil { |
|
return |
|
} |
|
|
|
//insert image log |
|
for _, m := range ms { |
|
hubImageLog := &model.HubImageLog{ |
|
UserName: u, |
|
MachineID: m.ID, |
|
ImageSrc: gmr.Image, |
|
ImageTag: "", |
|
Status: model.ImageSuccess, |
|
OperateType: model.ImageNoSnapshot, |
|
} |
|
s.dao.InsertHubImageLog(hubImageLog) |
|
} |
|
|
|
if ins, err = s.dao.GenPaasMachines(c, pgmr); err != nil { |
|
return |
|
} |
|
for _, in := range ins { |
|
if in.InstanceCreateStatus == model.CreateFailedMachineInPaas { |
|
s.dao.UpdateMachineStatusByName(model.ImmediatelyFailedMachineInMerlin, in.InstanceName) |
|
} |
|
} |
|
return |
|
} |
|
|
|
// DelMachineWhenCanBeDel Del Machine When Can Be Del. |
|
func (s *Service) DelMachineWhenCanBeDel(c context.Context, id int64, username string) (instance *model.ReleaseInstance, err error) { |
|
var ( |
|
machine *model.Machine |
|
) |
|
if machine, err = s.dao.QueryMachine(id); err != nil { |
|
return |
|
} |
|
|
|
if machine.IsCreating() { |
|
err = ecode.MerlinCanNotBeDel |
|
return |
|
} |
|
|
|
return s.DelMachine(c, id, username) |
|
|
|
} |
|
|
|
// DelMachine delete machine by giving id. |
|
func (s *Service) DelMachine(c context.Context, id int64, username string, beforeDelMachineFuncs ...model.BeforeDelMachineFunc) (instance *model.ReleaseInstance, err error) { |
|
for _, beforeDelMachine := range beforeDelMachineFuncs { |
|
if err = beforeDelMachine(c, id, username); err != nil { |
|
return |
|
} |
|
} |
|
return s.delMachineWithoutComponent(c, id, username) |
|
} |
|
|
|
func (s *Service) delMachineWithoutComponent(c context.Context, mID int64, username string) (instance *model.ReleaseInstance, err error) { |
|
var ( |
|
machine *model.Machine |
|
) |
|
if machine, err = s.dao.QueryMachine(mID); err != nil { |
|
return |
|
} |
|
machineLog := &model.MachineLog{ |
|
OperateType: model.DeleteForMachineLog, |
|
Username: username, |
|
MachineID: mID, |
|
} |
|
if instance, err = s.delMachineWithoutLog(c, machine, username); err != nil { |
|
machineLog.OperateResult = model.OperationFailedForMachineLog |
|
} else { |
|
machineLog.OperateResult = model.OperationSuccessForMachineLog |
|
} |
|
machineLog.OperateType = model.DeleteForMachineLog |
|
machineLog.Username = username |
|
machineLog.MachineID = machine.ID |
|
err = s.dao.InsertMachineLog(machineLog) |
|
return |
|
} |
|
|
|
func (s *Service) delMachineWithoutLog(c context.Context, machine *model.Machine, username string) (instance *model.ReleaseInstance, err error) { |
|
if instance, err = s.dao.DelPaasMachine(c, machine.ToPaasQueryAndDelMachineRequest()); err != nil { |
|
return |
|
} |
|
if err = s.dao.UpdateTaskStatusByMachines([]int64{machine.ID}, model.TaskDone); err != nil { |
|
return |
|
} |
|
if err = s.dao.DelMachine(machine.ID, username); err != nil { |
|
return |
|
} |
|
if err = s.SendMailDeleteMachine(username, machine); err != nil { |
|
err = nil |
|
log.Error("Send mail failed (%v)", err) |
|
} |
|
return |
|
} |
|
|
|
// QueryMachineDetail query detail information of machine. |
|
func (s *Service) QueryMachineDetail(c context.Context, mID int64) (detail model.MachineDetail, err error) { |
|
var ( |
|
machine *model.Machine |
|
passMachineDetail *model.PaasMachineDetail |
|
cluster *model.Cluster |
|
nodes []*model.MachineNode |
|
isSnapShot bool |
|
) |
|
if machine, err = s.dao.QueryMachine(mID); err != nil { |
|
return |
|
} |
|
if passMachineDetail, err = s.dao.QueryPaasMachine(c, machine.ToPaasQueryAndDelMachineRequest()); err != nil { |
|
return |
|
} |
|
if cluster, err = s.dao.QueryCluster(c, machine.NetworkID); err != nil { |
|
return |
|
} |
|
if cluster == nil { |
|
err = ecode.MerlinInvalidClusterErr |
|
return |
|
} |
|
if err = cluster.Verify(); err != nil { |
|
return |
|
} |
|
if nodes, err = s.dao.QueryMachineNodes(mID); err != nil { |
|
return |
|
} |
|
|
|
isSnapShot = strings.Contains(passMachineDetail.Image, s.c.BiliHub.MachineTagPri) |
|
|
|
detail = model.MachineDetail{ |
|
Machine: *machine, |
|
Nodes: nodes, |
|
PaasMachineDetail: passMachineDetail.ConvertUnits(), |
|
Name: machine.Name, |
|
NetworkName: cluster.Networks[0].Name, |
|
IsSnapShot: isSnapShot, |
|
} |
|
return |
|
} |
|
|
|
// QueryMachinePackages query packages of machine. |
|
func (s *Service) QueryMachinePackages(c context.Context) (mp []*model.MachinePackage, err error) { |
|
return s.dao.FindAllMachinePackages() |
|
} |
|
|
|
//QueryMachines query multiple machines and update machine status |
|
func (s *Service) QueryMachines(c context.Context, session string, qmr *model.QueryMachineRequest) (p *model.PaginateMachine, err error) { |
|
var ( |
|
machines []*model.Machine |
|
total int64 |
|
cluster *model.Cluster |
|
podNames []string |
|
treeInstance *model.TreeInstance |
|
mapping map[string]*model.TreeInstance |
|
) |
|
if mapping, err = s.QueryTreeInstanceForMerlin(c, session, &qmr.TreeNode); err != nil { |
|
return |
|
} |
|
for k := range mapping { |
|
podNames = append(podNames, k) |
|
} |
|
|
|
if total, machines, err = s.dao.QueryMachines(podNames, qmr); err != nil { |
|
return |
|
} |
|
|
|
genMachines := make([]model.GenMachine, len(machines)) |
|
for i, m := range machines { |
|
if cluster, err = s.dao.QueryCluster(c, m.NetworkID); err != nil { |
|
return |
|
} |
|
genMachines[i] = model.GenMachine{ |
|
Machine: *m, |
|
ClusterName: cluster.Name, |
|
NetworkName: cluster.Networks[0].Name, |
|
} |
|
treeInstance = mapping[m.PodName] |
|
if treeInstance != nil { |
|
genMachines[i].IP = treeInstance.InternalIP |
|
} |
|
} |
|
p = &model.PaginateMachine{ |
|
PageNum: qmr.PageNum, |
|
PageSize: qmr.PageSize, |
|
Total: total, |
|
Machines: genMachines, |
|
} |
|
return |
|
} |
|
|
|
// QueryMachineLogs query machine logs. |
|
func (s *Service) QueryMachineLogs(c context.Context, queryRequest *model.QueryMachineLogRequest) (p *model.PaginateMachineLog, err error) { |
|
var ( |
|
total int64 |
|
machineLogs []*model.AboundMachineLog |
|
) |
|
if total, machineLogs, err = s.dao.FindMachineLogs(queryRequest); err != nil { |
|
return |
|
} |
|
p = &model.PaginateMachineLog{ |
|
PageNum: queryRequest.PageNum, |
|
PageSize: queryRequest.PageSize, |
|
Total: total, |
|
MachineLogs: machineLogs, |
|
} |
|
return |
|
} |
|
|
|
// QueryMachineStatus query the status of machine. |
|
func (s *Service) QueryMachineStatus(c context.Context, machineID int64) (msr *model.MachineStatusResponse, err error) { |
|
var m *model.Machine |
|
if m, err = s.dao.QueryMachine(machineID); err != nil { |
|
return |
|
} |
|
if m.IsFailed() || m.IsDeleted() { |
|
return |
|
} |
|
if msr, err = s.verifyPassStatus(c, m, true); err != nil { |
|
return |
|
} |
|
return |
|
} |
|
|
|
// TransferMachine Transfer Machine. |
|
func (s *Service) TransferMachine(c context.Context, machineID int64, username, receiver string) (status int, err error) { |
|
var ( |
|
machine *model.Machine |
|
treePath string |
|
treeRoles []*model.TreeRole |
|
isReceiverAccessTreeNode bool |
|
) |
|
|
|
if _, err = s.dao.FindUserByUserName(receiver); err != nil { |
|
err = ecode.MerlinUserNotExist |
|
return |
|
} |
|
|
|
if machine, err = s.dao.QueryMachine(machineID); err != nil { |
|
return |
|
} |
|
|
|
// 查看接受者有无机器所在服务树节点权限 |
|
treePath = machine.BusinessUnit + "." + machine.Project + "." + machine.App |
|
|
|
if treeRoles, err = s.dao.TreeRolesAsPlatform(c, treePath); err != nil { |
|
return |
|
} |
|
|
|
for _, treeRole := range treeRoles { |
|
if treeRole.UserName == receiver { |
|
isReceiverAccessTreeNode = true |
|
break |
|
} |
|
} |
|
|
|
if !isReceiverAccessTreeNode { |
|
err = ecode.MerlinUserNoAccessTreeNode |
|
return |
|
} |
|
|
|
machineLog := &model.MachineLog{ |
|
OperateType: model.TransferForMachineLog, |
|
Username: username, |
|
MachineID: machineID, |
|
} |
|
|
|
if err = s.dao.UpdateMachineUser(machineID, receiver); err != nil { |
|
machineLog.OperateResult = model.OperationFailedForMachineLog |
|
|
|
} else { |
|
machineLog.OperateResult = model.OperationSuccessForMachineLog |
|
|
|
//send mail |
|
mailHeader := fmt.Sprintf("机器:[%s] 被用户[%s]从用户[%s]名下转移至用户[%s]", machine.Name, username, machine.Username, receiver) |
|
|
|
var sendMailUsers []string |
|
sendMailUsers = append(sendMailUsers, username) |
|
sendMailUsers = append(sendMailUsers, receiver) |
|
sendMailUsers = append(sendMailUsers, machine.Username) |
|
|
|
s.SendMailForMultiUsers(c, sendMailUsers, mailHeader) |
|
} |
|
|
|
err = s.dao.InsertMachineLog(machineLog) |
|
return |
|
} |
|
|
|
func (s *Service) verifyPassStatus(c context.Context, m *model.Machine, targetCreating bool) (msr *model.MachineStatusResponse, err error) { |
|
var ( |
|
ms *model.MachineStatus |
|
b bool |
|
status int |
|
shadow *model.MachineStatusResponse |
|
) |
|
if msr = model.InstanceMachineStatusResponse(m.Status); msr != nil { |
|
return |
|
} |
|
if ms, err = s.dao.QueryPaasMachineStatus(c, m.ToPaasQueryAndDelMachineRequest()); err != nil { |
|
return |
|
} |
|
if b, err = s.TreeMachineIsExist(c, m.PodName, m.ToTreeNode()); err != nil { |
|
return |
|
} |
|
shadow = ms.ToMachineStatusResponse() |
|
if b { |
|
shadow.SynTree = model.True |
|
} else { |
|
shadow.SynTree = model.False |
|
} |
|
if targetCreating { |
|
status = shadow.CreatingMachineStatus() |
|
} else { |
|
status = shadow.FailedMachineStatus() |
|
} |
|
if err = s.dao.UpdateMachineStatus(m.ID, status); err != nil { |
|
return |
|
} |
|
msr = shadow |
|
return |
|
}
|
|
|