-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
Copy pathaws_secretManager_handler.go
134 lines (121 loc) · 5.34 KB
/
aws_secretManager_handler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package resolver
import (
"context"
"fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/secretsmanager"
"github.com/go-logr/logr"
kedav1alpha1 "github.com/kedacore/keda/v2/apis/keda/v1alpha1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
corev1listers "k8s.io/client-go/listers/core/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
)
type AwsSecretManagerHandler struct {
secretManager *kedav1alpha1.AwsSecretManager
session *session.Session
secretclient *secretsmanager.SecretsManager
}
func NewAwsSecretManagerHandler(a *kedav1alpha1.AwsSecretManager) *AwsSecretManagerHandler {
return &AwsSecretManagerHandler{
secretManager: a,
}
}
func (ash *AwsSecretManagerHandler) Read(ctx context.Context, secretName, versionId, versionStage string) (string, error) {
input := &secretsmanager.GetSecretValueInput{
SecretId: aws.String(secretName),
}
if versionId != "" {
input.VersionId = aws.String(versionId)
}
if versionStage != "" {
input.VersionStage = aws.String(versionStage)
}
result, err := ash.secretclient.GetSecretValue(input)
if err != nil {
if aerr, ok := err.(awserr.Error); ok {
switch aerr.Code() {
case secretsmanager.ErrCodeResourceNotFoundException:
err = fmt.Errorf(secretsmanager.ErrCodeResourceNotFoundException+": %s", aerr.Error())
return "", err
case secretsmanager.ErrCodeInvalidParameterException:
err = fmt.Errorf(secretsmanager.ErrCodeInvalidParameterException+": %s", aerr.Error())
return "", err
case secretsmanager.ErrCodeInvalidRequestException:
err = fmt.Errorf(secretsmanager.ErrCodeInvalidRequestException+": %s", aerr.Error())
return "", err
case secretsmanager.ErrCodeDecryptionFailure:
err = fmt.Errorf(secretsmanager.ErrCodeDecryptionFailure+": %s", aerr.Error())
return "", err
case secretsmanager.ErrCodeInternalServiceError:
err = fmt.Errorf(secretsmanager.ErrCodeInternalServiceError+": %s", aerr.Error())
return "", err
default:
err = fmt.Errorf(aerr.Error())
return "", err
}
} else {
err = fmt.Errorf(err.Error())
return "", err
}
}
return *result.SecretString, nil
}
func (ash *AwsSecretManagerHandler) Initialize(ctx context.Context, client client.Client, logger logr.Logger, triggerNamespace string, secretsLister corev1listers.SecretLister, podTemplateSpec *corev1.PodTemplateSpec) error {
config, err := ash.getcredentials(ctx, client, logger, triggerNamespace, secretsLister, podTemplateSpec)
if err != nil {
return err
}
if ash.secretManager.Cloud.Region != "" {
config.WithRegion(ash.secretManager.Cloud.Region)
}
if ash.secretManager.Cloud.Endpoint != "" {
config.WithEndpoint(ash.secretManager.Cloud.Endpoint)
}
ash.session = session.Must(session.NewSession())
ash.secretclient = secretsmanager.New(ash.session, config)
return err
}
func (ash *AwsSecretManagerHandler) getcredentials(ctx context.Context, client client.Client, logger logr.Logger, triggerNamespace string, secretsLister corev1listers.SecretLister, podTemplateSpec *corev1.PodTemplateSpec) (*aws.Config, error) {
config := aws.NewConfig()
podIdentity := ash.secretManager.PodIdentity
if podIdentity == nil {
podIdentity = &kedav1alpha1.AuthPodIdentity{}
}
switch podIdentity.Provider {
case "", kedav1alpha1.PodIdentityProviderNone:
accessKeyId := resolveAuthSecret(ctx, client, logger, ash.secretManager.Credentials.AccessKey.SecretKeyRef.Name, triggerNamespace, ash.secretManager.Credentials.AccessKey.SecretKeyRef.Key, secretsLister)
accessSecretKey := resolveAuthSecret(ctx, client, logger, ash.secretManager.Credentials.AccessSecretKey.SecretKeyRef.Name, triggerNamespace, ash.secretManager.Credentials.AccessSecretKey.SecretKeyRef.Key, secretsLister)
if accessKeyId == "" || accessSecretKey == "" {
return nil, fmt.Errorf("AccessKeyId and AccessSecretKey are expected when not using a pod identity provider")
}
config.WithCredentials(credentials.NewStaticCredentials(accessKeyId, accessSecretKey, ""))
return config, nil
case kedav1alpha1.PodIdentityProviderAwsEKS:
awsRoleArn, err := ash.getRoleArnAwsEKS(ctx, client, logger, triggerNamespace, podTemplateSpec)
if err != nil {
return nil, fmt.Errorf("error resolving role arn for AwsEKS pod identity: %s", err)
}
config.WithCredentials(stscreds.NewCredentials(ash.session, awsRoleArn))
return config, nil
case kedav1alpha1.PodIdentityProviderAwsKiam:
awsRoleArn := podTemplateSpec.ObjectMeta.Annotations[kedav1alpha1.PodIdentityAnnotationKiam]
config.WithCredentials(stscreds.NewCredentials(ash.session, awsRoleArn))
return config, nil
default:
return nil, fmt.Errorf("pod identity provider %s not supported", podIdentity.Provider)
}
}
func (ash *AwsSecretManagerHandler) getRoleArnAwsEKS(ctx context.Context, client client.Client, logger logr.Logger, triggerNamespace string, podTemplateSpec *corev1.PodTemplateSpec) (string, error) {
serviceAccountName := podTemplateSpec.Spec.ServiceAccountName
serviceAccount := &corev1.ServiceAccount{}
err := client.Get(ctx, types.NamespacedName{Name: serviceAccountName, Namespace: triggerNamespace}, serviceAccount)
if err != nil {
return "", err
}
return serviceAccount.Annotations[kedav1alpha1.PodIdentityAnnotationEKS], nil
}