From b9e480d84d3ab08911af3010019b6b869a4dd824 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Mar 2026 13:58:12 +0000 Subject: [PATCH 01/14] Bump sigstore/cosign-installer from 4.0.0 to 4.1.0 Bumps [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) from 4.0.0 to 4.1.0. - [Release notes](https://github.com/sigstore/cosign-installer/releases) - [Commits](https://github.com/sigstore/cosign-installer/compare/faadad0cce49287aee09b3a48701e75088a2c6ad...ba7bc0a3fef59531c69a25acd34668d6d3fe6f22) --- updated-dependencies: - dependency-name: sigstore/cosign-installer dependency-version: 4.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/build-and-push.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-and-push.yml b/.github/workflows/build-and-push.yml index 2cc6ac9..1512ba8 100644 --- a/.github/workflows/build-and-push.yml +++ b/.github/workflows/build-and-push.yml @@ -116,7 +116,7 @@ jobs: echo "digest=$DIGEST" >> "$GITHUB_OUTPUT" - name: Install cosign - uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0 + uses: sigstore/cosign-installer@ba7bc0a3fef59531c69a25acd34668d6d3fe6f22 # v4.1.0 with: cosign-release: "v2.2.4" From 2c79c72dbfae0cad97e46467a51385f446edf365 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Mar 2026 13:58:19 +0000 Subject: [PATCH 02/14] Bump actions/upload-artifact from 4.6.2 to 7.0.0 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.6.2 to 7.0.0. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/ea165f8d65b6e75b540449e92b4886f43607fa02...bbbca2ddaa5d8feaa63e36b76fdaad77386f024f) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build-and-push.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-and-push.yml b/.github/workflows/build-and-push.yml index 2cc6ac9..902216b 100644 --- a/.github/workflows/build-and-push.yml +++ b/.github/workflows/build-and-push.yml @@ -62,7 +62,7 @@ jobs: buildah push "${CONTAINER}-${TARGETARCH}" "docker-archive:/tmp/image-${TARGETARCH}.tar:${CONTAINER}-${TARGETARCH}" - name: Upload image artifact - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: image-${{ matrix.targetarch }}-${{ github.run_id }} path: /tmp/image-${{ matrix.targetarch }}.tar From c7d33b82feb749650c07e29957d0fbacab62e7d2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 25 Mar 2026 13:56:53 +0000 Subject: [PATCH 03/14] Bump actions/download-artifact from 4.3.0 to 8.0.1 Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4.3.0 to 8.0.1. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/d3f86a106a0bac45b974a628896c90dbdf5c8093...3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-version: 8.0.1 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build-and-push.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-and-push.yml b/.github/workflows/build-and-push.yml index 2cc6ac9..7005afe 100644 --- a/.github/workflows/build-and-push.yml +++ b/.github/workflows/build-and-push.yml @@ -79,13 +79,13 @@ jobs: steps: - name: Download AMD64 image - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: image-amd64-${{ github.run_id }} path: /tmp - name: Download ARM64 image - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: image-arm64-${{ github.run_id }} path: /tmp From d0bbe75f29e27f504a3d84adb1b140386121ae2f Mon Sep 17 00:00:00 2001 From: Michele Baldessari Date: Tue, 31 Mar 2026 16:01:22 +0200 Subject: [PATCH 04/14] Initial schema validation --- Makefile | 10 +++ catalog.schema.json | 34 ++++++++ pattern.schema.json | 187 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 231 insertions(+) create mode 100644 catalog.schema.json create mode 100644 pattern.schema.json diff --git a/Makefile b/Makefile index 6b49502..5a03c52 100644 --- a/Makefile +++ b/Makefile @@ -23,6 +23,16 @@ generate-catalog: ## Generates actual catalog yaml tree generate-dockerfile: ## Generate Dockerfile from template VERSION=$(VERSION) SUPPORTED_OCP_VERSIONS=$(SUPPORTED_OCP_VERSIONS) envsubst < templates/pattern-ui-catalog.Dockerfile.template > $(PATTERN_CATALOG_DOCKERFILE) +.PHONY: schema-validate +schema-validate: ## Validate catalog YAML files against JSON schemas + @command -v check-jsonschema >/dev/null 2>&1 || { echo "Error: check-jsonschema not found. Install with: pip install check-jsonschema"; exit 1; } + check-jsonschema --schemafile catalog.schema.json catalog/catalog.yaml + @for f in catalog/*/pattern.yaml; do \ + echo "Validating $$f..."; \ + check-jsonschema --schemafile pattern.schema.json "$$f"; \ + done + @echo "All catalog files validated successfully." + .PHONY: pattern-ui-catalog-build pattern-ui-catalog-build: generate-dockerfile## Build the pattern catalog image @echo "Building pattern catalog image..." diff --git a/catalog.schema.json b/catalog.schema.json new file mode 100644 index 0000000..2a052af --- /dev/null +++ b/catalog.schema.json @@ -0,0 +1,34 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://validatedpatterns.io/catalog.schema.json", + "title": "Pattern Catalog", + "description": "Schema for the pattern catalog index file (catalog.yaml)", + "type": "object", + "required": ["generated_at", "generator_version", "catalog_description", "patterns"], + "additionalProperties": false, + "properties": { + "generated_at": { + "type": "string", + "description": "ISO 8601 timestamp of catalog generation", + "format": "date-time" + }, + "generator_version": { + "type": "string", + "description": "Version of the catalog generator", + "pattern": "^[0-9]+\\.[0-9]+$" + }, + "catalog_description": { + "type": "string", + "description": "Description shown in the catalog UI" + }, + "patterns": { + "type": "array", + "description": "List of pattern identifiers included in the catalog", + "items": { + "type": "string", + "pattern": "^[a-z][a-z0-9-]*$" + }, + "minItems": 1 + } + } +} diff --git a/pattern.schema.json b/pattern.schema.json new file mode 100644 index 0000000..052ed16 --- /dev/null +++ b/pattern.schema.json @@ -0,0 +1,187 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://validatedpatterns.io/pattern.schema.json", + "title": "Validated Pattern Metadata", + "description": "Schema for validated pattern metadata files (pattern.yaml)", + "type": "object", + "required": [ + "metadata_version", + "name", + "pattern_version", + "display_name", + "repo_url", + "docs_repo_url", + "issues_url", + "docs_url", + "ci_url", + "tier", + "owners", + "requirements", + "extra_features", + "org" + ], + "additionalProperties": false, + "properties": { + "metadata_version": { + "type": "string", + "description": "Version of the metadata format", + "pattern": "^[0-9]+\\.[0-9]+$" + }, + "name": { + "type": "string", + "description": "Unique identifier for the pattern", + "pattern": "^[a-z][a-z0-9-]*$" + }, + "description": { + "type": "string", + "description": "A short description of the pattern" + }, + "pattern_version": { + "type": "string", + "description": "Version of the pattern", + "pattern": "^[0-9]+\\.[0-9]+$" + }, + "display_name": { + "type": "string", + "description": "Human-readable display name" + }, + "repo_url": { + "type": "string", + "description": "URL to the pattern repository", + "format": "uri" + }, + "docs_repo_url": { + "type": "string", + "description": "URL to the documentation repository", + "format": "uri" + }, + "issues_url": { + "type": "string", + "description": "URL to the issue tracker", + "format": "uri" + }, + "docs_url": { + "type": "string", + "description": "URL to the pattern documentation", + "format": "uri" + }, + "ci_url": { + "type": "string", + "description": "URL to the CI/CD pipeline", + "format": "uri" + }, + "tier": { + "type": "string", + "description": "Support tier for the pattern", + "enum": ["maintained", "tested", "sandbox"] + }, + "owners": { + "type": "array", + "description": "List of pattern owners (GitHub usernames)", + "items": { + "type": "string" + }, + "minItems": 1 + }, + "requirements": { + "type": "object", + "description": "Infrastructure requirements for the pattern", + "required": ["hub"], + "additionalProperties": false, + "properties": { + "hub": { + "$ref": "#/$defs/clusterRequirements" + }, + "spoke": { + "$ref": "#/$defs/clusterRequirements" + } + } + }, + "extra_features": { + "type": "object", + "description": "Additional feature flags", + "required": ["hypershift_support", "spoke_support"], + "additionalProperties": false, + "properties": { + "hypershift_support": { + "type": "boolean" + }, + "spoke_support": { + "type": "boolean" + } + } + }, + "external_requirements": { + "description": "Additional external requirements or null", + "oneOf": [ + { "type": "null" }, + { + "type": "object", + "properties": { + "cluster_sizing_note": { + "type": "string", + "description": "Additional notes about cluster sizing" + } + }, + "additionalProperties": false + } + ] + }, + "org": { + "type": "string", + "description": "GitHub organization name" + }, + "spoke": { + "description": "Spoke configuration (reserved for future use)", + "type": "null" + } + }, + "$defs": { + "cloudProviderSpec": { + "type": "object", + "required": ["replicas", "type"], + "additionalProperties": false, + "properties": { + "replicas": { + "type": "integer", + "minimum": 0, + "description": "Number of replicas" + }, + "type": { + "type": "string", + "description": "Instance/machine type" + } + } + }, + "nodePoolSpec": { + "type": "object", + "additionalProperties": false, + "minProperties": 1, + "properties": { + "aws": { + "$ref": "#/$defs/cloudProviderSpec" + }, + "gcp": { + "$ref": "#/$defs/cloudProviderSpec" + }, + "azure": { + "$ref": "#/$defs/cloudProviderSpec" + } + } + }, + "clusterRequirements": { + "type": "object", + "description": "Requirements for a cluster (hub or spoke)", + "required": ["compute", "controlPlane"], + "additionalProperties": false, + "properties": { + "compute": { + "$ref": "#/$defs/nodePoolSpec" + }, + "controlPlane": { + "$ref": "#/$defs/nodePoolSpec" + } + } + } + } +} From b577f9b0249a9ba917001b8e889774641e95dade Mon Sep 17 00:00:00 2001 From: Michele Baldessari Date: Tue, 31 Mar 2026 16:02:59 +0200 Subject: [PATCH 05/14] Add action to check for json schema --- .github/workflows/jsonschema.yaml | 51 +++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 .github/workflows/jsonschema.yaml diff --git a/.github/workflows/jsonschema.yaml b/.github/workflows/jsonschema.yaml new file mode 100644 index 0000000..c65e401 --- /dev/null +++ b/.github/workflows/jsonschema.yaml @@ -0,0 +1,51 @@ +--- +name: Verify json schema + +on: + push: + paths: + - '.github/workflows/jsonschema.yaml' + - 'catalog/**' + - '*.schema.json' + pull_request: + paths: + - '.github/workflows/jsonschema.yaml' + - 'catalog/**' + - '*.schema.json' + +permissions: read-all # zizmor: ignore[excessive-permissions] + +jobs: + jsonschema_tests: + name: Json Schema tests + strategy: + matrix: + python-version: [3.11.3] + runs-on: ubuntu-latest + + steps: + - name: Checkout Code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install check-jsonschema + + - name: Validate catalog.yaml + run: | + check-jsonschema --schemafile catalog.schema.json catalog/catalog.yaml + + - name: Validate pattern metadata files + run: | + for f in catalog/*/pattern.yaml; do + echo "Validating ${f}..." + check-jsonschema --schemafile pattern.schema.json "${f}" + done From d8ff19fc786c892cfebcddf57af96984567cce0a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Apr 2026 13:58:14 +0000 Subject: [PATCH 06/14] Bump sigstore/cosign-installer from 4.1.0 to 4.1.1 Bumps [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) from 4.1.0 to 4.1.1. - [Release notes](https://github.com/sigstore/cosign-installer/releases) - [Commits](https://github.com/sigstore/cosign-installer/compare/ba7bc0a3fef59531c69a25acd34668d6d3fe6f22...cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003) --- updated-dependencies: - dependency-name: sigstore/cosign-installer dependency-version: 4.1.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/build-and-push.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-and-push.yml b/.github/workflows/build-and-push.yml index 88f6181..d370251 100644 --- a/.github/workflows/build-and-push.yml +++ b/.github/workflows/build-and-push.yml @@ -116,7 +116,7 @@ jobs: echo "digest=$DIGEST" >> "$GITHUB_OUTPUT" - name: Install cosign - uses: sigstore/cosign-installer@ba7bc0a3fef59531c69a25acd34668d6d3fe6f22 # v4.1.0 + uses: sigstore/cosign-installer@cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003 # v4.1.1 with: cosign-release: "v2.2.4" From fc2654f7122e100841fe0a493dae8b9955fea631 Mon Sep 17 00:00:00 2001 From: Akos Eros Date: Mon, 13 Apr 2026 10:34:26 +0200 Subject: [PATCH 07/14] feat: Add list make target, change org var to overridable --- Makefile | 4 ++++ generate-catalog.sh | 2 +- list-all-patterns.sh | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 5a03c52..1b3cd3f 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,10 @@ help: ## Display this help. ##@ Pattern Catalog +.PHONY: list-patterns +list-patterns: ## Lists all pattern repos + ./list-all-patterns.sh + .PHONY: generate-catalog generate-catalog: ## Generates actual catalog yaml tree ./generate-catalog.sh diff --git a/generate-catalog.sh b/generate-catalog.sh index 6d2b277..b6c4ab6 100755 --- a/generate-catalog.sh +++ b/generate-catalog.sh @@ -10,7 +10,7 @@ set -o pipefail # # Dependencies: gh, yq (v4+), jq, base64 -ORGS=("validatedpatterns" "validatedpatterns-sandbox") +ORGS=(${ORGS[@]:-"validatedpatterns" "validatedpatterns-sandbox"}) TOPIC=${TOPIC:-pattern} GENERATOR_VERSION="1.0" CATALOG_DIR="catalog" diff --git a/list-all-patterns.sh b/list-all-patterns.sh index 4ab39fe..6db50aa 100755 --- a/list-all-patterns.sh +++ b/list-all-patterns.sh @@ -5,7 +5,7 @@ set -o pipefail # - validatedpatterns # - validatedpatterns-sandbox -ORGS=("validatedpatterns" "validatedpatterns-sandbox") +ORGS=(${ORGS[@]:-"validatedpatterns" "validatedpatterns-sandbox"}) TOPIC=${TOPIC:-pattern} for org in ${ORGS[@]}; do From 562d59fc9b7a622eb02e64e5c00ee9af701f957e Mon Sep 17 00:00:00 2001 From: Michele Baldessari Date: Wed, 15 Apr 2026 13:33:58 +0200 Subject: [PATCH 08/14] Add somre readme improvements for custom catalog --- README.md | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 167 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index b279749..aca302c 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,9 @@ A catalog of [Validated Patterns](https://validatedpatterns.io) metadata, served The `generate-catalog.sh` script queries the GitHub API for all repositories tagged with `pattern` in the `validatedpatterns` and `validatedpatterns-sandbox` organizations. For each repository it: 1. Fetches `pattern-metadata.yaml` and normalizes it into a consistent schema -2. Fetches `values-secret.yaml.template` if present -3. Writes per-pattern files under `catalog//` -4. Generates a `catalog/catalog.yaml` index listing all discovered patterns +1. Fetches `values-secret.yaml.template` if present +1. Writes per-pattern files under `catalog//` +1. Generates a `catalog/catalog.yaml` index listing all discovered patterns The resulting `catalog/` directory is served by an nginx container image that the patterns-operator deploys on-cluster. @@ -55,16 +55,175 @@ pushes to `main` or `stable-v1` when files in `catalog/`, `templates/`, or the workflow itself change: 1. **validate-yaml** — validates all YAML files under `catalog/` with `yamllint` -2. **build-container** — builds the image for amd64 and arm64 in parallel on native runners -3. **push-multiarch-manifest** — assembles a multi-arch manifest, pushes to Quay, and signs with cosign (only in the upstream `validatedpatterns/pattern-ui-catalog` repo) +1. **build-container** — builds the image for amd64 and arm64 in parallel on native runners +1. **push-multiarch-manifest** — assembles a multi-arch manifest, pushes to Quay, and signs with cosign (only in the upstream `validatedpatterns/pattern-ui-catalog` repo) -| Branch | Image tag | +| Branch | Image tag | |-------------|---------------| -| `main` | `:latest` | -| `stable-v1` | `:stable-v1` | +| `main` | `:latest` | +| `stable-v1` | `:stable-v1` | The workflow requires `QUAY_USERNAME` and `QUAY_PASSWORD` secrets configured in a `quay` environment. +## Creating a custom catalog + +You can build your own catalog image containing a curated set of patterns. This +is useful when you maintain internal or third-party patterns that are not part of +the upstream `validatedpatterns` organizations. + +### 1. Prepare the catalog directory + +Create a `catalog/` tree with the following structure: + +```txt +catalog/ + catalog.yaml + my-pattern/pattern.yaml + my-pattern/values-secret.yaml.template # optional + another-pattern/pattern.yaml +``` + +**`catalog/catalog.yaml`** — the index file listing every pattern in the catalog: + +```yaml +generated_at: "2026-04-15T00:00:00Z" +generator_version: "1.0" +catalog_description: "My custom pattern catalog" +patterns: + - my-pattern + - another-pattern +``` + +**`catalog//pattern.yaml`** — metadata for each pattern. Required fields +are defined by `pattern.schema.json`; a minimal example: + +```yaml +metadata_version: "1.0" +name: my-pattern +pattern_version: "1.0" +display_name: My Pattern +repo_url: https://github.com/my-org/my-pattern +docs_repo_url: https://github.com/my-org/my-pattern-docs +issues_url: https://github.com/my-org/my-pattern/issues +docs_url: https://my-org.github.io/my-pattern/ +ci_url: https://my-org.github.io/my-pattern/ci +tier: sandbox # maintained | tested | sandbox +owners: + - my-github-user +requirements: + hub: + compute: + aws: + replicas: 3 + type: m5.2xlarge + controlPlane: + aws: + replicas: 3 + type: m5.xlarge +extra_features: + hypershift_support: false + spoke_support: false +external_requirements: null +org: my-org +spoke: null +``` + +You can optionally validate your files against the JSON schemas shipped in this +repository: + +```sh +make schema-validate +``` + +### 2. Build and push the image + +Override `UPLOADREGISTRY` (and optionally `VERSION`) to point at your own +registry: + +```sh +make UPLOADREGISTRY=quay.io/my-org VERSION=1.0.0 pattern-ui-catalog-build +make UPLOADREGISTRY=quay.io/my-org VERSION=1.0.0 pattern-ui-catalog-push +``` + +This produces `quay.io/my-org/pattern-ui-catalog:1.0.0`. + +### 3. Point the patterns-operator at your catalog image + +The [patterns-operator](https://github.com/validatedpatterns/patterns-operator) +reads an optional `catalog.image` key from its ConfigMap. By default it deploys +`quay.io/validatedpatterns/pattern-ui-catalog:stable-v1`. To override it, patch +(or create) the `patterns-operator-config` ConfigMap in the operator namespace +(`patterns-operator` by default): + +```sh +oc patch configmap patterns-operator-config \ + -n patterns-operator \ + --type merge \ + -p '{"data":{"catalog.image":"quay.io/my-org/pattern-ui-catalog:1.0.0"}}' +``` + +If the ConfigMap does not exist yet: + +```sh +oc create configmap patterns-operator-config \ + -n patterns-operator \ + --from-literal=catalog.image=quay.io/my-org/pattern-ui-catalog:1.0.0 +``` + +The operator picks up the change on its next reconciliation loop and performs a +rolling update of the catalog deployment. + +## Authenticated container registries + +If your custom catalog image is hosted on a registry that requires +authentication (e.g. a private Quay repository), you need to configure a pull +secret so that the cluster can pull the image. + +### 1. Create a pull secret + +Create an authentication secret in the operator namespace: + +```sh +oc create secret docker-registry my-catalog-pull-secret \ + -n patterns-operator \ + --docker-server=quay.io \ + --docker-username='' \ + --docker-password='' +``` + +### 2. Link the secret to the operator service account + +The catalog deployment runs under the `patterns-operator-controller-manager` +service account. Link the pull secret to it: + +```sh +oc secrets link patterns-operator-controller-manager my-catalog-pull-secret \ + -n patterns-operator \ + --for=pull +``` + +### 3. Alternative: global pull secret + +If multiple workloads need access to the same registry, you can add the +credentials to the cluster-wide pull secret instead. Extract the current secret, +merge your credentials, and apply: + +```sh +oc get secret/pull-secret -n openshift-config --template='{{index .data ".dockerconfigjson" | base64decode}}' > /tmp/pull-secret.json + +# Authenticate to your registry (this merges the new entry into the file) +oc registry login --registry=quay.io \ + --auth-basic=':' \ + --to=/tmp/pull-secret.json + +oc set data secret/pull-secret -n openshift-config \ + --from-file=.dockerconfigjson=/tmp/pull-secret.json +``` + +> **Note:** Updating the global pull secret triggers a rolling reboot of all +> nodes in the cluster. Prefer the per-service-account approach when only the +> catalog needs access. + ## Repository structure ``` From 666bfc791be12df8c3f319e7bae264ca4681eac4 Mon Sep 17 00:00:00 2001 From: Michele Baldessari Date: Wed, 15 Apr 2026 13:57:36 +0200 Subject: [PATCH 09/14] Add custom github org mention and values secret mention --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index aca302c..9405951 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,22 @@ You can build your own catalog image containing a curated set of patterns. This is useful when you maintain internal or third-party patterns that are not part of the upstream `validatedpatterns` organizations. +If the patterns you want to include are all hosted on GitHub you can just run the +following script: + +```sh +TOPIC=pattern ORGS="org1 org2" make generate-catalog +``` + +The above script will generate the catalog bit by using +any repo with the `pattern` topic (topics are some sort of tags on GitHub) +in `org1` and `org2` on github. Then you can just skip to section +[Build and push the image](#2-build-and-push-the-image). + +```sh +make UPLOADREGISTRY=quay.io/ pattern-ui-catalog-build pattern-ui-catalog-push +``` + ### 1. Prepare the catalog directory Create a `catalog/` tree with the following structure: @@ -128,6 +144,9 @@ org: my-org spoke: null ``` +**`catalog//values-secret.yaml.template`** - metadata for secret material +for the pattern. See [here](https://validatedpatterns.io/learn/secrets-management-in-the-validated-patterns-framework/) for more information. + You can optionally validate your files against the JSON schemas shipped in this repository: From e483f13f64ef293331fe354d5a98402763816b3e Mon Sep 17 00:00:00 2001 From: Michele Baldessari Date: Wed, 15 Apr 2026 15:38:08 +0200 Subject: [PATCH 10/14] Use ui-catalog-enabled as the topic to detect viable repos --- generate-catalog.sh | 2 +- list-all-patterns.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/generate-catalog.sh b/generate-catalog.sh index b6c4ab6..6ae843e 100755 --- a/generate-catalog.sh +++ b/generate-catalog.sh @@ -11,7 +11,7 @@ set -o pipefail # Dependencies: gh, yq (v4+), jq, base64 ORGS=(${ORGS[@]:-"validatedpatterns" "validatedpatterns-sandbox"}) -TOPIC=${TOPIC:-pattern} +TOPIC=${TOPIC:-"ui-catalog-enabled"} GENERATOR_VERSION="1.0" CATALOG_DIR="catalog" diff --git a/list-all-patterns.sh b/list-all-patterns.sh index 6db50aa..c45c586 100755 --- a/list-all-patterns.sh +++ b/list-all-patterns.sh @@ -6,7 +6,7 @@ set -o pipefail # - validatedpatterns-sandbox ORGS=(${ORGS[@]:-"validatedpatterns" "validatedpatterns-sandbox"}) -TOPIC=${TOPIC:-pattern} +TOPIC=${TOPIC:-"ui-catalog-enabled"} for org in ${ORGS[@]}; do REPOS=$(gh repo list "${org}" --no-archived --topic "${TOPIC}" --visibility public --limit 100 |awk '{ print $1 }' | sort) From 785727841f344a9b33560e593b6cbd7eedab533a Mon Sep 17 00:00:00 2001 From: Michele Baldessari Date: Thu, 16 Apr 2026 09:25:04 +0200 Subject: [PATCH 11/14] Update catalog --- catalog/catalog.yaml | 9 +- catalog/hypershift/pattern.yaml | 42 ++ .../hypershift/values-secret.yaml.template | 52 +++ catalog/industrial-edge/pattern.yaml | 62 --- .../values-secret.yaml.template | 14 - catalog/layered-zero-trust/pattern.yaml | 63 +++ .../values-secret.yaml.template | 372 ++++++++++++++++++ catalog/medical-diagnosis/pattern.yaml | 40 -- .../values-secret.yaml.template | 45 --- catalog/mlops-fraud-detection/pattern.yaml | 41 ++ catalog/openshift-ai/pattern.yaml | 40 -- .../openshift-ai/values-secret.yaml.template | 38 -- catalog/travelops/pattern.yaml | 42 ++ catalog/travelops/values-secret.yaml.template | 24 ++ 14 files changed, 641 insertions(+), 243 deletions(-) create mode 100644 catalog/hypershift/pattern.yaml create mode 100644 catalog/hypershift/values-secret.yaml.template delete mode 100644 catalog/industrial-edge/pattern.yaml delete mode 100644 catalog/industrial-edge/values-secret.yaml.template create mode 100644 catalog/layered-zero-trust/pattern.yaml create mode 100644 catalog/layered-zero-trust/values-secret.yaml.template delete mode 100644 catalog/medical-diagnosis/pattern.yaml delete mode 100644 catalog/medical-diagnosis/values-secret.yaml.template create mode 100644 catalog/mlops-fraud-detection/pattern.yaml delete mode 100644 catalog/openshift-ai/pattern.yaml delete mode 100644 catalog/openshift-ai/values-secret.yaml.template create mode 100644 catalog/travelops/pattern.yaml create mode 100644 catalog/travelops/values-secret.yaml.template diff --git a/catalog/catalog.yaml b/catalog/catalog.yaml index 1546fe7..885bfcf 100644 --- a/catalog/catalog.yaml +++ b/catalog/catalog.yaml @@ -1,10 +1,11 @@ -generated_at: "2026-03-13T15:39:18Z" +generated_at: "2026-04-16T07:24:39Z" generator_version: "1.0" catalog_description: 'Additional patterns can be found here: validatedpatterns.io' patterns: - ansible-edge-gitops - - industrial-edge - - medical-diagnosis + - layered-zero-trust + - mlops-fraud-detection - multicloud-gitops - rag-llm-gitops - - openshift-ai + - travelops + - hypershift diff --git a/catalog/hypershift/pattern.yaml b/catalog/hypershift/pattern.yaml new file mode 100644 index 0000000..afbe217 --- /dev/null +++ b/catalog/hypershift/pattern.yaml @@ -0,0 +1,42 @@ +metadata_version: "1.0" +name: hypershift +description: An infrastructure pattern for deploying and managing OpenShift clusters using HyperShift. +pattern_version: "1.0" +display_name: HyperShift +repo_url: https://github.com/validatedpatterns-sandbox/hypershift +docs_repo_url: https://github.com/validatedpatterns/docs +issues_url: https://github.com/validatedpatterns-sandbox/hypershift/issues +docs_url: https://validatedpatterns.io/patterns/hypershift/ +ci_url: https://validatedpatterns.io/ci/?pattern=hypershift +tier: tested +owners: + - day0hero +requirements: + hub: + compute: + gcp: + replicas: 3 + type: n1-standard-8 + azure: + replicas: 3 + type: Standard_D8s_v3 + aws: + replicas: 3 + type: m5.4xlarge + controlPlane: + gcp: + replicas: 3 + type: n1-standard-4 + azure: + replicas: 3 + type: Standard_D4s_v3 + aws: + replicas: 3 + type: m5.2xlarge +extra_features: + hypershift_support: true + spoke_support: false +external_requirements: null +s3 bucket: true +org: validatedpatterns-sandbox +spoke: null diff --git a/catalog/hypershift/values-secret.yaml.template b/catalog/hypershift/values-secret.yaml.template new file mode 100644 index 0000000..a2be8ec --- /dev/null +++ b/catalog/hypershift/values-secret.yaml.template @@ -0,0 +1,52 @@ +# A more formal description of this format can be found here: +# https://github.com/hybrid-cloud-patterns/common/tree/main/ansible/roles/vault_utils#values-secret-file-format + +version: "2.0" +# Ideally you NEVER COMMIT THESE VALUES TO GIT (although if all passwords are +# automatically generated inside the vault this should not really matter) + +secrets: + - name: aws + fields: + - name: AWS_ACCESS_KEY_ID + ini_file: ~/.aws/credentials + ini_section: default + ini_key: aws_access_key_id + - name: AWS_SECRET_ACCESS_KEY + ini_file: ~/.aws/credentials + ini_key: aws_secret_access_key + - name: awsCreds + fields: + - name: credentials + path: ~/.aws/credentials +# Begin groupsync/oauth config +# - name: oauthCreds +# fields: +# - name: content +# path: ~/.oauth +# - name: githubGroupSync +# fields: +# - name: appId +# value: "gh-app-appId" +# - name: installationId +# value: "gh-app-installationID" +# - name: privateKey +# path: ~/.github-group-sync.pem +# +# End groupsync/oauth config + #- name: publickey + # fields: + # - name: content + # path: ~/.ssh/id_rsa.pub + #- name: privatekey + # fields: + # - name: content + # path: ~/.ssh/id_rsa + #- name: openshiftPullSecret + # fields: + # - name: content + # path: ~/.pullsecret.json + +# Examples: +# ~/.oauth +# 123456789abcdefghijklmnop123456789abcdef diff --git a/catalog/industrial-edge/pattern.yaml b/catalog/industrial-edge/pattern.yaml deleted file mode 100644 index 5ea3987..0000000 --- a/catalog/industrial-edge/pattern.yaml +++ /dev/null @@ -1,62 +0,0 @@ -metadata_version: "1.0" -name: industrial-edge -pattern_version: "2.0" -display_name: Industrial Edge -repo_url: https://github.com/validatedpatterns/industrial-edge -docs_repo_url: https://github.com/validatedpatterns/docs -issues_url: https://github.com/validatedpatterns/industrial-edge/issues -docs_url: https://validatedpatterns.io/patterns/industrial-edge/ -ci_url: https://validatedpatterns.io/ci/?pattern=industrialedge -tier: tested -owners: - - mbaldessari - - darkdoc -requirements: - hub: - compute: - gcp: - replicas: 5 - type: n1-standard-16 - azure: - replicas: 5 - type: Standard_D16s_v5 - aws: - replicas: 4 - type: m5.4xlarge - controlPlane: - gcp: - replicas: 3 - type: n1-standard-16 - azure: - replicas: 3 - type: Standard_D16s_v3 - aws: - replicas: 3 - type: m5.4xlarge - spoke: - compute: - gcp: - replicas: 3 - type: n1-standard-16 - azure: - replicas: 3 - type: Standard_D16s_v5 - aws: - replicas: 3 - type: m5.2xlarge - controlPlane: - gcp: - replicas: 3 - type: n1-standard-16 - azure: - replicas: 3 - type: Standard_D16s_v5 - aws: - replicas: 3 - type: m5.2xlarge -extra_features: - hypershift_support: false - spoke_support: true -external_requirements: null -org: validatedpatterns -spoke: null diff --git a/catalog/industrial-edge/values-secret.yaml.template b/catalog/industrial-edge/values-secret.yaml.template deleted file mode 100644 index a6d3417..0000000 --- a/catalog/industrial-edge/values-secret.yaml.template +++ /dev/null @@ -1,14 +0,0 @@ -version: "2.0" -secrets: -# uncomment this if global.imageregistry.type is quay -# - name: imageregistry -# fields: -# # eg. Quay -> Robot Accounts -> Robot Login -# - name: username -# onMissingValue: prompt -# value: null -# prompt: "Insert Quay Username" -# - name: password -# onMissingValue: prompt -# value: null -# prompt: "Insert Quay Password" diff --git a/catalog/layered-zero-trust/pattern.yaml b/catalog/layered-zero-trust/pattern.yaml new file mode 100644 index 0000000..e681f8c --- /dev/null +++ b/catalog/layered-zero-trust/pattern.yaml @@ -0,0 +1,63 @@ +metadata_version: "1.0" +name: layered-zero-trust +description: The Layered Zero Trust pattern shows how to implement zero trust in a Red Hat OpenShift environment. +pattern_version: "1.0" +display_name: Layered Zero Trust +repo_url: https://github.com/validatedpatterns/layered-zero-trust +docs_repo_url: https://github.com/validatedpatterns/docs +issues_url: https://github.com/validatedpatterns/layered-zero-trust/issues +docs_url: https://validatedpatterns.io/patterns/layered-zero-trust/ +ci_url: https://validatedpatterns.io/ci/?pattern=layeredzerotrust +tier: tested +owners: + - sabre1041 + - michaelepley +requirements: + hub: + compute: + gcp: + replicas: 3 + type: n1-standard-8 + azure: + replicas: 3 + type: Standard_D8s_v3 + aws: + replicas: 3 + type: m5.2xlarge + controlPlane: + gcp: + replicas: 3 + type: n1-standard-4 + azure: + replicas: 3 + type: Standard_D4s_v3 + aws: + replicas: 3 + type: m5.xlarge + spoke: + compute: + gcp: + replicas: 0 + type: n1-standard-8 + azure: + replicas: 0 + type: Standard_D8s_v3 + aws: + replicas: 0 + type: m5.2xlarge + controlPlane: + gcp: + replicas: 3 + type: n1-standard-8 + azure: + replicas: 3 + type: Standard_D8s_v3 + aws: + replicas: 3 + type: m5.2xlarge +extra_features: + hypershift_support: true + spoke_support: true +external_requirements: null +org: validatedpatterns +spoke: null diff --git a/catalog/layered-zero-trust/values-secret.yaml.template b/catalog/layered-zero-trust/values-secret.yaml.template new file mode 100644 index 0000000..9185fc4 --- /dev/null +++ b/catalog/layered-zero-trust/values-secret.yaml.template @@ -0,0 +1,372 @@ +# A more formal description of this format can be found here: +# https://github.com/validatedpatterns/rhvp.cluster_utils/tree/main/roles/vault_utils#values-secret-file-format + +version: "2.0" +# Ideally you NEVER COMMIT THESE VALUES TO GIT (although if all passwords are +# automatically generated inside the vault this should not really matter) + +# Vault Secret Organization: +# -------------------------- +# Secrets are organized for least-privilege access: +# +# Application Secrets (fine-grained isolation): +# apps/qtodo/ - QTodo application secrets (app-level isolation) +# apps// - Add your app here for isolated secrets +# +# Infrastructure Secrets (hub/infra/*): +# hub/infra/keycloak/ - Keycloak infrastructure secrets +# hub/infra/rhtpa/ - RHTPA infrastructure secrets +# hub/infra/quay/ - Quay registry credentials +# hub/infra/users/ - User credentials managed by IdP +# +# Framework Secrets: +# global/ - VP framework default (config-demo, etc.) +# +# Each path has a corresponding Vault policy granting access ONLY to its +# specific path (e.g., apps-qtodo-secret grants read to secret/data/apps/qtodo/*). + +vaultPolicies: + basicPolicy: | + length=10 + rule "charset" { charset = "abcdefghijklmnopqrstuvwxyz" min-chars = 1 } + rule "charset" { charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" min-chars = 1 } + rule "charset" { charset = "0123456789" min-chars = 1 } + + advancedPolicy: | + length=20 + rule "charset" { charset = "abcdefghijklmnopqrstuvwxyz" min-chars = 1 } + rule "charset" { charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" min-chars = 1 } + rule "charset" { charset = "0123456789" min-chars = 1 } + rule "charset" { charset = "!@#^&*" min-chars = 1 } + + alphaNumericPolicy: | + length=32 + rule "charset" { charset = "abcdefghijklmnopqrstuvwxyz" min-chars = 1 } + rule "charset" { charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" min-chars = 1 } + rule "charset" { charset = "0123456789" min-chars = 1 } + +secrets: + # =========================================================================== + # GLOBAL SECRETS (global/) + # VP framework default path for demo/test secrets + # =========================================================================== + - name: config-demo + vaultPrefixes: + - global + fields: + - name: secret + onMissingValue: generate + vaultPolicy: validatedPatternDefaultPolicy + + # =========================================================================== + # QTODO APPLICATION SECRETS (apps/qtodo/) + # Secrets specific to the QTodo application - isolated at app level + # Policy: apps-qtodo-secret (read access to apps/qtodo/*) + # =========================================================================== + - name: qtodo-db + vaultPrefixes: + - apps/qtodo + fields: + - name: admin-password + onMissingValue: generate + vaultPolicy: validatedPatternDefaultPolicy + - name: db-password + onMissingValue: generate + vaultPolicy: validatedPatternDefaultPolicy + + # qtodo-oidc-client secret is no longer needed — qtodo now authenticates + # to Keycloak using SPIFFE JWT SVID (federated client assertion) + #- name: qtodo-oidc-client + # vaultPrefixes: + # - apps/qtodo + # fields: + # - name: client-secret + # onMissingValue: generate + # vaultPolicy: alphaNumericPolicy + + - name: qtodo-truststore + vaultPrefixes: + - apps/qtodo + fields: + - name: truststore-password + onMissingValue: generate + vaultPolicy: alphaNumericPolicy + + # =========================================================================== + # ACS Secrets (Uncomment to enable) + # =========================================================================== + - name: acs-central + vaultPrefixes: + - hub/infra/acs + fields: + - name: admin-password + onMissingValue: generate + vaultPolicy: validatedPatternDefaultPolicy + + # NOTE: Init bundle is NOT needed for same-cluster deployments. + # The RHACS operator auto-generates authentication when Central and + # SecuredCluster are on the same cluster. Only uncomment for multi-cluster + # scenarios where you need to connect remote secured clusters. + #- name: acs-init-bundle + # vaultPrefixes: + # - hub/infra/acs + # fields: + # - name: init-bundle + # onMissingValue: ignore # Must be generated manually via roxctl + + # =========================================================================== + # KEYCLOAK INFRASTRUCTURE SECRETS (hub/infra/keycloak/) + # Secrets for Keycloak infrastructure deployment + # Policy: hub-infra-keycloak-secret (read access to hub/infra/keycloak/*) + # =========================================================================== + - name: keycloak + vaultPrefixes: + - hub/infra/keycloak + fields: + - name: admin-password + onMissingValue: generate + vaultPolicy: validatedPatternDefaultPolicy + - name: db-password + onMissingValue: generate + vaultPolicy: validatedPatternDefaultPolicy + + # =========================================================================== + # RHTPA INFRASTRUCTURE SECRETS (hub/infra/rhtpa/) + # Secrets for Red Hat Trusted Profile Analyzer infrastructure + # Policy: hub-infra-rhtpa-secret (read access to hub/infra/rhtpa/*) + # =========================================================================== + - name: rhtpa-db + vaultPrefixes: + - hub/infra/rhtpa + fields: + - name: db-password + onMissingValue: generate + vaultPolicy: alphaNumericPolicy + + - name: rhtpa-oidc-cli + vaultPrefixes: + - hub/infra/rhtpa + fields: + - name: client-secret + onMissingValue: generate + vaultPolicy: alphaNumericPolicy + + # =========================================================================== + # USER CREDENTIALS (hub/infra/users/) + # User passwords managed by Keycloak for application access + # Policy: hub-infra-users-secret (Keycloak needs to provision these) + # =========================================================================== + - name: keycloak-users + vaultPrefixes: + - hub/infra/users + fields: + - name: qtodo-admin-password + onMissingValue: generate + vaultPolicy: validatedPatternDefaultPolicy + - name: qtodo-user1-password + onMissingValue: generate + vaultPolicy: validatedPatternDefaultPolicy + - name: rhtas-user-password + onMissingValue: generate + vaultPolicy: validatedPatternDefaultPolicy + - name: rhtpa-user-password + onMissingValue: generate + vaultPolicy: alphaNumericPolicy + + # =========================================================================== + # QUAY INFRASTRUCTURE SECRETS (hub/infra/quay/) + # Registry credentials for Quay + # Policy: hub-infra-quay-secret (read access to hub/infra/quay/*) + # =========================================================================== + - name: quay-users + vaultPrefixes: + - hub/infra/quay + fields: + - name: quay-admin-password + onMissingValue: generate + vaultPolicy: validatedPatternDefaultPolicy + - name: quay-user-password + onMissingValue: generate + vaultPolicy: validatedPatternDefaultPolicy + + # External Registry Credentials (e.g., Quay.io, Docker Hub, GHCR) + # Reserved for future use with container signing workflows + # Uncomment and provide your credentials when needed + #- name: external-registry + # vaultPrefixes: + # - hub/infra + # fields: + # - name: username + # value: "your-registry-username" # Replace with your username + # onMissingValue: error + # - name: password + # value: "your-registry-token" # Replace with your token/password + # onMissingValue: error + + # =========================================================================== + # COCO (CONFIDENTIAL CONTAINERS) SECRETS + # Uncomment the secrets below when deploying with CoCo support. + # Pre-deployment steps: + # 1. Run ./scripts/gen-secrets-coco.sh to generate KBS keypair + # 2. Run ./scripts/get-pcr.sh to retrieve PCR measurements + # =========================================================================== + + # SSH keys for podvm debug access (optional). + # Note: dm-verity based podvm images do not support SSH key injection by design. + # This only works with non-dm-verity images built with SSH debug enabled. + #- name: sshKey + # vaultPrefixes: + # - global + # fields: + # - name: id_rsa.pub + # path: ~/.config/validated-patterns/id_rsa.pub + # - name: id_rsa + # path: ~/.config/validated-patterns/id_rsa + + # Container Image Signature Verification Policy + # Controls which container images are allowed to run in confidential containers. + # The policy is fetched by the TEE via initdata using image_security_policy_uri. + # + # Three policy variants are provided: + # - insecure: Accept all images (for development/testing only) + # - reject: Reject all images (useful for testing policy enforcement) + # - signed: Only accept images signed with cosign (for production) + # + # Select policy in initdata: + # image_security_policy_uri = 'kbs:///default/security-policy/insecure' + # + # TODO: Rename to 'container-image-policy' in trustee-chart to better reflect + # that this is about container image signature verification, not general security policy. + #- name: securityPolicyConfig + # vaultPrefixes: + # - hub + # fields: + # # Accept all images without verification (INSECURE - dev/testing only) + # - name: insecure + # value: | + # { + # "default": [{"type": "insecureAcceptAnything"}], + # "transports": {} + # } + # # Reject all images (useful for testing policy enforcement) + # - name: reject + # value: | + # { + # "default": [{"type": "reject"}], + # "transports": {} + # } + # # Only accept signed images (production) + # # Edit the transports section to add your signed images. + # # Each image needs a corresponding cosign public key in cosign-keys secret. + # - name: signed + # value: | + # { + # "default": [{"type": "reject"}], + # "transports": { + # "docker": { + # "registry.example.com/my-image": [ + # { + # "type": "sigstoreSigned", + # "keyPath": "kbs:///default/cosign-keys/key-0" + # } + # ] + # } + # } + # } + + # PCR measurements for attestation. + # Required: run ./scripts/get-pcr.sh before deploying. + #- name: pcrStash + # vaultPrefixes: + # - hub + # fields: + # - name: json + # path: ~/.config/validated-patterns/trustee/measurements.json + + # Attestation status resource accessible via KBS/CDH from inside the TEE. + # Workloads can fetch this to confirm they are running in an attested environment. + #- name: attestationStatus + # vaultPrefixes: + # - hub + # fields: + # - name: status + # value: 'attested' + # - name: random + # value: '' + # onMissingValue: generate + # vaultPolicy: validatedPatternDefaultPolicy + + # Cosign public keys for image signature verification + # Required when using the "signed" policy above. + # Add your cosign public key files here. + # Generate a cosign key pair: cosign generate-key-pair + #- name: cosign-keys + # vaultPrefixes: + # - hub + # fields: + # - name: key-0 + # path: ~/.config/validated-patterns/trustee/cosign-key-0.pub + + # KBS authentication keys (Ed25519) for Trustee admin API + # Generate with: + # mkdir -p ~/.config/validated-patterns/trustee + # openssl genpkey -algorithm ed25519 > ~/.config/validated-patterns/trustee/kbsPrivateKey + # openssl pkey -in ~/.config/validated-patterns/trustee/kbsPrivateKey -pubout -out ~/.config/validated-patterns/trustee/kbsPublicKey + # chmod 600 ~/.config/validated-patterns/trustee/kbsPrivateKey + #- name: kbsPublicKey + # vaultPrefixes: + # - hub + # fields: + # - name: publicKey + # path: ~/.config/validated-patterns/trustee/kbsPublicKey + + #- name: passphrase + # vaultPrefixes: + # - hub + # fields: + # - name: passphrase + # value: '' + # onMissingValue: generate + # vaultPolicy: validatedPatternDefaultPolicy + + # =========================================================================== + # HUB-SPECIFIC SECRETS (hub/) + # Secrets for hub cluster management (spoke kubeconfigs, etc.) + # Policy: hub-secret (built-in VP policy) + # =========================================================================== + # If you use clusterPools you will need to uncomment the following lines + #- name: aws + # fields: + # - name: aws_access_key_id + # ini_file: ~/.aws/credentials + # ini_section: default + # ini_key: aws_access_key_id + # - name: aws_secret_access_key + # ini_file: ~/.aws/credentials + # ini_key: aws_secret_access_key + #- name: publickey + # fields: + # - name: content + # path: ~/.ssh/id_rsa.pub + #- name: privatekey + # fields: + # - name: content + # path: ~/.ssh/id_rsa + #- name: openshiftPullSecret + # fields: + # - name: content + # path: ~/.pullsecret.json + + # If you are going to import spoke clusters, add here their kubeconfig entries + #- name: kubeconfig-spoke-1 + # vaultPrefixes: + # - hub + # fields: + # - name: content + # path: ~/.kube/kubeconfig-ztvp-spoke + #- name: kubeconfig-spoke-2 + # vaultPrefixes: + # - hub + # fields: + # - name: content + # path: ~/.kube/kubeconfig-ztvp-spoke-2 diff --git a/catalog/medical-diagnosis/pattern.yaml b/catalog/medical-diagnosis/pattern.yaml deleted file mode 100644 index 8e34898..0000000 --- a/catalog/medical-diagnosis/pattern.yaml +++ /dev/null @@ -1,40 +0,0 @@ -metadata_version: "1.0" -name: medical-diagnosis -pattern_version: "1.0" -display_name: Medical Diagnosis -repo_url: https://github.com/validatedpatterns/medical-diagnosis -docs_repo_url: https://github.com/validatedpatterns/docs -issues_url: https://github.com/validatedpatterns/medical-diagnosis/issues -docs_url: https://validatedpatterns.io/patterns/medical-diagnosis/ -ci_url: https://validatedpatterns.io/ci/?pattern=medicaldiag -tier: maintained -owners: - - day0hero -requirements: - hub: - compute: - gcp: - replicas: 5 - type: n1-standard-16 - azure: - replicas: 5 - type: Standard_D16s_v3 - aws: - replicas: 5 - type: m5.4xlarge - controlPlane: - gcp: - replicas: 3 - type: n1-standard-4 - azure: - replicas: 3 - type: Standard_D4s_v3 - aws: - replicas: 3 - type: m5.xlarge -extra_features: - hypershift_support: false - spoke_support: false -external_requirements: null -org: validatedpatterns -spoke: null diff --git a/catalog/medical-diagnosis/values-secret.yaml.template b/catalog/medical-diagnosis/values-secret.yaml.template deleted file mode 100644 index 8e066f9..0000000 --- a/catalog/medical-diagnosis/values-secret.yaml.template +++ /dev/null @@ -1,45 +0,0 @@ ---- -version: "2.0" - -# Due to some bug in one of the python container that we can't modify -# the db password for the user can't contain special characters - -vaultPolicies: - basicPolicy: | - length=10 - rule "charset" { charset = "abcdefghijklmnopqrstuvwxyz" min-chars = 1 } - rule "charset" { charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" min-chars = 1 } - rule "charset" { charset = "0123456789" min-chars = 1 } - -secrets: - # NEVER COMMIT THESE VALUES TO GIT - - # Database login credentials and configuration - - name: xraylab - fields: - - name: database-user - value: xraylab - - name: database-host - value: xraylabdb - - name: database-db - value: xraylabdb - - name: database-master-user - value: xraylab - - name: database-password - onMissingValue: generate - vaultPolicy: basicPolicy - - name: database-root-password - onMissingValue: generate - vaultPolicy: validatedPatternDefaultPolicy - - name: database-master-password - onMissingValue: generate - vaultPolicy: validatedPatternDefaultPolicy - - # Grafana Dashboard admin user/password - - name: grafana - fields: - - name: GF_SECURITY_ADMIN_USER - value: root - - name: GF_SECURITY_ADMIN_PASSWORD - onMissingValue: generate - vaultPolicy: validatedPatternDefaultPolicy diff --git a/catalog/mlops-fraud-detection/pattern.yaml b/catalog/mlops-fraud-detection/pattern.yaml new file mode 100644 index 0000000..fad1f7f --- /dev/null +++ b/catalog/mlops-fraud-detection/pattern.yaml @@ -0,0 +1,41 @@ +metadata_version: "1.0" +name: mlops-fraud-detection +description: Build, train and serve models in RHOAI to detect credit card fraud using Kubeflow Pipelines, KServe and Minio +pattern_version: "1.0" +display_name: MLOps Fraud Detection +repo_url: https://github.com/validatedpatterns/mlops-fraud-detection +docs_repo_url: https://github.com/validatedpatterns/docs +issues_url: https://github.com/validatedpatterns/mlops-fraud-detection/issues +docs_url: https://validatedpatterns.io/patterns/mlops-fraud-detection/ +ci_url: https://validatedpatterns.io/ci/?pattern=mlopsfraud +tier: sandbox +owners: + - dminnear-rh +requirements: + hub: + compute: + gcp: + replicas: 3 + type: n1-standard-8 + azure: + replicas: 3 + type: Standard_D8s_v3 + aws: + replicas: 3 + type: m5.2xlarge + controlPlane: + gcp: + replicas: 3 + type: n1-standard-4 + azure: + replicas: 3 + type: Standard_D4s_v3 + aws: + replicas: 3 + type: m5.xlarge +extra_features: + hypershift_support: false + spoke_support: false +external_requirements: null +org: validatedpatterns +spoke: null diff --git a/catalog/openshift-ai/pattern.yaml b/catalog/openshift-ai/pattern.yaml deleted file mode 100644 index 055d814..0000000 --- a/catalog/openshift-ai/pattern.yaml +++ /dev/null @@ -1,40 +0,0 @@ -metadata_version: "1.0" -name: openshift-ai -pattern_version: "1.0" -display_name: OpenShift AI -repo_url: https://github.com/validatedpatterns-sandbox/openshift-ai -docs_repo_url: https://github.com/validatedpatterns/docs -issues_url: https://github.com/validatedpatterns-sandbox/openshift-ai/issues -docs_url: https://validatedpatterns.io/patterns/openshift-ai -ci_url: https://validatedpatterns.io/ci/?pattern=openshiftai -tier: sandbox -owners: - - day0hero -requirements: - hub: - compute: - gcp: - replicas: 3 - type: n2-standard-16 - azure: - replicas: 3 - type: Standard_D16as_v4 - aws: - replicas: 3 - type: m5.4xlarge - controlPlane: - gcp: - replicas: 1 - type: n1-standard-8 - azure: - replicas: 1 - type: Standard_D8s_v3 - aws: - replicas: 1 - type: m5.2xlarge -extra_features: - hypershift_support: false - spoke_support: false -external_requirements: null -org: validatedpatterns-sandbox -spoke: null diff --git a/catalog/openshift-ai/values-secret.yaml.template b/catalog/openshift-ai/values-secret.yaml.template deleted file mode 100644 index 8f40e0a..0000000 --- a/catalog/openshift-ai/values-secret.yaml.template +++ /dev/null @@ -1,38 +0,0 @@ -# A more formal description of this format can be found here: -# https://github.com/hybrid-cloud-patterns/common/tree/main/ansible/roles/vault_utils#values-secret-file-format - -version: "2.0" -# Ideally you NEVER COMMIT THESE VALUES TO GIT (although if all passwords are -# automatically generated inside the vault this should not really matter) - -secrets: - - name: config-demo - vaultPrefixes: - - global - fields: - - name: secret - onMissingValue: generate - vaultPolicy: validatedPatternDefaultPolicy - - # If you use clusterPools you will need to uncomment the following lines - #- name: aws - # fields: - # - name: aws_access_key_id - # ini_file: ~/.aws/credentials - # ini_section: default - # ini_key: aws_access_key_id - # - name: aws_secret_access_key - # ini_file: ~/.aws/credentials - # ini_key: aws_secret_access_key - #- name: publickey - # fields: - # - name: content - # path: ~/.ssh/id_rsa.pub - #- name: privatekey - # fields: - # - name: content - # path: ~/.ssh/id_rsa - #- name: openshiftPullSecret - # fields: - # - name: content - # path: ~/.pullsecret.json diff --git a/catalog/travelops/pattern.yaml b/catalog/travelops/pattern.yaml new file mode 100644 index 0000000..f6b6856 --- /dev/null +++ b/catalog/travelops/pattern.yaml @@ -0,0 +1,42 @@ +metadata_version: "1.0" +name: travelops +description: A pattern deploying a demo travel-booking stack on OpenShift with Service Mesh (Istio), mTLS, distributed tracing, and observability +pattern_version: "1.0" +display_name: TravelOps +repo_url: https://github.com/validatedpatterns/travelops +docs_repo_url: https://github.com/validatedpatterns/docs +issues_url: https://github.com/validatedpatterns/travelops/issues +docs_url: https://validatedpatterns.io/patterns/travelops/ +ci_url: https://validatedpatterns.io/ci/?pattern=travelops +tier: tested +owners: + - dminnear-rh + - day0hero +requirements: + hub: + compute: + gcp: + replicas: 3 + type: n1-standard-8 + azure: + replicas: 3 + type: Standard_D8s_v3 + aws: + replicas: 3 + type: m5.2xlarge + controlPlane: + gcp: + replicas: 3 + type: n1-standard-4 + azure: + replicas: 3 + type: Standard_D4s_v3 + aws: + replicas: 3 + type: m5.xlarge +extra_features: + hypershift_support: false + spoke_support: false +external_requirements: null +org: validatedpatterns +spoke: null diff --git a/catalog/travelops/values-secret.yaml.template b/catalog/travelops/values-secret.yaml.template new file mode 100644 index 0000000..4915f3d --- /dev/null +++ b/catalog/travelops/values-secret.yaml.template @@ -0,0 +1,24 @@ +# A more formal description of this format can be found here: +# https://github.com/hybrid-cloud-patterns/common/tree/main/ansible/roles/vault_utils#values-secret-file-format + +version: "2.0" +# Ideally you NEVER COMMIT THESE VALUES TO GIT (although if all passwords are +# automatically generated inside the vault this should not really matter) + +secrets: + - name: mysql-credentials + vaultPrefixes: + - global + fields: + - name: rootpasswd + onMissingValue: generate + vaultPolicy: validatedPatternDefaultPolicy + - name: minio-credentials + vaultPrefixes: + - global + fields: + - name: accessKey + value: minioAccessKey + - name: secretKey + onMissingValue: generate + vaultPolicy: validatedPatternDefaultPolicy From e37ac419036807c4e914c572daad3f99d3c1bbaf Mon Sep 17 00:00:00 2001 From: Michele Baldessari Date: Thu, 16 Apr 2026 09:31:09 +0200 Subject: [PATCH 12/14] Fix schema and one metdata update --- catalog/catalog.yaml | 2 +- catalog/hypershift/pattern.yaml | 4 ++-- pattern.schema.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/catalog/catalog.yaml b/catalog/catalog.yaml index 885bfcf..a0b9ba4 100644 --- a/catalog/catalog.yaml +++ b/catalog/catalog.yaml @@ -1,4 +1,4 @@ -generated_at: "2026-04-16T07:24:39Z" +generated_at: "2026-04-16T07:30:15Z" generator_version: "1.0" catalog_description: 'Additional patterns can be found here: validatedpatterns.io' patterns: diff --git a/catalog/hypershift/pattern.yaml b/catalog/hypershift/pattern.yaml index afbe217..54fac04 100644 --- a/catalog/hypershift/pattern.yaml +++ b/catalog/hypershift/pattern.yaml @@ -36,7 +36,7 @@ requirements: extra_features: hypershift_support: true spoke_support: false -external_requirements: null -s3 bucket: true +external_requirements: + s3_bucket: true org: validatedpatterns-sandbox spoke: null diff --git a/pattern.schema.json b/pattern.schema.json index 052ed16..8c9db0a 100644 --- a/pattern.schema.json +++ b/pattern.schema.json @@ -123,7 +123,7 @@ "description": "Additional notes about cluster sizing" } }, - "additionalProperties": false + "additionalProperties": true } ] }, From 260ab8f68625a4458f2a0467ce077475a512da70 Mon Sep 17 00:00:00 2001 From: Michele Baldessari Date: Thu, 16 Apr 2026 11:01:36 +0200 Subject: [PATCH 13/14] Add tech-preview mention --- generate-catalog.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generate-catalog.sh b/generate-catalog.sh index 6ae843e..cd8b8f5 100755 --- a/generate-catalog.sh +++ b/generate-catalog.sh @@ -120,7 +120,7 @@ for org in "${ORGS[@]}"; do done # Build catalog index -CATALOG_DESCRIPTION=${CATALOG_DESCRIPTION:-'Additional patterns can be found here: validatedpatterns.io'} +CATALOG_DESCRIPTION=${CATALOG_DESCRIPTION:-'(Tech-Preview) Additional patterns can be found here: validatedpatterns.io'} { echo "generated_at: \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"" echo "generator_version: \"${GENERATOR_VERSION}\"" From 59bd4aff715699ce1dacf06baa77440f6c69b891 Mon Sep 17 00:00:00 2001 From: Michele Baldessari Date: Thu, 16 Apr 2026 11:03:50 +0200 Subject: [PATCH 14/14] Update catalog --- catalog/ansible-edge-gitops/pattern.yaml | 1 + catalog/catalog.yaml | 4 ++-- catalog/rag-llm-gitops/pattern.yaml | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/catalog/ansible-edge-gitops/pattern.yaml b/catalog/ansible-edge-gitops/pattern.yaml index 21b5595..fb445ce 100644 --- a/catalog/ansible-edge-gitops/pattern.yaml +++ b/catalog/ansible-edge-gitops/pattern.yaml @@ -1,6 +1,7 @@ metadata_version: "2.0" name: ansible-edge-gitops pattern_version: "2.0" +description: Ansible Edge GitOps demonstrates managing edge devices and VMs at scale using Ansible Automation Platform on OpenShift, bringing GitOps practices to environments that lack native GitOps support. display_name: Ansible Edge GitOps repo_url: https://github.com/validatedpatterns/ansible-edge-gitops docs_repo_url: https://github.com/validatedpatterns/docs diff --git a/catalog/catalog.yaml b/catalog/catalog.yaml index a0b9ba4..1ba177d 100644 --- a/catalog/catalog.yaml +++ b/catalog/catalog.yaml @@ -1,6 +1,6 @@ -generated_at: "2026-04-16T07:30:15Z" +generated_at: "2026-04-16T09:03:31Z" generator_version: "1.0" -catalog_description: 'Additional patterns can be found here: validatedpatterns.io' +catalog_description: '(Tech-Preview) Additional patterns can be found here: validatedpatterns.io' patterns: - ansible-edge-gitops - layered-zero-trust diff --git a/catalog/rag-llm-gitops/pattern.yaml b/catalog/rag-llm-gitops/pattern.yaml index de605df..05c2f7f 100644 --- a/catalog/rag-llm-gitops/pattern.yaml +++ b/catalog/rag-llm-gitops/pattern.yaml @@ -1,6 +1,7 @@ metadata_version: "1.0" name: rag-llm-gitops pattern_version: "1.0" +description: Deploy a RAG chatbot application on OpenShift that augments LLM responses with enterprise documentation stored in a vector database, using a GitOps framework display_name: AI Generation with LLM and RAG repo_url: https://github.com/validatedpatterns/rag-llm-gitops docs_repo_url: https://github.com/validatedpatterns/docs