|
7 | 7 | "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient"
|
8 | 8 | "github.com/sirupsen/logrus"
|
9 | 9 | corev1 "k8s.io/api/core/v1"
|
10 |
| - apierrors "k8s.io/apimachinery/pkg/api/errors" |
11 | 10 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
12 | 11 | )
|
13 | 12 |
|
@@ -50,29 +49,45 @@ func (r *BearerTokenRetriever) Retrieve(reference *corev1.ObjectReference) (toke
|
50 | 49 | }
|
51 | 50 |
|
52 | 51 | func getAPISecret(logger logrus.FieldLogger, kubeclient operatorclient.ClientInterface, sa *corev1.ServiceAccount) (APISecret *corev1.Secret, err error) {
|
53 |
| - for _, ref := range sa.Secrets { |
54 |
| - // corev1.ObjectReference only has Name populated. |
55 |
| - secret, getErr := kubeclient.KubernetesInterface().CoreV1().Secrets(sa.GetNamespace()).Get(context.TODO(), ref.Name, metav1.GetOptions{}) |
56 |
| - if getErr != nil { |
57 |
| - if apierrors.IsNotFound(getErr) { |
58 |
| - logger.Warnf("skipping secret %s - %v", ref.Name, getErr) |
59 |
| - continue |
60 |
| - } |
| 52 | + seList, err := kubeclient.KubernetesInterface().CoreV1().Secrets(sa.GetNamespace()).List(context.TODO(), metav1.ListOptions{}) |
| 53 | + if err != nil { |
| 54 | + logger.Errorf("unable to retrieve list of secrets in the namespace %s - %v", sa.GetNamespace(), err) |
| 55 | + return nil, err |
| 56 | + } |
| 57 | + secrets := filterSecretsBySAName(sa.Name, seList) |
61 | 58 |
|
62 |
| - err = getErr |
63 |
| - break |
| 59 | + for _, ref := range sa.Secrets { |
| 60 | + if _, ok := secrets[ref.Name]; !ok { |
| 61 | + logger.Warnf("skipping secret %s: secret not found", ref.Name) |
| 62 | + continue |
64 | 63 | }
|
| 64 | + } |
65 | 65 |
|
| 66 | + for _, secret := range secrets { |
66 | 67 | // Validate that this is a token for API access.
|
67 | 68 | if !IsServiceAccountToken(secret, sa) {
|
68 |
| - logger.Warnf("skipping secret %s - %v", ref.Name, getErr) |
| 69 | + logger.Warnf("skipping secret %s: not token secret", secret.Name) |
69 | 70 | continue
|
70 | 71 | }
|
71 |
| - |
72 | 72 | // The first eligible secret that has an API access token is returned.
|
73 | 73 | APISecret = secret
|
74 | 74 | break
|
75 | 75 | }
|
76 | 76 |
|
77 | 77 | return
|
78 | 78 | }
|
| 79 | + |
| 80 | +// filterSecretsBySAName returna a maps of secrets that are associated with a |
| 81 | +// specific ServiceAccount via annotations kubernetes.io/service-account.name |
| 82 | +func filterSecretsBySAName(saName string, secrets *corev1.SecretList) map[string]*corev1.Secret { |
| 83 | + secretMap := make(map[string]*corev1.Secret) |
| 84 | + for _, ref := range secrets.Items { |
| 85 | + annotations := ref.GetAnnotations() |
| 86 | + value := annotations[corev1.ServiceAccountNameKey] |
| 87 | + if value == saName { |
| 88 | + secretMap[ref.Name] = &ref |
| 89 | + } |
| 90 | + } |
| 91 | + |
| 92 | + return secretMap |
| 93 | +} |
0 commit comments