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" 
  
						 
					
						
							
								
									
										
										
										
											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" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 "github.com/coredns/coredns/middleware/pkg/dnsutil" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 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-05-22 16:05:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 Next             middleware . Handler 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 Zones            [ ] string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 primaryZone      int 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 Proxy            proxy . Proxy   // Proxy for looking up names during the resolution process 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 APIEndpoint      string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 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 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 interfaceAddrs   InterfaceAddrser 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07: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 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type   service   struct   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 name        string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 namespace   string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 addr        string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 ports       [ ] api . ServicePort 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 endpoints   [ ] endpoint 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-11 16:23:10 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								type   pod   struct   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 name        string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 namespace   string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 addr        string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								type   recordRequest   struct   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 port ,   protocol ,   endpoint ,   service ,   namespace ,   typeName ,   zone   string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 16:56:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var   errNoItems   =   errors . New ( "no items found" ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var   errNsNotExposed   =   errors . New ( "namespace is not exposed" ) 
  
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var   errInvalidRequest   =   errors . New ( "invalid query name" ) 
  
						 
					
						
							
								
									
										
										
										
											2017-05-22 16:05:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var   errZoneNotFound   =   errors . New ( "zone not found" ) 
  
						 
					
						
							
								
									
										
										
										
											2017-05-25 12:08:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var   errAPIBadPodType   =   errors . New ( "expected type *api.Pod" ) 
  
						 
					
						
							
								
									
										
										
										
											2017-05-22 16:05:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var   errPodsDisabled   =   errors . New ( "pod records disabled" ) 
  
						 
					
						
							
								
									
										
										
										
											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-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-05-22 16:05:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 r ,   e   :=   k . parseRequest ( state . Name ( ) ,   state . QType ( ) ) 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 if   e   !=   nil   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   nil ,   nil ,   e 
  
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 14:37:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 switch   state . Type ( )   { 
  
						 
					
						
							
								
									
										
										
										
											2017-05-30 08:20:39 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 case   "A" ,   "CNAME" : 
  
						 
					
						
							
								
									
										
										
										
											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 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 svcs   =   append ( svcs ,   k . defaultNSMsg ( r ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   svcs ,   nil ,   nil 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 14:37:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 s ,   e   :=   k . Records ( r ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   s ,   nil ,   e   // Haven't implemented debug queries yet. 
  
						 
					
						
							
								
									
										
										
										
											2017-05-30 08:20:39 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 case   "SRV" : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 s ,   e   :=   k . Records ( r ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 // 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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 case   "TXT" : 
  
						 
					
						
							
								
									
										
										
										
											2017-05-22 16:05:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 err   :=   k . recordsForTXT ( r ,   & svcs ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   svcs ,   nil ,   err 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 case   "NS" : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 err   =   k . recordsForNS ( r ,   & svcs ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   svcs ,   nil ,   err 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 14:37:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 return   nil ,   nil ,   nil 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-05-22 16:05:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   recordsForTXT ( r   recordRequest ,   svcs   * [ ] msg . Service )   ( err   error )   { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 14:37:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 switch   r . typeName   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 case   "dns-version" : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 s   :=   msg . Service { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-29 12:06:26 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 Text :   DNSSchemaVersion , 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 14:37:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 TTL :    28800 , 
  
						 
					
						
							
								
									
										
										
										
											2017-05-22 16:05:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 Key :    msg . Path ( strings . Join ( [ ] string { r . typeName ,   r . zone } ,   "." ) ,   "coredns" ) } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 * svcs   =   append ( * svcs ,   s ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   nil 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 14:37:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
									
										
										
										
											2017-05-22 16:05:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 return   nil 
  
						 
					
						
							
								
									
										
										
										
											2016-10-30 15:54:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-14 19:31:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// PrimaryZone will return the first non-reverse zone being handled by this middleware 
  
						 
					
						
							
								
									
										
										
										
											2016-12-02 17:50:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   PrimaryZone ( )   string   { 
  
						 
					
						
							
								
									
										
										
										
											2016-11-14 19:31:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 return   k . Zones [ k . primaryZone ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-05 15:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Reverse implements the ServiceBackend interface. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   Reverse ( state   request . Request ,   exact   bool ,   opt   middleware . Options )   ( [ ] msg . Service ,   [ ] msg . Service ,   error )   { 
  
						 
					
						
							
								
									
										
										
										
											2017-05-22 16:05:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-05 15:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 ip   :=   dnsutil . ExtractAddressFromReverse ( state . Name ( ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 if   ip   ==   ""   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   nil ,   nil ,   nil 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 records   :=   k . getServiceRecordForIP ( ip ,   state . Name ( ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 return   records ,   nil ,   nil 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-05-22 16:05:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   isRequestInReverseRange ( name   string )   bool   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 ip   :=   dnsutil . ExtractAddressFromReverse ( name ) 
  
						 
					
						
							
								
									
										
										
										
											2017-02-01 12:56:10 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 for   _ ,   c   :=   range   k . ReverseCidrs   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 if   c . Contains ( net . ParseIP ( ip ) )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   true 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 return   false 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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-01-05 10:09:59 -05: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 )   { 
  
						 
					
						
							
								
									
										
										
										
											2016-08-05 18:19:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 // For a custom api server or running outside a k8s cluster 
  
						 
					
						
							
								
									
										
										
										
											2016-08-08 14:30:04 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 // set URL in env.KUBERNETES_MASTER or set endpoint in Corefile 
  
						 
					
						
							
								
									
										
										
										
											2016-08-05 18:19:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 loadingRules   :=   clientcmd . NewDefaultClientConfigLoadingRules ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 overrides   :=   & clientcmd . ConfigOverrides { } 
  
						 
					
						
							
								
									
										
										
										
											2016-09-23 18:07:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 clusterinfo   :=   clientcmdapi . Cluster { } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 authinfo   :=   clientcmdapi . AuthInfo { } 
  
						 
					
						
							
								
									
										
										
										
											2016-08-22 23:15:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 if   len ( k . APIEndpoint )   >   0   { 
  
						 
					
						
							
								
									
										
										
										
											2016-09-23 18:07:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 clusterinfo . Server   =   k . APIEndpoint 
  
						 
					
						
							
								
									
										
										
										
											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   { 
  
						 
					
						
							
								
									
										
										
										
											2016-10-30 15:54:16 +00: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   { 
  
						 
					
						
							
								
									
										
										
										
											2016-10-30 15:54:16 +00: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-01-20 02:22:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 k . APIConn   =   newdnsController ( kubeClient ,   k . ResyncPeriod ,   k . Selector ,   k . PodMode   ==   PodModeVerified ) 
  
						 
					
						
							
								
									
										
										
										
											2016-08-22 23:15:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-05 18:19:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 return   err 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-05-22 16:05:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   parseRequest ( lowerCasedName   string ,   qtype   uint16 )   ( r   recordRequest ,   err   error )   { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 // 3 Possible cases 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 //   SRV Request: _port._protocol.service.namespace.type.zone 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 //   A Request (endpoint): endpoint.service.namespace.type.zone 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 //   A Request (service): service.namespace.type.zone 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 // separate zone from rest of lowerCasedName 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 var   segs   [ ] string 
  
						 
					
						
							
								
									
										
										
										
											2016-08-22 23:15:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 for   _ ,   z   :=   range   k . Zones   { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 if   dns . IsSubDomain ( z ,   lowerCasedName )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 r . zone   =   z 
  
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 segs   =   dns . SplitDomainName ( lowerCasedName ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 segs   =   segs [ : len ( segs ) - dns . CountLabel ( r . zone ) ] 
  
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 break 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 if   r . zone   ==   ""   { 
  
						 
					
						
							
								
									
										
										
										
											2017-05-22 16:05:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 return   r ,   errZoneNotFound 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 if   qtype   ==   dns . TypeNS   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   r ,   nil 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 if   qtype   ==   dns . TypeA   &&   isDefaultNS ( lowerCasedName ,   r )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   r ,   nil 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 offset   :=   0 
  
						 
					
						
							
								
									
										
										
										
											2017-05-22 16:05:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 if   qtype   ==   dns . TypeSRV   { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-23 15:11:32 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 if   len ( segs )   !=   5   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   r ,   errInvalidRequest 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 // This is a SRV style request, get first two elements as port and 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 // protocol, stripping leading underscores if present. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 if   segs [ 0 ] [ 0 ]   ==   '_'   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 r . port   =   segs [ 0 ] [ 1 : ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 }   else   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 r . port   =   segs [ 0 ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 if   ! symbolContainsWildcard ( r . port )   { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-23 15:11:32 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 return   r ,   errInvalidRequest 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 if   segs [ 1 ] [ 0 ]   ==   '_'   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 r . protocol   =   segs [ 1 ] [ 1 : ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 if   r . protocol   !=   "tcp"   &&   r . protocol   !=   "udp"   { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-23 15:11:32 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 return   r ,   errInvalidRequest 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 }   else   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 r . protocol   =   segs [ 1 ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 if   ! symbolContainsWildcard ( r . protocol )   { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-23 15:11:32 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 return   r ,   errInvalidRequest 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 if   r . port   ==   ""   ||   r . protocol   ==   ""   { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-23 15:11:32 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 return   r ,   errInvalidRequest 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
									
										
										
										
											2017-01-23 15:11:32 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 offset   =   2 
  
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
									
										
										
										
											2017-05-22 16:05:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 if   qtype   ==   dns . TypeA   &&   len ( segs )   ==   4   { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-23 15:11:32 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 // This is an endpoint A record request. Get first element as endpoint. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 r . endpoint   =   segs [ 0 ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 offset   =   1 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 if   len ( segs )   ==   ( offset   +   3 )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 r . service   =   segs [ offset ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 r . namespace   =   segs [ offset + 1 ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 r . typeName   =   segs [ offset + 2 ] 
  
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 return   r ,   nil 
  
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-05-22 16:05:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 if   len ( segs )   ==   1   &&   qtype   ==   dns . TypeTXT   { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 14:37:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 r . typeName   =   segs [ 0 ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   r ,   nil 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-23 15:11:32 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 return   r ,   errInvalidRequest 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 15:54:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Records looks up services in kubernetes. If exact is true, it will lookup 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// just this name. This is used when find matches when completing SRV lookups 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// for instance. 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   Records ( 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-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 if   ( ! symbolContainsWildcard ( 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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -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-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 // Did not find item in k8s 
  
						 
					
						
							
								
									
										
										
										
											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-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 records   :=   k . getRecordsForK8sItems ( services ,   pods ,   r . zone ) 
  
						 
					
						
							
								
									
										
										
										
											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-05-22 16:05:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   getRecordsForK8sItems ( services   [ ] service ,   pods   [ ] pod ,   zone   string )   ( records   [ ] msg . Service )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 zonePath   :=   msg . Path ( zone ,   "coredns" ) 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-11 16:23:10 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 for   _ ,   svc   :=   range   services   { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 if   svc . addr   ==   api . ClusterIPNone   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 // This is a headless service, create records for each endpoint 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 for   _ ,   ep   :=   range   svc . endpoints   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 s   :=   msg . Service { 
  
						 
					
						
							
								
									
										
										
										
											2017-05-22 16:05:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 Key :    strings . Join ( [ ] string { zonePath ,   "svc" ,   svc . namespace ,   svc . name ,   endpointHostname ( ep . addr ) } ,   "/" ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 Host :   ep . addr . IP , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 Port :   int ( ep . port . Port ) , 
  
						 
					
						
							
								
									
										
										
										
											2016-12-02 17:50:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 } 
  
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 records   =   append ( records ,   s ) 
  
						 
					
						
							
								
									
										
										
										
											2016-12-02 17:50:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 }   else   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 // Create records for each exposed port... 
  
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 for   _ ,   p   :=   range   svc . ports   { 
  
						 
					
						
							
								
									
										
										
										
											2017-05-22 16:05:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 s   :=   msg . Service { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 Key :    strings . Join ( [ ] string { zonePath ,   "svc" ,   svc . namespace ,   svc . name } ,   "/" ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 Host :   svc . addr , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 Port :   int ( p . Port ) } 
  
						 
					
						
							
								
									
										
										
										
											2016-12-02 17:50:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 records   =   append ( records ,   s ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
									
										
										
										
											2017-05-30 08:20:39 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 // If the addr is not an IP (i.e. an external service), add the record ... 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 s   :=   msg . Service { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 Key :    strings . Join ( [ ] string { zonePath ,   "svc" ,   svc . namespace ,   svc . name } ,   "/" ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 Host :   svc . addr } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 if   t ,   _   :=   s . HostType ( ) ;   t   ==   dns . TypeCNAME   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 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   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 s   :=   msg . Service { 
  
						 
					
						
							
								
									
										
										
										
											2017-05-22 16:05:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 Key :    strings . Join ( [ ] string { zonePath ,   "pod" ,   p . namespace ,   p . name } ,   "/" ) , 
  
						 
					
						
							
								
									
										
										
										
											2017-01-11 16:23:10 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 Host :   p . addr , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 records   =   append ( records ,   s ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 return   records 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-11 16:23:10 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   ipFromPodName ( podname   string )   string   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 if   strings . Count ( podname ,   "-" )   ==   3   &&   ! strings . Contains ( podname ,   "--" )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   strings . Replace ( podname ,   "-" ,   "." ,   - 1 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 return   strings . Replace ( podname ,   "-" ,   ":" ,   - 1 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   findPods ( namespace ,   podname   string )   ( pods   [ ] pod ,   err   error )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 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   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 s   :=   pod { name :   podname ,   namespace :   namespace ,   addr :   ip } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 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-01-20 02:22:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 nsWildcard   :=   symbolContainsWildcard ( namespace ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 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 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 if   ip   ==   p . Status . PodIP   &&   symbolMatches ( namespace ,   p . Namespace ,   nsWildcard )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 s   :=   pod { name :   podname ,   namespace :   namespace ,   addr :   ip } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 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. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   get ( r   recordRequest )   ( services   [ ] service ,   pods   [ ] pod ,   err   error )   { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 switch   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 case   r . typeName   ==   "pod" : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 pods ,   err   =   k . findPods ( r . namespace ,   r . service ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   nil ,   pods ,   err 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 default : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 services ,   err   =   k . findServices ( r ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   services ,   nil ,   err 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   findServices ( r   recordRequest )   ( [ ] service ,   error )   { 
  
						 
					
						
							
								
									
										
										
										
											2016-10-12 12:46:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 serviceList   :=   k . APIConn . ServiceList ( ) 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 var   resultItems   [ ] service 
  
						 
					
						
							
								
									
										
										
										
											2016-07-14 14:50:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 nsWildcard   :=   symbolContainsWildcard ( r . namespace ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 serviceWildcard   :=   symbolContainsWildcard ( r . service ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 portWildcard   :=   symbolContainsWildcard ( r . port )   ||   r . port   ==   "" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 protocolWildcard   :=   symbolContainsWildcard ( r . protocol )   ||   r . protocol   ==   "" 
  
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 for   _ ,   svc   :=   range   serviceList   { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 if   ! ( symbolMatches ( r . namespace ,   svc . Namespace ,   nsWildcard )   &&   symbolMatches ( 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-05-30 08:20:39 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 s   :=   service { name :   svc . Name ,   namespace :   svc . Namespace } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 // External Service 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 if   svc . Spec . ExternalName   !=   ""   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 s . addr   =   svc . Spec . ExternalName 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 resultItems   =   append ( resultItems ,   s ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 // ClusterIP service 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 if   svc . Spec . ClusterIP   !=   api . ClusterIPNone   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 s . addr   =   svc . Spec . ClusterIP 
  
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 for   _ ,   p   :=   range   svc . Spec . Ports   { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 if   ! ( symbolMatches ( r . port ,   strings . ToLower ( p . Name ) ,   portWildcard )   &&   symbolMatches ( r . protocol ,   strings . ToLower ( string ( p . Protocol ) ) ,   protocolWildcard ) )   { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													 continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 s . ports   =   append ( s . ports ,   p ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 resultItems   =   append ( resultItems ,   s ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 // Headless service 
  
						 
					
						
							
								
									
										
										
										
											2017-05-30 08:20:39 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 s . addr   =   svc . Spec . ClusterIP 
  
						 
					
						
							
								
									
										
										
										
											2017-05-22 16:05:48 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 endpointsList   :=   k . APIConn . EndpointsList ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 for   _ ,   ep   :=   range   endpointsList . Items   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 if   ep . ObjectMeta . Name   !=   svc . Name   ||   ep . ObjectMeta . Namespace   !=   svc . Namespace   { 
  
						 
					
						
							
								
									
										
										
										
											2016-07-14 14:50:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 for   _ ,   eps   :=   range   ep . Subsets   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 for   _ ,   addr   :=   range   eps . Addresses   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 for   _ ,   p   :=   range   eps . Ports   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 ephostname   :=   endpointHostname ( addr ) 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														 if   r . endpoint   !=   ""   &&   r . endpoint   !=   ephostname   { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															 continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 } 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														 if   ! ( symbolMatches ( r . port ,   strings . ToLower ( p . Name ) ,   portWildcard )   &&   symbolMatches ( r . protocol ,   strings . ToLower ( string ( p . Protocol ) ) ,   protocolWildcard ) )   { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															 continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 s . endpoints   =   append ( s . endpoints ,   endpoint { addr :   addr ,   port :   p } ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
									
										
										
										
											2016-07-14 14:50:14 -07: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-01-05 10:09:59 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   symbolMatches ( queryString ,   candidateString   string ,   wildcard   bool )   bool   { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-15 03:12:28 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 if   wildcard   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   true 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 return   queryString   ==   candidateString 
  
						 
					
						
							
								
									
										
										
										
											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-05-22 16:05:48 -04: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-05-22 16:05:48 -04: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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 09:48:11 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// symbolContainsWildcard checks whether symbol contains a wildcard value 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func   symbolContainsWildcard ( symbol   string )   bool   { 
  
						 
					
						
							
								
									
										
										
										
											2017-01-22 03:15:12 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 return   ( symbol   ==   "*"   ||   symbol   ==   "any" ) 
  
						 
					
						
							
								
									
										
										
										
											2016-09-23 09:48:11 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}