-
Notifications
You must be signed in to change notification settings - Fork 179
/
Copy pathsecrets.go
99 lines (85 loc) · 2.65 KB
/
secrets.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
package secrets
import (
"context"
"fmt"
)
//go:generate mockery -name=API -output=automock -outpkg=automock -case=underscore
// Option wrapper for relevant Options for the client
type Option struct {
ProjectID string
LocationID string
KmsRing string
KmsKey string
ServiceAccount string // filename of the serviceaccount to use
}
// Client wrapper for KMS and GCS secret storage
type Client struct {
Option
api API
}
// API provides a mockable interface for the GCP api. Find the implementation of the GCP wrapped API in wrapped.go
type API interface {
Encrypt(ctx context.Context, plaintext []byte) ([]byte, error)
Decrypt(ctx context.Context, ciphertext []byte) ([]byte, error)
}
// New returns a new Client, wrapping kms and gcs for storing/reading encrypted secrets from GCP
func New(opts Option, api API) (*Client, error) {
if opts.ProjectID == "" {
return nil, fmt.Errorf("ProjectID is required to initialize a client")
}
if opts.LocationID == "" {
return nil, fmt.Errorf("LocationID is required to initialize a client")
}
if opts.KmsRing == "" {
return nil, fmt.Errorf("KmsRing is required to initialize a client")
}
if opts.KmsKey == "" {
return nil, fmt.Errorf("KmsKey is required to initialize a client")
}
if opts.ServiceAccount == "" {
return nil, fmt.Errorf("ServiceAccount is required to initialize a client")
}
if api == nil {
return nil, fmt.Errorf("Can't create client without api")
}
return &Client{Option: opts, api: api}, nil
}
// Encrypt attempts to encrypt a secret with kms
func (sc *Client) Encrypt(ctx context.Context, plaintext []byte) ([]byte, error) {
if len(plaintext) == 0 {
return nil, fmt.Errorf("cannot encrypt zero value")
}
return sc.api.Encrypt(ctx, plaintext)
}
// Decrypt attempts to decrypt a secret with kms
func (sc *Client) Decrypt(ctx context.Context, ciphertext []byte) ([]byte, error) {
if len(ciphertext) == 0 {
return nil, fmt.Errorf("cannot decrypt zero value")
}
return sc.api.Decrypt(ctx, ciphertext)
}
// WithKmsRing modifies option to have a kms ring
func (o Option) WithKmsRing(ring string) Option {
o.KmsRing = ring
return o
}
// WithKmsKey modifies option to have a kms key
func (o Option) WithKmsKey(key string) Option {
o.KmsKey = key
return o
}
// WithProjectID modifies option to have a project id
func (o Option) WithProjectID(pid string) Option {
o.ProjectID = pid
return o
}
// WithLocationID modifies option to have a zone id
func (o Option) WithLocationID(l string) Option {
o.LocationID = l
return o
}
// WithServiceAccount modifies option to have a service account
func (o Option) WithServiceAccount(sa string) Option {
o.ServiceAccount = sa
return o
}