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" 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-05 07:57:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"strconv" 
							 
						 
					
						
							
								
									
										
										
										
											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-10-30 15:54:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dnsstrings  "github.com/miekg/coredns/middleware/pkg/strings" 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"github.com/miekg/coredns/middleware/proxy" 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-30 15:54:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/miekg/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 07:57:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"k8s.io/client-go/1.5/pkg/api" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unversionedapi  "k8s.io/client-go/1.5/pkg/api/unversioned" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"k8s.io/client-go/1.5/kubernetes" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"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" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"k8s.io/client-go/1.5/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-10-30 15:54:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Services implements the ServiceBackend interface.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( k  * Kubernetes )  Services ( state  request . Request ,  exact  bool ,  opt  middleware . Options )  ( [ ] msg . Service ,  [ ] msg . Service ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s ,  e  :=  k . Records ( state . Name ( ) ,  exact ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  s ,  nil ,  e  // Haven't implemented debug queries yet. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 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.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// TODO(infoblox): implement!  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( k  * Kubernetes )  IsNameError ( err  error )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Debug implements the ServiceBackend interface.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( k  * Kubernetes )  Debug ( )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  "debug" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( k  * Kubernetes )  InitKubeCache ( )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  k . LabelSelector  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										log . Printf ( "[INFO] Kubernetes middleware configured without a label selector. No label-based filtering will be performed." ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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.  
						 
					
						
							
								
									
										
										
										
											2016-08-22 23:15:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( k  * Kubernetes )  Records ( name  string ,  exact  bool )  ( [ ] msg . Service ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2016-10-30 15:54:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// TODO: refactor 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-10-30 15:54:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! nsWildcard )  &&  ( len ( k . Namespaces )  >  0 )  &&  ( ! dnsstrings . StringInSlice ( namespace ,  k . Namespaces ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-05 07:57:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									k8sItems ,  err  :=  k . Get ( namespace ,  nsWildcard ,  serviceName ,  serviceWildcard ,  typeName ) 
							 
						 
					
						
							
								
									
										
										
										
											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-11-05 07:57:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									records  :=  k . getRecordsForServiceItems ( k8sItems ,  zone ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-07 01:40:58 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  records ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2016-06-06 12:49:53 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-05 07:57:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( k  * Kubernetes )  getRecordsForServiceItems ( serviceItems  [ ] * api . Service ,  zone  string )  [ ] 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 for each exposed port... 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-05 07:57:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										key  :=  k . NameTemplate . RecordNameFromNameValues ( nametemplate . NameValues { TypeName :  "svc" ,  ServiceName :  item . ObjectMeta . Name ,  Namespace :  item . ObjectMeta . Namespace ,  Zone :  zone } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										key  =  strings . Replace ( key ,  "." ,  "/" ,  - 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  i ,  p  :=  range  item . Spec . Ports  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s  :=  msg . Service { Key :  msg . Path ( strconv . Itoa ( i )  +  "."  +  key ,  "coredns" ) ,  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-11-05 07:57:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( k  * Kubernetes )  Get ( namespace  string ,  nsWildcard  bool ,  servicename  string ,  serviceWildcard  bool ,  typeName  string )  ( [ ] * api . Service ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  typeName  ==  "pod" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  fmt . Errorf ( "pod not implemented" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  k . getServices ( namespace ,  nsWildcard ,  servicename ,  serviceWildcard ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( k  * Kubernetes )  getServices ( 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-10-30 15:54:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  nsWildcard  &&  ( len ( k . Namespaces )  >  0 )  &&  ( ! dnsstrings . 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-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" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}