Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable resolving a subset of the values in a value set #3301

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
6 changes: 4 additions & 2 deletions pkg/cnab/provider/credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ func (r *Runtime) loadCredentials(ctx context.Context, b cnab.ExtendedBundle, ru
ctx, span := tracing.StartSpan(ctx)
defer span.EndSpan()

resolvedCredentials, err := r.credentials.ResolveAll(ctx, run.Credentials)
resolvedCredentials, err := r.credentials.ResolveAll(ctx, run.Credentials, run.Credentials.Keys())
if err != nil {
return span.Error(err)
}

for i, cred := range run.Credentials.Credentials {
run.Credentials.Credentials[i].ResolvedValue = resolvedCredentials[cred.Name]
if resolvedValue, ok := resolvedCredentials[cred.Name]; ok {
run.Credentials.Credentials[i].ResolvedValue = resolvedValue
}
}

err = run.Credentials.ValidateBundle(b.Credentials, run.Action)
Expand Down
2 changes: 1 addition & 1 deletion pkg/cnab/provider/parameters.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func (r *Runtime) loadParameters(ctx context.Context, b cnab.ExtendedBundle, run
ctx, span := tracing.StartSpan(ctx)
defer span.EndSpan()

resolvedParameters, err := r.parameters.ResolveAll(ctx, run.Parameters)
resolvedParameters, err := r.parameters.ResolveAll(ctx, run.Parameters, run.Parameters.Keys())
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/porter/lifecycle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,7 @@ func TestPorter_applyActionOptionsToInstallation_PreservesExistingParams(t *test
require.Equal(t, "secret", i.Parameters.Parameters[1].Source.Strategy, "my-second-param should be stored on the installation using a secret since it's sensitive")

// Check the values stored are correct
params, err := p.Parameters.ResolveAll(ctx, i.Parameters)
params, err := p.Parameters.ResolveAll(ctx, i.Parameters, i.Parameters.Keys())
require.NoError(t, err, "Failed to resolve the installation parameters")
require.Equal(t, secrets.Set{
"my-first-param": "3", // Should have used the override
Expand Down
4 changes: 2 additions & 2 deletions pkg/porter/parameters.go
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ func (p *Porter) loadParameterSets(ctx context.Context, bun cnab.ExtendedBundle,
}
}

rc, err := p.Parameters.ResolveAll(ctx, pset)
rc, err := p.Parameters.ResolveAll(ctx, pset, pset.Keys())
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -894,7 +894,7 @@ func (p *Porter) applyActionOptionsToInstallation(ctx context.Context, ba Bundle

//
// 4. Resolve the installation's internal parameter set
resolvedOverrides, err := p.Parameters.ResolveAll(ctx, inst.Parameters)
resolvedOverrides, err := p.Parameters.ResolveAll(ctx, inst.Parameters, inst.Parameters.Keys())
if err != nil {
return err
}
Expand Down
19 changes: 14 additions & 5 deletions pkg/storage/credential_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,20 @@ func (s CredentialStore) GetDataStore() Store {
Secrets
*/

func (s CredentialStore) ResolveAll(ctx context.Context, creds CredentialSet) (secrets.Set, error) {
func (s CredentialStore) ResolveAll(ctx context.Context, creds CredentialSet, keys []string) (secrets.Set, error) {
ctx, span := tracing.StartSpan(ctx)
defer span.EndSpan()

resolvedCreds := make(secrets.Set)
var resolveErrors error
var resolveErrors *multierror.Error

for _, key := range keys {
cred, ok := creds.GetCredential(key)
if !ok {
resolveErrors = multierror.Append(resolveErrors, span.Errorf("credential %s not found", key))
continue
}

for _, cred := range creds.Credentials {
var value string
var err error
if isHandledByHostPlugin(cred.Source.Strategy) {
Expand All @@ -73,13 +82,13 @@ func (s CredentialStore) ResolveAll(ctx context.Context, creds CredentialSet) (s
value, err = s.Secrets.Resolve(ctx, cred.Source.Strategy, cred.Source.Hint)
}
if err != nil {
resolveErrors = multierror.Append(resolveErrors, fmt.Errorf("unable to resolve credential %s.%s from %s %s: %w", creds.Name, cred.Name, cred.Source.Strategy, cred.Source.Hint, err))
resolveErrors = multierror.Append(resolveErrors, span.Errorf("unable to resolve credential %s.%s from %s %s: %w", creds.Name, cred.Name, cred.Source.Strategy, cred.Source.Hint, err))
}

resolvedCreds[cred.Name] = value
}

return resolvedCreds, resolveErrors
return resolvedCreds, resolveErrors.ErrorOrNil()
}

func (s CredentialStore) Validate(ctx context.Context, creds CredentialSet) error {
Expand Down
19 changes: 19 additions & 0 deletions pkg/storage/credentialset.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,3 +185,22 @@ func (s CredentialSet) ValidateBundle(spec map[string]bundle.Credential, action
}
return nil
}

// Keys returns the names of all the credentials in the set.
func (s CredentialSet) Keys() []string {
keys := make([]string, 0, len(s.Credentials))
for _, cred := range s.Credentials {
keys = append(keys, cred.Name)
}
return keys
}

// GetCredential returns the credential with the given name, and a boolean indicating if it was found.
func (s CredentialSet) GetCredential(name string) (*secrets.SourceMap, bool) {
for _, cred := range s.Credentials {
if cred.Name == name {
return &cred, true
}
}
return nil, false
}
2 changes: 1 addition & 1 deletion pkg/storage/credentialset_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
// CredentialSetProvider is Porter's interface for managing and resolving credentials.
type CredentialSetProvider interface {
GetDataStore() Store
ResolveAll(ctx context.Context, creds CredentialSet) (secrets.Set, error)
ResolveAll(ctx context.Context, creds CredentialSet, keys []string) (secrets.Set, error)
Validate(ctx context.Context, creds CredentialSet) error
InsertCredentialSet(ctx context.Context, creds CredentialSet) error
ListCredentialSets(ctx context.Context, listOptions ListOptions) ([]CredentialSet, error)
Expand Down
7 changes: 6 additions & 1 deletion pkg/storage/parameter_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package storage
import (
"context"
"fmt"
"slices"
"strings"

"get.porter.sh/porter/pkg/secrets"
Expand Down Expand Up @@ -54,11 +55,15 @@ func (s ParameterStore) GetDataStore() Store {
return s.Documents
}

func (s ParameterStore) ResolveAll(ctx context.Context, params ParameterSet) (secrets.Set, error) {
func (s ParameterStore) ResolveAll(ctx context.Context, params ParameterSet, keys []string) (secrets.Set, error) {
resolvedParams := make(secrets.Set)
var resolveErrors error

for _, param := range params.Parameters {
if !slices.Contains(keys, param.Name) {
continue
}

var value string
var err error
if isHandledByHostPlugin(param.Source.Strategy) {
Expand Down
22 changes: 19 additions & 3 deletions pkg/storage/parameter_store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func TestParameterStorage_ResolveNonSecret(t *testing.T) {
"param2": "param2_value",
}

resolved, err := paramStore.ResolveAll(context.Background(), testParameterSet)
resolved, err := paramStore.ResolveAll(context.Background(), testParameterSet, testParameterSet.Keys())
require.NoError(t, err)
require.Equal(t, expected, resolved)
}
Expand Down Expand Up @@ -153,7 +153,23 @@ func TestParameterStorage_ResolveAll(t *testing.T) {
"param2": "param2_value",
}

resolved, err := paramStore.ResolveAll(context.Background(), testParameterSet)
resolved, err := paramStore.ResolveAll(context.Background(), testParameterSet, testParameterSet.Keys())
require.NoError(t, err)
require.Equal(t, expected, resolved)
})

t.Run("resolve params only resolves the requested keys", func(t *testing.T) {
paramStore := NewTestParameterProvider(t)
defer paramStore.Close()

paramStore.AddSecret("param1", "param1_value")
paramStore.AddSecret("param2", "param2_value")

expected := secrets.Set{
"param1": "param1_value",
}

resolved, err := paramStore.ResolveAll(context.Background(), testParameterSet, []string{"param1"})
require.NoError(t, err)
require.Equal(t, expected, resolved)
})
Expand All @@ -170,7 +186,7 @@ func TestParameterStorage_ResolveAll(t *testing.T) {
"param2": "",
}

resolved, err := paramStore.ResolveAll(context.Background(), testParameterSet)
resolved, err := paramStore.ResolveAll(context.Background(), testParameterSet, testParameterSet.Keys())
require.EqualError(t, err, "1 error occurred:\n\t* unable to resolve parameter myparamset.param2 from secret param2: secret not found\n\n")
require.Equal(t, expected, resolved)
})
Expand Down
9 changes: 9 additions & 0 deletions pkg/storage/parameterset.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,12 @@ func (s ParameterSet) ValidateBundle(spec map[string]bundle.Parameter, action st
}
return nil
}

// Keys returns the names of all the parameters in the set.
func (s ParameterSet) Keys() []string {
keys := make([]string, len(s.Parameters))
for _, param := range s.Parameters {
keys = append(keys, param.Name)
}
return keys
}
2 changes: 1 addition & 1 deletion pkg/storage/parameterset_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type ParameterSetProvider interface {
GetDataStore() Store

// ResolveAll parameter values in the parameter set.
ResolveAll(ctx context.Context, params ParameterSet) (secrets.Set, error)
ResolveAll(ctx context.Context, params ParameterSet, keys []string) (secrets.Set, error)

// Validate the parameter set is defined properly.
Validate(ctx context.Context, params ParameterSet) error
Expand Down
2 changes: 1 addition & 1 deletion pkg/storage/sanitizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func sanitizedParam(param secrets.SourceMap, id string) secrets.SourceMap {

// RestoreParameterSet resolves the raw parameter data from a secrets store.
func (s *Sanitizer) RestoreParameterSet(ctx context.Context, pset ParameterSet, bun cnab.ExtendedBundle) (map[string]interface{}, error) {
params, err := s.parameter.ResolveAll(ctx, pset)
params, err := s.parameter.ResolveAll(ctx, pset, pset.Keys())
if err != nil {
return nil, err
}
Expand Down
Loading