get.porter.sh/porter@v1.3.0/pkg/storage/parameter_store.go (about) 1 package storage 2 3 import ( 4 "context" 5 "fmt" 6 "slices" 7 "strings" 8 9 "get.porter.sh/porter/pkg/secrets" 10 hostSecrets "get.porter.sh/porter/pkg/secrets/plugins/host" 11 "get.porter.sh/porter/pkg/tracing" 12 "github.com/cnabio/cnab-go/secrets/host" 13 "github.com/hashicorp/go-multierror" 14 ) 15 16 var _ ParameterSetProvider = &ParameterStore{} 17 18 const ( 19 CollectionParameters = "parameters" 20 ) 21 22 // ParameterStore provides access to parameter sets by instantiating plugins that 23 // implement CRUD storage. 24 type ParameterStore struct { 25 Documents Store 26 Secrets secrets.Store 27 HostSecrets hostSecrets.Store 28 } 29 30 func NewParameterStore(storage Store, secrets secrets.Store) *ParameterStore { 31 return &ParameterStore{ 32 Documents: storage, 33 Secrets: secrets, 34 HostSecrets: hostSecrets.NewStore(), 35 } 36 } 37 38 // EnsureParameterIndices creates indices on the parameters collection. 39 func EnsureParameterIndices(ctx context.Context, store Store) error { 40 ctx, span := tracing.StartSpan(ctx) 41 defer span.EndSpan() 42 43 span.Debug("Initializing parameter collection indices") 44 indices := EnsureIndexOptions{ 45 Indices: []Index{ 46 // query parameters by namespace + name 47 {Collection: CollectionParameters, Keys: []string{"namespace", "name"}, Unique: true}, 48 }, 49 } 50 err := store.EnsureIndex(ctx, indices) 51 return span.Error(err) 52 } 53 54 func (s ParameterStore) GetDataStore() Store { 55 return s.Documents 56 } 57 58 func (s ParameterStore) ResolveAll(ctx context.Context, params ParameterSet, keys []string) (secrets.Set, error) { 59 resolvedParams := make(secrets.Set) 60 var resolveErrors error 61 62 for _, param := range params.Parameters { 63 if !slices.Contains(keys, param.Name) { 64 continue 65 } 66 67 var value string 68 var err error 69 if isHandledByHostPlugin(param.Source.Strategy) { 70 value, err = s.HostSecrets.Resolve(ctx, param.Source.Strategy, param.Source.Hint) 71 } else { 72 value, err = s.Secrets.Resolve(ctx, param.Source.Strategy, param.Source.Hint) 73 } 74 if err != nil { 75 resolveErrors = multierror.Append(resolveErrors, fmt.Errorf("unable to resolve parameter %s.%s from %s %s: %w", params.Name, param.Name, param.Source.Strategy, param.Source.Hint, err)) 76 } 77 78 resolvedParams[param.Name] = value 79 } 80 81 return resolvedParams, resolveErrors 82 } 83 84 func (s ParameterStore) Validate(ctx context.Context, params ParameterSet) error { 85 validSources := []string{secrets.SourceSecret, host.SourceValue, host.SourceEnv, host.SourcePath, host.SourceCommand} 86 var errors error 87 88 for _, cs := range params.Parameters { 89 valid := false 90 for _, validSource := range validSources { 91 if cs.Source.Strategy == validSource { 92 valid = true 93 break 94 } 95 } 96 if !valid { 97 errors = multierror.Append(errors, fmt.Errorf( 98 "%s is not a valid source. Valid sources are: %s", 99 cs.Source.Strategy, 100 strings.Join(validSources, ", "), 101 )) 102 } 103 } 104 105 return errors 106 } 107 108 func (s ParameterStore) InsertParameterSet(ctx context.Context, params ParameterSet) error { 109 params.SchemaVersion = DefaultParameterSetSchemaVersion 110 opts := InsertOptions{ 111 Documents: []interface{}{params}, 112 } 113 return s.Documents.Insert(ctx, CollectionParameters, opts) 114 } 115 116 func (s ParameterStore) ListParameterSets(ctx context.Context, listOptions ListOptions) ([]ParameterSet, error) { 117 var out []ParameterSet 118 err := s.Documents.Find(ctx, CollectionParameters, listOptions.ToFindOptions(), &out) 119 return out, err 120 } 121 122 func (s ParameterStore) GetParameterSet(ctx context.Context, namespace string, name string) (ParameterSet, error) { 123 var out ParameterSet 124 opts := FindOptions{ 125 Filter: map[string]interface{}{ 126 "namespace": namespace, 127 "name": name, 128 }, 129 } 130 err := s.Documents.FindOne(ctx, CollectionParameters, opts, &out) 131 return out, err 132 } 133 134 func (s ParameterStore) UpdateParameterSet(ctx context.Context, params ParameterSet) error { 135 params.SchemaVersion = DefaultParameterSetSchemaVersion 136 opts := UpdateOptions{ 137 Document: params, 138 } 139 return s.Documents.Update(ctx, CollectionParameters, opts) 140 } 141 142 func (s ParameterStore) UpsertParameterSet(ctx context.Context, params ParameterSet) error { 143 params.SchemaVersion = DefaultParameterSetSchemaVersion 144 opts := UpdateOptions{ 145 Document: params, 146 Upsert: true, 147 } 148 return s.Documents.Update(ctx, CollectionParameters, opts) 149 } 150 151 func (s ParameterStore) RemoveParameterSet(ctx context.Context, namespace string, name string) error { 152 opts := RemoveOptions{ 153 Namespace: namespace, 154 Name: name, 155 } 156 return s.Documents.Remove(ctx, CollectionParameters, opts) 157 }