{"id":31715321,"url":"https://github.com/rm3l/rhdh-must-gather","last_synced_at":"2025-10-09T01:56:08.176Z","repository":{"id":314345523,"uuid":"1042355369","full_name":"rm3l/rhdh-must-gather","owner":"rm3l","description":null,"archived":false,"fork":false,"pushed_at":"2025-09-11T22:28:11.000Z","size":537,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-12T00:24:46.934Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rm3l.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-21T22:15:14.000Z","updated_at":"2025-09-11T22:28:15.000Z","dependencies_parsed_at":"2025-09-12T00:24:49.591Z","dependency_job_id":"6e6ba08c-0561-4249-8f29-c1852dc43c91","html_url":"https://github.com/rm3l/rhdh-must-gather","commit_stats":null,"previous_names":["rm3l/rhdh-must-gather"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/rm3l/rhdh-must-gather","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rm3l%2Frhdh-must-gather","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rm3l%2Frhdh-must-gather/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rm3l%2Frhdh-must-gather/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rm3l%2Frhdh-must-gather/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rm3l","download_url":"https://codeload.github.com/rm3l/rhdh-must-gather/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rm3l%2Frhdh-must-gather/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279000696,"owners_count":26082894,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-08T02:00:06.501Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-10-09T01:56:06.513Z","updated_at":"2025-10-09T01:56:08.165Z","avatar_url":"https://github.com/rm3l.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# RHDH Must-Gather Tool (WIP)\n\nA specialized diagnostic data collection tool for Red Hat Developer Hub (RHDH) deployments on Kubernetes and OpenShift clusters.\n\n## Overview\n\nThis tool helps support teams and engineers collect essential RHDH-specific information to troubleshoot issues effectively. It focuses exclusively on RHDH resources and can be combined with generic cluster information collection. It supports:\n\n- **Multi-platform**: OpenShift and standard Kubernetes (AKS, GKE, EKS)\n- **Multi-deployment**: Helm-based and Operator-based RHDH instances\n- **RHDH-focused collection**: Only RHDH-specific logs, configurations, and resources\n- **Privacy-aware**: Automatic sanitization of secrets, tokens, and sensitive data (WIP)\n\n\u003e **Note**: This tool collects only RHDH-specific data. For cluster-wide general information, use the generic OpenShift must-gather: `oc adm must-gather`\n\n## Quick Start\n\n### Using with OpenShift (`oc adm must-gather`)\n\n```bash\n# Use the published image\noc adm must-gather --image=ghcr.io/rm3l/rhdh-must-gather:main\n\n# Collect only logs and events from last 2 hours\noc adm must-gather --image=ghcr.io/rm3l/rhdh-must-gather:main --since=2h\n\n# Collect logs and events since specific time\noc adm must-gather --image=ghcr.io/rm3l/rhdh-must-gather:main --since-time=2025-08-21T20:00:00Z\n```\n\n### Using with Kubernetes (WIP)\n\n#### Option 1: Using PersistentVolume (Recommended)\n\n```bash\n# Create PVC for persistent storage\ncat \u003c\u003cEOF | kubectl apply -f -\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: rhdh-must-gather-pvc\nspec:\n  accessModes:\n    - ReadWriteOnce\n  resources:\n    requests:\n      storage: 1Gi\n---\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: rhdh-must-gather\nspec:\n  template:\n    spec:\n      containers:\n      - name: must-gather\n        image: ghcr.io/rm3l/rhdh-must-gather:main\n        volumeMounts:\n        - name: output\n          mountPath: /must-gather\n      volumes:\n      - name: output\n        persistentVolumeClaim:\n          claimName: rhdh-must-gather-pvc\n      restartPolicy: Never\nEOF\n\n# Wait for job completion\nkubectl wait --for=condition=complete job/rhdh-must-gather --timeout=600s\n\n# Create a temporary pod to access the data\nkubectl run data-retriever --image=busybox --rm -i --tty \\\n  --overrides='{\"spec\":{\"volumes\":[{\"name\":\"data\",\"persistentVolumeClaim\":{\"claimName\":\"rhdh-must-gather-pvc\"}}],\"containers\":[{\"name\":\"data-retriever\",\"image\":\"busybox\",\"volumeMounts\":[{\"name\":\"data\",\"mountPath\":\"/data\"}],\"stdin\":true,\"tty\":true}]}}' \\\n  -- tar -czf - -C /data . \u003e must-gather-output.tar.gz\n\n# Clean up\nkubectl delete job rhdh-must-gather\nkubectl delete pvc rhdh-must-gather-pvc\n```\n\n#### Option 2: Using initContainer with Shared Volume\n\n```bash\n# Use an init container pattern with a long-running sidecar\ncat \u003c\u003cEOF | kubectl apply -f -\napiVersion: batch/v1\nkind: Job\nmetadata:\n  name: rhdh-must-gather\nspec:\n  template:\n    spec:\n      initContainers:\n      - name: must-gather\n        image: ghcr.io/rm3l/rhdh-must-gather:main\n        volumeMounts:\n        - name: output\n          mountPath: /must-gather\n      containers:\n      - name: data-holder\n        image: busybox\n        command: [\"sleep\", \"3600\"]  # Sleep for 1 hour\n        volumeMounts:\n        - name: output\n          mountPath: /must-gather\n      volumes:\n      - name: output\n        emptyDir: {}\n      restartPolicy: Never\nEOF\n\n# Wait for init container to complete\nkubectl wait --for=condition=initialized pod -l job-name=rhdh-must-gather --timeout=600s\n\n# Copy the results\nPOD_NAME=$(kubectl get pods -l job-name=rhdh-must-gather -o jsonpath='{.items[0].metadata.name}')\nkubectl cp $POD_NAME:/must-gather ./must-gather-output\n\n# Clean up\nkubectl delete job rhdh-must-gather\n```\n\n### Local Development/Testing\n\n```bash\n# Clone the repository\ngit clone \u003crepository-url\u003e\ncd rhdh-must-gather\n\n# Run locally (requires kubectl access)\nmake test-local-all\n\n# Build and test in container\nmake build test-container\n```\n\n## What Data is Collected\n\nThis tool focuses exclusively on RHDH-related resources. For cluster-wide information, combine with generic must-gather.\n\n### Platform Information (gather_platform)\n- **Platform Detection**: Automatically identifies the Kubernetes platform type:\n    - **OpenShift**: OCP, ROSA (Red Hat OpenShift Service on AWS), ARO (Azure Red Hat OpenShift), ROKS (Red Hat OpenShift on IBM Cloud)\n    - **Managed Kubernetes**: EKS (AWS), GKE (Google Cloud), AKS (Azure)\n    - **Vanilla Kubernetes**: Standard Kubernetes installations\n- **Infrastructure Detection**: Identifies underlying cloud providers (AWS, GCP, Azure, IBM Cloud, vSphere)\n- **Version Information**: Collects OpenShift and Kubernetes version details\n\n### RHDH-Specific Data\n\n#### Helm Deployments (gather_helm)\n- **Release Information**: Helm releases, history, status (text and YAML formats)\n- **Configuration**: User-provided values, computed values, manifests, hooks, and notes\n- **Kubernetes Resources**: Deployments, StatefulSets with full YAML definitions and descriptions\n- **[Application Runtime Data](#application-runtime-data-extracted-from-running-containers)**\n- **Namespace Resources**: All ConfigMaps and Secrets (sanitized) with descriptions\n\n#### Operator Deployments (gather_operator)\n- **OLM Information**: ClusterServiceVersions, Subscriptions, InstallPlans, OperatorGroups, CatalogSources\n- **Custom Resources**: Backstage CRDs with definitions and descriptions\n- **Backstage Custom Resources**: Full CR configurations and status\n- **Operator Infrastructure**: Deployments, logs, and configurations in operator namespaces\n- **[Application Runtime Data](#application-runtime-data-extracted-from-running-containers)**\n- **Namespace Resources**: ConfigMaps and Secrets (sanitized) for each namespace containing Backstage CRs\n\n#### Application Runtime Data (extracted from running containers)\n- **RHDH version information**: `backstage.json` contains Backstage version\n- **Build metadata**: `build-metadata.json` with RHDH version, Backstage version, upstream/midstream sources, and build timestamp\n- **Node.js version**: Runtime Node.js version from `node --version`\n- **Container user ID**: Security context information from `id` command\n- **Dynamic plugins structure**: Directory listing of `dynamic-plugins-root` filesystem\n- **Generated app-config**: `app-config.dynamic-plugins.yaml` created by the dynamic plugins installer\n\n#### Dynamic Plugins and Configuration\n- **Dynamic plugins root directory** structure from filesystem (`ls -lhrta dynamic-plugins-root`)\n- **Generated app-config** from dynamic plugins installer (`app-config.dynamic-plugins.yaml`)\n- **ConfigMaps** containing app configurations and dynamic plugin definitions\n- **Plugin dependencies** and configurations including installed dynamic plugins like:\n  - Red Hat Developer Hub plugins (global-header, quickstart, dynamic-home-page, marketplace)\n  - Backstage community plugins (techdocs, scaffolder modules, analytics providers)\n  - Backend modules and frontend components\n\n#### Logs and Runtime Data\n- **Container logs** with configurable time windows (`MUST_GATHER_SINCE`, `MUST_GATHER_SINCE_TIME`)\n- **Multi-container logs**: Separate logs for `backstage-backend` and `install-dynamic-plugins` containers\n- **Database logs** from PostgreSQL StatefulSets\n- **Must-gather container logs** (when running in pod)\n\n#### RHDH Kubernetes Resources (Detailed)\n- **Deployments and StatefulSets**: Full YAML definitions and kubectl describe output\n- **Pods**: Complete pod specifications, status, and logs for all related pods\n- **ConfigMaps**: Application configurations, dynamic plugins, and other config data\n- **Secrets**: Sanitized secret resources (data fields redacted for security)\n- **Services, Routes, Ingresses**: Network configurations for RHDH access\n\n### Cluster Information (optional)\n- **Cluster-wide diagnostic dump** using `oc cluster-info dump` (enabled with `--cluster-info` flag)\n\n## Privacy and Security (WIP)\n\n### Automatic Data Sanitization\n\nThe tool includes automatic sanitization of sensitive information to make the collected data safe for sharing:\n\n**Automatically Sanitized Data:**\n- **Kubernetes Secret data values** - All `data:` fields in Secret resources are replaced with `[REDACTED]`\n- **Base64 encoded sensitive data** - Long base64 strings (40+ characters) that likely contain sensitive information\n- **JWT tokens** - Complete JWT tokens matching the standard format\n- **Bearer tokens** - Authorization headers with bearer tokens\n- **SSH private keys** - Complete SSH key blocks from BEGIN to END\n- **Database connection strings** - URLs containing embedded credentials\n- **URLs with credentials** - HTTP/HTTPS URLs with username:password@ format\n\n**Sanitization Features:**\n- **Precision targeting** - Avoids false positives on legitimate data like Kubernetes status fields\n- **Structure preservation** - Maintains YAML/JSON structure for diagnostic value\n- **Comprehensive coverage** - Processes all YAML, JSON, and text files in the collected data\n- **Detailed reporting** - Provides sanitization summary with file and item counts\n\n**Important**: While automatic sanitization catches common sensitive patterns, always review the sanitization report and manually check for any domain-specific sensitive information before sharing externally.\n\n## Configuration\n\n### Environment Variables\n\n| Variable                 | Default         | Description                                            |\n|--------------------------|-----------------|--------------------------------------------------------|\n| `BASE_COLLECTION_PATH`   | `/must-gather`  | Output directory for collected data                    |\n| `LOG_LEVEL`              | `info`          | Logging level (info, debug, trace)                     |\n| `CMD_TIMEOUT`            | `30`            | Timeout for individual kubectl/helm commands (seconds) |\n| `MUST_GATHER_SINCE`      | -               | Relative time for log collection (e.g., \"2h\", \"30m\")   |\n| `MUST_GATHER_SINCE_TIME` | -               | Absolute timestamp for log collection (RFC3339)        |\n\n### Command Line Options\n\nThe gather script accepts the following options:\n\n```bash\n# Default collection (all RHDH data: platform, helm, operator, routes, ingresses)\noc adm must-gather --image=ghcr.io/rm3l/rhdh-must-gather\n\n# Exclude specific data collection types\noc adm must-gather --image=ghcr.io/rm3l/rhdh-must-gather -- /usr/bin/gather --without-operator\noc adm must-gather --image=ghcr.io/rm3l/rhdh-must-gather -- /usr/bin/gather --without-helm\noc adm must-gather --image=ghcr.io/rm3l/rhdh-must-gather -- /usr/bin/gather --without-platform\noc adm must-gather --image=ghcr.io/rm3l/rhdh-must-gather -- /usr/bin/gather --without-route\noc adm must-gather --image=ghcr.io/rm3l/rhdh-must-gather -- /usr/bin/gather --without-ingress\n\n# Collect only specific deployment types\noc adm must-gather --image=ghcr.io/rm3l/rhdh-must-gather -- /usr/bin/gather --without-operator  # Helm only\noc adm must-gather --image=ghcr.io/rm3l/rhdh-must-gather -- /usr/bin/gather --without-helm      # Operator only\n\n# Minimal collection (platform info only)\noc adm must-gather --image=ghcr.io/rm3l/rhdh-must-gather -- /usr/bin/gather --without-operator --without-helm --without-route --without-ingress\n\n# With cluster-wide information\noc adm must-gather --image=ghcr.io/rm3l/rhdh-must-gather -- /usr/bin/gather --cluster-info\n\n# Combine exclusion flags with other options\noc adm must-gather --image=ghcr.io/rm3l/rhdh-must-gather -- /usr/bin/gather --without-operator --cluster-info\n\n# Collect from specific namespaces only\noc adm must-gather --image=ghcr.io/rm3l/rhdh-must-gather -- /usr/bin/gather --namespaces rhdh-prod,rhdh-staging\noc adm must-gather --image=ghcr.io/rm3l/rhdh-must-gather -- /usr/bin/gather --namespaces=my-rhdh-namespace\n\n# Combine namespace filtering with component exclusions\noc adm must-gather --image=ghcr.io/rm3l/rhdh-must-gather -- /usr/bin/gather --namespaces rhdh-ns --without-operator\noc adm must-gather --image=ghcr.io/rm3l/rhdh-must-gather -- /usr/bin/gather --namespaces prod-ns,staging-ns --without-helm\n\n# With time constraints (last 2 hours)\noc adm must-gather --image=ghcr.io/rm3l/rhdh-must-gather --since=2h\n\n# With debug logging\noc adm must-gather --image=ghcr.io/rm3l/rhdh-must-gather -- LOG_LEVEL=debug /usr/bin/gather\n\n# Help information\noc adm must-gather --image=ghcr.io/rm3l/rhdh-must-gather -- /usr/bin/gather --help\n```\n\n#### Available Exclusion Flags\n\n| Flag | Description | Use Case |\n|------|-------------|----------|\n| `--without-operator` | Skip operator-based RHDH deployment data | When you know RHDH is deployed via Helm only |\n| `--without-helm` | Skip Helm-based RHDH deployment data | When you know RHDH is deployed via Operator only |\n| `--without-platform` | Skip platform detection and information | For minimal collections when platform info is not needed |\n| `--without-route` | Skip OpenShift route collection | For non-OpenShift clusters or when routes are not relevant |\n| `--without-ingress` | Skip Kubernetes ingress collection | When ingresses are not used for RHDH access |\n\n#### Namespace Filtering\n\n| Flag | Description | Use Case |\n|------|-------------|----------|\n| `--namespaces ns1,ns2` | Limit collection to specified comma-separated namespaces | When RHDH is deployed in specific known namespaces |\n| `--namespaces=ns1,ns2` | Alternative syntax for namespace filtering | Same as above with equals syntax |\n\n**Examples:**\n- `--namespaces rhdh-prod,rhdh-staging` - Collect only from production and staging namespaces\n- `--namespaces=my-rhdh-ns` - Collect only from a single namespace\n- Combine with exclusions: `--namespaces prod-ns --without-helm` - Only operator data from prod-ns\n\n## Output Structure\n\n```\n/must-gather/\n├── version                         # Tool version information (e.g., \"rhdh/must-gather 0.0.0-unknown\")\n├── sanitization-report.txt         # Data sanitization summary and details\n├── all-routes.txt                  # All OpenShift routes cluster-wide\n├── all-ingresses.txt               # All Kubernetes ingresses cluster-wide\n├── must-gather.log                 # Must-gather container logs (if running in pod)\n├── cluster-info/                   # Cluster-wide information (if --cluster-info used)\n│   └── [cluster-info dump output]\n├── platform/                       # Platform and infrastructure information\n│   ├── platform.json               # Structured platform data (platform, underlying, versions)\n│   └── platform.txt                # Human-readable platform summary\n├── helm/                           # Helm deployment data (if RHDH Helm releases found)\n│   ├── all-rhdh-releases.txt       # List of detected RHDH Helm releases with namespaces, revisions, status\n│   └── releases/                   # Per-release data\n│       └── ns=[namespace]/         # Per-namespace organization\n│           ├── _configmaps/        # Namespace-wide ConfigMaps with both formats\n│           │   ├── [configmap-name].yaml               # Full ConfigMap YAML\n│           │   └── [configmap-name].describe.txt       # kubectl describe output\n│           ├── _secrets/           # Namespace-wide Secrets (sanitized)\n│           │   ├── [secret-name].yaml                  # Full Secret YAML (sanitized)\n│           │   └── [secret-name].describe.txt          # kubectl describe output (data redacted)\n│           └── [release-name]/     # Per-release directory\n│               ├── values.yaml         # User-provided values\n│               ├── all-values.yaml     # All computed values (25KB+ files)\n│               ├── manifest.yaml       # Deployed manifest (18KB+ files)\n│               ├── hooks.yaml          # Helm hooks\n│               ├── history.txt         # Release history\n│               ├── history.yaml        # Release history (YAML)\n│               ├── status.txt          # Release status (text)\n│               ├── status.yaml         # Release status (YAML, 21KB+ files)\n│               ├── notes.txt           # Release notes\n│               ├── deployment/         # Application deployment info\n│               │   ├── deployment.yaml\n│               │   ├── deployment.describe.txt\n│               │   ├── app-container-userid.txt      # \"uid=1001 gid=0(root) groups=0(root)\"\n│               │   ├── backstage.json              # {\"version\": \"1.39.1\"}\n│               │   ├── build-metadata.json         # RHDH version, Backstage version, source repos, build time\n│               │   ├── node-version.txt            # \"v22.16.0\"\n│               │   ├── dynamic-plugins-root.fs.txt # Directory listing with plugin packages\n│               │   ├── app-config.dynamic-plugins.yaml # Generated app config (9KB files)\n│               │   ├── logs-app.txt                # All container logs (2MB+ files)\n│               │   ├── logs-app--backstage-backend.txt # Backend logs (2MB+ files)\n│               │   ├── logs-app--install-dynamic-plugins.txt # Init container logs (17KB files)\n│               │   └── pods/           # Pod details and logs\n│               │       ├── pods.txt\n│               │       ├── pods.yaml\n│               │       └── pods.describe.txt\n│               └── db-statefulset/     # Database StatefulSet info (if database enabled)\n│                   ├── db-statefulset.yaml\n│                   ├── db-statefulset.describe.txt\n│                   ├── logs-db.txt     # Database logs\n│                   └── pods/           # Database pod details\n│                       ├── pods.txt\n│                       ├── pods.yaml\n│                       └── pods.describe.txt\n└── operator/                       # Operator deployment data (if RHDH operators found)\n    ├── all-deployments.txt         # List of all RHDH operator deployments\n    ├── olm/                        # OLM information\n    │   ├── rhdh-csv-all.txt        # ClusterServiceVersions\n    │   ├── rhdh-subscriptions-all.txt # Subscriptions\n    │   ├── installplans-all.txt     # InstallPlans\n    │   ├── operatorgroups-all.txt   # OperatorGroups\n    │   └── catalogsources-all.txt   # CatalogSources\n    ├── crds/                       # Custom Resource Definitions\n    │   ├── all-crds.txt            # All CRDs in cluster\n    │   ├── backstages.rhdh.redhat.com.yaml # RHDH CRD definition\n    │   └── backstages.rhdh.redhat.com.describe.txt # CRD description\n    ├── ns=[operator-namespace]/     # Per-operator-namespace data (e.g., ns=rhdh-operator)\n    │   ├── all-resources.txt       # All resources in namespace\n    │   ├── configs/                # ConfigMaps with both formats\n    │   │   ├── all-configmaps.txt\n    │   │   ├── [configmap-name].yaml       # Full ConfigMap YAML\n    │   │   └── [configmap-name].describe.txt # kubectl describe output\n    │   ├── deployments/            # Operator deployments\n    │   │   ├── all-deployments.txt\n    │   │   ├── [deployment-selector].yaml\n    │   │   └── [deployment-selector].describe.txt\n    │   └── logs.txt               # Operator logs\n    └── backstage-crs/              # Backstage Custom Resources\n        ├── all-backstage-crs.txt   # List of all Backstage CRs\n        └── ns=[cr-namespace]/      # Per-CR-namespace data (where Backstage CRs are deployed)\n            ├── _configmaps/        # Namespace-wide ConfigMaps with both formats\n            │   ├── [configmap-name].yaml               # Full ConfigMap YAML\n            │   └── [configmap-name].describe.txt       # kubectl describe output\n            ├── _secrets/           # Namespace-wide Secrets (sanitized)\n            │   ├── [secret-name].yaml                  # Full Secret YAML (sanitized)\n            │   └── [secret-name].describe.txt          # kubectl describe output (data redacted)\n            └── [cr-name]/          # Per-CR directory\n                ├── [cr-name].yaml      # CR definition\n                ├── describe.txt        # CR description\n                ├── deployment/         # Application deployment (same structure as Helm)\n                │   ├── deployment.yaml\n                │   ├── deployment.describe.txt\n                │   ├── app-container-userid.txt      # \"uid=1001 gid=0(root) groups=0(root)\"\n                │   ├── backstage.json              # {\"version\": \"1.39.1\"}\n                │   ├── build-metadata.json         # RHDH version, Backstage version, source repos, build time\n                │   ├── node-version.txt            # \"v22.16.0\"\n                │   ├── dynamic-plugins-root.fs.txt # Directory listing with plugin packages\n                │   ├── app-config.dynamic-plugins.yaml # Generated app config (9KB files)\n                │   ├── logs-app.txt                # All container logs (2MB+ files)\n                │   ├── logs-app--backstage-backend.txt # Backend logs (2MB+ files)\n                │   ├── logs-app--install-dynamic-plugins.txt # Init container logs (17KB files)\n                │   └── pods/           # Application pods\n                │       ├── pods.txt\n                │       ├── pods.yaml\n                │       └── pods.describe.txt\n                └── db-statefulset/     # Database StatefulSet (if database enabled)\n                    ├── db-statefulset.yaml\n                    ├── db-statefulset.describe.txt\n                    ├── logs-db.txt     # Database logs\n                    └── pods/           # Database pods\n                        ├── pods.txt\n                        ├── pods.yaml\n                        └── pods.describe.txt\n```\n\n\u003e **Note**: The tool automatically detects and collects data for both Helm and Operator-based RHDH deployments. For cluster-wide information, use the `--cluster-info` flag or combine with standard `oc adm must-gather`.\n\nSee the [examples](examples) folder for sample outputs on various platforms.\n\n## Development\n\n### Testing\n\n```bash\n# Test locally (requires kubectl access to cluster)\nmake test-local-all\n\n# Test specific script locally\nmake test-local-script SCRIPT=helm    # Test only gather_helm\nmake test-local-script SCRIPT=operator # Test only gather_operator\n\n# Test in container with local cluster access\nmake test-container-all\n\n# Test with OpenShift using oc adm must-gather\nmake openshift-test\n\n# Test on regular Kubernetes (non-OpenShift) by creating a Job in the cluster\nmake k8s-test\n\n# Clean up test artifacts and images\nmake clean\n```\n\n### Building the Image\n\n```bash\n# Build locally\nmake build\n\n# Build and push to registry\nmake build-push REGISTRY=your-registry.com/namespace\n\n# Build and push with custom image name and tag\nmake build-push REGISTRY=your-registry.com/namespace IMAGE_NAME=my-rhdh-must-gather IMAGE_TAG=v1.0.0\n```\n\n### Available Variables\n\n```bash\n# Customize registry and image details\nmake build REGISTRY=your-registry.com IMAGE_NAME=custom-name IMAGE_TAG=v1.0.0\n\n# Set log level for testing\nmake test-local-all LOG_LEVEL=debug\n\n# View all available targets\nmake help\n```\n\n## License\n\nApache License 2.0 - see [LICENSE](LICENSE) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frm3l%2Frhdh-must-gather","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frm3l%2Frhdh-must-gather","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frm3l%2Frhdh-must-gather/lists"}