diff --git a/.env.example b/.env.example index ce2ac44..4ae081f 100644 --- a/.env.example +++ b/.env.example @@ -1,8 +1,6 @@ - export KEYCLOAK_CLIENT_SECRET="" export KEYCLOAK_CLIENT_ID="" export KEYCLOAK_REALM="" export KEYCLOAK_LOGIN_REALM="" export KEYCLOAK_METADATA_URL="" export KEYCLOAK_BASE_URL="" - diff --git a/Makefile b/Makefile index 2676caf..dc0c6ff 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,7 @@ NAMESPACE ?= rhdh VERSION ?= 1.9 ORCH ?= false +PLUGINS ?= USE_CONTAINER ?= false CATALOG_INDEX_TAG ?= RUNNER_IMAGE ?= quay.io/rhdh-community/rhdh-e2e-runner:main @@ -12,6 +13,9 @@ DEPLOY_FLAGS = --namespace $(NAMESPACE) ifeq ($(ORCH),true) DEPLOY_FLAGS += --with-orchestrator endif +ifneq ($(PLUGINS),) +DEPLOY_FLAGS += --plugins $(PLUGINS) +endif # ── Deploy ──────────────────────────────────────────────────────────────────── @@ -36,22 +40,32 @@ endif # ── Cleanup ─────────────────────────────────────────────────────────────────── -.PHONY: undeploy-helm undeploy-operator undeploy-infra clean +.PHONY: undeploy-helm undeploy-operator undeploy-infra undeploy-plugins clean -undeploy-helm: ## Uninstall Helm RHDH release - helm uninstall redhat-developer-hub -n $(NAMESPACE) || true - oc delete configmap app-config-rhdh -n $(NAMESPACE) --ignore-not-found - oc delete secret rhdh-secrets -n $(NAMESPACE) --ignore-not-found +undeploy-helm: ## Uninstall Helm RHDH release and all cluster resources (PLUGINS=keycloak,lighthouse to also teardown plugin infra) +ifdef PLUGINS + ./teardown.sh helm --namespace $(NAMESPACE) --plugins $(PLUGINS) +else + ./teardown.sh helm --namespace $(NAMESPACE) +endif -undeploy-operator: ## Remove Operator RHDH deployment - oc delete backstage developer-hub -n $(NAMESPACE) --ignore-not-found - oc delete configmap app-config-rhdh dynamic-plugins -n $(NAMESPACE) --ignore-not-found - oc delete secret rhdh-secrets -n $(NAMESPACE) --ignore-not-found +undeploy-operator: ## Remove Operator RHDH deployment and all cluster resources (PLUGINS=keycloak,lighthouse to also teardown plugin infra) +ifdef PLUGINS + ./teardown.sh operator --namespace $(NAMESPACE) --plugins $(PLUGINS) +else + ./teardown.sh operator --namespace $(NAMESPACE) +endif + +undeploy-plugins: ## Teardown plugin infrastructure only, leave RHDH running (PLUGINS=keycloak,lighthouse) +ifndef PLUGINS + $(error PLUGINS is required, e.g. make undeploy-plugins PLUGINS=keycloak,lighthouse) +endif + TEARDOWN=true NAMESPACE=$(NAMESPACE) bash scripts/config-plugins.sh $(PLUGINS) undeploy-infra: ## Uninstall orchestrator infra chart helm uninstall orchestrator-infra -n $(NAMESPACE) || true -clean: ## Delete the entire namespace +clean: ## Delete the entire namespace (removes everything) oc delete project $(NAMESPACE) --ignore-not-found # ── Status ──────────────────────────────────────────────────────────────────── diff --git a/README.md b/README.md index 1db72b2..58576a1 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,8 @@ This project provides automated deployment scripts and configuration files to se - 📦 **Multiple Install Types**: Support for both Helm and Operator installation methods - 🔄 **Flexible Version Support**: Deploy any RHDH version (latest, semantic versions like 1.7, CI builds like 1.7-98-CI) - 🌐 **Cluster Information Sharing**: Automatic sharing of deployment URLs, OpenShift console access, and cluster credentials -- 🔐 **Integrated Keycloak Authentication**: Automatic Keycloak deployment with pre-configured realm and test users -- 👥 **Pre-configured Test Users**: Ready-to-use test accounts (test1, test2) with authentication setup +- 🔐 **Flexible Authentication**: Guest login by default; optional Keycloak OIDC via `--plugins keycloak` +- 👥 **Runtime Test Users**: Keycloak test users provisioned with a generated password stored in a cluster Secret - 🏠 **Local Deployment**: Support for local development and testing environments - ⚡ **Resource Management**: Automatic cleanup with configurable timers and resource limits - 🎯 **Instance Limits**: Maximum of two concurrent test instances to manage resource usage @@ -28,17 +28,19 @@ Deploy test environments directly from Pull Requests using slash commands and te The bot supports flexible deployment commands directly from PR comments: -``` +```bash /test deploy [duration] ``` **Parameters:** + - `install-type`: `helm` or `operator` - `version`: Version to deploy (see supported versions below) - `duration`: Optional cleanup timer (e.g., `4h`, `2.5h`) **Examples:** -``` + +```bash /test deploy helm 1.7 4h # Deploy RHDH 1.7 with Helm, cleanup after 4 hours /test deploy operator 1.6 2.5h # Deploy RHDH 1.6 with Operator, cleanup after 2.5 hours /test deploy helm 1.7 # Deploy latest CI version with Helm with defaut duration 3h @@ -48,7 +50,8 @@ The bot supports flexible deployment commands directly from PR comments: ### How to Use PR Integration 1. **Comment on any PR on rhdh-test-instance repo:** - ``` + + ```bash /test deploy helm 1.7 4h ``` @@ -56,7 +59,7 @@ The bot supports flexible deployment commands directly from PR comments: The bot provides comprehensive feedback through PR comments for eg: -``` +```text 🚀 Deployed RHDH version: 1.7 using helm 🌐 RHDH URL: https://redhat-developer-hub-rhdh.apps.rhdh-4-17-us-east-2-kz69l.rhdh-qe.devcluster.openshift.com @@ -70,15 +73,13 @@ The bot provides comprehensive feedback through PR comments for eg: ⏰ Cluster Availability: Next 1 hours ``` - - ### Live Status of deploy Job **Prow Status:** -https://prow.ci.openshift.org/?repo=redhat-developer%2Frhdh-test-instance&type=presubmit&job=pull-ci-redhat-developer-rhdh-test-instance-main-deploy + **Job History:** -https://prow.ci.openshift.org/job-history/gs/test-platform-results/pr-logs/directory/pull-ci-redhat-developer-rhdh-test-instance-main-deploy + ### Testing Custom Configurations via PRs @@ -86,7 +87,8 @@ Users can deploy different configuration flavors by: 1. **Creating a PR** with modified configuration files 2. **Using bot commands** to deploy the PR's configuration: - ``` + + ```bash /test deploy helm 1.7 2h ``` @@ -102,28 +104,33 @@ For local development and testing environments, you can deploy RHDH directly to - `oc` CLI logged into your OpenShift cluster - `helm` CLI installed - `make` installed -- `.env` file configured with Keycloak credentials (copy from `.env.example`) +- `.env` file configured (copy from `.env.example`) — only needed if using Vault-based secrets locally ### Quick Start 1. **Clone the repository:** + ```bash git clone cd rhdh-test-instance ``` -2. **Configure environment:** +2. **Configure environment (optional):** + ```bash cp .env.example .env - # Edit .env with your Keycloak credentials + # Only needed for Vault-based local secrets ``` 3. **Deploy RHDH:** + ```bash - make deploy-helm VERSION=1.9-190-CI + make deploy-helm VERSION=1.9-190-CI # Guest auth (default) + make deploy-helm VERSION=1.9-190-CI PLUGINS=keycloak # With Keycloak OIDC ``` 4. **Access your RHDH instance:** + ```bash make url ``` @@ -153,10 +160,23 @@ make deploy-operator VERSION=1.9 ORCH=true #### Cleanup ```bash -make undeploy-helm # Remove Helm release -make undeploy-operator # Remove Operator deployment -make undeploy-infra # Remove orchestrator infra chart -make clean # Delete the entire namespace +# Remove RHDH only (leave Keycloak/Lighthouse in place) +make undeploy-helm +make undeploy-operator + +# Remove RHDH and tear down plugin infrastructure +make undeploy-helm PLUGINS=keycloak,lighthouse +make undeploy-operator PLUGINS=keycloak + +# Tear down plugin infra only, leave RHDH running +make undeploy-plugins PLUGINS=keycloak,lighthouse +make undeploy-plugins PLUGINS=lighthouse + +# Remove orchestrator infra chart +make undeploy-infra + +# Delete the entire namespace (removes everything) +make clean ``` #### Status and Debugging @@ -167,18 +187,19 @@ make logs # Tail RHDH pod logs make url # Print RHDH URL ``` -#### Configuration +#### Variables All make commands accept these variables: -| Variable | Default | Description | -|----------|---------|-------------| -| `NAMESPACE` | `rhdh` | Target namespace | -| `VERSION` | `1.9` | RHDH version (`1.9`, `1.9-190-CI`, or `next`) | -| `ORCH` | `false` | Set to `true` to deploy with orchestrator support | -| `USE_CONTAINER` | `false` | Set to `true` to run commands inside the e2e-runner container | -| `CATALOG_INDEX_TAG` | auto | Catalog index image tag (defaults to major.minor from version, or `next`) | -| `RUNNER_IMAGE` | `quay.io/rhdh-community/rhdh-e2e-runner:main` | Container image for `install-operator` | +| Variable | Default | Description | +| ------------------- | --------------------------------------------- | ------------------------------------------------------------------------- | +| `NAMESPACE` | `rhdh` | Target namespace | +| `VERSION` | `1.9` | RHDH version (`1.9`, `1.9-190-CI`, or `next`) | +| `ORCH` | `false` | Set to `true` to deploy with orchestrator support | +| `PLUGINS` | _(empty)_ | Comma-separated plugins to deploy/teardown (e.g. `keycloak,lighthouse`) | +| `USE_CONTAINER` | `false` | Set to `true` to run commands inside the e2e-runner container | +| `CATALOG_INDEX_TAG` | auto | Catalog index image tag (defaults to major.minor from version, or `next`) | +| `RUNNER_IMAGE` | `quay.io/rhdh-community/rhdh-e2e-runner:main` | Container image for `install-operator` | > **Note:** `install-operator` requires you to be logged into the cluster via `oc login` on your host. > It automatically passes the session token to the e2e-runner container (needs Linux tools like `umoci`, `opm`, `skopeo`). @@ -186,35 +207,55 @@ All make commands accept these variables: ### Direct Script Usage -You can also use `deploy.sh` directly: +You can also use `deploy.sh` and `teardown.sh` directly: + +**Deploy:** ```bash -./deploy.sh [--namespace ] [--with-orchestrator] +./deploy.sh [--namespace ] [--with-orchestrator] [--plugins ] ``` -**Examples:** ```bash ./deploy.sh helm 1.9 ./deploy.sh helm 1.9-190-CI ./deploy.sh helm next ./deploy.sh helm 1.9 --namespace rhdh-helm --with-orchestrator +./deploy.sh helm 1.9 --plugins keycloak,lighthouse ./deploy.sh operator 1.9 --namespace rhdh-operator ./deploy.sh operator next --with-orchestrator ``` +**Teardown:** + +```bash +./teardown.sh [--namespace ] [--plugins ] [--clean] +``` + +```bash +./teardown.sh helm # Remove RHDH only +./teardown.sh helm --plugins keycloak,lighthouse # Remove RHDH + plugin infra +./teardown.sh helm --namespace rhdh-helm --plugins keycloak # Remove from non-default namespace +./teardown.sh operator --plugins keycloak,lighthouse +./teardown.sh helm --clean # Full wipe: delete entire namespace +./teardown.sh helm --plugins keycloak,lighthouse --clean # Teardown plugins then delete namespace +``` + +> **Note:** `--clean` deletes the entire namespace after teardown, removing all resources including image streams. Omit it when redeploying to the same namespace to preserve cached image streams and avoid registry rate limits. + ### Accessing Your Local RHDH Instance After successful installation, access your RHDH instance at: -``` + +```text https://redhat-developer-hub-. ``` ### Login Process -1. Navigate to the RHDH URL -2. Click "Sign In" -3. Use one of the test users (test1/test1@123 or test2/test2@123) -4. Explore the developer portal features +1. Navigate to the RHDH URL (`make url` to print it) +2. Click **Sign In** +3. **Guest auth** (default): click **Enter** to sign in as `guest` +4. **Keycloak auth** (when `--plugins keycloak` was used): sign in with any test user defined in `resources/keycloak/users.json` — see [Finding Keycloak Credentials](#finding-keycloak-credentials) below ## Configuration @@ -223,18 +264,15 @@ https://redhat-developer-hub-. The main application configuration is stored in `config/app-config-rhdh.yaml`: ```yaml -# Key configuration areas: app: - baseUrl: "${RHDH_BASE_URL}" - + baseUrl: '${RHDH_BASE_URL}' + auth: environment: production providers: - oidc: - production: - metadataUrl: "${KEYCLOAK_METADATA_URL}" - clientId: "${KEYCLOAK_CLIENT_ID}" - clientSecret: "${KEYCLOAK_CLIENT_SECRET}" + guest: + dangerouslyAllowOutsideDevelopment: true +signInPage: guest catalog: locations: @@ -242,6 +280,8 @@ catalog: target: https://github.com/redhat-developer/rhdh/blob/main/catalog-entities/all.yaml ``` +When the `keycloak` plugin is enabled, an additional `pluginConfig` block within the Keycloak `dynamic-plugins.yaml` overlay switches authentication to OIDC, overriding the base guest config. + ### Dynamic Plugins Configure dynamic plugins in `config/dynamic-plugins.yaml`: @@ -272,40 +312,69 @@ upstream: - rhdh-secrets ``` -## Authentication with Keycloak +## Authentication -### Automatic Keycloak Deployment +### Default: Guest Login -The installation script automatically deploys Keycloak with: -- Admin user: `admin` / `admin123` -- Predefined realm: `rhdh` -- Pre-configured OIDC client -- Test users for development +By default, RHDH is configured with the Guest provider so you can sign in immediately without any additional setup. A `guest` user entity is pre-registered in the catalog. -### Test Users +### Optional: Keycloak OIDC -The following test users are created automatically: +When you deploy with `--plugins keycloak`, Keycloak is automatically set up with an OIDC client and the sign-in page switches to OIDC. Test users and groups are created from `resources/keycloak/users.json` and `resources/keycloak/groups.json`. -| Username | Password | Email | Role | -|----------|----------|--------|------| -| test1 | test1@123 | test1@example.com | User | -| test2 | test2@123 | test2@example.com | User | - -### Keycloak Configuration - -Keycloak is configured with: - **Realm**: `rhdh` - **Client ID**: `rhdh-client` +- **Test user password**: randomly generated at deploy time (see below) -## Project Structure +### Finding Keycloak Credentials + +After a successful Keycloak deployment, credentials are stored in a cluster Secret and also printed to the deploy log. + +**Via `oc`:** + +```bash +# Print all credentials +oc get secret keycloak-test-credentials -n rhdh -o jsonpath='{.data}' | \ + jq 'to_entries[] | "\(.key): \(.value | @base64d)"' -r +# Print only the shared user password +oc get secret keycloak-test-credentials -n rhdh \ + -o jsonpath='{.data.KEYCLOAK_USER_PASSWORD}' | base64 -d && echo + +# Print the username list +oc get secret keycloak-test-credentials -n rhdh \ + -o jsonpath='{.data.KEYCLOAK_USERNAMES}' | base64 -d && echo +``` + +**Via OpenShift Console:** + +Navigate to **Workloads > Secrets > `keycloak-test-credentials`** in your namespace and click **Reveal values**. + +**Secret keys:** + +| Key | Description | +|---|---| +| `KEYCLOAK_URL` | Keycloak base URL | +| `KEYCLOAK_USERNAMES` | Comma-separated list of all test usernames (read from `users.json` at deploy time) | +| `KEYCLOAK_USER_PASSWORD` | Shared password for all test users (generated at runtime — not hardcoded) | + +**Admin credentials** are stored by the Bitnami Helm chart itself in the `keycloak-keycloak` Secret in the same namespace: + +```bash +oc get secret keycloak-keycloak -n rhdh \ + -o jsonpath='{.data.admin-password}' | base64 -d && echo ``` + +## Project Structure + +```directory rhdh-test-instance/ ├── config/ -│ ├── app-config-rhdh.yaml # Main RHDH configuration -│ ├── dynamic-plugins.yaml # Dynamic plugins configuration +│ ├── app-config-rhdh.yaml # Main RHDH configuration (guest auth by default) +│ ├── dynamic-plugins.yaml # Base dynamic plugins configuration │ ├── orchestrator-dynamic-plugins.yaml # Orchestrator plugins (merged when ORCH=true) -│ └── rhdh-secrets.yaml # Kubernetes secrets template +│ ├── rbac-policies.yaml # RBAC policy ConfigMap +│ └── rhdh-secrets.yaml # Reference template for rhdh-secrets Secret ├── helm/ │ ├── deploy.sh # Helm deployment script │ └── value_file.yaml # Helm chart values @@ -313,14 +382,25 @@ rhdh-test-instance/ │ ├── install-operator.sh # One-time operator installation (runs in container) │ ├── deploy.sh # Operator instance deployment │ └── subscription.yaml # Backstage CR template -├── utils/ -│ └── keycloak/ -│ ├── keycloak-deploy.sh # Keycloak deployment script -│ ├── keycloak-values.yaml # Keycloak Helm values -│ ├── rhdh-client.json # Keycloak client configuration -│ ├── users.json # Test users configuration -│ └── groups.json # Groups configuration -├── deploy.sh # Main entry point +├── resources/ +│ ├── catalog-entities/ # Catalog entity ConfigMaps (applied unconditionally) +│ │ ├── components.yaml +│ │ ├── operators.yaml +│ │ ├── plugins.yaml +│ │ ├── resources.yaml +│ │ └── users.yaml # guest user entity +│ ├── image-stream-imports/ # Pre-import images to avoid rate limits +│ ├── keycloak/ # Keycloak plugin resources and config +│ ├── lighthouse/ # Lighthouse plugin resources and config +│ └── rhdh-script-examples/ # Demo workloads for Topology/Kubernetes views +├── scripts/ +│ ├── config-plugins.sh # Plugin orchestration (round-robin setup/teardown) +│ ├── setup-resources.sh # Shared cluster resource provisioning/teardown +│ └── plugins/ +│ ├── config-keycloak-plugin.sh # Keycloak deploy, realm/client/user setup +│ └── config-lighthouse-plugin.sh # Lighthouse deploy and URL injection +├── deploy.sh # Main deploy entry point +├── teardown.sh # Main teardown entry point ├── Makefile # Make targets ├── OWNERS # Project maintainers └── README.md # This file @@ -331,15 +411,15 @@ rhdh-test-instance/ ### PR Deployments (Vault Integration) When using PR deployments, secrets are automatically pulled from vault at: -https://vault.ci.openshift.org/ui/vault/secrets/kv/kv/list/selfservice/rhdh-test-instance/ + These secrets are available as environment variables with the same name and can be used directly in Kubernetes secrets. From there, they can be referenced in `app-config-rhdh.yaml` or `dynamic-plugins.yaml` configurations. **Access Requirements:** + - To add or view vault secrets, ensure you have appropriate access - For access requests, reach out in #team-rhdh slack channel ### Local Deployments (.env Configuration) For local development, you can add secrets in a `.env` file and use them in your app-config or dynamic plugins configuration. - diff --git a/config/app-config-guest-auth.yaml b/config/app-config-guest-auth.yaml new file mode 100644 index 0000000..9ebc38f --- /dev/null +++ b/config/app-config-guest-auth.yaml @@ -0,0 +1,8 @@ +auth: + environment: development + providers: + guest: + development: + userEntityRef: user:default/guest + dangerouslyAllowOutsideDevelopment: true +signInPage: guest diff --git a/config/app-config-rhdh.yaml b/config/app-config-rhdh.yaml index c4e9986..615598a 100644 --- a/config/app-config-rhdh.yaml +++ b/config/app-config-rhdh.yaml @@ -1,27 +1,22 @@ app: - baseUrl: "${RHDH_BASE_URL}" + baseUrl: '${RHDH_BASE_URL}' backend: - baseUrl: "${RHDH_BASE_URL}" + baseUrl: '${RHDH_BASE_URL}' cors: - origin: "${RHDH_BASE_URL}" + origin: '${RHDH_BASE_URL}' + csp: + connect-src: + - "'self'" + - 'http:' + - 'https:' + img-src: + - "'self'" + - 'data:' auth: # see https://backstage.io/docs/auth/ to learn about auth providers - environment: production session: - secret: superSecretSecret - providers: - oidc: - production: - metadataUrl: "${KEYCLOAK_METADATA_URL}" - clientId: "${KEYCLOAK_CLIENT_ID}" - clientSecret: "${KEYCLOAK_CLIENT_SECRET}" - prompt: auto - callbackUrl: "${RHDH_BASE_URL}/api/auth/oidc/handler/frame" - signIn: - resolvers: - - resolver: emailLocalPartMatchingUserEntityName -signInPage: oidc + secret: '${SESSION_SECRET}' catalog: import: entityFilename: catalog-info.yaml @@ -34,15 +29,13 @@ catalog: target: https://github.com/redhat-developer/rhdh/blob/main/catalog-entities/all.yaml - type: url target: https://github.com/redhat-developer/red-hat-developer-hub-software-templates/blob/main/templates.yaml - providers: - keycloakOrg: - default: - baseUrl: "${KEYCLOAK_BASE_URL}" - loginRealm: "${KEYCLOAK_LOGIN_REALM}" - realm: "${KEYCLOAK_REALM}" - clientId: "${KEYCLOAK_CLIENT_ID}" - clientSecret: "${KEYCLOAK_CLIENT_SECRET}" - schedule: - frequency: { minutes: 20 } - initialDelay: { seconds: 15 } - timeout: { minutes: 5 } \ No newline at end of file + - type: file + target: ./catalog-entities/users.yaml + - type: file + target: ./catalog-entities/components.yaml + - type: file + target: ./catalog-entities/operators.yaml + - type: file + target: ./catalog-entities/resources.yaml + - type: file + target: ./catalog-entities/plugins.yaml diff --git a/config/dynamic-plugins.yaml b/config/dynamic-plugins.yaml index 1707b52..8af3c33 100644 --- a/config/dynamic-plugins.yaml +++ b/config/dynamic-plugins.yaml @@ -1,6 +1,5 @@ includes: - dynamic-plugins.default.yaml plugins: - - package: ./dynamic-plugins/dist/backstage-community-plugin-catalog-backend-module-keycloak-dynamic - disabled: false - \ No newline at end of file + - package: ./dynamic-plugins/dist/backstage-community-plugin-analytics-provider-segment + disabled: true diff --git a/config/rbac-policies.yaml b/config/rbac-policies.yaml new file mode 100644 index 0000000..6c7ee66 --- /dev/null +++ b/config/rbac-policies.yaml @@ -0,0 +1,32 @@ +kind: ConfigMap +apiVersion: v1 +metadata: + name: rbac-policy + labels: + backstage.io/kubernetes-id: developer-hub +data: + rbac-policy.csv: | + p, role:default/admin, catalog-entity, read, allow + p, role:default/admin, catalog.entity.create, create, allow + + g, user:default/guest, role:default/admin + + p, role:default/admin, catalog-entity, read, allow + p, role:default/admin, catalog.entity.create, create, allow + + g, user:default/someuser, role:default/developer + + g, user:default/ant-man, role:default/conditional-role + conditional-policy.yaml: | + result: CONDITIONAL + roleEntityRef: 'role:default/conditional-role' + pluginId: catalog + resourceType: catalog-entity + permissionMapping: + - read + conditions: + rule: IS_ENTITY_OWNER + resourceType: catalog-entity + params: + claims: + - $ownerRefs diff --git a/config/rhdh-secrets.yaml b/config/rhdh-secrets.yaml index 26085c3..ba1e324 100644 --- a/config/rhdh-secrets.yaml +++ b/config/rhdh-secrets.yaml @@ -10,4 +10,5 @@ stringData: KEYCLOAK_LOGIN_REALM: $KEYCLOAK_LOGIN_REALM KEYCLOAK_REALM: $KEYCLOAK_REALM KEYCLOAK_CLIENT_ID: $KEYCLOAK_CLIENT_ID - KEYCLOAK_CLIENT_SECRET: $KEYCLOAK_CLIENT_SECRET \ No newline at end of file + KEYCLOAK_CLIENT_SECRET: $KEYCLOAK_CLIENT_SECRET + LIGHTHOUSE_URL: $LIGHTHOUSE_URL diff --git a/deploy.sh b/deploy.sh index 584e3d0..ae93be3 100755 --- a/deploy.sh +++ b/deploy.sh @@ -15,12 +15,14 @@ if [[ $# -lt 2 ]]; then echo "Options:" echo " --namespace Deploy to specified namespace (default: rhdh)" echo " --with-orchestrator Deploy with orchestrator support" + echo " --plugins Deploy with plugins support (default: none)" echo "Examples:" echo " $0 helm 1.5-171-CI" echo " $0 helm next" echo " $0 operator 1.5" echo " $0 helm 1.9 --with-orchestrator" echo " $0 helm 1.9 --namespace rhdh-helm --with-orchestrator" + echo " $0 helm 1.9 --plugins keycloak,lighthouse" exit 1 fi @@ -40,6 +42,10 @@ while [[ $# -gt 0 ]]; do echo "Orchestrator support enabled" shift ;; + --plugins) + PLUGINS="$2" + shift 2 + ;; *) echo "Error: Unknown option: $1" echo "Usage: $0 [--namespace ] [--with-orchestrator]" @@ -61,20 +67,46 @@ fi [[ "${OPENSHIFT_CI}" != "true" ]] && source .env # source utils/utils.sh -# Deploy Keycloak with users and roles. -# comment this out if you don't want to deploy Keycloak or use your own Keycloak instance. -source utils/keycloak/keycloak-deploy.sh $namespace - # Create or switch to the specified namespace oc new-project "$namespace" || oc project "$namespace" -# Create configmap with environment variables substituted -oc create configmap app-config-rhdh \ - --from-file="config/app-config-rhdh.yaml" \ - --namespace="$namespace" \ - --dry-run=client -o yaml | oc apply -f - --namespace="$namespace" +# Resolve cluster router base and RHDH URL early so setup-resources.sh and +# plugin scripts have them available (e.g. for creating the rhdh-secrets Secret). +export CLUSTER_ROUTER_BASE +CLUSTER_ROUTER_BASE=$(oc get route console -n openshift-console -o=jsonpath='{.spec.host}' | sed 's/^[^.]*\.//') +if oc get route console -n openshift-console -o=jsonpath='{.spec.tls.termination}' 2>/dev/null | grep -q .; then + RHDH_PROTOCOL="https" +else + RHDH_PROTOCOL="http" +fi +if [[ "$installation_method" == "helm" ]]; then + export RHDH_BASE_URL="${RHDH_PROTOCOL}://redhat-developer-hub-${namespace}.${CLUSTER_ROUTER_BASE}" +else + export RHDH_BASE_URL="${RHDH_PROTOCOL}://backstage-developer-hub-${namespace}.${CLUSTER_ROUTER_BASE}" +fi +echo "RHDH URL: ${RHDH_BASE_URL}" + +# Apply cluster resources that are always present (catalog entities, RBAC +# policies, app-config and dynamic-plugins ConfigMaps, image stream pre-imports, +# demo workloads). Run before plugin scripts so all base config exists before +# plugins append to it. +export NAMESPACE="$namespace" +source scripts/setup-resources.sh +setup_resources -export CLUSTER_ROUTER_BASE=$(oc get route console -n openshift-console -o=jsonpath='{.spec.host}' | sed 's/^[^.]*\.//') +export IS_AUTH_ENABLED="${IS_AUTH_ENABLED:-false}" + +source scripts/config-plugins.sh +if [[ -n "${PLUGINS:-}" ]]; then + main "$PLUGINS" +fi + +# If no auth plugin set IS_AUTH_ENABLED=true, mount the guest auth ConfigMap. +if [[ "${IS_AUTH_ENABLED}" != "true" ]]; then + export GUEST_AUTH_CONFIG_MAP_ENTRY=" - name: app-config-guest-auth" +else + export GUEST_AUTH_CONFIG_MAP_ENTRY="" +fi if [[ "$installation_method" == "helm" ]]; then source helm/deploy.sh "$namespace" "$version" @@ -89,9 +121,9 @@ else fi # Wait for the deployment to be ready -oc rollout status deployment -l 'app.kubernetes.io/instance in (redhat-developer-hub,developer-hub)' -n "$namespace" --timeout=500s || echo "Error: Timed out waiting for deployment to be ready." +oc rollout status deployment -l 'app.kubernetes.io/instance in (redhat-developer-hub,developer-hub)' -n "$namespace" --timeout=500s || { echo "Error: Timed out waiting for deployment to be ready."; exit 1; } echo " RHDH_BASE_URL : $RHDH_BASE_URL -" \ No newline at end of file +" diff --git a/helm/deploy.sh b/helm/deploy.sh index 9795cad..84172a6 100755 --- a/helm/deploy.sh +++ b/helm/deploy.sh @@ -11,9 +11,6 @@ namespace="$1" version="$2" github=0 # by default don't use the Github repo unless the chart doesn't exist in the OCI registry -# Get cluster router base -export CLUSTER_ROUTER_BASE=$(oc get route console -n openshift-console -o=jsonpath='{.spec.host}' | sed 's/^[^.]*\.//') - # Validate version and determine chart version if [[ "$version" =~ ^([0-9]+(\.[0-9]+)?)$ ]]; then CV=$(curl -s "https://quay.io/api/v1/repository/rhdh/chart/tag/?onlyActiveTags=true&limit=600" | jq -r '.tags[].name' | grep "^${version}-" | sort -V | tail -n 1) @@ -44,18 +41,6 @@ fi echo "Using ${CHART_URL} to install Helm chart" -# RHDH URL -# Detect protocol based on cluster route TLS configuration -if oc get route console -n openshift-console -o=jsonpath='{.spec.tls.termination}' 2>/dev/null | grep -q .; then - RHDH_PROTOCOL="https" -else - RHDH_PROTOCOL="http" -fi -export RHDH_BASE_URL="${RHDH_PROTOCOL}://redhat-developer-hub-${namespace}.${CLUSTER_ROUTER_BASE}" - -# Apply secrets -envsubst < config/rhdh-secrets.yaml | oc apply -f - --namespace="$namespace" - # Install orchestrator infrastructure if requested if [[ "${WITH_ORCHESTRATOR}" == "1" ]]; then echo "Installing orchestrator infrastructure chart..." @@ -83,13 +68,25 @@ if [[ "${WITH_ORCHESTRATOR}" == "1" ]]; then echo "Serverless operator pods are running." fi -# Build dynamic plugins value file +# Build dynamic plugins value file. +# Read from the cluster ConfigMap seeded in deploy.sh and augmented by any +# plugin setup scripts. Fall back to config/dynamic-plugins.yaml if the +# ConfigMap is not available (e.g. standalone helm/deploy.sh execution). DYNAMIC_PLUGINS_FILE=$(mktemp) trap "rm -f $DYNAMIC_PLUGINS_FILE" EXIT echo "global:" > "$DYNAMIC_PLUGINS_FILE" echo " dynamic:" >> "$DYNAMIC_PLUGINS_FILE" # Escape {{inherit}} for Helm's Go template engine: {{inherit}} -> {{ "{{inherit}}" }} -sed -e 's/^/ /' -e 's/{{inherit}}/{{ "{{inherit}}" }}/g' config/dynamic-plugins.yaml >> "$DYNAMIC_PLUGINS_FILE" +if oc get configmap dynamic-plugins --namespace "$namespace" &>/dev/null; then + oc get configmap dynamic-plugins \ + --namespace "$namespace" \ + -o jsonpath='{.data.dynamic-plugins\.yaml}' \ + | sed -e 's/^/ /' -e 's/{{inherit}}/{{ "{{inherit}}" }}/g' \ + >> "$DYNAMIC_PLUGINS_FILE" +else + sed -e 's/^/ /' -e 's/{{inherit}}/{{ "{{inherit}}" }}/g' \ + config/dynamic-plugins.yaml >> "$DYNAMIC_PLUGINS_FILE" +fi # Build helm install arguments HELM_ARGS=( @@ -106,8 +103,15 @@ if [[ "${WITH_ORCHESTRATOR}" == "1" ]]; then HELM_ARGS+=(--set orchestrator.enabled=true) fi -# Install Helm chart -helm install redhat-developer-hub "${CHART_URL}" --version "$CV" "${HELM_ARGS[@]}" +if [[ "${IS_AUTH_ENABLED:-false}" != "true" ]]; then + HELM_ARGS+=( + --set "upstream.backstage.extraAppConfig[1].configMapRef=app-config-guest-auth" + --set "upstream.backstage.extraAppConfig[1].filename=app-config-guest-auth.yaml" + ) +fi + +# Install or upgrade Helm chart +helm upgrade --install redhat-developer-hub "${CHART_URL}" --version "$CV" "${HELM_ARGS[@]}" # Scale down and up to ensure fresh pods (helm does not monitor config changes) oc scale deployment -l 'app.kubernetes.io/instance in (redhat-developer-hub,developer-hub)' --replicas=0 -n "$namespace" diff --git a/helm/value_file.yaml b/helm/value_file.yaml index fc8165c..564a38e 100644 --- a/helm/value_file.yaml +++ b/helm/value_file.yaml @@ -11,4 +11,88 @@ upstream: - configMapRef: app-config-rhdh filename: app-config-rhdh.yaml extraEnvVarsSecrets: - - rhdh-secrets \ No newline at end of file + - rhdh-secrets + extraEnvVars: # need to look to see if these are required or not ... + - name: NODE_TLS_REJECT_UNAUTHORIZED + value: '0' + - name: SEGMENT_TEST_MODE + value: 'true' + - name: BACKEND_SECRET + valueFrom: + secretKeyRef: + key: backend-secret + name: '{{ include "rhdh.backend-secret-name" $ }}' + - name: POSTGRESQL_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + key: postgres-password + name: '{{- include "rhdh.postgresql.secretName" . }}' + extraVolumeMounts: + - name: dynamic-plugins-root + mountPath: /opt/app-root/src/dynamic-plugins-root + - name: extensions-catalog + mountPath: /extensions + - name: temp + mountPath: /tmp + - name: rbac-policy + mountPath: /opt/app-root/src/rbac + - name: catalog-entities + mountPath: /opt/app-root/src/catalog-entities + extraVolumes: + # -- Ephemeral volume that will contain the dynamic plugins installed by the initContainer below at start. + - name: dynamic-plugins-root + ephemeral: + volumeClaimTemplate: + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + # -- Size of the volume that will contain the dynamic plugins. It should be large enough to contain all the plugins. + storage: 5Gi + # Volume that will expose the `dynamic-plugins.yaml` file from the `dynamic-plugins` config map. + # The `dynamic-plugins` config map is created by the helm chart from the content of the `global.dynamic` field. + - name: dynamic-plugins + configMap: + defaultMode: 420 + name: dynamic-plugins + optional: true + # Optional volume that allows exposing the `.npmrc` file (through a `dynamic-plugins-npmrc` secret) + # to be used when running `npm pack` during the dynamic plugins installation by the initContainer. + - name: dynamic-plugins-npmrc + secret: + defaultMode: 420 + optional: true + secretName: '{{ printf "%s-dynamic-plugins-npmrc" .Release.Name }}' + # Optional volume that allows adding a container registry `auth.json` file (through a `dynamic-plugins-registry-auth` secret) + # to be used when installing plugins from secure container registries during the dynamic plugins installation by the initContainer. + - name: dynamic-plugins-registry-auth + secret: + defaultMode: 416 + optional: true + secretName: '{{ printf "%s-dynamic-plugins-registry-auth" .Release.Name }}' + - name: npmcacache + emptyDir: {} + # -- Ephemeral volume used by the install-dynamic-plugins init container to extract catalog entities from the catalog index image. + # Mounted at the /extensions path in the backstage-backend main container for automatic discovery by the extension catalog backend providers. + - name: extensions-catalog + emptyDir: {} + - name: temp + emptyDir: {} + - name: rbac-policy + configMap: + defaultMode: 420 + name: rbac-policy + - name: catalog-entities + projected: + sources: + - configMap: + name: users-config-map + - configMap: + name: operators-config-map + - configMap: + name: plugins-config-map + - configMap: + name: components-config-map + - configMap: + name: resources-config-map diff --git a/operator/deploy.sh b/operator/deploy.sh index bb71e80..0731a0a 100755 --- a/operator/deploy.sh +++ b/operator/deploy.sh @@ -54,28 +54,19 @@ else fi echo "Using catalog index tag: ${CATALOG_INDEX_TAG}" -# Detect protocol based on cluster route TLS configuration -if oc get route console -n openshift-console -o=jsonpath='{.spec.tls.termination}' 2>/dev/null | grep -q .; then - RHDH_PROTOCOL="https" -else - RHDH_PROTOCOL="http" -fi -export RHDH_BASE_URL="${RHDH_PROTOCOL}://backstage-developer-hub-${namespace}.${CLUSTER_ROUTER_BASE}" - -# Apply secrets -envsubst < config/rhdh-secrets.yaml | oc apply -f - --namespace="$namespace" - -# Create dynamic-plugins ConfigMap +# The dynamic-plugins ConfigMap was seeded in deploy.sh from the base config +# and may have been augmented by plugin setup scripts. Append orchestrator +# plugin entries here if requested, then apply the Backstage CR. if [[ "${WITH_ORCHESTRATOR}" == "1" ]]; then - echo "Merging orchestrator plugins into dynamic-plugins configuration..." - ORCH_PLUGINS=$(cat config/orchestrator-dynamic-plugins.yaml | grep -A 100 '^plugins:' | tail -n +2) - oc create configmap dynamic-plugins \ - --from-file=dynamic-plugins.yaml=<(cat config/dynamic-plugins.yaml; echo ""; echo "$ORCH_PLUGINS") \ - --namespace="$namespace" \ - --dry-run=client -o yaml | oc apply -f - -else + echo "Merging orchestrator plugins into dynamic-plugins ConfigMap..." + ORCH_PLUGINS=$(grep -A 100 '^plugins:' config/orchestrator-dynamic-plugins.yaml | tail -n +2) oc create configmap dynamic-plugins \ - --from-file="config/dynamic-plugins.yaml" \ + --from-file=dynamic-plugins.yaml=<( + oc get configmap dynamic-plugins \ + --namespace="$namespace" \ + -o jsonpath='{.data.dynamic-plugins\.yaml}' + echo "$ORCH_PLUGINS" + ) \ --namespace="$namespace" \ --dry-run=client -o yaml | oc apply -f - fi diff --git a/operator/subscription.yaml b/operator/subscription.yaml index ed1cd55..74cea2f 100644 --- a/operator/subscription.yaml +++ b/operator/subscription.yaml @@ -7,9 +7,23 @@ spec: appConfig: configMaps: - name: app-config-rhdh +${GUEST_AUTH_CONFIG_MAP_ENTRY} mountPath: /opt/app-root/src extraFiles: mountPath: /opt/app-root/src + configMaps: + - name: rbac-policy + mountPath: /opt/app-root/src/rbac + - name: users-config-map + mountPath: /opt/app-root/src/catalog-entities + - name: operators-config-map + mountPath: /opt/app-root/src/catalog-entities + - name: plugins-config-map + mountPath: /opt/app-root/src/catalog-entities + - name: components-config-map + mountPath: /opt/app-root/src/catalog-entities + - name: resources-config-map + mountPath: /opt/app-root/src/catalog-entities replicas: 1 route: enabled: true @@ -17,9 +31,13 @@ spec: extraEnvs: envs: - name: RHDH_BASE_URL - value: "${RHDH_BASE_URL}" + value: '${RHDH_BASE_URL}' - name: CATALOG_INDEX_IMAGE - value: "quay.io/rhdh/plugin-catalog-index:${CATALOG_INDEX_TAG}" + value: 'quay.io/rhdh/plugin-catalog-index:${CATALOG_INDEX_TAG}' + - name: NODE_TLS_REJECT_UNAUTHORIZED + value: '0' + - name: SEGMENT_TEST_MODE + value: 'true' secrets: - name: rhdh-secrets database: diff --git a/resources/catalog-entities/components.yaml b/resources/catalog-entities/components.yaml new file mode 100644 index 0000000..b38d448 --- /dev/null +++ b/resources/catalog-entities/components.yaml @@ -0,0 +1,178 @@ +kind: ConfigMap +apiVersion: v1 +metadata: + name: components-config-map + labels: + backstage.io/kubernetes-id: developer-hub +data: + components.yaml: | + apiVersion: backstage.io/v1alpha1 + kind: Component + metadata: + name: developer-hub + description: List of resources deployed to openshift to be viewed through the kubernetes and topology plugins + annotations: + backstage.io/kubernetes-id: developer-hub + tekton.dev/cicd: "true" + spec: + type: service + system: integrations + lifecycle: qa + owner: fantastic-four + --- + # Demo Component 1: RHDH itself — scanned by the initial Lighthouse audit job. + # The lighthouse.io/website-url annotation tells the plugin which URL's audit + # history to display on the Overview page. + apiVersion: backstage.io/v1alpha1 + kind: Component + metadata: + name: demo-lighthouse-rhdh + title: Demo Lighthouse — RHDH + description: > + Demo component showcasing the Lighthouse plugin using RHDH itself as the + audited website. The Lighthouse audit card on the Overview page shows the + latest performance, accessibility, best-practices, and SEO scores returned + by the self-hosted lighthouse-audit-service. + annotations: + # Required: the URL that was submitted to the lighthouse-audit-service. + # Must match the URL used in the initial scan job. + # See: https://github.com/backstage/community-plugins/tree/main/workspaces/lighthouse/plugins/lighthouse + lighthouse.io/website-url: ${RHDH_BASE_URL} + + backstage.io/kubernetes-id: lighthouse-demo + tags: + - demo + - lighthouse + - performance + - accessibility + links: + - url: https://developer.chrome.com/docs/lighthouse/overview/ + title: Lighthouse Documentation + icon: docs + spec: + type: website + lifecycle: experimental + owner: group:default/guardians-of-the-galaxy + dependencyOf: + - resource:default/lighthouse-instance + --- + # Demo Component 2: backstage.io — a publicly accessible website used to + # demonstrate that any external URL can be audited, not just the RHDH instance. + apiVersion: backstage.io/v1alpha1 + kind: Component + metadata: + name: demo-lighthouse-website + title: Demo Lighthouse — Backstage.io + description: > + Demo component owned by the X-Men team that demonstrates auditing an + external public website with the Lighthouse plugin. Owned by a different + team than demo-lighthouse-rhdh to enable RBAC testing. + annotations: + lighthouse.io/website-url: https://janus-idp.io + + backstage.io/kubernetes-id: lighthouse-demo + tags: + - demo + - lighthouse + - performance + links: + - url: https://developer.chrome.com/docs/lighthouse/overview/ + title: Lighthouse Documentation + icon: docs + spec: + type: website + lifecycle: experimental + owner: group:default/x-men + dependencyOf: + - resource:default/lighthouse-instance + --- + # Demo Component 3: A third website component owned by a different team to demonstrate + # multi-team RBAC scenarios. No lighthouse.io/website-url annotation — shows that + # catalog components can exist alongside Lighthouse-annotated ones without triggering scans. + apiVersion: backstage.io/v1alpha1 + kind: Component + metadata: + name: demo-lighthouse-docs + title: Demo Lighthouse — Docs Site + description: > + Demo component owned by the Avengers team. Provides a third ownership context for + multi-team RBAC testing alongside demo-lighthouse-rhdh and demo-lighthouse-website. + No Lighthouse annotation — demonstrates that the audit card only appears on components + that explicitly opt in via the lighthouse.io/website-url annotation. + annotations: + backstage.io/kubernetes-id: lighthouse-demo + tags: + - demo + - lighthouse + - catalog + links: + - url: https://developer.chrome.com/docs/lighthouse/overview/ + title: Lighthouse Documentation + icon: docs + spec: + type: website + lifecycle: experimental + owner: group:default/avengers + dependencyOf: + - resource:default/lighthouse-instance + --- + # Plugin Component: Lighthouse RHDH plugin. + # Required so that the lighthouse-instance Resource's dependencyOf relation resolves. + apiVersion: backstage.io/v1alpha1 + kind: Component + metadata: + name: backstage-community-plugin-lighthouse + title: Lighthouse Plugin + description: > + Backstage community Lighthouse plugin deployed in RHDH. Provides web performance + and accessibility audit views on component entity pages and a dedicated /lighthouse + catalog page, powered by the self-hosted lighthouse-audit-service running in the cluster. + annotations: + backstage.io/kubernetes-id: developer-hub + tags: + - plugin + - lighthouse + - performance + - accessibility + links: + - url: https://github.com/backstage/community-plugins/tree/main/workspaces/lighthouse + title: Plugin Repository + icon: github + spec: + type: plugin + lifecycle: experimental + system: integrations + owner: group:default/cluster-admins + dependsOn: + - resource:default/lighthouse-instance + --- + # Plugin Component: Keycloak catalog backend module. + # Required so that the keycloak and rhsso-operator Resources' dependencyOf relations resolve. + apiVersion: backstage.io/v1alpha1 + kind: Component + metadata: + name: backstage-community-keycloak + title: Keycloak Catalog Module + description: > + Backstage community Keycloak catalog backend module deployed in RHDH. Ingests users and + groups from the Keycloak rhdh realm into the Backstage catalog, powering catalog ownership + and RBAC policies. Also configures the OIDC sign-in provider so users authenticate via + Keycloak. + annotations: + backstage.io/kubernetes-id: developer-hub + tags: + - plugin + - keycloak + - identity + - catalog + links: + - url: https://github.com/backstage/community-plugins/tree/main/workspaces/keycloak + title: Plugin Repository + icon: github + spec: + type: plugin + lifecycle: production + system: integrations + owner: group:default/cluster-admins + dependsOn: + - resource:default/keycloak diff --git a/resources/catalog-entities/operators.yaml b/resources/catalog-entities/operators.yaml new file mode 100644 index 0000000..9ecdab2 --- /dev/null +++ b/resources/catalog-entities/operators.yaml @@ -0,0 +1,278 @@ +kind: ConfigMap +apiVersion: v1 +metadata: + name: operators-config-map + labels: + backstage.io/kubernetes-id: developer-hub +data: + operators.yaml: | + # RHSSO and Keycloak + apiVersion: backstage.io/v1alpha1 + kind: Resource + metadata: + name: rhsso-operator + title: Red Hat Single Sign-On Operator + description: Operator that is used to configure Red Hat Single Sign-On through the use of Keycloak for an OpenShift instance + annotations: + backstage.io/kubernetes-id: rhsso-operator + backstage.io/kubernetes-namespace: rhdh + spec: + type: operator + owner: cluster-admins + dependencyOf: component:default/backstage-community-keycloak + dependsOn: + - resource:default/test-cluster + --- + apiVersion: backstage.io/v1alpha1 + kind: Resource + metadata: + name: keycloak + title: Keycloak + description: Red Hat Single Sign-On Operator deployment of Keycloak + annotations: + backstage.io/kubernetes-id: keycloak + backstage.io/kubernetes-namespace: rhdh + links: + - url: https://www.keycloak.org/documentation + title: Documentation + icon: web + spec: + type: identity-provider + lifecycle: production + owner: cluster-admins + dependencyOf: component:default/backstage-community-keycloak + dependsOn: + - resource:default/rhsso-operator + --- + # ACM, Multiclusterhub, search + apiVersion: backstage.io/v1alpha1 + kind: Resource + metadata: + name: acm-operator + title: Advanced Cluster Manager for Kubernetes Operator + description: Operator that is used to configure the Advanced Cluster Manager for an OpenShift instance + annotations: + backstage.io/kubernetes-id: acm-operator + backstage.io/kubernetes-namespace: rhdh + spec: + type: operator + owner: cluster-admins + dependencyOf: component:default/backstage-community-ocm + dependsOn: + - resource:default/test-cluster + --- + apiVersion: backstage.io/v1alpha1 + kind: Resource + metadata: + name: search-operator + title: Search Operator + description: Operator that is used in conjuction with the Advanced Cluster Manager for an OpenShift instance + annotations: + backstage.io/kubernetes-id: search-operator + backstage.io/kubernetes-namespace: rhdh + spec: + type: operator + owner: cluster-admins + dependencyOf: component:default/backstage-community-ocm + dependsOn: + - resource:default/test-cluster + --- + apiVersion: backstage.io/v1alpha1 + kind: Resource + metadata: + name: multiclusterhub + title: MultiClusterHub + description: Advanced Cluster Manager deployment of the MultiClusterHub + annotations: + backstage.io/kubernetes-id: multiclusterhub + backstage.io/kubernetes-namespace: rhdh + spec: + type: operator + owner: cluster-admins + dependencyOf: component:default/backstage-community-ocm + dependsOn: + - resource:default/acm-operator + --- + apiVersion: backstage.io/v1alpha1 + kind: Resource + metadata: + name: pipelines-operator + title: Red Hat OpenShift Pipelines Operator + description: Operator that is used to configure Red Hat OpenShift Pipelines for an OpenShift instance + annotations: + backstage.io/kubernetes-id: pipelines-operator + backstage.io/kubernetes-namespace: openshift-operators + spec: + type: operator + owner: cluster-admins + dependencyOf: component:default/backstage-plugin-tekton-workspace + dependsOn: + - resource:default/test-cluster + --- + # Nexus Repository Manager Operator + apiVersion: backstage.io/v1alpha1 + kind: Resource + metadata: + name: nxrm-operator + title: Nexus Repository Manager Operator + description: Operator that is used to deploy and manage Sonatype Nexus Repository Manager instances + annotations: + backstage.io/kubernetes-id: nxrm-operator + backstage.io/kubernetes-namespace: rhdh + spec: + type: operator + owner: cluster-admins + dependencyOf: component:default/janus-idp-nexus-repository-manager + dependsOn: + - resource:default/test-cluster + --- + apiVersion: backstage.io/v1alpha1 + kind: Resource + metadata: + name: nexus-repo + title: Nexus Repository Manager + description: Nexus Repository Manager instance for artifact management + annotations: + backstage.io/kubernetes-id: nexus-repo + backstage.io/kubernetes-namespace: rhdh + links: + - url: https://help.sonatype.com/repomanager3 + title: Documentation + icon: web + spec: + type: artifact-repository + lifecycle: production + owner: cluster-admins + dependencyOf: component:default/janus-idp-nexus-repository-manager + dependsOn: + - resource:default/nxrm-operator + --- + # SonarQube Community Edition (no operator — plain Deployment) + apiVersion: backstage.io/v1alpha1 + kind: Resource + metadata: + name: sonarqube-instance + title: SonarQube Community Edition + description: SonarQube CE instance for code quality and security analysis + annotations: + backstage.io/kubernetes-id: sonarqube-instance + backstage.io/kubernetes-namespace: rhdh + links: + - url: https://docs.sonarsource.com/sonarqube/latest/ + title: Documentation + icon: web + spec: + type: code-quality-platform + lifecycle: production + owner: cluster-admins + dependencyOf: + - component:default/backstage-community-plugin-sonarqube + dependsOn: + - resource:default/test-cluster + --- + # ArgoCD Operator + apiVersion: backstage.io/v1alpha1 + kind: Resource + metadata: + name: argocd-operator + title: ArgoCD Operator + description: Operator that is used to deploy and manage ArgoCD instances for GitOps continuous delivery + annotations: + backstage.io/kubernetes-id: argocd-operator + backstage.io/kubernetes-namespace: rhdh + spec: + type: operator + owner: cluster-admins + dependencyOf: component:default/roadiehq-argocd + dependsOn: + - resource:default/test-cluster + --- + apiVersion: backstage.io/v1alpha1 + kind: Resource + metadata: + name: argocd-instance + title: ArgoCD + description: ArgoCD instance for GitOps continuous delivery workflows + annotations: + backstage.io/kubernetes-id: argocd-instance + backstage.io/kubernetes-namespace: rhdh + links: + - url: https://argo-cd.readthedocs.io/ + title: Documentation + icon: web + spec: + type: gitops-platform + lifecycle: production + owner: cluster-admins + dependencyOf: component:default/roadiehq-argocd + dependsOn: + - resource:default/argocd-operator + --- + # Jenkins LTS (plain Deployment — no operator) + apiVersion: backstage.io/v1alpha1 + kind: Resource + metadata: + name: jenkins-instance + title: Jenkins LTS + description: Jenkins LTS CI/CD server for build history and pipeline integration with RHDH + annotations: + backstage.io/kubernetes-id: jenkins-instance + backstage.io/kubernetes-namespace: rhdh + links: + - url: https://www.jenkins.io/doc/ + title: Documentation + icon: web + spec: + type: ci-platform + lifecycle: production + owner: cluster-admins + dependencyOf: + - component:default/backstage-community-plugin-jenkins + dependsOn: + - resource:default/test-cluster + --- + # JFrog Artifactory OSS Helm Chart + apiVersion: backstage.io/v1alpha1 + kind: Resource + metadata: + name: jfrog-artifactory-instance + title: JFrog Artifactory OSS + description: JFrog Artifactory OSS artifact repository for container image registry integration with RHDH + annotations: + backstage.io/kubernetes-id: jfrog-artifactory-instance + backstage.io/kubernetes-namespace: rhdh + links: + - url: https://jfrog.com/help/r/jfrog-artifactory-documentation + title: Documentation + icon: web + spec: + type: artifact-registry + lifecycle: production + owner: cluster-admins + dependencyOf: + - component:default/backstage-community-plugin-jfrog-artifactory + dependsOn: + - resource:default/test-cluster + --- + # Lighthouse Audit Service (plain Deployment — no operator) + apiVersion: backstage.io/v1alpha1 + kind: Resource + metadata: + name: lighthouse-instance + title: Lighthouse Audit Service + description: Self-hosted lighthouse-audit-service providing web performance and accessibility audit history for RHDH + annotations: + backstage.io/kubernetes-id: lighthouse-instance + backstage.io/kubernetes-namespace: rhdh + links: + - url: https://github.com/backstage/lighthouse-audit-service + title: Documentation + icon: web + spec: + type: audit-service + lifecycle: production + owner: cluster-admins + dependencyOf: + - component:default/backstage-community-plugin-lighthouse + dependsOn: + - resource:default/test-cluster diff --git a/resources/catalog-entities/plugins.yaml b/resources/catalog-entities/plugins.yaml new file mode 100644 index 0000000..2604012 --- /dev/null +++ b/resources/catalog-entities/plugins.yaml @@ -0,0 +1,20 @@ +kind: ConfigMap +apiVersion: v1 +metadata: + name: plugins-config-map + labels: + backstage.io/kubernetes-id: developer-hub +data: + plugins.yaml: | + apiVersion: backstage.io/v1alpha1 + kind: Location + metadata: + name: plugin-locations + description: A collection of all plugin related catalog entities + spec: + type: url + targets: + - https://github.com/backstage/community-plugins/blob/main/workspaces/keycloak/plugins/catalog-backend-module-keycloak/catalog-info.yaml + - https://github.com/backstage/community-plugins/blob/main/workspaces/lighthouse/plugins/lighthouse/catalog-info.yaml + - https://github.com/backstage/community-plugins/blob/main/workspaces/sonarqube/plugins/sonarqube/catalog-info.yaml + - https://github.com/backstage/community-plugins/blob/main/workspaces/sonarqube/plugins/sonarqube-backend/catalog-info.yaml diff --git a/resources/catalog-entities/resources.yaml b/resources/catalog-entities/resources.yaml new file mode 100644 index 0000000..b943b49 --- /dev/null +++ b/resources/catalog-entities/resources.yaml @@ -0,0 +1,22 @@ +kind: ConfigMap +apiVersion: v1 +metadata: + name: resources-config-map + labels: + backstage.io/kubernetes-id: developer-hub +data: + resources.yaml: | + apiVersion: backstage.io/v1alpha1 + kind: Resource + metadata: + name: minio + title: Minio + description: Open-source object storage server + annotations: + backstage.io/kubernetes-id: minio + spec: + type: object-storage + system: integrations + lifecycle: production + owner: avengers + --- diff --git a/resources/catalog-entities/users.yaml b/resources/catalog-entities/users.yaml new file mode 100644 index 0000000..f513e75 --- /dev/null +++ b/resources/catalog-entities/users.yaml @@ -0,0 +1,17 @@ +kind: ConfigMap +apiVersion: v1 +metadata: + name: users-config-map + labels: + backstage.io/kubernetes-id: developer-hub +data: + users.yaml: | + apiVersion: backstage.io/v1alpha1 + kind: User + metadata: + name: guest + description: Default guest user for unauthenticated access + spec: + profile: + displayName: Guest User + memberOf: [] diff --git a/resources/image-stream-imports/alpine-import.yaml b/resources/image-stream-imports/alpine-import.yaml new file mode 100644 index 0000000..437db5f --- /dev/null +++ b/resources/image-stream-imports/alpine-import.yaml @@ -0,0 +1,22 @@ +apiVersion: image.openshift.io/v1 +kind: ImageStreamImport +metadata: + name: internal-alpine +spec: + import: true + images: + - from: + kind: DockerImage + name: alpine:latest + to: + name: latest + importPolicy: + insecure: false # Set to true if using an insecure registry +--- +apiVersion: image.openshift.io/v1 +kind: ImageStream +metadata: + name: internal-alpine +spec: + lookupPolicy: + local: true # Ensure the image is resolved locally diff --git a/resources/image-stream-imports/keycloak-legacy-import.yaml b/resources/image-stream-imports/keycloak-legacy-import.yaml new file mode 100644 index 0000000..56d618c --- /dev/null +++ b/resources/image-stream-imports/keycloak-legacy-import.yaml @@ -0,0 +1,22 @@ +apiVersion: image.openshift.io/v1 +kind: ImageStreamImport +metadata: + name: internal-keycloak-legacy +spec: + import: true + images: + - from: + kind: DockerImage + name: bitnamilegacy/keycloak:26.3.3-debian-12-r0 + to: + name: latest + importPolicy: + insecure: false # Set to true if using an insecure registry +--- +apiVersion: image.openshift.io/v1 +kind: ImageStream +metadata: + name: internal-keycloak-legacy +spec: + lookupPolicy: + local: true # Ensure the image is resolved locally diff --git a/resources/image-stream-imports/lighthouse-import.yaml b/resources/image-stream-imports/lighthouse-import.yaml new file mode 100644 index 0000000..51f3a3c --- /dev/null +++ b/resources/image-stream-imports/lighthouse-import.yaml @@ -0,0 +1,48 @@ +apiVersion: image.openshift.io/v1 +kind: ImageStreamImport +metadata: + name: internal-lighthouse-audit-service +spec: + import: true + images: + - from: + kind: DockerImage + name: docker.io/spotify/lighthouse-audit-service:latest + to: + name: latest + importPolicy: + insecure: false +--- +apiVersion: image.openshift.io/v1 +kind: ImageStream +metadata: + name: internal-lighthouse-audit-service +spec: + lookupPolicy: + local: true +--- +# PostgreSQL 13 — used as the lighthouse-audit-service backing store. +# bitnami/postgresql is hosted on Docker Hub, so we pre-import it to avoid +# hitting registry rate limits. +apiVersion: image.openshift.io/v1 +kind: ImageStreamImport +metadata: + name: internal-postgres +spec: + import: true + images: + - from: + kind: DockerImage + name: docker.io/postgres:13 + to: + name: "13" + importPolicy: + insecure: false +--- +apiVersion: image.openshift.io/v1 +kind: ImageStream +metadata: + name: internal-postgres +spec: + lookupPolicy: + local: true diff --git a/resources/image-stream-imports/postgesql-legacy-import.yaml b/resources/image-stream-imports/postgesql-legacy-import.yaml new file mode 100644 index 0000000..cd1fbe5 --- /dev/null +++ b/resources/image-stream-imports/postgesql-legacy-import.yaml @@ -0,0 +1,22 @@ +apiVersion: image.openshift.io/v1 +kind: ImageStreamImport +metadata: + name: internal-postgresql-legacy +spec: + import: true + images: + - from: + kind: DockerImage + name: bitnamilegacy/postgresql:17.6.0-debian-12-r4 + to: + name: latest + importPolicy: + insecure: false # Set to true if using an insecure registry +--- +apiVersion: image.openshift.io/v1 +kind: ImageStream +metadata: + name: internal-postgresql-legacy +spec: + lookupPolicy: + local: true # Ensure the image is resolved locally diff --git a/resources/keycloak/dynamic-plugins.yaml b/resources/keycloak/dynamic-plugins.yaml new file mode 100644 index 0000000..21f8c0b --- /dev/null +++ b/resources/keycloak/dynamic-plugins.yaml @@ -0,0 +1,32 @@ +- package: 'oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-catalog-backend-module-keycloak:bs_1.45.3__3.16.0' + disabled: false + pluginConfig: + catalog: + providers: + keycloakOrg: + default: + baseUrl: '${KEYCLOAK_BASE_URL}' + loginRealm: '${KEYCLOAK_LOGIN_REALM}' + realm: '${KEYCLOAK_REALM}' + clientId: '${KEYCLOAK_CLIENT_ID}' + clientSecret: '${KEYCLOAK_CLIENT_SECRET}' + schedule: + frequency: { minutes: 20 } + initialDelay: { seconds: 15 } + timeout: { minutes: 5 } + auth: + environment: production + providers: + oidc: + production: + metadataUrl: '${KEYCLOAK_METADATA_URL}' + clientId: '${KEYCLOAK_CLIENT_ID}' + clientSecret: '${KEYCLOAK_CLIENT_SECRET}' + prompt: auto + callbackUrl: '${RHDH_BASE_URL}/api/auth/oidc/handler/frame' + signIn: + resolvers: + - resolver: emailLocalPartMatchingUserEntityName + guest: + dangerouslyAllowOutsideDevelopment: false + signInPage: oidc diff --git a/resources/keycloak/groups.json b/resources/keycloak/groups.json new file mode 100644 index 0000000..e30ea25 --- /dev/null +++ b/resources/keycloak/groups.json @@ -0,0 +1,9 @@ +[ + {"name": "avengers"}, + {"name": "defenders"}, + {"name": "fantastic-four"}, + {"name": "guardians-of-the-galaxy"}, + {"name": "x-force"}, + {"name": "x-men"}, + {"name": "cluster-admins"} +] diff --git a/utils/keycloak/keycloak-values.yaml b/resources/keycloak/keycloak-values.yaml similarity index 62% rename from utils/keycloak/keycloak-values.yaml rename to resources/keycloak/keycloak-values.yaml index 27db0c6..f3de3f8 100644 --- a/utils/keycloak/keycloak-values.yaml +++ b/resources/keycloak/keycloak-values.yaml @@ -6,15 +6,18 @@ replicaCount: 1 # Use Bitnami legacy repository (Bitnami images moved to bitnamilegacy as of Aug 2025) # Note: Legacy images are not updated/maintained. Consider migrating to official Keycloak image for long-term. +# Images are pre-pulled into the cluster's internal registry via resources/image-stream-imports/ +# to avoid Docker Hub rate limits. The ${NAMESPACE} placeholder is substituted by the deploy script. image: - registry: docker.io - repository: bitnamilegacy/keycloak - tag: "26.3.3-debian-12-r0" + registry: image-registry.openshift-image-registry.svc:5000 + repository: ${NAMESPACE}/internal-keycloak-legacy + tag: latest pullPolicy: IfNotPresent auth: adminUser: admin - adminPassword: admin123 + existingSecret: keycloak-credentials + passwordSecretKey: admin-password service: type: ClusterIP @@ -23,7 +26,7 @@ service: # OpenShift Route configuration route: enabled: true - host: "" # Will be auto-generated by OpenShift + host: '' # Will be auto-generated by OpenShift tls: enabled: false @@ -33,14 +36,15 @@ ingress: postgresql: enabled: true image: - registry: docker.io - repository: bitnamilegacy/postgresql - tag: "17.6.0-debian-12-r4" + registry: image-registry.openshift-image-registry.svc:5000 + repository: ${NAMESPACE}/internal-postgresql-legacy + tag: latest pullPolicy: IfNotPresent auth: - postgresPassword: postgres123 + existingSecret: keycloak-credentials + secretKeys: + userPasswordKey: password username: keycloak - password: keycloak123 database: keycloak primary: resources: @@ -65,18 +69,19 @@ resources: extraEnvVars: - name: KEYCLOAK_ADMIN value: admin - - name: KEYCLOAK_ADMIN_PASSWORD - value: admin123 - name: KC_HOSTNAME_STRICT - value: "false" + value: 'false' - name: KC_HOSTNAME_STRICT_HTTPS - value: "false" + value: 'false' - name: KC_HTTP_ENABLED - value: "true" + value: 'true' - name: KC_PROXY - value: "edge" + value: 'edge' - name: JAVA_OPTS_APPEND - value: "-Djava.net.preferIPv4Stack=true -Xms256m -Xmx512m" + value: '-Djava.net.preferIPv4Stack=true -Xms256m -Xmx512m' + +# KEYCLOAK_ADMIN_PASSWORD is sourced from keycloak-credentials secret at runtime. +extraEnvVarsSecret: keycloak-credentials # Increase probe timeouts for slower startup on resource-constrained clusters livenessProbe: @@ -101,4 +106,4 @@ readinessProbe: # - start-dev # Configuration is now handled by our REST API job in the deployment script -# No keycloakConfigCli needed \ No newline at end of file +# No keycloakConfigCli needed diff --git a/utils/keycloak/rhdh-client.json b/resources/keycloak/rhdh-client.json similarity index 96% rename from utils/keycloak/rhdh-client.json rename to resources/keycloak/rhdh-client.json index 2f5ed39..027915b 100644 --- a/utils/keycloak/rhdh-client.json +++ b/resources/keycloak/rhdh-client.json @@ -9,13 +9,8 @@ "enabled": true, "alwaysDisplayInConsole": false, "clientAuthenticatorType": "client-secret", - "secret": "rhdh-client-secret", - "redirectUris": [ - "*" - ], - "webOrigins": [ - "*" - ], + "redirectUris": [], + "webOrigins": [], "notBefore": 0, "bearerOnly": false, "consentRequired": false, @@ -83,4 +78,4 @@ "configure": true, "manage": true } -} \ No newline at end of file +} diff --git a/resources/keycloak/users.json b/resources/keycloak/users.json new file mode 100644 index 0000000..ab56490 --- /dev/null +++ b/resources/keycloak/users.json @@ -0,0 +1,552 @@ +[ + { + "username": "ant_man", + "firstName": "Scott", + "lastName": "Lang", + "email": "ant_man@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "fantastic-four" + ] + }, + { + "username": "hulk", + "firstName": "Bruce", + "lastName": "Banner", + "email": "hulk@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "defenders" + ] + }, + { + "username": "thor", + "firstName": "Thor", + "lastName": "Odinson", + "email": "thor@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "avengers" + ] + }, + { + "username": "wasp", + "firstName": "Janet", + "lastName": "van Dyne", + "email": "wasp@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "defenders" + ] + }, + { + "username": "captain_america", + "firstName": "Steve", + "lastName": "Rogers", + "email": "captain_america@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "avengers" + ] + }, + { + "username": "hawkeye", + "firstName": "Clint", + "lastName": "Barton", + "email": "hawkeye@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "defenders" + ] + }, + { + "username": "scarlet_witch", + "firstName": "Wanda", + "lastName": "Maximoff", + "email": "scarlet_witch@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "avengers" + ] + }, + { + "username": "black_panther", + "firstName": "King", + "lastName": "T'Challa", + "email": "black_panther@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "avengers" + ] + }, + { + "username": "vision", + "firstName": "Roy", + "lastName": "Thomas", + "email": "vision@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "avengers" + ] + }, + { + "username": "mantis", + "firstName": "Mantis", + "lastName": "Brandt", + "email": "mantis@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "guardians-of-the-galaxy" + ] + }, + { + "username": "beast", + "firstName": "Hank", + "lastName": "McCoy", + "email": "beast@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "x-men" + ] + }, + { + "username": "captain_marvel", + "firstName": "Carol", + "lastName": "Danvers", + "email": "captain_marvel@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "avengers" + ] + }, + { + "username": "she_hulk", + "firstName": "Susan", + "lastName": "Walters", + "email": "she_hulk@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "fantastic-four" + ] + }, + { + "username": "thing", + "firstName": "Ben", + "lastName": "Grim", + "email": "thing@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "fantastic-four" + ] + }, + { + "username": "spiderman", + "firstName": "Peter", + "lastName": "Parker", + "email": "spiderman@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "fantastic-four" + ] + }, + { + "username": "valkyrie", + "firstName": "Brunnhilde", + "lastName": "of Asgard", + "email": "valkyrie@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "defenders" + ] + }, + { + "username": "nova", + "firstName": "Frankie", + "lastName": "Raye", + "email": "nova@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "fantastic-four" + ] + }, + { + "username": "storm", + "firstName": "Ororo", + "lastName": "Munroe", + "email": "storm@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "avengers" + ] + }, + { + "username": "psylocke", + "firstName": "Elizabeth", + "lastName": "Braddock", + "email": "psylocke@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "x-men" + ] + }, + { + "username": "penance", + "firstName": "Monet", + "lastName": "Clarisse", + "email": "penance@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "x-men" + ] + }, + { + "username": "cable", + "firstName": "Nathan", + "lastName": "Christopher", + "email": "cable@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "x-men" + ] + }, + { + "username": "iron_man", + "firstName": "Tony", + "lastName": "Stark", + "email": "iron_man@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "avengers" + ] + }, + { + "username": "cyclops", + "firstName": "Scott", + "lastName": "Summers", + "email": "cyclops@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "x-men" + ] + }, + { + "username": "gambit", + "firstName": "Remy", + "lastName": "LeBeau", + "email": "gambit@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "x-men" + ] + }, + { + "username": "wolverine", + "firstName": "Logan", + "lastName": "Howlett", + "email": "wolverine@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "x-men" + ] + }, + { + "username": "professor_x", + "firstName": "Charles", + "lastName": "Xavier", + "email": "professor_x@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "x-men" + ] + }, + { + "username": "mister_fantastic", + "firstName": "Reed", + "lastName": "Richards", + "email": "mister_fantastic@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "fantastic-four" + ] + }, + { + "username": "invisible_woman", + "firstName": "Sue", + "lastName": "Storm", + "email": "invisible_woman@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "fantastic-four" + ] + }, + { + "username": "human_torch", + "firstName": "Johnny", + "lastName": "Storm", + "email": "human_torch@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "fantastic-four" + ] + }, + { + "username": "starhawk", + "firstName": "Stakar", + "lastName": "of the House of Ogord", + "email": "starhawk@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "guardians-of-the-galaxy" + ] + }, + { + "username": "star_lord", + "firstName": "Peter", + "lastName": "Quill", + "email": "star_lord@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "guardians-of-the-galaxy" + ] + }, + { + "username": "gamora", + "firstName": "Gamora", + "lastName": "Titan", + "email": "gamora@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "guardians-of-the-galaxy" + ] + }, + { + "username": "drax", + "firstName": "Arthur", + "lastName": "Douglas", + "email": "drax@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "guardians-of-the-galaxy" + ] + }, + { + "username": "rocket_raccoon", + "firstName": "Rocket", + "lastName": "Raccoon", + "email": "rocket_raccoon@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "guardians-of-the-galaxy" + ] + }, + { + "username": "adam_warlock", + "firstName": "Adam", + "lastName": "Warlock", + "email": "adam_warlock@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "guardians-of-the-galaxy" + ] + }, + { + "username": "groot", + "firstName": "Groot", + "lastName": "Groot", + "email": "groot@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "guardians-of-the-galaxy" + ] + }, + { + "username": "captain_britain", + "firstName": "Betsy", + "lastName": "Braddock", + "email": "captain_britain@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "x-force" + ] + }, + { + "username": "deadpool", + "firstName": "Wade", + "lastName": "Wilson", + "email": "deadpool@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "x-force" + ] + }, + { + "username": "colossus", + "firstName": "Piotr", + "lastName": "Rasputin", + "email": "colossus@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "x-force" + ] + }, + { + "username": "domino", + "firstName": "Neena", + "lastName": "Thurman", + "email": "domino@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "x-force" + ] + }, + { + "username": "x_23", + "firstName": "Laura", + "lastName": "Kinney", + "email": "x_23@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "x-force" + ] + }, + { + "username": "marvel_girl", + "firstName": "Jean", + "lastName": "Grey", + "email": "marvel_girl@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "x-force" + ] + }, + { + "username": "copycat", + "firstName": "Vanessa", + "lastName": "Carlysle", + "email": "copycat@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "x-force" + ] + }, + { + "username": "bishop", + "firstName": "Lucas", + "lastName": "Bishop", + "email": "bishop@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "x-force" + ] + }, + { + "username": "doctor_strange", + "firstName": "Stephen", + "lastName": "Strange", + "email": "doctor_strange@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "defenders" + ] + }, + { + "username": "silver_surfer", + "firstName": "Norrin", + "lastName": "Radd", + "email": "silver_surfer@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "defenders" + ] + }, + { + "username": "nighthawk", + "firstName": "Kyle", + "lastName": "Richmond", + "email": "nighthawk@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "defenders" + ] + }, + { + "username": "power_man", + "firstName": "Victor", + "lastName": "Alvarez", + "email": "power_man@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "defenders" + ] + }, + { + "username": "admin", + "firstName": "Admin", + "lastName": "Admin", + "email": "admin@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "cluster-admins" + ] + }, + { + "username": "super_user", + "firstName": "Super", + "lastName": "User", + "email": "super_user@example.com", + "enabled": true, + "emailVerified": true, + "groups": [ + "cluster-admins" + ] + } +] diff --git a/resources/lighthouse/dynamic-plugins.yaml b/resources/lighthouse/dynamic-plugins.yaml new file mode 100644 index 0000000..70627c0 --- /dev/null +++ b/resources/lighthouse/dynamic-plugins.yaml @@ -0,0 +1,57 @@ +- package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-lighthouse:bs_1.45.3__0.16.0!backstage-community-plugin-lighthouse + disabled: false + pluginConfig: + dynamicPlugins: + frontend: + backstage-community.plugin-lighthouse: + appIcons: + - name: lighthouse + importName: LighthouseIcon + dynamicRoutes: + - path: /lighthouse + importName: LighthousePage + menuItem: + icon: lighthouse + text: menuItem.lighthouse + textKey: menuItem.lighthouse + mountPoints: + - mountPoint: entity.page.overview/cards + importName: EntityLastLighthouseAuditCard + config: + layout: + gridColumnEnd: + md: span 6 + xs: span 12 + if: + allOf: + - isLighthouseAvailable +- package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-lighthouse-backend:bs_1.45.3__0.17.0!backstage-community-plugin-lighthouse-backend + disabled: false + pluginConfig: + backend: + csp: + # Lighthouse HTML reports contain inline