| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | Copyright 2016 The Kubernetes Authors. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package bootstrap | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2020-02-08 10:16:47 +08:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 	"strings" | 
					
						
							|  |  |  | 	"time" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-18 03:25:06 +08:00
										 |  |  | 	"k8s.io/klog/v2" | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-14 21:43:20 +08:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2019-06-25 19:47:06 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	v1 "k8s.io/api/core/v1" | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 	apierrors "k8s.io/apimachinery/pkg/api/errors" | 
					
						
							| 
									
										
										
										
											2020-02-09 01:30:21 +08:00
										 |  |  | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | 
					
						
							| 
									
										
										
										
											2017-11-14 21:43:20 +08:00
										 |  |  | 	"k8s.io/apimachinery/pkg/labels" | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | 
					
						
							|  |  |  | 	"k8s.io/apimachinery/pkg/util/wait" | 
					
						
							| 
									
										
										
										
											2017-11-14 21:43:20 +08:00
										 |  |  | 	informers "k8s.io/client-go/informers/core/v1" | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 	clientset "k8s.io/client-go/kubernetes" | 
					
						
							| 
									
										
										
										
											2017-11-14 21:43:20 +08:00
										 |  |  | 	corelisters "k8s.io/client-go/listers/core/v1" | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 	"k8s.io/client-go/tools/cache" | 
					
						
							|  |  |  | 	"k8s.io/client-go/util/workqueue" | 
					
						
							| 
									
										
										
										
											2018-08-14 08:22:57 +08:00
										 |  |  | 	bootstrapapi "k8s.io/cluster-bootstrap/token/api" | 
					
						
							| 
									
										
										
										
											2019-06-25 19:47:06 +08:00
										 |  |  | 	jws "k8s.io/cluster-bootstrap/token/jws" | 
					
						
							| 
									
										
										
										
											2017-11-09 06:34:54 +08:00
										 |  |  | 	api "k8s.io/kubernetes/pkg/apis/core" | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-27 03:51:44 +08:00
										 |  |  | // SignerOptions contains options for the Signer
 | 
					
						
							|  |  |  | type SignerOptions struct { | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 	// ConfigMapNamespace is the namespace of the ConfigMap
 | 
					
						
							|  |  |  | 	ConfigMapNamespace string | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// ConfigMapName is the name for the ConfigMap
 | 
					
						
							|  |  |  | 	ConfigMapName string | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// TokenSecretNamespace string is the namespace for token Secrets.
 | 
					
						
							|  |  |  | 	TokenSecretNamespace string | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-24 11:57:53 +08:00
										 |  |  | 	// ConfigMapResync is the time.Duration at which to fully re-list configmaps.
 | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 	// If zero, re-list will be delayed as long as possible
 | 
					
						
							|  |  |  | 	ConfigMapResync time.Duration | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// SecretResync is the time.Duration at which to fully re-list secrets.
 | 
					
						
							|  |  |  | 	// If zero, re-list will be delayed as long as possible
 | 
					
						
							|  |  |  | 	SecretResync time.Duration | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-27 03:51:44 +08:00
										 |  |  | // DefaultSignerOptions returns a set of default options for creating a Signer.
 | 
					
						
							|  |  |  | func DefaultSignerOptions() SignerOptions { | 
					
						
							|  |  |  | 	return SignerOptions{ | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 		ConfigMapNamespace:   api.NamespacePublic, | 
					
						
							| 
									
										
										
										
											2017-02-15 02:29:23 +08:00
										 |  |  | 		ConfigMapName:        bootstrapapi.ConfigMapClusterInfo, | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 		TokenSecretNamespace: api.NamespaceSystem, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-27 03:51:44 +08:00
										 |  |  | // Signer is a controller that signs a ConfigMap with a set of tokens.
 | 
					
						
							|  |  |  | type Signer struct { | 
					
						
							| 
									
										
										
										
											2017-11-14 21:43:20 +08:00
										 |  |  | 	client             clientset.Interface | 
					
						
							|  |  |  | 	configMapKey       string | 
					
						
							|  |  |  | 	configMapName      string | 
					
						
							|  |  |  | 	configMapNamespace string | 
					
						
							|  |  |  | 	secretNamespace    string | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// syncQueue handles synchronizing updates to the ConfigMap.  We'll only ever
 | 
					
						
							|  |  |  | 	// have one item (Named <ConfigMapName>) in this queue. We are using it
 | 
					
						
							|  |  |  | 	// serializes and collapses updates as they can come from both the ConfigMap
 | 
					
						
							|  |  |  | 	// and Secrets controllers.
 | 
					
						
							| 
									
										
										
										
											2017-11-14 21:43:20 +08:00
										 |  |  | 	syncQueue workqueue.RateLimitingInterface | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	secretLister corelisters.SecretLister | 
					
						
							|  |  |  | 	secretSynced cache.InformerSynced | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-14 21:43:20 +08:00
										 |  |  | 	configMapLister corelisters.ConfigMapLister | 
					
						
							|  |  |  | 	configMapSynced cache.InformerSynced | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-27 03:51:44 +08:00
										 |  |  | // NewSigner returns a new *Signer.
 | 
					
						
							|  |  |  | func NewSigner(cl clientset.Interface, secrets informers.SecretInformer, configMaps informers.ConfigMapInformer, options SignerOptions) (*Signer, error) { | 
					
						
							|  |  |  | 	e := &Signer{ | 
					
						
							| 
									
										
										
										
											2017-11-14 21:43:20 +08:00
										 |  |  | 		client:             cl, | 
					
						
							|  |  |  | 		configMapKey:       options.ConfigMapNamespace + "/" + options.ConfigMapName, | 
					
						
							|  |  |  | 		configMapName:      options.ConfigMapName, | 
					
						
							|  |  |  | 		configMapNamespace: options.ConfigMapNamespace, | 
					
						
							|  |  |  | 		secretNamespace:    options.TokenSecretNamespace, | 
					
						
							|  |  |  | 		secretLister:       secrets.Lister(), | 
					
						
							|  |  |  | 		secretSynced:       secrets.Informer().HasSynced, | 
					
						
							|  |  |  | 		configMapLister:    configMaps.Lister(), | 
					
						
							|  |  |  | 		configMapSynced:    configMaps.Informer().HasSynced, | 
					
						
							|  |  |  | 		syncQueue:          workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "bootstrap_signer_queue"), | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-11-14 21:43:20 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	configMaps.Informer().AddEventHandlerWithResyncPeriod( | 
					
						
							|  |  |  | 		cache.FilteringResourceEventHandler{ | 
					
						
							|  |  |  | 			FilterFunc: func(obj interface{}) bool { | 
					
						
							|  |  |  | 				switch t := obj.(type) { | 
					
						
							|  |  |  | 				case *v1.ConfigMap: | 
					
						
							|  |  |  | 					return t.Name == options.ConfigMapName && t.Namespace == options.ConfigMapNamespace | 
					
						
							|  |  |  | 				default: | 
					
						
							|  |  |  | 					utilruntime.HandleError(fmt.Errorf("object passed to %T that is not expected: %T", e, obj)) | 
					
						
							|  |  |  | 					return false | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2017-11-14 21:43:20 +08:00
										 |  |  | 			Handler: cache.ResourceEventHandlerFuncs{ | 
					
						
							|  |  |  | 				AddFunc:    func(_ interface{}) { e.pokeConfigMapSync() }, | 
					
						
							|  |  |  | 				UpdateFunc: func(_, _ interface{}) { e.pokeConfigMapSync() }, | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		options.ConfigMapResync, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-14 21:43:20 +08:00
										 |  |  | 	secrets.Informer().AddEventHandlerWithResyncPeriod( | 
					
						
							|  |  |  | 		cache.FilteringResourceEventHandler{ | 
					
						
							|  |  |  | 			FilterFunc: func(obj interface{}) bool { | 
					
						
							|  |  |  | 				switch t := obj.(type) { | 
					
						
							|  |  |  | 				case *v1.Secret: | 
					
						
							|  |  |  | 					return t.Type == bootstrapapi.SecretTypeBootstrapToken && t.Namespace == e.secretNamespace | 
					
						
							|  |  |  | 				default: | 
					
						
							|  |  |  | 					utilruntime.HandleError(fmt.Errorf("object passed to %T that is not expected: %T", e, obj)) | 
					
						
							|  |  |  | 					return false | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 			}, | 
					
						
							| 
									
										
										
										
											2017-11-14 21:43:20 +08:00
										 |  |  | 			Handler: cache.ResourceEventHandlerFuncs{ | 
					
						
							|  |  |  | 				AddFunc:    func(_ interface{}) { e.pokeConfigMapSync() }, | 
					
						
							|  |  |  | 				UpdateFunc: func(_, _ interface{}) { e.pokeConfigMapSync() }, | 
					
						
							|  |  |  | 				DeleteFunc: func(_ interface{}) { e.pokeConfigMapSync() }, | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		options.SecretResync, | 
					
						
							|  |  |  | 	) | 
					
						
							| 
									
										
										
										
											2017-11-14 21:43:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-31 22:19:55 +08:00
										 |  |  | 	return e, nil | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Run runs controller loops and returns when they are done
 | 
					
						
							| 
									
										
										
										
											2021-04-23 02:20:58 +08:00
										 |  |  | func (e *Signer) Run(ctx context.Context) { | 
					
						
							| 
									
										
										
										
											2017-11-14 21:43:20 +08:00
										 |  |  | 	// Shut down queues
 | 
					
						
							|  |  |  | 	defer utilruntime.HandleCrash() | 
					
						
							|  |  |  | 	defer e.syncQueue.ShutDown() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-23 02:20:58 +08:00
										 |  |  | 	if !cache.WaitForNamedCacheSync("bootstrap_signer", ctx.Done(), e.configMapSynced, e.secretSynced) { | 
					
						
							| 
									
										
										
										
											2017-11-14 21:43:20 +08:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-10 02:49:10 +08:00
										 |  |  | 	klog.V(5).Infof("Starting workers") | 
					
						
							| 
									
										
										
										
											2021-04-23 02:20:58 +08:00
										 |  |  | 	go wait.UntilWithContext(ctx, e.serviceConfigMapQueue, 0) | 
					
						
							|  |  |  | 	<-ctx.Done() | 
					
						
							| 
									
										
										
										
											2018-11-10 02:49:10 +08:00
										 |  |  | 	klog.V(1).Infof("Shutting down") | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-27 03:51:44 +08:00
										 |  |  | func (e *Signer) pokeConfigMapSync() { | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 	e.syncQueue.Add(e.configMapKey) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-23 02:20:58 +08:00
										 |  |  | func (e *Signer) serviceConfigMapQueue(ctx context.Context) { | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 	key, quit := e.syncQueue.Get() | 
					
						
							|  |  |  | 	if quit { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer e.syncQueue.Done(key) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-23 02:20:58 +08:00
										 |  |  | 	e.signConfigMap(ctx) | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // signConfigMap computes the signatures on our latest cached objects and writes
 | 
					
						
							|  |  |  | // back if necessary.
 | 
					
						
							| 
									
										
										
										
											2021-04-23 02:20:58 +08:00
										 |  |  | func (e *Signer) signConfigMap(ctx context.Context) { | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 	origCM := e.getConfigMap() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if origCM == nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var needUpdate = false | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-15 20:14:21 +08:00
										 |  |  | 	newCM := origCM.DeepCopy() | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// First capture the config we are signing
 | 
					
						
							| 
									
										
										
										
											2017-02-15 02:29:23 +08:00
										 |  |  | 	content, ok := newCM.Data[bootstrapapi.KubeConfigKey] | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 	if !ok { | 
					
						
							| 
									
										
										
										
											2018-11-10 02:49:10 +08:00
										 |  |  | 		klog.V(3).Infof("No %s key in %s/%s ConfigMap", bootstrapapi.KubeConfigKey, origCM.Namespace, origCM.Name) | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Next remove and save all existing signatures
 | 
					
						
							|  |  |  | 	sigs := map[string]string{} | 
					
						
							|  |  |  | 	for key, value := range newCM.Data { | 
					
						
							| 
									
										
										
										
											2017-02-15 02:29:23 +08:00
										 |  |  | 		if strings.HasPrefix(key, bootstrapapi.JWSSignatureKeyPrefix) { | 
					
						
							|  |  |  | 			tokenID := strings.TrimPrefix(key, bootstrapapi.JWSSignatureKeyPrefix) | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 			sigs[tokenID] = value | 
					
						
							|  |  |  | 			delete(newCM.Data, key) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Now recompute signatures and store them on the new map
 | 
					
						
							|  |  |  | 	tokens := e.getTokens() | 
					
						
							|  |  |  | 	for tokenID, tokenValue := range tokens { | 
					
						
							| 
									
										
										
										
											2019-06-25 19:47:06 +08:00
										 |  |  | 		sig, err := jws.ComputeDetachedSignature(content, tokenID, tokenValue) | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			utilruntime.HandleError(err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Check to see if this signature is changed or new.
 | 
					
						
							|  |  |  | 		oldSig, _ := sigs[tokenID] | 
					
						
							|  |  |  | 		if sig != oldSig { | 
					
						
							|  |  |  | 			needUpdate = true | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		delete(sigs, tokenID) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-15 02:29:23 +08:00
										 |  |  | 		newCM.Data[bootstrapapi.JWSSignatureKeyPrefix+tokenID] = sig | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// If we have signatures left over we know that some signatures were
 | 
					
						
							|  |  |  | 	// removed.  We now need to update the ConfigMap
 | 
					
						
							|  |  |  | 	if len(sigs) != 0 { | 
					
						
							|  |  |  | 		needUpdate = true | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if needUpdate { | 
					
						
							| 
									
										
										
										
											2021-04-23 02:20:58 +08:00
										 |  |  | 		e.updateConfigMap(ctx, newCM) | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-23 02:20:58 +08:00
										 |  |  | func (e *Signer) updateConfigMap(ctx context.Context, cm *v1.ConfigMap) { | 
					
						
							|  |  |  | 	_, err := e.client.CoreV1().ConfigMaps(cm.Namespace).Update(ctx, cm, metav1.UpdateOptions{}) | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 	if err != nil && !apierrors.IsConflict(err) && !apierrors.IsNotFound(err) { | 
					
						
							| 
									
										
										
										
											2018-11-10 02:49:10 +08:00
										 |  |  | 		klog.V(3).Infof("Error updating ConfigMap: %v", err) | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // getConfigMap gets the ConfigMap we are interested in
 | 
					
						
							| 
									
										
										
										
											2019-02-27 03:51:44 +08:00
										 |  |  | func (e *Signer) getConfigMap() *v1.ConfigMap { | 
					
						
							| 
									
										
										
										
											2017-11-14 21:43:20 +08:00
										 |  |  | 	configMap, err := e.configMapLister.ConfigMaps(e.configMapNamespace).Get(e.configMapName) | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// If we can't get the configmap just return nil. The resync will eventually
 | 
					
						
							|  |  |  | 	// sync things up.
 | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-11-14 21:43:20 +08:00
										 |  |  | 		if !apierrors.IsNotFound(err) { | 
					
						
							|  |  |  | 			utilruntime.HandleError(err) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-14 21:43:20 +08:00
										 |  |  | 	return configMap | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-27 03:51:44 +08:00
										 |  |  | func (e *Signer) listSecrets() []*v1.Secret { | 
					
						
							| 
									
										
										
										
											2017-11-14 21:43:20 +08:00
										 |  |  | 	secrets, err := e.secretLister.Secrets(e.secretNamespace).List(labels.Everything()) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		utilruntime.HandleError(err) | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	items := []*v1.Secret{} | 
					
						
							| 
									
										
										
										
											2017-11-14 21:43:20 +08:00
										 |  |  | 	for _, secret := range secrets { | 
					
						
							|  |  |  | 		if secret.Type == bootstrapapi.SecretTypeBootstrapToken { | 
					
						
							|  |  |  | 			items = append(items, secret) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return items | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // getTokens returns a map of tokenID->tokenSecret. It ensures the token is
 | 
					
						
							|  |  |  | // valid for signing.
 | 
					
						
							| 
									
										
										
										
											2019-02-27 03:51:44 +08:00
										 |  |  | func (e *Signer) getTokens() map[string]string { | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 	ret := map[string]string{} | 
					
						
							|  |  |  | 	secretObjs := e.listSecrets() | 
					
						
							|  |  |  | 	for _, secret := range secretObjs { | 
					
						
							|  |  |  | 		tokenID, tokenSecret, ok := validateSecretForSigning(secret) | 
					
						
							|  |  |  | 		if !ok { | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Check and warn for duplicate secrets. Behavior here will be undefined.
 | 
					
						
							|  |  |  | 		if _, ok := ret[tokenID]; ok { | 
					
						
							| 
									
										
										
										
											2017-02-21 02:21:07 +08:00
										 |  |  | 			// This should never happen as we ensure a consistent secret name.
 | 
					
						
							|  |  |  | 			// But leave this in here just in case.
 | 
					
						
							| 
									
										
										
										
											2018-11-10 02:49:10 +08:00
										 |  |  | 			klog.V(1).Infof("Duplicate bootstrap tokens found for id %s, ignoring on in %s/%s", tokenID, secret.Namespace, secret.Name) | 
					
						
							| 
									
										
										
										
											2017-02-10 07:53:23 +08:00
										 |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// This secret looks good, add it to the list.
 | 
					
						
							|  |  |  | 		ret[tokenID] = tokenSecret | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret | 
					
						
							|  |  |  | } |