mirror of
				https://github.com/coredns/coredns.git
				synced 2025-10-31 10:13:14 -04:00 
			
		
		
		
	* middleware/kubernetes: pull TXT out of parseRequest Put the TXT handling one layer higher and remove it from parseRequest. Also rename the podsvc field in there to podOrSvc. Now that it isn't used anymore for TXT record (dns-version) that was put in there. We can make this a boolean (in a future PR). Make parseRequest get an optional Zone that is from state.Zone and use that instead of its own code. Removed some tests and other smaller cleanups. Fixes #836 * add this reverse * another check * readd * Rename to kPod and kService for some clarity
		
			
				
	
	
		
			121 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			121 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package kubernetes
 | |
| 
 | |
| import (
 | |
| 	"github.com/coredns/coredns/middleware/pkg/dnsutil"
 | |
| 
 | |
| 	"github.com/miekg/dns"
 | |
| )
 | |
| 
 | |
| type recordRequest struct {
 | |
| 	// The named port from the kubernetes DNS spec, this is the service part (think _https) from a well formed
 | |
| 	// SRV record.
 | |
| 	port string
 | |
| 	// The protocol is usually _udp or _tcp (if set), and comes from the protocol part of a well formed
 | |
| 	// SRV record.
 | |
| 	protocol  string
 | |
| 	endpoint  string
 | |
| 	service   string
 | |
| 	namespace string
 | |
| 	// A each name can be for a pod or a service, here we track what we've seen. This value is true for
 | |
| 	// pods and false for services. If we ever need to extend this well use a typed value.
 | |
| 	podOrSvc   string
 | |
| 	zone       string
 | |
| 	federation string
 | |
| }
 | |
| 
 | |
| // TODO(miek): make it use request.Request.
 | |
| func (k *Kubernetes) parseRequest(lowerCasedName string, qtype uint16, zone ...string) (r recordRequest, err error) {
 | |
| 	// 3 Possible cases
 | |
| 	//   SRV Request: _port._protocol.service.namespace.[federation.]type.zone
 | |
| 	//   A Request (endpoint): endpoint.service.namespace.[federation.]type.zone
 | |
| 	//   A Request (service): service.namespace.[federation.]type.zone
 | |
| 
 | |
| 	if len(zone) == 0 {
 | |
| 		panic("parseRequest must be called with a zone")
 | |
| 	}
 | |
| 
 | |
| 	base, _ := dnsutil.TrimZone(lowerCasedName, zone[0])
 | |
| 	segs := dns.SplitDomainName(base)
 | |
| 
 | |
| 	r.zone = zone[0]
 | |
| 	r.federation, segs = k.stripFederation(segs)
 | |
| 
 | |
| 	if qtype == dns.TypeNS {
 | |
| 		return r, nil
 | |
| 	}
 | |
| 
 | |
| 	if qtype == dns.TypeA && isDefaultNS(lowerCasedName, r) {
 | |
| 		return r, nil
 | |
| 	}
 | |
| 
 | |
| 	offset := 0
 | |
| 	if qtype == dns.TypeSRV {
 | |
| 		// The kubernetes peer-finder expects queries with empty port and service to resolve
 | |
| 		// If neither is specified, treat it as a wildcard
 | |
| 		if len(segs) == 3 {
 | |
| 			r.port = "*"
 | |
| 			r.service = "*"
 | |
| 			offset = 0
 | |
| 		} else {
 | |
| 			if len(segs) != 5 {
 | |
| 				return r, errInvalidRequest
 | |
| 			}
 | |
| 			// This is a SRV style request, get first two elements as port and
 | |
| 			// protocol, stripping leading underscores if present.
 | |
| 			if segs[0][0] == '_' {
 | |
| 				r.port = segs[0][1:]
 | |
| 			} else {
 | |
| 				r.port = segs[0]
 | |
| 				if !wildcard(r.port) {
 | |
| 					return r, errInvalidRequest
 | |
| 				}
 | |
| 			}
 | |
| 			if segs[1][0] == '_' {
 | |
| 				r.protocol = segs[1][1:]
 | |
| 				if r.protocol != "tcp" && r.protocol != "udp" {
 | |
| 					return r, errInvalidRequest
 | |
| 				}
 | |
| 			} else {
 | |
| 				r.protocol = segs[1]
 | |
| 				if !wildcard(r.protocol) {
 | |
| 					return r, errInvalidRequest
 | |
| 				}
 | |
| 			}
 | |
| 			if r.port == "" || r.protocol == "" {
 | |
| 				return r, errInvalidRequest
 | |
| 			}
 | |
| 			offset = 2
 | |
| 		}
 | |
| 	}
 | |
| 	if (qtype == dns.TypeA || qtype == dns.TypeAAAA) && len(segs) == 4 {
 | |
| 		// This is an endpoint A/AAAA record request. Get first element as endpoint.
 | |
| 		r.endpoint = segs[0]
 | |
| 		offset = 1
 | |
| 	}
 | |
| 
 | |
| 	if len(segs) == (offset + 3) {
 | |
| 		r.service = segs[offset]
 | |
| 		r.namespace = segs[offset+1]
 | |
| 		r.podOrSvc = segs[offset+2]
 | |
| 
 | |
| 		return r, nil
 | |
| 	}
 | |
| 
 | |
| 	return r, errInvalidRequest
 | |
| }
 | |
| 
 | |
| // String return a string representation of r, it just returns all
 | |
| // fields concatenated with dots.
 | |
| // This is mostly used in tests.
 | |
| func (r recordRequest) String() string {
 | |
| 	s := r.port
 | |
| 	s += "." + r.protocol
 | |
| 	s += "." + r.endpoint
 | |
| 	s += "." + r.service
 | |
| 	s += "." + r.namespace
 | |
| 	s += "." + r.podOrSvc
 | |
| 	s += "." + r.zone
 | |
| 	s += "." + r.federation
 | |
| 	return s
 | |
| }
 |