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-07-18 10:47:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 "log" 
  
						 
					
						
							
								
									
										
										
										
											2016-09-23 09:48:11 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 "strings" 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									 "time" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 "github.com/miekg/coredns/middleware" 
  
						 
					
						
							
								
									
										
										
										
											2016-09-23 09:14:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 "github.com/miekg/coredns/middleware/etcd/msg" 
  
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 "github.com/miekg/coredns/middleware/kubernetes/nametemplate" 
  
						 
					
						
							
								
									
										
										
										
											2016-09-07 11:10:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 "github.com/miekg/coredns/middleware/pkg/dnsutil" 
  
						 
					
						
							
								
									
										
										
										
											2016-09-23 09:48:11 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 dns_strings   "github.com/miekg/coredns/middleware/pkg/strings" 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									 "github.com/miekg/coredns/middleware/proxy" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 "github.com/miekg/dns" 
  
						 
					
						
							
								
									
										
										
										
											2016-08-05 18:19:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 "k8s.io/kubernetes/pkg/api" 
  
						 
					
						
							
								
									
										
										
										
											2016-08-12 20:44:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 unversionedapi   "k8s.io/kubernetes/pkg/api/unversioned" 
  
						 
					
						
							
								
									
										
										
										
											2016-09-23 18:07:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 "k8s.io/kubernetes/pkg/client/restclient" 
  
						 
					
						
							
								
									
										
										
										
											2016-09-25 08:39:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 unversionedclient   "k8s.io/kubernetes/pkg/client/unversioned" 
  
						 
					
						
							
								
									
										
										
										
											2016-08-05 18:19:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 clientcmdapi   "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api" 
  
						 
					
						
							
								
									
										
										
										
											2016-08-19 17:14:17 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 "k8s.io/kubernetes/pkg/labels" 
  
						 
					
						
							
								
									
										
										
										
											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   { 
  
						 
					
						
							
								
									
										
										
										
											2016-08-12 20:44:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 Next            middleware . Handler 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 Zones           [ ] string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 Proxy           proxy . Proxy   // Proxy for looking up names during the resolution process 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 APIEndpoint     string 
  
						 
					
						
							
								
									
										
										
										
											2016-09-23 18:07:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 APICertAuth     string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 APIClientCert   string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 APIClientKey    string 
  
						 
					
						
							
								
									
										
										
										
											2016-08-12 20:44:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 APIConn         * dnsController 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 ResyncPeriod    time . Duration 
  
						 
					
						
							
								
									
										
										
										
											2016-10-12 12:46:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 NameTemplate    * nametemplate . Template 
  
						 
					
						
							
								
									
										
										
										
											2016-08-12 20:44:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 Namespaces      [ ] string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 LabelSelector   * unversionedapi . LabelSelector 
  
						 
					
						
							
								
									
										
										
										
											2016-08-19 17:14:17 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 Selector        * labels . Selector 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 18:07:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   getClientConfig ( )   ( * restclient . 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 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 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. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// TODO(miek): is this correct? 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   InitKubeCache ( )   error   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 config ,   err   :=   k . getClientConfig ( ) 
  
						 
					
						
							
								
									
										
										
										
											2016-08-05 18:19:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 if   err   !=   nil   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   err 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 18:07:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 kubeClient ,   err   :=   unversionedclient . New ( config ) 
  
						 
					
						
							
								
									
										
										
										
											2016-08-05 18:19:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 if   err   !=   nil   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 log . Printf ( "[ERROR] Failed to create kubernetes notification controller: %v" ,   err ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   err 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
									
										
										
										
											2016-08-22 23:15:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 if   k . LabelSelector   ==   nil   { 
  
						 
					
						
							
								
									
										
										
										
											2016-08-16 09:12:52 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 log . Printf ( "[INFO] Kubernetes middleware configured without a label selector. No label-based filtering will be performed." ) 
  
						 
					
						
							
								
									
										
										
										
											2016-08-12 20:44:08 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 }   else   { 
  
						 
					
						
							
								
									
										
										
										
											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-08-22 23:15:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 log . Printf ( "[ERROR] Unable to create Selector for LabelSelector '%s'.Error was: %s" ,   k . LabelSelector ,   err ) 
  
						 
					
						
							
								
									
										
										
										
											2016-08-19 17:14:17 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 return   err 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
									
										
										
										
											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-08-22 23:15:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 k . APIConn   =   newdnsController ( kubeClient ,   k . ResyncPeriod ,   k . Selector ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-05 18:19:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 return   err 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// getZoneForName returns the zone string that matches the name and a 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// list of the DNS labels from name that are within the zone. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// For example, if "coredns.local" is a zone configured for the 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Kubernetes middleware, then getZoneForName("a.b.coredns.local") 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// will return ("coredns.local", ["a", "b"]). 
  
						 
					
						
							
								
									
										
										
										
											2016-08-22 23:15:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   getZoneForName ( name   string )   ( string ,   [ ] string )   { 
  
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 var   zone   string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 var   serviceSegments   [ ] string 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 23:15:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 for   _ ,   z   :=   range   k . Zones   { 
  
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 if   dns . IsSubDomain ( z ,   name )   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 zone   =   z 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 serviceSegments   =   dns . SplitDomainName ( name ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 serviceSegments   =   serviceSegments [ : len ( serviceSegments ) - dns . CountLabel ( zone ) ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 break 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 return   zone ,   serviceSegments 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07: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 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// for instance. 
  
						 
					
						
							
								
									
										
										
										
											2016-08-22 23:15:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   Records ( name   string ,   exact   bool )   ( [ ] msg . Service ,   error )   { 
  
						 
					
						
							
								
									
										
										
										
											2016-08-05 18:19:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 // TODO: refector this. 
  
						 
					
						
							
								
									
										
										
										
											2016-10-12 12:46:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 // Right now NamespaceFromSegmentArray do not supports PRE queries 
  
						 
					
						
							
								
									
										
										
										
											2016-09-07 11:10:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 ip   :=   dnsutil . ExtractAddressFromReverse ( name ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 if   ip   !=   ""   { 
  
						 
					
						
							
								
									
										
										
										
											2016-08-22 23:15:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 records   :=   k . getServiceRecordForIP ( ip ,   name ) 
  
						 
					
						
							
								
									
										
										
										
											2016-08-05 18:19:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 return   records ,   nil 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 var   ( 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 serviceName   string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 namespace     string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 typeName      string 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 23:15:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 zone ,   serviceSegments   :=   k . getZoneForName ( name ) 
  
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 // TODO: Implementation above globbed together segments for the serviceName if 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 //       multiple segments remained. Determine how to do similar globbing using 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 //		 the template-based implementation. 
  
						 
					
						
							
								
									
										
										
										
											2016-10-12 12:46:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 namespace   =   k . NameTemplate . NamespaceFromSegmentArray ( serviceSegments ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 serviceName   =   k . NameTemplate . ServiceFromSegmentArray ( serviceSegments ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 typeName   =   k . NameTemplate . TypeFromSegmentArray ( serviceSegments ) 
  
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-14 14:50:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 if   namespace   ==   ""   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 err   :=   errors . New ( "Parsing query string did not produce a namespace value. Assuming wildcard namespace." ) 
  
						 
					
						
							
								
									
										
										
										
											2016-07-18 10:47:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 log . Printf ( "[WARN] %v\n" ,   err ) 
  
						 
					
						
							
								
									
										
										
										
											2016-09-23 09:48:11 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 namespace   =   "*" 
  
						 
					
						
							
								
									
										
										
										
											2016-07-14 14:50:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 if   serviceName   ==   ""   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 err   :=   errors . New ( "Parsing query string did not produce a serviceName value. Assuming wildcard serviceName." ) 
  
						 
					
						
							
								
									
										
										
										
											2016-07-18 10:47:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 log . Printf ( "[WARN] %v\n" ,   err ) 
  
						 
					
						
							
								
									
										
										
										
											2016-09-23 09:48:11 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 serviceName   =   "*" 
  
						 
					
						
							
								
									
										
										
										
											2016-07-14 14:50:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 09:48:11 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 nsWildcard   :=   symbolContainsWildcard ( namespace ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 serviceWildcard   :=   symbolContainsWildcard ( serviceName ) 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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. 
  
						 
					
						
							
								
									
										
										
										
											2016-09-23 09:48:11 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 if   ( ! nsWildcard )   &&   ( len ( k . Namespaces )   >   0 )   &&   ( ! dns_strings . StringInSlice ( namespace ,   k . Namespaces ) )   { 
  
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 return   nil ,   nil 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 23:15:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 k8sItems ,   err   :=   k . Get ( namespace ,   nsWildcard ,   serviceName ,   serviceWildcard ) 
  
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 if   err   !=   nil   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   nil ,   err 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 if   k8sItems   ==   nil   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 // Did not find item in k8s 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   nil ,   nil 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 23:15:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 records   :=   k . getRecordsForServiceItems ( k8sItems ,   nametemplate . NameValues { TypeName :   typeName ,   ServiceName :   serviceName ,   Namespace :   namespace ,   Zone :   zone } ) 
  
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 return   records ,   nil 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// TODO: assemble name from parts found in k8s data based on name template rather than reusing query string 
  
						 
					
						
							
								
									
										
										
										
											2016-09-23 10:13:02 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   getRecordsForServiceItems ( serviceItems   [ ] * api . Service ,   values   nametemplate . NameValues )   [ ] msg . Service   { 
  
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 var   records   [ ] msg . Service 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 for   _ ,   item   :=   range   serviceItems   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 clusterIP   :=   item . Spec . ClusterIP 
  
						 
					
						
							
								
									
										
										
										
											2016-07-14 14:50:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 // Create records by constructing record name from template... 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 //values.Namespace = item.Metadata.Namespace 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 //values.ServiceName = item.Metadata.Name 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 //s := msg.Service{Host: g.NameTemplate.GetRecordNameFromNameValues(values)} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 //records = append(records, s) 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-14 14:50:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 // Create records for each exposed port... 
  
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 for   _ ,   p   :=   range   item . Spec . Ports   { 
  
						 
					
						
							
								
									
										
										
										
											2016-08-05 18:19:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 s   :=   msg . Service { Host :   clusterIP ,   Port :   int ( p . Port ) } 
  
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 records   =   append ( records ,   s ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 return   records 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Get performs the call to the Kubernetes http API. 
  
						 
					
						
							
								
									
										
										
										
											2016-09-23 10:13:02 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   Get ( namespace   string ,   nsWildcard   bool ,   servicename   string ,   serviceWildcard   bool )   ( [ ] * api . Service ,   error )   { 
  
						 
					
						
							
								
									
										
										
										
											2016-10-12 12:46:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 serviceList   :=   k . APIConn . ServiceList ( ) 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 10:13:02 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 var   resultItems   [ ] * api . Service 
  
						 
					
						
							
								
									
										
										
										
											2016-07-14 14:50:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 10:13:02 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 for   _ ,   item   :=   range   serviceList   { 
  
						 
					
						
							
								
									
										
										
										
											2016-08-05 18:19:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 if   symbolMatches ( namespace ,   item . Namespace ,   nsWildcard )   &&   symbolMatches ( servicename ,   item . Name ,   serviceWildcard )   { 
  
						 
					
						
							
								
									
										
										
										
											2016-07-14 14:50:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 // If namespace has a wildcard, filter results against Corefile namespace list. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 // (Namespaces without a wildcard were filtered before the call to this function.) 
  
						 
					
						
							
								
									
										
										
										
											2016-09-23 09:48:11 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 if   nsWildcard   &&   ( len ( k . Namespaces )   >   0 )   &&   ( ! dns_strings . StringInSlice ( item . Namespace ,   k . Namespaces ) )   { 
  
						 
					
						
							
								
									
										
										
										
											2016-07-14 14:50:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 } 
  
						 
					
						
							
								
									
										
										
										
											2016-09-22 08:29:50 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 resultItems   =   append ( resultItems ,   item ) 
  
						 
					
						
							
								
									
										
										
										
											2016-07-14 14:50:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 return   resultItems ,   nil 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-14 14:50:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   symbolMatches ( queryString   string ,   candidateString   string ,   wildcard   bool )   bool   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 result   :=   false 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 switch   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 case   ! wildcard : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 result   =   ( queryString   ==   candidateString ) 
  
						 
					
						
							
								
									
										
										
										
											2016-09-23 09:48:11 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 case   queryString   ==   "*" : 
  
						 
					
						
							
								
									
										
										
										
											2016-07-14 14:50:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 result   =   true 
  
						 
					
						
							
								
									
										
										
										
											2016-09-23 09:48:11 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 case   queryString   ==   "any" : 
  
						 
					
						
							
								
									
										
										
										
											2016-07-14 14:50:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 result   =   true 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 return   result 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-05 18:19:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// kubernetesNameError checks if the error is ErrorCodeKeyNotFound from kubernetes. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func   isKubernetesNameError ( err   error )   bool   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 return   false 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								} 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 23:15:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func   ( k   * Kubernetes )   getServiceRecordForIP ( ip ,   name   string )   [ ] msg . Service   { 
  
						 
					
						
							
								
									
										
										
										
											2016-09-23 10:13:02 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 svcList ,   err   :=   k . APIConn . svcLister . List ( labels . Everything ( ) ) 
  
						 
					
						
							
								
									
										
										
										
											2016-08-05 18:19:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 if   err   !=   nil   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 return   nil 
  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									 } 
  
						 
					
						
							
								
									
										
										
										
											2016-09-23 10:13:02 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									 for   _ ,   service   :=   range   svcList   { 
  
						 
					
						
							
								
									
										
										
										
											2016-08-05 18:19:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 if   service . Spec . ClusterIP   ==   ip   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 return   [ ] msg . Service { msg . Service { Host :   ip } } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 } 
  
						 
					
						
							
								
									
										
										
										
											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   { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 return   ( strings . Contains ( symbol ,   "*" )   ||   ( symbol   ==   "any" ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}