Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
50f75ee
feat: add new must-gather chart
rm3l Mar 11, 2026
b673df4
Add README template and apply pre-commit hooks
rm3l Mar 11, 2026
c36f8a0
add test hook template
rm3l Mar 11, 2026
a1e7a95
ci: add a set of relevant test values files for CI
rm3l Mar 11, 2026
fe503b6
add values.schema.tmpl.json and generate from pre-commit hooks
rm3l Mar 11, 2026
697a5d0
fix: address SonarCloud warnings
rm3l Mar 11, 2026
9f68b8d
run pre-commit hooks
rm3l Mar 11, 2026
bed5953
fix: address SonarCloud warnings
rm3l Mar 11, 2026
ab6fd71
fix log level value and validation
rm3l Mar 11, 2026
81023d7
fix: fix RBAC for pods/exec to work properly when running against K8s
rm3l Mar 11, 2026
2d282d7
ensure a new Job is created each time the Helm release is upgraded
rm3l Mar 12, 2026
7359a13
fix field in CI values
rm3l Mar 12, 2026
bde908d
handle logLevel parameter correctly
rm3l Mar 12, 2026
a7a75ec
make gather.namespaces an array instead to simplify config
rm3l Mar 12, 2026
b30421a
set podSecurityContext and container security context to improve secu…
rm3l Mar 12, 2026
44c21b7
better handle image refs in the values file and support digests
rm3l Mar 12, 2026
eba8205
Apply suggestions from code review
rm3l Mar 12, 2026
d5056a6
chore: conditionally set image pull policy
rm3l Mar 13, 2026
c43edf6
docs: add note about using the Chart on OCP
rm3l Mar 13, 2026
99d5c69
Simplify the whole gather logic by switching to a single Pod
rm3l Mar 13, 2026
55f1db6
fix: add missing permission to the ServiceAccount of the test pod
rm3l Mar 13, 2026
f2495ae
fix: avoid exposing SA token to containers that don't need API access
rm3l Mar 13, 2026
9ce4b1a
add missing permission to retrieve cluster version on OCP
rm3l Mar 13, 2026
213e5a4
remove fsGroup as it works correctly on both K8s and OCP
rm3l Mar 13, 2026
2412237
grant secrets get/list permission only if withSecrets or Helm collect…
rm3l Mar 16, 2026
835c46a
avoid confusive double negative fields
rm3l Mar 16, 2026
5a09172
clarify how the rbac scope affects the handling of gather.namespaces
rm3l Mar 16, 2026
a0f3cda
fix examples for setting test.image
rm3l Mar 16, 2026
2944ff3
simplify by removing '| default ...' if the field already has a defau…
rm3l Mar 16, 2026
bafe158
fix missing RBAC permissions
rm3l Mar 17, 2026
b77f552
allow users to selectively disable RBAC rules they cannot grant
rm3l Mar 18, 2026
0175764
fix missing RBAC permissions
rm3l Mar 18, 2026
cf76eff
add pods/portforward permission for heap dump collection
rm3l Mar 29, 2026
978a337
Merge remote-tracking branch 'upstream/main' into rhidp-12626-add-new…
rm3l Mar 29, 2026
34a9336
Update charts/must-gather/Chart.yaml
rm3l Mar 30, 2026
5274454
Merge branch 'main' into rhidp-12626-add-new-helm-chart-for-rhdh-must…
Fortune-Ndlovu Mar 30, 2026
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: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
.LSOverride
.idea

*.tar.gz

