Skip to content

Commit 72467ef

Browse files
committed
adding revision and rollback subcommands
1 parent 993b7db commit 72467ef

File tree

4 files changed

+231
-17
lines changed

4 files changed

+231
-17
lines changed

cmd/revision.go

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package cmd
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"os"
7+
"strconv"
8+
9+
"github.com/databus23/helm-diff/diff"
10+
"github.com/databus23/helm-diff/manifest"
11+
"github.com/spf13/cobra"
12+
"k8s.io/helm/pkg/helm"
13+
)
14+
15+
type revision struct {
16+
release string
17+
client helm.Interface
18+
suppressedKinds []string
19+
revisions []string
20+
}
21+
22+
const revisionCmdLongUsage = `
23+
This command compares the manifests details of a named release.
24+
25+
It can be used to compare the manifests of
26+
27+
- lastest REVISION with specified REVISION
28+
$ helm diff revision [flags] RELEASE REVISION1
29+
Example:
30+
$ helm diff revision my-release 2
31+
32+
- REVISION1 with REVISION2
33+
$ helm diff revision [flags] RELEASE REVISION1 REVISION2
34+
Example:
35+
$ helm diff revision my-release 2 3
36+
`
37+
38+
func revisionCmd() *cobra.Command {
39+
diff := revision{}
40+
revisionCmd := &cobra.Command{
41+
Use: "revision [flags] RELEASE REVISION1 [REVISION2]",
42+
Short: "Shows diff between revision's manifests",
43+
Long: revisionCmdLongUsage,
44+
RunE: func(cmd *cobra.Command, args []string) error {
45+
if v, _ := cmd.Flags().GetBool("version"); v {
46+
fmt.Println(Version)
47+
return nil
48+
}
49+
50+
switch {
51+
case len(args) < 2:
52+
return errors.New("Too few arguments to Command \"revision\".\nMinimum 2 arguments required: release name, revision")
53+
case len(args) > 3:
54+
return errors.New("Too many arguments to Command \"revision\".\nMaximum 3 arguments allowed: release name, revision1, revision2")
55+
}
56+
57+
if q, _ := cmd.Flags().GetBool("suppress-secrets"); q {
58+
diff.suppressedKinds = append(diff.suppressedKinds, "Secret")
59+
}
60+
61+
diff.release = args[0]
62+
diff.revisions = args[1:]
63+
if diff.client == nil {
64+
diff.client = helm.NewClient(helm.Host(os.Getenv("TILLER_HOST")), helm.ConnectTimeout(int64(30)))
65+
}
66+
return diff.differentiate()
67+
},
68+
}
69+
70+
revisionCmd.Flags().BoolP("suppress-secrets", "q", false, "suppress secrets in the output")
71+
revisionCmd.Flags().StringArrayVar(&diff.suppressedKinds, "suppress", []string{}, "allows suppression of the values listed in the diff output")
72+
revisionCmd.SuggestionsMinimumDistance = 1
73+
return revisionCmd
74+
}
75+
76+
func (d *revision) differentiate() error {
77+
78+
switch len(d.revisions) {
79+
case 1:
80+
releaseResponse, err := d.client.ReleaseContent(d.release)
81+
82+
if err != nil {
83+
return prettyError(err)
84+
}
85+
86+
revision, _ := strconv.Atoi(d.revisions[0])
87+
revisionResponse, err := d.client.ReleaseContent(d.release, helm.ContentReleaseVersion(int32(revision)))
88+
if err != nil {
89+
return prettyError(err)
90+
}
91+
92+
diff.DiffManifests(manifest.Parse(revisionResponse.Release.Manifest), manifest.Parse(releaseResponse.Release.Manifest), d.suppressedKinds, os.Stdout)
93+
94+
case 2:
95+
revision1, _ := strconv.Atoi(d.revisions[0])
96+
revision2, _ := strconv.Atoi(d.revisions[1])
97+
if revision1 > revision2 {
98+
revision1, revision2 = revision2, revision1
99+
}
100+
101+
revisionResponse1, err := d.client.ReleaseContent(d.release, helm.ContentReleaseVersion(int32(revision1)))
102+
if err != nil {
103+
return prettyError(err)
104+
}
105+
106+
revisionResponse2, err := d.client.ReleaseContent(d.release, helm.ContentReleaseVersion(int32(revision2)))
107+
if err != nil {
108+
return prettyError(err)
109+
}
110+
111+
diff.DiffManifests(manifest.Parse(revisionResponse1.Release.Manifest), manifest.Parse(revisionResponse2.Release.Manifest), d.suppressedKinds, os.Stdout)
112+
113+
default:
114+
return errors.New("Invalid Arguments")
115+
}
116+
117+
return nil
118+
}

