diff --git a/pkg/porter/cnab.go b/pkg/porter/cnab.go index 2e003eaf2..7eeea21a9 100644 --- a/pkg/porter/cnab.go +++ b/pkg/porter/cnab.go @@ -234,11 +234,20 @@ func (o *sharedOptions) parseParams() error { // parseParamSets parses the variable assignments in ParameterSets. func (o *sharedOptions) parseParamSets(p *Porter) error { - parsed, err := p.loadParameterSets(o.ParameterSets) - if err != nil { - return errors.Wrapf(err, "unable to process provided parameter sets: %v", o.ParameterSets) + if len(o.ParameterSets) > 0 { + // Load the manifest as it may be needed to determine if any + // parameters are of the Porter-exclusive type of 'file' + err := p.LoadManifestFrom(o.File) + if err != nil { + return err + } + + parsed, err := p.loadParameterSets(o.ParameterSets) + if err != nil { + return errors.Wrapf(err, "unable to process provided parameter sets: %v", o.ParameterSets) + } + o.parsedParamSets = parsed } - o.parsedParamSets = parsed return nil } diff --git a/pkg/porter/cnab_test.go b/pkg/porter/cnab_test.go index bef422b6e..1aeb87e62 100644 --- a/pkg/porter/cnab_test.go +++ b/pkg/porter/cnab_test.go @@ -6,6 +6,7 @@ import ( "testing" "get.porter.sh/porter/pkg/build" + "get.porter.sh/porter/pkg/config" "get.porter.sh/porter/pkg/context" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -91,6 +92,10 @@ func TestSharedOptions_defaultDriver(t *testing.T) { func TestParseParamSets_viaPathOrName(t *testing.T) { p := NewTestPorter(t) + cxt := p.TestConfig.TestContext + + // Add manifest used to parse parameter sets + cxt.AddTestFile("testdata/porter.yaml", config.Name) p.TestParameters.TestSecrets.AddSecret("foo_secret", "foo_value") p.TestParameters.TestSecrets.AddSecret("PARAM2_SECRET", "VALUE2") @@ -102,6 +107,9 @@ func TestParseParamSets_viaPathOrName(t *testing.T) { "HELLO_CUSTOM", "/paramset.json", }, + bundleFileOptions: bundleFileOptions{ + File: config.Name, + }, } err := opts.parseParamSets(p.Porter) @@ -114,6 +122,33 @@ func TestParseParamSets_viaPathOrName(t *testing.T) { assert.Equal(t, wantParams, opts.parsedParamSets, "resolved unexpected parameter values") } +func TestParseParamSets_FileType(t *testing.T) { + p := NewTestPorter(t) + cxt := p.TestConfig.TestContext + + // Add manifest used to parse parameter sets + cxt.AddTestFile("testdata/porter-with-file-param.yaml", config.Name) + + p.TestConfig.TestContext.AddTestFile("testdata/paramset-with-file-param.json", "/paramset.json") + + opts := sharedOptions{ + ParameterSets: []string{ + "/paramset.json", + }, + bundleFileOptions: bundleFileOptions{ + File: config.Name, + }, + } + + err := opts.parseParamSets(p.Porter) + assert.NoError(t, err) + + wantParams := map[string]string{ + "my-file-param": "/local/path/to/my-file-param", + } + assert.Equal(t, wantParams, opts.parsedParamSets, "resolved unexpected parameter values") +} + func TestCombineParameters(t *testing.T) { t.Run("no override present, no parameter set present", func(t *testing.T) { opts := sharedOptions{} diff --git a/pkg/porter/lifecycle_test.go b/pkg/porter/lifecycle_test.go index 7cdd22d7c..731d9d162 100644 --- a/pkg/porter/lifecycle_test.go +++ b/pkg/porter/lifecycle_test.go @@ -4,6 +4,7 @@ import ( "path/filepath" "testing" + "get.porter.sh/porter/pkg/config" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -84,6 +85,10 @@ func TestInstallFromTagIgnoresCurrentBundle(t *testing.T) { func TestBundleLifecycleOpts_ToActionArgs(t *testing.T) { p := NewTestPorter(t) + cxt := p.TestConfig.TestContext + + // Add manifest which is used to parse parameter sets + cxt.AddTestFile("testdata/porter.yaml", config.Name) deps := &dependencyExecutioner{} @@ -118,6 +123,7 @@ func TestBundleLifecycleOpts_ToActionArgs(t *testing.T) { sharedOptions: sharedOptions{ bundleFileOptions: bundleFileOptions{ RelocationMapping: "relocation-mapping.json", + File: config.Name, }, Name: "MyClaim", Params: []string{ diff --git a/pkg/porter/parameters.go b/pkg/porter/parameters.go index 84523fea4..ca26baf00 100644 --- a/pkg/porter/parameters.go +++ b/pkg/porter/parameters.go @@ -307,6 +307,23 @@ func (p *Porter) loadParameterSets(params []string) (valuesource.Set, error) { return nil, err } + // A parameter may correspond to a Porter-specific parameter type of 'file' + // If so, add value (filepath) directly to map and remove from pset + for _, paramDef := range p.Manifest.Parameters { + if paramDef.Type == "file" { + for i, param := range pset.Parameters { + if param.Name == paramDef.Name { + // Pass through value (filepath) directly to resolvedParameters + resolvedParameters[param.Name] = param.Source.Value + // Eliminate this param from pset to prevent its resolution by + // the cnab-go library, which doesn't support this parameter type + pset.Parameters[i] = pset.Parameters[len(pset.Parameters)-1] + pset.Parameters = pset.Parameters[:len(pset.Parameters)-1] + } + } + } + } + rc, err := p.Parameters.ResolveAll(pset) if err != nil { return nil, err diff --git a/pkg/porter/testdata/paramset-with-file-param.json b/pkg/porter/testdata/paramset-with-file-param.json new file mode 100644 index 000000000..6a3856522 --- /dev/null +++ b/pkg/porter/testdata/paramset-with-file-param.json @@ -0,0 +1,13 @@ +{ + "name": "mypset", + "created": "1983-04-18T01:02:03.000000004Z", + "modified": "1983-04-18T01:02:03.000000004Z", + "parameters": [ + { + "name": "my-file-param", + "source": { + "path": "/local/path/to/my-file-param" + } + } + ] +} diff --git a/pkg/porter/testdata/porter-with-file-param.yaml b/pkg/porter/testdata/porter-with-file-param.yaml new file mode 100644 index 000000000..f80b04c26 --- /dev/null +++ b/pkg/porter/testdata/porter-with-file-param.yaml @@ -0,0 +1,27 @@ +name: HELLO_CUSTOM +version: 0.1.0 +description: "A bundle with a custom action" +tag: getporter/porter-hello:v0.1.0 + +parameters: + - name: my-file-param + description: "My file param" + type: file + path: /container/path/to/file + +mixins: + - exec + +install: + - exec: + description: "cat file" + command: bash + flags: + c: '"cat /container/path/to/file"' + +uninstall: + - exec: + description: "cat file" + command: bash + flags: + c: '"cat /container/path/to/file"' diff --git a/tests/install_test.go b/tests/install_test.go index 20df66c56..ccd5a7bc6 100644 --- a/tests/install_test.go +++ b/tests/install_test.go @@ -51,9 +51,11 @@ func TestInstall_fileParam(t *testing.T) { p.TestConfig.TestContext.AddTestFile(filepath.Join(p.TestDir, "testdata/bundle-with-file-params.yaml"), "porter.yaml") p.TestConfig.TestContext.AddTestFile(filepath.Join(p.TestDir, "testdata/helpers.sh"), "helpers.sh") p.TestConfig.TestContext.AddTestFile(filepath.Join(p.TestDir, "testdata/myfile"), "./myfile") + p.TestConfig.TestContext.AddTestFile(filepath.Join(p.TestDir, "testdata/myotherfile"), "./myotherfile") installOpts := porter.InstallOptions{} installOpts.Params = []string{"myfile=./myfile"} + installOpts.ParameterSets = []string{filepath.Join(p.TestDir, "testdata/parameter-set-with-file-param.json")} err := installOpts.Validate([]string{}, p.Porter) require.NoError(t, err) @@ -67,5 +69,6 @@ func TestInstall_fileParam(t *testing.T) { claim, err := p.Claims.Read(p.Manifest.Name) require.NoError(t, err, "could not fetch claim") - require.Equal(t, "Hello World!", claim.Outputs["myfile"], "expected output to match the decoded file contents") + require.Equal(t, "Hello World!", claim.Outputs["myfile"], "expected output 'myfile' to match the decoded file contents") + require.Equal(t, "Hello Other World!", claim.Outputs["myotherfile"], "expected output 'myotherfile' to match the decoded file contents") } diff --git a/tests/testdata/bundle-with-file-params.yaml b/tests/testdata/bundle-with-file-params.yaml index 5ebab2f31..677f65f62 100644 --- a/tests/testdata/bundle-with-file-params.yaml +++ b/tests/testdata/bundle-with-file-params.yaml @@ -10,6 +10,9 @@ parameters: - name: myfile type: file path: /root/myfile + - name: myotherfile + type: file + path: /root/myotherfile # This is added to cover bug fix for https://github.com/deislabs/porter/issues/835 # It will be inherently exercised in install_test.go via a default bundle installation - name: onlyUpgrade @@ -22,6 +25,11 @@ outputs: type: string applyTo: - install + - name: myotherfile + type: file + path: /root/myotherfile + applyTo: + - install install: - exec: diff --git a/tests/testdata/myotherfile b/tests/testdata/myotherfile new file mode 100644 index 000000000..cbe6fe039 --- /dev/null +++ b/tests/testdata/myotherfile @@ -0,0 +1 @@ +Hello Other World! \ No newline at end of file diff --git a/tests/testdata/parameter-set-with-file-param.json b/tests/testdata/parameter-set-with-file-param.json new file mode 100644 index 000000000..4a98695cd --- /dev/null +++ b/tests/testdata/parameter-set-with-file-param.json @@ -0,0 +1,13 @@ +{ + "name": "mybun", + "created": "2020-06-23T13:31:06.22727-06:00", + "modified": "2020-06-23T13:31:44.692834-06:00", + "parameters": [ + { + "name": "myotherfile", + "source": { + "path": "./myotherfile" + } + } + ] +} \ No newline at end of file