Refactor CRD defaulting and validation as generic #3403
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Refactor the code for working with TracingPolicy CRD outside of Kubernetes
context to generically support any CRD. This includes loading custom resources
from YAML, applying defaults and validating them.
This design replaces the global state (tracingpolicy.defaultState), previously
initialized using sync.Once and used to cache validators and structural schemas,
with a generic struct (CRDContext[P]), initialized per CRD. CRDContext holds
structs necessary to process a particular CRD. CRDContexts for
TracingPolicy(Namespaced) are initialized in init().
The defaulting and validating logic is mostly unchanged and mimics the behavior
of Kubernetes apiserver. Two differences from the previous implementation maybe
worth noting:
pass a pointer as a type parameter, but then use reflect to allocate the
struct, to unmarshal into it. It's a bit ugly, but works.
To ensure that the generic functionality stays decoupled from TracingPolicy,
move it from pkg/tracingpolicy to a new pkg/crdutils package.
There is already another crdutils package under pkg/k8s module. However, it's
specific to Tetragon CRDs, while the defaulting and validating logic is
completely generic. Therefore, it seems better to keep it separate.