2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Package kubernetes provides the kubernetes backend. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								package   kubernetes 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import   ( 
  
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 "errors" 
  
						 
					
						
							
								
									
										
										
										
											2016-10-30 15:54:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 "fmt" 
  
						 
					
						
							
								
									
										
										
										
											2016-07-18 10:47:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 "log" 
  
						 
					
						
							
								
									
										
										
										
											2017-02-01 12:56:10 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 "net" 
  
						 
					
						
							
								
									
										
										
										
											2016-09-23 09:48:11 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 "strings" 
  
						 
					
						
							
								
									
										
										
										
											2017-08-10 17:14:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 "sync/atomic" 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									 "time" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-21 22:51:47 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 "github.com/coredns/coredns/middleware" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 "github.com/coredns/coredns/middleware/etcd/msg" 
  
						 
					
						
							
								
									
										
										
										
											2017-08-10 01:08:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 "github.com/coredns/coredns/middleware/pkg/dnsutil" 
  
						 
					
						
							
								
									
										
										
										
											2017-08-10 17:14:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 "github.com/coredns/coredns/middleware/pkg/healthcheck" 
  
						 
					
						
							
								
									
										
										
										
											2017-02-21 22:51:47 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 dnsstrings   "github.com/coredns/coredns/middleware/pkg/strings" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 "github.com/coredns/coredns/middleware/proxy" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 "github.com/coredns/coredns/request" 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 "github.com/miekg/dns" 
  
						 
					
						
							
								
									
										
										
										
											2016-11-05 15:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 "k8s.io/client-go/1.5/kubernetes" 
  
						 
					
						
							
								
									
										
										
										
											2016-11-05 07:57:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 "k8s.io/client-go/1.5/pkg/api" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 unversionedapi   "k8s.io/client-go/1.5/pkg/api/unversioned" 
  
						 
					
						
							
								
									
										
										
										
											2016-11-05 15:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 "k8s.io/client-go/1.5/pkg/labels" 
  
						 
					
						
							
								
									
										
										
										
											2016-11-05 07:57:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 "k8s.io/client-go/1.5/rest" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 "k8s.io/client-go/1.5/tools/clientcmd" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 clientcmdapi   "k8s.io/client-go/1.5/tools/clientcmd/api" 
  
						 
					
						
							
								
									
										
										
										
											2016-08-05 18:19:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 09:14:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Kubernetes implements a middleware that connects to a Kubernetes cluster. 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								type   Kubernetes   struct   { 
  
						 
					
						
							
								
									
										
										
										
											2017-06-28 18:44:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 Next            middleware . Handler 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 Zones           [ ] string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 Proxy           proxy . Proxy   // Proxy for looking up names during the resolution process 
  
						 
					
						
							
								
									
										
										
										
											2017-08-10 17:14:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 APIServerList   [ ] string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 APIProxy        * apiProxy 
  
						 
					
						
							
								
									
										
										
										
											2017-06-28 18:44:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 APICertAuth     string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 APIClientCert   string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 APIClientKey    string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 APIConn         dnsController 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 ResyncPeriod    time . Duration 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 Namespaces      [ ] string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 LabelSelector   * unversionedapi . LabelSelector 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 Selector        * labels . Selector 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 PodMode         string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 ReverseCidrs    [ ] net . IPNet 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 Fallthrough     bool 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-11 16:21:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 primaryZoneIndex     int 
  
						 
					
						
							
								
									
										
										
										
											2017-08-07 07:09:32 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 interfaceAddrsFunc   func ( )   net . IP 
  
						 
					
						
							
								
									
										
										
										
											2017-08-10 19:26:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 autoPathSearch       [ ] string   // Local search path from /etc/resolv.conf. Needed for autopath. 
  
						 
					
						
							
								
									
										
										
										
											2017-06-28 18:44:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-11 16:23:10 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const   ( 
  
						 
					
						
							
								
									
										
										
										
											2017-01-29 12:06:26 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 // PodModeDisabled is the default value where pod requests are ignored 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 PodModeDisabled   =   "disabled" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 // PodModeVerified is where Pod requests are answered only if they exist 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 PodModeVerified   =   "verified" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 // PodModeInsecure is where pod requests are answered without verfying they exist 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 PodModeInsecure   =   "insecure" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 // DNSSchemaVersion is the schema version: https://github.com/kubernetes/dns/blob/master/docs/specification.md 
  
						 
					
						
							
								
									
										
										
										
											2017-05-30 08:20:39 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 DNSSchemaVersion   =   "1.0.1" 
  
						 
					
						
							
								
									
										
										
										
											2017-01-11 16:23:10 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								type   endpoint   struct   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 addr   api . EndpointAddress 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 port   api . EndpointPort 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-10 01:08:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// kService is a service as retrieved via the k8s API. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type   kService   struct   { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 name        string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 namespace   string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 addr        string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 ports       [ ] api . ServicePort 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 endpoints   [ ] endpoint 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-10 01:08:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// kPod is a pod as retrieved via the k8s API. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type   kPod   struct   { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-11 16:23:10 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 name        string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 namespace   string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 addr        string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-03 09:03:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var   ( 
  
						 
					
						
							
								
									
										
										
										
											2017-08-06 05:54:24 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 errNoItems          =   errors . New ( "no items found" ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 errNsNotExposed     =   errors . New ( "namespace is not exposed" ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 errInvalidRequest   =   errors . New ( "invalid query name" ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 errAPIBadPodType    =   errors . New ( "expected type *api.Pod" ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 errPodsDisabled     =   errors . New ( "pod records disabled" ) 
  
						 
					
						
							
								
									
										
										
										
											2017-08-03 09:03:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								) 
  
						 
					
						
							
								
									
										
										
										
											2016-11-10 16:24:06 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 15:54:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Services implements the ServiceBackend interface. 
  
						 
					
						
							
								
									
										
										
										
											2017-05-22 16:05:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   Services ( state   request . Request ,   exact   bool ,   opt   middleware . Options )   ( svcs   [ ] msg . Service ,   debug   [ ] msg . Service ,   err   error )   { 
  
						 
					
						
							
								
									
										
										
										
											2017-08-10 01:08:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 // We're looking again at types, which we've already done in ServeDNS, but there are some types k8s just can't answer. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 switch   state . QType ( )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 case   dns . TypeTXT : 
  
						 
					
						
							
								
									
										
										
										
											2017-08-10 22:14:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 // 1 label + zone, label must be "dns-version". 
  
						 
					
						
							
								
									
										
										
										
											2017-08-10 01:08:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 t ,   err   :=   dnsutil . TrimZone ( state . Name ( ) ,   state . Zone ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 if   err   !=   nil   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   nil ,   nil ,   err 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 segs   :=   dns . SplitDomainName ( t ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 if   len ( segs )   !=   1   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   nil ,   nil ,   errors . New ( "servfail" ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 if   segs [ 0 ]   !=   "dns-version"   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   nil ,   nil ,   errInvalidRequest 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 svc   :=   msg . Service { Text :   DNSSchemaVersion ,   TTL :   28800 ,   Key :   msg . Path ( state . QName ( ) ,   "coredns" ) } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   [ ] msg . Service { svc } ,   nil ,   nil 
  
						 
					
						
							
								
									
										
										
										
											2017-08-10 22:14:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 case   dns . TypeNS : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 // We can only get here if the qname equal the zone, see ServeDNS in handler.go. 
  
						 
					
						
							
								
									
										
										
										
											2017-08-10 23:13:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 ns   :=   k . nsAddr ( ) 
  
						 
					
						
							
								
									
										
										
										
											2017-08-10 22:14:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 svc   :=   msg . Service { Host :   ns . A . String ( ) ,   Key :   msg . Path ( state . QName ( ) ,   "coredns" ) } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   [ ] msg . Service { svc } ,   nil ,   nil 
  
						 
					
						
							
								
									
										
										
										
											2017-08-10 01:08:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-11 12:12:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 r ,   e   :=   k . parseRequest ( state ) 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 if   e   !=   nil   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   nil ,   nil ,   e 
  
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
									
										
										
										
											2017-08-10 01:08:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 switch   state . QType ( )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 case   dns . TypeA ,   dns . TypeAAAA ,   dns . TypeCNAME : 
  
						 
					
						
							
								
									
										
										
										
											2017-05-22 16:05:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 if   state . Type ( )   ==   "A"   &&   isDefaultNS ( state . Name ( ) ,   r )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 // If this is an A request for "ns.dns", respond with a "fake" record for coredns. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 // SOA records always use this hardcoded name 
  
						 
					
						
							
								
									
										
										
										
											2017-08-11 08:34:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 ns   :=   k . nsAddr ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 svc   :=   msg . Service { Host :   ns . A . String ( ) ,   Key :   msg . Path ( state . QName ( ) ,   "coredns" ) } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   [ ] msg . Service { svc } ,   nil ,   nil 
  
						 
					
						
							
								
									
										
										
										
											2017-05-22 16:05:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
									
										
										
										
											2017-07-01 18:19:57 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 s ,   e   :=   k . Entries ( r ) 
  
						 
					
						
							
								
									
										
										
										
											2017-07-20 08:19:29 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 if   state . QType ( )   ==   dns . TypeAAAA   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 // AAAA not implemented 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   nil ,   nil ,   e 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 14:37:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 return   s ,   nil ,   e   // Haven't implemented debug queries yet. 
  
						 
					
						
							
								
									
										
										
										
											2017-08-10 01:08:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 case   dns . TypeSRV : 
  
						 
					
						
							
								
									
										
										
										
											2017-07-01 18:19:57 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 s ,   e   :=   k . Entries ( r ) 
  
						 
					
						
							
								
									
										
										
										
											2017-05-30 08:20:39 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 // SRV for external services is not yet implemented, so remove those records 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 noext   :=   [ ] msg . Service { } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 for   _ ,   svc   :=   range   s   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 if   t ,   _   :=   svc . HostType ( ) ;   t   !=   dns . TypeCNAME   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 noext   =   append ( noext ,   svc ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   noext ,   nil ,   e 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 14:37:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 return   nil ,   nil ,   nil 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-11 16:21:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// primaryZone will return the first non-reverse zone being handled by this middleware 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   primaryZone ( )   string   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 return   k . Zones [ k . primaryZoneIndex ] 
  
						 
					
						
							
								
									
										
										
										
											2016-11-14 19:31:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 15:54:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Lookup implements the ServiceBackend interface. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   Lookup ( state   request . Request ,   name   string ,   typ   uint16 )   ( * dns . Msg ,   error )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 return   k . Proxy . Lookup ( state ,   name ,   typ ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// IsNameError implements the ServiceBackend interface. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   IsNameError ( err   error )   bool   { 
  
						 
					
						
							
								
									
										
										
										
											2017-08-10 22:14:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 return   err   ==   errNoItems   ||   err   ==   errNsNotExposed   ||   err   ==   errInvalidRequest 
  
						 
					
						
							
								
									
										
										
										
											2016-10-30 15:54:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Debug implements the ServiceBackend interface. 
  
						 
					
						
							
								
									
										
										
										
											2017-03-06 11:42:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   Debug ( )   string   {   return   "debug"   } 
  
						 
					
						
							
								
									
										
										
										
											2016-10-30 15:54:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-05 07:57:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   getClientConfig ( )   ( * rest . Config ,   error )   { 
  
						 
					
						
							
								
									
										
										
										
											2017-06-23 18:02:45 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 loadingRules   :=   & clientcmd . ClientConfigLoadingRules { } 
  
						 
					
						
							
								
									
										
										
										
											2016-08-05 18:19:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 overrides   :=   & clientcmd . ConfigOverrides { } 
  
						 
					
						
							
								
									
										
										
										
											2016-09-23 18:07:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 clusterinfo   :=   clientcmdapi . Cluster { } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 authinfo   :=   clientcmdapi . AuthInfo { } 
  
						 
					
						
							
								
									
										
										
										
											2017-08-10 17:14:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 if   len ( k . APIServerList )   >   0   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 endpoint   :=   k . APIServerList [ 0 ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 if   len ( k . APIServerList )   >   1   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 // Use a random port for api proxy, will get the value later through listener.Addr() 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 listener ,   err   :=   net . Listen ( "tcp" ,   "127.0.0.1:0" ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 if   err   !=   nil   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 return   nil ,   fmt . Errorf ( "failed to create kubernetes api proxy: %v" ,   err ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 k . APIProxy   =   & apiProxy { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 listener :   listener , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 handler :   proxyHandler { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 HealthCheck :   healthcheck . HealthCheck { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 FailTimeout :   3   *   time . Second , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 MaxFails :      1 , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 Future :        10   *   time . Second , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 Path :          "/" , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 Interval :      5   *   time . Second , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 } , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 } , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 k . APIProxy . handler . Hosts   =   make ( [ ] * healthcheck . UpstreamHost ,   len ( k . APIServerList ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 for   i ,   entry   :=   range   k . APIServerList   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 uh   :=   & healthcheck . UpstreamHost { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 Name :   strings . TrimPrefix ( entry ,   "http://" ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 CheckDown :   func ( upstream   * proxyHandler )   healthcheck . UpstreamHostDownFunc   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 return   func ( uh   * healthcheck . UpstreamHost )   bool   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															 down   :=   false 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															 uh . CheckMu . Lock ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															 until   :=   uh . OkUntil 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															 uh . CheckMu . Unlock ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															 if   ! until . IsZero ( )   &&   time . Now ( ) . After ( until )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																 down   =   true 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															 fails   :=   atomic . LoadInt32 ( & uh . Fails ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															 if   fails   >=   upstream . MaxFails   &&   upstream . MaxFails   !=   0   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																 down   =   true 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															 return   down 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 } ( & k . APIProxy . handler ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 k . APIProxy . handler . Hosts [ i ]   =   uh 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 k . APIProxy . Handler   =   & k . APIProxy . handler 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 // Find the random port used for api proxy 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 endpoint   =   fmt . Sprintf ( "http://%s" ,   listener . Addr ( ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 clusterinfo . Server   =   endpoint 
  
						 
					
						
							
								
									
										
										
										
											2016-10-19 17:04:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 }   else   { 
  
						 
					
						
							
								
									
										
										
										
											2016-11-05 07:57:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 cc ,   err   :=   rest . InClusterConfig ( ) 
  
						 
					
						
							
								
									
										
										
										
											2016-10-19 17:04:35 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 if   err   !=   nil   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   nil ,   err 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   cc ,   err 
  
						 
					
						
							
								
									
										
										
										
											2016-09-23 18:07:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 if   len ( k . APICertAuth )   >   0   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 clusterinfo . CertificateAuthority   =   k . APICertAuth 
  
						 
					
						
							
								
									
										
										
										
											2016-08-05 18:19:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
									
										
										
										
											2016-09-23 18:07:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 if   len ( k . APIClientCert )   >   0   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 authinfo . ClientCertificate   =   k . APIClientCert 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 if   len ( k . APIClientKey )   >   0   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 authinfo . ClientKey   =   k . APIClientKey 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 overrides . ClusterInfo   =   clusterinfo 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 overrides . AuthInfo   =   authinfo 
  
						 
					
						
							
								
									
										
										
										
											2016-08-05 18:19:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 clientConfig   :=   clientcmd . NewNonInteractiveDeferredLoadingClientConfig ( loadingRules ,   overrides ) 
  
						 
					
						
							
								
									
										
										
										
											2016-09-23 18:07:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 return   clientConfig . ClientConfig ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// InitKubeCache initializes a new Kubernetes cache. 
  
						 
					
						
							
								
									
										
										
										
											2017-05-22 16:05:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   InitKubeCache ( )   ( err   error )   { 
  
						 
					
						
							
								
									
										
										
										
											2016-09-23 18:07:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 config ,   err   :=   k . getClientConfig ( ) 
  
						 
					
						
							
								
									
										
										
										
											2016-08-05 18:19:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 if   err   !=   nil   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   err 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-05 07:57:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 kubeClient ,   err   :=   kubernetes . NewForConfig ( config ) 
  
						 
					
						
							
								
									
										
										
										
											2016-08-05 18:19:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 if   err   !=   nil   { 
  
						 
					
						
							
								
									
										
										
										
											2017-06-14 09:37:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 return   fmt . Errorf ( "failed to create kubernetes notification controller: %v" ,   err ) 
  
						 
					
						
							
								
									
										
										
										
											2016-08-05 18:19:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
									
										
										
										
											2016-10-30 15:54:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 if   k . LabelSelector   !=   nil   { 
  
						 
					
						
							
								
									
										
										
										
											2016-08-19 17:14:17 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 var   selector   labels . Selector 
  
						 
					
						
							
								
									
										
										
										
											2016-08-22 23:15:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 selector ,   err   =   unversionedapi . LabelSelectorAsSelector ( k . LabelSelector ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 k . Selector   =   & selector 
  
						 
					
						
							
								
									
										
										
										
											2016-08-19 17:14:17 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 if   err   !=   nil   { 
  
						 
					
						
							
								
									
										
										
										
											2017-06-14 09:37:10 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 return   fmt . Errorf ( "unable to create Selector for LabelSelector '%s'.Error was: %s" ,   k . LabelSelector ,   err ) 
  
						 
					
						
							
								
									
										
										
										
											2016-08-19 17:14:17 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
									
										
										
										
											2016-10-30 15:54:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-04-30 03:48:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 if   k . LabelSelector   !=   nil   { 
  
						 
					
						
							
								
									
										
										
										
											2016-08-22 23:15:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 log . Printf ( "[INFO] Kubernetes middleware configured with the label selector '%s'. Only kubernetes objects matching this label selector will be exposed." ,   unversionedapi . FormatLabelSelector ( k . LabelSelector ) ) 
  
						 
					
						
							
								
									
										
										
										
											2016-08-12 20:44:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
									
										
										
										
											2016-10-30 15:54:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-14 09:38:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 opts   :=   dnsControlOpts { 
  
						 
					
						
							
								
									
										
										
										
											2017-08-09 03:13:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 initPodCache :   k . PodMode   ==   PodModeVerified , 
  
						 
					
						
							
								
									
										
										
										
											2017-06-14 09:38:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 k . APIConn   =   newdnsController ( kubeClient ,   k . ResyncPeriod ,   k . Selector ,   opts ) 
  
						 
					
						
							
								
									
										
										
										
											2016-08-22 23:15:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-05 18:19:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 return   err 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-07-01 18:19:57 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Records not implemented, see Entries(). 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   Records ( name   string ,   exact   bool )   ( [ ] msg . Service ,   error )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 return   nil ,   fmt . Errorf ( "NOOP" ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Entries looks up services in kubernetes. If exact is true, it will lookup 
  
						 
					
						
							
								
									
										
										
										
											2016-10-30 15:54:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// just this name. This is used when find matches when completing SRV lookups 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// for instance. 
  
						 
					
						
							
								
									
										
										
										
											2017-07-01 18:19:57 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   Entries ( r   recordRequest )   ( [ ] msg . Service ,   error )   { 
  
						 
					
						
							
								
									
										
										
										
											2016-07-14 14:50:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 // Abort if the namespace does not contain a wildcard, and namespace is not published per CoreFile 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 // Case where namespace contains a wildcard is handled in Get(...) method. 
  
						 
					
						
							
								
									
										
										
										
											2017-08-05 12:29:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 if   ( ! wildcard ( r . namespace ) )   &&   ( len ( k . Namespaces )   >   0 )   &&   ( ! dnsstrings . StringInSlice ( r . namespace ,   k . Namespaces ) )   { 
  
						 
					
						
							
								
									
										
										
										
											2016-11-11 16:56:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 return   nil ,   errNsNotExposed 
  
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
									
										
										
										
											2017-01-29 12:06:26 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 services ,   pods ,   err   :=   k . get ( r ) 
  
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 if   err   !=   nil   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   nil ,   err 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
									
										
										
										
											2017-01-11 16:23:10 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 if   len ( services )   ==   0   &&   len ( pods )   ==   0   { 
  
						 
					
						
							
								
									
										
										
										
											2016-11-11 16:56:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 return   nil ,   errNoItems 
  
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-14 09:38:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 records   :=   k . getRecordsForK8sItems ( services ,   pods ,   r ) 
  
						 
					
						
							
								
									
										
										
										
											2017-06-14 10:29:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 return   records ,   nil 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   endpointHostname ( addr   api . EndpointAddress )   string   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 if   addr . Hostname   !=   ""   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   strings . ToLower ( addr . Hostname ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 if   strings . Contains ( addr . IP ,   "." )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   strings . Replace ( addr . IP ,   "." ,   "-" ,   - 1 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 if   strings . Contains ( addr . IP ,   ":" )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   strings . ToLower ( strings . Replace ( addr . IP ,   ":" ,   "-" ,   - 1 ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 return   "" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-10 01:08:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   getRecordsForK8sItems ( services   [ ] kService ,   pods   [ ] kPod ,   r   recordRequest )   ( records   [ ] msg . Service )   { 
  
						 
					
						
							
								
									
										
										
										
											2017-06-14 09:38:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 zonePath   :=   msg . Path ( r . zone ,   "coredns" ) 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-11 16:23:10 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 for   _ ,   svc   :=   range   services   { 
  
						 
					
						
							
								
									
										
										
										
											2017-06-14 10:29:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 if   svc . addr   ==   api . ClusterIPNone   ||   len ( svc . endpoints )   >   0   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 // This is a headless service or endpoints are present, create records for each endpoint 
  
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 for   _ ,   ep   :=   range   svc . endpoints   { 
  
						 
					
						
							
								
									
										
										
										
											2017-08-14 08:49:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 s   :=   msg . Service { Host :   ep . addr . IP ,   Port :   int ( ep . port . Port ) } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 s . Key   =   strings . Join ( [ ] string { zonePath ,   Svc ,   svc . namespace ,   svc . name ,   endpointHostname ( ep . addr ) } ,   "/" ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 records   =   append ( records ,   s ) 
  
						 
					
						
							
								
									
										
										
										
											2016-12-02 17:50:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
									
										
										
										
											2017-08-05 12:29:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
									
										
										
										
											2017-06-14 09:38:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-05 12:29:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 // Create records for each exposed port... 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 for   _ ,   p   :=   range   svc . ports   { 
  
						 
					
						
							
								
									
										
										
										
											2017-08-14 08:49:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 s   :=   msg . Service { Host :   svc . addr ,   Port :   int ( p . Port ) } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 s . Key   =   strings . Join ( [ ] string { zonePath ,   Svc ,   svc . namespace ,   svc . name } ,   "/" ) 
  
						 
					
						
							
								
									
										
										
										
											2017-05-30 08:20:39 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-05 12:29:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 records   =   append ( records ,   s ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 // If the addr is not an IP (i.e. an external service), add the record ... 
  
						 
					
						
							
								
									
										
										
										
											2017-08-14 08:49:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 s   :=   msg . Service { Key :   strings . Join ( [ ] string { zonePath ,   Svc ,   svc . namespace ,   svc . name } ,   "/" ) ,   Host :   svc . addr } 
  
						 
					
						
							
								
									
										
										
										
											2017-08-05 12:29:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 if   t ,   _   :=   s . HostType ( ) ;   t   ==   dns . TypeCNAME   { 
  
						 
					
						
							
								
									
										
										
										
											2017-08-14 08:49:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 s . Key   =   strings . Join ( [ ] string { zonePath ,   Svc ,   svc . namespace ,   svc . name } ,   "/" ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-05 12:29:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 records   =   append ( records ,   s ) 
  
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-11 16:23:10 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 for   _ ,   p   :=   range   pods   { 
  
						 
					
						
							
								
									
										
										
										
											2017-08-14 08:49:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 s   :=   msg . Service { Key :   strings . Join ( [ ] string { zonePath ,   Pod ,   p . namespace ,   p . name } ,   "/" ) ,   Host :   p . addr } 
  
						 
					
						
							
								
									
										
										
										
											2017-01-11 16:23:10 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 records   =   append ( records ,   s ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 return   records 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-10 01:08:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   findPods ( namespace ,   podname   string )   ( pods   [ ] kPod ,   err   error )   { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-11 16:23:10 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 if   k . PodMode   ==   PodModeDisabled   { 
  
						 
					
						
							
								
									
										
										
										
											2017-05-22 16:05:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 return   pods ,   errPodsDisabled 
  
						 
					
						
							
								
									
										
										
										
											2017-01-11 16:23:10 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 var   ip   string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 if   strings . Count ( podname ,   "-" )   ==   3   &&   ! strings . Contains ( podname ,   "--" )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 ip   =   strings . Replace ( podname ,   "-" ,   "." ,   - 1 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 }   else   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 ip   =   strings . Replace ( podname ,   "-" ,   ":" ,   - 1 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 if   k . PodMode   ==   PodModeInsecure   { 
  
						 
					
						
							
								
									
										
										
										
											2017-08-10 01:08:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 s   :=   kPod { name :   podname ,   namespace :   namespace ,   addr :   ip } 
  
						 
					
						
							
								
									
										
										
										
											2017-01-11 16:23:10 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 pods   =   append ( pods ,   s ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   pods ,   nil 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-20 02:22:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 // PodModeVerified 
  
						 
					
						
							
								
									
										
										
										
											2017-05-22 16:05:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 objList   :=   k . APIConn . PodIndex ( ip ) 
  
						 
					
						
							
								
									
										
										
										
											2017-01-11 16:23:10 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-05 12:29:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 nsWildcard   :=   wildcard ( namespace ) 
  
						 
					
						
							
								
									
										
										
										
											2017-01-20 02:22:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 for   _ ,   o   :=   range   objList   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 p ,   ok   :=   o . ( * api . Pod ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 if   ! ok   { 
  
						 
					
						
							
								
									
										
										
										
											2017-05-25 12:08:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 return   nil ,   errAPIBadPodType 
  
						 
					
						
							
								
									
										
										
										
											2017-01-20 02:22:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 // If namespace has a wildcard, filter results against Corefile namespace list. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 if   nsWildcard   &&   ( len ( k . Namespaces )   >   0 )   &&   ( ! dnsstrings . StringInSlice ( p . Namespace ,   k . Namespaces ) )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 // check for matching ip and namespace 
  
						 
					
						
							
								
									
										
										
										
											2017-08-05 12:29:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 if   ip   ==   p . Status . PodIP   &&   match ( namespace ,   p . Namespace ,   nsWildcard )   { 
  
						 
					
						
							
								
									
										
										
										
											2017-08-10 01:08:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 s   :=   kPod { name :   podname ,   namespace :   namespace ,   addr :   ip } 
  
						 
					
						
							
								
									
										
										
										
											2017-01-20 02:22:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 pods   =   append ( pods ,   s ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   pods ,   nil 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 return   pods ,   nil 
  
						 
					
						
							
								
									
										
										
										
											2017-01-11 16:23:10 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-29 12:06:26 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// get retrieves matching data from the cache. 
  
						 
					
						
							
								
									
										
										
										
											2017-08-10 01:08:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   get ( r   recordRequest )   ( services   [ ] kService ,   pods   [ ] kPod ,   err   error )   { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 switch   { 
  
						 
					
						
							
								
									
										
										
										
											2017-08-10 01:08:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 case   r . podOrSvc   ==   Pod : 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 pods ,   err   =   k . findPods ( r . namespace ,   r . service ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   nil ,   pods ,   err 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 default : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 services ,   err   =   k . findServices ( r ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   services ,   nil ,   err 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-10 01:08:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   findServices ( r   recordRequest )   ( [ ] kService ,   error )   { 
  
						 
					
						
							
								
									
										
										
										
											2016-10-12 12:46:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 serviceList   :=   k . APIConn . ServiceList ( ) 
  
						 
					
						
							
								
									
										
										
										
											2017-08-10 01:08:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 var   resultItems   [ ] kService 
  
						 
					
						
							
								
									
										
										
										
											2016-07-14 14:50:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-05 12:29:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 nsWildcard   :=   wildcard ( r . namespace ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 serviceWildcard   :=   wildcard ( r . service ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 portWildcard   :=   wildcard ( r . port )   ||   r . port   ==   "" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 protocolWildcard   :=   wildcard ( r . protocol )   ||   r . protocol   ==   "" 
  
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 for   _ ,   svc   :=   range   serviceList   { 
  
						 
					
						
							
								
									
										
										
										
											2017-08-05 12:29:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 if   ! ( match ( r . namespace ,   svc . Namespace ,   nsWildcard )   &&   match ( r . service ,   svc . Name ,   serviceWildcard ) )   { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 // If namespace has a wildcard, filter results against Corefile namespace list. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 // (Namespaces without a wildcard were filtered before the call to this function.) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 if   nsWildcard   &&   ( len ( k . Namespaces )   >   0 )   &&   ( ! dnsstrings . StringInSlice ( svc . Namespace ,   k . Namespaces ) )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
									
										
										
										
											2017-08-10 01:08:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 s   :=   kService { name :   svc . Name ,   namespace :   svc . Namespace } 
  
						 
					
						
							
								
									
										
										
										
											2017-06-14 10:29:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 // Endpoint query or headless service 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 if   svc . Spec . ClusterIP   ==   api . ClusterIPNone   ||   r . endpoint   !=   ""   { 
  
						 
					
						
							
								
									
										
										
										
											2017-05-30 08:20:39 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 s . addr   =   svc . Spec . ClusterIP 
  
						 
					
						
							
								
									
										
										
										
											2017-06-14 10:29:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 endpointsList   :=   k . APIConn . EndpointsList ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 for   _ ,   ep   :=   range   endpointsList . Items   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 if   ep . ObjectMeta . Name   !=   svc . Name   ||   ep . ObjectMeta . Namespace   !=   svc . Namespace   { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 } 
  
						 
					
						
							
								
									
										
										
										
											2017-06-14 10:29:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 for   _ ,   eps   :=   range   ep . Subsets   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 for   _ ,   addr   :=   range   eps . Addresses   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 for   _ ,   p   :=   range   eps . Ports   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															 ephostname   :=   endpointHostname ( addr ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															 if   r . endpoint   !=   ""   &&   r . endpoint   !=   ephostname   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																 continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															 } 
  
						 
					
						
							
								
									
										
										
										
											2017-08-05 12:29:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															 if   ! ( match ( r . port ,   p . Name ,   portWildcard )   &&   match ( r . protocol ,   string ( p . Protocol ) ,   protocolWildcard ) )   { 
  
						 
					
						
							
								
									
										
										
										
											2017-06-14 10:29:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																 continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															 s . endpoints   =   append ( s . endpoints ,   endpoint { addr :   addr ,   port :   p } ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 if   len ( s . endpoints )   >   0   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 resultItems   =   append ( resultItems ,   s ) 
  
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
									
										
										
										
											2017-06-14 10:29:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 // External service 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 if   svc . Spec . ExternalName   !=   ""   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 s . addr   =   svc . Spec . ExternalName 
  
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 resultItems   =   append ( resultItems ,   s ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
									
										
										
										
											2017-05-22 16:05:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-14 10:29:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 // ClusterIP service 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 s . addr   =   svc . Spec . ClusterIP 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 for   _ ,   p   :=   range   svc . Spec . Ports   { 
  
						 
					
						
							
								
									
										
										
										
											2017-08-05 12:29:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 if   ! ( match ( r . port ,   p . Name ,   portWildcard )   &&   match ( r . protocol ,   string ( p . Protocol ) ,   protocolWildcard ) )   { 
  
						 
					
						
							
								
									
										
										
										
											2016-07-14 14:50:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
									
										
										
										
											2017-06-14 10:29:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 s . ports   =   append ( s . ports ,   p ) 
  
						 
					
						
							
								
									
										
										
										
											2016-07-14 14:50:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
									
										
										
										
											2017-06-14 10:29:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 resultItems   =   append ( resultItems ,   s ) 
  
						 
					
						
							
								
									
										
										
										
											2016-07-14 14:50:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 return   resultItems ,   nil 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-05 12:29:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   match ( a ,   b   string ,   wildcard   bool )   bool   { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 if   wildcard   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   true 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
									
										
										
										
											2017-08-05 12:29:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 return   strings . EqualFold ( a ,   b ) 
  
						 
					
						
							
								
									
										
										
										
											2016-07-14 14:50:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// getServiceRecordForIP: Gets a service record with a cluster ip matching the ip argument 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// If a service cluster ip does not match, it checks all endpoints 
  
						 
					
						
							
								
									
										
										
										
											2016-08-22 23:15:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   getServiceRecordForIP ( ip ,   name   string )   [ ] msg . Service   { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 // First check services with cluster ips 
  
						 
					
						
							
								
									
										
										
										
											2017-05-22 16:05:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 svcList   :=   k . APIConn . ServiceList ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 10:13:02 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 for   _ ,   service   :=   range   svcList   { 
  
						 
					
						
							
								
									
										
										
										
											2017-02-07 16:22:43 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 if   ( len ( k . Namespaces )   >   0 )   &&   ! dnsstrings . StringInSlice ( service . Namespace ,   k . Namespaces )   { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
									
										
										
										
											2016-08-05 18:19:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 if   service . Spec . ClusterIP   ==   ip   { 
  
						 
					
						
							
								
									
										
										
										
											2017-08-11 16:21:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 domain   :=   strings . Join ( [ ] string { service . Name ,   service . Namespace ,   Svc ,   k . primaryZone ( ) } ,   "." ) 
  
						 
					
						
							
								
									
										
										
										
											2017-01-29 12:06:26 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 return   [ ] msg . Service { { Host :   domain } } 
  
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 // If no cluster ips match, search endpoints 
  
						 
					
						
							
								
									
										
										
										
											2017-05-22 16:05:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 epList   :=   k . APIConn . EndpointsList ( ) 
  
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 for   _ ,   ep   :=   range   epList . Items   { 
  
						 
					
						
							
								
									
										
										
										
											2017-02-07 16:22:43 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 if   ( len ( k . Namespaces )   >   0 )   &&   ! dnsstrings . StringInSlice ( ep . ObjectMeta . Namespace ,   k . Namespaces )   { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 for   _ ,   eps   :=   range   ep . Subsets   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 for   _ ,   addr   :=   range   eps . Addresses   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 if   addr . IP   ==   ip   { 
  
						 
					
						
							
								
									
										
										
										
											2017-08-11 16:21:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 domain   :=   strings . Join ( [ ] string { endpointHostname ( addr ) ,   ep . ObjectMeta . Name ,   ep . ObjectMeta . Namespace ,   Svc ,   k . primaryZone ( ) } ,   "." ) 
  
						 
					
						
							
								
									
										
										
										
											2017-01-29 12:06:26 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 return   [ ] msg . Service { { Host :   domain } } 
  
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
									
										
										
										
											2016-08-05 18:19:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
									
										
										
										
											2016-08-05 18:19:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 return   nil 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-05 12:29:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// wildcard checks whether s contains a wildcard value 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func   wildcard ( s   string )   bool   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 return   ( s   ==   "*"   ||   s   ==   "any" ) 
  
						 
					
						
							
								
									
										
										
										
											2016-09-23 09:48:11 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
									
										
										
										
											2017-06-14 09:38:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-03 23:14:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   localPodIP ( )   net . IP   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 addrs ,   err   :=   net . InterfaceAddrs ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 if   err   !=   nil   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   nil 
  
						 
					
						
							
								
									
										
										
										
											2017-06-14 09:38:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 for   _ ,   addr   :=   range   addrs   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 ip ,   _ ,   _   :=   net . ParseCIDR ( addr . String ( ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 ip   =   ip . To4 ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 if   ip   ==   nil   ||   ip . IsLoopback ( )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
									
										
										
										
											2017-08-03 23:14:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 return   ip 
  
						 
					
						
							
								
									
										
										
										
											2017-06-14 09:38:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 return   nil 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
									
										
										
										
											2017-06-28 18:44:30 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-04 07:34:00 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const   ( 
  
						 
					
						
							
								
									
										
										
										
											2017-08-04 09:46:40 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 // Svc is the DNS schema for kubernetes services 
  
						 
					
						
							
								
									
										
										
										
											2017-08-04 07:34:00 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 Svc   =   "svc" 
  
						 
					
						
							
								
									
										
										
										
											2017-08-04 09:46:40 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 // Pod is the DNS schema for kubernetes pods 
  
						 
					
						
							
								
									
										
										
										
											2017-08-04 07:34:00 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 Pod   =   "pod" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)