Clients of webhook can now decorate the request context with additional metadata
via:
```
ac := &AdmissionController{
... // As before
WithContext: func(ctx context.Context) context.Context {
// logic to attach stuff to ctx
}
}
```
This metadata can then be accessed off of the context in methods like
`SetDefaults` and `Validate` on types registered as webhook handlers.
Fixes: https://github.com/knative/pkg/issues/306
* Drop webhook logic to increment spec.generation
With Kubernetes 1.11+ metadata.generation now increments properly
when the status subresource is enabled on CRDs
For more details see: https://github.com/knative/serving/issues/643
* Drop the generational duck type
* Initial commit for the webhook to set the annotations about mutator.
The user that created or updated the resource will be set in the
annotations.
* update comments
* remove debug logging
* logging :/
* logging :/, returns
* logging :/ III
* error wrap
* simplify test
* rename the test
* add pkg/errors to the deps for better errors
* do not require CRD to implement Annotatable
* review issues
* fix interface as required by review
* Webhook creates a patch for all fields generated by round tripping the JSON through Golang types.
* Add unit tests for InnerDefaultResource.
* Linter errors.
* PR comments - test changes
* t.Helper()
* PR comments.
Immutable fields with default values may now be changed iff they change is to populate their default value. This is to support defaulting in the scenario where an object was created long ago and a new field (with a default!) is added. When controllers attempt to mutate the object status today, this would create a webhook rejection! With this change, we compare against a freshly defaulted "old" object to exclude newly defaulted fields from the immutability check.
We saw this in knative/serving for the newly added TimeoutSeconds field in Revision (otherwise immutable), which I believe it leading to upgrade testing flakes since post-upgrade Revision status updates will fail.
* Change VerifyType to return an error instead of panicking
Signed-off-by: Vincent Demeester <vdemeest@redhat.com>
* Move the use of `VerifyType` in tests
Those calls to `duck.VerifyType` are done at runtime and thus could be
costly at program startup. Putting them under tests ensure we still
assert those types but during unit testing.
Signed-off-by: Vincent Demeester <vdemeest@redhat.com>
This starts to sketch common libraries for instantiating informers/listers for a particular GroupVersionResource as one of our duck types.
You can instantiate a duck.InformerFactory like so:
```go
dynaClient, err := dynamic.NewForConfig(cfg)
if err != nil {
logger.Fatalf("Error building dynamic clientset: %v", err)
}
// Cache as the outermost layer so we only register the EventHandler once.
dif := &duck.CachedInformerFactory{
Delegate: &duck.EnqueueInformerFactory{
Delegate: &duck.TypedInformerFactory{
Client: dynaClient,
Type: &duckv1alpha1.Target{},
ResyncPeriod: 30 * time.Second,
StopChannel: stopCh,
},
EventHandler: cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
// Enqueue, obj is: *duckerv1alpha1.Target
},
UpdateFunc: func(old, new interface{}) {
// Enqueue, old and new are: *duckerv1alpha1.Target
},
},
},
}
```
Then, as you come across new GroupVersionResources that you want to handle:
```go
informer, lister, err := dif.Get(gvr)
if err != nil {
logger.Fatalf("Error starting shared index informer: %v", err)
}
```
With the `duck.TypedInformerFactory` the objects will be returned as the provided `Type:`, so in this example, you could safely write:
```go
elt, err := lister.ByNamespace(ns).Get(name)
if err != nil { ... }
target := elt.(*duckv1alpha1.Target)
// Stuff involving target.
```
* Prune the GenericCRD spec to what is used.
Encapsulate our change detection slightly.
* Support common spec mutations via duck typing.
This adds support for performing common mutations to objects via duck types and JSON patching.
Fixes: https://github.com/knative/pkg/issues/76
* Eliminate getSpecJSON thru schemaless duck typing.
This leverages a one-off trick to get the JSON of the spec field from arbitrary types.