Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@ written while it was being built. See [RELEASING.md](RELEASING.md).

### Changed

- A deployment can now be reached under any hostnames, not only `app.<domain>`
and `auth.<domain>`. The app's hostname is the first entry of
`frontend.ingress.hosts`, Keycloak's is `keycloak.hostname.hostname`, and the
chart derives the ingresses, the TLS certificates, the OIDC issuer urls and
the realm's login redirect urls from those two. Previously the subdomains were
fixed in the chart's templates, so changing either value pointed the traffic
at one name while the login flow still expected the other. Both values are now
required: the chart refuses to render rather than guessing a hostname nothing
is served under, and the two OIDC issuer settings are gone from `values.yaml`
because they only ever had one working value.
- Your hackathon lists are now grouped by when they happen — Happening now,
Coming up, Finished — and each one says how far away it is: "starts in 4
days", "day 1 of 4", "ended 3 days ago". The dates are still there behind the
Expand Down
2 changes: 1 addition & 1 deletion helm-chart/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ type: application

# The chart's own version. Bumped by hand when the chart changes, and
# independent of the app: the CI publishes whatever it finds here.
version: 0.3.1
version: 0.4.0
# The app release this chart deploys. A new app release does
# not become deployable until someone points the chart at it.
appVersion: "0.9.1"
Expand Down
4 changes: 2 additions & 2 deletions helm-chart/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Hackagon has been deployed!

Frontend: https://app.{{ .Values.baseDomain }}
Keycloak: https://auth.{{ .Values.baseDomain }}
Frontend: https://{{ include "hackagon.frontendHost" . }}
Keycloak: {{ include "hackagon.keycloakUrl" . }}

To get the generated frontend OIDC secrets, run:

Expand Down
32 changes: 23 additions & 9 deletions helm-chart/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -62,24 +62,38 @@ Create the name of the service account to use
{{- end }}

{{/*
Base domain with substitution
First ingress host is the canonical frontend hostname.
(in case we have multiple urls)
Rendered with `tpl`, like every other host value; keep this one free of
`hackagon.frontendHost` or it recurses.
*/}}
{{- define "hackagon.baseDomain" -}}
{{- .Values.baseDomain | replace "{baseDomain}" .Values.baseDomain }}
{{- define "hackagon.frontendHost" -}}
{{- $first := first (.Values.frontend.ingress.hosts | default list) | required "frontend.ingress.hosts must name at least one host: it is the app's public name" }}
{{- $host := $first.host | required "frontend.ingress.hosts[0].host is required: it is the app's public name" }}
{{- tpl $host . | required "frontend.ingress.hosts[0].host must render to a non-empty hostname" }}
{{- end }}

{{/*
Frontend host with substitution
Public url Keycloak runs under. Required `enabled` or not: browsers are sent
here, and it is the `iss` claim in every token.
*/}}
{{- define "hackagon.frontendHost" -}}
{{- printf "app.%s" (include "hackagon.baseDomain" .) | replace "{baseDomain}" .Values.baseDomain }}
{{- define "hackagon.keycloakUrl" -}}
{{- .Values.keycloak.hostname.hostname | required "keycloak.hostname.hostname is required (e.g. \"https://auth.example.com\")" | trimSuffix "/" }}
{{- end }}

{{/*
Keycloak host with substitution
The `iss` claim; the backend rejects a token that does not match it. The realm
is `hackagon` chart-wide, so this is derived rather than configurable.
*/}}
{{- define "hackagon.oidcIssuer" -}}
{{- printf "%s/realms/hackagon" (include "hackagon.keycloakUrl" .) }}
{{- end }}

{{/*
The Keycloak url as a bare hostname, for an ingress `host:` field.
*/}}
{{- define "hackagon.keycloakHost" -}}
{{- printf "auth.%s" (include "hackagon.baseDomain" .) | replace "{baseDomain}" .Values.baseDomain }}
{{- include "hackagon.keycloakUrl" . | trimPrefix "https://" | trimPrefix "http://" }}
{{- end }}

