get.porter.sh/porter@v1.3.0/pkg/storage/credentialset_test.go (about)

     1  package storage
     2  
     3  import (
     4  	"context"
     5  	"strings"
     6  	"testing"
     7  	"time"
     8  
     9  	"get.porter.sh/porter/pkg/cnab"
    10  	"get.porter.sh/porter/pkg/encoding"
    11  	"get.porter.sh/porter/pkg/schema"
    12  	"get.porter.sh/porter/pkg/secrets"
    13  	"get.porter.sh/porter/tests"
    14  	"github.com/cnabio/cnab-go/bundle"
    15  	"github.com/stretchr/testify/assert"
    16  	"github.com/stretchr/testify/require"
    17  )
    18  
    19  func TestNewCredentialSet(t *testing.T) {
    20  	cs := NewCredentialSet("dev", "mycreds", secrets.SourceMap{
    21  		Name: "password",
    22  		Source: secrets.Source{
    23  			Strategy: "env",
    24  			Hint:     "MY_PASSWORD",
    25  		},
    26  	})
    27  
    28  	assert.Equal(t, "mycreds", cs.Name, "Name was not set")
    29  	assert.Equal(t, "dev", cs.Namespace, "Namespace was not set")
    30  	assert.NotEmpty(t, cs.Status.Created, "Created was not set")
    31  	assert.NotEmpty(t, cs.Status.Modified, "Modified was not set")
    32  	assert.Equal(t, cs.Status.Created, cs.Status.Modified, "Created and Modified should have the same timestamp")
    33  	assert.Equal(t, SchemaTypeCredentialSet, cs.SchemaType, "incorrect SchemaType")
    34  	assert.Equal(t, DefaultCredentialSetSchemaVersion, cs.SchemaVersion, "incorrect SchemaVersion")
    35  	assert.Len(t, cs.Credentials, 1, "Credentials should be initialized with 1 value")
    36  }
    37  
    38  func TestValidate(t *testing.T) {
    39  	t.Run("valid - credential specified", func(t *testing.T) {
    40  		spec := map[string]bundle.Credential{
    41  			"kubeconfig": {},
    42  		}
    43  		cs := CredentialSet{CredentialSetSpec: CredentialSetSpec{
    44  			Credentials: []secrets.SourceMap{
    45  				{Name: "kubeconfig", ResolvedValue: "top secret creds"},
    46  			}}}
    47  
    48  		err := cs.ValidateBundle(spec, "install")
    49  		require.NoError(t, err, "expected Validate to pass because the credential was specified")
    50  	})
    51  
    52  	t.Run("valid - credential not required", func(t *testing.T) {
    53  		spec := map[string]bundle.Credential{
    54  			"kubeconfig": {ApplyTo: []string{"install"}, Required: false},
    55  		}
    56  		cs := CredentialSet{}
    57  		err := cs.ValidateBundle(spec, "install")
    58  		require.NoError(t, err, "expected Validate to pass because the credential isn't required")
    59  	})
    60  
    61  	t.Run("valid - missing inapplicable credential", func(t *testing.T) {
    62  		spec := map[string]bundle.Credential{
    63  			"kubeconfig": {ApplyTo: []string{"install"}, Required: true},
    64  		}
    65  		cs := CredentialSet{}
    66  		err := cs.ValidateBundle(spec, "custom")
    67  		require.NoError(t, err, "expected Validate to pass because the credential isn't applicable to the custom action")
    68  	})
    69  
    70  	t.Run("invalid - missing required credential", func(t *testing.T) {
    71  		spec := map[string]bundle.Credential{
    72  			"kubeconfig": {ApplyTo: []string{"install"}, Required: true},
    73  		}
    74  		cs := CredentialSet{}
    75  		err := cs.ValidateBundle(spec, "install")
    76  		require.Error(t, err, "expected Validate to fail because the credential applies to the specified action and is required")
    77  		assert.Contains(t, err.Error(), "bundle requires credential")
    78  	})
    79  }
    80  
    81  func TestDisplayCredentials_Validate(t *testing.T) {
    82  	t.Parallel()
    83  
    84  	testcases := []struct {
    85  		name          string
    86  		schemaType    string
    87  		schemaVersion cnab.SchemaVersion
    88  		wantError     string
    89  	}{
    90  		{
    91  			name:          "schemaType: none",
    92  			schemaType:    "",
    93  			schemaVersion: DefaultCredentialSetSchemaVersion,
    94  			wantError:     ""},
    95  		{
    96  			name:          "schemaType: CredentialSet",
    97  			schemaType:    SchemaTypeCredentialSet,
    98  			schemaVersion: DefaultCredentialSetSchemaVersion,
    99  			wantError:     ""},
   100  		{
   101  			name:          "schemaType: CREDENTIALSET",
   102  			schemaType:    strings.ToUpper(SchemaTypeCredentialSet),
   103  			schemaVersion: DefaultCredentialSetSchemaVersion,
   104  			wantError:     ""},
   105  		{
   106  			name:          "schemaType: credentialset",
   107  			schemaType:    strings.ToLower(SchemaTypeCredentialSet),
   108  			schemaVersion: DefaultCredentialSetSchemaVersion,
   109  			wantError:     ""},
   110  		{
   111  			name:          "schemaType: ParameterSet",
   112  			schemaType:    SchemaTypeParameterSet,
   113  			schemaVersion: DefaultCredentialSetSchemaVersion,
   114  			wantError:     "invalid schemaType ParameterSet, expected CredentialSet"},
   115  		{
   116  			name:          "validate embedded cs",
   117  			schemaType:    SchemaTypeCredentialSet,
   118  			schemaVersion: "", // required!
   119  			wantError:     "invalid schema version"},
   120  	}
   121  
   122  	for _, tc := range testcases {
   123  		tc := tc
   124  		t.Run(tc.name, func(t *testing.T) {
   125  			t.Parallel()
   126  			cs := CredentialSet{
   127  				CredentialSetSpec: CredentialSetSpec{
   128  					SchemaType:    tc.schemaType,
   129  					SchemaVersion: tc.schemaVersion,
   130  				}}
   131  
   132  			err := cs.Validate(context.Background(), schema.CheckStrategyExact)
   133  			if tc.wantError == "" {
   134  				require.NoError(t, err)
   135  			} else {
   136  				tests.RequireErrorContains(t, err, tc.wantError)
   137  			}
   138  		})
   139  	}
   140  }
   141  
   142  func TestCredentialSet_Validate_DefaultSchemaType(t *testing.T) {
   143  	cs := NewCredentialSet("", "mycs")
   144  	cs.SchemaType = ""
   145  	require.NoError(t, cs.Validate(context.Background(), schema.CheckStrategyExact))
   146  	assert.Equal(t, SchemaTypeCredentialSet, cs.SchemaType)
   147  }
   148  
   149  func TestMarshal(t *testing.T) {
   150  	now, _ := time.Parse(time.RFC3339, "2006-01-02T15:04:05Z07:00")
   151  
   152  	orig := CredentialSet{
   153  		CredentialSetSpec: CredentialSetSpec{
   154  			SchemaVersion: "schemaVersion",
   155  			Namespace:     "namespace",
   156  			Name:          "name",
   157  			Credentials: []secrets.SourceMap{
   158  				{
   159  					Name: "cred1",
   160  					Source: secrets.Source{
   161  						Strategy: "secret",
   162  						Hint:     "mysecret",
   163  					},
   164  				},
   165  			},
   166  		},
   167  		Status: CredentialSetStatus{
   168  			Created:  now,
   169  			Modified: now,
   170  		},
   171  	}
   172  
   173  	formats := []string{"json", "yaml"}
   174  	for _, format := range formats {
   175  		t.Run(format, func(t *testing.T) {
   176  			raw, err := encoding.Marshal(format, orig)
   177  			require.NoError(t, err)
   178  
   179  			var copy CredentialSet
   180  			err = encoding.Unmarshal(format, raw, &copy)
   181  			require.NoError(t, err)
   182  			assert.Equal(t, orig, copy)
   183  		})
   184  	}
   185  }
   186  
   187  func TestCredentialSet_String(t *testing.T) {
   188  	t.Run("global namespace", func(t *testing.T) {
   189  		cs := CredentialSet{CredentialSetSpec: CredentialSetSpec{Name: "mycreds"}}
   190  		assert.Equal(t, "/mycreds", cs.String())
   191  	})
   192  
   193  	t.Run("local namespace", func(t *testing.T) {
   194  		cs := CredentialSet{CredentialSetSpec: CredentialSetSpec{Namespace: "dev", Name: "mycreds"}}
   195  		assert.Equal(t, "dev/mycreds", cs.String())
   196  	})
   197  }