Skip to content

Commit c460f0d

Browse files
committed
Helm chart: print how to open Radar after install and upgrade
Add templates/NOTES.txt. It prints the ingress URLs or HTTPRoute hostnames when Radar is exposed that way, and otherwise the README's port-forward command, which works for every Service type. All of them follow the release namespace, fullname, service port and basePath. The wording comes from the Radar docs and the ingress/HTTPRoute commands from Helm's `helm create` NOTES.txt scaffold. OIDC and proxy installs get the documented sign-in line and a link to the authentication docs, installs exposed beyond ClusterIP without auth get the documented warning, and Cloud installs get the log check. The notes never print a value that can hold a credential. basePath normalisation moves into a radar.basePath helper shared by the Deployment and NOTES; rendered manifests are unchanged.
1 parent 86ae0f5 commit c460f0d

5 files changed

Lines changed: 365 additions & 5 deletions

File tree

‎deploy/helm/radar/README.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ kubectl port-forward svc/radar 9280:9280 -n radar
2727
open http://localhost:9280
2828
```
2929

30+
Each install or upgrade prints how to open Radar for the values you set. To see
31+
it again, run `helm get notes radar -n radar`.
32+
3033
### With Ingress
3134

3235
```bash
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
{{- /* Every sentence here is taken from the Radar docs (docs/*.md, radarhq.io/docs)
2+
and the ingress/HTTPRoute commands from Helm's `helm create` NOTES.txt
3+
scaffold. Keep it that way: don't add claims the docs don't make.
4+
Never print a value that can hold a credential. cloud.url is named, not
5+
printed, because a URL can carry userinfo or a token in its query. */ -}}
6+
{{- $fullName := include "radar.fullname" . -}}
7+
{{- $ns := .Release.Namespace -}}
8+
{{- $port := .Values.service.port -}}
9+
{{- $basePath := include "radar.basePath" . -}}
10+
{{- $authDocs := "https://radarhq.io/docs/configuration/authentication" -}}
11+
{{- $mode := .Values.auth.mode -}}
12+
{{- $routed := or .Values.ingress.enabled .Values.httpRoute.enabled -}}
13+
{{- $proxyAuth := printf "Authentication: proxy (auth.mode=proxy). Users authenticate through the proxy,\nwhich forwards their identity to Radar via HTTP headers. The auth proxy should\nbe the only path to Radar.\nSetup: %s" $authDocs -}}
14+
{{- if .Values.cloud.enabled }}
15+
The Radar pod dials the Radar Cloud endpoint (cloud.url) over an outbound WebSocket.
16+
Once connected, the Radar Cloud install page redirects you into the cluster view.
17+
The pod's own listener serves only /api/health; Radar is served over the Cloud tunnel.
18+
19+
If the install page times out, check the Radar pod logs:
20+
21+
kubectl logs -n {{ $ns }} deploy/{{ $fullName }}
22+
{{- else if and (eq $mode "proxy") (not $routed) }}
23+
{{- /* No Service address or port-forward: the docs say the auth proxy should
24+
be the only path to Radar. */}}
25+
{{ $proxyAuth }}
26+
{{- else }}
27+
{{- if .Values.ingress.enabled }}
28+
{{- $urls := list }}
29+
{{- range $h := .Values.ingress.hosts }}
30+
{{- range $h.paths }}
31+
{{- $path := ternary (printf "%s/" $basePath) .path (ne $basePath "") }}
32+
{{- $urls = append $urls (printf "http%s://%s%s" (ternary "s" "" (not (empty $.Values.ingress.tls))) ($h.host | default "") $path) }}
33+
{{- end }}
34+
{{- end }}
35+
Open Radar at:
36+
{{- range uniq $urls }}
37+
{{ . }}
38+
{{- end }}
39+
{{- else if .Values.httpRoute.enabled }}
40+
{{- $gw := first .Values.httpRoute.parentRefs }}
41+
{{- $gwNs := $gw.namespace | default $ns }}
42+
{{- if .Values.httpRoute.hostnames }}
43+
Radar's HTTPRoute hostnames:
44+
{{- range .Values.httpRoute.hostnames }}
45+
{{ . }}{{ $basePath }}/
46+
{{- end }}
47+
{{- else }}
48+
Get the Gateway listener hostname:
49+
50+
export APP_HOSTNAME=$(kubectl get --namespace {{ $gwNs }} gateway/{{ $gw.name }} -o jsonpath="{.spec.listeners[0].hostname}")
51+
{{- end }}
52+
53+
Your HTTPRoute depends on the listener configuration of your gateway.
54+
You can check the gateway configuration with:
55+
56+
kubectl get --namespace {{ $gwNs }} gateway/{{ $gw.name }} -o yaml
57+
{{- else }}
58+
Access via port-forward:
59+
60+
kubectl port-forward svc/{{ $fullName }} 9280:{{ $port }} -n {{ $ns }}
61+
open http://localhost:9280{{ $basePath }}{{ if $basePath }}/{{ end }}
62+
{{- end }}
63+
{{- if eq $mode "oidc" }}
64+
65+
Authentication: OIDC (auth.mode=oidc). Radar redirects to your identity
66+
provider, validates the token, and creates a session cookie.
67+
Setup: {{ $authDocs }}
68+
{{- else if eq $mode "proxy" }}
69+
70+
{{ $proxyAuth }}
71+
{{- else if or $routed (ne .Values.service.type "ClusterIP") }}
72+
73+
Warning: no auth (auth.mode=none). Only use this behind a trusted private
74+
network boundary. Anyone who can reach Radar can use the permissions granted to
75+
its ServiceAccount. For shared or externally reachable installations, configure
76+
authentication: {{ $authDocs }}
77+
{{- end }}
78+
{{- end }}

