diff --git a/internal/helm/plan.go b/internal/helm/plan.go index 1364112..ea184f3 100644 --- a/internal/helm/plan.go +++ b/internal/helm/plan.go @@ -106,6 +106,7 @@ var upgrade = func(cfg Config) []Step { Chart: cfg.Chart, Release: cfg.Release, ChartVersion: cfg.ChartVersion, + DryRun: cfg.DryRun, Wait: cfg.Wait, ReuseValues: cfg.ReuseValues, Timeout: cfg.Timeout, diff --git a/internal/helm/plan_test.go b/internal/helm/plan_test.go index c34bc48..716a27c 100644 --- a/internal/helm/plan_test.go +++ b/internal/helm/plan_test.go @@ -93,6 +93,7 @@ func (suite *PlanTestSuite) TestUpgrade() { APIServer: "123.456.78.9", ServiceAccount: "helmet", ChartVersion: "seventeen", + DryRun: true, Wait: true, ReuseValues: true, Timeout: "go sit in the corner", @@ -126,6 +127,7 @@ func (suite *PlanTestSuite) TestUpgrade() { Chart: cfg.Chart, Release: cfg.Release, ChartVersion: cfg.ChartVersion, + DryRun: true, Wait: cfg.Wait, ReuseValues: cfg.ReuseValues, Timeout: cfg.Timeout, diff --git a/internal/run/upgrade.go b/internal/run/upgrade.go index 9fa6180..cff2c70 100644 --- a/internal/run/upgrade.go +++ b/internal/run/upgrade.go @@ -10,6 +10,7 @@ type Upgrade struct { Release string ChartVersion string + DryRun bool Wait bool ReuseValues bool Timeout string @@ -25,18 +26,53 @@ func (u *Upgrade) Execute(_ Config) error { // Prepare gets the Upgrade ready to execute. func (u *Upgrade) Prepare(cfg Config) error { + if u.Chart == "" { + return fmt.Errorf("chart is required") + } + if u.Release == "" { + return fmt.Errorf("release is required") + } + args := []string{"--kubeconfig", cfg.KubeConfig} if cfg.Namespace != "" { args = append(args, "--namespace", cfg.Namespace) } - - args = append(args, "upgrade", "--install", u.Release, u.Chart) - if cfg.Debug { - args = append([]string{"--debug"}, args...) + args = append(args, "--debug") } + args = append(args, "upgrade", "--install") + + if u.ChartVersion != "" { + args = append(args, "--version", u.ChartVersion) + } + if u.DryRun { + args = append(args, "--dry-run") + } + if u.Wait { + args = append(args, "--wait") + } + if u.ReuseValues { + args = append(args, "--reuse-values") + } + if u.Timeout != "" { + args = append(args, "--timeout", u.Timeout) + } + if u.Force { + args = append(args, "--force") + } + if cfg.Values != "" { + args = append(args, "--set", cfg.Values) + } + if cfg.StringValues != "" { + args = append(args, "--set-string", cfg.StringValues) + } + for _, vFile := range cfg.ValuesFiles { + args = append(args, "--values", vFile) + } + + args = append(args, u.Release, u.Chart) u.cmd = command(helmBin, args...) u.cmd.Stdout(cfg.Stdout) u.cmd.Stderr(cfg.Stderr) diff --git a/internal/run/upgrade_test.go b/internal/run/upgrade_test.go index 19b84b9..13b2080 100644 --- a/internal/run/upgrade_test.go +++ b/internal/run/upgrade_test.go @@ -31,7 +31,7 @@ func TestUpgradeTestSuite(t *testing.T) { suite.Run(t, new(UpgradeTestSuite)) } -func (suite *UpgradeTestSuite) TestPrepare() { +func (suite *UpgradeTestSuite) TestPrepareAndExecute() { defer suite.ctrl.Finish() u := Upgrade{ @@ -79,12 +79,8 @@ func (suite *UpgradeTestSuite) TestPrepareNamespaceFlag() { return suite.mockCmd } - suite.mockCmd.EXPECT(). - Stdout(gomock.Any()) - suite.mockCmd.EXPECT(). - Stderr(gomock.Any()) - suite.mockCmd.EXPECT(). - Run() + suite.mockCmd.EXPECT().Stdout(gomock.Any()) + suite.mockCmd.EXPECT().Stderr(gomock.Any()) cfg := Config{ Namespace: "melt", @@ -92,7 +88,72 @@ func (suite *UpgradeTestSuite) TestPrepareNamespaceFlag() { } err := u.Prepare(cfg) suite.Require().Nil(err) - u.Execute(cfg) +} + +func (suite *UpgradeTestSuite) TestPrepareWithUpgradeFlags() { + defer suite.ctrl.Finish() + + u := Upgrade{ + Chart: "hot_ac", + Release: "maroon_5_memories", + ChartVersion: "radio_edit", //-version + DryRun: true, //-run + Wait: true, //-wait + ReuseValues: true, //-values + Timeout: "sit_in_the_corner", //-timeout + Force: true, //-force + } + + cfg := Config{ + KubeConfig: "/root/.kube/config", + Values: "age=35", + StringValues: "height=5ft10in", + ValuesFiles: []string{"/usr/local/stats", "/usr/local/grades"}, + } + + command = func(path string, args ...string) cmd { + suite.Equal(helmBin, path) + suite.Equal([]string{"--kubeconfig", "/root/.kube/config", "upgrade", "--install", + "--version", "radio_edit", + "--dry-run", + "--wait", + "--reuse-values", + "--timeout", "sit_in_the_corner", + "--force", + "--set", "age=35", + "--set-string", "height=5ft10in", + "--values", "/usr/local/stats", + "--values", "/usr/local/grades", + "maroon_5_memories", "hot_ac"}, args) + + return suite.mockCmd + } + + suite.mockCmd.EXPECT().Stdout(gomock.Any()) + suite.mockCmd.EXPECT().Stderr(gomock.Any()) + + err := u.Prepare(cfg) + suite.Require().Nil(err) +} + +func (suite *UpgradeTestSuite) TestRequiresChartAndRelease() { + // These aren't really expected, but allowing them gives clearer test-failure messages + suite.mockCmd.EXPECT().Stdout(gomock.Any()).AnyTimes() + suite.mockCmd.EXPECT().Stderr(gomock.Any()).AnyTimes() + + u := Upgrade{ + Release: "seth_everman_unskippable_cutscene", + } + + err := u.Prepare(Config{}) + suite.EqualError(err, "chart is required", "Chart should be mandatory") + + u = Upgrade{ + Chart: "billboard_top_zero", + } + + err = u.Prepare(Config{}) + suite.EqualError(err, "release is required", "Release should be mandatory") } func (suite *UpgradeTestSuite) TestPrepareDebugFlag() { @@ -125,7 +186,7 @@ func (suite *UpgradeTestSuite) TestPrepareDebugFlag() { u.Prepare(cfg) - want := fmt.Sprintf("Generated command: '%s --debug --kubeconfig /root/.kube/config upgrade "+ + want := fmt.Sprintf("Generated command: '%s --kubeconfig /root/.kube/config --debug upgrade "+ "--install lewis_capaldi_someone_you_loved at40'\n", helmBin) suite.Equal(want, stderr.String()) suite.Equal("", stdout.String())