get.porter.sh/porter@v1.3.0/pkg/cnab/provider/credentials_test.go (about)

     1  package cnabprovider
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"get.porter.sh/porter/pkg/cnab"
     8  	"get.porter.sh/porter/pkg/secrets"
     9  	"get.porter.sh/porter/pkg/storage"
    10  	"github.com/cnabio/cnab-go/bundle"
    11  	"github.com/cnabio/cnab-go/secrets/host"
    12  	"github.com/cnabio/cnab-go/valuesource"
    13  	"github.com/stretchr/testify/assert"
    14  	"github.com/stretchr/testify/require"
    15  )
    16  
    17  func TestRuntime_loadCredentials(t *testing.T) {
    18  	t.Parallel()
    19  
    20  	r := NewTestRuntime(t)
    21  	defer r.Close()
    22  
    23  	r.TestCredentials.AddSecret("password", "mypassword")
    24  	r.TestCredentials.AddSecret("db-password", "topsecret")
    25  
    26  	b := cnab.NewBundle(bundle.Bundle{
    27  		Credentials: map[string]bundle.Credential{
    28  			"password": {
    29  				Location: bundle.Location{
    30  					EnvironmentVariable: "PASSWORD",
    31  				},
    32  			},
    33  			"db-password": {
    34  				Location: bundle.Location{
    35  					EnvironmentVariable: "DB_PASSWORD",
    36  				},
    37  			},
    38  		},
    39  	})
    40  
    41  	run := storage.Run{
    42  		Action: cnab.ActionInstall,
    43  		Credentials: storage.NewInternalCredentialSet(secrets.SourceMap{
    44  			Name: "password",
    45  			Source: secrets.Source{
    46  				Strategy: secrets.SourceSecret,
    47  				Hint:     "password",
    48  			},
    49  		}),
    50  	}
    51  	err := r.loadCredentials(context.Background(), b, &run)
    52  	require.NoError(t, err, "loadCredentials failed")
    53  	require.Equal(t, "sha256:2d6d3c91ef272afeef2bb29b2fb4b1670c756c623195e71916b8ee138fba60cb",
    54  		run.CredentialsDigest, "expected loadCredentials to set the digest of resolved credentials")
    55  	require.NotEmpty(t, run.Credentials.Credentials[0].ResolvedValue, "expected loadCredentials to set the resolved value of the credentials on the Run")
    56  
    57  	gotValues := run.Credentials.ToCNAB()
    58  	wantValues := valuesource.Set{
    59  		"password": "mypassword",
    60  	}
    61  	assert.Equal(t, wantValues, gotValues, "resolved unexpected credential values")
    62  }
    63  
    64  func TestRuntime_loadCredentials_WithApplyTo(t *testing.T) {
    65  	getBundle := func(required bool) cnab.ExtendedBundle {
    66  		return cnab.ExtendedBundle{Bundle: bundle.Bundle{
    67  			Credentials: map[string]bundle.Credential{
    68  				"password": {
    69  					Location: bundle.Location{
    70  						EnvironmentVariable: "PASSWORD",
    71  					},
    72  					Required: required,
    73  					ApplyTo:  []string{"install", "upgrade", "uninstall"},
    74  				},
    75  			},
    76  		},
    77  		}
    78  	}
    79  
    80  	t.Run("missing required credential does not apply", func(t *testing.T) {
    81  		t.Parallel()
    82  		r := NewTestRuntime(t)
    83  		defer r.Close()
    84  
    85  		run := &storage.Run{Action: "status"}
    86  		b := getBundle(true)
    87  		err := r.loadCredentials(context.Background(), b, run)
    88  		require.NoError(t, err, "loadCredentials failed")
    89  
    90  		gotValues := run.Credentials.ToCNAB()
    91  		assert.Empty(t, gotValues)
    92  	})
    93  
    94  	t.Run("optional credential missing", func(t *testing.T) {
    95  		t.Parallel()
    96  		r := NewTestRuntime(t)
    97  		defer r.Close()
    98  
    99  		run := &storage.Run{Action: "install"}
   100  		b := getBundle(false)
   101  		err := r.loadCredentials(context.Background(), b, run)
   102  		require.NoError(t, err, "loadCredentials failed")
   103  
   104  		gotValues := run.Credentials.ToCNAB()
   105  		assert.Empty(t, gotValues)
   106  	})
   107  
   108  	t.Run("required credential missing", func(t *testing.T) {
   109  		t.Parallel()
   110  		r := NewTestRuntime(t)
   111  		defer r.Close()
   112  
   113  		run := &storage.Run{Action: "install"}
   114  		b := getBundle(true)
   115  		err := r.loadCredentials(context.Background(), b, run)
   116  		require.Error(t, err, "expected the credential to be required")
   117  	})
   118  
   119  	t.Run("credential resolved", func(t *testing.T) {
   120  		t.Parallel()
   121  		r := NewTestRuntime(t)
   122  		defer r.Close()
   123  
   124  		r.TestCredentials.AddSecret("password", "mypassword")
   125  
   126  		b := getBundle(true)
   127  		run := &storage.Run{
   128  			Action:         cnab.ActionInstall,
   129  			CredentialSets: []string{"mycreds"},
   130  			Credentials: storage.NewInternalCredentialSet(secrets.SourceMap{
   131  				Name: "password",
   132  				Source: secrets.Source{
   133  					Strategy: secrets.SourceSecret,
   134  					Hint:     "password",
   135  				},
   136  			}),
   137  		}
   138  		err := r.loadCredentials(context.Background(), b, run)
   139  		require.NoError(t, err, "loadCredentials failed")
   140  		require.Equal(t, "sha256:2d6d3c91ef272afeef2bb29b2fb4b1670c756c623195e71916b8ee138fba60cb",
   141  			run.CredentialsDigest, "expected loadCredentials to set the digest of resolved credentials")
   142  		require.NotEmpty(t, run.Credentials.Credentials[0].ResolvedValue, "expected loadCredentials to set the resolved value of the credentials on the Run")
   143  
   144  		gotValues := run.Credentials.ToCNAB()
   145  		assert.Equal(t, valuesource.Set{"password": "mypassword"}, gotValues, "incorrect resolved credentials")
   146  	})
   147  
   148  }
   149  
   150  func TestRuntime_nonSecretValue_loadCredentials(t *testing.T) {
   151  	t.Parallel()
   152  
   153  	r := NewTestRuntime(t)
   154  	defer r.Close()
   155  
   156  	b := cnab.NewBundle(bundle.Bundle{
   157  		Credentials: map[string]bundle.Credential{
   158  			"password": {
   159  				Location: bundle.Location{
   160  					EnvironmentVariable: "PASSWORD",
   161  				},
   162  			},
   163  		},
   164  	})
   165  
   166  	run := storage.Run{
   167  		Action: cnab.ActionInstall,
   168  		Credentials: storage.NewInternalCredentialSet(secrets.SourceMap{
   169  			Name: "password",
   170  			Source: secrets.Source{
   171  				Strategy: host.SourceValue,
   172  				Hint:     "mypassword",
   173  			},
   174  		}),
   175  	}
   176  	err := r.loadCredentials(context.Background(), b, &run)
   177  	require.NoError(t, err, "loadCredentials failed")
   178  	require.Equal(t, "sha256:9b6063069a6d911421cf53b30b91836b70957c30eddc70a760eff4765b8cede5",
   179  		run.CredentialsDigest, "expected loadCredentials to set the digest of resolved credentials")
   180  	require.NotEmpty(t, run.Credentials.Credentials[0].ResolvedValue, "expected loadCredentials to set the resolved value of the credentials on the Run")
   181  
   182  	gotValues := run.Credentials.ToCNAB()
   183  	wantValues := valuesource.Set{
   184  		"password": "mypassword",
   185  	}
   186  	assert.Equal(t, wantValues, gotValues, "resolved unexpected credential values")
   187  }