# helm chart dependencies
charts/*/charts/
**/charts/*.tgz
Expand Down
23 changes: 23 additions & 0 deletions charts/must-gather/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
38 changes: 38 additions & 0 deletions charts/must-gather/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
annotations:
charts.openshift.io/name: Red Hat Developer Hub Must Gather
charts.openshift.io/provider: Red Hat
charts.openshift.io/archs: x86_64
charts.openshift.io/supportURL: https://access.redhat.com/support
apiVersion: v2
name: rhdh-must-gather
description: |
A Helm chart for deploying the RHDH Must-Gather diagnostic tool on Kubernetes

type: application

# Application version - matches the must-gather tool version
appVersion: "0.2.0"

keywords:
- rhdh
- red-hat-developer-hub
- backstage
- diagnostics
- must-gather
- troubleshooting

home: https://github.com/redhat-developer/rhdh-must-gather
sources:
- https://github.com/redhat-developer/rhdh-must-gather

kubeVersion: ">= 1.27.0-0"
maintainers:
- name: Red Hat
url: https://redhat.com

# 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/)
# Note that when this chart is published to https://github.com/openshift-helm-charts/charts
# it will follow the RHDH versioning 1.y.z
version: 0.1.0
151 changes: 151 additions & 0 deletions charts/must-gather/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@

# Must Gather Chart for Red Hat Developer Hub (RHDH)

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

A Helm chart for deploying the RHDH Must-Gather diagnostic tool on Kubernetes

**Homepage:** <https://github.com/redhat-developer/rhdh-must-gather>

## Maintainers

| Name | Email | Url |
| ---- | ------ | --- |
| Red Hat | | <https://redhat.com> |

## Source Code

* <https://github.com/redhat-developer/rhdh-must-gather>

## Requirements

Kubernetes: `>= 1.27.0-0`

## TL;DR

```console
helm upgrade --install my-rhdh-must-gather rhdh-must-gather \
--repo https://redhat-developer.github.io/rhdh-chart \
--version 0.1.0
Comment thread
rm3l marked this conversation as resolved.
```

Running the command again will automatically replace the previous pod and start a new gather.

Then follow the instructions that will be printed to retrieve the gathered data.

## Running on OpenShift

This chart works on both Kubernetes and OpenShift.

But for OpenShift, we recommend using the `oc adm must-gather` command, like so:

```sh
oc adm must-gather --image=quay.io/rhdh-community/rhdh-must-gather
```

See the [must-gather tool README](https://github.com/redhat-developer/rhdh-must-gather#for-openshift-clusters) for more details.

## Testing a Release

Once a Helm Release has been deployed, you can test it using the [`helm test`](https://helm.sh/docs/helm/helm_test/) command:

```sh
helm test <release_name>
```

This will run a simple Pod in the cluster to check that the required resources have been created.

You can control whether to disable this test pod or you can also customize the image it leverages.
See the `test.enabled` and `test.image` parameters in the [`values.yaml`](./values.yaml) file.

> **Tip**: Disabling the test pod will not prevent the `helm test` command from passing later on. It will simply report that no test suite is available.

Below are a few examples:

<details>

<summary>Disabling the test pod</summary>

```sh
helm install <release_name> <repo> \
--set test.enabled=false
```

</details>

<details>

<summary>Customizing the test pod image</summary>

```sh
helm install <release_name> <repo> \
--set test.image.registry=docker.io \
--set test.image.repository=bitnami/kubectl \
--set test.image.tag=1.30.0
```
Comment thread
rm3l marked this conversation as resolved.

</details>

## Uninstalling the Chart

To uninstall/delete a Helm release named `my-rhdh-must-gather`:

```console
helm uninstall my-rhdh-must-gather
```

The command removes all the Kubernetes resources associated with the chart and deletes the release.

## Values

| Key | Description | Type | Default |
|-----|-------------|------|---------|
| affinity | Affinity rules for pod scheduling | object | `{}` |
| dataHolder | Runs alongside the gather container and stays alive so you can exec in and retrieve the output. | object | `{"resources":{"limits":{"cpu":"100m","ephemeral-storage":"64Mi","memory":"128Mi"},"requests":{"cpu":"50m","ephemeral-storage":"32Mi","memory":"64Mi"}}}` |
| dataHolder.resources | Resource requests and limits for the data-holder container | object | `{"limits":{"cpu":"100m","ephemeral-storage":"64Mi","memory":"128Mi"},"requests":{"cpu":"50m","ephemeral-storage":"32Mi","memory":"64Mi"}}` |
| fullnameOverride | | string | `""` |
| gather | Gather script configuration | object | `{"clusterInfo":false,"cmdTimeout":"30","extraArgs":[],"logLevel":"info","namespaces":[],"since":"","sinceTime":"","withHeapDumps":false,"withHelm":true,"withIngress":true,"withNamespaceInspect":true,"withOperator":true,"withOrchestrator":true,"withPlatform":true,"withRoute":true,"withSecrets":false}` |
| gather.cmdTimeout | Command timeout for individual kubectl/helm commands (seconds) | string | `"30"` |
| gather.extraArgs | Additional custom arguments to pass to the gather script | list | `[]` |
| gather.logLevel | Log level: info, INFO, debug, DEBUG, trace, TRACE | string | `"info"` |
| gather.namespaces | Example: ["rhdh-prod", "rhdh-staging"] | list | `[]` |
| gather.since | Relative time for log collection (e.g., "2h", "30m") | string | `""` |
| gather.sinceTime | Absolute timestamp for log collection (RFC3339 format) | string | `""` |
| gather.withOperator | Collection features (enabled by default; set to false to skip) | bool | `true` |
| gather.withSecrets | Optional collection features (disabled by default) | bool | `false` |
| image | Container image configuration | object | `{"digest":"","pullPolicy":"","registry":"quay.io","repository":"rhdh-community/rhdh-must-gather","tag":"latest"}` |
| image.digest | Image digest (e.g., sha256:abc123...). Can be used with or without tag. | string | `""` |
| image.tag | Overrides the image tag whose default is the chart appVersion. | string | `"latest"` |
| imagePullSecrets | Secrets for pulling images from a private registry | list | `[]` |
| nameOverride | Override the chart name | string | `""` |
| nodeSelector | Node selector for pod scheduling | object | `{}` |
| persistence | Persistent volume configuration for storing gathered data | object | `{"accessMode":"ReadWriteOnce","size":"1Gi","storageClass":""}` |
| persistence.accessMode | Access mode | string | `"ReadWriteOnce"` |
| persistence.size | Storage size | string | `"1Gi"` |
| persistence.storageClass | Storage class (empty = use cluster default) | string | `""` |
| podAnnotations | Pod annotations | object | `{}` |
| podLabels | Pod labels | object | `{}` |
| podSecurityContext | Pod security context | object | `{"runAsNonRoot":true,"seccompProfile":{"type":"RuntimeDefault"}}` |
| rbac | RBAC configuration | object | `{"create":true,"rules":{"backstages":true,"ingresses":true,"knative":true,"olm":true,"platform":true,"routes":true,"sonataflow":true},"scope":"cluster"}` |
| rbac.create | Create RBAC resources (Role/ClusterRole and bindings) | bool | `true` |
| rbac.rules | a rule here does not require disabling the corresponding gather.with* flag. | object | `{"backstages":true,"ingresses":true,"knative":true,"olm":true,"platform":true,"routes":true,"sonataflow":true}` |
| rbac.rules.backstages | rhdh.redhat.com — Backstage custom resources | bool | `true` |
| rbac.rules.ingresses | networking.k8s.io — Ingresses, NetworkPolicies | bool | `true` |
| rbac.rules.knative | operator.knative.dev, operator.serverless.openshift.io — Knative/Serverless | bool | `true` |
| rbac.rules.olm | operators.coreos.com — OLM resources (subscriptions, CSVs, etc.) | bool | `true` |
| rbac.rules.platform | config.openshift.io — ClusterVersions, Infrastructures (cluster scope only) | bool | `true` |
| rbac.rules.routes | route.openshift.io — OpenShift Routes | bool | `true` |
| rbac.rules.sonataflow | sonataflow.org — SonataFlow custom resources | bool | `true` |
| resources | Resource requests and limits for the gather container | object | `{"limits":{"cpu":"500m","ephemeral-storage":"128Mi","memory":"512Mi"},"requests":{"cpu":"100m","ephemeral-storage":"64Mi","memory":"128Mi"}}` |
| securityContext | Container security context | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]}}` |
| serviceAccount | Service account configuration | object | `{"annotations":{},"name":"","tokenExpirationSeconds":3600}` |
| serviceAccount.annotations | Annotations to add to the service account | object | `{}` |
| serviceAccount.name | If not set, a name is generated using the fullname template. | string | `""` |
| serviceAccount.tokenExpirationSeconds | into the gather init container (minimum 600). | int | `3600` |
| strategy | Deployment strategy | object | `{"type":"Recreate"}` |
| test | Helm test configuration | object | `{"enabled":true,"image":{"digest":"","pullPolicy":"","registry":"docker.io","repository":"bitnami/kubectl","tag":"latest"}}` |
| test.enabled | Enable the Helm test | bool | `true` |
| test.image | Image for the test pod | object | `{"digest":"","pullPolicy":"","registry":"docker.io","repository":"bitnami/kubectl","tag":"latest"}` |
| tolerations | Tolerations for pod scheduling | list | `[]` |

93 changes: 93 additions & 0 deletions charts/must-gather/README.md.gotmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Must Gather Chart for Red Hat Developer Hub (RHDH)

{{ template "chart.deprecationWarning" . }}

{{ template "chart.versionBadge" . }}
{{ template "chart.typeBadge" . }}

{{ template "chart.description" . }}

{{ template "chart.homepageLine" . }}

{{ template "chart.maintainersSection" . }}

{{ template "chart.sourcesSection" . }}

{{ template "chart.requirementsSection" . }}

## TL;DR

```console
helm upgrade --install my-rhdh-must-gather rhdh-must-gather \
--repo https://redhat-developer.github.io/rhdh-chart \
--version {{ template "chart.version" . }}
Comment thread
rm3l marked this conversation as resolved.
```

Running the command again will automatically replace the previous pod and start a new gather.

Then follow the instructions that will be printed to retrieve the gathered data.

## Running on OpenShift

This chart works on both Kubernetes and OpenShift.

But for OpenShift, we recommend using the `oc adm must-gather` command, like so:

```sh
oc adm must-gather --image=quay.io/rhdh-community/rhdh-must-gather
```

See the [must-gather tool README](https://github.com/redhat-developer/rhdh-must-gather#for-openshift-clusters) for more details.

## Testing a Release

Once a Helm Release has been deployed, you can test it using the [`helm test`](https://helm.sh/docs/helm/helm_test/) command:

```sh
helm test <release_name>
```

This will run a simple Pod in the cluster to check that the required resources have been created.

You can control whether to disable this test pod or you can also customize the image it leverages.
See the `test.enabled` and `test.image` parameters in the [`values.yaml`](./values.yaml) file.

> **Tip**: Disabling the test pod will not prevent the `helm test` command from passing later on. It will simply report that no test suite is available.

Below are a few examples:

<details>

<summary>Disabling the test pod</summary>

```sh
helm install <release_name> <repo> \
--set test.enabled=false
```

</details>

<details>

<summary>Customizing the test pod image</summary>

```sh
helm install <release_name> <repo> \
--set test.image.registry=docker.io \
--set test.image.repository=bitnami/kubectl \
--set test.image.tag=1.30.0
```

</details>

## Uninstalling the Chart

To uninstall/delete a Helm release named `my-rhdh-must-gather`:

```console
helm uninstall my-rhdh-must-gather
```

The command removes all the Kubernetes resources associated with the chart and deletes the release.

{{ template "chart.valuesSection" . }}
1 change: 1 addition & 0 deletions charts/must-gather/ci/default-values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Default values — tests the chart with all defaults
8 changes: 8 additions & 0 deletions charts/must-gather/ci/with-minimal-collection-values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Minimal collection — skip optional components to speed up gathering
gather:
withOperator: false
withOrchestrator: false
withHelm: false
withRoute: false
withIngress: false
logLevel: "TRACE"
9 changes: 9 additions & 0 deletions charts/must-gather/ci/with-namespace-rbac-values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Namespace-scoped RBAC — creates a Role instead of a ClusterRole.
# Collection is restricted to the release namespace only;
# gather.namespaces is ignored in this mode.
rbac:
scope: namespace
gather:
# NOTE: this field will be ignored when rbac.scope is "namespace".
namespaces:
- "kube-system"
6 changes: 6 additions & 0 deletions charts/must-gather/ci/with-namespace-scoped-values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Scope collection to specific namespaces
gather:
namespaces:
- "rhdh-prod"
- "rhdh-staging"
since: "2h"
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Collect secrets (sanitized) and cluster-level info
gather:
withSecrets: true
clusterInfo: true
logLevel: "DEBUG"
3 changes: 3 additions & 0 deletions charts/must-gather/ci/with-test-disabled-values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Helm test disabled
test:
enabled: false
32 changes: 32 additions & 0 deletions charts/must-gather/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
-------------------------------------------------------------------
RHDH Must-Gather is now running. This might take a few minutes.

To check the gather logs:
kubectl -n {{ .Release.Namespace }} logs -l app.kubernetes.io/instance={{ .Release.Name }},app.kubernetes.io/component=gather -c gather -f

To retrieve the gathered diagnostic data once the gather completes:

1. Wait for the pod to be ready (gather init container completed):
kubectl -n {{ .Release.Namespace }} wait --for=condition=ready pod -l app.kubernetes.io/instance={{ .Release.Name }},app.kubernetes.io/component=gather --timeout=3600s

2. Download the gathered data from the data-holder container:
kubectl -n {{ .Release.Namespace }} exec deploy/{{ include "rhdh-must-gather.fullname" . }} -c data-holder -- tar czf - -C /must-gather . > rhdh-must-gather-output.tar.gz

To clean up the must-gather resources:
helm uninstall {{ .Release.Name }} -n {{ .Release.Namespace }}

Configuration used:
- Log level: {{ .Values.gather.logLevel | lower }}
- Storage size: {{ .Values.persistence.size }}
{{- if .Values.gather.namespaces }}
- Target namespaces: {{ .Values.gather.namespaces | join ", " }}
{{- end }}
{{- if .Values.gather.withSecrets }}
- Secrets collection: enabled (sanitized)
{{- end }}
{{- if .Values.gather.withHeapDumps }}
- Heap dump collection: enabled
{{- end }}

For more information, visit: https://github.com/redhat-developer/rhdh-must-gather
-------------------------------------------------------------------
Loading
Loading