-
Notifications
You must be signed in to change notification settings - Fork 5
/
impl.go
107 lines (99 loc) · 3.02 KB
/
impl.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
package secretsmgr
import (
"encoding/json"
"errors"
"fmt"
"time"
"github.com/Cloud-Foundations/golib/pkg/log"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/arn"
"github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/secretsmanager"
)
func getAwsSecret(metadataClient *ec2metadata.EC2Metadata,
secretId string, logger log.DebugLogger) (map[string]string, error) {
if awsService, err := makeService(metadataClient, secretId); err != nil {
return nil, err
} else {
return getAwsSecretUncached(awsService, secretId, logger)
}
}
func getAwsSecretUncached(awsService *secretsmanager.SecretsManager,
secretId string, logger log.DebugLogger) (map[string]string, error) {
input := secretsmanager.GetSecretValueInput{SecretId: aws.String(secretId)}
output, err := awsService.GetSecretValue(&input)
if err != nil {
return nil,
fmt.Errorf("error calling secretsmanager:GetSecretValue: %s", err)
}
if output.SecretString == nil {
return nil, errors.New("no SecretString in secret")
}
secret := []byte(*output.SecretString)
var secrets map[string]string
if err := json.Unmarshal(secret, &secrets); err != nil {
return nil, fmt.Errorf("error unmarshaling secret: %s", err)
}
logger.Debugf(1, "fetched AWS Secret: %s\n", secretId)
return secrets, nil
}
func getRegion(metadataClient *ec2metadata.EC2Metadata,
secretId string) (string, error) {
if arn, err := arn.Parse(secretId); err == nil {
return arn.Region, nil
} else {
return metadataClient.Region()
}
}
func makeService(metadataClient *ec2metadata.EC2Metadata,
secretId string) (*secretsmanager.SecretsManager, error) {
region, err := getRegion(metadataClient, secretId)
if err != nil {
return nil, err
}
awsSession, err := session.NewSession(&aws.Config{
Region: aws.String(region),
})
if err != nil {
return nil, fmt.Errorf("error creating session: %s", err)
}
if awsSession == nil {
return nil, errors.New("awsSession == nil")
}
return secretsmanager.New(awsSession), nil
}
func newCachedSecret(metadataClient *ec2metadata.EC2Metadata,
secretId string, maximumAge time.Duration,
logger log.DebugLogger) (*CachedSecret, error) {
if metadataClient == nil {
return nil, errors.New("nil metadataClient")
}
if awsService, err := makeService(metadataClient, secretId); err != nil {
return nil, err
} else {
logger.Debugf(1, "created cached AWS Secret: %s, lifetime: %s\n",
secretId, maximumAge)
return &CachedSecret{
awsService: awsService,
logger: logger,
maximumAge: maximumAge,
secretId: secretId,
}, nil
}
}
func (cs *CachedSecret) getSecret() (map[string]string, error) {
cs.mutex.Lock()
defer cs.mutex.Unlock()
if time.Since(cs.fetchTime) < cs.maximumAge {
cs.logger.Debugf(1, "fetched AWS Secret: %s from cache\n", cs.secretId)
return cs.secrets, nil
}
secrets, err := getAwsSecretUncached(cs.awsService, cs.secretId, cs.logger)
if err != nil {
return nil, err
}
cs.fetchTime = time.Now()
cs.secrets = secrets
return secrets, nil
}