Skip to content

Commit e21ba66

Browse files
committed
Restructre cli to have subcommands
This change moves the orginal `helm diff` command to `helm diff upgrade` and adds a `helm diff version` subcommand. Using the root command is depreacted but still works to maintain backward compatibility. This change is a preparation to allow for different modes in the plugin (e.g. diffing between revisions).
1 parent 870756c commit e21ba66

File tree

10 files changed

+180
-127
lines changed

10 files changed

+180
-127
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
diff
21
vendor/
2+
bin/
3+
build/
34
release/
45
.envrc

Makefile

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,23 @@ HELM_HOME ?= $(shell helm home)
22
HAS_GLIDE := $(shell command -v glide;)
33
VERSION := $(shell sed -n -e 's/version:[ "]*\([^"]*\).*/\1/p' plugin.yaml)
44

5-
LDFLAGS := -X main.Version=$(VERSION)
6-
75
PKG:= github.com/databus23/helm-diff
6+
LDFLAGS := -X $(PKG)/cmd.Version=$(VERSION)
87

98
# Clear the "unreleased" string in BuildMetadata
109
LDFLAGS += -X $(PKG)/vendor/k8s.io/helm/pkg/version.BuildMetadata=
1110
LDFLAGS += -X $(PKG)/vendor/k8s.io/helm/pkg/version.Version=$(shell grep -A1 "package: k8s.io/helm" glide.yaml | sed -n -e 's/[ ]*version:.*\(v[.0-9]*\).*/\1/p')
1211

1312
.PHONY: install
14-
install: bootstrap build
13+
install: build
1514
mkdir -p $(HELM_HOME)/plugins/helm-diff
16-
cp diff $(HELM_HOME)/plugins/helm-diff/
15+
cp bin/diff $(HELM_HOME)/plugins/helm-diff/
1716
cp plugin.yaml $(HELM_HOME)/plugins/helm-diff/
1817

1918
.PHONY: build
2019
build:
21-
go build -i -v -o diff -ldflags="$(LDFLAGS)"
20+
mkdir -p bin/
21+
go build -i -v -o bin/diff -ldflags="$(LDFLAGS)"
2222

2323
.PHONY: bootstrap
2424
bootstrap:

helm.go renamed to cmd/helm.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package main
1+
package cmd
22

33
// This file contains functions that where blatantly copied from
44
// https://github.wdf.sap.corp/kubernetes/helm
@@ -13,9 +13,9 @@ import (
1313

1414
"github.com/ghodss/yaml"
1515
"google.golang.org/grpc"
16+
"k8s.io/helm/pkg/downloader"
1617
"k8s.io/helm/pkg/getter"
1718
"k8s.io/helm/pkg/helm/environment"
18-
"k8s.io/helm/pkg/downloader"
1919
"k8s.io/helm/pkg/helm/helmpath"
2020
"k8s.io/helm/pkg/strvals"
2121
)

cmd/root.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package cmd
2+
3+
import "github.com/spf13/cobra"
4+
5+
func New() *cobra.Command {
6+
7+
cmd := &cobra.Command{
8+
Use: "diff",
9+
Short: "Show manifest differences",
10+
}
11+
12+
chartCommand := newChartCommand()
13+
cmd.AddCommand(newVersionCmd(), chartCommand)
14+
//Alias root command to chart subcommand
15+
cmd.Args = chartCommand.Args
16+
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+
}
21+
cmd.SetHelpCommand(&cobra.Command{}) // Disable the help command
22+
23+
return cmd
24+
25+
}

