Skip to content

Use one canonical version for a kind missing in the preferred group version - #375

Open
AndreyZa wants to merge 1 commit into
splunk:mainfrom
AndreyZa:canonical-version-missing-preferred
Open

AndreyZa wants to merge 1 commit into
splunk:mainfrom
AndreyZa:canonical-version-missing-preferred

Conversation

@AndreyZa

@AndreyZa AndreyZa commented Oct 6, 2026

Copy link
Copy Markdown

Fixes #312.

Problem

When a kind is missing from its group's preferred version, qbec falls back to making each version that serves the kind canonical for itself. kyverno.io is the common case: the preferred version v2 has no ClusterPolicy, which is served by v1 and v2beta1.

CanonicalResources() then returns v1 or v2beta1 depending on Go map iteration order. Listing through v2beta1 never matches objects declared as v1, so in roughly half of qbec diff / qbec apply runs every ClusterPolicy becomes a deletion candidate. That is the good-path/bad-path pair in #312: list objects: type=kyverno.io/v1, Kind=ClusterPolicy versus type=kyverno.io/v2beta1, Kind=ClusterPolicy followed by a spurious deletion.

Change

In internal/remote/k8smeta/meta.go, a kind that falls back now gets one canonical version shared by all of its versions: the highest by Kubernetes version ordering (version.CompareKubeAwareVersionStrings: GA > beta > alpha, then major and minor). For ClusterPolicy that is v1. Kinds that do exist in their group's preferred version are not affected.

Testing

  • New TestCanonicalKindMissingInPreferredVersion models the kyverno.io discovery. Both ClusterPolicy versions resolve to v1; CleanupPolicy, which the preferred version does serve, stays on v2; and CanonicalResources() returns v1 across 100 calls. On main the test fails: v2beta1 is canonical for itself, and the listed version flips between calls. With this change it passes.
  • make build, go vet ./... and addlicense -check are clean.
  • go test ./... passes apart from vm/internal/ds/helm3 TestRunTemplate, which fails the same way on main in my environment (the PodDisruptionBudget renders as policy/v1beta1), so it is unrelated. Integration tests were not run locally — no kind cluster here.

…ersion

kyverno.io serves ClusterPolicy in v1 and v2beta1, but its preferred version v2
has no ClusterPolicy. qbec made each such version canonical for itself, and
CanonicalResources() picked v1 or v2beta1 at random (Go map order). Listing
through v2beta1 never matches objects declared as v1, so every ClusterPolicy
became a deletion candidate in about half of diff/apply runs.

Now all versions of such a kind share the highest version by Kubernetes version
ordering (GA > beta > alpha), for ClusterPolicy that is v1.

Fixes splunk#312
@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

CLA Assistant Lite bot All contributors have signed the CLA ✍️ ✅

@AndreyZa

AndreyZa commented Oct 6, 2026

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

srv-gh-tools added a commit to splunk/cla-agreement that referenced this pull request Oct 6, 2026
@AndreyZa

AndreyZa commented Oct 6, 2026

Copy link
Copy Markdown
Author

I have read the Code of Conduct and I hereby accept the Terms

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unstable qbec diff results (different versions for same Kind leads to object deletions)

1 participant