-
Notifications
You must be signed in to change notification settings - Fork 1
/
secret-manager.go
87 lines (75 loc) · 2.64 KB
/
secret-manager.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
package aws
import (
"context"
"encoding/json"
"fmt"
"github.com/aws/aws-sdk-go/aws"
"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/aws/aws-sdk-go/service/secretsmanager/secretsmanageriface"
log "github.com/sirupsen/logrus"
)
// Config configuration for AWS
type Config struct {
Region string
SecretName *string
PreviousVersion string
RoleARN string
}
func newSecretManagerClient(region, roleArn string) *secretsmanager.SecretsManager {
log.Infof("Using region: %s", region)
sess := session.Must(session.NewSession(&aws.Config{
Region: aws.String(region), // Sessions Manager functions require region configuration
}))
if roleArn != "" {
log.Debugf("Using Role Arn: %s", roleArn)
// the new Credentials object wraps the AssumeRoleProvider
sess.Config.Credentials = stscreds.NewCredentials(sess, roleArn)
}
// Create a SecretsManager client with additional configuration
return secretsmanager.New(sess, aws.NewConfig().WithRegion(region))
}
// GetSecretData will fetch the secret from secret manager
func GetSecretData(api secretsmanageriface.SecretsManagerAPI, secretValueInput *secretsmanager.GetSecretValueInput) (map[string]interface{}, error) {
var secretData map[string]interface{}
ctx := context.Background()
secretValueOutput, err := api.GetSecretValueWithContext(ctx, secretValueInput)
if err != nil {
return nil, fmt.Errorf("failed to access secret version: %w", err)
}
err = json.Unmarshal([]byte(*secretValueOutput.SecretString), &secretData)
if err != nil {
return nil, fmt.Errorf("bad secret JSON data, can not decode secret JSON data: %w", err)
}
return secretData, nil
}
func buildSecretValueInput(cfg *Config) (*secretsmanager.GetSecretValueInput, error) {
secretName := cfg.SecretName
if aws.StringValue(secretName) == "" {
return nil, fmt.Errorf("error: missing SECRET_NAME environment variable")
}
versionStage := aws.String("AWSCURRENT")
if cfg.PreviousVersion != "" {
versionStage = aws.String("AWSPREVIOUS")
}
secretValueInput := &secretsmanager.GetSecretValueInput{
SecretId: secretName,
VersionStage: versionStage,
}
return secretValueInput, nil
}
// RetrieveSecret from AWS secrets manager
func RetrieveSecret(cfg *Config) (map[string]interface{}, error) {
log.Info("Using AWS Secret Manager")
secretValueInput, err := buildSecretValueInput(cfg)
if err != nil {
return nil, err
}
client := newSecretManagerClient(cfg.Region, cfg.RoleARN)
secretData, err := GetSecretData(client, secretValueInput)
if err != nil {
return nil, err
}
return secretData, nil
}