cmd/upgrade.go

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package cmd
2+
3+
import (
4+
"os"
5+
6+
"github.com/databus23/helm-diff/diff"
7+
"github.com/databus23/helm-diff/manifest"
8+
"github.com/mgutz/ansi"
9+
"github.com/spf13/cobra"
10+
"k8s.io/helm/pkg/helm"
11+
)
12+
13+
type diffCmd struct {
14+
release string
15+
chart string
16+
client helm.Interface
17+
valueFiles valueFiles
18+
values []string
19+
reuseValues bool
20+
resetValues bool
21+
suppressedKinds []string
22+
}
23+
24+
const globalUsage = `Show a diff explaining what a helm upgrade would change.
25+
26+
This fetches the currently deployed version of a release
27+
and compares it to a chart plus values.
28+
This can be used visualize what changes a helm upgrade will
29+
perform.
30+
`
31+
32+
func newChartCommand() *cobra.Command {
33+
diff := diffCmd{}
34+
35+
cmd := &cobra.Command{
36+
Use: "upgrade [flags] [RELEASE] [CHART]",
37+
Short: "Show a diff explaining what a helm upgrade would change.",
38+
Long: globalUsage,
39+
Example: "helm diff upgrade my-release stable/postgresql --values values.yaml",
40+
Args: func(cmd *cobra.Command, args []string) error {
41+
return checkArgsLength(len(args), "release name", "chart path")
42+
},
43+
RunE: func(cmd *cobra.Command, args []string) error {
44+
45+
if q, _ := cmd.Flags().GetBool("suppress-secrets"); q {
46+
diff.suppressedKinds = append(diff.suppressedKinds, "Secret")
47+
}
48+
49+
if nc, _ := cmd.Flags().GetBool("no-color"); nc {
50+
ansi.DisableColors(true)
51+
}
52+
53+
diff.release = args[0]
54+
diff.chart = args[1]
55+
if diff.client == nil {
56+
diff.client = helm.NewClient(helm.Host(os.Getenv("TILLER_HOST")), helm.ConnectTimeout(int64(30)))
57+
}
58+
return diff.run()
59+
},
60+
}
61+
62+
f := cmd.Flags()
63+
f.BoolP("suppress-secrets", "q", false, "suppress secrets in the output")
64+
f.Bool("no-color", false, "remove colors from the output")
65+
f.VarP(&diff.valueFiles, "values", "f", "specify values in a YAML file (can specify multiple)")
66+
f.StringArrayVar(&diff.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
67+
f.BoolVar(&diff.reuseValues, "reuse-values", false, "reuse the last release's values and merge in any new values")
68+
f.BoolVar(&diff.resetValues, "reset-values", false, "reset the values to the ones built into the chart and merge in any new values")
69+
f.StringArrayVar(&diff.suppressedKinds, "suppress", []string{}, "allows suppression of the values listed in the diff output")
70+
71+
return cmd
72+
73+
}
74+
75+
func (d *diffCmd) run() error {
76+
chartPath, err := locateChartPath(d.chart, "", false, "")
77+
if err != nil {
78+
return err
79+
}
80+
81+
if err := d.valueFiles.Valid(); err != nil {
82+
return err
83+
}
84+
85+
rawVals, err := d.vals()
86+
if err != nil {
87+
return err
88+
}
89+
90+
releaseResponse, err := d.client.ReleaseContent(d.release)
91+
92+
if err != nil {
93+
return prettyError(err)
94+
}
95+
96+
upgradeResponse, err := d.client.UpdateRelease(
97+
d.release,
98+
chartPath,
99+
helm.UpdateValueOverrides(rawVals),
100+
helm.ReuseValues(d.reuseValues),
101+
helm.ResetValues(d.resetValues),
102+
helm.UpgradeDryRun(true),
103+
)
104+
if err != nil {
105+
return prettyError(err)
106+
}
107+
108+
currentSpecs := manifest.Parse(releaseResponse.Release.Manifest)
109+
newSpecs := manifest.Parse(upgradeResponse.Release.Manifest)
110+
111+
diff.DiffManifests(currentSpecs, newSpecs, d.suppressedKinds, os.Stdout)
112+
113+
return nil
114+
}

cmd/version.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/spf13/cobra"
7+
)
8+
9+
// Version identifier populated via the CI/CD process.
10+
var Version = "HEAD"
11+
12+
func newVersionCmd() *cobra.Command {
13+
return &cobra.Command{
14+
Use: "version",
15+
Short: "Show version of the helm diff plugin",
16+
Run: func(*cobra.Command, []string) {
17+
fmt.Println(Version)
18+
},
19+
}
20+
}

diff.go renamed to diff/diff.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package main
1+
package diff
22