‎deploy/helm/radar/templates/_helpers.tpl‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,18 @@ Create the name of the service account to use
6161
{{- end }}
6262
{{- end }}
6363

64+
{{/*
65+
The URL path prefix Radar serves under: "" for root, otherwise "/<prefix>"
66+
with no trailing slash. Shared by the Deployment (--base-path, probes) and
67+
NOTES.txt (the URL printed after install).
68+
*/}}
69+
{{- define "radar.basePath" -}}
70+
{{- $trimmed := trimAll "/" (default "" .Values.basePath) -}}
71+
{{- if $trimmed -}}
72+
{{- printf "/%s" $trimmed -}}
73+
{{- end -}}
74+
{{- end }}
75+
6476
{{- define "radar.operatorSettings" -}}
6577
{{- $settings := dict "version" 1 -}}
6678
{{- if .Values.audit -}}

‎deploy/helm/radar/templates/deployment.yaml‎

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,7 @@
44
{{- if and (eq .Values.timeline.storage "postgres") (not .Values.timeline.postgres.existingSecret) }}
55
{{- fail "timeline.postgres.existingSecret is required when timeline.storage=postgres" }}
66
{{- end }}
7-
{{- $basePath := "" -}}
8-
{{- $trimmedBasePath := trimAll "/" (default "" .Values.basePath) -}}
9-
{{- if $trimmedBasePath -}}
10-
{{- $basePath = printf "/%s" $trimmedBasePath -}}
11-
{{- end -}}
7+
{{- $basePath := include "radar.basePath" . -}}
128
{{- if and $basePath .Values.cloud.enabled }}
139
{{- fail "basePath is not supported with cloud.enabled=true: Radar Cloud owns the URL path, and the binary refuses the combination at startup — unset one of them" }}
1410
{{- end }}
Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
suite: NOTES
2+
templates:
3+
- NOTES.txt
4+
release:
5+
name: radar
6+
namespace: radar
7+
tests:
8+
- it: ClusterIP (default) prints the documented port-forward
9+
asserts:
10+
- equalRaw:
11+
value: |
12+
Access via port-forward:
13+
14+
kubectl port-forward svc/radar 9280:9280 -n radar
15+
open http://localhost:9280
16+
17+
- it: ClusterIP follows release namespace, fullname, service port and basePath
18+
release:
19+
name: tools
20+
namespace: platform
21+
set:
22+
service:
23+
port: 8080
24+
basePath: /radar/
25+
asserts:
26+
- matchRegexRaw:
27+
pattern: kubectl port-forward svc/tools-radar 9280:8080 -n platform\n
28+
- matchRegexRaw:
29+
pattern: open http://localhost:9280/radar/\n?$
30+
- notMatchRegexRaw:
31+
pattern: Warning
32+
33+
- it: NodePort and LoadBalancer get the port-forward plus the no-auth warning
34+
set:
35+
service:
36+
type: LoadBalancer
37+
asserts:
38+
- matchRegexRaw:
39+
pattern: "^Access via port-forward:\n\n kubectl port-forward svc/radar 9280:9280 -n radar\n open http://localhost:9280\n\nWarning: no auth"
40+
- notMatchRegexRaw:
41+
pattern: (SERVICE_IP|NODE_PORT)
42+
43+
- it: NodePort gets the same port-forward
44+
set:
45+
service:
46+
type: NodePort
47+
asserts:
48+
- matchRegexRaw:
49+
pattern: kubectl port-forward svc/radar 9280:9280 -n radar
50+
- matchRegexRaw:
51+
pattern: "Warning: no auth"
52+
53+
- it: Ingress prints each host, https when ingress.tls is set
54+
set:
55+
ingress:
56+
enabled: true
57+
hosts:
58+
- host: radar.example.com
59+
paths:
60+
- path: /
61+
pathType: Prefix
62+
- host: radar.example.org
63+
paths:
64+
- path: /
65+
pathType: Prefix
66+
tls:
67+
- secretName: radar-tls
68+
hosts:
69+
- radar.example.com
70+
asserts:
71+
- matchRegexRaw:
72+
pattern: "Open Radar at:\n https://radar.example.com/\n https://radar.example.org/\n"
73+
- matchRegexRaw:
74+
pattern: "Warning: no auth"
75+
- notMatchRegexRaw:
76+
pattern: port-forward
77+
78+
- it: Ingress without TLS prints http
79+
set:
80+
ingress:
81+
enabled: true
82+
asserts:
83+
- matchRegexRaw:
84+
pattern: "Open Radar at:\n http://radar.example.com/\n"
85+
86+
- it: Ingress uses basePath instead of the ingress path and drops duplicates
87+
set:
88+
basePath: /radar
89+
ingress:
90+
enabled: true
91+
hosts:
92+
- host: tools.example.com
93+
paths:
94+
- path: /radar
95+
pathType: Prefix
96+
- path: /radar/
97+
pathType: Prefix
98+
asserts:
99+
- matchRegexRaw:
100+
pattern: "Open Radar at:\n http://tools.example.com/radar/\n\n"
101+
102+
- it: HTTPRoute prints its hostnames without a scheme and points at the Gateway
103+
set:
104+
httpRoute:
105+
enabled: true
106+
parentRefs:
107+
- name: public-gateway
108+
namespace: gateway-system
109+
hostnames:
110+
- radar.example.com
111+
- radar.example.org
112+
asserts:
113+
- matchRegexRaw:
114+
pattern: "Radar's HTTPRoute hostnames:\n radar.example.com/\n radar.example.org/\n"
115+
- notMatchRegexRaw:
116+
pattern: https?://radar\.example
117+
- matchRegexRaw:
118+
pattern: Your HTTPRoute depends on the listener configuration of your gateway
119+
- matchRegexRaw:
120+
pattern: kubectl get --namespace gateway-system gateway/public-gateway -o yaml
121+
- matchRegexRaw:
122+
pattern: "Warning: no auth"
123+
124+
- it: HTTPRoute without hostnames prints the Gateway listener hostname command
125+
set:
126+
httpRoute:
127+
enabled: true
128+
parentRefs:
129+
- name: public-gateway
130+
asserts:
131+
- matchRegexRaw:
132+
pattern: export APP_HOSTNAME=\$\(kubectl get --namespace radar gateway/public-gateway -o jsonpath="\{\.spec\.listeners\[0\]\.hostname\}"\)
133+
- matchRegexRaw:
134+
pattern: kubectl get --namespace radar gateway/public-gateway -o yaml
135+
136+
- it: OIDC adds the documented sign-in line and the auth docs link
137+
set:
138+
auth:
139+
mode: oidc
140+
oidc:
141+
issuerURL: https://idp.example.com
142+
clientID: radar
143+
redirectURL: https://radar.example.com/auth/callback
144+
asserts:
145+
- matchRegexRaw:
146+
pattern: Access via port-forward
147+
- matchRegexRaw:
148+
pattern: "Authentication: OIDC \\(auth.mode=oidc\\). Radar redirects to your identity\nprovider, validates the token, and creates a session cookie.\nSetup: https://radarhq.io/docs/configuration/authentication"
149+
- notMatchRegexRaw:
150+
pattern: Warning
151+
152+
- it: proxy auth without an ingress or route prints only the proxy note
153+
set:
154+
auth:
155+
mode: proxy
156+
asserts:
157+
- equalRaw:
158+
value: |
159+
Authentication: proxy (auth.mode=proxy). Users authenticate through the proxy,
160+
which forwards their identity to Radar via HTTP headers. The auth proxy should
161+
be the only path to Radar.
162+
Setup: https://radarhq.io/docs/configuration/authentication
163+
164+
- it: proxy auth on a LoadBalancer Service does not print a port-forward
165+
set:
166+
auth:
167+
mode: proxy
168+
service:
169+
type: LoadBalancer
170+
asserts:
171+
- notMatchRegexRaw:
172+
pattern: port-forward
173+
- matchRegexRaw:
174+
pattern: The auth proxy should\nbe the only path to Radar
175+
176+
- it: proxy auth behind an Ingress prints the URL and the proxy note
177+
set:
178+
auth:
179+
mode: proxy
180+
ingress:
181+
enabled: true
182+
asserts:
183+
- matchRegexRaw:
184+
pattern: "Open Radar at:\n http://radar.example.com/\n\nAuthentication: proxy"
185+
- notMatchRegexRaw:
186+
pattern: Warning
187+
188+
- it: Radar Cloud prints the tunnel endpoint and the log command only
189+
set:
190+
cloud:
191+
enabled: true
192+
url: wss://cloud.example/agent
193+
clusterName: prod-eu
194+
existingSecret: radar-cloud-config
195+
ingress:
196+
enabled: true
197+
asserts:
198+
- matchRegexRaw:
199+
pattern: The Radar pod dials the Radar Cloud endpoint \(cloud.url\) over an outbound WebSocket
200+
- notMatchRegexRaw:
201+
pattern: cloud\.example
202+
- matchRegexRaw:
203+
pattern: kubectl logs -n radar deploy/radar
204+
- notMatchRegexRaw:
205+
pattern: (port-forward svc|Open Radar at|Warning)
206+
207+
# Credentials set everywhere a value can hold one. The marker must never
208+
# reach the notes, in any mode.
209+
- it: never prints credentials (ClusterIP)
210+
set: &credentials
211+
auth:
212+
secret: SHOULD-NOT-APPEAR
213+
oidc:
214+
clientSecret: SHOULD-NOT-APPEAR
215+
cloud:
216+
token: SHOULD-NOT-APPEAR
217+
argocd:
218+
token: SHOULD-NOT-APPEAR
219+
traffic:
220+
prometheusUrl: https://user:SHOULD-NOT-APPEAR@prometheus.example
221+
prometheusHeaders:
222+
Authorization: Bearer SHOULD-NOT-APPEAR
223+
asserts: &noCredentials
224+
- notMatchRegexRaw:
225+
pattern: SHOULD-NOT-APPEAR
226+
227+
- it: never prints credentials (LoadBalancer)
228+
set:
229+
<<: *credentials
230+
service:
231+
type: LoadBalancer
232+
asserts: *noCredentials
233+
234+
- it: never prints credentials (ingress, OIDC)
235+
set:
236+
<<: *credentials
237+
ingress:
238+
enabled: true
239+
auth:
240+
mode: oidc
241+
secret: SHOULD-NOT-APPEAR
242+
oidc:
243+
issuerURL: https://idp.example.com
244+
clientID: radar
245+
clientSecret: SHOULD-NOT-APPEAR
246+
redirectURL: https://radar.example.com/auth/callback
247+
asserts: *noCredentials
248+
249+
- it: never prints credentials (HTTPRoute, proxy)
250+
set:
251+
<<: *credentials
252+
httpRoute:
253+
enabled: true
254+
parentRefs:
255+
- name: public-gateway
256+
hostnames:
257+
- radar.example.com
258+
auth:
259+
mode: proxy
260+
secret: SHOULD-NOT-APPEAR
261+
asserts: *noCredentials
262+
263+
- it: never prints credentials (Cloud, token in the URL)
264+
set:
265+
<<: *credentials
266+
cloud:
267+
enabled: true
268+
url: wss://user:SHOULD-NOT-APPEAR@cloud.example/agent?token=SHOULD-NOT-APPEAR
269+
clusterName: prod-eu
270+
token: SHOULD-NOT-APPEAR
271+
asserts: *noCredentials

0 commit comments

Comments
 (0)