...

Source file src/k8s.io/kubernetes/pkg/kubelet/secret/secret_manager_test.go

Documentation: k8s.io/kubernetes/pkg/kubelet/secret

     1  /*
     2  Copyright 2018 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package secret
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"strings"
    23  	"testing"
    24  	"time"
    25  
    26  	"k8s.io/api/core/v1"
    27  
    28  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    29  	"k8s.io/apimachinery/pkg/runtime"
    30  
    31  	clientset "k8s.io/client-go/kubernetes"
    32  	"k8s.io/client-go/kubernetes/fake"
    33  	"k8s.io/kubernetes/pkg/kubelet/util/manager"
    34  	"k8s.io/utils/clock"
    35  )
    36  
    37  func checkObject(t *testing.T, store manager.Store, ns, name string, shouldExist bool) {
    38  	_, err := store.Get(ns, name)
    39  	if shouldExist && err != nil {
    40  		t.Errorf("unexpected actions: %#v", err)
    41  	}
    42  	if !shouldExist && (err == nil || !strings.Contains(err.Error(), fmt.Sprintf("object %q/%q not registered", ns, name))) {
    43  		t.Errorf("unexpected actions: %#v", err)
    44  	}
    45  }
    46  
    47  func noObjectTTL() (time.Duration, bool) {
    48  	return time.Duration(0), false
    49  }
    50  
    51  func getSecret(fakeClient clientset.Interface) manager.GetObjectFunc {
    52  	return func(namespace, name string, opts metav1.GetOptions) (runtime.Object, error) {
    53  		return fakeClient.CoreV1().Secrets(namespace).Get(context.TODO(), name, opts)
    54  	}
    55  }
    56  
    57  type envSecrets struct {
    58  	envVarNames  []string
    59  	envFromNames []string
    60  }
    61  
    62  type secretsToAttach struct {
    63  	imagePullSecretNames []string
    64  	containerEnvSecrets  []envSecrets
    65  }
    66  
    67  func podWithSecrets(ns, podName string, toAttach secretsToAttach) *v1.Pod {
    68  	pod := &v1.Pod{
    69  		ObjectMeta: metav1.ObjectMeta{
    70  			Namespace: ns,
    71  			Name:      podName,
    72  		},
    73  		Spec: v1.PodSpec{},
    74  	}
    75  	for _, name := range toAttach.imagePullSecretNames {
    76  		pod.Spec.ImagePullSecrets = append(
    77  			pod.Spec.ImagePullSecrets, v1.LocalObjectReference{Name: name})
    78  	}
    79  	for i, secrets := range toAttach.containerEnvSecrets {
    80  		container := v1.Container{
    81  			Name: fmt.Sprintf("container-%d", i),
    82  		}
    83  		for _, name := range secrets.envFromNames {
    84  			envFrom := v1.EnvFromSource{
    85  				SecretRef: &v1.SecretEnvSource{
    86  					LocalObjectReference: v1.LocalObjectReference{
    87  						Name: name,
    88  					},
    89  				},
    90  			}
    91  			container.EnvFrom = append(container.EnvFrom, envFrom)
    92  		}
    93  
    94  		for _, name := range secrets.envVarNames {
    95  			envSource := &v1.EnvVarSource{
    96  				SecretKeyRef: &v1.SecretKeySelector{
    97  					LocalObjectReference: v1.LocalObjectReference{
    98  						Name: name,
    99  					},
   100  				},
   101  			}
   102  			container.Env = append(container.Env, v1.EnvVar{ValueFrom: envSource})
   103  		}
   104  		pod.Spec.Containers = append(pod.Spec.Containers, container)
   105  	}
   106  	return pod
   107  }
   108  
   109  func TestCacheBasedSecretManager(t *testing.T) {
   110  	fakeClient := &fake.Clientset{}
   111  	store := manager.NewObjectStore(getSecret(fakeClient), clock.RealClock{}, noObjectTTL, 0)
   112  	manager := &secretManager{
   113  		manager: manager.NewCacheBasedManager(store, getSecretNames),
   114  	}
   115  
   116  	// Create a pod with some secrets.
   117  	s1 := secretsToAttach{
   118  		imagePullSecretNames: []string{"s1"},
   119  		containerEnvSecrets: []envSecrets{
   120  			{envVarNames: []string{"s1"}},
   121  			{envVarNames: []string{"s2"}},
   122  			{envFromNames: []string{"s20"}},
   123  		},
   124  	}
   125  	manager.RegisterPod(podWithSecrets("ns1", "name1", s1))
   126  	// Update the pod with a different secrets.
   127  	s2 := secretsToAttach{
   128  		imagePullSecretNames: []string{"s1"},
   129  		containerEnvSecrets: []envSecrets{
   130  			{envVarNames: []string{"s3"}},
   131  			{envVarNames: []string{"s4"}},
   132  			{envFromNames: []string{"s40"}},
   133  		},
   134  	}
   135  	manager.RegisterPod(podWithSecrets("ns1", "name1", s2))
   136  	// Create another pod, but with same secrets in different namespace.
   137  	manager.RegisterPod(podWithSecrets("ns2", "name2", s2))
   138  	// Create and delete a pod with some other secrets.
   139  	s3 := secretsToAttach{
   140  		imagePullSecretNames: []string{"s5"},
   141  		containerEnvSecrets: []envSecrets{
   142  			{envVarNames: []string{"s6"}},
   143  			{envFromNames: []string{"s60"}},
   144  		},
   145  	}
   146  	manager.RegisterPod(podWithSecrets("ns3", "name", s3))
   147  	manager.UnregisterPod(podWithSecrets("ns3", "name", s3))
   148  
   149  	// We should have only: s1, s3 and s4 secrets in namespaces: ns1 and ns2.
   150  	for _, ns := range []string{"ns1", "ns2", "ns3"} {
   151  		for _, secret := range []string{"s1", "s2", "s3", "s4", "s5", "s6", "s20", "s40", "s50"} {
   152  			shouldExist :=
   153  				(secret == "s1" || secret == "s3" || secret == "s4" || secret == "s40") && (ns == "ns1" || ns == "ns2")
   154  			checkObject(t, store, ns, secret, shouldExist)
   155  		}
   156  	}
   157  }
   158  

View as plain text