Skip to content

Commit b542ea9

Browse files
Copilotyxxhero
andcommitted
Implement --kube-context flag support for all helm-diff commands
Co-authored-by: yxxhero <11087727+yxxhero@users.noreply.github.com>
1 parent 0d43d95 commit b542ea9

6 files changed

Lines changed: 131 additions & 17 deletions

File tree

cmd/helm3.go

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,38 +65,50 @@ func compatibleHelm3Version() error {
6565
return nil
6666
}
6767

68-
func getRelease(release, namespace string) ([]byte, error) {
68+
func getRelease(release, namespace, kubeContext string) ([]byte, error) {
6969
args := []string{"get", "manifest", release}
7070
if namespace != "" {
7171
args = append(args, "--namespace", namespace)
7272
}
73+
if kubeContext != "" {
74+
args = append(args, "--kube-context", kubeContext)
75+
}
7376
cmd := exec.Command(os.Getenv("HELM_BIN"), args...)
7477
return outputWithRichError(cmd)
7578
}
7679

77-
func getHooks(release, namespace string) ([]byte, error) {
80+
func getHooks(release, namespace, kubeContext string) ([]byte, error) {
7881
args := []string{"get", "hooks", release}
7982
if namespace != "" {
8083
args = append(args, "--namespace", namespace)
8184
}
85+
if kubeContext != "" {
86+
args = append(args, "--kube-context", kubeContext)
87+
}
8288
cmd := exec.Command(os.Getenv("HELM_BIN"), args...)
8389
return outputWithRichError(cmd)
8490
}
8591

86-
func getRevision(release string, revision int, namespace string) ([]byte, error) {
92+
func getRevision(release string, revision int, namespace, kubeContext string) ([]byte, error) {
8793
args := []string{"get", "manifest", release, "--revision", strconv.Itoa(revision)}
8894
if namespace != "" {
8995
args = append(args, "--namespace", namespace)
9096
}
97+
if kubeContext != "" {
98+
args = append(args, "--kube-context", kubeContext)
99+
}
91100
cmd := exec.Command(os.Getenv("HELM_BIN"), args...)
92101
return outputWithRichError(cmd)
93102
}
94103

95-
func getChart(release, namespace string) (string, error) {
104+
func getChart(release, namespace, kubeContext string) (string, error) {
96105
args := []string{"get", "all", release, "--template", "{{.Release.Chart.Name}}"}
97106
if namespace != "" {
98107
args = append(args, "--namespace", namespace)
99108
}
109+
if kubeContext != "" {
110+
args = append(args, "--kube-context", kubeContext)
111+
}
100112
cmd := exec.Command(os.Getenv("HELM_BIN"), args...)
101113
out, err := outputWithRichError(cmd)
102114
if err != nil {
@@ -125,6 +137,9 @@ func (d *diffCmd) template(isUpgrade bool) ([]byte, error) {
125137
if d.namespace != "" {
126138
flags = append(flags, "--namespace", d.namespace)
127139
}
140+
if d.kubeContext != "" {
141+
flags = append(flags, "--kube-context", d.kubeContext)
142+
}
128143
if d.postRenderer != "" {
129144
flags = append(flags, "--post-renderer", d.postRenderer)
130145
}
@@ -341,6 +356,12 @@ func (d *diffCmd) writeExistingValues(f *os.File, all bool) error {
341356
if all {
342357
args = append(args, "--all")
343358
}
359+
if d.namespace != "" {
360+
args = append(args, "--namespace", d.namespace)
361+
}
362+
if d.kubeContext != "" {
363+
args = append(args, "--kube-context", d.kubeContext)
364+
}
344365
cmd := exec.Command(os.Getenv("HELM_BIN"), args...)
345366
debugPrint("Executing %s", strings.Join(cmd.Args, " "))
346367
defer func() {

cmd/kube_context_test.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+
"testing"
5+
)
6+
7+
func TestKubeContextFlag(t *testing.T) {
8+
tests := []struct {
9+
name string
10+
kubeContext string
11+
expected bool
12+
}{
13+
{
14+
name: "with kube-context",
15+
kubeContext: "test-context",
16+
expected: true,
17+
},
18+
{
19+
name: "without kube-context",
20+
kubeContext: "",
21+
expected: false,
22+
},
23+
}
24+
25+
for _, tt := range tests {
26+
t.Run(tt.name, func(t *testing.T) {
27+
// Test diffCmd struct
28+
d := &diffCmd{
29+
kubeContext: tt.kubeContext,
30+
namespace: "test-namespace",
31+
}
32+
33+
// Verify the field is set correctly
34+
if (d.kubeContext != "") != tt.expected {
35+
t.Errorf("kubeContext field: expected %v, got %v", tt.expected, d.kubeContext != "")
36+
}
37+
38+
// Test release struct
39+
r := &release{
40+
kubeContext: tt.kubeContext,
41+
}
42+
43+
if (r.kubeContext != "") != tt.expected {
44+
t.Errorf("release kubeContext field: expected %v, got %v", tt.expected, r.kubeContext != "")
45+
}
46+
47+
// Test revision struct
48+
rev := &revision{
49+
kubeContext: tt.kubeContext,
50+
}
51+
52+
if (rev.kubeContext != "") != tt.expected {
53+
t.Errorf("revision kubeContext field: expected %v, got %v", tt.expected, rev.kubeContext != "")
54+
}
55+
56+
// Test rollback struct
57+
rb := &rollback{
58+
kubeContext: tt.kubeContext,
59+
}
60+
61+
if (rb.kubeContext != "") != tt.expected {
62+
t.Errorf("rollback kubeContext field: expected %v, got %v", tt.expected, rb.kubeContext != "")
63+
}
64+
})
65+
}
66+
}
67+
68+
func TestKubeContextInDiffCmd(t *testing.T) {
69+
// Test that the diffCmd has the kubeContext field in the struct
70+
d := diffCmd{
71+
kubeContext: "test-context",
72+
namespace: "test-namespace",
73+
release: "test-release",
74+
chart: "test-chart",
75+
}
76+
77+
if d.kubeContext != "test-context" {
78+
t.Errorf("Expected kubeContext to be 'test-context', got '%s'", d.kubeContext)
79+
}
80+
81+
// Test that the field can be set to empty
82+
d.kubeContext = ""
83+
if d.kubeContext != "" {
84+
t.Errorf("Expected kubeContext to be empty, got '%s'", d.kubeContext)
85+
}
86+
}

cmd/release.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type release struct {
1717
releases []string
1818
includeTests bool
1919
normalizeManifests bool
20+
kubeContext string
2021
diff.Options
2122
}
2223

@@ -63,6 +64,7 @@ func releaseCmd() *cobra.Command {
6364
releaseCmd.Flags().BoolVar(&diff.detailedExitCode, "detailed-exitcode", false, "return a non-zero exit code when there are changes")
6465
releaseCmd.Flags().BoolVar(&diff.includeTests, "include-tests", false, "enable the diffing of the helm test hooks")
6566
releaseCmd.Flags().BoolVar(&diff.normalizeManifests, "normalize-manifests", false, "normalize manifests before running diff to exclude style differences from the output")
67+
releaseCmd.Flags().StringVar(&diff.kubeContext, "kube-context", "", "name of the kubeconfig context to use")
6668
AddDiffOptions(releaseCmd.Flags(), &diff.Options)
6769

6870
releaseCmd.SuggestionsMinimumDistance = 1
@@ -82,11 +84,11 @@ func (d *release) differentiateHelm3() error {
8284
namespace1 = strings.Split(release1, "/")[0]
8385
release1 = strings.Split(release1, "/")[1]
8486
}
85-
releaseResponse1, err := getRelease(release1, namespace1)
87+
releaseResponse1, err := getRelease(release1, namespace1, d.kubeContext)
8688
if err != nil {
8789
return err
8890
}
89-
releaseChart1, err := getChart(release1, namespace1)
91+
releaseChart1, err := getChart(release1, namespace1, d.kubeContext)
9092
if err != nil {
9193
return err
9294
}
@@ -97,11 +99,11 @@ func (d *release) differentiateHelm3() error {
9799
namespace2 = strings.Split(release2, "/")[0]
98100
release2 = strings.Split(release2, "/")[1]
99101
}
100-
releaseResponse2, err := getRelease(release2, namespace2)
102+
releaseResponse2, err := getRelease(release2, namespace2, d.kubeContext)
101103
if err != nil {
102104
return err
103105
}
104-
releaseChart2, err := getChart(release2, namespace2)
106+
releaseChart2, err := getChart(release2, namespace2, d.kubeContext)
105107
if err != nil {
106108
return err
107109
}

cmd/revision.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ type revision struct {
1818
revisions []string
1919
includeTests bool
2020
normalizeManifests bool
21+
kubeContext string
2122
diff.Options
2223
}
2324

@@ -70,6 +71,7 @@ func revisionCmd() *cobra.Command {
7071
revisionCmd.Flags().BoolVar(&diff.detailedExitCode, "detailed-exitcode", false, "return a non-zero exit code when there are changes")
7172
revisionCmd.Flags().BoolVar(&diff.includeTests, "include-tests", false, "enable the diffing of the helm test hooks")
7273
revisionCmd.Flags().BoolVar(&diff.normalizeManifests, "normalize-manifests", false, "normalize manifests before running diff to exclude style differences from the output")
74+
revisionCmd.Flags().StringVar(&diff.kubeContext, "kube-context", "", "name of the kubeconfig context to use")
7375
AddDiffOptions(revisionCmd.Flags(), &diff.Options)
7476

7577
revisionCmd.SuggestionsMinimumDistance = 1
@@ -85,14 +87,14 @@ func (d *revision) differentiateHelm3() error {
8587
}
8688
switch len(d.revisions) {
8789
case 1:
88-
releaseResponse, err := getRelease(d.release, namespace)
90+
releaseResponse, err := getRelease(d.release, namespace, d.kubeContext)
8991

9092
if err != nil {
9193
return err
9294
}
9395

9496
revision, _ := strconv.Atoi(d.revisions[0])
95-
revisionResponse, err := getRevision(d.release, revision, namespace)
97+
revisionResponse, err := getRevision(d.release, revision, namespace, d.kubeContext)
9698
if err != nil {
9799
return err
98100
}
@@ -110,12 +112,12 @@ func (d *revision) differentiateHelm3() error {
110112
revision1, revision2 = revision2, revision1
111113
}
112114

113-
revisionResponse1, err := getRevision(d.release, revision1, namespace)
115+
revisionResponse1, err := getRevision(d.release, revision1, namespace, d.kubeContext)
114116
if err != nil {
115117
return err
116118
}
117119

118-
revisionResponse2, err := getRevision(d.release, revision2, namespace)
120+
revisionResponse2, err := getRevision(d.release, revision2, namespace, d.kubeContext)
119121
if err != nil {
120122
return err
121123
}

cmd/rollback.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ type rollback struct {
1818
revisions []string
1919
includeTests bool
2020
normalizeManifests bool
21+
kubeContext string
2122
diff.Options
2223
}
2324

@@ -60,6 +61,7 @@ func rollbackCmd() *cobra.Command {
6061
rollbackCmd.Flags().BoolVar(&diff.detailedExitCode, "detailed-exitcode", false, "return a non-zero exit code when there are changes")
6162
rollbackCmd.Flags().BoolVar(&diff.includeTests, "include-tests", false, "enable the diffing of the helm test hooks")
6263
rollbackCmd.Flags().BoolVar(&diff.normalizeManifests, "normalize-manifests", false, "normalize manifests before running diff to exclude style differences from the output")
64+
rollbackCmd.Flags().StringVar(&diff.kubeContext, "kube-context", "", "name of the kubeconfig context to use")
6365
AddDiffOptions(rollbackCmd.Flags(), &diff.Options)
6466

6567
rollbackCmd.SuggestionsMinimumDistance = 1
@@ -74,15 +76,15 @@ func (d *rollback) backcastHelm3() error {
7476
excludes = []string{}
7577
}
7678
// get manifest of the latest release
77-
releaseResponse, err := getRelease(d.release, namespace)
79+
releaseResponse, err := getRelease(d.release, namespace, d.kubeContext)
7880

7981
if err != nil {
8082
return err
8183
}
8284

8385
// get manifest of the release to rollback
8486
revision, _ := strconv.Atoi(d.revisions[0])
85-
revisionResponse, err := getRevision(d.release, revision, namespace)
87+
revisionResponse, err := getRevision(d.release, revision, namespace, d.kubeContext)
8688
if err != nil {
8789
return err
8890
}

cmd/upgrade.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ type diffCmd struct {
4141
enableDNS bool
4242
SkipSchemaValidation bool
4343
namespace string // namespace to assume the release to be installed into. Defaults to the current kube config namespace.
44+
kubeContext string // name of the kubeconfig context to use
4445
valueFiles valueFiles
4546
values []string
4647
stringValues []string
@@ -211,7 +212,7 @@ func newChartCommand() *cobra.Command {
211212
var kubeconfig string
212213
f.StringVar(&kubeconfig, "kubeconfig", "", "This flag is ignored, to allow passing of this top level flag to helm")
213214
f.BoolVar(&diff.threeWayMerge, "three-way-merge", false, "use three-way-merge to compute patch and generate diff output")
214-
// f.StringVar(&diff.kubeContext, "kube-context", "", "name of the kubeconfig context to use")
215+
f.StringVar(&diff.kubeContext, "kube-context", "", "name of the kubeconfig context to use")
215216
f.StringVar(&diff.chartVersion, "version", "", "specify the exact chart version to use. If this is not specified, the latest version is used")
216217
f.StringVar(&diff.chartRepo, "repo", "", "specify the chart repository url to locate the requested chart")
217218
f.BoolVar(&diff.detailedExitCode, "detailed-exitcode", false, "return a non-zero exit code when there are changes")
@@ -270,7 +271,7 @@ func (d *diffCmd) runHelm3() error {
270271
}
271272

272273
if d.clusterAccessAllowed() {
273-
releaseManifest, err = getRelease(d.release, d.namespace)
274+
releaseManifest, err = getRelease(d.release, d.namespace, d.kubeContext)
274275
}
275276

276277
var newInstall bool
@@ -313,7 +314,7 @@ func (d *diffCmd) runHelm3() error {
313314
currentSpecs := make(map[string]*manifest.MappingResult)
314315
if !newInstall && d.clusterAccessAllowed() {
315316
if !d.noHooks && !d.threeWayMerge {
316-
hooks, err := getHooks(d.release, d.namespace)
317+
hooks, err := getHooks(d.release, d.namespace, d.kubeContext)
317318
if err != nil {
318319
return err
319320
}

0 commit comments

Comments
 (0)