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
2 changes: 1 addition & 1 deletion charts/mint/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 9.0.0-beta.2
version: 9.0.0-beta.3
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
Expand Down
20 changes: 19 additions & 1 deletion charts/mint/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# MINT

![Version: 9.0.0-beta.2](https://img.shields.io/badge/Version-9.0.0--beta.2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.16.3](https://img.shields.io/badge/AppVersion-1.16.3-informational?style=flat-square)
![Version: 9.0.0-beta.3](https://img.shields.io/badge/Version-9.0.0--beta.3-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.16.3](https://img.shields.io/badge/AppVersion-1.16.3-informational?style=flat-square)

A Helm chart for MINT

Expand Down Expand Up @@ -262,6 +262,24 @@ A Helm chart for MINT
| components.ui.ingress.hosts[0].paths[0].pathType | string | `"ImplementationSpecific"` | |
| components.ui.ingress.tls | list | `[]` | |
| components.ui.resources | object | `{}` | Resource specifications for UI |
| components.ui_react.config.auth_callback_origin | string | `""` | Origin to use for the OAuth2 callback. Leave empty to use the deployment's own origin, which is correct for a real cluster host. |
| components.ui_react.config.client_id | string | `""` | OAuth2 client ID for the React UI. Required when this component is enabled, and must be a client distinct from the legacy UI's: the identity provider allows one callback URL per client, so sharing one would break login on the existing UI. |
| components.ui_react.config.data_catalog_api | string | `""` | Overrides the data catalog API URL |
| components.ui_react.config.ensemble_manager_api | string | `""` | Overrides the ensemble manager API URL |
| components.ui_react.config.hasura_endpoint | string | `""` | Overrides the Hasura GraphQL endpoint URL |
| components.ui_react.config.model_catalog_api | string | `""` | Overrides the model catalog API URL |
| components.ui_react.enabled | bool | `false` | Enable or disable the React UI. Deployed alongside the legacy `ui` component rather than replacing it; the cutover is a separate decision. Disabled by default because enabling it requires an OAuth2 client registered with the identity provider, and rendering fails without one. |
| components.ui_react.image.pullPolicy | string | `"Always"` | Image pull policy for the React UI |
| components.ui_react.image.repository | string | `"mintproject/mint-ui-react"` | Docker image repository for the React UI |
| components.ui_react.image.tag | string | `"55a3472a975b11af51fcfedf3f6f9b66db024bf0"` | Docker image tag for the React UI. Unlike the other components, this application lives in the monorepo rather than in a submodule, so this tag is a *monorepo* commit SHA. The image-tag bump automation only resolves submodule SHAs and will not update this component -- set it by hand. |
| components.ui_react.ingress.annotations | object | `{}` | |
| components.ui_react.ingress.className | string | `""` | |
| components.ui_react.ingress.enabled | bool | `true` | Enable or disable ingress for the React UI |
| components.ui_react.ingress.hosts[0].host | string | `"next.mint.local"` | |
| components.ui_react.ingress.hosts[0].paths[0].path | string | `"/"` | |
| components.ui_react.ingress.hosts[0].paths[0].pathType | string | `"ImplementationSpecific"` | |
| components.ui_react.ingress.tls | list | `[]` | |
| components.ui_react.resources | object | `{}` | Resource specifications for the React UI |
| default_user | string | `"[email protected]"` | Default user email |
| external_services.ckan.enabled | bool | `false` | Enable or disable CKAN service |
| external_services.ckan.extra.default_dataset_id | string | `""` | Default dataset ID for CKAN service. Used by Ensemble Manager to upload data when a task has no dataset_id |
Expand Down
9 changes: 9 additions & 0 deletions charts/mint/ci/default-values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Installs the chart with its default values.
#
# This file exists to preserve coverage that was previously implicit: with no
# ci/ directory, chart-testing installed the chart once using values.yaml as-is.
# Adding any file to ci/ replaces that behaviour with one install per file, so
# without this the default-values install would silently stop being tested.
#
# Deliberately empty -- the point is to change nothing.
{}
23 changes: 23 additions & 0 deletions charts/mint/ci/ui-react-values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Installs the chart with the React UI enabled.
#
# Covers, as rendering behaviour:
# - endpoint derivation from each component's own ingress declaration
# (hasura, model_catalog_api and ensemble_manager are left to derive)
# - per-key override precedence (data_catalog_api is set explicitly and must
# win over the value that would have been derived)
# - the component's own deployment, service and ingress reaching Ready,
# which is also the check that the pinned image tag is pullable
#
# Not covered here: the required-client-ID failure. chart-testing has no
# "expect this render to fail" mode, so a values file omitting client_id would
# just turn CI red. That path is enforced by a `fail` in ui-react-config.yaml.
components:
ui_react:
enabled: true
config:
# Any non-empty value satisfies the required check; nothing in CI
# authenticates against a real identity provider.
client_id: mint-ci
# Set explicitly so the rendered ConfigMap must show this value rather
# than the one derived from components.data_catalog.ingress.
data_catalog_api: https://data-catalog.example.test/override
62 changes: 62 additions & 0 deletions charts/mint/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -249,3 +249,65 @@ Usage:
{{- tpl (.value | toYaml) .context }}
{{- end }}
{{- end -}}

{{- define "helm.ui_react_node_port" -}}
{{- if .Values.service.type }}
{{- if eq .Values.service.type "NodePort" }}
{{- if .Values.service.port }}
{{- add .Values.service.port 11 }}
{{- else }}
{{- add 30000 11 }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}

{{/*
Base URL of a component, derived from its own ingress declaration.

Renders "http://host" or "https://host" -- the scheme from that component's
own TLS setting. Renders nothing at all when the component is disabled, has
no ingress hosts, or its first host is blank. Callers must treat empty as
"no endpoint" rather than appending a path to it.

Unlike the legacy ui ConfigMap, the host list is guarded before `first` is
called, so an empty `hosts` does not fail the render.

Usage:
{{ include "mint.component_url" (dict "component" .Values.components.hasura) }}
*/}}
{{- define "mint.component_url" -}}
{{- $c := .component -}}
{{- if and $c $c.enabled $c.ingress -}}
{{- with $c.ingress.hosts -}}
{{- $host := (first .).host -}}
{{- if $host -}}
http{{ if $c.ingress.tls }}s{{ end }}://{{ $host }}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}

{{/*
Resolve one ui_react endpoint, with the explicit override taking precedence
over the value derived from the target component's ingress.

An override is used verbatim -- the suffix is not appended, because an
operator stating a URL explicitly is stating the whole URL. When there is no
override and the component yields no base URL, this renders nothing, so the
key is omitted from the ConfigMap and the application falls back to its own
default.

Usage:
{{ include "mint.ui_react.endpoint" (dict "override" $cfg.hasura_endpoint "component" .Values.components.hasura "suffix" "/v1/graphql") }}
*/}}
{{- define "mint.ui_react.endpoint" -}}
{{- if .override -}}
{{- .override -}}
{{- else -}}
{{- $base := include "mint.component_url" (dict "component" .component) -}}
{{- if $base -}}
{{- $base }}{{ .suffix -}}
{{- end -}}
{{- end -}}
{{- end -}}
60 changes: 60 additions & 0 deletions charts/mint/templates/ingress-ui-react.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{{- if and .Values.components.ui_react.enabled .Values.components.ui_react.ingress.enabled -}}
{{- $fullName := include "mint.prefix" . -}}
{{- $svcPort := .Values.service.port -}}
{{- if and .Values.components.ui_react.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
{{- if not (hasKey .Values.components.ui_react.ingress.annotations "kubernetes.io/ingress.class") }}
{{- $_ := set .Values.components.ui_react.ingress.annotations "kubernetes.io/ingress.class" .Values.components.ui_react.ingress.className}}
{{- end }}
{{- end }}
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1beta1
{{- else -}}
apiVersion: extensions/v1beta1
{{- end }}
kind: Ingress
metadata:
name: {{ $fullName }}-ui-react
namespace: {{ .Release.Namespace }}
{{- with .Values.components.ui_react.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if and .Values.components.ui_react.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
ingressClassName: {{ .Values.components.ui_react.ingress.className }}
{{- end }}
{{- if .Values.components.ui_react.ingress.tls }}
tls:
{{- range .Values.components.ui_react.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.components.ui_react.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
{{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
pathType: {{ .pathType }}
{{- end }}
backend:
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
service:
name: {{ $fullName }}-ui-react
port:
number: {{ $svcPort }}
{{- else }}
serviceName: {{ $fullName }}-ui-react
servicePort: {{ $svcPort }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
51 changes: 51 additions & 0 deletions charts/mint/templates/ui-react-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{{- if .Values.components.ui_react.enabled }}
{{- $cfg := .Values.components.ui_react.config }}
{{- if not $cfg.client_id }}
{{- fail "components.ui_react.config.client_id is required when components.ui_react.enabled is true. The React UI must use its own OAuth2 client, registered separately from the legacy UI's: an identity provider allows one callback URL per client, so sharing the legacy client would break login on the existing UI. Register a client for this deployment's host and set components.ui_react.config.client_id." }}
{{- end }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "mint.prefix" . }}-ui-react-config-map
namespace: {{ .Release.Namespace }}
labels:
{{- include "helm.labels" . | nindent 4 }}
data:
# Consumed as environment variables by the image's entrypoint, which renders
# them into the runtime config script at startup. The generator in the image
# -- not this template -- owns the config shape and its defaults, so a key
# omitted here falls back to that default rather than being blanked out.

# Service endpoints, derived from each component's own ingress declaration
# unless overridden explicitly on ui_react.config.
{{- with include "mint.ui_react.endpoint" (dict "override" $cfg.hasura_endpoint "component" .Values.components.hasura "suffix" "/v1/graphql") }}
HASURA_ENDPOINT: {{ . | quote }}
{{- end }}
{{- with include "mint.ui_react.endpoint" (dict "override" $cfg.data_catalog_api "component" .Values.components.data_catalog "suffix" "") }}
DATA_CATALOG_API: {{ . | quote }}
{{- end }}
{{- with include "mint.ui_react.endpoint" (dict "override" $cfg.model_catalog_api "component" .Values.components.model_catalog_api "suffix" (printf "/%s" (default "" .Values.components.model_catalog_api.api_version))) }}
MODEL_CATALOG_API: {{ . | quote }}
{{- end }}
{{- with include "mint.ui_react.endpoint" (dict "override" $cfg.ensemble_manager_api "component" .Values.components.ensemble_manager "suffix" (printf "/%s" (default "" .Values.components.ensemble_manager.api_version))) }}
ENSEMBLE_MANAGER_API: {{ . | quote }}
{{- end }}

# Authentication. Server and provider are inherited from the chart's
# top-level auth values; the client ID is deliberately per-component.
# Keycloak is not plumbed through the chart, so AUTH_REALM is not emitted.
AUTH_PROVIDER: {{ .Values.auth.provider | quote }}
AUTH_SERVER: {{ .Values.auth.server | quote }}
AUTH_CLIENT_ID: {{ $cfg.client_id | quote }}
{{- with $cfg.auth_callback_origin }}
AUTH_CALLBACK_ORIGIN: {{ . | quote }}
{{- end }}

{{- with .Values.welcome_message }}
WELCOME_MESSAGE: {{ . | quote }}
{{- end }}
{{- with .Values.google.maps.key }}
GOOGLE_MAPS_KEY: {{ . | quote }}
{{- end }}
{{- end }}
76 changes: 76 additions & 0 deletions charts/mint/templates/ui-react.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
{{- if .Values.components.ui_react.enabled }}
---
apiVersion: v1
kind: Service
metadata:
name: {{ include "mint.prefix" . }}-ui-react
namespace: {{ .Release.Namespace }}
labels:
{{- include "helm.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- name: "http"
port: {{ .Values.service.port }}
targetPort: http
{{- if eq .Values.service.type "NodePort" }}
nodePort: {{ include "helm.ui_react_node_port" . }}
{{- end }}
protocol: TCP
selector:
app: {{ include "mint.prefix" . }}-ui-react
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "mint.prefix" . }}-ui-react
namespace: {{ .Release.Namespace }}
labels:
{{- include "helm.labels" . | nindent 4 }}
spec:
replicas: 1
selector:
matchLabels:
app: {{ include "mint.prefix" . }}-ui-react
template:
metadata:
labels:
app: {{ include "mint.prefix" . }}-ui-react
annotations:
# The entrypoint reads this configuration once, at startup, so a
# ConfigMap change must roll the pods to take effect.
checksum/config: {{ include (print $.Template.BasePath "/ui-react-config.yaml") . | sha256sum }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: ui-react
{{- with .Values.components.ui_react }}
image: "{{ .image.repository }}:{{ .image.tag | default $.Chart.AppVersion }}"
imagePullPolicy: {{ .image.pullPolicy }}
resources:
{{- toYaml .resources | nindent 12 }}
{{- end }}
# The entrypoint generates the runtime config script from these at
# startup. Note that this writes into the web root, so a read-only
# root filesystem would break startup.
envFrom:
- configMapRef:
name: {{ include "mint.prefix" . }}-ui-react-config-map
ports:
- name: http
containerPort: 80
protocol: TCP
livenessProbe:
httpGet:
path: /
port: http
readinessProbe:
httpGet:
path: /
port: http
{{- end }}
52 changes: 52 additions & 0 deletions charts/mint/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,58 @@ components:
- path: /
pathType: ImplementationSpecific
tls: []
ui_react:
# -- Enable or disable the React UI. Deployed alongside the legacy `ui`
# component rather than replacing it; the cutover is a separate decision.
# Disabled by default because enabling it requires an OAuth2 client
# registered with the identity provider, and rendering fails without one.
enabled: false
image:
# -- Docker image repository for the React UI
repository: mintproject/mint-ui-react
# -- Docker image tag for the React UI.
# Unlike the other components, this application lives in the monorepo
# rather than in a submodule, so this tag is a *monorepo* commit SHA.
# The image-tag bump automation only resolves submodule SHAs and will
# not update this component -- set it by hand.
tag: 55a3472a975b11af51fcfedf3f6f9b66db024bf0
# -- Image pull policy for the React UI
pullPolicy: Always
# -- Resource specifications for the React UI
resources: {}
config:
# -- OAuth2 client ID for the React UI. Required when this component is
# enabled, and must be a client distinct from the legacy UI's: the
# identity provider allows one callback URL per client, so sharing one
# would break login on the existing UI.
client_id: ""
# -- Origin to use for the OAuth2 callback. Leave empty to use the
# deployment's own origin, which is correct for a real cluster host.
auth_callback_origin: ""
# Explicit endpoint overrides. Each is derived from the corresponding
# component's own ingress when left empty; setting one takes precedence
# and is used verbatim, including any path.
# -- Overrides the Hasura GraphQL endpoint URL
hasura_endpoint: ""
# -- Overrides the data catalog API URL
data_catalog_api: ""
# -- Overrides the model catalog API URL
model_catalog_api: ""
# -- Overrides the ensemble manager API URL
ensemble_manager_api: ""
ingress:
# -- Enable or disable ingress for the React UI
enabled: true
className: ""
annotations: {}
hosts:
# Its own host rather than a path prefix on the legacy UI's: the
# application is built to be served from the root.
- host: next.mint.local
paths:
- path: /
pathType: ImplementationSpecific
tls: []
ensemble_manager:
# -- Enable or disable Ensemble Manager
enabled: true
Expand Down
Loading
Loading