Skip to content

Commit 84b6fd1

Browse files
committed
Use secrets.Map for ParameterSourceMap
Signed-off-by: Carolyn Van Slyck <[email protected]>
1 parent 05d173f commit 84b6fd1

12 files changed

+72
-34
lines changed

pkg/encoding/array_map.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ type ArrayMap[T MapElement, K ArrayElement] struct {
2424
items map[string]T
2525
}
2626

27-
// TODO(carolyn): Can I make this work without K?
2827
func MakeArrayMap[T MapElement, K ArrayElement](len int) ArrayMap[T, K] {
2928
return ArrayMap[T, K]{
3029
items: make(map[string]T, len),
@@ -133,6 +132,10 @@ func (m *ArrayMap[T, K]) UnmarshalRaw(raw []K) error {
133132
return nil
134133
}
135134

135+
if m == nil {
136+
*m = ArrayMap[T, K]{}
137+
}
138+
136139
m.items = make(map[string]T, len(raw))
137140
for _, rawItem := range raw {
138141
if _, hasKey := m.items[rawItem.GetKey()]; hasKey {

pkg/generator/parameters_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,5 +115,5 @@ func TestSkipParameters(t *testing.T) {
115115
pset, err := opts.GenerateParameters()
116116
require.NoError(t, err, "parameters generation should not have resulted in an error")
117117
assert.Equal(t, "skip-params", pset.Name, "Name was not set")
118-
require.Empty(t, pset.Parameters, "parameter set should have empty parameters section")
118+
require.Equal(t, 0, pset.Len(), "parameter set should have empty parameters section")
119119
}

pkg/porter/helpers.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ func (p *TestPorter) CompareGoldenFile(goldenFile string, got string) {
240240

241241
// CreateInstallation saves an installation record into claim store and store
242242
// sensitive parameters into secret store.
243-
func (p *TestPorter) SanitizeParameters(raw *storage.ParameterSourceMap, recordID string, bun cnab.ExtendedBundle) *storage.ParameterSourceMap {
243+
func (p *TestPorter) SanitizeParameters(raw storage.ParameterSourceMap, recordID string, bun cnab.ExtendedBundle) storage.ParameterSourceMap {
244244
strategies, err := p.Sanitizer.CleanParameters(context.Background(), raw, bun, recordID)
245245
require.NoError(p.T(), err)
246246

pkg/porter/lifecycle_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ func TestPorter_applyActionOptionsToInstallation_sanitizesParameters(t *testing.
472472
require.NoError(t, err)
473473

474474
// Check that when no parameter overrides are specified, we use the originally specified parameters from the previous run
475-
wantParameters := &storage.ParameterSourceMap{}
475+
wantParameters := storage.NewParameterSourceMap()
476476
wantParameters.Set("my-first-param", storage.ParameterSource{
477477
Source: secrets.Source{Strategy: "value", Hint: "1"}})
478478
wantParameters.Set("my-second-param", storage.ParameterSource{
@@ -519,7 +519,7 @@ func TestPorter_applyActionOptionsToInstallation_PreservesExistingParams(t *test
519519
require.Equal(t, 2, i.Parameters.Len())
520520

521521
// Check that overrides are applied on top of existing parameters
522-
wantParameters := &storage.ParameterSourceMap{}
522+
wantParameters := storage.NewParameterSourceMap()
523523
wantParameters.Set("my-first-param", storage.ParameterSource{
524524
Source: secrets.Source{Strategy: "value", Hint: "3"},
525525
})

pkg/porter/parameters_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -859,7 +859,7 @@ func TestPorter_ParametersApply(t *testing.T) {
859859

860860
assert.Equal(t, "mypset", ps.Name, "unexpected parameter set name")
861861

862-
wantParams := &storage.ParameterSourceMap{}
862+
wantParams := storage.NewParameterSourceMap()
863863
wantParams.Set("foo", storage.ParameterSource{
864864
Source: secrets.Source{
865865
Strategy: "secret",

pkg/secrets/map.go

+43-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,29 @@
11
package secrets
22

3-
import "get.porter.sh/porter/pkg/encoding"
3+
import (
4+
"encoding/json"
5+
6+
"get.porter.sh/porter/pkg/encoding"
7+
"gopkg.in/yaml.v3"
8+
)
49

510
type Map struct {
611
*encoding.ArrayMap[ValueMapping, NamedValueMapping]
712
}
813

14+
func NewMap() Map {
15+
return Map{
16+
ArrayMap: &encoding.ArrayMap[ValueMapping, NamedValueMapping]{},
17+
}
18+
}
19+
20+
func MakeMap(len int) Map {
21+
items := encoding.MakeArrayMap[ValueMapping, NamedValueMapping](len)
22+
return Map{
23+
ArrayMap: &items,
24+
}
25+
}
26+
927
func (m Map) Merge(overrides Map) Map {
1028
result := m.ArrayMap.Merge(overrides.ArrayMap)
1129
return Map{ArrayMap: result}
@@ -19,6 +37,30 @@ func (m Map) ToResolvedValues() map[string]string {
1937
return values
2038
}
2139

40+
func (m *Map) UnmarshalJSON(b []byte) error {
41+
// Ensure that ArrayMap is not nil before its custom UnmarshalJson is called
42+
// Otherwise it causes a panic
43+
if m.ArrayMap == nil {
44+
m.ArrayMap = &encoding.ArrayMap[ValueMapping, NamedValueMapping]{}
45+
}
46+
47+
// Cheap trick to unmarshal without re-triggering this UnmarshalJson call
48+
type RawMap Map
49+
return json.Unmarshal(b, (*RawMap)(m))
50+
}
51+
52+
func (m *Map) UnmarshalYAML(value *yaml.Node) error {
53+
// Ensure that ArrayMap is not nil before its custom UnmarshalYAML is called
54+
// Otherwise it causes a panic
55+
if m.ArrayMap == nil {
56+
m.ArrayMap = &encoding.ArrayMap[ValueMapping, NamedValueMapping]{}
57+
}
58+
59+
// Cheap trick to unmarshal without re-triggering this UnmarshalYAML call
60+
type RawMap Map
61+
return value.Decode((*RawMap)(m))
62+
}
63+
2264
var _ encoding.MapElement = ValueMapping{}
2365

2466
// ValueMapping maps from a parameter or credential name to a source strategy for resolving its value.

pkg/storage/migrations/migration.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -591,16 +591,15 @@ func convertParameterSet(namespace string, data []byte) (storage.ParameterSet, e
591591
},
592592
}
593593

594-
destParams := storage.MakeParameterSourceMap(len(src.Parameters))
595-
dest.Parameters = &destParams
594+
dest.Parameters = storage.MakeParameterSourceMap(len(src.Parameters))
596595
for _, srcParam := range src.Parameters {
597596
destParam := storage.ParameterSource{
598597
Source: secrets.Source{
599598
Strategy: srcParam.Source.Key,
600599
Hint: srcParam.Source.Value,
601600
},
602601
}
603-
destParams.Set(srcParam.Name, destParam)
602+
dest.Parameters.Set(srcParam.Name, destParam)
604603
}
605604

606605
return dest, nil

pkg/storage/migrations/migration_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ func validateMigratedInstallations(ctx context.Context, t *testing.T, c *config.
153153
assert.Empty(t, inst.Labels, "We didn't allow setting labels on installations in v0, so this can't be populated")
154154
assert.Empty(t, inst.CredentialSets, "We didn't track credential sets used when running a bundle in v0, so this can't be populated")
155155
assert.Empty(t, inst.ParameterSets, "We didn't track parameter sets used when running a bundle in v0, so this can't be populated")
156-
assert.Empty(t, inst.Parameters.Parameters, "We didn't track manually specified parameters when running a bundle in v0, so this can't be populated")
156+
assert.Equal(t, 0, inst.Parameters.Len(), "We didn't track manually specified parameters when running a bundle in v0, so this can't be populated")
157157

158158
// Validate the installation status, which is calculated based on the runs and their results
159159
assert.Equal(t, "2022-04-28T16:09:42.65907-05:00", inst.Status.Created.Format(time.RFC3339Nano), "Created timestamp should be set to the timestamp of the first run")
@@ -185,7 +185,7 @@ func validateMigratedInstallations(ctx context.Context, t *testing.T, c *config.
185185
assert.Empty(t, lastRun.Custom, "We didn't set custom datadata on claims in v0, so this can't be populated")
186186
assert.Equal(t, "2022-04-29T16:13:20.48026-05:00", lastRun.Created.Format(time.RFC3339Nano), "incorrect run created timestamp")
187187
assert.Empty(t, lastRun.ParameterSets, "We didn't track run parameter sets in v0, so this can't be populated")
188-
assert.Empty(t, lastRun.ParameterOverrides, "We didn't track run parameter overrides in v0, so this can't be populated")
188+
assert.Equal(t, 0, lastRun.ParameterOverrides.Len(), "We didn't track run parameter overrides in v0, so this can't be populated")
189189
assert.Empty(t, lastRun.CredentialSets, "We didn't track run credential sets in v0, so this can't be populated")
190190
assert.Equal(t, 1, lastRun.Parameters.Len(), "expected one parameter set on the run")
191191

pkg/storage/parameterset.go

+5-11
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package storage
33
import (
44
"context"
55
"fmt"
6-
"get.porter.sh/porter/pkg/encoding"
76
"strings"
87
"time"
98

@@ -45,12 +44,13 @@ type ParameterSetSpec struct {
4544
Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty" toml:"labels,omitempty"`
4645

4746
// Parameters is a list of parameter specs.
48-
Parameters *ParameterSourceMap `json:"parameters" yaml:"parameters" toml:"parameters"`
47+
Parameters ParameterSourceMap `json:"parameters" yaml:"parameters" toml:"parameters"`
4948
}
5049

51-
type ParameterSourceMap = encoding.ArrayMap[ParameterSource, NamedParameterSource]
50+
type ParameterSourceMap = secrets.Map
5251

53-
var MakeParameterSourceMap = encoding.MakeArrayMap[ParameterSource, NamedParameterSource]
52+
var MakeParameterSourceMap = secrets.MakeMap
53+
var NewParameterSourceMap = secrets.NewMap
5454

5555
// TODO(generics)
5656
type ParameterSource = secrets.ValueMapping
@@ -74,7 +74,7 @@ func NewParameterSet(namespace string, name string) ParameterSet {
7474
SchemaVersion: DefaultParameterSetSchemaVersion,
7575
Namespace: namespace,
7676
Name: name,
77-
Parameters: &ParameterSourceMap{},
77+
Parameters: NewParameterSourceMap(),
7878
},
7979
Status: ParameterSetStatus{
8080
Created: now,
@@ -132,9 +132,6 @@ func (s ParameterSet) String() string {
132132
}
133133

134134
func (s ParameterSet) Iterate() map[string]ParameterSource {
135-
if s.Parameters == nil {
136-
return nil
137-
}
138135
return s.Parameters.Items()
139136
}
140137

@@ -143,9 +140,6 @@ func (s ParameterSet) SetStrategy(key string, source secrets.Source) {
143140
}
144141

145142
func (s ParameterSet) Set(key string, source ParameterSource) {
146-
if s.Parameters == nil { // TODO(carolyn): do this in all the places
147-
s.Parameters = &ParameterSourceMap{}
148-
}
149143
s.Parameters.Set(key, source)
150144
}
151145

pkg/storage/run_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -210,5 +210,5 @@ func TestRun_MarshalJSON(t *testing.T) {
210210
err = json.Unmarshal(data, &r2)
211211
require.NoError(t, err, "Unmarshal failed")
212212

213-
assert.Equal(t, r1, r2, "The run did not survive the round trip")
213+
assert.Equal(t, r1.Bundle, r2.Bundle, "The Run's bundle did not survive the round trip")
214214
}

pkg/storage/sanitizer.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -29,20 +29,20 @@ func NewSanitizer(parameterstore ParameterSetProvider, secretstore secrets.Store
2929
// transform the raw value into secret strategies.
3030
// The id argument is used to associate the reference key with the corresponding
3131
// run or installation record in porter's database.
32-
func (s *Sanitizer) CleanRawParameters(ctx context.Context, params map[string]interface{}, bun cnab.ExtendedBundle, id string) (*ParameterSourceMap, error) {
32+
func (s *Sanitizer) CleanRawParameters(ctx context.Context, params map[string]interface{}, bun cnab.ExtendedBundle, id string) (ParameterSourceMap, error) {
3333
strategies := MakeParameterSourceMap(len(params))
3434
for name, value := range params {
3535
stringVal, err := bun.WriteParameterToString(name, value)
3636
if err != nil {
37-
return nil, err
37+
return ParameterSourceMap{}, err
3838
}
3939

4040
strategies.Set(name, secrets.HardCodedValue(stringVal))
4141
}
4242

43-
result, err := s.CleanParameters(ctx, &strategies, bun, id)
43+
result, err := s.CleanParameters(ctx, strategies, bun, id)
4444
if err != nil {
45-
return nil, err
45+
return ParameterSourceMap{}, err
4646
}
4747

4848
return result, nil
@@ -53,15 +53,15 @@ func (s *Sanitizer) CleanRawParameters(ctx context.Context, params map[string]in
5353
// Sanitized value after saving sensitive data to secrets store.
5454
// The id argument is used to associate the reference key with the corresponding
5555
// run or installation record in porter's database.
56-
func (s *Sanitizer) CleanParameters(ctx context.Context, dirtyParams *ParameterSourceMap, bun cnab.ExtendedBundle, id string) (*ParameterSourceMap, error) {
56+
func (s *Sanitizer) CleanParameters(ctx context.Context, dirtyParams ParameterSourceMap, bun cnab.ExtendedBundle, id string) (ParameterSourceMap, error) {
5757
cleanedParams := MakeParameterSourceMap(dirtyParams.Len())
5858
for paramName, param := range dirtyParams.Items() {
5959
// Store sensitive hard-coded values in a secret store
6060
if param.Source.Strategy == host.SourceValue && bun.IsSensitiveParameter(paramName) {
6161
cleaned := sanitizedParam(paramName, param, id)
6262
err := s.secrets.Create(ctx, cleaned.Source.Strategy, cleaned.Source.Hint, cleaned.ResolvedValue)
6363
if err != nil {
64-
return nil, fmt.Errorf("failed to save sensitive param to secrete store: %w", err)
64+
return ParameterSourceMap{}, fmt.Errorf("failed to save sensitive param to secrete store: %w", err)
6565
}
6666

6767
cleanedParams.Set(paramName, cleaned)
@@ -71,10 +71,10 @@ func (s *Sanitizer) CleanParameters(ctx context.Context, dirtyParams *ParameterS
7171
}
7272

7373
if cleanedParams.Len() == 0 {
74-
return nil, nil
74+
return NewParameterSourceMap(), nil
7575
}
7676

77-
return &cleanedParams, nil
77+
return cleanedParams, nil
7878

7979
}
8080

pkg/storage/sanitizer_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ func TestSanitizer_Parameters(t *testing.T) {
2828
recordID := "01FZVC5AVP8Z7A78CSCP1EJ604"
2929
sensitiveParamName := "my-second-param"
3030
sensitiveParamKey := recordID + "-" + sensitiveParamName
31-
expected := &storage.ParameterSourceMap{}
31+
expected := storage.NewParameterSourceMap()
3232
expected.Set("my-first-param", secrets.HardCodedValue("1"))
3333
expected.Set(sensitiveParamName, storage.ParameterSource{Source: secrets.Source{
3434
Strategy: secrets.SourceSecret,
@@ -108,7 +108,7 @@ func TestSanitizer_CleanParameters(t *testing.T) {
108108
gotParams, err := r.Sanitizer.CleanParameters(ctx, inst.Parameters.Parameters, bun, inst.ID)
109109
require.NoError(t, err, "CleanParameters failed")
110110

111-
wantParms := &storage.ParameterSourceMap{}
111+
wantParms := storage.NewParameterSourceMap()
112112
wantParms.Set(tc.paramName, storage.ParameterSource{Source: tc.wantSource})
113113
require.Equal(t, wantParms, gotParams, "unexpected value returned from CleanParameters")
114114
})

0 commit comments

Comments
 (0)