diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 4ba8f14..801e7a3 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -21,22 +21,10 @@ jobs: - name: Lint chart run: helm lint chart/ - - name: Template chart (NebariApp disabled) - run: helm template test chart/ --set nebariapp.enabled=false - - name: Template chart (NebariApp enabled) run: | helm template test chart/ \ - --set nebariapp.enabled=true \ - --set nebariapp.hostname=test.example.com \ + --set nebariapp.serve.enabled=true \ + --set nebariapp.serve.hostname=test.example.com \ --set nebariapp.dashboard.enabled=true \ --set nebariapp.dashboard.hostname=dashboard.example.com - - - name: Template chart (NebariApp + auth enabled) - run: | - helm template test chart/ \ - --set nebariapp.enabled=true \ - --set nebariapp.hostname=test.example.com \ - --set nebariapp.dashboard.enabled=true \ - --set nebariapp.dashboard.hostname=dashboard.example.com \ - --set nebariapp.auth.enabled=true diff --git a/.github/workflows/test-integration.yaml b/.github/workflows/test-integration.yaml index 331462f..d1a618f 100644 --- a/.github/workflows/test-integration.yaml +++ b/.github/workflows/test-integration.yaml @@ -119,7 +119,7 @@ jobs: helm install rayserve chart/ \ --set kuberay-operator.enabled=false \ --set nebariapp.enabled=true \ - --set nebariapp.hostname=rayserve.nebari.local \ + --set nebariapp.serve.hostname=rayserve.nebari.local \ --set nebariapp.serve.enabled=true \ --set nebariapp.dashboard.enabled=true \ --set nebariapp.dashboard.hostname=ray-dashboard.nebari.local \ diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 640019a..c476a09 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -33,7 +33,8 @@ jobs: run: | helm install rayserve chart/ \ --set kuberay-operator.enabled=false \ - --set nebariapp.enabled=false \ + --set nebariapp.serve.enabled=false \ + --set nebariapp.dashboard.enabled=false \ --set head.resources.requests.cpu=500m \ --set head.resources.requests.memory=512Mi \ --set head.resources.limits.cpu=1 \ diff --git a/.gitignore b/.gitignore index 71dcf0d..27aee61 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ # Helm chart/charts/ -chart/Chart.lock # Dev environment dev/.cache/ diff --git a/README.md b/README.md index 785a93f..2cd845a 100644 --- a/README.md +++ b/README.md @@ -70,17 +70,13 @@ spec: releaseName: rayserve values: | nebariapp: - enabled: true serve: enabled: false # Keep serve endpoint internal-only dashboard: enabled: true hostname: ray-dashboard.example.com - auth: - enabled: true - provider: keycloak - provisionClient: true - redirectURI: /oauth2/callback + auth: + enabled: true destination: server: https://kubernetes.default.svc namespace: rayserve @@ -195,14 +191,12 @@ Key values in `chart/values.yaml`: | Value | Default | Description | |-------|---------|-------------| -| `nebariapp.enabled` | `false` | Create NebariApp resources for routing/TLS/auth | | `nebariapp.serve.enabled` | `false` | Expose the serve endpoint externally (set `false` to keep internal-only) | -| `nebariapp.hostname` | - | Hostname for the Ray Serve endpoint (required when serve.enabled) | -| `nebariapp.dashboard.enabled` | `true` | Create a separate NebariApp for the Ray Dashboard | -| `nebariapp.dashboard.hostname` | - | Hostname for the Ray Dashboard (required when dashboard enabled) | -| `nebariapp.auth.enabled` | `false` | Enable OIDC authentication via Keycloak | -| `nebariapp.auth.redirectURI` | `/oauth2/callback` | OAuth callback path (Envoy Gateway rejects `/`) | -| `nebariapp.gateway` | `public` | Gateway to use (`public` or `internal`) | +| `nebariapp.serve.hostname` | - | Hostname for the Ray Serve endpoint (required when serve.enabled) | +| `nebariapp.serve.auth.enabled` | `false` | Enable OIDC authentication for the Ray Serve endpoint via Keycloak | +| `nebariapp.dashboard.enabled` | `false` | Create a separate NebariApp for the Ray Dashboard | +| `nebariapp.dashboard.hostname` | - | Hostname for the Ray Dashboard (required when dashboard.enabled) | +| `nebariapp.dashboard.auth.enabled` | `false` | Enable OIDC authentication for the Ray Dashboard endpoint via Keycloak | ### Ray Cluster diff --git a/chart/Chart.lock b/chart/Chart.lock new file mode 100644 index 0000000..55fd8cd --- /dev/null +++ b/chart/Chart.lock @@ -0,0 +1,9 @@ +dependencies: +- name: nebari-app + repository: oci://quay.io/reiemp/charts + version: 0.1.2 +- name: kuberay-operator + repository: https://ray-project.github.io/kuberay-helm/ + version: 1.3.0 +digest: sha256:9e9345b359fb1be3ec07a39e1fbe3ce0b600309715741d318087170486ba8cde +generated: "2026-08-28T17:43:29.042013605+02:00" diff --git a/chart/Chart.yaml b/chart/Chart.yaml index ba07c8b..185dec4 100644 --- a/chart/Chart.yaml +++ b/chart/Chart.yaml @@ -5,6 +5,9 @@ type: application version: 0.4.1 appVersion: "2.43.0" dependencies: + - name: nebari-app + repository: oci://quay.io/reiemp/charts + version: "0.1.3" - name: kuberay-operator version: 1.3.0 repository: https://ray-project.github.io/kuberay-helm/ diff --git a/chart/templates/NOTES.txt b/chart/templates/NOTES.txt index 4794381..22a1884 100644 --- a/chart/templates/NOTES.txt +++ b/chart/templates/NOTES.txt @@ -3,27 +3,35 @@ The RayService controller manages the Ray cluster and Serve proxy. Serve is pre-initialized with host 0.0.0.0 on port 8000. -{{- if .Values.nebariapp.enabled }} +{{ $tplCtx := . }} +{{- range $name, $component := dict + "Ray Serve" (dict + "nebariapp" .Values.nebariapp.serve + "serviceName" (include "nebari-rayserve.serve-service-name" .) + "servicePort" 8000 + ) + "Ray Dashboard" (dict + "nebariapp" .Values.nebariapp.dashboard + "serviceName" (include "nebari-rayserve.head-service-name" .) + "servicePort" 8265 +) -}} +{{- if $component.nebariapp.enabled }} +{{- $nebariapp := include "nebari-app.deepTplJson" (dict "value" (omit $component.nebariapp "enabled") "ctx" $tplCtx) | fromJson }} -NebariApp is ENABLED. The nebari-operator will configure: - {{- if ne (toString (dig "serve" "enabled" true .Values.nebariapp)) "false" }} - - HTTPRoute for Ray Serve: {{ .Values.nebariapp.hostname }} - {{- end }} - {{- if .Values.nebariapp.dashboard.enabled }} - - HTTPRoute for Ray Dashboard: {{ .Values.nebariapp.dashboard.hostname }} - {{- end }} - {{- if .Values.nebariapp.auth.enabled }} - - OIDC authentication via {{ .Values.nebariapp.auth.provider }} +NebariApp for {{ $name }} is ENABLED. The nebari-operator will configure: + - HTTPRoute: {{ $nebariapp.hostname }} + {{- if (and $nebariapp.auth $nebariapp.auth.enabled) }} + - OIDC authentication via {{ $nebariapp.auth.provider | default "keycloak" }} {{- end }} {{- else }} To access locally: - kubectl port-forward svc/{{ include "nebari-rayserve.serve-service-name" . }} 8000:8000 -n {{ .Release.Namespace }} - kubectl port-forward svc/{{ include "nebari-rayserve.head-service-name" . }} 8265:8265 -n {{ .Release.Namespace }} + kubectl port-forward svc/{{ $component.serviceName }} {{ $component.servicePort }}:{{ $component.servicePort }} -n {{ $tplCtx.Release.Namespace }} {{- end }} +{{- end }} === Deploying Models === diff --git a/chart/templates/nebariapp.yaml b/chart/templates/nebariapp.yaml index 59285d3..cfb8f16 100644 --- a/chart/templates/nebariapp.yaml +++ b/chart/templates/nebariapp.yaml @@ -1,96 +1,25 @@ -{{- if and .Values.nebariapp.enabled (ne (toString (dig "serve" "enabled" true .Values.nebariapp)) "false") }} -{{- if .Values.nebariapp.hostname }} +{{- if .Values.nebariapp.serve.enabled -}} # NebariApp for Ray Serve endpoint -apiVersion: reconcilers.nebari.dev/v1 -kind: NebariApp -metadata: - name: {{ include "nebari-rayserve.fullname" . }} - labels: - {{- include "nebari-rayserve.labels" . | nindent 4 }} -spec: - hostname: {{ .Values.nebariapp.hostname }} - service: - name: {{ .Values.nebariapp.service.name | default (include "nebari-rayserve.serve-service-name" .) }} - port: {{ .Values.nebariapp.service.servePort }} - routing: - routes: - - pathPrefix: / - pathType: PathPrefix - {{- if .Values.nebariapp.auth.enabled }} - auth: - enabled: true - provider: {{ .Values.nebariapp.auth.provider }} - provisionClient: {{ .Values.nebariapp.auth.provisionClient }} - redirectURI: {{ .Values.nebariapp.auth.redirectURI }} - scopes: - {{- toYaml .Values.nebariapp.auth.scopes | nindent 6 }} - - {{- end }} - gateway: {{ .Values.nebariapp.gateway }} -{{- end }} +{{ include "nebari-app.nebariApp" (dict + "metadata" (dict + "name" (include "nebari-rayserve.fullname" .) + "namespace" .Release.Namespace + "labels" (include "nebari-rayserve.labels" . | fromYaml) + ) + "spec" (omit .Values.nebariapp.serve "enabled") + "tplCtx" . +) -}} {{- end }} --- -{{- if and .Values.nebariapp.enabled .Values.nebariapp.dashboard.enabled }} +{{- if .Values.nebariapp.dashboard.enabled -}} # NebariApp for Ray Dashboard -apiVersion: reconcilers.nebari.dev/v1 -kind: NebariApp -metadata: - name: {{ include "nebari-rayserve.fullname" . }}-dashboard - labels: - {{- include "nebari-rayserve.labels" . | nindent 4 }} -spec: - hostname: {{ required "nebariapp.dashboard.hostname is required when dashboard is enabled" .Values.nebariapp.dashboard.hostname }} - service: - name: {{ .Values.nebariapp.service.name | default (include "nebari-rayserve.head-service-name" .) }} - port: {{ .Values.nebariapp.service.dashboardPort }} - routing: - routes: - - pathPrefix: / - pathType: PathPrefix - {{- if .Values.nebariapp.auth.enabled }} - auth: - enabled: true - provider: {{ .Values.nebariapp.auth.provider }} - provisionClient: {{ .Values.nebariapp.auth.provisionClient }} - redirectURI: {{ .Values.nebariapp.auth.redirectURI }} - scopes: - {{- toYaml .Values.nebariapp.auth.scopes | nindent 6 }} - - {{- end }} - {{- with .Values.nebariapp.dashboard.landingPage }} - landingPage: - enabled: {{ .enabled | default false }} - {{- with .displayName }} - displayName: {{ . | quote }} - {{- end }} - {{- with .description }} - description: {{ . | quote }} - {{- end }} - {{- with .icon }} - icon: {{ . | quote }} - {{- end }} - {{- with .category }} - category: {{ . | quote }} - {{- end }} - {{- if kindIs "float64" .priority }} - priority: {{ .priority }} - {{- end }} - {{- with .externalUrl }} - externalUrl: {{ . | quote }} - {{- end }} - {{- with .healthCheck }} - healthCheck: - enabled: {{ .enabled | default false }} - {{- with .path }} - path: {{ . | quote }} - {{- end }} - {{- if .intervalSeconds }} - intervalSeconds: {{ .intervalSeconds }} - {{- end }} - {{- if .timeoutSeconds }} - timeoutSeconds: {{ .timeoutSeconds }} - {{- end }} - {{- end }} - {{- end }} - gateway: {{ .Values.nebariapp.gateway }} +{{ include "nebari-app.nebariApp" (dict + "metadata" (dict + "name" (printf "%s-dashboard" (include "nebari-rayserve.fullname" .)) + "namespace" .Release.Namespace + "labels" (include "nebari-rayserve.labels" . | fromYaml) + ) + "spec" (omit .Values.nebariapp.dashboard "enabled") + "tplCtx" . +) -}} {{- end }} diff --git a/chart/values.yaml b/chart/values.yaml index b25c4d7..236f212 100644 --- a/chart/values.yaml +++ b/chart/values.yaml @@ -1,16 +1,24 @@ # ============================================================================= # Nebari Integration # ============================================================================= -# Creates a NebariApp CRD that configures routing, TLS, and auth via nebari-operator. -# Set enabled: true when deploying on a Nebari cluster. +# Creates NebariApp CRs that configure routing, TLS, and auth via nebari-operator. nebariapp: - enabled: false - # hostname: rayserve.nebari.example.com # Required when serve.enabled is true serve: - enabled: false # Set to true and provide nebariapp.hostname to expose the serve endpoint externally + enabled: false + hostname: '{{ fail "nebariapps.serve.hostname is required if nebariapps.serve.enabled is true" }}' + service: + name: '{{ include "nebari-rayserve.serve-service-name" . | toJson }}' + port: 8000 + routing: + routes: + - pathPrefix: / + pathType: PathPrefix dashboard: - enabled: true - # hostname: ray-dashboard.nebari.example.com # Separate hostname for dashboard + enabled: false + hostname: '{{ fail "nebariapps.dashboard.hostname is required if nebariapps.dashboard.enabled is true" }}' + service: + name: '{{ include "nebari-rayserve.head-service-name" . | toJson }}' + port: 8265 landingPage: enabled: false displayName: "Ray Dashboard" @@ -23,21 +31,10 @@ nebariapp: path: /api/component_activities intervalSeconds: 30 timeoutSeconds: 5 - service: - name: "" # Defaults to --serve-svc (serve) or -head-svc (dashboard) - servePort: 8000 - dashboardPort: 8265 - auth: - enabled: false - provider: keycloak - provisionClient: true - redirectURI: /oauth2/callback - scopes: - - openid - - profile - - email - - gateway: public + routing: + routes: + - pathPrefix: / + pathType: PathPrefix # ============================================================================= # KubeRay Operator