mirror of https://github.com/knative/caching.git
Auto-update dependencies (#201)
Produced via: `dep ensure -update knative.dev/test-infra knative.dev/pkg` /assign n3wscott /cc n3wscott
This commit is contained in:
parent
fec8f79136
commit
1094caadae
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package generators
|
|||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"k8s.io/gengo/generator"
|
||||
"k8s.io/gengo/namer"
|
||||
"k8s.io/gengo/types"
|
||||
|
|
|
|||
|
|
@ -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}}
|
||||
|
|
|
|||
|
|
@ -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/<repo>/pkg/client/injection/reconciler/<clientgroup>/<version>/<resource>"
|
||||
...
|
||||
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)] -> <resource deleted?> - 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/<repo>/pkg/client/injection/reconciler/<clientgroup>/<version>/<kind>"
|
||||
```
|
||||
|
||||
Controller related artifacts:
|
||||
|
||||
- `NewImpl` - gets an injection based client and lister for <kind>, 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 <kind>.
|
||||
|
||||
```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 <kind>.
|
||||
|
||||
```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/<repo>/pkg/client/injection/reconciler/<clientgroup>/<version>/<kind>/stubs/controller.go`
|
||||
|
||||
- A basic implementation of `NewController`.
|
||||
|
||||
`knative.dev/<repo>/pkg/client/injection/reconciler/<clientgroup>/<version>/<kind>/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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in New Issue