1
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
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
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
137 manager.RegisterPod(podWithSecrets("ns2", "name2", s2))
138
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
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