-
Notifications
You must be signed in to change notification settings - Fork 200
/
credential_store.go
146 lines (123 loc) · 3.69 KB
/
credential_store.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
135
136
137
138
139
140
141
142
143
144
145
146
package credentials
import (
"fmt"
"strings"
"get.porter.sh/porter/pkg/secrets"
"get.porter.sh/porter/pkg/storage"
"github.com/cnabio/cnab-go/secrets/host"
"github.com/hashicorp/go-multierror"
"github.com/pkg/errors"
)
var _ Provider = &CredentialStore{}
const (
CollectionCredentials = "credentials"
)
// CredentialStore provides access to credential sets by instantiating plugins that
// implement CRUD storage.
type CredentialStore struct {
Documents storage.Store
Secrets secrets.Store
}
func NewCredentialStore(storage storage.Store, secrets secrets.Store) *CredentialStore {
return &CredentialStore{
Documents: storage,
Secrets: secrets,
}
}
// Initialize the underlying storage with any additional schema changes, such as indexes.
func (s CredentialStore) Initialize() error {
indices := storage.EnsureIndexOptions{
Indices: []storage.Index{
// query credentials by namespace + name
{Collection: CollectionCredentials, Keys: []string{"namespace", "name"}, Unique: true},
},
}
return s.Documents.EnsureIndex(indices)
}
func (s CredentialStore) GetDataStore() storage.Store {
return s.Documents
}
/*
Secrets
*/
func (s CredentialStore) ResolveAll(creds CredentialSet) (secrets.Set, error) {
resolvedCreds := make(secrets.Set)
var resolveErrors error
for _, cred := range creds.Credentials {
value, err := s.Secrets.Resolve(cred.Source.Key, cred.Source.Value)
if err != nil {
resolveErrors = multierror.Append(resolveErrors, errors.Wrapf(err, "unable to resolve credential %s.%s from %s %s", creds.Name, cred.Name, cred.Source.Key, cred.Source.Value))
}
resolvedCreds[cred.Name] = value
}
return resolvedCreds, resolveErrors
}
func (s CredentialStore) Validate(creds CredentialSet) error {
validSources := []string{secrets.SourceSecret, host.SourceValue, host.SourceEnv, host.SourcePath, host.SourceCommand}
var errors error
for _, cs := range creds.Credentials {
valid := false
for _, validSource := range validSources {
if cs.Source.Key == validSource {
valid = true
break
}
}
if valid == false {
errors = multierror.Append(errors, fmt.Errorf(
"%s is not a valid source. Valid sources are: %s",
cs.Source.Key,
strings.Join(validSources, ", "),
))
}
}
return errors
}
/*
Document Storage
*/
func (s CredentialStore) InsertCredentialSet(cset CredentialSet) error {
opts := storage.InsertOptions{
Documents: []interface{}{cset},
}
return s.Documents.Insert(CollectionCredentials, opts)
}
func (s CredentialStore) ListCredentialSets(namespace string, name string, labels map[string]string) ([]CredentialSet, error) {
var out []CredentialSet
opts := storage.FindOptions{
Filter: storage.CreateListFiler(namespace, name, labels),
}
err := s.Documents.Find(CollectionCredentials, opts, &out)
return out, err
}
func (s CredentialStore) GetCredentialSet(namespace string, name string) (CredentialSet, error) {
var out CredentialSet
opts := storage.FindOptions{
Filter: map[string]interface{}{
"namespace": namespace,
"name": name,
},
}
err := s.Documents.FindOne(CollectionCredentials, opts, &out)
return out, err
}
func (s CredentialStore) UpdateCredentialSet(creds CredentialSet) error {
opts := storage.UpdateOptions{
Document: creds,
}
return s.Documents.Update(CollectionCredentials, opts)
}
func (s CredentialStore) UpsertCredentialSet(creds CredentialSet) error {
opts := storage.UpdateOptions{
Document: creds,
Upsert: true,
}
return s.Documents.Update(CollectionCredentials, opts)
}
func (s CredentialStore) RemoveCredentialSet(namespace string, name string) error {
opts := storage.RemoveOptions{
Namespace: namespace,
Name: name,
}
return s.Documents.Remove(CollectionCredentials, opts)
}