cmd/rollback.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"strconv"
7+
8+
"github.com/databus23/helm-diff/diff"
9+
"github.com/databus23/helm-diff/manifest"
10+
"github.com/spf13/cobra"
11+
"k8s.io/helm/pkg/helm"
12+
)
13+
14+
type rollback struct {
15+
release string
16+
client helm.Interface
17+
suppressedKinds []string
18+
revisions []string
19+
}
20+
21+
const rollbackCmdLongUsage = `
22+
This command compares the laset manifests details of a named release
23+
with specific revision values to rollback.
24+
25+
It forecasts/visualizes changes, that a helm rollback could perform.
26+
`
27+
28+
func rollbackCmd() *cobra.Command {
29+
diff := rollback{}
30+
rollbackCmd := &cobra.Command{
31+
Use: "rollback [flags] [RELEASE] [REVISION]",
32+
Short: "Show a diff explaining what a helm rollback could perform",
33+
Long: rollbackCmdLongUsage,
34+
Example: " helm diff rollback my-release 2",
35+
RunE: func(cmd *cobra.Command, args []string) error {
36+
if v, _ := cmd.Flags().GetBool("version"); v {
37+
fmt.Println(Version)
38+
return nil
39+
}
40+
41+
if err := checkArgsLength(len(args), "release name", "revision number"); err != nil {
42+
return err
43+
}
44+
45+
if q, _ := cmd.Flags().GetBool("suppress-secrets"); q {
46+
diff.suppressedKinds = append(diff.suppressedKinds, "Secret")
47+
}
48+
49+
diff.release = args[0]
50+
diff.revisions = args[1:]
51+
52+
if diff.client == nil {
53+
diff.client = helm.NewClient(helm.Host(os.Getenv("TILLER_HOST")), helm.ConnectTimeout(int64(30)))
54+
}
55+
56+
return diff.backcast()
57+
},
58+
}
59+
60+
rollbackCmd.Flags().BoolP("suppress-secrets", "q", false, "suppress secrets in the output")
61+
rollbackCmd.Flags().StringArrayVar(&diff.suppressedKinds, "suppress", []string{}, "allows suppression of the values listed in the diff output")
62+
rollbackCmd.SuggestionsMinimumDistance = 1
63+
return rollbackCmd
64+
}
65+
66+
func (d *rollback) backcast() error {
67+
68+
// get manifest of the latest release
69+
releaseResponse, err := d.client.ReleaseContent(d.release)
70+
71+
if err != nil {
72+
return prettyError(err)
73+
}
74+
75+
// get manifest of the release to rollback
76+
revision, _ := strconv.Atoi(d.revisions[0])
77+
revisionResponse, err := d.client.ReleaseContent(d.release, helm.ContentReleaseVersion(int32(revision)))
78+
if err != nil {
79+
return prettyError(err)
80+
}
81+
82+
// create a diff between the current manifest and the version of the manifest that a user is intended to rollback
83+
diff.DiffManifests(manifest.Parse(releaseResponse.Release.Manifest), manifest.Parse(revisionResponse.Release.Manifest), d.suppressedKinds, os.Stdout)
84+
85+
return nil
86+
}

cmd/root.go

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,41 @@
11
package cmd
22

3-
import "github.com/spf13/cobra"
3+
import (
4+
"github.com/mgutz/ansi"
5+
"github.com/spf13/cobra"
6+
)
47

58
func New() *cobra.Command {
69

10+
chartCommand := newChartCommand()
11+
712
cmd := &cobra.Command{
813
Use: "diff",
914
Short: "Show manifest differences",
15+
//Alias root command to chart subcommand
16+
Args: chartCommand.Args,
17+
// parse the flags and check for actions like suppress-secrets, no-colors
18+
PersistentPreRun: func(cmd *cobra.Command, args []string) {
19+
if nc, _ := cmd.Flags().GetBool("no-color"); nc {
20+
ansi.DisableColors(true)
21+
}
22+
},
23+
RunE: func(cmd *cobra.Command, args []string) error {
24+
cmd.Println(`Command "helm diff" is deprecated, use "helm diff upgrade" instead`)
25+
return chartCommand.RunE(cmd, args)
26+
},
1027
}
1128

12-
chartCommand := newChartCommand()
13-
cmd.AddCommand(newVersionCmd(), chartCommand)
14-
//Alias root command to chart subcommand
15-
cmd.Args = chartCommand.Args
29+
// add no-color as global flag
30+
cmd.PersistentFlags().Bool("no-color", false, "remove colors from the output")
31+
// add flagset from chartCommand
1632
cmd.Flags().AddFlagSet(chartCommand.Flags())
17-
cmd.RunE = func(cmd *cobra.Command, args []string) error {
18-
cmd.Println(`Command "helm diff" is deprecated, use "helm diff upgrade" instead`)
19-
return chartCommand.RunE(cmd, args)
20-
}
33+
cmd.AddCommand(newVersionCmd(), chartCommand)
34+
// add subcommands
35+
cmd.AddCommand(
36+
revisionCmd(),
37+
rollbackCmd(),
38+
)
2139
cmd.SetHelpCommand(&cobra.Command{}) // Disable the help command
22-
2340
return cmd
24-
2541
}

cmd/upgrade.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55

66
"github.com/databus23/helm-diff/diff"
77
"github.com/databus23/helm-diff/manifest"
8-
"github.com/mgutz/ansi"
98
"github.com/spf13/cobra"
109
"k8s.io/helm/pkg/helm"
1110
)
@@ -47,10 +46,6 @@ func newChartCommand() *cobra.Command {
4746
diff.suppressedKinds = append(diff.suppressedKinds, "Secret")
4847
}
4948

50-
if nc, _ := cmd.Flags().GetBool("no-color"); nc {
51-
ansi.DisableColors(true)
52-
}
53-
5449
diff.release = args[0]
5550
diff.chart = args[1]
5651
if diff.client == nil {
@@ -63,7 +58,6 @@ func newChartCommand() *cobra.Command {
6358
f := cmd.Flags()
6459
f.StringVar(&diff.chartVersion, "version", "", "specify the exact chart version to use. If this is not specified, the latest version is used")
6560
f.BoolP("suppress-secrets", "q", false, "suppress secrets in the output")
66-
f.Bool("no-color", false, "remove colors from the output")
6761
f.VarP(&diff.valueFiles, "values", "f", "specify values in a YAML file (can specify multiple)")
6862
f.StringArrayVar(&diff.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
6963
f.BoolVar(&diff.reuseValues, "reuse-values", false, "reuse the last release's values and merge in any new values")

0 commit comments

Comments
 (0)