2014-06-07 07:40:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								/ * 
							 
						 
					
						
							
								
									
										
										
										
											2015-05-02 00:19:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								Copyright  2014  The  Kubernetes  Authors  All  rights  reserved . 
							 
						 
					
						
							
								
									
										
										
										
											2014-06-07 07:40:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Licensed  under  the  Apache  License ,  Version  2.0  ( the  "License" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								you  may  not  use  this  file  except  in  compliance  with  the  License . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								You  may  obtain  a  copy  of  the  License  at 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    http : //www.apache.org/licenses/LICENSE-2.0
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								Unless  required  by  applicable  law  or  agreed  to  in  writing ,  software 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								distributed  under  the  License  is  distributed  on  an  "AS IS"  BASIS , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								WITHOUT  WARRANTIES  OR  CONDITIONS  OF  ANY  KIND ,  either  express  or  implied . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								See  the  License  for  the  specific  language  governing  permissions  and 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								limitations  under  the  License . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								* / 
							 
						 
					
						
							
								
									
										
										
										
											2014-06-19 07:01:49 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-06-11 21:13:19 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								// CAUTION: If you update code in this file, you may need to also update code
 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-12 03:34:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								//          in contrib/mesos/pkg/service/endpoints_controller.go
 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-10 11:58:57 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								package  endpoint 
							 
						 
					
						
							
								
									
										
										
										
											2014-06-07 07:40:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								import  ( 
							 
						 
					
						
							
								
									
										
										
										
											2015-03-21 05:24:43 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									"reflect" 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									"time" 
							 
						 
					
						
							
								
									
										
										
										
											2014-06-07 07:40:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-08-06 06:03:47 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/api" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/api/endpoints" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/api/errors" 
							 
						 
					
						
							
								
									
										
										
										
											2015-11-06 19:34:42 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									podutil  "k8s.io/kubernetes/pkg/api/pod" 
							 
						 
					
						
							
								
									
										
										
										
											2015-09-04 05:40:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/client/cache" 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-06 05:58:03 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									clientset  "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-06 17:12:00 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/controller" 
							 
						 
					
						
							
								
									
										
										
										
											2015-08-06 06:03:47 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/controller/framework" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/labels" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/runtime" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/util" 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-15 15:32:10 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									utilruntime  "k8s.io/kubernetes/pkg/util/runtime" 
							 
						 
					
						
							
								
									
										
										
										
											2015-09-10 01:45:01 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/util/sets" 
							 
						 
					
						
							
								
									
										
										
										
											2015-08-06 06:03:47 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/util/workqueue" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									"k8s.io/kubernetes/pkg/watch" 
							 
						 
					
						
							
								
									
										
										
										
											2014-08-11 15:34:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-06-25 11:51:57 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									"github.com/golang/glog" 
							 
						 
					
						
							
								
									
										
										
										
											2014-06-07 07:40:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								const  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// We'll attempt to recompute EVERY service's endpoints at least this
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// often. Higher numbers = lower CPU/network load; lower numbers =
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// shorter amount of time before a mistaken endpoint is corrected.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									FullServiceResyncPeriod  =  30  *  time . Second 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									keyFunc  =  framework . DeletionHandlingMetaNamespaceKeyFunc 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// NewEndpointController returns a new *EndpointController.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-29 14:34:08 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  NewEndpointController ( client  * clientset . Clientset ,  resyncPeriod  controller . ResyncPeriodFunc )  * EndpointController  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									e  :=  & EndpointController { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										client :  client , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										queue :   workqueue . New ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									e . serviceStore . Store ,  e . serviceController  =  framework . NewInformer ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										& cache . ListWatch { 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-10 17:39:03 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ListFunc :  func ( options  api . ListOptions )  ( runtime . Object ,  error )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-04 05:21:05 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												return  e . client . Core ( ) . Services ( api . NamespaceAll ) . List ( options ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											} , 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-10 17:39:03 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											WatchFunc :  func ( options  api . ListOptions )  ( watch . Interface ,  error )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-04 05:21:05 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												return  e . client . Core ( ) . Services ( api . NamespaceAll ) . Watch ( options ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										& api . Service { } , 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-06 17:12:00 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										// TODO: Can we have much longer period here?
 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										FullServiceResyncPeriod , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										framework . ResourceEventHandlerFuncs { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											AddFunc :  e . enqueueService , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											UpdateFunc :  func ( old ,  cur  interface { } )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												e . enqueueService ( cur ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											DeleteFunc :  e . enqueueService , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									e . podStore . Store ,  e . podController  =  framework . NewInformer ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										& cache . ListWatch { 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-10 17:39:03 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ListFunc :  func ( options  api . ListOptions )  ( runtime . Object ,  error )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-04 05:21:05 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												return  e . client . Core ( ) . Pods ( api . NamespaceAll ) . List ( options ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											} , 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-10 17:39:03 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											WatchFunc :  func ( options  api . ListOptions )  ( watch . Interface ,  error )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-04 05:21:05 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												return  e . client . Core ( ) . Pods ( api . NamespaceAll ) . Watch ( options ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										& api . Pod { } , 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-06 17:12:00 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										resyncPeriod ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										framework . ResourceEventHandlerFuncs { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											AddFunc :     e . addPod , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											UpdateFunc :  e . updatePod , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											DeleteFunc :  e . deletePod , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  e 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-02-05 03:21:33 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								// EndpointController manages selector-based service endpoints.
 
							 
						 
					
						
							
								
									
										
										
										
											2014-06-07 07:40:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								type  EndpointController  struct  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-29 14:34:08 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									client  * clientset . Clientset 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									serviceStore  cache . StoreToServiceLister 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									podStore      cache . StoreToPodLister 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Services that need to be updated. A channel is inappropriate here,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// because it allows services with lots of pods to be serviced much
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// more often than services with few pods; it also would cause a
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// service that's inserted multiple times to be processed more than
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// necessary.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									queue  * workqueue . Type 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Since we join two objects, we'll watch both of them with
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// controllers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									serviceController  * framework . Controller 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									podController      * framework . Controller 
							 
						 
					
						
							
								
									
										
										
										
											2014-06-07 07:40:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								// Runs e; will not return until stopCh is closed. workers determines how many
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// endpoints will be handled in parallel.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( e  * EndpointController )  Run ( workers  int ,  stopCh  <- chan  struct { } )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-15 15:32:10 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									defer  utilruntime . HandleCrash ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									go  e . serviceController . Run ( stopCh ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									go  e . podController . Run ( stopCh ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  i  :=  0 ;  i  <  workers ;  i ++  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										go  util . Until ( e . worker ,  time . Second ,  stopCh ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-07-12 15:15:30 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-25 05:16:27 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									go  func ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-15 15:32:10 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										defer  utilruntime . HandleCrash ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-25 05:16:27 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										time . Sleep ( 5  *  time . Minute )  // give time for our cache to fill
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										e . checkLeftoverEndpoints ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									<- stopCh 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									e . queue . ShutDown ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-07-12 15:15:30 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-09-10 01:45:01 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								func  ( e  * EndpointController )  getPodServiceMemberships ( pod  * api . Pod )  ( sets . String ,  error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									set  :=  sets . String { } 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									services ,  err  :=  e . serviceStore . GetPodServices ( pod ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-06-07 07:40:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										// don't log this error because this function makes pointless
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// errors when no services match.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  set ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2014-06-07 07:40:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									for  i  :=  range  services  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										key ,  err  :=  keyFunc ( & services [ i ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2014-10-28 08:56:33 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										set . Insert ( key ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  set ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// When a pod is added, figure out what services it will be a member of and
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// enqueue them. obj must have *api.Pod type.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( e  * EndpointController )  addPod ( obj  interface { } )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									pod  :=  obj . ( * api . Pod ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									services ,  err  :=  e . getPodServiceMemberships ( pod ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										glog . Errorf ( "Unable to get pod %v/%v's service memberships: %v" ,  pod . Namespace ,  pod . Name ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  key  :=  range  services  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										e . queue . Add ( key ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// When a pod is updated, figure out what services it used to be a member of
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// and what services it will be a member of, and enqueue the union of these.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// old and cur must be *api.Pod types.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( e  * EndpointController )  updatePod ( old ,  cur  interface { } )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  api . Semantic . DeepEqual ( old ,  cur )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									newPod  :=  old . ( * api . Pod ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									services ,  err  :=  e . getPodServiceMemberships ( newPod ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										glog . Errorf ( "Unable to get pod %v/%v's service memberships: %v" ,  newPod . Namespace ,  newPod . Name ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-19 01:49:00 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									oldPod  :=  cur . ( * api . Pod ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Only need to get the old services if the labels changed.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ! reflect . DeepEqual ( newPod . Labels ,  oldPod . Labels )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										oldServices ,  err  :=  e . getPodServiceMemberships ( oldPod ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-06-07 07:40:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											glog . Errorf ( "Unable to get pod %v/%v's service memberships: %v" ,  oldPod . Namespace ,  oldPod . Name ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return 
							 
						 
					
						
							
								
									
										
										
										
											2014-06-07 07:40:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										services  =  services . Union ( oldServices ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  key  :=  range  services  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										e . queue . Add ( key ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-13 23:52:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								// When a pod is deleted, enqueue the services the pod used to be a member of.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// obj could be an *api.Pod, or a DeletionFinalStateUnknown marker item.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( e  * EndpointController )  deletePod ( obj  interface { } )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  _ ,  ok  :=  obj . ( * api . Pod ) ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Enqueue all the services that the pod used to be a member
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// of. This happens to be exactly the same thing we do when a
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// pod is added.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										e . addPod ( obj ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									podKey ,  err  :=  keyFunc ( obj ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										glog . Errorf ( "Couldn't get key for object %+v: %v" ,  obj ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									glog . Infof ( "Pod %q was deleted but we don't have a record of its final state, so it will take up to %v before it will be removed from all endpoint records." ,  podKey ,  FullServiceResyncPeriod ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-02-03 02:51:52 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									// TODO: keep a map of pods to services to handle this condition.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// obj could be an *api.Service, or a DeletionFinalStateUnknown marker item.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( e  * EndpointController )  enqueueService ( obj  interface { } )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									key ,  err  :=  keyFunc ( obj ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										glog . Errorf ( "Couldn't get key for object %+v: %v" ,  obj ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2015-02-03 02:51:52 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									e . queue . Add ( key ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// worker runs a worker thread that just dequeues items, processes them, and
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// marks them done. You may run as many of these in parallel as you wish; the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// workqueue guarantees that they will not end up processing the same service
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// at the same time.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( e  * EndpointController )  worker ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										func ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											key ,  quit  :=  e . queue . Get ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  quit  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												return 
							 
						 
					
						
							
								
									
										
										
										
											2015-03-13 23:16:41 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											// Use defer: in the unlikely event that there's a
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// panic, we'd still like this to get marked done--
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// otherwise the controller will not be able to sync
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// this service again until it is restarted.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											defer  e . queue . Done ( key ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											e . syncService ( key . ( string ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2015-03-21 05:24:43 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								func  ( e  * EndpointController )  syncService ( key  string )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									startTime  :=  time . Now ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									defer  func ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										glog . V ( 4 ) . Infof ( "Finished syncing service %q endpoints. (%v)" ,  key ,  time . Now ( ) . Sub ( startTime ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									obj ,  exists ,  err  :=  e . serviceStore . Store . GetByKey ( key ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  ||  ! exists  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Delete the corresponding endpoint, as the service has been deleted.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// TODO: Please note that this will delete an endpoint when a
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// service is deleted. However, if we're down at the time when
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// the service is deleted, we will miss that deletion, so this
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// doesn't completely solve the problem. See #6877.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										namespace ,  name ,  err  :=  cache . SplitMetaNamespaceKey ( key ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-09-27 04:34:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											glog . Errorf ( "Need to delete endpoint with key %q, but couldn't understand the key: %v" ,  key ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											// Don't retry, as the key isn't going to magically become understandable.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-29 14:34:08 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										err  =  e . client . Endpoints ( namespace ) . Delete ( name ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										if  err  !=  nil  &&  ! errors . IsNotFound ( err )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											glog . Errorf ( "Error deleting endpoint %q: %v" ,  key ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											e . queue . Add ( key )  // Retry
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									service  :=  obj . ( * api . Service ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  service . Spec . Selector  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// services without a selector receive no endpoints from this controller;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// these services will receive the endpoints that are created out-of-band via the REST API.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									glog . V ( 5 ) . Infof ( "About to update endpoints for service %q" ,  key ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									pods ,  err  :=  e . podStore . Pods ( service . Namespace ) . List ( labels . Set ( service . Spec . Selector ) . AsSelector ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Since we're getting stuff from a local cache, it is
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// basically impossible to get this error.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										glog . Errorf ( "Error syncing service %q: %v" ,  key ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										e . queue . Add ( key )  // Retry
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									subsets  :=  [ ] api . EndpointSubset { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  i  :=  range  pods . Items  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pod  :=  & pods . Items [ i ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										for  i  :=  range  service . Spec . Ports  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											servicePort  :=  & service . Spec . Ports [ i ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											portName  :=  servicePort . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											portProto  :=  servicePort . Protocol 
							 
						 
					
						
							
								
									
										
										
										
											2015-11-06 19:34:42 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											portNum ,  err  :=  podutil . FindPort ( pod ,  servicePort ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-05-17 07:37:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												glog . V ( 4 ) . Infof ( "Failed to find port for service %s/%s: %v" ,  service . Namespace ,  service . Name ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  len ( pod . Status . PodIP )  ==  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-08-20 09:52:34 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												glog . V ( 5 ) . Infof ( "Failed to find an IP for pod %s/%s" ,  pod . Namespace ,  pod . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  pod . DeletionTimestamp  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												glog . V ( 5 ) . Infof ( "Pod is being deleted %s/%s" ,  pod . Namespace ,  pod . Name ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											epp  :=  api . EndpointPort { Name :  portName ,  Port :  portNum ,  Protocol :  portProto } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											epa  :=  api . EndpointAddress { IP :  pod . Status . PodIP ,  TargetRef :  & api . ObjectReference { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												Kind :             "Pod" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												Namespace :        pod . ObjectMeta . Namespace , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												Name :             pod . ObjectMeta . Name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												UID :              pod . ObjectMeta . UID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ResourceVersion :  pod . ObjectMeta . ResourceVersion , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} } 
							 
						 
					
						
							
								
									
										
										
										
											2015-09-10 09:28:53 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  api . IsPodReady ( pod )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												subsets  =  append ( subsets ,  api . EndpointSubset { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													Addresses :  [ ] api . EndpointAddress { epa } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													Ports :      [ ] api . EndpointPort { epp } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												glog . V ( 5 ) . Infof ( "Pod is out of service: %v/%v" ,  pod . Namespace ,  pod . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												subsets  =  append ( subsets ,  api . EndpointSubset { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													NotReadyAddresses :  [ ] api . EndpointAddress { epa } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													Ports :              [ ] api . EndpointPort { epp } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2014-09-27 04:34:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									subsets  =  endpoints . RepackSubsets ( subsets ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-09-27 04:34:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									// See if there's actually an update here.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									currentEndpoints ,  err  :=  e . client . Endpoints ( service . Namespace ) . Get ( service . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  errors . IsNotFound ( err )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											currentEndpoints  =  & api . Endpoints { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ObjectMeta :  api . ObjectMeta { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													Name :    service . Name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													Labels :  service . Labels , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2014-09-27 04:34:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											glog . Errorf ( "Error getting endpoints: %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											e . queue . Add ( key )  // Retry
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return 
							 
						 
					
						
							
								
									
										
										
										
											2014-06-07 07:40:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-17 07:18:02 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									if  reflect . DeepEqual ( currentEndpoints . Subsets ,  subsets )  &&  reflect . DeepEqual ( currentEndpoints . Labels ,  service . Labels )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										glog . V ( 5 ) . Infof ( "endpoints are equal for %s/%s, skipping update" ,  service . Namespace ,  service . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									newEndpoints  :=  currentEndpoints 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									newEndpoints . Subsets  =  subsets 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									newEndpoints . Labels  =  service . Labels 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  len ( currentEndpoints . ResourceVersion )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// No previous endpoints, create them
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										_ ,  err  =  e . client . Endpoints ( service . Namespace ) . Create ( newEndpoints ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Pre-existing
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										_ ,  err  =  e . client . Endpoints ( service . Namespace ) . Update ( newEndpoints ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										glog . Errorf ( "Error updating endpoints: %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										e . queue . Add ( key )  // Retry
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2014-06-07 07:40:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2014-08-11 15:34:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-04-25 05:16:27 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								// checkLeftoverEndpoints lists all currently existing endpoints and adds their
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// service to the queue. This will detect endpoints that exist with no
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// corresponding service; these endpoints need to be deleted. We only need to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// do this once on startup, because in steady-state these are detected (but
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// some stragglers could have been left behind if the endpoint controller
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// reboots).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								func  ( e  * EndpointController )  checkLeftoverEndpoints ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-10 17:39:03 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									list ,  err  :=  e . client . Endpoints ( api . NamespaceAll ) . List ( api . ListOptions { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-04-25 05:16:27 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										glog . Errorf ( "Unable to list endpoints (%v); orphaned endpoints will not be cleaned up. (They're pretty harmless, but you can restart this component if you want another attempt made.)" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  i  :=  range  list . Items  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ep  :=  & list . Items [ i ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										key ,  err  :=  keyFunc ( ep ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											glog . Errorf ( "Unable to get key for endpoint %#v" ,  ep ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										e . queue . Add ( key ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}