Files
simple-private-codecollection/docs/04-generation-rule-walkthrough.md
T
stewartshea 31ac475c97 Update Crossplane GCP Bucket generation rules to use preferred API version
Modified the generation rules for Crossplane GCP Buckets to omit the version in resource type definitions, allowing the use of the API server's preferred version (currently v1beta2). Updated documentation to reflect this change and clarify version pinning for schema stability.

Changes include:
- Updated YAML generation rules to remove explicit versioning.
- Revised documentation to explain the implications of omitting versioning and the preferred version usage.

This enhances resilience across CRD upgrades and simplifies the configuration for users.
2026-06-30 21:55:36 -04:00

5.3 KiB

04 — Generation rule walkthrough

What you'll do

Read the generation rule at codebundles/gcp-bucket-crossplane-health/.runwhen/generation-rules/gcp-bucket-crossplane-health.yaml line by line and understand each block.

The full file

apiVersion: runwhen.com/v1
kind: GenerationRules
spec:
  platform: kubernetes
  generationRules:
    - resourceTypes:
        - buckets.storage.gcp.upbound.io
      matchRules:
        - type: pattern
          pattern: ".+"
          properties: [name]
          mode: substring
      slxs:
        - baseName: xp-bkt-hlth
          qualifiers: ["resource", "cluster"]
          baseTemplateName: gcp-bucket-crossplane-health
          levelOfDetail: detailed
          outputItems:
            - type: slx
            - type: sli
            - type: runbook
              templateName: gcp-bucket-crossplane-health-taskset.yaml

Block-by-block

Envelope

apiVersion: runwhen.com/v1
kind: GenerationRules      # note the plural — the loader rejects "GenerationRule"
spec:
  platform: kubernetes     # per-file default; can be overridden per rule
  generationRules: [ ... ] # one or more rules
  • kind must be exactly GenerationRules. RunWhen Local's loader compares this to a schema constant.
  • spec.platform sets the default platform for every rule in the file.
  • spec.generationRules is a list — you can define many rules per file.

resourceTypes

resourceTypes:
  - buckets.storage.gcp.upbound.io

Omitting /v1beta2 (or /v1beta1) tells the indexer to use the API server's preferred version, which survives CRD schema upgrades. Pin the version only when you rely on a specific schema shape.

This is the selective discovery signal. Because this string appears in a loaded rule, the Kubernetes indexer knows to enumerate that CRD. Without any rule mentioning a CRD, it would not be listed.

You can list multiple types in one rule if you want the same SLX shape for each. Splitting into separate rules is usually cleaner though.

matchRules

matchRules:
  - type: pattern
    pattern: ".+"
    properties: [name]
    mode: substring

Match predicates are ANDed together. The pattern predicate here says "the resource's name property must match the regex .+ (i.e. non-empty) as a substring". Since every Bucket has a name, every Bucket matches.

You can filter more aggressively if you want. Examples:

# Only buckets whose name starts with "prod-"
- type: pattern
  pattern: "^prod-"
  properties: [name]
  mode: substring
# Only buckets that carry the label env=production
- type: exists
  path: "resource/metadata/labels/env"
# Combine — buckets in the prod GCP project label AND with a Ready condition entry
- type: and
  matches:
    - type: pattern
      pattern: "^runwhen-prod-.*"
      properties: [name]
      mode: substring
    - type: exists
      path: "resource/status/conditions"

slxs

slxs:
  - baseName: xp-bkt-hlth
    qualifiers: ["resource", "cluster"]
    baseTemplateName: gcp-bucket-crossplane-health
    levelOfDetail: detailed
    outputItems:
      - type: slx
      - type: sli
      - type: runbook
        templateName: gcp-bucket-crossplane-health-taskset.yaml
  • baseName — short identifier appended to the qualifier prefix to form the final slx_name. Keep it under 15 characters (xp-bkt-hlth is 11).
  • qualifiers — determines both the generated SLX name and how many SLXs are produced.
    • Including resource means "one SLX per matching Bucket".
    • Including cluster prefixes the name with the cluster name so it is stable across multi-cluster workspaces.
    • Not including namespace — Crossplane managed resources are cluster-scoped; they have no namespace.
  • baseTemplateName — the file-name stem for the templates. The output items resolve to <baseTemplateName>-<type>.yaml unless overridden. So type: slx looks up gcp-bucket-crossplane-health-slx.yaml, type: sli-sli.yaml, etc.
  • levelOfDetail — one of none | basic | detailed (or 0|1|2). This gates whether the SLX is emitted based on the platform's LOD filter. Since our airgap defaultLOD is detailed, we set the SLX to detailed so it always renders.
  • outputItems — one entry per artifact we want. type: runbook specifies an explicit templateName because we want to point at a file named -taskset.yaml, not -runbook.yaml, purely for convention matching what other RunWhen bundles do.

What resource identity ends up in the SLX

Given a Bucket named runwhen-nonprod-shared-litellm-logging on cluster shared-cluster, the rule will produce an SLX whose name is roughly:

shared-cluster-runwhen-nonprod-shared-litellm-logging-xp-bkt-hlth

RunWhen Local will also shorten and hash-suffix pieces as needed for length. The exact rendering happens in generation_rules.py::make_slx_name.

Screenshot placeholders

  • images/04-generation-rule-annotated.png — the YAML above with arrows pointing to the resource type, match rule, and output items.

Next

Continue to 05 — SLX and templates.