Skip to content

Commit 420855d

Browse files
authored
fix(helm): ensure coder can be deployed in a non-default namespace (#16579)
Added namespace to all resources in the helm chart and added tests to ensure that coder can be deployed in non-default namespaces, as specified via the namespace flag in the helm command. Ways to verify this: - current state: ```bash $ helm template my-coder coder -n coder --version 2.19.0 --repo https://helm.coder.com/v2 | yq '.metadata.namespace' null --- null --- null --- null --- null ``` - fixed state when checking out this PR: ```bash $ helm template my-coder ./helm/coder -n coder --set coder.image.tag=latest | yq '.metadata.namespace' coder --- coder --- coder --- coder --- coder ``` Change-Id: Ib66d4be9bcc4984dfe15709362e1fe0dcd3e847f Signed-off-by: Thomas Kosiewski <tk@coder.com>
1 parent a777c26 commit 420855d

File tree

73 files changed

+6040
-114
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+6040
-114
lines changed

helm/coder/templates/ingress.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
21
{{- if .Values.coder.ingress.enable }}
32
---
43
apiVersion: networking.k8s.io/v1
54
kind: Ingress
65
metadata:
76
name: coder
7+
namespace: {{ .Release.Namespace }}
88
labels:
99
{{- include "coder.labels" . | nindent 4 }}
1010
annotations:

helm/coder/templates/service.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ apiVersion: v1
44
kind: Service
55
metadata:
66
name: coder
7+
namespace: {{ .Release.Namespace }}
78
labels:
89
{{- include "coder.labels" . | nindent 4 }}
910
annotations:

helm/coder/tests/chart_test.go

Lines changed: 62 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ import (
2323
// updateGoldenFiles is a flag that can be set to update golden files.
2424
var updateGoldenFiles = flag.Bool("update", false, "Update golden files")
2525

26+
var namespaces = []string{
27+
"default",
28+
"coder",
29+
}
30+
2631
var testCases = []testCase{
2732
{
2833
name: "default_values",
@@ -116,6 +121,7 @@ var testCases = []testCase{
116121

117122
type testCase struct {
118123
name string // Name of the test case. This is used to control which values and golden file are used.
124+
namespace string // Namespace is the name of the namespace the resources should be generated within
119125
expectedError string // Expected error from running `helm template`.
120126
}
121127

@@ -124,7 +130,11 @@ func (tc testCase) valuesFilePath() string {
124130
}
125131

126132
func (tc testCase) goldenFilePath() string {
127-
return filepath.Join("./testdata", tc.name+".golden")
133+
if tc.namespace == "default" {
134+
return filepath.Join("./testdata", tc.name+".golden")
135+
}
136+
137+
return filepath.Join("./testdata", tc.name+"_"+tc.namespace+".golden")
128138
}
129139

130140
func TestRenderChart(t *testing.T) {
@@ -146,35 +156,41 @@ func TestRenderChart(t *testing.T) {
146156

147157
for _, tc := range testCases {
148158
tc := tc
149-
t.Run(tc.name, func(t *testing.T) {
150-
t.Parallel()
151159

152-
// Ensure that the values file exists.
153-
valuesFilePath := tc.valuesFilePath()
154-
if _, err := os.Stat(valuesFilePath); os.IsNotExist(err) {
155-
t.Fatalf("values file %q does not exist", valuesFilePath)
156-
}
160+
for _, ns := range namespaces {
161+
tc := tc
162+
tc.namespace = ns
157163

158-
// Run helm template with the values file.
159-
templateOutput, err := runHelmTemplate(t, helmPath, "..", valuesFilePath)
160-
if tc.expectedError != "" {
161-
require.Error(t, err, "helm template should have failed")
162-
require.Contains(t, templateOutput, tc.expectedError, "helm template output should contain expected error")
163-
} else {
164-
require.NoError(t, err, "helm template should not have failed")
165-
require.NotEmpty(t, templateOutput, "helm template output should not be empty")
166-
goldenFilePath := tc.goldenFilePath()
167-
goldenBytes, err := os.ReadFile(goldenFilePath)
168-
require.NoError(t, err, "failed to read golden file %q", goldenFilePath)
169-
170-
// Remove carriage returns to make tests pass on Windows.
171-
goldenBytes = bytes.Replace(goldenBytes, []byte("\r"), []byte(""), -1)
172-
expected := string(goldenBytes)
173-
174-
require.NoError(t, err, "failed to load golden file %q")
175-
require.Equal(t, expected, templateOutput)
176-
}
177-
})
164+
t.Run(tc.namespace+"/"+tc.name, func(t *testing.T) {
165+
t.Parallel()
166+
167+
// Ensure that the values file exists.
168+
valuesFilePath := tc.valuesFilePath()
169+
if _, err := os.Stat(valuesFilePath); os.IsNotExist(err) {
170+
t.Fatalf("values file %q does not exist", valuesFilePath)
171+
}
172+
173+
// Run helm template with the values file.
174+
templateOutput, err := runHelmTemplate(t, helmPath, "..", valuesFilePath, tc.namespace)
175+
if tc.expectedError != "" {
176+
require.Error(t, err, "helm template should have failed")
177+
require.Contains(t, templateOutput, tc.expectedError, "helm template output should contain expected error")
178+
} else {
179+
require.NoError(t, err, "helm template should not have failed")
180+
require.NotEmpty(t, templateOutput, "helm template output should not be empty")
181+
goldenFilePath := tc.goldenFilePath()
182+
goldenBytes, err := os.ReadFile(goldenFilePath)
183+
require.NoError(t, err, "failed to read golden file %q", goldenFilePath)
184+
185+
// Remove carriage returns to make tests pass on Windows.
186+
goldenBytes = bytes.ReplaceAll(goldenBytes, []byte("\r"), []byte(""))
187+
expected := string(goldenBytes)
188+
189+
require.NoError(t, err, "failed to load golden file %q")
190+
require.Equal(t, expected, templateOutput)
191+
}
192+
})
193+
}
178194
}
179195
}
180196

@@ -189,22 +205,28 @@ func TestUpdateGoldenFiles(t *testing.T) {
189205
require.NoError(t, err, "failed to build Helm dependencies")
190206

191207
for _, tc := range testCases {
208+
tc := tc
192209
if tc.expectedError != "" {
193210
t.Logf("skipping test case %q with render error", tc.name)
194211
continue
195212
}
196213

197-
valuesPath := tc.valuesFilePath()
198-
templateOutput, err := runHelmTemplate(t, helmPath, "..", valuesPath)
199-
if err != nil {
200-
t.Logf("error running `helm template -f %q`: %v", valuesPath, err)
201-
t.Logf("output: %s", templateOutput)
202-
}
203-
require.NoError(t, err, "failed to run `helm template -f %q`", valuesPath)
214+
for _, ns := range namespaces {
215+
tc := tc
216+
tc.namespace = ns
217+
218+
valuesPath := tc.valuesFilePath()
219+
templateOutput, err := runHelmTemplate(t, helmPath, "..", valuesPath, tc.namespace)
220+
if err != nil {
221+
t.Logf("error running `helm template -f %q`: %v", valuesPath, err)
222+
t.Logf("output: %s", templateOutput)
223+
}
224+
require.NoError(t, err, "failed to run `helm template -f %q`", valuesPath)
204225

205-
goldenFilePath := tc.goldenFilePath()
206-
err = os.WriteFile(goldenFilePath, []byte(templateOutput), 0o644) // nolint:gosec
207-
require.NoError(t, err, "failed to write golden file %q", goldenFilePath)
226+
goldenFilePath := tc.goldenFilePath()
227+
err = os.WriteFile(goldenFilePath, []byte(templateOutput), 0o644) // nolint:gosec
228+
require.NoError(t, err, "failed to write golden file %q", goldenFilePath)
229+
}
208230
}
209231
t.Log("Golden files updated. Please review the changes and commit them.")
210232
}
@@ -231,13 +253,13 @@ func updateHelmDependencies(t testing.TB, helmPath, chartDir string) error {
231253

232254
// runHelmTemplate runs helm template on the given chart with the given values and
233255
// returns the raw output.
234-
func runHelmTemplate(t testing.TB, helmPath, chartDir, valuesFilePath string) (string, error) {
256+
func runHelmTemplate(t testing.TB, helmPath, chartDir, valuesFilePath, namespace string) (string, error) {
235257
// Ensure that valuesFilePath exists
236258
if _, err := os.Stat(valuesFilePath); err != nil {
237259
return "", xerrors.Errorf("values file %q does not exist: %w", valuesFilePath, err)
238260
}
239261

240-
cmd := exec.Command(helmPath, "template", chartDir, "-f", valuesFilePath, "--namespace", "default")
262+
cmd := exec.Command(helmPath, "template", chartDir, "-f", valuesFilePath, "--namespace", namespace)
241263
t.Logf("exec command: %v", cmd.Args)
242264
out, err := cmd.CombinedOutput()
243265
return string(out), err

helm/coder/tests/testdata/auto_access_url_1.golden

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@ metadata:
1212
app.kubernetes.io/version: 0.1.0
1313
helm.sh/chart: coder-0.1.0
1414
name: coder
15+
namespace: default
1516
---
1617
# Source: coder/templates/rbac.yaml
1718
apiVersion: rbac.authorization.k8s.io/v1
1819
kind: Role
1920
metadata:
2021
name: coder-workspace-perms
22+
namespace: default
2123
rules:
2224
- apiGroups: [""]
2325
resources: ["pods"]
@@ -60,6 +62,7 @@ apiVersion: rbac.authorization.k8s.io/v1
6062
kind: RoleBinding
6163
metadata:
6264
name: "coder"
65+
namespace: default
6366
subjects:
6467
- kind: ServiceAccount
6568
name: "coder"
@@ -73,6 +76,7 @@ apiVersion: v1
7376
kind: Service
7477
metadata:
7578
name: coder
79+
namespace: default
7680
labels:
7781
helm.sh/chart: coder-0.1.0
7882
app.kubernetes.io/name: coder
@@ -109,6 +113,7 @@ metadata:
109113
app.kubernetes.io/version: 0.1.0
110114
helm.sh/chart: coder-0.1.0
111115
name: coder
116+
namespace: default
112117
spec:
113118
replicas: 1
114119
selector:

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy