Files
simple-private-codecollection/docs/04-generation-rule-walkthrough.md
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

170 lines
5.3 KiB
Markdown

# 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`](../codebundles/gcp-bucket-crossplane-health/.runwhen/generation-rules/gcp-bucket-crossplane-health.yaml)
line by line and understand each block.
## The full file
```yaml
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
```yaml
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`
```yaml
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`
```yaml
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:
```yaml
# Only buckets whose name starts with "prod-"
- type: pattern
pattern: "^prod-"
properties: [name]
mode: substring
```
```yaml
# Only buckets that carry the label env=production
- type: exists
path: "resource/metadata/labels/env"
```
```yaml
# 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`
```yaml
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`](https://github.com/runwhen-contrib/runwhen-local/blob/main/src/enrichers/generation_rules.py).
## 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](05-slx-and-templates.md).