33
import (
44
"fmt"
@@ -11,7 +11,7 @@ import (
1111
"github.com/databus23/helm-diff/manifest"
1212
)
1313

14-
func diffManifests(oldIndex, newIndex map[string]*manifest.MappingResult, suppressedKinds []string, to io.Writer) {
14+
func DiffManifests(oldIndex, newIndex map[string]*manifest.MappingResult, suppressedKinds []string, to io.Writer) {
1515
for key, oldContent := range oldIndex {
1616
if newContent, ok := newIndex[key]; ok {
1717
if oldContent.Content != newContent.Content {

glide.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

glide.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
package: github.com/databus23/helm-diff
22
import:
3+
- package: github.com/spf13/cobra
4+
version: 615425954c3b0d9485a7027d4d451fdcdfdee84e
5+
- package: github.com/spf13/pflag
6+
version: 583c0c0531f06d5278b7d917446061adc344b5cd
37
- package: k8s.io/helm
48
version: v2.8.2
59
#taken from k8s.io/helm hlide.yaml

main.go

Lines changed: 2 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -1,125 +1,14 @@
11
package main
22

33
import (
4-
"fmt"
54
"os"
65

7-
"github.com/mgutz/ansi"
8-
"github.com/spf13/cobra"
9-
"k8s.io/helm/pkg/helm"
10-
11-
"github.com/databus23/helm-diff/manifest"
6+
"github.com/databus23/helm-diff/cmd"
127
)
138

14-
const globalUsage = `
15-
Show a diff explaining what a helm upgrade would change.
16-
17-
This fetches the currently deployed version of a release
18-
and compares it to a local chart plus values.
19-
This can be used visualize what changes a helm upgrade will
20-
perform.
21-
`
22-
23-
// Version identifier populated via the CI/CD process.
24-
var Version = "HEAD"
25-
26-
type diffCmd struct {
27-
release string
28-
chart string
29-
client helm.Interface
30-
valueFiles valueFiles
31-
values []string
32-
reuseValues bool
33-
resetValues bool
34-
suppressedKinds []string
35-
}
36-
379
func main() {
38-
diff := diffCmd{}
39-
40-
cmd := &cobra.Command{
41-
Use: "diff [flags] [RELEASE] [CHART]",
42-
Short: "Show manifest differences",
43-
Long: globalUsage,
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-
}
4910

50-
if err := checkArgsLength(len(args), "release name", "chart path"); err != nil {
51-
return err
52-
}
53-
54-
if q, _ := cmd.Flags().GetBool("suppress-secrets"); q {
55-
diff.suppressedKinds = append(diff.suppressedKinds, "Secret")
56-
}
57-
58-
if nc, _ := cmd.Flags().GetBool("no-color"); nc {
59-
ansi.DisableColors(true)
60-
}
61-
62-
diff.release = args[0]
63-
diff.chart = args[1]
64-
if diff.client == nil {
65-
diff.client = helm.NewClient(helm.Host(os.Getenv("TILLER_HOST")), helm.ConnectTimeout(int64(30)))
66-
}
67-
return diff.run()
68-
},
69-
}
70-
71-
f := cmd.Flags()
72-
f.BoolP("version", "v", false, "show version")
73-
f.BoolP("suppress-secrets", "q", false, "suppress secrets in the output")
74-
f.Bool("no-color", false, "remove colors from the output")
75-
f.VarP(&diff.valueFiles, "values", "f", "specify values in a YAML file (can specify multiple)")
76-
f.StringArrayVar(&diff.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
77-
f.BoolVar(&diff.reuseValues, "reuse-values", false, "reuse the last release's values and merge in any new values")
78-
f.BoolVar(&diff.resetValues, "reset-values", false, "reset the values to the ones built into the chart and merge in any new values")
79-
f.StringArrayVar(&diff.suppressedKinds, "suppress", []string{}, "allows suppression of the values listed in the diff output")
80-
81-
if err := cmd.Execute(); err != nil {
11+
if err := cmd.New().Execute(); err != nil {
8212
os.Exit(1)
8313
}
8414
}
85-
86-
func (d *diffCmd) run() error {
87-
chartPath, err := locateChartPath(d.chart, "", false, "")
88-
if err != nil {
89-
return err
90-
}
91-
92-
if err := d.valueFiles.Valid(); err != nil {
93-
return err
94-
}
95-
96-
rawVals, err := d.vals()
97-
if err != nil {
98-
return err
99-
}
100-
101-
releaseResponse, err := d.client.ReleaseContent(d.release)
102-
103-
if err != nil {
104-
return prettyError(err)
105-
}
106-
107-
upgradeResponse, err := d.client.UpdateRelease(
108-
d.release,
109-
chartPath,
110-
helm.UpdateValueOverrides(rawVals),
111-
helm.ReuseValues(d.reuseValues),
112-
helm.ResetValues(d.resetValues),
113-
helm.UpgradeDryRun(true),
114-
)
115-
if err != nil {
116-
return prettyError(err)
117-
}
118-
119-
currentSpecs := manifest.Parse(releaseResponse.Release.Manifest)
120-
newSpecs := manifest.Parse(upgradeResponse.Release.Manifest)
121-
122-
diffManifests(currentSpecs, newSpecs, d.suppressedKinds, os.Stdout)
123-
124-
return nil
125-
}

0 commit comments

Comments
 (0)