This repository has been archived by the owner on Jan 13, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathawssecretsmanager.go
119 lines (97 loc) · 2.96 KB
/
awssecretsmanager.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
package secrets
import (
"context"
"errors"
"fmt"
"strings"
"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/session"
"github.com/aws/aws-sdk-go/service/secretsmanager"
)
var _ SecretStorage = &AWSSecretsManager{}
type AWSSecretsManager struct {
AWSSecretsManagerConfig
client *secretsmanager.SecretsManager
}
type AWSSecretsManagerConfig struct {
AWSConfig
UseSecretMaps bool // TODO: support storing to json maps if this is enabled.
}
func NewAWSSecretsManagerFromConfig(cfg AWSSecretsManagerConfig) (*AWSSecretsManager, error) {
sess, err := session.NewSession()
if err != nil {
return nil, fmt.Errorf("creating aws session: %w", err)
}
awscfg := aws.NewConfig().
WithCredentials(credentials.NewCredentials(&credentials.StaticProvider{
Value: credentials.Value{
AccessKeyID: cfg.AccessKeyID,
SecretAccessKey: cfg.SecretAccessKey,
},
})).
WithEndpoint(cfg.Endpoint).
WithRegion(cfg.Region)
awssm := secretsmanager.New(sess, awscfg)
sm := &AWSSecretsManager{
AWSSecretsManagerConfig: cfg,
client: awssm,
}
return sm, nil
}
func NewAWSSecretsManager(client *secretsmanager.SecretsManager) *AWSSecretsManager {
return &AWSSecretsManager{
client: client,
}
}
// SetSecret
// must have the secretsmanager:CreateSecret permission
// if using tags, must have secretsmanager:TagResource
// if using kms customer-managed keys, also need:
// - kms:GenerateDataKey
// - kms:Decrypt
func (s *AWSSecretsManager) SetSecret(name string, secret []byte) error {
name = strings.ReplaceAll(name, ":", "_")
_, err := s.client.CreateSecretWithContext(context.TODO(), &secretsmanager.CreateSecretInput{
Name: &name,
SecretBinary: secret,
})
if err != nil {
var aerr awserr.Error
if errors.As(err, &aerr) {
if aerr.Code() == secretsmanager.ErrCodeResourceExistsException {
// try replacing instead
_, err = s.client.UpdateSecretWithContext(context.TODO(), &secretsmanager.UpdateSecretInput{
SecretBinary: secret,
SecretId: &name,
})
if err != nil {
return fmt.Errorf("aws sm: update secret: %w", err)
}
return nil
}
}
return fmt.Errorf("aws sm: creating secret: %w", err)
}
return nil
}
// GetSecret
// must have permission secretsmanager:GetSecretValue
// kms:Decrypt - required only if you use a customer-managed Amazon Web Services KMS key to encrypt the secret
func (s *AWSSecretsManager) GetSecret(name string) (secret []byte, err error) {
name = strings.ReplaceAll(name, ":", "_")
sec, err := s.client.GetSecretValueWithContext(context.TODO(), &secretsmanager.GetSecretValueInput{
SecretId: &name,
})
if err != nil {
var aerr awserr.Error
if errors.As(err, &aerr) {
if aerr.Code() == secretsmanager.ErrCodeResourceNotFoundException {
return nil, ErrNotFound
}
}
return nil, fmt.Errorf("aws sm: get secret: %w", err)
}
return sec.SecretBinary, nil
}