{{/*
Expand Down Expand Up @@ -127,4 +141,4 @@ Get password: use provided value or generate one
{{- else }}
{{- include "hackagon.randAlphaNum" .length | b64enc }}
{{- end }}
{{- end }}
{{- end }}
10 changes: 5 additions & 5 deletions helm-chart/templates/backend-configmap.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{{- if and (contains "{keycloakService}" .Values.backend.config.oidc.jwksurl) (not .Values.keycloak.enabled) -}}
{{- fail "backend.config.oidc.jwksurl uses {keycloakService}, but keycloak.enabled is false: set jwksurl to the external Keycloak's certs endpoint" -}}
{{- if and (contains "hackagon.keycloakServiceName" .Values.backend.config.oidc.jwksurl) (not .Values.keycloak.enabled) -}}
{{- fail "backend.config.oidc.jwksurl points at the in-cluster Keycloak, but keycloak.enabled is false: set it to the external Keycloak's certs endpoint" -}}
{{- end -}}
apiVersion: v1
kind: ConfigMap
Expand All @@ -12,7 +12,7 @@ data:
config.yaml: |
server:
port: {{ .Values.backend.config.server.port | quote }}
adminemail: {{ .Values.backend.config.server.adminemail | replace "{baseDomain}" .Values.baseDomain | quote }}
adminemail: {{ tpl .Values.backend.config.server.adminemail . | quote }}
adminkeycloakid: {{ .Values.backend.config.server.adminkeycloakid | quote }}
database:
driver: {{ .Values.backend.config.database.driver | quote }}
Expand All @@ -22,8 +22,8 @@ data:
user: {{ .Values.backend.config.database.user | quote }}
password: {{ .Values.backend.config.database.postgresPassword | required "postgresql.auth.postgresPassword is required" | quote }}
oidc:
jwksurl: {{ .Values.backend.config.oidc.jwksurl | replace "{baseDomain}" .Values.baseDomain | replace "{keycloakService}" (include "hackagon.keycloakServiceName" .) | quote }}
issuerurl: {{ .Values.backend.config.oidc.issuerurl | replace "{baseDomain}" .Values.baseDomain | quote }}
jwksurl: {{ tpl .Values.backend.config.oidc.jwksurl . | quote }}
issuerurl: {{ include "hackagon.oidcIssuer" . | quote }}
algorithm: {{ .Values.backend.config.oidc.algorithm | quote }}
logging:
level: {{ .Values.backend.config.logging.level | quote }}
2 changes: 1 addition & 1 deletion helm-chart/templates/frontend-configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ data:
useSecure: {{ .Values.frontend.config.cookies.useSecure }}
oidc:
clientId: {{ .Values.frontend.config.oidc.clientId | quote }}
issuer: {{ .Values.frontend.config.oidc.issuer | replace "{baseDomain}" .Values.baseDomain | quote }}
issuer: {{ include "hackagon.oidcIssuer" . | quote }}
audience: {{ .Values.frontend.config.oidc.audience | quote }}
10 changes: 2 additions & 8 deletions helm-chart/templates/frontend-ingress.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ spec:
ingressClassName: {{ .Values.frontend.ingress.ingressClass }}
rules:
{{- range .Values.frontend.ingress.hosts }}
- host: {{ .host | replace "{baseDomain}" $.Values.baseDomain | replace "{releaseName}" $.Release.Name }}
- host: {{ tpl .host $ }}
http:
paths:
{{- range .paths }}
Expand All @@ -30,12 +30,6 @@ spec:
{{- end }}
{{- with .Values.frontend.ingress.tls }}
tls:
{{- range . }}
- hosts:
{{- range .hosts }}
- {{ . | replace "{baseDomain}" $.Values.baseDomain | replace "{releaseName}" $.Release.Name }}
{{- end }}
secretName: {{ .secretName | replace "{releaseName}" $.Release.Name }}
{{- end }}
{{- tpl (toYaml .) $ | nindent 4 }}
{{- end }}
{{- end }}
26 changes: 15 additions & 11 deletions helm-chart/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ frontend:
useSecure: true
oidc:
clientId: hackagon-frontend
issuer: "https://auth.{baseDomain}/realms/hackagon"
Comment thread
cmdoret marked this conversation as resolved.
audience: hackagon-backend

service:
Expand All @@ -69,15 +68,20 @@ frontend:
nginx.ingress.kubernetes.io/proxy-buffers: 8 16k
nginx.ingress.kubernetes.io/proxy_busy_buffers_size: 32k
nginx.ingress.kubernetes.io/ssl-redirect: "true"
# -- Public hostname of the app. The TLS host below and the realm's login
# Redirects follow the first entry.
hosts:
- host: "app.{baseDomain}"
# You can overwrite this default to any hard-coded custom domain,
# e.g. host: "hackagon.datascience.ch".
- host: "app.{{ .Values.baseDomain }}"
Comment thread
cmdoret marked this conversation as resolved.
paths:
- path: /
pathType: Prefix
tls:
- secretName: "{releaseName}-frontend-tls"
- secretName: '{{ .Release.Name }}-frontend-tls'
hosts:
- "app.{baseDomain}"
# Evaluates to the first host in frontend.ingress.hosts
- '{{ include "hackagon.frontendHost" . }}'

# ============================================================
# Backend
Expand All @@ -104,7 +108,7 @@ backend:
config:
server:
port: "3000"
adminemail: "admin@{baseDomain}"
adminemail: "admin@{{ .Values.baseDomain }}"
# -- Keycloak user id of the platform admin. Must equal the `id` of the
# `hackagon-admin` user in realmJson: casbin grants the `admin` role to
# exactly this id, and the backend seeds the admin row by it. Importing
Expand All @@ -123,10 +127,8 @@ backend:
# -- Where the backend fetches Keycloak's signing keys.
# With an external Keycloak (keycloak.enabled: false),
# override this with a url the backend pod can actually reach.
jwksurl: "http://{keycloakService}:8080/realms/hackagon/protocol/openid-connect/certs"
# -- Must stay the PUBLIC url: this is the `iss` claim Keycloak stamps into
# tokens, and the backend rejects any token whose issuer does not match.
issuerurl: "https://auth.{baseDomain}/realms/hackagon"
# the issuer is derived from the keycloak hostname and injected in configmaps.
jwksurl: 'http://{{ include "hackagon.keycloakServiceName" . }}:8080/realms/hackagon/protocol/openid-connect/certs'
algorithm: RS256
logging:
level: info
Expand All @@ -145,9 +147,11 @@ keycloak:
# -- Production mode requires hostname and database
mode: production

# -- Hostname for Keycloak (public admin UI)
# -- Public url Keycloak runs under; the auth hostname and the OIDC issuer
# derive from it. Required. Passed verbatim to the subchart, so `{...}`
# placeholders are not substituted here. e.g. "https://auth.example.com"
hostname:
hostname: "" # e.g. "https://auth.{baseDomain}"
hostname: ""

# -- Keycloak's own console admin, which lives in the `master` realm. Its
# password is NOT in realmJson: a realm export carries only that realm's
Expand Down
10 changes: 9 additions & 1 deletion tools/helm/lint-values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@

baseDomain: lint.invalid

frontend:
ingress:
hosts:
- host: "hackagon-app.lint.invalid"
paths:
- path: /
pathType: Prefix

backend:
config:
server:
Expand All @@ -14,7 +22,7 @@ backend:

keycloak:
hostname:
hostname: "https://auth.lint.invalid"
hostname: "https://hackagon-auth.lint.invalid"
database:
external:
host: "hackagon-postgresql"
Expand Down
4 changes: 3 additions & 1 deletion tools/just/helm.just
Original file line number Diff line number Diff line change
Expand Up @@ -193,5 +193,7 @@ publish:
echo ""
echo " Install with:"
echo " helm install hackagon {{ oci_repo }}/hackagon --version $chart_v \\"
echo " --set baseDomain=example.com --set-file realmJson=@path/to/realm.json"
echo " --set baseDomain=example.com \\"
echo " --set keycloak.hostname.hostname=https://auth.example.com \\"
echo " --set-file realmJson=@path/to/realm.json"
echo ""
1 change: 1 addition & 0 deletions tools/keycloak-handover/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ decryptable by you, which is how you know the recipient key took effect.
helm upgrade --install hackagon ../../helm-chart \
--set-file realmJson=./realm.json \
--set baseDomain=<domain> \
--set keycloak.hostname.hostname=https://auth.<domain> \
--set backend.config.server.adminkeycloakid=1183370a-46a2-4dad-b8fd-dd927d083e14 \
--set frontendSecrets.clientSecret=<from CREDENTIALS.md>
```
Expand Down
Loading