forked from databus23/helm-diff
-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
156 lines (127 loc) · 3.98 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package main
import (
"fmt"
"os"
"strings"
"github.com/mgutz/ansi"
"github.com/spf13/cobra"
"k8s.io/helm/pkg/helm"
"github.com/databus23/helm-diff/manifest"
)
const globalUsage = `
Show a diff explaining what a helm upgrade would change.
This fetches the currently deployed version of a release
and compares it to a local chart plus values.
This can be used visualize what changes a helm upgrade will
perform.
`
// Version identifier populated via the CI/CD process.
var Version = "HEAD"
type diffCmd struct {
release string
chart string
version string
client helm.Interface
valueFiles valueFiles
values []string
reuseValues bool
resetValues bool
suppressedKinds []string
}
func main() {
diff := diffCmd{}
cmd := &cobra.Command{
Use: "diff [flags] [RELEASE] [CHART]@[CHART VERSION]",
Short: "Show manifest differences",
Long: globalUsage,
RunE: func(cmd *cobra.Command, args []string) error {
if v, _ := cmd.Flags().GetBool("version"); v {
fmt.Println(Version)
return nil
}
if err := checkArgsLength(len(args), "release name", "chart path"); err != nil {
return err
}
if q, _ := cmd.Flags().GetBool("suppress-secrets"); q {
diff.suppressedKinds = append(diff.suppressedKinds, "Secret")
}
if nc, _ := cmd.Flags().GetBool("no-color"); nc {
ansi.DisableColors(true)
}
diff.release = args[0]
diff.chart = args[1]
diff.version = ""
if strings.Contains(args[1], "@") {
s := strings.Split(args[1], "@")
diff.chart = s[0]
diff.version = s[1]
}
if diff.client == nil {
diff.client = helm.NewClient(helm.Host(os.Getenv("TILLER_HOST")))
}
return diff.run()
},
}
f := cmd.Flags()
f.BoolP("version", "v", false, "show version")
f.BoolP("suppress-secrets", "q", false, "suppress secrets in the output")
f.Bool("no-color", false, "remove colors from the output")
f.VarP(&diff.valueFiles, "values", "f", "specify values in a YAML file (can specify multiple)")
f.StringArrayVar(&diff.values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
f.BoolVar(&diff.reuseValues, "reuse-values", false, "reuse the last release's values and merge in any new values")
f.BoolVar(&diff.resetValues, "reset-values", false, "reset the values to the ones built into the chart and merge in any new values")
f.StringArrayVar(&diff.suppressedKinds, "suppress", []string{}, "allows suppression of the values listed in the diff output")
if err := cmd.Execute(); err != nil {
os.Exit(1)
}
}
func (d *diffCmd) run() error {
chartPath, err := locateChartPath(d.chart, d.version, false, "")
if err != nil {
return err
}
rawVals, err := d.vals()
if err != nil {
return err
}
releaseResponse, err := d.client.ReleaseContent(d.release)
var newInstall bool
if err != nil && strings.Contains(err.Error(), fmt.Sprintf("release: %q not found", d.release)) {
fmt.Println("Release was not present in Helm. Diff will show entire contents as new.")
newInstall = true
err = nil
}
if err != nil {
return prettyError(err)
}
var currentSpecs, newSpecs map[string]*manifest.MappingResult
if newInstall {
installResponse, err := d.client.InstallRelease(
chartPath,
"default",
helm.ReleaseName(d.release),
helm.ValueOverrides(rawVals),
helm.InstallDryRun(true),
)
if err != nil {
return prettyError(err)
}
currentSpecs = make(map[string]*manifest.MappingResult)
newSpecs = manifest.Parse(installResponse.Release.Manifest)
} else {
upgradeResponse, err := d.client.UpdateRelease(
d.release,
chartPath,
helm.UpdateValueOverrides(rawVals),
helm.ReuseValues(d.reuseValues),
helm.UpgradeDryRun(true),
)
if err != nil {
return prettyError(err)
}
currentSpecs = manifest.Parse(releaseResponse.Release.Manifest)
newSpecs = manifest.Parse(upgradeResponse.Release.Manifest)
}
diffManifests(currentSpecs, newSpecs, d.suppressedKinds, os.Stdout)
return nil
}