From 4a97bfcaf01c6487bca6e1ba79ded2c634545aaf Mon Sep 17 00:00:00 2001 From: Carolyn Van Slyck Date: Mon, 18 Mar 2019 10:55:07 -0500 Subject: [PATCH] Skelletor the install command --- cmd/porter/bundle.go | 55 ++++++++++++++++++++++++++++++++++++++ cmd/porter/bundle_test.go | 38 ++++++++++++++++++++++++++ cmd/porter/main.go | 2 ++ cmd/porter/main_test.go | 31 +++++++++++++++++++++ pkg/porter/install.go | 48 +++++++++++++++++++++++++++++++++ pkg/porter/install_test.go | 19 +++++++++++++ 6 files changed, 193 insertions(+) create mode 100644 cmd/porter/bundle.go create mode 100644 cmd/porter/bundle_test.go create mode 100644 cmd/porter/main_test.go create mode 100644 pkg/porter/install.go create mode 100644 pkg/porter/install_test.go diff --git a/cmd/porter/bundle.go b/cmd/porter/bundle.go new file mode 100644 index 0000000000..ecf97ea69e --- /dev/null +++ b/cmd/porter/bundle.go @@ -0,0 +1,55 @@ +package main + +import ( + "github.com/deislabs/porter/pkg/porter" + "github.com/spf13/cobra" +) + +func buildBundleCommands(p *porter.Porter) *cobra.Command { + cmd := &cobra.Command{ + Use: "bundle", + Short: "bundle commands", + } + + cmd.AddCommand(buildBundleInstallCommand(p)) + + return cmd +} + +func buildBundleInstallCommand(p *porter.Porter) *cobra.Command { + opts := porter.InstallOptions{} + cmd := &cobra.Command{ + Use: "install", + Short: "Install a bundle", + Example: ` porter install + porter install --insecure + porter install --file myapp/bundle.json + porter install --name MyAppInDev + porter install --param-file=base-values.txt --param-file=dev-values.txt --param test-mode=true --param header-color=blue +`, + PreRunE: func(cmd *cobra.Command, args []string) error { + return opts.Prepare() + }, + RunE: func(cmd *cobra.Command, args []string) error { + return p.InstallBundle(opts) + }, + } + + f := cmd.Flags() + f.BoolVar(&opts.Insecure, "insecure", false, + "Allow installing untrusted bundles") + f.StringVarP(&opts.File, "file", "f", "bundle.json", + "Path to the CNAB definition to install") + f.StringVar(&opts.Name, "name", "", + "Name of the claim, defaults to the name of the bundle") + f.StringSliceVar(&opts.ParamFiles, "param-file", nil, + "Path to a parameters definition file for the bundle, each line in the form of NAME=VALUE. May be specified multiple times.") + f.StringSliceVar(&opts.RawParams, "param", nil, + "Define an individual parameter in the form NAME=VALUE. Overrides parameters set with the same name using --param-file. May be specified multiple times.") + + return cmd +} + +func buildInstallCommand(p *porter.Porter) *cobra.Command { + return buildBundleInstallCommand(p) +} diff --git a/cmd/porter/bundle_test.go b/cmd/porter/bundle_test.go new file mode 100644 index 0000000000..179df11e98 --- /dev/null +++ b/cmd/porter/bundle_test.go @@ -0,0 +1,38 @@ +package main + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestValidateInstallCommand(t *testing.T) { + testcases := []struct { + name string + args string + wantError string + }{ + {"no args", "install", ""}, + {"invalid param", "install --param A:B", "invalid parameter (A:B), must be in name=value format"}, + } + + for _, tc := range testcases { + t.Run(tc.name, func(t *testing.T) { + p := buildRootCommand() + osargs := strings.Split(tc.args, " ") + cmd, args, err := p.Find(osargs) + require.NoError(t, err) + + err = cmd.ParseFlags(args) + require.NoError(t, err) + + err = cmd.PreRunE(cmd, args) + if tc.wantError == "" { + require.NoError(t, err) + } else { + require.EqualError(t, err, tc.wantError) + } + }) + } +} diff --git a/cmd/porter/main.go b/cmd/porter/main.go index 4e91bf5cb8..0011638d8b 100644 --- a/cmd/porter/main.go +++ b/cmd/porter/main.go @@ -35,6 +35,8 @@ func buildRootCommand() *cobra.Command { cmd.AddCommand(buildCreateCommand(p)) cmd.AddCommand(buildRunCommand(p)) cmd.AddCommand(buildBuildCommand(p)) + cmd.AddCommand(buildBundleCommands(p)) + cmd.AddCommand(buildInstallCommand(p)) cmd.AddCommand(buildListCommands(p)) return cmd diff --git a/cmd/porter/main_test.go b/cmd/porter/main_test.go new file mode 100644 index 0000000000..ff72581713 --- /dev/null +++ b/cmd/porter/main_test.go @@ -0,0 +1,31 @@ +package main + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestCommandWiring(t *testing.T) { + testcases := []string{ + "build", + "create", + "install", + "run", + "schema", + "bundle install", + "list mixins", + "version", + } + + for _, tc := range testcases { + t.Run(tc, func(t *testing.T) { + osargs := strings.Split(tc, " ") + + rootCmd := buildRootCommand() + _, _, err := rootCmd.Find(osargs) + assert.NoError(t, err) + }) + } +} diff --git a/pkg/porter/install.go b/pkg/porter/install.go new file mode 100644 index 0000000000..b054bf25f6 --- /dev/null +++ b/pkg/porter/install.go @@ -0,0 +1,48 @@ +package porter + +import ( + "fmt" + + "github.com/deislabs/porter/pkg/parameters" +) + +type InstallOptions struct { + // Name of the claim. + Name string + + // File path to the CNAB bundle. + File string + + // Insecure bundle installation allowed. + Insecure bool + + // RawParams is the unparsed list of NAME=VALUE parameters set on the command line. + RawParams []string + + // Params is the parsed set of parameters from RawParams. + Params map[string]string + + // ParamFiles is a list of file paths containing lines of NAME=VALUE parameter definitions. + ParamFiles []string +} + +func (o *InstallOptions) Prepare() error { + return o.parseParams() +} + +func (o *InstallOptions) parseParams() error { + p, err := parameters.ParseVariableAssignments(o.RawParams) + if err == nil { + o.Params = p + } + return err +} + +func (p *Porter) InstallBundle(opts InstallOptions) error { + err := p.Config.LoadManifest() + if err != nil { + return err + } + fmt.Fprintf(p.Out, "installing %s...\n", p.Manifest.Name) + return nil +} diff --git a/pkg/porter/install_test.go b/pkg/porter/install_test.go new file mode 100644 index 0000000000..27ee697622 --- /dev/null +++ b/pkg/porter/install_test.go @@ -0,0 +1,19 @@ +package porter + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestInstallOptions_Prepare(t *testing.T) { + opts := InstallOptions{ + RawParams: []string{"A=1", "B=2"}, + } + + err := opts.Prepare() + require.NoError(t, err) + + assert.Len(t, opts.Params, 2) +}