diff --git a/internal/db/models/dns/dns_task_dao.go b/internal/db/models/dns/dns_task_dao.go index 959a5030..08121b00 100644 --- a/internal/db/models/dns/dns_task_dao.go +++ b/internal/db/models/dns/dns_task_dao.go @@ -12,10 +12,11 @@ import ( type DNSTaskType = string const ( - DNSTaskTypeClusterChange DNSTaskType = "clusterChange" - DNSTaskTypeNodeChange DNSTaskType = "nodeChange" - DNSTaskTypeServerChange DNSTaskType = "serverChange" - DNSTaskTypeDomainChange DNSTaskType = "domainChange" + DNSTaskTypeClusterChange DNSTaskType = "clusterChange" + DNSTaskTypeClusterRemoveDomain DNSTaskType = "clusterRemoveDomain" // 从集群中移除域名 + DNSTaskTypeNodeChange DNSTaskType = "nodeChange" + DNSTaskTypeServerChange DNSTaskType = "serverChange" + DNSTaskTypeDomainChange DNSTaskType = "domainChange" ) type DNSTaskDAO dbs.DAO @@ -40,20 +41,21 @@ func init() { } // CreateDNSTask 生成任务 -func (this *DNSTaskDAO) CreateDNSTask(tx *dbs.Tx, clusterId int64, serverId int64, nodeId int64, domainId int64, taskType string) error { +func (this *DNSTaskDAO) CreateDNSTask(tx *dbs.Tx, clusterId int64, serverId int64, nodeId int64, domainId int64, recordName string, taskType string) error { if clusterId <= 0 && serverId <= 0 && nodeId <= 0 && domainId <= 0 { return nil } err := this.Query(tx).InsertOrUpdateQuickly(maps.Map{ - "clusterId": clusterId, - "serverId": serverId, - "nodeId": nodeId, - "domainId": domainId, - "updatedAt": time.Now().Unix(), - "type": taskType, - "isDone": false, - "isOk": false, - "error": "", + "clusterId": clusterId, + "serverId": serverId, + "nodeId": nodeId, + "domainId": domainId, + "recordName": recordName, + "updatedAt": time.Now().Unix(), + "type": taskType, + "isDone": false, + "isOk": false, + "error": "", }, maps.Map{ "updatedAt": time.Now().Unix(), "isDone": false, @@ -63,24 +65,29 @@ func (this *DNSTaskDAO) CreateDNSTask(tx *dbs.Tx, clusterId int64, serverId int6 return err } -// CreateClusterTask 生成集群任务 +// CreateClusterTask 生成集群变更任务 func (this *DNSTaskDAO) CreateClusterTask(tx *dbs.Tx, clusterId int64, taskType DNSTaskType) error { - return this.CreateDNSTask(tx, clusterId, 0, 0, 0, taskType) + return this.CreateDNSTask(tx, clusterId, 0, 0, 0, "", taskType) +} + +// CreateClusterRemoveTask 生成集群删除域名任务 +func (this *DNSTaskDAO) CreateClusterRemoveTask(tx *dbs.Tx, clusterId int64, domainId int64, recordName string) error { + return this.CreateDNSTask(tx, clusterId, 0, 0, domainId, recordName, DNSTaskTypeClusterRemoveDomain) } // CreateNodeTask 生成节点任务 func (this *DNSTaskDAO) CreateNodeTask(tx *dbs.Tx, nodeId int64, taskType DNSTaskType) error { - return this.CreateDNSTask(tx, 0, 0, nodeId, 0, taskType) + return this.CreateDNSTask(tx, 0, 0, nodeId, 0, "", taskType) } // CreateServerTask 生成服务任务 func (this *DNSTaskDAO) CreateServerTask(tx *dbs.Tx, clusterId int64, serverId int64, taskType DNSTaskType) error { - return this.CreateDNSTask(tx, clusterId, serverId, 0, 0, taskType) + return this.CreateDNSTask(tx, clusterId, serverId, 0, 0, "", taskType) } // CreateDomainTask 生成域名更新任务 func (this *DNSTaskDAO) CreateDomainTask(tx *dbs.Tx, domainId int64, taskType DNSTaskType) error { - return this.CreateDNSTask(tx, 0, 0, 0, domainId, taskType) + return this.CreateDNSTask(tx, 0, 0, 0, domainId, "", taskType) } // FindAllDoingTasks 查找所有正在执行的任务 @@ -101,6 +108,7 @@ func (this *DNSTaskDAO) FindAllDoingOrErrorTasks(tx *dbs.Tx, nodeClusterId int64 } _, err = query. Where("(isDone=0 OR (isDone=1 AND isOk=0))"). + Asc("updatedAt"). AscPk(). Slice(&result). FindAll() diff --git a/internal/db/models/dns/dns_task_model.go b/internal/db/models/dns/dns_task_model.go index c67b3905..f04dd952 100644 --- a/internal/db/models/dns/dns_task_model.go +++ b/internal/db/models/dns/dns_task_model.go @@ -1,30 +1,32 @@ package dns -// DNS更新任务 +// DNSTask DNS更新任务 type DNSTask struct { - Id uint64 `field:"id"` // ID - ClusterId uint32 `field:"clusterId"` // 集群ID - ServerId uint32 `field:"serverId"` // 服务ID - NodeId uint32 `field:"nodeId"` // 节点ID - DomainId uint32 `field:"domainId"` // 域名ID - Type string `field:"type"` // 任务类型 - UpdatedAt uint64 `field:"updatedAt"` // 更新时间 - IsDone bool `field:"isDone"` // 是否已完成 - IsOk bool `field:"isOk"` // 是否成功 - Error string `field:"error"` // 错误信息 + Id uint64 `field:"id"` // ID + ClusterId uint32 `field:"clusterId"` // 集群ID + ServerId uint32 `field:"serverId"` // 服务ID + NodeId uint32 `field:"nodeId"` // 节点ID + DomainId uint32 `field:"domainId"` // 域名ID + RecordName string `field:"recordName"` // 记录名 + Type string `field:"type"` // 任务类型 + UpdatedAt uint64 `field:"updatedAt"` // 更新时间 + IsDone bool `field:"isDone"` // 是否已完成 + IsOk bool `field:"isOk"` // 是否成功 + Error string `field:"error"` // 错误信息 } type DNSTaskOperator struct { - Id interface{} // ID - ClusterId interface{} // 集群ID - ServerId interface{} // 服务ID - NodeId interface{} // 节点ID - DomainId interface{} // 域名ID - Type interface{} // 任务类型 - UpdatedAt interface{} // 更新时间 - IsDone interface{} // 是否已完成 - IsOk interface{} // 是否成功 - Error interface{} // 错误信息 + Id interface{} // ID + ClusterId interface{} // 集群ID + ServerId interface{} // 服务ID + NodeId interface{} // 节点ID + DomainId interface{} // 域名ID + RecordName interface{} // 记录名 + Type interface{} // 任务类型 + UpdatedAt interface{} // 更新时间 + IsDone interface{} // 是否已完成 + IsOk interface{} // 是否成功 + Error interface{} // 错误信息 } func NewDNSTaskOperator() *DNSTaskOperator { diff --git a/internal/db/models/node_cluster_dao.go b/internal/db/models/node_cluster_dao.go index e60f0e87..e7e2cf77 100644 --- a/internal/db/models/node_cluster_dao.go +++ b/internal/db/models/node_cluster_dao.go @@ -471,7 +471,29 @@ func (this *NodeClusterDAO) UpdateClusterDNS(tx *dbs.Tx, clusterId int64, dnsNam if clusterId <= 0 { return errors.New("invalid clusterId") } - op := NewNodeClusterOperator() + + // 删除老的域名中相关记录 + oldOne, err := this.Query(tx). + Pk(clusterId). + Result("dnsName", "dnsDomainId"). + Find() + if err != nil { + return err + } + if oldOne == nil { + return nil + } + + var oldCluster = oldOne.(*NodeCluster) + var oldDNSDomainId = int64(oldCluster.DnsDomainId) + if (oldDNSDomainId > 0 && oldDNSDomainId != dnsDomainId) || (oldCluster.DnsName != dnsName) { + err = dns.SharedDNSTaskDAO.CreateClusterRemoveTask(tx, clusterId, oldDNSDomainId, oldCluster.DnsName) + if err != nil { + return err + } + } + + var op = NewNodeClusterOperator() op.Id = clusterId op.DnsName = dnsName op.DnsDomainId = dnsDomainId @@ -480,7 +502,7 @@ func (this *NodeClusterDAO) UpdateClusterDNS(tx *dbs.Tx, clusterId int64, dnsNam cnameRecords = []string{} } - dnsConfig := &dnsconfigs.ClusterDNSConfig{ + var dnsConfig = &dnsconfigs.ClusterDNSConfig{ NodesAutoSync: nodesAutoSync, ServersAutoSync: serversAutoSync, CNameRecords: cnameRecords, diff --git a/internal/rpc/services/service_dns_task.go b/internal/rpc/services/service_dns_task.go index c94d883f..2859ee18 100644 --- a/internal/rpc/services/service_dns_task.go +++ b/internal/rpc/services/service_dns_task.go @@ -62,7 +62,7 @@ func (this *DNSTaskService) FindAllDoingDNSTasks(ctx context.Context, req *pb.Fi } switch task.Type { - case dns.DNSTaskTypeClusterChange: + case dns.DNSTaskTypeClusterChange, dns.DNSTaskTypeClusterRemoveDomain: clusterName, err := models.SharedNodeClusterDAO.FindNodeClusterName(tx, int64(task.ClusterId)) if err != nil { return nil, err diff --git a/internal/tasks/dns_task_executor.go b/internal/tasks/dns_task_executor.go index dad27244..c85a488e 100644 --- a/internal/tasks/dns_task_executor.go +++ b/internal/tasks/dns_task_executor.go @@ -87,6 +87,14 @@ func (this *DNSTaskExecutor) Loop() error { return err } } + case dnsmodels.DNSTaskTypeClusterRemoveDomain: + err = this.doClusterRemove(taskId, int64(task.ClusterId), int64(task.DomainId), task.RecordName) + if err != nil { + err = dnsmodels.SharedDNSTaskDAO.UpdateDNSTaskError(nil, taskId, err.Error()) + if err != nil { + return err + } + } case dnsmodels.DNSTaskTypeDomainChange: err = this.doDomainWithTask(taskId, int64(task.DomainId)) if err != nil { @@ -133,14 +141,14 @@ func (this *DNSTaskExecutor) doServer(taskId int64, oldClusterId int64, serverId var recordType = dnstypes.RecordTypeCNAME // 新的DNS设置 - manager, newDomainId, domain, clusterDNSName, dnsConfig, err := this.findDNSManager(tx, int64(serverDNS.ClusterId)) + manager, newDomainId, domain, clusterDNSName, dnsConfig, err := this.findDNSManagerWithClusterId(tx, int64(serverDNS.ClusterId)) if err != nil { return err } // 如果集群发生了变化,则从老的集群中删除 if oldClusterId > 0 && int64(serverDNS.ClusterId) != oldClusterId { - oldManager, oldDomainId, oldDomain, _, _, err := this.findDNSManager(tx, oldClusterId) + oldManager, oldDomainId, oldDomain, _, _, err := this.findDNSManagerWithClusterId(tx, oldClusterId) if err != nil { return err } @@ -312,7 +320,7 @@ func (this *DNSTaskExecutor) doCluster(taskId int64, clusterId int64) error { }() var tx *dbs.Tx - manager, domainId, domain, clusterDNSName, dnsConfig, err := this.findDNSManager(tx, clusterId) + manager, domainId, domain, clusterDNSName, dnsConfig, err := this.findDNSManagerWithClusterId(tx, clusterId) if err != nil { return err } @@ -505,6 +513,83 @@ func (this *DNSTaskExecutor) doCluster(taskId int64, clusterId int64) error { return nil } +func (this *DNSTaskExecutor) doClusterRemove(taskId int64, clusterId int64, domainId int64, dnsName string) error { + var isOk = false + defer func() { + if isOk { + err := dnsmodels.SharedDNSTaskDAO.UpdateDNSTaskDone(nil, taskId) + if err != nil { + remotelogs.Error("DNSTaskExecutor", err.Error()) + } + } + }() + + var tx *dbs.Tx + if len(dnsName) == 0 { + dnsInfo, err := models.SharedNodeClusterDAO.FindClusterDNSInfo(tx, clusterId, nil) + if err != nil { + return err + } + if dnsInfo == nil { + isOk = true + return nil + } + dnsName = dnsInfo.DnsName + if len(dnsName) == 0 { + isOk = true + return nil + } + } + + domain, manager, err := this.findDNSManagerWithDomainId(tx, domainId) + if err != nil { + return err + } + if domain == nil { + isOk = true + return nil + } + var fullName = dnsName + "." + domain.Name + + records, err := domain.DecodeRecords() + if err != nil { + return err + } + + var isChanged bool + + for _, record := range records { + // node A + if (record.Type == dnstypes.RecordTypeA || record.Type == dnstypes.RecordTypeAAAA) && record.Name == dnsName { + err = manager.DeleteRecord(domain.Name, record) + if err != nil { + return err + } + isChanged = true + } + + // server CNAME + if record.Type == dnstypes.RecordTypeCNAME && strings.TrimRight(record.Value, ".") == fullName { + err = manager.DeleteRecord(domain.Name, record) + if err != nil { + return err + } + isChanged = true + } + } + + if isChanged { + err = dnsmodels.SharedDNSTaskDAO.CreateDomainTask(tx, domainId, dnsmodels.DNSTaskTypeDomainChange) + if err != nil { + return err + } + } + + isOk = true + + return nil +} + func (this *DNSTaskExecutor) doDomain(domainId int64) error { return this.doDomainWithTask(0, domainId) } @@ -577,7 +662,7 @@ func (this *DNSTaskExecutor) doDomainWithTask(taskId int64, domainId int64) erro return nil } -func (this *DNSTaskExecutor) findDNSManager(tx *dbs.Tx, clusterId int64) (manager dnsclients.ProviderInterface, domainId int64, domain string, clusterDNSName string, dnsConfig *dnsconfigs.ClusterDNSConfig, err error) { +func (this *DNSTaskExecutor) findDNSManagerWithClusterId(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) if err != nil { return nil, 0, "", "", nil, err @@ -591,39 +676,51 @@ func (this *DNSTaskExecutor) findDNSManager(tx *dbs.Tx, clusterId int64) (manage return nil, 0, "", "", nil, err } - dnsDomain, err := dnsmodels.SharedDNSDomainDAO.FindEnabledDNSDomain(tx, int64(clusterDNS.DnsDomainId), nil) + dnsDomain, manager, err := this.findDNSManagerWithDomainId(tx, int64(clusterDNS.DnsDomainId)) if err != nil { return nil, 0, "", "", nil, err } + if dnsDomain == nil { - return nil, 0, "", "", nil, nil - } - providerId := int64(dnsDomain.ProviderId) - if providerId <= 0 { - return nil, 0, "", "", nil, nil - } - - provider, err := dnsmodels.SharedDNSProviderDAO.FindEnabledDNSProvider(tx, providerId) - if err != nil { - return nil, 0, "", "", nil, err - } - if provider == nil { - return nil, 0, "", "", nil, nil - } - - manager = dnsclients.FindProvider(provider.Type) - if manager == nil { - remotelogs.Error("DNSTaskExecutor", "unsupported dns provider type '"+provider.Type+"'") - return nil, 0, "", "", nil, nil - } - params, err := provider.DecodeAPIParams() - if err != nil { - return nil, 0, "", "", nil, err - } - err = manager.Auth(params) - if err != nil { - return nil, 0, "", "", nil, err + return nil, 0, "", clusterDNS.DnsName, dnsConfig, nil } return manager, int64(dnsDomain.Id), dnsDomain.Name, clusterDNS.DnsName, dnsConfig, nil } + +func (this *DNSTaskExecutor) findDNSManagerWithDomainId(tx *dbs.Tx, domainId int64) (*dnsmodels.DNSDomain, dnsclients.ProviderInterface, error) { + dnsDomain, err := dnsmodels.SharedDNSDomainDAO.FindEnabledDNSDomain(tx, domainId, nil) + if err != nil { + return nil, nil, err + } + if dnsDomain == nil { + return nil, nil, nil + } + providerId := int64(dnsDomain.ProviderId) + if providerId <= 0 { + return nil, nil, nil + } + + provider, err := dnsmodels.SharedDNSProviderDAO.FindEnabledDNSProvider(tx, providerId) + if err != nil { + return nil, nil, err + } + if provider == nil { + return nil, nil, nil + } + + var manager = dnsclients.FindProvider(provider.Type) + if manager == nil { + remotelogs.Error("DNSTaskExecutor", "unsupported dns provider type '"+provider.Type+"'") + return nil, nil, nil + } + params, err := provider.DecodeAPIParams() + if err != nil { + return nil, nil, err + } + err = manager.Auth(params) + if err != nil { + return nil, nil, err + } + return dnsDomain, manager, nil +}