diff --git a/Gopkg.lock b/Gopkg.lock index ee87d5ca..c1ba93c0 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -966,7 +966,7 @@ [[projects]] branch = "master" - digest = "1:8356c43d1864b3da53067c02c8912e1e56db1778019f1b745c5cb5e4028216a1" + digest = "1:9baf7494df34e555a6a2c9ab5c951a7b07c593d8176a679eab98897b1bb50d0d" name = "knative.dev/pkg" packages = [ "apis", @@ -985,18 +985,18 @@ "metrics/metricskey", ] pruneopts = "T" - revision = "248c9f0353cab2acd75f6d582fcdb9e45d1e285b" + revision = "a447f39709f1ee8c1854517c247330b8ecb9a6ca" [[projects]] branch = "master" - digest = "1:9fc1b7e84778267884b614c45b0939aa8984dcab5794eb3c6bb5e57bd0a99c41" + digest = "1:d2545cd71ef3604f5d2d792e569c6e3a4df31e336d76e709b0b8bac759c0faf7" name = "knative.dev/test-infra" packages = [ "scripts", "tools/dep-collector", ] pruneopts = "UT" - revision = "1b5477b12d75ea7210d970ff9a234277dcd9ee18" + revision = "c7c50ccd8082344a5f8ea85a5ae8de59308d325c" [[projects]] digest = "1:8730e0150dfb2b7e173890c8b9868e7a273082ef8e39f4940e3506a481cf895c" diff --git a/vendor/knative.dev/pkg/Gopkg.lock b/vendor/knative.dev/pkg/Gopkg.lock index 49d80171..15378938 100644 --- a/vendor/knative.dev/pkg/Gopkg.lock +++ b/vendor/knative.dev/pkg/Gopkg.lock @@ -1323,14 +1323,14 @@ [[projects]] branch = "master" - digest = "1:8bd3cae999736fca901bdd918ab9e9a899f39446701a296ade11ca44ae0a741e" + digest = "1:9fc1b7e84778267884b614c45b0939aa8984dcab5794eb3c6bb5e57bd0a99c41" name = "knative.dev/test-infra" packages = [ "scripts", "tools/dep-collector", ] pruneopts = "UT" - revision = "64615f92c4ebdd4e4423015ffc0db45877660a0d" + revision = "1b5477b12d75ea7210d970ff9a234277dcd9ee18" [[projects]] digest = "1:8730e0150dfb2b7e173890c8b9868e7a273082ef8e39f4940e3506a481cf895c" diff --git a/vendor/knative.dev/pkg/codegen/cmd/injection-gen/generators/reconciler_controller.go b/vendor/knative.dev/pkg/codegen/cmd/injection-gen/generators/reconciler_controller.go index 833d9591..25bbad22 100644 --- a/vendor/knative.dev/pkg/codegen/cmd/injection-gen/generators/reconciler_controller.go +++ b/vendor/knative.dev/pkg/codegen/cmd/injection-gen/generators/reconciler_controller.go @@ -18,6 +18,7 @@ package generators import ( "io" + "k8s.io/gengo/generator" "k8s.io/gengo/namer" "k8s.io/gengo/types" diff --git a/vendor/knative.dev/pkg/codegen/cmd/injection-gen/generators/reconciler_reconciler.go b/vendor/knative.dev/pkg/codegen/cmd/injection-gen/generators/reconciler_reconciler.go index 1c68460e..3cdddb8b 100644 --- a/vendor/knative.dev/pkg/codegen/cmd/injection-gen/generators/reconciler_reconciler.go +++ b/vendor/knative.dev/pkg/codegen/cmd/injection-gen/generators/reconciler_reconciler.go @@ -116,6 +116,10 @@ func (g *reconcilerReconcilerGenerator) GenerateType(c *generator.Context, t *ty Package: "go.uber.org/zap", Name: "SugaredLogger", }), + "setsNewString": c.Universe.Function(types.Name{ + Package: "k8s.io/apimachinery/pkg/util/sets", + Name: "NewString", + }), } sw.Do(reconcilerInterfaceFactory, m) @@ -304,8 +308,8 @@ func (r *reconcilerImpl) updateFinalizersFiltered(ctx context.Context, resource var finalizers []string // If there's nothing to update, just return. - existingFinalizers := sets.NewString(existing.Finalizers...) - desiredFinalizers := sets.NewString(resource.Finalizers...) + existingFinalizers := {{.setsNewString|raw}}(existing.Finalizers...) + desiredFinalizers := {{.setsNewString|raw}}(resource.Finalizers...) if desiredFinalizers.Has(finalizerName) { if existingFinalizers.Has(finalizerName) { @@ -352,7 +356,7 @@ func (r *reconcilerImpl) setFinalizerIfFinalizer(ctx context.Context, resource * return nil } - finalizers := sets.NewString(resource.Finalizers...) + finalizers := {{.setsNewString|raw}}(resource.Finalizers...) // If this resource is not being deleted, mark the finalizer. if resource.GetDeletionTimestamp().IsZero() { @@ -373,7 +377,7 @@ func (r *reconcilerImpl) clearFinalizer(ctx context.Context, resource *{{.type|r return nil } - finalizers := sets.NewString(resource.Finalizers...) + finalizers := {{.setsNewString|raw}}(resource.Finalizers...) if reconcileEvent != nil { var event *{{.reconcilerReconcilerEvent|raw}} diff --git a/vendor/knative.dev/pkg/injection/README.md b/vendor/knative.dev/pkg/injection/README.md index 03809e95..07882bbe 100644 --- a/vendor/knative.dev/pkg/injection/README.md +++ b/vendor/knative.dev/pkg/injection/README.md @@ -33,6 +33,78 @@ func NewController(ctx context.Context, cmw configmap.Watcher) *controller.Impl } ``` +### Generated Reconcilers + +A code generator is available for simple subset of reconciliation requirements. +A label above the API type will signal to the injection code generator to +generate a strongly typed reconciler. Use `+genreconciler` to generate the +reconcilers. + +```go +// +genclient +// +genreconciler +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type ExampleType struct { + ... +} +``` + +`+genreconciler` will produce a helper method to get a controller impl. + +Update `NewController` as follows: + +```go +"knative.dev/pkg/controller" +... +impl := controller.NewImpl(c, logger, "NameOfController") +``` + +becomes + +```go +reconciler "knative.dev//pkg/client/injection/reconciler///" +... +impl := reconciler.NewImpl(ctx, c) +``` + +See +[Generated Reconciler Responsibilities](#generated-reconciler-responsibilities) +for more information. + +## Implementing Reconcilers + +Type `Reconciler` is expected to implement `Reconcile`: + +```go +func (r *Reconciler) Reconcile(ctx context.Context, key string) error { + ... +} +``` + +### Generated Reconcilers + +If generated reconcilers are used, Type `Reconciler` is expected to implement +`ReconcileKind`: + +```go +func (r *Reconciler) ReconcileKind(ctx context.Context, o *samplesv1alpha1.AddressableService) reconciler.Event { + ... +} +``` + +And if finalizers are required, + +```go +func (r *Reconciler) FinalizeKind(ctx context.Context, o *samplesv1alpha1.AddressableService) reconciler.Event { + ... +} +``` + +See +[Generated Reconciler Responsibilities](#generated-reconciler-responsibilities) +for more information. + ## Consuming Informers Knative controllers use "informers" to set up the various event hooks needed to @@ -86,7 +158,7 @@ func NewController(ctx context.Context, cmw configmap.Watcher) *controller.Impl Similar to `injection.Default`, we also have `injection.Fake`. While linking the normal accessors sets up the former, linking their fakes set up the latter. -``` +```go import ( "testing" @@ -112,7 +184,7 @@ func TestFoo(t *testing.T) { The fake clients also support manually setting up contexts seeded with objects: -``` +```go import ( "testing" @@ -216,3 +288,133 @@ required = [ unused-packages = false non-go = false ``` + +## Generated Reconciler Responsibilities + +The goal of generating the reconcilers is to provide the controller implementor +a strongly typed interface, and ensure correct reconciler behaviour around +status updates, Kubernetes event creation, and queue management. + +We have already helped the queue management with libraries in this repo. But +there was a gap in support and standards around how status updates (and retries) +are performed, and when Kubernetes events are created for the resource. + +The general flow with generated reconcilers looks like the following: + +``` +[k8s] -> [watches] -> [reconciler enqeueue] -> [Reconcile(key)] -> [ReconcileKind(resource)] + ^-- you set up. ^-- generated ^-- stubbed and you customize +``` + +Optionally, support for finalizers: + +``` +[Reconcile(key)] -> - no -> [ReconcileKind(resource)] + ` + (optional) + `- yes -> [FinalizeKind(resource)] +``` + +- `ReconcileKind` is only called if the resource's deletion timestamp is empty. +- `FinalizeKind` is optional, and if implemnted by the reconciler will be called + when the resource's deletion timestamp is set. + +The responsibility and consequences of using the generated +`ReconcileKind(resource)` method are as follows: + +- In `NewController`, set up watches and reconciler enqueue requests as before. +- Implementing `ReconcileKind(ctx, resource)` to handle active resources. +- Implementing `FinalizeKind(ctx, resource)` to finalize deleting active + resources. + - NOTE: Implementing `FinalizeKind` will result in the reconciler using + finalizers on the resource. +- Resulting changes from `Reconcile` calling `ReconcileKind(ctx, resource)`: + - DO NOT edit the spec of `resource`, it will be ignored. + - DO NOT edit the metadata of `resource`, it will be ignored. + - If `resource.status` is changed, `Reconcile` will synchronize it back to the + API Server. + - Note: the watches setup for `resource.Kind` will see the update to status + and cause another reconciliation. +- `ReconcileKind(ctx, resource)` returns a + [`reconciler.Event`](../reconciler/events.go) results in: +- If `event` is an `error` (`reconciler.Event` extends `error` internally), + `Reconciler` will produce a `Warning` kubernetes event with _reason_ + `InternalError` and the body of the error as the message. + - Additionally, the `error` will be returned from `Reconciler` and `key` will + requeue back into the reconciler key queue. +- If `event` is a `reconciler.Event`, `Reconciler` will log a typed and reasoned + Kubernetes Event based on the contents of `event`. + - `event` is not considered an error for requeue and nil is returned from + `Reconciler`. +- If additional events are required to be produced, an implementation can pull a + recorder from the context: `recorder := controller.GetEventRecorder(ctx)`. + +Future features to be considered: + +- Leverage `configStore` and specifically `ctx = r.configStore.ToContext(ctx)` + inside `Reconcile`. +- Resulting changes from `Reconcile` calling `ReconcileKind(ctx, resource)`: + - If `resource.metadata.labels` or `.annotations` are updated, `Reconcile` + will synchronize it back to the API Server. +- Adjust `+genreconciler` to allow for generated reconcilers to be made without + annotating the type struct. + +### Artifacts + +The artifacts are targeted to the configured `client/injection` directory: + +```go +kindreconciler "knative.dev//pkg/client/injection/reconciler///" +``` + +Controller related artifacts: + +- `NewImpl` - gets an injection based client and lister for , sets up + Kubernetes Event recorders, and delegates to `controller.NewImpl` for queue + management. + +```go +impl := reconciler.NewImpl(ctx, reconcilerInstance) +``` + +Reconciler related artifacts: + +- `Interface` - defines the strongly typed interfaces to be implemented by a + controller reconciling . + +```go +// Check that our Reconciler implements Interface +var _ addressableservicereconciler.Interface = (*Reconciler)(nil) +``` + +- `Finalizer` - defines the strongly typed interfaces to be implemented by a + controller finalizing . + +```go +// Check that our Reconciler implements Interface +var _ addressableservicereconciler.Finalizer = (*Reconciler)(nil) +``` + +#### Stubs + +To get started, or to use as reference. It is intended to be copied out of the +`client` dir. + +`knative.dev//pkg/client/injection/reconciler////stubs/controller.go` + +- A basic implementation of `NewController`. + +`knative.dev//pkg/client/injection/reconciler////stubs/reconciler.go` + +- A basic implementation of `type Reconciler struct {}` and + `Reconciler.ReconcileKind`. +- A commented out example of a basic implementation of + `Reconciler.FinalizeKind`. +- An example `reconciler.Event`: `newReconciledNormal` + +### Examples + +Please look at +[`sample-controller`](http://github.com/knative/sample-controller) or +[`sample-source`](http://github.com/knative/sample-source) for working +integrations of the generated geconciler code. diff --git a/vendor/knative.dev/pkg/webhook/psbinding/reconciler.go b/vendor/knative.dev/pkg/webhook/psbinding/reconciler.go index 2c328c4b..ebb9061e 100644 --- a/vendor/knative.dev/pkg/webhook/psbinding/reconciler.go +++ b/vendor/knative.dev/pkg/webhook/psbinding/reconciler.go @@ -162,7 +162,7 @@ func (r *BaseReconciler) ReconcileDeletion(ctx context.Context, fb Bindable) err // If it is our turn to finalize the Binding, then first undo the effect // of our Binding on the resource. logging.FromContext(ctx).Infof("Removing the binding for %s", fb.GetName()) - if err := r.ReconcileSubject(ctx, fb, fb.Undo); apierrs.IsNotFound(err) { + if err := r.ReconcileSubject(ctx, fb, fb.Undo); apierrs.IsNotFound(err) || apierrs.IsForbidden(err) { // If the subject has been deleted, then there is nothing to undo. } else if err != nil { return err @@ -252,7 +252,9 @@ func (r *BaseReconciler) ReconcileSubject(ctx context.Context, fb Bindable, muta // use to fetch our PodSpecable resources. _, lister, err := r.Factory.Get(gvr) if err != nil { - return fmt.Errorf("error getting a lister for resource '%+v': %v", gvr, err) + logging.FromContext(ctx).Errorf("Error getting a lister for resource '%+v': %v", gvr, err) + fb.GetBindingStatus().MarkBindingUnavailable("SubjectUnavailable", err.Error()) + return err } // Based on the type of subject reference, build up a list of referents. diff --git a/vendor/knative.dev/test-infra/scripts/README.md b/vendor/knative.dev/test-infra/scripts/README.md index 7644d98e..cc2cdd10 100644 --- a/vendor/knative.dev/test-infra/scripts/README.md +++ b/vendor/knative.dev/test-infra/scripts/README.md @@ -175,7 +175,7 @@ This is a helper script for Knative E2E test scripts. To use it: 1. Calling your script with `--run-tests` and the variable `KO_DOCKER_REPO` set will immediately start the tests against the cluster currently configured for `kubectl`. - + 1. By default `knative_teardown()` and `test_teardown()` will be called after the tests finish, use `--skip-teardowns` if you don't want them to be called.