diff --git a/internal/db/models/node_cluster_dao.go b/internal/db/models/node_cluster_dao.go index e0c25c6b..d27e5715 100644 --- a/internal/db/models/node_cluster_dao.go +++ b/internal/db/models/node_cluster_dao.go @@ -436,7 +436,7 @@ func (this *NodeClusterDAO) ExistClusterDNSName(tx *dbs.Tx, dnsName string, excl } // 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) error { if clusterId <= 0 { return errors.New("invalid clusterId") } @@ -445,9 +445,14 @@ func (this *NodeClusterDAO) UpdateClusterDNS(tx *dbs.Tx, clusterId int64, dnsNam op.DnsName = dnsName op.DnsDomainId = dnsDomainId + if len(cnameRecords) == 0 { + cnameRecords = []string{} + } + dnsConfig := &dnsconfigs.ClusterDNSConfig{ NodesAutoSync: nodesAutoSync, ServersAutoSync: serversAutoSync, + CNameRecords: cnameRecords, } dnsJSON, err := json.Marshal(dnsConfig) if err != nil { diff --git a/internal/db/models/node_cluster_model_ext.go b/internal/db/models/node_cluster_model_ext.go index 98b747c6..83213dc8 100644 --- a/internal/db/models/node_cluster_model_ext.go +++ b/internal/db/models/node_cluster_model_ext.go @@ -5,7 +5,7 @@ import ( "github.com/TeaOSLab/EdgeCommon/pkg/dnsconfigs" ) -// 解析DNS配置 +// DecodeDNSConfig 解析DNS配置 func (this *NodeCluster) DecodeDNSConfig() (*dnsconfigs.ClusterDNSConfig, error) { if len(this.Dns) == 0 || this.Dns == "null" { // 一定要返回一个默认的值,防止产生nil diff --git a/internal/rpc/services/service_dns_domain.go b/internal/rpc/services/service_dns_domain.go index cd94dd4f..bb33692d 100644 --- a/internal/rpc/services/service_dns_domain.go +++ b/internal/rpc/services/service_dns_domain.go @@ -402,6 +402,15 @@ func (this *DNSDomainService) findClusterDNSChanges(cluster *models.NodeCluster, tx := this.NullTx() + // 自动设置的cname记录 + var cnameRecords = []string{} + if len(cluster.Dns) > 0 { + dnsConfig, _ := cluster.DecodeDNSConfig() + if dnsConfig != nil { + cnameRecords = dnsConfig.CNameRecords + } + } + // 节点域名 nodes, err := models.SharedNodeDAO.FindAllEnabledNodesDNSWithClusterId(tx, clusterId, true) if err != nil { @@ -527,6 +536,27 @@ func (this *DNSDomainService) findClusterDNSChanges(cluster *models.NodeCluster, } } + // 自动设置的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: "", // 注意这里为空,需要在执行过程中获取默认值 + }, + }) + } else { + doneServerRecords = append(doneServerRecords, record) + } + } + // 多余的域名 for _, record := range serverRecords { if !lists.ContainsString(serverDNSNames, record.Name) { diff --git a/internal/rpc/services/service_node_cluster.go b/internal/rpc/services/service_node_cluster.go index 7f7c9fc6..44938cba 100644 --- a/internal/rpc/services/service_node_cluster.go +++ b/internal/rpc/services/service_node_cluster.go @@ -446,6 +446,7 @@ func (this *NodeClusterService) FindEnabledNodeClusterDNS(ctx context.Context, r Provider: nil, NodesAutoSync: dnsConfig.NodesAutoSync, ServersAutoSync: dnsConfig.ServersAutoSync, + CnameRecords: dnsConfig.CNameRecords, }, nil } @@ -502,6 +503,7 @@ func (this *NodeClusterService) FindEnabledNodeClusterDNS(ctx context.Context, r Provider: pbProvider, NodesAutoSync: dnsConfig.NodesAutoSync, ServersAutoSync: dnsConfig.ServersAutoSync, + CnameRecords: dnsConfig.CNameRecords, DefaultRoute: defaultRoute, }, nil } @@ -595,7 +597,7 @@ func (this *NodeClusterService) UpdateNodeClusterDNS(ctx context.Context, req *p 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) if err != nil { return nil, err } diff --git a/internal/tasks/dns_task_executor.go b/internal/tasks/dns_task_executor.go index 8d50835a..c41b145a 100644 --- a/internal/tasks/dns_task_executor.go +++ b/internal/tasks/dns_task_executor.go @@ -125,7 +125,7 @@ func (this *DNSTaskExecutor) doServer(taskId int64, serverId int64) error { return nil } - manager, domainId, domain, clusterDNSName, err := this.findDNSManager(tx, int64(serverDNS.ClusterId)) + manager, domainId, domain, clusterDNSName, _, err := this.findDNSManager(tx, int64(serverDNS.ClusterId)) if err != nil { return err } @@ -264,7 +264,7 @@ func (this *DNSTaskExecutor) doCluster(taskId int64, clusterId int64) error { }() var tx *dbs.Tx - manager, domainId, domain, clusterDNSName, err := this.findDNSManager(tx, clusterId) + manager, domainId, domain, clusterDNSName, cnameRecords, err := this.findDNSManager(tx, clusterId) if err != nil { return err } @@ -273,17 +273,24 @@ func (this *DNSTaskExecutor) doCluster(taskId int64, clusterId int64) error { return nil } + var clusterDomain = clusterDNSName + "." + domain + // 以前的节点记录 records, err := manager.GetRecords(domain) if err != nil { 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 { if (record.Type == dnstypes.RecordTypeA || record.Type == dnstypes.RecordTypeAAAA) && record.Name == clusterDNSName { key := record.Route + "@" + record.Value oldRecordsMap[key] = record } + + if record.Type == dnstypes.RecordTypeCNAME { + oldCnameRecordsMap[record.Name] = record + } } // 当前的节点记录 @@ -357,6 +364,74 @@ 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: "", // 注意这里为空,需要在执行过程中获取默认值 + }) + if err != nil { + return err + } + } + } + + // 自动设置的CNAME + 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: "", // 注意这里为空,需要在执行过程中获取默认值 + }) + 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 { err = dnsmodels.SharedDNSTaskDAO.CreateDomainTask(tx, domainId, dnsmodels.DNSTaskTypeDomainChange) @@ -436,47 +511,53 @@ func (this *DNSTaskExecutor) doDomain(taskId int64, domainId int64) error { 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, cnameRecords []string, err error) { clusterDNS, err := models.SharedNodeClusterDAO.FindClusterDNSInfo(tx, clusterId, nil) if err != nil { - return nil, 0, "", "", err + return nil, 0, "", "", nil, err } 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) if err != nil { - return nil, 0, "", "", err + return nil, 0, "", "", nil, err } if dnsDomain == nil { - return nil, 0, "", "", nil + return nil, 0, "", "", nil, nil } providerId := int64(dnsDomain.ProviderId) if providerId <= 0 { - return nil, 0, "", "", nil + return nil, 0, "", "", nil, nil } provider, err := dnsmodels.SharedDNSProviderDAO.FindEnabledDNSProvider(tx, providerId) if err != nil { - return nil, 0, "", "", err + return nil, 0, "", "", nil, err } if provider == nil { - return nil, 0, "", "", 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 + return nil, 0, "", "", nil, nil } params, err := provider.DecodeAPIParams() if err != nil { - return nil, 0, "", "", err + return nil, 0, "", "", nil, err } err = manager.Auth(params) 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.CNameRecords, nil }