From b904b58de02d91031773e9e951efd295471f064a Mon Sep 17 00:00:00 2001 From: Yousong Zhou Date: Thu, 9 Jan 2020 22:21:13 +0800 Subject: [PATCH 1/3] dnsrecords: add helper methods --- pkg/compute/models/dnsrecords.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/pkg/compute/models/dnsrecords.go b/pkg/compute/models/dnsrecords.go index 57bd9b9f30..2b03f41fd5 100644 --- a/pkg/compute/models/dnsrecords.go +++ b/pkg/compute/models/dnsrecords.go @@ -375,6 +375,26 @@ func (man *SDnsRecordManager) QueryDnsIps(projectId, name, kind string) []*DnsIp return dnsIps } +func (rec *SDnsRecord) IsCNAME() bool { + return strings.HasPrefix(rec.Records, "CNAME:") +} + +func (rec *SDnsRecord) HasRecordType(typ string) bool { + for _, r := range rec.GetInfo() { + if strings.HasPrefix(r, typ+":") { + return true + } + } + return false +} + +func (rec *SDnsRecord) GetCNAME() string { + if !rec.IsCNAME() { + panic("not a cname record: " + rec.Records) + } + return rec.Records[len("CNAME:"):] +} + func (rec *SDnsRecord) GetInfo() []string { return strings.Split(rec.Records, DNS_RECORDS_SEPARATOR) } From 1c8475437377ad872d28fa1e8923eb5abb16e636 Mon Sep 17 00:00:00 2001 From: Yousong Zhou Date: Thu, 9 Jan 2020 21:24:31 +0800 Subject: [PATCH 2/3] dns: prepare for responding with A record of cname value --- pkg/dns/dns.go | 53 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/pkg/dns/dns.go b/pkg/dns/dns.go index f4cabe5058..d6e137259b 100644 --- a/pkg/dns/dns.go +++ b/pkg/dns/dns.go @@ -319,27 +319,42 @@ func (r *SRegionDNS) Name() string { } func (r *SRegionDNS) queryLocalDnsRecords(req *recordRequest) (recs []msg.Service) { - ips := models.DnsRecordManager.QueryDnsIps(req.ProjectId(), req.Name(), req.Type()) - if len(ips) == 0 { + var ( + projId = req.ProjectId() + name = req.Name() + getTtl = func(ttl int) uint32 { + if ttl == 0 { + return defaultTTL + } + return uint32(ttl) + } + rec = models.DnsRecordManager.QueryDns(projId, name) + ) + + if rec == nil { return } - for _, ip := range ips { - var s = msg.Service{} - var ttl uint32 = uint32(ip.Ttl) - if ttl == 0 { - ttl = defaultTTL + var ( + qtype = req.Type() + pref = qtype + ":" + prefLen = len(pref) + ) + for _, recStr := range rec.GetInfo() { + if !strings.HasPrefix(recStr, pref) { + continue } + val := recStr[prefLen:] if req.IsSRV() { - parts := strings.SplitN(ip.Addr, ":", 4) + parts := strings.SplitN(val, ":", 4) if len(parts) < 2 { - ylog.Errorf("Invalid SRV records: %q", ip.Addr) + ylog.Errorf("Invalid SRV records: %q", val) continue } host := parts[0] port, err := strconv.Atoi(parts[1]) if err != nil { - ylog.Errorf("SRV: invalid port: %s", ip.Addr) + ylog.Errorf("SRV: invalid port: %s", val) continue } priority := 0 @@ -348,22 +363,30 @@ func (r *SRegionDNS) queryLocalDnsRecords(req *recordRequest) (recs []msg.Servic var err error weight, err = strconv.Atoi(parts[2]) if err != nil { - ylog.Errorf("SRV: invalid weight: %s", ip.Addr) + ylog.Errorf("SRV: invalid weight: %s", val) continue } if len(parts) >= 4 { priority, err = strconv.Atoi(parts[3]) if err != nil { - ylog.Errorf("SRV: invalid priority: %s", ip.Addr) + ylog.Errorf("SRV: invalid priority: %s", val) continue } } } - s = msg.Service{Host: host, Port: port, Weight: weight, Priority: priority, TTL: ttl} + recs = append(recs, msg.Service{ + Host: host, + Port: port, + Weight: weight, + Priority: priority, + TTL: getTtl(rec.Ttl), + }) } else { - s = msg.Service{Host: ip.Addr, TTL: ttl} + recs = append(recs, msg.Service{ + Host: val, + TTL: getTtl(rec.Ttl), + }) } - recs = append(recs, s) } return } From fb9e3c9522644464fecaf3154e911e2fce63524f Mon Sep 17 00:00:00 2001 From: Yousong Zhou Date: Thu, 9 Jan 2020 23:18:37 +0800 Subject: [PATCH 3/3] dns: chain load records for cname --- pkg/dns/dns.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pkg/dns/dns.go b/pkg/dns/dns.go index d6e137259b..a7720bdb9e 100644 --- a/pkg/dns/dns.go +++ b/pkg/dns/dns.go @@ -334,6 +334,16 @@ func (r *SRegionDNS) queryLocalDnsRecords(req *recordRequest) (recs []msg.Servic if rec == nil { return } + if req.state.QType() != dns.TypeCNAME && rec.IsCNAME() { + name = rec.GetCNAME() + recs = append(recs, msg.Service{ + Host: name, + TTL: getTtl(rec.Ttl), + }) + // github.com/coredns/coredns/plugin.{A,AAAA} will call + // Services again later for these CNAME + return recs + } var ( qtype = req.Type()