crossplane-contrib / crossplane-contrib/crossplane-diff
Optionally SSA dry-run new resources for higher-fidelity addition diffs
- Dominant language
- Go
- Stars
- 42
- Forks
- 15
- Avg merge
- 10h 26m
- Merged PRs (30d)
- 33
Description
## Background
`crossplane-diff` runs a server-side apply (SSA) dry-run against the apiserver to render the "would-be" form of each resource being diffed. This picks up apiserver-side mutations that don't come from the render pipeline:
- CRD `default:` field values
- Mutating admission webhook output (sidecar injectors, label/annotation injectors, etc.)
- Validating admission webhooks (invalid references, quota, policy)
Currently, the dry-run is only performed when the target resource already exists in the cluster. See `cmd/diff/diffprocessor/diff_calculator.go` — the `applyClient.DryRunApply` call is gated on `current != nil`. For brand-new resources (additions), the diff emits `desired` straight from the render pipeline.
This is an intentional choice: it avoids requiring `create` RBAC on every GVK that might be diffed, which is otherwise unnecessary because we never persist anything.
## The asymmetry
- `~~~` modification diffs reflect defaulted + webhooked state
- `+++` addition diffs do **not**
For most Crossplane managed resources the gap is small — providers typically don't chain heavy mutating webhooks at the apiserver level, and most reconciliation happens later in the provider controller. But the gap is nonzero, and it conflicts with the project's "accuracy above all else" principle.
## Proposal
Add an opt-in flag (e.g. `--ssa-additions` or `--strict-additions`) that, when set, also performs the dry-run SSA for resources that don't yet exist in the cluster. Default off, so existing deployments don't get a surprise RBAC requirement.
When enabled, document that:
- The role needs `create` on every GVK that may appear as an addition
- Validating webhooks may reject resources that `crossplane render` produced; this turns what was a clean `+++` diff into a diff-time error (arguably more accurate, but a behavior change)
## Priority
Low. No reported cases of additions diverging from reality in practice. File this so we don't lose the idea.
## References
- Discussion in [today's session]
- `cmd/diff/diffprocessor/diff_calculator.go` (the `current != nil` gate around `DryRunApply`)
- `cmd/diff/client/kubernetes/apply_client.go` (the SSA implementation)
Contributor guide
Research direction
Start in cmd/diff/diffprocessor/diff_calculator.go, where applyClient.DryRunApply is gated on current != nil, and read cmd/diff/client/kubernetes/apply_client.go for the SSA implementation. Add an opt-in path for additions while preserving the default behavior, then document the required create RBAC and webhook rejection behavior. Done means enabled additions receive SSA dry-run treatment without changing existing deployments by default.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, kubernetes
- Domain
- cli
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100