Skip to content

Commit ba03cee

Browse files
committed
(bug) Fix service account token secret reference
Problem: The filterSecretsBySAName function attempts to identify all service account token secrets related to a serviceAccount. To do so, the filterSecretsBySAName function uses a range-for loop to iterate over entries in the secrets argument. If a valid service account token secret is found, a pointer to the range-for loop's value variable is added to a map of results. Unfortunately, if a valid entry is found in the middle of the list of secrets, the value returned by the range-for loop is updated, causes the entry in the map to change. Solution: Add a pointer to the actual secret instead of the range-for loop's value variable. Signed-off-by: Alexander Greene <[email protected]>
1 parent edffd9c commit ba03cee

File tree

2 files changed

+99
-2
lines changed

2 files changed

+99
-2
lines changed

pkg/lib/scoped/token_retriever.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,11 @@ func getAPISecret(logger logrus.FieldLogger, kubeclient operatorclient.ClientInt
8181
// specific ServiceAccount via annotations kubernetes.io/service-account.name
8282
func filterSecretsBySAName(saName string, secrets *corev1.SecretList) map[string]*corev1.Secret {
8383
secretMap := make(map[string]*corev1.Secret)
84-
for _, ref := range secrets.Items {
84+
for i, ref := range secrets.Items {
8585
annotations := ref.GetAnnotations()
8686
value := annotations[corev1.ServiceAccountNameKey]
8787
if value == saName {
88-
secretMap[ref.Name] = &ref
88+
secretMap[ref.Name] = &secrets.Items[i]
8989
}
9090
}
9191

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package scoped
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
corev1 "k8s.io/api/core/v1"
8+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
9+
)
10+
11+
const serviceAccountName = "foo"
12+
13+
func TestFilterSecretsBySAName(t *testing.T) {
14+
tests := []struct {
15+
name string
16+
secrets *corev1.SecretList
17+
wantedSecretNames []string
18+
}{
19+
{
20+
name: "NoSecretFound",
21+
secrets: &corev1.SecretList{
22+
Items: []corev1.Secret{
23+
*newSecret("aSecret"),
24+
*newSecret("someSecret"),
25+
*newSecret("zSecret"),
26+
},
27+
},
28+
wantedSecretNames: []string{},
29+
},
30+
{
31+
name: "FirstSecretFound",
32+
secrets: &corev1.SecretList{
33+
Items: []corev1.Secret{
34+
*newSecret("aSecret", withAnnotations(map[string]string{corev1.ServiceAccountNameKey: serviceAccountName})),
35+
*newSecret("someSecret"),
36+
*newSecret("zSecret"),
37+
},
38+
},
39+
wantedSecretNames: []string{"aSecret"},
40+
},
41+
42+
{
43+
name: "SecondSecretFound",
44+
secrets: &corev1.SecretList{
45+
Items: []corev1.Secret{
46+
*newSecret("aSecret"),
47+
*newSecret("someSecret", withAnnotations(map[string]string{corev1.ServiceAccountNameKey: serviceAccountName})),
48+
*newSecret("zSecret"),
49+
},
50+
},
51+
wantedSecretNames: []string{"someSecret"},
52+
},
53+
54+
{
55+
name: "ThirdSecretFound",
56+
secrets: &corev1.SecretList{
57+
Items: []corev1.Secret{
58+
*newSecret("aSecret"),
59+
*newSecret("someSecret"),
60+
*newSecret("zSecret", withAnnotations(map[string]string{corev1.ServiceAccountNameKey: serviceAccountName})),
61+
},
62+
},
63+
wantedSecretNames: []string{"zSecret"},
64+
},
65+
}
66+
67+
for _, tt := range tests {
68+
t.Run(tt.name, func(t *testing.T) {
69+
got := filterSecretsBySAName(serviceAccountName, tt.secrets)
70+
require.Equal(t, len(tt.wantedSecretNames), len(got))
71+
for _, wantedSecretName := range tt.wantedSecretNames {
72+
require.NotNil(t, got[wantedSecretName])
73+
require.Equal(t, wantedSecretName, got[wantedSecretName].GetName())
74+
}
75+
})
76+
}
77+
}
78+
79+
type secretOption func(*corev1.Secret)
80+
81+
func withAnnotations(annotations map[string]string) secretOption {
82+
return func(s *corev1.Secret) {
83+
s.SetAnnotations(annotations)
84+
}
85+
}
86+
87+
func newSecret(name string, opts ...secretOption) *corev1.Secret {
88+
s := &corev1.Secret{
89+
ObjectMeta: metav1.ObjectMeta{
90+
Name: name,
91+
},
92+
}
93+
for _, opt := range opts {
94+
opt(s)
95+
}
96+
return s
97+
}

0 commit comments

Comments
 (0)