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/rhdh/Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
apiVersion: v2
name: redhat-developer-hub
type: application
version: 2.4.1
version: 2.5.0
appVersion: 2.1.0
annotations:
artifacthub.io/category: integration-delivery
Expand Down
20 changes: 15 additions & 5 deletions charts/rhdh/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

# RHDH Helm Chart for OpenShift and Kubernetes

![Version: 2.4.1](https://img.shields.io/badge/Version-2.4.1-informational?style=flat-square)
![Version: 2.5.0](https://img.shields.io/badge/Version-2.5.0-informational?style=flat-square)
![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square)

A Helm chart for deploying Red Hat Developer Hub, which is a Red Hat supported version of Backstage.
Expand Down Expand Up @@ -36,7 +36,7 @@ For the **Generally Available** version of this chart, see:
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add redhat-developer https://redhat-developer.github.io/rhdh-chart

helm install my-rhdh redhat-developer/redhat-developer-hub --version 2.4.1
helm install my-rhdh redhat-developer/redhat-developer-hub --version 2.5.0
```

## Introduction
Expand Down Expand Up @@ -243,7 +243,7 @@ Kubernetes: `>= 1.31.0-0`
| image.digest | Overrides the image tag with an image digest. | string | `""` |
| imagePullSecrets | Secrets for pulling images from private registries (merged with global.imagePullSecrets). | list | `[]` |
| ingress | Kubernetes Ingress configuration. | object | `{"annotations":{},"className":"","enabled":false,"hosts":[{"host":"{{ .Values.host }}","paths":[{"path":"/","pathType":"ImplementationSpecific"}]}],"tls":[]}` |
| intelligentAssistant | Built-in Intelligent Assistant feature configuration. | object | `{"config":{"profile":{"existingConfigMap":{"key":"","name":""}},"stack":{"existingConfigMap":{"key":"","name":""}}},"core":{"argsOverride":[],"commandOverride":[],"extraArgs":[],"extraEnv":[],"extraVolumeMounts":[],"image":{"digest":"","registry":"quay.io","repository":"lightspeed-core/lightspeed-stack","tag":"dev-20260824-cbd182b"},"imagePullPolicy":"IfNotPresent","resources":{"limits":{"cpu":"1000m","memory":"2Gi"},"requests":{"cpu":"100m","memory":"512Mi"}},"securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true,"runAsNonRoot":true,"seccompProfile":{"type":"RuntimeDefault"}}},"enabled":true,"existingSecret":"","okp":{"affinity":{},"httpd":{"compressed":"true","encrypt":"false","serverName":"localhost"},"image":{"digest":"","pullPolicy":"IfNotPresent","registry":"registry.redhat.io","repository":"offline-knowledge-portal/rhokp-rhel9","tag":"1.2.12-1788274041"},"imagePullSecrets":[],"ingress":{"annotations":{},"className":"","enabled":true,"host":"","tls":{"enabled":false,"secretName":""}},"livenessProbe":{"initialDelaySeconds":30,"periodSeconds":30},"nodeSelector":{},"readinessProbe":{"initialDelaySeconds":10,"periodSeconds":10},"replicaCount":1,"resources":{"limits":{"cpu":"2","memory":"4Gi"},"requests":{"cpu":"200m","memory":"2Gi"}},"route":{"enabled":true,"tls":{"insecureEdgeTerminationPolicy":"Redirect","termination":"edge"}},"securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"runAsNonRoot":true,"seccompProfile":{"type":"RuntimeDefault"}},"service":{"type":"ClusterIP"},"solr":{"hostBind":"0.0.0.0","memory":"1g"},"tolerations":[],"topologySpreadConstraints":[]},"plugins":[{"enabled":true,"package":"ref://red-hat-developer-hub-backstage-plugin-intelligent-assistant"},{"enabled":true,"package":"ref://red-hat-developer-hub-backstage-plugin-intelligent-assistant-backend"}],"runtimeVolume":{"emptyDir":{},"persistentVolumeClaim":{},"type":"emptyDir"}}` |
| intelligentAssistant | Built-in Intelligent Assistant feature configuration. | object | `{"config":{"profile":{"existingConfigMap":{"key":"","name":""}},"stack":{"existingConfigMap":{"key":"","name":""}}},"core":{"argsOverride":[],"commandOverride":[],"extraArgs":[],"extraEnv":[],"extraVolumeMounts":[],"image":{"digest":"","registry":"quay.io","repository":"lightspeed-core/lightspeed-stack","tag":"dev-20260824-cbd182b"},"imagePullPolicy":"IfNotPresent","resources":{"limits":{"cpu":"1000m","memory":"2Gi"},"requests":{"cpu":"100m","memory":"512Mi"}},"securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true,"runAsNonRoot":true,"seccompProfile":{"type":"RuntimeDefault"}}},"enabled":true,"existingSecret":"","okp":{"affinity":{},"enabled":false,"httpd":{"compressed":"true","encrypt":"false","serverName":"localhost"},"image":{"digest":"","pullPolicy":"IfNotPresent","registry":"registry.redhat.io","repository":"offline-knowledge-portal/rhokp-rhel9","tag":"1.2.12-1788274041"},"imagePullSecrets":[],"ingress":{"annotations":{},"className":"","enabled":true,"host":"","tls":{"enabled":false,"secretName":""}},"livenessProbe":{"initialDelaySeconds":30,"periodSeconds":30},"nodeSelector":{},"readinessProbe":{"initialDelaySeconds":10,"periodSeconds":10},"replicaCount":1,"resources":{"limits":{"cpu":"2","memory":"4Gi"},"requests":{"cpu":"200m","memory":"2Gi"}},"route":{"enabled":true,"tls":{"insecureEdgeTerminationPolicy":"Redirect","termination":"edge"}},"securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"runAsNonRoot":true,"seccompProfile":{"type":"RuntimeDefault"}},"service":{"type":"ClusterIP"},"solr":{"hostBind":"0.0.0.0","memory":"1g"},"tolerations":[],"topologySpreadConstraints":[]},"plugins":[{"enabled":true,"package":"ref://red-hat-developer-hub-backstage-plugin-intelligent-assistant"},{"enabled":true,"package":"ref://red-hat-developer-hub-backstage-plugin-intelligent-assistant-backend"}],"runtimeVolume":{"emptyDir":{},"persistentVolumeClaim":{},"type":"emptyDir"}}` |
| intelligentAssistant.config | Configuration files mounted into the sidecar. By default, the chart creates ConfigMaps from bundled source files. Set existingConfigMap to use a pre-existing ConfigMap instead. | object | `{"profile":{"existingConfigMap":{"key":"","name":""}},"stack":{"existingConfigMap":{"key":"","name":""}}}` |
| intelligentAssistant.config.profile | Python profile with prompt templates (rhdh-profile.py). | object | `{"existingConfigMap":{"key":"","name":""}}` |
| intelligentAssistant.config.profile.existingConfigMap | Use an existing ConfigMap instead of the bundled default. | object | Created from bundled rhdh-profile.py |
Expand All @@ -258,8 +258,9 @@ Kubernetes: `>= 1.31.0-0`
| intelligentAssistant.core.commandOverride | Override the container's default command. Leave empty to use the image entrypoint. | list | `[]` |
| intelligentAssistant.core.extraArgs | Extra arguments appended after the default arguments. Ignored when argsOverride is set. | list | `[]` |
| intelligentAssistant.existingSecret | Name of an existing Secret that supplies credentials and settings to the lightspeed-core container. Configure the provider itself in lightspeed-stack.yaml. If empty, no Secret is loaded. Expected keys (all optional; include only keys used by the configured provider): VLLM_URL, VLLM_API_KEY, VLLM_MAX_TOKENS, VLLM_TLS_VERIFY, OPENAI_API_KEY, VERTEX_AI_PROJECT, VERTEX_AI_LOCATION, GOOGLE_APPLICATION_CREDENTIALS, ENABLE_VALIDATION, VALIDATION_PROVIDER, VALIDATION_MODEL_NAME Set ENABLE_VALIDATION to question_validity to enable validation. GOOGLE_APPLICATION_CREDENTIALS must be a path to a credentials file mounted in the sidecar. See files/intelligent-assistant/secret.example.yaml for a reference template. | string | `""` |
| intelligentAssistant.okp | OKP (Offline Knowledge Portal) configuration. Deploys an OKP instance for document retrieval when Intelligent Assistant is enabled. | object | `{"affinity":{},"httpd":{"compressed":"true","encrypt":"false","serverName":"localhost"},"image":{"digest":"","pullPolicy":"IfNotPresent","registry":"registry.redhat.io","repository":"offline-knowledge-portal/rhokp-rhel9","tag":"1.2.12-1788274041"},"imagePullSecrets":[],"ingress":{"annotations":{},"className":"","enabled":true,"host":"","tls":{"enabled":false,"secretName":""}},"livenessProbe":{"initialDelaySeconds":30,"periodSeconds":30},"nodeSelector":{},"readinessProbe":{"initialDelaySeconds":10,"periodSeconds":10},"replicaCount":1,"resources":{"limits":{"cpu":"2","memory":"4Gi"},"requests":{"cpu":"200m","memory":"2Gi"}},"route":{"enabled":true,"tls":{"insecureEdgeTerminationPolicy":"Redirect","termination":"edge"}},"securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"runAsNonRoot":true,"seccompProfile":{"type":"RuntimeDefault"}},"service":{"type":"ClusterIP"},"solr":{"hostBind":"0.0.0.0","memory":"1g"},"tolerations":[],"topologySpreadConstraints":[]}` |
| intelligentAssistant.okp | OKP (Offline Knowledge Portal) configuration. Deploys an OKP instance for RHDH documentation retrieval when explicitly enabled. The image is large and can significantly increase initial installation time. | object | `{"affinity":{},"enabled":false,"httpd":{"compressed":"true","encrypt":"false","serverName":"localhost"},"image":{"digest":"","pullPolicy":"IfNotPresent","registry":"registry.redhat.io","repository":"offline-knowledge-portal/rhokp-rhel9","tag":"1.2.12-1788274041"},"imagePullSecrets":[],"ingress":{"annotations":{},"className":"","enabled":true,"host":"","tls":{"enabled":false,"secretName":""}},"livenessProbe":{"initialDelaySeconds":30,"periodSeconds":30},"nodeSelector":{},"readinessProbe":{"initialDelaySeconds":10,"periodSeconds":10},"replicaCount":1,"resources":{"limits":{"cpu":"2","memory":"4Gi"},"requests":{"cpu":"200m","memory":"2Gi"}},"route":{"enabled":true,"tls":{"insecureEdgeTerminationPolicy":"Redirect","termination":"edge"}},"securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"runAsNonRoot":true,"seccompProfile":{"type":"RuntimeDefault"}},"service":{"type":"ClusterIP"},"solr":{"hostBind":"0.0.0.0","memory":"1g"},"tolerations":[],"topologySpreadConstraints":[]}` |
| intelligentAssistant.okp.affinity | Pod scheduling: affinity rules for the OKP pod. | object | `{}` |
| intelligentAssistant.okp.enabled | Enable OKP-backed RHDH documentation retrieval. Disabled by default on all platforms. | bool | `false` |
| intelligentAssistant.okp.imagePullSecrets | Image pull secrets for the OKP container image. Required on vanilla Kubernetes to authenticate with registry.redhat.io. Not needed on OpenShift where the cluster-wide pull secret covers Red Hat registries. | list | `[]` |
| intelligentAssistant.okp.livenessProbe | Liveness probe configuration for the OKP container. | object | `{"initialDelaySeconds":30,"periodSeconds":30}` |
| intelligentAssistant.okp.nodeSelector | Pod scheduling: node selector for the OKP pod. | object | `{}` |
Expand Down Expand Up @@ -412,7 +413,7 @@ For detailed information on configuring the catalog index, including how to over

### NetworkPolicies

This chart deploys a **default-deny** NetworkPolicy for the RHDH backend pod, blocking all ingress and egress traffic that is not explicitly allowed. When the built-in PostgreSQL is enabled (`postgresql.enabled=true`), the database pods also get their own default-deny policy with selective allow rules.
This chart deploys a **default-deny** NetworkPolicy for the RHDH backend pod, blocking all ingress and egress traffic that is not explicitly allowed. When the built-in PostgreSQL is enabled (`postgresql.enabled=true`), the database pods also get their own default-deny policy with selective allow rules. When OKP is active, its pods receive a separate default-deny ingress and egress policy with rules allowing only the required HTTP ingress.

The following traffic is allowed out of the box:

Expand All @@ -422,9 +423,16 @@ The following traffic is allowed out of the box:
| Egress | 443 (TCP) | Any | HTTPS (Git forges, auth providers, external APIs) |
| Egress | 5432 (TCP) | Built-in PostgreSQL pods (scoped) or any (external DB) | Database access |
| Egress | 6379 (TCP) | Any | Redis (BYO — no pod/namespace selector) |
| Egress | 80 (TCP) | Any destination | LCORE access to an HTTP OKP Ingress |
| Egress | 8080 (TCP) | OKP pods | LCORE access to the internal OKP Service fallback |
| Ingress | 7007 (TCP) | OpenShift router namespace or any namespace (non-OCP) | User traffic via Route / Ingress |
| Ingress | 8080 (TCP) | RHDH pods and the OpenShift router namespace or any namespace (non-OCP) | OKP queries and product-document citations via Route / Ingress |
| Ingress | 9464 (TCP) | `openshift-monitoring`, `openshift-user-workload-monitoring`, `gmp-system`, `gke-gmp-system`, `monitoring` | Prometheus metrics scraping |

OKP initiates no outbound connections: its HTTP server and Solr process run in the same pod and serve the documentation embedded in the image. Its default-deny policy therefore blocks all new egress connections. NetworkPolicy is stateful, so response traffic for allowed ingress connections remains permitted.

RHDH already permits HTTPS egress on port 443. When OKP uses HTTP instead, the chart permits RHDH egress on port 80 for a Kubernetes Ingress or restricts port 8080 egress to OKP pods for the internal Service fallback. No additional RHDH egress policy is created when `OKP_SERVICE_URL` uses HTTPS.

**Redis egress is intentionally unscoped.** RHDH does not deploy Redis; users bring their own instance, which may live in the same namespace, a different namespace, or an external managed service. The rule therefore allows egress on port 6379 to any destination.

**Bitnami subchart NetworkPolicies are disabled** (`postgresql.primary.networkPolicy.enabled=false`, `postgresql.readReplicas.networkPolicy.enabled=false`) because this chart provides its own tighter policies for the built-in database pods.
Expand Down Expand Up @@ -453,6 +461,8 @@ When using the built-in Intelligent Assistant feature, do not also keep those pl

The Lightspeed Core sidecar loads `intelligentAssistant.existingSecret` as environment variables. If you update that Secret outside of Helm, Kubernetes does not guarantee that the Backstage Pod restarts automatically. Use a no-op `helm upgrade` or manually restart the Backstage deployment after changing the secret data.

RHDH documentation retrieval is disabled by default in Intelligent Assistant. To enable it, set `intelligentAssistant.okp.enabled=true`. This deploys the OKP workload and uses the OKP-enabled Lightspeed Stack configuration. The OKP container image is large, so enabling it can significantly increase the initial installation time while the image is downloaded. On vanilla Kubernetes, you must also configure the OKP Ingress and Red Hat registry credentials. See [Intelligent Assistant and OKP integration](../../docs/intelligent-assistant.md) for platform-specific configuration.

### Vanilla Kubernetes compatibility mode

To deploy this chart on vanilla Kubernetes or any other non-OCP platform, apply the following changes. Note that further customizations might be required, depending on your exact Kubernetes setup:
Expand Down
11 changes: 10 additions & 1 deletion charts/rhdh/README.md.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ For detailed information on configuring the catalog index, including how to over

### NetworkPolicies

This chart deploys a **default-deny** NetworkPolicy for the RHDH backend pod, blocking all ingress and egress traffic that is not explicitly allowed. When the built-in PostgreSQL is enabled (`postgresql.enabled=true`), the database pods also get their own default-deny policy with selective allow rules.
This chart deploys a **default-deny** NetworkPolicy for the RHDH backend pod, blocking all ingress and egress traffic that is not explicitly allowed. When the built-in PostgreSQL is enabled (`postgresql.enabled=true`), the database pods also get their own default-deny policy with selective allow rules. When OKP is active, its pods receive a separate default-deny ingress and egress policy with rules allowing only the required HTTP ingress.

The following traffic is allowed out of the box:

Expand All @@ -267,9 +267,16 @@ The following traffic is allowed out of the box:
| Egress | 443 (TCP) | Any | HTTPS (Git forges, auth providers, external APIs) |
| Egress | 5432 (TCP) | Built-in PostgreSQL pods (scoped) or any (external DB) | Database access |
| Egress | 6379 (TCP) | Any | Redis (BYO — no pod/namespace selector) |
| Egress | 80 (TCP) | Any destination | LCORE access to an HTTP OKP Ingress |
| Egress | 8080 (TCP) | OKP pods | LCORE access to the internal OKP Service fallback |
| Ingress | 7007 (TCP) | OpenShift router namespace or any namespace (non-OCP) | User traffic via Route / Ingress |
| Ingress | 8080 (TCP) | RHDH pods and the OpenShift router namespace or any namespace (non-OCP) | OKP queries and product-document citations via Route / Ingress |
| Ingress | 9464 (TCP) | `openshift-monitoring`, `openshift-user-workload-monitoring`, `gmp-system`, `gke-gmp-system`, `monitoring` | Prometheus metrics scraping |

OKP initiates no outbound connections: its HTTP server and Solr process run in the same pod and serve the documentation embedded in the image. Its default-deny policy therefore blocks all new egress connections. NetworkPolicy is stateful, so response traffic for allowed ingress connections remains permitted.

RHDH already permits HTTPS egress on port 443. When OKP uses HTTP instead, the chart permits RHDH egress on port 80 for a Kubernetes Ingress or restricts port 8080 egress to OKP pods for the internal Service fallback. No additional RHDH egress policy is created when `OKP_SERVICE_URL` uses HTTPS.

**Redis egress is intentionally unscoped.** RHDH does not deploy Redis; users bring their own instance, which may live in the same namespace, a different namespace, or an external managed service. The rule therefore allows egress on port 6379 to any destination.

**Bitnami subchart NetworkPolicies are disabled** (`postgresql.primary.networkPolicy.enabled=false`, `postgresql.readReplicas.networkPolicy.enabled=false`) because this chart provides its own tighter policies for the built-in database pods.
Expand Down Expand Up @@ -298,6 +305,8 @@ When using the built-in Intelligent Assistant feature, do not also keep those pl

The Lightspeed Core sidecar loads `intelligentAssistant.existingSecret` as environment variables. If you update that Secret outside of Helm, Kubernetes does not guarantee that the Backstage Pod restarts automatically. Use a no-op `helm upgrade` or manually restart the Backstage deployment after changing the secret data.

RHDH documentation retrieval is disabled by default in Intelligent Assistant. To enable it, set `intelligentAssistant.okp.enabled=true`. This deploys the OKP workload and uses the OKP-enabled Lightspeed Stack configuration. The OKP container image is large, so enabling it can significantly increase the initial installation time while the image is downloaded. On vanilla Kubernetes, you must also configure the OKP Ingress and Red Hat registry credentials. See [Intelligent Assistant and OKP integration](../../docs/intelligent-assistant.md) for platform-specific configuration.

### Vanilla Kubernetes compatibility mode

To deploy this chart on vanilla Kubernetes or any other non-OCP platform, apply the following changes. Note that further customizations might be required, depending on your exact Kubernetes setup:
Expand Down
7 changes: 4 additions & 3 deletions charts/rhdh/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -320,12 +320,13 @@ imagePullSecrets:

{{/*
Return whether OKP should be deployed.
On OpenShift (openshift.route.enabled): active when IA is enabled and okp.route.enabled is true.
On vanilla K8s: only active when okp.ingress.enabled is true and okp.ingress.host is set.
OKP must be explicitly enabled on every platform.
On OpenShift (openshift.route.enabled): also requires okp.route.enabled.
On vanilla K8s: also requires okp.ingress.enabled and a non-empty okp.ingress.host.
*/}}
{{- define "rhdh.intelligentAssistant.okp.active" -}}
{{- $ia := include "rhdh.intelligentAssistant" . | fromYaml -}}
{{- if and $ia.enabled (or (and .Values.openshift.route.enabled $ia.okp.route.enabled) (and (not .Values.openshift.route.enabled) $ia.okp.ingress.enabled $ia.okp.ingress.host)) -}}
{{- if and $ia.enabled $ia.okp.enabled (or (and .Values.openshift.route.enabled $ia.okp.route.enabled) (and (not .Values.openshift.route.enabled) $ia.okp.ingress.enabled $ia.okp.ingress.host)) -}}
true
{{- end -}}
{{- end -}}
Expand Down
Loading
Loading