From 43ca049cdbdad4892b0c926e7c6536d064efde72 Mon Sep 17 00:00:00 2001 From: Matt Moore Date: Mon, 25 Nov 2019 09:57:10 -0800 Subject: [PATCH] Reduce the boilerplate for setting up duck.InformerFactory's. (#896) This augments the injection codegen with the capability to produce a duck.InformerFactory attached to context for each type that we process. Now a `duck.InformerFactory` for "Addressable" can be produced by "Get"ing it from the context. This is triggered by placing `// +genduck` on the type that implements `duck.Implementable`. --- apis/duck/patch_test.go | 14 ++ apis/duck/scale_test.go | 14 ++ apis/duck/v1/addressable_types.go | 5 +- apis/duck/v1/podspec_types.go | 3 +- apis/duck/v1/source_types.go | 2 +- apis/duck/v1/status_types.go | 3 +- apis/duck/v1alpha1/addressable_types.go | 5 +- apis/duck/v1alpha1/conditions_types.go | 3 +- apis/duck/v1alpha1/legacy_targetable_types.go | 5 +- .../duck/v1alpha1/retired_targetable_types.go | 5 +- apis/duck/v1beta1/addressable_types.go | 5 +- apis/duck/v1beta1/source_types.go | 2 +- apis/duck/v1beta1/status_types.go | 3 +- apis/duck/verify.go | 3 + apis/duck/verify_test.go | 87 +++++++++ .../ducks/duck/v1/addressable/addressable.go | 60 ++++++ .../ducks/duck/v1/addressable/fake/fake.go | 30 +++ .../ducks/duck/v1/conditions/conditions.go | 60 ++++++ .../ducks/duck/v1/conditions/fake/fake.go | 30 +++ .../ducks/duck/v1/podspecable/fake/fake.go | 30 +++ .../ducks/duck/v1/podspecable/podspecable.go | 60 ++++++ .../ducks/duck/v1/source/fake/fake.go | 30 +++ .../injection/ducks/duck/v1/source/source.go | 60 ++++++ .../duck/v1alpha1/addressable/addressable.go | 60 ++++++ .../duck/v1alpha1/addressable/fake/fake.go | 30 +++ .../duck/v1alpha1/conditions/conditions.go | 60 ++++++ .../duck/v1alpha1/conditions/fake/fake.go | 30 +++ .../v1alpha1/legacytargetable/fake/fake.go | 30 +++ .../legacytargetable/legacytargetable.go | 60 ++++++ .../duck/v1alpha1/targetable/fake/fake.go | 30 +++ .../duck/v1alpha1/targetable/targetable.go | 60 ++++++ .../duck/v1beta1/addressable/addressable.go | 60 ++++++ .../duck/v1beta1/addressable/fake/fake.go | 30 +++ .../duck/v1beta1/conditions/conditions.go | 60 ++++++ .../duck/v1beta1/conditions/fake/fake.go | 30 +++ .../ducks/duck/v1beta1/source/fake/fake.go | 30 +++ .../ducks/duck/v1beta1/source/source.go | 60 ++++++ codegen/cmd/injection-gen/generators/duck.go | 130 +++++++++++++ .../cmd/injection-gen/generators/fakeduck.go | 104 ++++++++++ .../cmd/injection-gen/generators/packages.go | 181 ++++++++++++------ hack/update-codegen.sh | 2 +- injection/ducks.go | 40 ++++ injection/informers.go | 6 + injection/interface.go | 7 + resolver/addressable_resolver.go | 9 +- resolver/addressable_resolver_test.go | 2 + 46 files changed, 1550 insertions(+), 80 deletions(-) create mode 100644 client/injection/ducks/duck/v1/addressable/addressable.go create mode 100644 client/injection/ducks/duck/v1/addressable/fake/fake.go create mode 100644 client/injection/ducks/duck/v1/conditions/conditions.go create mode 100644 client/injection/ducks/duck/v1/conditions/fake/fake.go create mode 100644 client/injection/ducks/duck/v1/podspecable/fake/fake.go create mode 100644 client/injection/ducks/duck/v1/podspecable/podspecable.go create mode 100644 client/injection/ducks/duck/v1/source/fake/fake.go create mode 100644 client/injection/ducks/duck/v1/source/source.go create mode 100644 client/injection/ducks/duck/v1alpha1/addressable/addressable.go create mode 100644 client/injection/ducks/duck/v1alpha1/addressable/fake/fake.go create mode 100644 client/injection/ducks/duck/v1alpha1/conditions/conditions.go create mode 100644 client/injection/ducks/duck/v1alpha1/conditions/fake/fake.go create mode 100644 client/injection/ducks/duck/v1alpha1/legacytargetable/fake/fake.go create mode 100644 client/injection/ducks/duck/v1alpha1/legacytargetable/legacytargetable.go create mode 100644 client/injection/ducks/duck/v1alpha1/targetable/fake/fake.go create mode 100644 client/injection/ducks/duck/v1alpha1/targetable/targetable.go create mode 100644 client/injection/ducks/duck/v1beta1/addressable/addressable.go create mode 100644 client/injection/ducks/duck/v1beta1/addressable/fake/fake.go create mode 100644 client/injection/ducks/duck/v1beta1/conditions/conditions.go create mode 100644 client/injection/ducks/duck/v1beta1/conditions/fake/fake.go create mode 100644 client/injection/ducks/duck/v1beta1/source/fake/fake.go create mode 100644 client/injection/ducks/duck/v1beta1/source/source.go create mode 100644 codegen/cmd/injection-gen/generators/duck.go create mode 100644 codegen/cmd/injection-gen/generators/fakeduck.go create mode 100644 injection/ducks.go diff --git a/apis/duck/patch_test.go b/apis/duck/patch_test.go index 3ef5dfebc..f22ecf09e 100644 --- a/apis/duck/patch_test.go +++ b/apis/duck/patch_test.go @@ -22,6 +22,8 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" ) func TestCreateMergePatch(t *testing.T) { @@ -292,6 +294,18 @@ type PatchSpec struct { var _ Implementable = (*Patchable)(nil) var _ Populatable = (*Patch)(nil) +func (*Patch) GetObjectKind() schema.ObjectKind { + return nil // not used +} + +func (p *Patch) DeepCopyObject() runtime.Object { + return nil // not used +} + +func (p *Patch) GetListType() runtime.Object { + return nil // not used +} + func (*Patchable) GetFullType() Populatable { return &Patch{} } diff --git a/apis/duck/scale_test.go b/apis/duck/scale_test.go index a357637e2..5e2b130df 100644 --- a/apis/duck/scale_test.go +++ b/apis/duck/scale_test.go @@ -21,6 +21,8 @@ import ( appsv1 "k8s.io/api/apps/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" "knative.dev/pkg/apis/duck" ) @@ -47,6 +49,18 @@ var ( _ duck.Implementable = (*Scalable)(nil) ) +func (*Scalable) GetObjectKind() schema.ObjectKind { + return nil // not used +} + +func (p *Scalable) DeepCopyObject() runtime.Object { + return nil // not used +} + +func (p *Scalable) GetListType() runtime.Object { + return nil // not used +} + // GetFullType implements duck.Implementable func (*Scalable) GetFullType() duck.Populatable { return &Scalable{} diff --git a/apis/duck/v1/addressable_types.go b/apis/duck/v1/addressable_types.go index 7d804ea88..e5955aeb6 100644 --- a/apis/duck/v1/addressable_types.go +++ b/apis/duck/v1/addressable_types.go @@ -27,9 +27,11 @@ import ( "knative.dev/pkg/apis/duck" ) +// +genduck + // Addressable provides a generic mechanism for a custom resource // definition to indicate a destination for message delivery. - +// // Addressable is the schema for the destination information. This is // typically stored in the object's `status`, as this information may // be generated by the controller. @@ -44,7 +46,6 @@ var ( _ apis.Convertible = (*Addressable)(nil) ) -// +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // AddressableType is a skeleton type wrapping Addressable in the manner we expect diff --git a/apis/duck/v1/podspec_types.go b/apis/duck/v1/podspec_types.go index 9f8ab6c9a..0dd9ec338 100644 --- a/apis/duck/v1/podspec_types.go +++ b/apis/duck/v1/podspec_types.go @@ -25,11 +25,12 @@ import ( "knative.dev/pkg/apis/duck" ) +// +genduck + // PodSpecable is implemented by types containing a PodTemplateSpec // in the manner of ReplicaSet, Deployment, DaemonSet, StatefulSet. type PodSpecable corev1.PodTemplateSpec -// +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // WithPod is the shell that demonstrates how PodSpecable types wrap diff --git a/apis/duck/v1/source_types.go b/apis/duck/v1/source_types.go index 834a17734..321156d73 100644 --- a/apis/duck/v1/source_types.go +++ b/apis/duck/v1/source_types.go @@ -30,7 +30,7 @@ import ( // Source is an Implementable "duck type". var _ duck.Implementable = (*Source)(nil) -// +genclient +// +genduck // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // Source is the minimum resource shape to adhere to the Source Specification. diff --git a/apis/duck/v1/status_types.go b/apis/duck/v1/status_types.go index dc48c574c..c2cb989a1 100644 --- a/apis/duck/v1/status_types.go +++ b/apis/duck/v1/status_types.go @@ -28,13 +28,14 @@ import ( "knative.dev/pkg/apis/duck" ) +// +genduck + // Conditions is a simple wrapper around apis.Conditions to implement duck.Implementable. type Conditions apis.Conditions // Conditions is an Implementable "duck type". var _ duck.Implementable = (*Conditions)(nil) -// +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // KResource is a skeleton type wrapping Conditions in the manner we expect diff --git a/apis/duck/v1alpha1/addressable_types.go b/apis/duck/v1alpha1/addressable_types.go index e0b330011..05a8d91ae 100644 --- a/apis/duck/v1alpha1/addressable_types.go +++ b/apis/duck/v1alpha1/addressable_types.go @@ -29,9 +29,11 @@ import ( "knative.dev/pkg/apis/duck/v1beta1" ) +// +genduck + // Addressable provides a generic mechanism for a custom resource // definition to indicate a destination for message delivery. - +// // Addressable is the schema for the destination information. This is // typically stored in the object's `status`, as this information may // be generated by the controller. @@ -48,7 +50,6 @@ var ( _ apis.Convertible = (*Addressable)(nil) ) -// +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // AddressableType is a skeleton type wrapping Addressable in the manner we expect diff --git a/apis/duck/v1alpha1/conditions_types.go b/apis/duck/v1alpha1/conditions_types.go index 043ad5e8a..5093898c9 100644 --- a/apis/duck/v1alpha1/conditions_types.go +++ b/apis/duck/v1alpha1/conditions_types.go @@ -27,6 +27,8 @@ import ( "knative.dev/pkg/apis/duck" ) +// +genduck + // Conditions is the schema for the conditions portion of the payload type Conditions []Condition @@ -118,7 +120,6 @@ func (c *Condition) IsUnknown() bool { // Conditions is an Implementable "duck type". var _ duck.Implementable = (*Conditions)(nil) -// +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // KResource is a skeleton type wrapping Conditions in the manner we expect diff --git a/apis/duck/v1alpha1/legacy_targetable_types.go b/apis/duck/v1alpha1/legacy_targetable_types.go index 27e7c3daa..c8a32a735 100644 --- a/apis/duck/v1alpha1/legacy_targetable_types.go +++ b/apis/duck/v1alpha1/legacy_targetable_types.go @@ -24,6 +24,8 @@ import ( "knative.dev/pkg/apis/duck" ) +// +genduck + // LegacyTargetable left around until we migrate to Addressable in the // dependent resources. Addressable has more structure in the way it // defines the fields. LegacyTargetable only assumed a single string @@ -32,7 +34,7 @@ import ( // This is to support existing resources until they migrate. // // Do not use this for anything new, use Addressable - +// // LegacyTargetable is the old schema for the addressable portion // of the payload // @@ -44,7 +46,6 @@ type LegacyTargetable struct { // LegacyTargetable is an Implementable "duck type". var _ duck.Implementable = (*LegacyTargetable)(nil) -// +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // LegacyTarget is a skeleton type wrapping LegacyTargetable in the manner we diff --git a/apis/duck/v1alpha1/retired_targetable_types.go b/apis/duck/v1alpha1/retired_targetable_types.go index 9306336d2..d8afb324a 100644 --- a/apis/duck/v1alpha1/retired_targetable_types.go +++ b/apis/duck/v1alpha1/retired_targetable_types.go @@ -24,6 +24,8 @@ import ( "knative.dev/pkg/apis/duck" ) +// +genduck + // Targetable is an earlier version of the Callable interface. // Callable is a higher-level interface which implements Addressable // but further promises that the destination may synchronously return @@ -31,7 +33,7 @@ import ( // // Targetable implementations should instead implement Addressable and // include an `eventing.knative.dev/returns=any` annotation. - +// // Targetable is retired; implement Addressable for now. type Targetable struct { DomainInternal string `json:"domainInternal,omitempty"` @@ -40,7 +42,6 @@ type Targetable struct { // Targetable is an Implementable "duck type". var _ duck.Implementable = (*Targetable)(nil) -// +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // Target is a skeleton type wrapping Targetable in the manner we expect diff --git a/apis/duck/v1beta1/addressable_types.go b/apis/duck/v1beta1/addressable_types.go index 2aa9de0d2..6093bd033 100644 --- a/apis/duck/v1beta1/addressable_types.go +++ b/apis/duck/v1beta1/addressable_types.go @@ -28,9 +28,11 @@ import ( v1 "knative.dev/pkg/apis/duck/v1" ) +// +genduck + // Addressable provides a generic mechanism for a custom resource // definition to indicate a destination for message delivery. - +// // Addressable is the schema for the destination information. This is // typically stored in the object's `status`, as this information may // be generated by the controller. @@ -45,7 +47,6 @@ var ( _ apis.Convertible = (*Addressable)(nil) ) -// +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // AddressableType is a skeleton type wrapping Addressable in the manner we expect diff --git a/apis/duck/v1beta1/source_types.go b/apis/duck/v1beta1/source_types.go index d4c478939..5853a1ae4 100644 --- a/apis/duck/v1beta1/source_types.go +++ b/apis/duck/v1beta1/source_types.go @@ -30,7 +30,7 @@ import ( // Source is an Implementable "duck type". var _ duck.Implementable = (*Source)(nil) -// +genclient +// +genduck // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // Source is the minimum resource shape to adhere to the Source Specification. diff --git a/apis/duck/v1beta1/status_types.go b/apis/duck/v1beta1/status_types.go index 7056b0d09..b2095fb58 100644 --- a/apis/duck/v1beta1/status_types.go +++ b/apis/duck/v1beta1/status_types.go @@ -28,13 +28,14 @@ import ( "knative.dev/pkg/apis/duck" ) +// +genduck + // Conditions is a simple wrapper around apis.Conditions to implement duck.Implementable. type Conditions apis.Conditions // Conditions is an Implementable "duck type". var _ duck.Implementable = (*Conditions)(nil) -// +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // KResource is a skeleton type wrapping Conditions in the manner we expect diff --git a/apis/duck/verify.go b/apis/duck/verify.go index 236a392c7..3f42330ff 100644 --- a/apis/duck/verify.go +++ b/apis/duck/verify.go @@ -20,6 +20,7 @@ import ( "encoding/json" "fmt" + "knative.dev/pkg/apis" "knative.dev/pkg/kmp" ) @@ -36,6 +37,8 @@ type Implementable interface { // duck type. It will generally have TypeMeta, ObjectMeta, and a Status field // wrapping a Fooable field. type Populatable interface { + apis.Listable + // Populate fills in all possible fields, so that we can verify that // they roundtrip properly through JSON. Populate() diff --git a/apis/duck/verify_test.go b/apis/duck/verify_test.go index d1fcbf074..497f2816c 100644 --- a/apis/duck/verify_test.go +++ b/apis/duck/verify_test.go @@ -19,6 +19,9 @@ package duck import ( "errors" "testing" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" ) func TestMatches(t *testing.T) { @@ -224,6 +227,18 @@ type FooStatus struct { var _ Implementable = (*Fooable)(nil) var _ Populatable = (*Foo)(nil) +func (*Foo) GetObjectKind() schema.ObjectKind { + return nil // not used +} + +func (p *Foo) DeepCopyObject() runtime.Object { + return nil // not used +} + +func (p *Foo) GetListType() runtime.Object { + return nil // not used +} + func (*Fooable) GetFullType() Populatable { return &Foo{} } @@ -251,6 +266,18 @@ type BarStatus struct { var _ Implementable = (*Barable)(nil) var _ Populatable = (*Bar)(nil) +func (*Bar) GetObjectKind() schema.ObjectKind { + return nil // not used +} + +func (p *Bar) DeepCopyObject() runtime.Object { + return nil // not used +} + +func (p *Bar) GetListType() runtime.Object { + return nil // not used +} + func (*Barable) GetFullType() Populatable { return &Bar{} } @@ -278,6 +305,18 @@ type SliceStatus struct { var _ Implementable = (*Sliceable)(nil) var _ Populatable = (*Slice)(nil) +func (*Slice) GetObjectKind() schema.ObjectKind { + return nil // not used +} + +func (p *Slice) DeepCopyObject() runtime.Object { + return nil // not used +} + +func (p *Slice) GetListType() runtime.Object { + return nil // not used +} + func (*Sliceable) GetFullType() Populatable { return &Slice{} } @@ -298,6 +337,18 @@ type StringStatus struct { var _ Implementable = (*Stringable)(nil) var _ Populatable = (*String)(nil) +func (*String) GetObjectKind() schema.ObjectKind { + return nil // not used +} + +func (p *String) DeepCopyObject() runtime.Object { + return nil // not used +} + +func (p *String) GetListType() runtime.Object { + return nil // not used +} + func (*Stringable) GetFullType() Populatable { return &String{} } @@ -316,6 +367,18 @@ type UnableToMarshal struct{} var _ Implementable = (*UnableToMarshal)(nil) var _ Populatable = (*UnableToMarshal)(nil) +func (*UnableToMarshal) GetObjectKind() schema.ObjectKind { + return nil // not used +} + +func (p *UnableToMarshal) DeepCopyObject() runtime.Object { + return nil // not used +} + +func (p *UnableToMarshal) GetListType() runtime.Object { + return nil // not used +} + func (u *UnableToMarshal) GetFullType() Populatable { return u } @@ -334,6 +397,18 @@ type UnableToUnmarshal struct{} var _ Implementable = (*UnableToUnmarshal)(nil) var _ Populatable = (*UnableToUnmarshal)(nil) +func (*UnableToUnmarshal) GetObjectKind() schema.ObjectKind { + return nil // not used +} + +func (p *UnableToUnmarshal) DeepCopyObject() runtime.Object { + return nil // not used +} + +func (p *UnableToUnmarshal) GetListType() runtime.Object { + return nil // not used +} + func (u *UnableToUnmarshal) GetFullType() Populatable { return u } @@ -354,6 +429,18 @@ type UnexportedFields struct { var _ Implementable = (*UnexportedFields)(nil) var _ Populatable = (*UnexportedFields)(nil) +func (*UnexportedFields) GetObjectKind() schema.ObjectKind { + return nil // not used +} + +func (p *UnexportedFields) DeepCopyObject() runtime.Object { + return nil // not used +} + +func (p *UnexportedFields) GetListType() runtime.Object { + return nil // not used +} + func (u *UnexportedFields) GetFullType() Populatable { return &UnexportedFields{} } diff --git a/client/injection/ducks/duck/v1/addressable/addressable.go b/client/injection/ducks/duck/v1/addressable/addressable.go new file mode 100644 index 000000000..81079c096 --- /dev/null +++ b/client/injection/ducks/duck/v1/addressable/addressable.go @@ -0,0 +1,60 @@ +/* +Copyright 2019 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package addressable + +import ( + "context" + + duck "knative.dev/pkg/apis/duck" + v1 "knative.dev/pkg/apis/duck/v1" + controller "knative.dev/pkg/controller" + injection "knative.dev/pkg/injection" + dynamicclient "knative.dev/pkg/injection/clients/dynamicclient" + logging "knative.dev/pkg/logging" +) + +func init() { + injection.Default.RegisterDuck(WithDuck) +} + +// Key is used for associating the Informer inside the context.Context. +type Key struct{} + +func WithDuck(ctx context.Context) context.Context { + dc := dynamicclient.Get(ctx) + dif := &duck.CachedInformerFactory{ + Delegate: &duck.TypedInformerFactory{ + Client: dc, + Type: (&v1.Addressable{}).GetFullType(), + ResyncPeriod: controller.GetResyncPeriod(ctx), + StopChannel: ctx.Done(), + }, + } + return context.WithValue(ctx, Key{}, dif) +} + +// Get extracts the typed informer from the context. +func Get(ctx context.Context) duck.InformerFactory { + untyped := ctx.Value(Key{}) + if untyped == nil { + logging.FromContext(ctx).Panic( + "Unable to fetch knative.dev/pkg/apis/duck.InformerFactory from context.") + } + return untyped.(duck.InformerFactory) +} diff --git a/client/injection/ducks/duck/v1/addressable/fake/fake.go b/client/injection/ducks/duck/v1/addressable/fake/fake.go new file mode 100644 index 000000000..f3f9b3b85 --- /dev/null +++ b/client/injection/ducks/duck/v1/addressable/fake/fake.go @@ -0,0 +1,30 @@ +/* +Copyright 2019 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package fake + +import ( + addressable "knative.dev/pkg/client/injection/ducks/duck/v1/addressable" + injection "knative.dev/pkg/injection" +) + +var Get = addressable.Get + +func init() { + injection.Fake.RegisterDuck(addressable.WithDuck) +} diff --git a/client/injection/ducks/duck/v1/conditions/conditions.go b/client/injection/ducks/duck/v1/conditions/conditions.go new file mode 100644 index 000000000..9bd73b060 --- /dev/null +++ b/client/injection/ducks/duck/v1/conditions/conditions.go @@ -0,0 +1,60 @@ +/* +Copyright 2019 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package conditions + +import ( + "context" + + duck "knative.dev/pkg/apis/duck" + v1 "knative.dev/pkg/apis/duck/v1" + controller "knative.dev/pkg/controller" + injection "knative.dev/pkg/injection" + dynamicclient "knative.dev/pkg/injection/clients/dynamicclient" + logging "knative.dev/pkg/logging" +) + +func init() { + injection.Default.RegisterDuck(WithDuck) +} + +// Key is used for associating the Informer inside the context.Context. +type Key struct{} + +func WithDuck(ctx context.Context) context.Context { + dc := dynamicclient.Get(ctx) + dif := &duck.CachedInformerFactory{ + Delegate: &duck.TypedInformerFactory{ + Client: dc, + Type: (&v1.Conditions{}).GetFullType(), + ResyncPeriod: controller.GetResyncPeriod(ctx), + StopChannel: ctx.Done(), + }, + } + return context.WithValue(ctx, Key{}, dif) +} + +// Get extracts the typed informer from the context. +func Get(ctx context.Context) duck.InformerFactory { + untyped := ctx.Value(Key{}) + if untyped == nil { + logging.FromContext(ctx).Panic( + "Unable to fetch knative.dev/pkg/apis/duck.InformerFactory from context.") + } + return untyped.(duck.InformerFactory) +} diff --git a/client/injection/ducks/duck/v1/conditions/fake/fake.go b/client/injection/ducks/duck/v1/conditions/fake/fake.go new file mode 100644 index 000000000..7e9b5b215 --- /dev/null +++ b/client/injection/ducks/duck/v1/conditions/fake/fake.go @@ -0,0 +1,30 @@ +/* +Copyright 2019 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package fake + +import ( + conditions "knative.dev/pkg/client/injection/ducks/duck/v1/conditions" + injection "knative.dev/pkg/injection" +) + +var Get = conditions.Get + +func init() { + injection.Fake.RegisterDuck(conditions.WithDuck) +} diff --git a/client/injection/ducks/duck/v1/podspecable/fake/fake.go b/client/injection/ducks/duck/v1/podspecable/fake/fake.go new file mode 100644 index 000000000..26db5f2a7 --- /dev/null +++ b/client/injection/ducks/duck/v1/podspecable/fake/fake.go @@ -0,0 +1,30 @@ +/* +Copyright 2019 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package fake + +import ( + podspecable "knative.dev/pkg/client/injection/ducks/duck/v1/podspecable" + injection "knative.dev/pkg/injection" +) + +var Get = podspecable.Get + +func init() { + injection.Fake.RegisterDuck(podspecable.WithDuck) +} diff --git a/client/injection/ducks/duck/v1/podspecable/podspecable.go b/client/injection/ducks/duck/v1/podspecable/podspecable.go new file mode 100644 index 000000000..92b92a716 --- /dev/null +++ b/client/injection/ducks/duck/v1/podspecable/podspecable.go @@ -0,0 +1,60 @@ +/* +Copyright 2019 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package podspecable + +import ( + "context" + + duck "knative.dev/pkg/apis/duck" + v1 "knative.dev/pkg/apis/duck/v1" + controller "knative.dev/pkg/controller" + injection "knative.dev/pkg/injection" + dynamicclient "knative.dev/pkg/injection/clients/dynamicclient" + logging "knative.dev/pkg/logging" +) + +func init() { + injection.Default.RegisterDuck(WithDuck) +} + +// Key is used for associating the Informer inside the context.Context. +type Key struct{} + +func WithDuck(ctx context.Context) context.Context { + dc := dynamicclient.Get(ctx) + dif := &duck.CachedInformerFactory{ + Delegate: &duck.TypedInformerFactory{ + Client: dc, + Type: (&v1.PodSpecable{}).GetFullType(), + ResyncPeriod: controller.GetResyncPeriod(ctx), + StopChannel: ctx.Done(), + }, + } + return context.WithValue(ctx, Key{}, dif) +} + +// Get extracts the typed informer from the context. +func Get(ctx context.Context) duck.InformerFactory { + untyped := ctx.Value(Key{}) + if untyped == nil { + logging.FromContext(ctx).Panic( + "Unable to fetch knative.dev/pkg/apis/duck.InformerFactory from context.") + } + return untyped.(duck.InformerFactory) +} diff --git a/client/injection/ducks/duck/v1/source/fake/fake.go b/client/injection/ducks/duck/v1/source/fake/fake.go new file mode 100644 index 000000000..c5f3cd1e0 --- /dev/null +++ b/client/injection/ducks/duck/v1/source/fake/fake.go @@ -0,0 +1,30 @@ +/* +Copyright 2019 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package fake + +import ( + source "knative.dev/pkg/client/injection/ducks/duck/v1/source" + injection "knative.dev/pkg/injection" +) + +var Get = source.Get + +func init() { + injection.Fake.RegisterDuck(source.WithDuck) +} diff --git a/client/injection/ducks/duck/v1/source/source.go b/client/injection/ducks/duck/v1/source/source.go new file mode 100644 index 000000000..5f6a38dec --- /dev/null +++ b/client/injection/ducks/duck/v1/source/source.go @@ -0,0 +1,60 @@ +/* +Copyright 2019 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package source + +import ( + "context" + + duck "knative.dev/pkg/apis/duck" + v1 "knative.dev/pkg/apis/duck/v1" + controller "knative.dev/pkg/controller" + injection "knative.dev/pkg/injection" + dynamicclient "knative.dev/pkg/injection/clients/dynamicclient" + logging "knative.dev/pkg/logging" +) + +func init() { + injection.Default.RegisterDuck(WithDuck) +} + +// Key is used for associating the Informer inside the context.Context. +type Key struct{} + +func WithDuck(ctx context.Context) context.Context { + dc := dynamicclient.Get(ctx) + dif := &duck.CachedInformerFactory{ + Delegate: &duck.TypedInformerFactory{ + Client: dc, + Type: (&v1.Source{}).GetFullType(), + ResyncPeriod: controller.GetResyncPeriod(ctx), + StopChannel: ctx.Done(), + }, + } + return context.WithValue(ctx, Key{}, dif) +} + +// Get extracts the typed informer from the context. +func Get(ctx context.Context) duck.InformerFactory { + untyped := ctx.Value(Key{}) + if untyped == nil { + logging.FromContext(ctx).Panic( + "Unable to fetch knative.dev/pkg/apis/duck.InformerFactory from context.") + } + return untyped.(duck.InformerFactory) +} diff --git a/client/injection/ducks/duck/v1alpha1/addressable/addressable.go b/client/injection/ducks/duck/v1alpha1/addressable/addressable.go new file mode 100644 index 000000000..b7cd815bd --- /dev/null +++ b/client/injection/ducks/duck/v1alpha1/addressable/addressable.go @@ -0,0 +1,60 @@ +/* +Copyright 2019 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package addressable + +import ( + "context" + + duck "knative.dev/pkg/apis/duck" + v1alpha1 "knative.dev/pkg/apis/duck/v1alpha1" + controller "knative.dev/pkg/controller" + injection "knative.dev/pkg/injection" + dynamicclient "knative.dev/pkg/injection/clients/dynamicclient" + logging "knative.dev/pkg/logging" +) + +func init() { + injection.Default.RegisterDuck(WithDuck) +} + +// Key is used for associating the Informer inside the context.Context. +type Key struct{} + +func WithDuck(ctx context.Context) context.Context { + dc := dynamicclient.Get(ctx) + dif := &duck.CachedInformerFactory{ + Delegate: &duck.TypedInformerFactory{ + Client: dc, + Type: (&v1alpha1.Addressable{}).GetFullType(), + ResyncPeriod: controller.GetResyncPeriod(ctx), + StopChannel: ctx.Done(), + }, + } + return context.WithValue(ctx, Key{}, dif) +} + +// Get extracts the typed informer from the context. +func Get(ctx context.Context) duck.InformerFactory { + untyped := ctx.Value(Key{}) + if untyped == nil { + logging.FromContext(ctx).Panic( + "Unable to fetch knative.dev/pkg/apis/duck.InformerFactory from context.") + } + return untyped.(duck.InformerFactory) +} diff --git a/client/injection/ducks/duck/v1alpha1/addressable/fake/fake.go b/client/injection/ducks/duck/v1alpha1/addressable/fake/fake.go new file mode 100644 index 000000000..8b6d8e5c8 --- /dev/null +++ b/client/injection/ducks/duck/v1alpha1/addressable/fake/fake.go @@ -0,0 +1,30 @@ +/* +Copyright 2019 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package fake + +import ( + addressable "knative.dev/pkg/client/injection/ducks/duck/v1alpha1/addressable" + injection "knative.dev/pkg/injection" +) + +var Get = addressable.Get + +func init() { + injection.Fake.RegisterDuck(addressable.WithDuck) +} diff --git a/client/injection/ducks/duck/v1alpha1/conditions/conditions.go b/client/injection/ducks/duck/v1alpha1/conditions/conditions.go new file mode 100644 index 000000000..5bdbf9f5a --- /dev/null +++ b/client/injection/ducks/duck/v1alpha1/conditions/conditions.go @@ -0,0 +1,60 @@ +/* +Copyright 2019 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package conditions + +import ( + "context" + + duck "knative.dev/pkg/apis/duck" + v1alpha1 "knative.dev/pkg/apis/duck/v1alpha1" + controller "knative.dev/pkg/controller" + injection "knative.dev/pkg/injection" + dynamicclient "knative.dev/pkg/injection/clients/dynamicclient" + logging "knative.dev/pkg/logging" +) + +func init() { + injection.Default.RegisterDuck(WithDuck) +} + +// Key is used for associating the Informer inside the context.Context. +type Key struct{} + +func WithDuck(ctx context.Context) context.Context { + dc := dynamicclient.Get(ctx) + dif := &duck.CachedInformerFactory{ + Delegate: &duck.TypedInformerFactory{ + Client: dc, + Type: (&v1alpha1.Conditions{}).GetFullType(), + ResyncPeriod: controller.GetResyncPeriod(ctx), + StopChannel: ctx.Done(), + }, + } + return context.WithValue(ctx, Key{}, dif) +} + +// Get extracts the typed informer from the context. +func Get(ctx context.Context) duck.InformerFactory { + untyped := ctx.Value(Key{}) + if untyped == nil { + logging.FromContext(ctx).Panic( + "Unable to fetch knative.dev/pkg/apis/duck.InformerFactory from context.") + } + return untyped.(duck.InformerFactory) +} diff --git a/client/injection/ducks/duck/v1alpha1/conditions/fake/fake.go b/client/injection/ducks/duck/v1alpha1/conditions/fake/fake.go new file mode 100644 index 000000000..06fcf1d80 --- /dev/null +++ b/client/injection/ducks/duck/v1alpha1/conditions/fake/fake.go @@ -0,0 +1,30 @@ +/* +Copyright 2019 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package fake + +import ( + conditions "knative.dev/pkg/client/injection/ducks/duck/v1alpha1/conditions" + injection "knative.dev/pkg/injection" +) + +var Get = conditions.Get + +func init() { + injection.Fake.RegisterDuck(conditions.WithDuck) +} diff --git a/client/injection/ducks/duck/v1alpha1/legacytargetable/fake/fake.go b/client/injection/ducks/duck/v1alpha1/legacytargetable/fake/fake.go new file mode 100644 index 000000000..382913e2a --- /dev/null +++ b/client/injection/ducks/duck/v1alpha1/legacytargetable/fake/fake.go @@ -0,0 +1,30 @@ +/* +Copyright 2019 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package fake + +import ( + legacytargetable "knative.dev/pkg/client/injection/ducks/duck/v1alpha1/legacytargetable" + injection "knative.dev/pkg/injection" +) + +var Get = legacytargetable.Get + +func init() { + injection.Fake.RegisterDuck(legacytargetable.WithDuck) +} diff --git a/client/injection/ducks/duck/v1alpha1/legacytargetable/legacytargetable.go b/client/injection/ducks/duck/v1alpha1/legacytargetable/legacytargetable.go new file mode 100644 index 000000000..9d09a2934 --- /dev/null +++ b/client/injection/ducks/duck/v1alpha1/legacytargetable/legacytargetable.go @@ -0,0 +1,60 @@ +/* +Copyright 2019 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package legacytargetable + +import ( + "context" + + duck "knative.dev/pkg/apis/duck" + v1alpha1 "knative.dev/pkg/apis/duck/v1alpha1" + controller "knative.dev/pkg/controller" + injection "knative.dev/pkg/injection" + dynamicclient "knative.dev/pkg/injection/clients/dynamicclient" + logging "knative.dev/pkg/logging" +) + +func init() { + injection.Default.RegisterDuck(WithDuck) +} + +// Key is used for associating the Informer inside the context.Context. +type Key struct{} + +func WithDuck(ctx context.Context) context.Context { + dc := dynamicclient.Get(ctx) + dif := &duck.CachedInformerFactory{ + Delegate: &duck.TypedInformerFactory{ + Client: dc, + Type: (&v1alpha1.LegacyTargetable{}).GetFullType(), + ResyncPeriod: controller.GetResyncPeriod(ctx), + StopChannel: ctx.Done(), + }, + } + return context.WithValue(ctx, Key{}, dif) +} + +// Get extracts the typed informer from the context. +func Get(ctx context.Context) duck.InformerFactory { + untyped := ctx.Value(Key{}) + if untyped == nil { + logging.FromContext(ctx).Panic( + "Unable to fetch knative.dev/pkg/apis/duck.InformerFactory from context.") + } + return untyped.(duck.InformerFactory) +} diff --git a/client/injection/ducks/duck/v1alpha1/targetable/fake/fake.go b/client/injection/ducks/duck/v1alpha1/targetable/fake/fake.go new file mode 100644 index 000000000..6fb1aa236 --- /dev/null +++ b/client/injection/ducks/duck/v1alpha1/targetable/fake/fake.go @@ -0,0 +1,30 @@ +/* +Copyright 2019 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package fake + +import ( + targetable "knative.dev/pkg/client/injection/ducks/duck/v1alpha1/targetable" + injection "knative.dev/pkg/injection" +) + +var Get = targetable.Get + +func init() { + injection.Fake.RegisterDuck(targetable.WithDuck) +} diff --git a/client/injection/ducks/duck/v1alpha1/targetable/targetable.go b/client/injection/ducks/duck/v1alpha1/targetable/targetable.go new file mode 100644 index 000000000..c4deac1ca --- /dev/null +++ b/client/injection/ducks/duck/v1alpha1/targetable/targetable.go @@ -0,0 +1,60 @@ +/* +Copyright 2019 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package targetable + +import ( + "context" + + duck "knative.dev/pkg/apis/duck" + v1alpha1 "knative.dev/pkg/apis/duck/v1alpha1" + controller "knative.dev/pkg/controller" + injection "knative.dev/pkg/injection" + dynamicclient "knative.dev/pkg/injection/clients/dynamicclient" + logging "knative.dev/pkg/logging" +) + +func init() { + injection.Default.RegisterDuck(WithDuck) +} + +// Key is used for associating the Informer inside the context.Context. +type Key struct{} + +func WithDuck(ctx context.Context) context.Context { + dc := dynamicclient.Get(ctx) + dif := &duck.CachedInformerFactory{ + Delegate: &duck.TypedInformerFactory{ + Client: dc, + Type: (&v1alpha1.Targetable{}).GetFullType(), + ResyncPeriod: controller.GetResyncPeriod(ctx), + StopChannel: ctx.Done(), + }, + } + return context.WithValue(ctx, Key{}, dif) +} + +// Get extracts the typed informer from the context. +func Get(ctx context.Context) duck.InformerFactory { + untyped := ctx.Value(Key{}) + if untyped == nil { + logging.FromContext(ctx).Panic( + "Unable to fetch knative.dev/pkg/apis/duck.InformerFactory from context.") + } + return untyped.(duck.InformerFactory) +} diff --git a/client/injection/ducks/duck/v1beta1/addressable/addressable.go b/client/injection/ducks/duck/v1beta1/addressable/addressable.go new file mode 100644 index 000000000..1bccaa559 --- /dev/null +++ b/client/injection/ducks/duck/v1beta1/addressable/addressable.go @@ -0,0 +1,60 @@ +/* +Copyright 2019 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package addressable + +import ( + "context" + + duck "knative.dev/pkg/apis/duck" + v1beta1 "knative.dev/pkg/apis/duck/v1beta1" + controller "knative.dev/pkg/controller" + injection "knative.dev/pkg/injection" + dynamicclient "knative.dev/pkg/injection/clients/dynamicclient" + logging "knative.dev/pkg/logging" +) + +func init() { + injection.Default.RegisterDuck(WithDuck) +} + +// Key is used for associating the Informer inside the context.Context. +type Key struct{} + +func WithDuck(ctx context.Context) context.Context { + dc := dynamicclient.Get(ctx) + dif := &duck.CachedInformerFactory{ + Delegate: &duck.TypedInformerFactory{ + Client: dc, + Type: (&v1beta1.Addressable{}).GetFullType(), + ResyncPeriod: controller.GetResyncPeriod(ctx), + StopChannel: ctx.Done(), + }, + } + return context.WithValue(ctx, Key{}, dif) +} + +// Get extracts the typed informer from the context. +func Get(ctx context.Context) duck.InformerFactory { + untyped := ctx.Value(Key{}) + if untyped == nil { + logging.FromContext(ctx).Panic( + "Unable to fetch knative.dev/pkg/apis/duck.InformerFactory from context.") + } + return untyped.(duck.InformerFactory) +} diff --git a/client/injection/ducks/duck/v1beta1/addressable/fake/fake.go b/client/injection/ducks/duck/v1beta1/addressable/fake/fake.go new file mode 100644 index 000000000..5c4617a0b --- /dev/null +++ b/client/injection/ducks/duck/v1beta1/addressable/fake/fake.go @@ -0,0 +1,30 @@ +/* +Copyright 2019 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package fake + +import ( + addressable "knative.dev/pkg/client/injection/ducks/duck/v1beta1/addressable" + injection "knative.dev/pkg/injection" +) + +var Get = addressable.Get + +func init() { + injection.Fake.RegisterDuck(addressable.WithDuck) +} diff --git a/client/injection/ducks/duck/v1beta1/conditions/conditions.go b/client/injection/ducks/duck/v1beta1/conditions/conditions.go new file mode 100644 index 000000000..869e79dc1 --- /dev/null +++ b/client/injection/ducks/duck/v1beta1/conditions/conditions.go @@ -0,0 +1,60 @@ +/* +Copyright 2019 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package conditions + +import ( + "context" + + duck "knative.dev/pkg/apis/duck" + v1beta1 "knative.dev/pkg/apis/duck/v1beta1" + controller "knative.dev/pkg/controller" + injection "knative.dev/pkg/injection" + dynamicclient "knative.dev/pkg/injection/clients/dynamicclient" + logging "knative.dev/pkg/logging" +) + +func init() { + injection.Default.RegisterDuck(WithDuck) +} + +// Key is used for associating the Informer inside the context.Context. +type Key struct{} + +func WithDuck(ctx context.Context) context.Context { + dc := dynamicclient.Get(ctx) + dif := &duck.CachedInformerFactory{ + Delegate: &duck.TypedInformerFactory{ + Client: dc, + Type: (&v1beta1.Conditions{}).GetFullType(), + ResyncPeriod: controller.GetResyncPeriod(ctx), + StopChannel: ctx.Done(), + }, + } + return context.WithValue(ctx, Key{}, dif) +} + +// Get extracts the typed informer from the context. +func Get(ctx context.Context) duck.InformerFactory { + untyped := ctx.Value(Key{}) + if untyped == nil { + logging.FromContext(ctx).Panic( + "Unable to fetch knative.dev/pkg/apis/duck.InformerFactory from context.") + } + return untyped.(duck.InformerFactory) +} diff --git a/client/injection/ducks/duck/v1beta1/conditions/fake/fake.go b/client/injection/ducks/duck/v1beta1/conditions/fake/fake.go new file mode 100644 index 000000000..e50d50bc9 --- /dev/null +++ b/client/injection/ducks/duck/v1beta1/conditions/fake/fake.go @@ -0,0 +1,30 @@ +/* +Copyright 2019 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package fake + +import ( + conditions "knative.dev/pkg/client/injection/ducks/duck/v1beta1/conditions" + injection "knative.dev/pkg/injection" +) + +var Get = conditions.Get + +func init() { + injection.Fake.RegisterDuck(conditions.WithDuck) +} diff --git a/client/injection/ducks/duck/v1beta1/source/fake/fake.go b/client/injection/ducks/duck/v1beta1/source/fake/fake.go new file mode 100644 index 000000000..7ef330c7b --- /dev/null +++ b/client/injection/ducks/duck/v1beta1/source/fake/fake.go @@ -0,0 +1,30 @@ +/* +Copyright 2019 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package fake + +import ( + source "knative.dev/pkg/client/injection/ducks/duck/v1beta1/source" + injection "knative.dev/pkg/injection" +) + +var Get = source.Get + +func init() { + injection.Fake.RegisterDuck(source.WithDuck) +} diff --git a/client/injection/ducks/duck/v1beta1/source/source.go b/client/injection/ducks/duck/v1beta1/source/source.go new file mode 100644 index 000000000..20559ceb7 --- /dev/null +++ b/client/injection/ducks/duck/v1beta1/source/source.go @@ -0,0 +1,60 @@ +/* +Copyright 2019 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package source + +import ( + "context" + + duck "knative.dev/pkg/apis/duck" + v1beta1 "knative.dev/pkg/apis/duck/v1beta1" + controller "knative.dev/pkg/controller" + injection "knative.dev/pkg/injection" + dynamicclient "knative.dev/pkg/injection/clients/dynamicclient" + logging "knative.dev/pkg/logging" +) + +func init() { + injection.Default.RegisterDuck(WithDuck) +} + +// Key is used for associating the Informer inside the context.Context. +type Key struct{} + +func WithDuck(ctx context.Context) context.Context { + dc := dynamicclient.Get(ctx) + dif := &duck.CachedInformerFactory{ + Delegate: &duck.TypedInformerFactory{ + Client: dc, + Type: (&v1beta1.Source{}).GetFullType(), + ResyncPeriod: controller.GetResyncPeriod(ctx), + StopChannel: ctx.Done(), + }, + } + return context.WithValue(ctx, Key{}, dif) +} + +// Get extracts the typed informer from the context. +func Get(ctx context.Context) duck.InformerFactory { + untyped := ctx.Value(Key{}) + if untyped == nil { + logging.FromContext(ctx).Panic( + "Unable to fetch knative.dev/pkg/apis/duck.InformerFactory from context.") + } + return untyped.(duck.InformerFactory) +} diff --git a/codegen/cmd/injection-gen/generators/duck.go b/codegen/cmd/injection-gen/generators/duck.go new file mode 100644 index 000000000..b755ce7de --- /dev/null +++ b/codegen/cmd/injection-gen/generators/duck.go @@ -0,0 +1,130 @@ +/* +Copyright 2019 The Knative Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package generators + +import ( + "io" + + clientgentypes "k8s.io/code-generator/cmd/client-gen/types" + "k8s.io/gengo/generator" + "k8s.io/gengo/namer" + "k8s.io/gengo/types" + "k8s.io/klog" +) + +// duckGenerator produces logic to register a duck.InformerFactory for a particular +// type onto context. +type duckGenerator struct { + generator.DefaultGen + outputPackage string + groupVersion clientgentypes.GroupVersion + groupGoName string + typeToGenerate *types.Type + imports namer.ImportTracker +} + +var _ generator.Generator = (*duckGenerator)(nil) + +func (g *duckGenerator) Filter(c *generator.Context, t *types.Type) bool { + // Only process the type for this informer generator. + return t == g.typeToGenerate +} + +func (g *duckGenerator) Namers(c *generator.Context) namer.NameSystems { + publicPluralNamer := &ExceptionNamer{ + Exceptions: map[string]string{ + // these exceptions are used to deconflict the generated code + // you can put your fully qualified package like + // to generate a name that doesn't conflict with your group. + // "k8s.io/apis/events/v1beta1.Event": "EventResource" + }, + KeyFunc: func(t *types.Type) string { + return t.Name.Package + "." + t.Name.Name + }, + Delegate: namer.NewPublicPluralNamer(map[string]string{ + "Endpoints": "Endpoints", + }), + } + + return namer.NameSystems{ + "raw": namer.NewRawNamer(g.outputPackage, g.imports), + "publicPlural": publicPluralNamer, + } +} + +func (g *duckGenerator) Imports(c *generator.Context) (imports []string) { + imports = append(imports, g.imports.ImportLines()...) + return +} + +func (g *duckGenerator) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { + sw := generator.NewSnippetWriter(w, c, "{{", "}}") + + klog.V(5).Infof("processing type %v", t) + + m := map[string]interface{}{ + "group": namer.IC(g.groupGoName), + "type": t, + "version": namer.IC(g.groupVersion.Version.String()), + "injectionRegisterDuck": c.Universe.Type(types.Name{Package: "knative.dev/pkg/injection", Name: "Default.RegisterDuck"}), + "getResyncPeriod": c.Universe.Type(types.Name{Package: "knative.dev/pkg/controller", Name: "GetResyncPeriod"}), + "dynamicGet": c.Universe.Type(types.Name{Package: "knative.dev/pkg/injection/clients/dynamicclient", Name: "Get"}), + "duckTypedInformerFactory": c.Universe.Type(types.Name{Package: "knative.dev/pkg/apis/duck", Name: "TypedInformerFactory"}), + "duckCachedInformerFactory": c.Universe.Type(types.Name{Package: "knative.dev/pkg/apis/duck", Name: "CachedInformerFactory"}), + "duckInformerFactory": c.Universe.Type(types.Name{Package: "knative.dev/pkg/apis/duck", Name: "InformerFactory"}), + "loggingFromContext": c.Universe.Function(types.Name{ + Package: "knative.dev/pkg/logging", + Name: "FromContext", + }), + } + + sw.Do(duckFactory, m) + + return sw.Error() +} + +var duckFactory = ` +func init() { + {{.injectionRegisterDuck|raw}}(WithDuck) +} + +// Key is used for associating the Informer inside the context.Context. +type Key struct{} + +func WithDuck(ctx context.Context) context.Context { + dc := {{.dynamicGet|raw}}(ctx) + dif := &{{.duckCachedInformerFactory|raw}}{ + Delegate: &{{.duckTypedInformerFactory|raw}}{ + Client: dc, + Type: (&{{.type|raw}}{}).GetFullType(), + ResyncPeriod: {{.getResyncPeriod|raw}}(ctx), + StopChannel: ctx.Done(), + }, + } + return context.WithValue(ctx, Key{}, dif) +} + +// Get extracts the typed informer from the context. +func Get(ctx context.Context) {{.duckInformerFactory|raw}} { + untyped := ctx.Value(Key{}) + if untyped == nil { + {{.loggingFromContext|raw}}(ctx).Panic( + "Unable to fetch {{.duckInformerFactory}} from context.") + } + return untyped.({{.duckInformerFactory|raw}}) +} +` diff --git a/codegen/cmd/injection-gen/generators/fakeduck.go b/codegen/cmd/injection-gen/generators/fakeduck.go new file mode 100644 index 000000000..df036c618 --- /dev/null +++ b/codegen/cmd/injection-gen/generators/fakeduck.go @@ -0,0 +1,104 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package generators + +import ( + "io" + + clientgentypes "k8s.io/code-generator/cmd/client-gen/types" + "k8s.io/gengo/generator" + "k8s.io/gengo/namer" + "k8s.io/gengo/types" + "k8s.io/klog" +) + +// fakeDuckGenerator produces a file of listers for a given GroupVersion and +// type. +type fakeDuckGenerator struct { + generator.DefaultGen + outputPackage string + imports namer.ImportTracker + + typeToGenerate *types.Type + groupVersion clientgentypes.GroupVersion + groupGoName string + duckInjectionPkg string +} + +var _ generator.Generator = (*fakeDuckGenerator)(nil) + +func (g *fakeDuckGenerator) Filter(c *generator.Context, t *types.Type) bool { + // Only process the type for this duck generator. + return t == g.typeToGenerate +} + +func (g *fakeDuckGenerator) Namers(c *generator.Context) namer.NameSystems { + publicPluralNamer := &ExceptionNamer{ + Exceptions: map[string]string{ + // these exceptions are used to deconflict the generated code + // you can put your fully qualified package like + // to generate a name that doesn't conflict with your group. + // "k8s.io/apis/events/v1beta1.Event": "EventResource" + }, + KeyFunc: func(t *types.Type) string { + return t.Name.Package + "." + t.Name.Name + }, + Delegate: namer.NewPublicPluralNamer(map[string]string{ + "Endpoints": "Endpoints", + }), + } + + return namer.NameSystems{ + "raw": namer.NewRawNamer(g.outputPackage, g.imports), + "publicPlural": publicPluralNamer, + } +} + +func (g *fakeDuckGenerator) Imports(c *generator.Context) (imports []string) { + imports = append(imports, g.imports.ImportLines()...) + return +} + +func (g *fakeDuckGenerator) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { + sw := generator.NewSnippetWriter(w, c, "{{", "}}") + + klog.V(5).Infof("processing type %v", t) + + m := map[string]interface{}{ + "withDuck": c.Universe.Type(types.Name{Package: g.duckInjectionPkg, Name: "WithDuck"}), + "duckGet": c.Universe.Function(types.Name{Package: g.duckInjectionPkg, Name: "Get"}), + "group": namer.IC(g.groupGoName), + "type": t, + "version": namer.IC(g.groupVersion.Version.String()), + "injectionRegisterDuck": c.Universe.Function(types.Name{ + Package: "knative.dev/pkg/injection", + Name: "Fake.RegisterDuck", + }), + } + + sw.Do(injectionFakeDuck, m) + + return sw.Error() +} + +var injectionFakeDuck = ` +var Get = {{.duckGet|raw}} + +func init() { + {{.injectionRegisterDuck|raw}}({{.withDuck|raw}}) +} +` diff --git a/codegen/cmd/injection-gen/generators/packages.go b/codegen/cmd/injection-gen/generators/packages.go index 1a58a3c6c..2b14c4bda 100644 --- a/codegen/cmd/injection-gen/generators/packages.go +++ b/codegen/cmd/injection-gen/generators/packages.go @@ -48,22 +48,12 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat versionPackagePath := filepath.Join(arguments.OutputPackagePath) var packageList generator.Packages - typesForGroupVersion := make(map[clientgentypes.GroupVersion][]*types.Type) groupVersions := make(map[string]clientgentypes.GroupVersions) groupGoNames := make(map[string]string) for _, inputDir := range arguments.InputDirs { p := context.Universe.Package(vendorless(inputDir)) - objectMeta, _, err := objectMetaForPackage(p) // TODO: ignoring internal. - if err != nil { - klog.Fatal(err) - } - if objectMeta == nil { - // no types in this package had genclient - continue - } - var gv clientgentypes.GroupVersion var targetGroupVersions map[string]clientgentypes.GroupVersions @@ -95,22 +85,16 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat // Generate the informer factory and fake. packageList = append(packageList, versionFactoryPackages(versionPackagePath, boilerplate, customArgs)...) - var typesToGenerate []*types.Type + var typesWithInformers []*types.Type + var duckTypes []*types.Type for _, t := range p.Types { - tags := util.MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) - if !tags.GenerateClient || tags.NoVerbs || !tags.HasVerb("list") || !tags.HasVerb("watch") { - continue + tags := MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) + if tags.NeedsInformerInjection() { + typesWithInformers = append(typesWithInformers, t) } - - typesToGenerate = append(typesToGenerate, t) - - if _, ok := typesForGroupVersion[gv]; !ok { - typesForGroupVersion[gv] = []*types.Type{} + if tags.NeedsDuckInjection() { + duckTypes = append(duckTypes, t) } - typesForGroupVersion[gv] = append(typesForGroupVersion[gv], t) - } - if len(typesToGenerate) == 0 { - continue } groupVersionsEntry, ok := targetGroupVersions[groupPackageName] @@ -123,34 +107,52 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat groupVersionsEntry.Versions = append(groupVersionsEntry.Versions, clientgentypes.PackageVersion{Version: gv.Version, Package: gvPackage}) targetGroupVersions[groupPackageName] = groupVersionsEntry - orderer := namer.Orderer{Namer: namer.NewPrivateNamer(0)} - typesToGenerate = orderer.OrderTypes(typesToGenerate) + if len(typesWithInformers) != 0 { + orderer := namer.Orderer{Namer: namer.NewPrivateNamer(0)} + typesWithInformers = orderer.OrderTypes(typesWithInformers) - // Generate the informer and fake, for each type. - packageList = append(packageList, versionInformerPackages(versionPackagePath, groupPackageName, gv, groupGoNames[groupPackageName], boilerplate, typesToGenerate, customArgs)...) + // Generate the informer and fake, for each type. + packageList = append(packageList, versionInformerPackages(versionPackagePath, groupPackageName, gv, groupGoNames[groupPackageName], boilerplate, typesWithInformers, customArgs)...) + } + + if len(duckTypes) != 0 { + orderer := namer.Orderer{Namer: namer.NewPrivateNamer(0)} + duckTypes = orderer.OrderTypes(duckTypes) + + // Generate a duck-typed informer for each type. + packageList = append(packageList, versionDuckPackages(versionPackagePath, groupPackageName, gv, groupGoNames[groupPackageName], boilerplate, duckTypes, customArgs)...) + } } return packageList } -// objectMetaForPackage returns the type of ObjectMeta used by package p. -func objectMetaForPackage(p *types.Package) (*types.Type, bool, error) { - generatingForPackage := false - for _, t := range p.Types { - if !util.MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)).GenerateClient { - continue - } - generatingForPackage = true - for _, member := range t.Members { - if member.Name == "ObjectMeta" { - return member.Type, isInternal(member), nil - } - } +// Tags represents a genclient configuration for a single type. +type Tags struct { + util.Tags + + GenerateDuck bool +} + +func (t Tags) NeedsInformerInjection() bool { + return t.GenerateClient && !t.NoVerbs && t.HasVerb("list") && t.HasVerb("watch") +} + +func (t Tags) NeedsDuckInjection() bool { + return t.GenerateDuck +} + +// MustParseClientGenTags calls ParseClientGenTags but instead of returning error it panics. +func MustParseClientGenTags(lines []string) Tags { + ret := Tags{ + Tags: util.MustParseClientGenTags(lines), } - if generatingForPackage { - return nil, false, fmt.Errorf("unable to find ObjectMeta for any types in package %s", p.Path) - } - return nil, false, nil + + values := types.ExtractCommentTags("+", lines) + // log.Printf("GOT values %v", values) + _, ret.GenerateDuck = values["genduck"] + + return ret } // isInternal returns true if the tags for a member do not contain a json tag @@ -193,8 +195,8 @@ func versionClientsPackages(basePackage string, boilerplate []byte, customArgs * return generators }, FilterFunc: func(c *generator.Context, t *types.Type) bool { - tags := util.MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) - return tags.GenerateClient && tags.HasVerb("list") && tags.HasVerb("watch") + tags := MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) + return tags.NeedsInformerInjection() }, }) @@ -219,8 +221,8 @@ func versionClientsPackages(basePackage string, boilerplate []byte, customArgs * return generators }, FilterFunc: func(c *generator.Context, t *types.Type) bool { - tags := util.MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) - return tags.GenerateClient && tags.HasVerb("list") && tags.HasVerb("watch") + tags := MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) + return tags.NeedsInformerInjection() }, }) @@ -252,8 +254,8 @@ func versionFactoryPackages(basePackage string, boilerplate []byte, customArgs * return generators }, FilterFunc: func(c *generator.Context, t *types.Type) bool { - tags := util.MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) - return tags.GenerateClient && tags.HasVerb("list") && tags.HasVerb("watch") + tags := MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) + return tags.NeedsInformerInjection() }, }) @@ -279,8 +281,8 @@ func versionFactoryPackages(basePackage string, boilerplate []byte, customArgs * return generators }, FilterFunc: func(c *generator.Context, t *types.Type) bool { - tags := util.MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) - return tags.GenerateClient && tags.HasVerb("list") && tags.HasVerb("watch") + tags := MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) + return tags.NeedsInformerInjection() }, }) @@ -323,8 +325,8 @@ func versionInformerPackages(basePackage string, groupPkgName string, gv clientg return generators }, FilterFunc: func(c *generator.Context, t *types.Type) bool { - tags := util.MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) - return tags.GenerateClient && tags.HasVerb("list") && tags.HasVerb("watch") + tags := MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) + return tags.NeedsInformerInjection() }, }) @@ -351,8 +353,75 @@ func versionInformerPackages(basePackage string, groupPkgName string, gv clientg return generators }, FilterFunc: func(c *generator.Context, t *types.Type) bool { - tags := util.MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) - return tags.GenerateClient && tags.HasVerb("list") && tags.HasVerb("watch") + tags := MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) + return tags.NeedsInformerInjection() + }, + }) + } + return vers +} + +func versionDuckPackages(basePackage string, groupPkgName string, gv clientgentypes.GroupVersion, groupGoName string, boilerplate []byte, typesToGenerate []*types.Type, customArgs *informergenargs.CustomArgs) []generator.Package { + packagePath := filepath.Join(basePackage, "ducks", groupPkgName, strings.ToLower(gv.Version.NonEmpty())) + + vers := make([]generator.Package, 0, len(typesToGenerate)) + + for _, t := range typesToGenerate { + // Fix for golang iterator bug. + t := t + + packagePath := packagePath + "/" + strings.ToLower(t.Name.Name) + + // Impl + vers = append(vers, &generator.DefaultPackage{ + PackageName: strings.ToLower(t.Name.Name), + PackagePath: packagePath, + HeaderText: boilerplate, + GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { + // Impl + generators = append(generators, &duckGenerator{ + DefaultGen: generator.DefaultGen{ + OptionalName: strings.ToLower(t.Name.Name), + }, + outputPackage: packagePath, + groupVersion: gv, + groupGoName: groupGoName, + typeToGenerate: t, + imports: generator.NewImportTracker(), + }) + + return generators + }, + FilterFunc: func(c *generator.Context, t *types.Type) bool { + tags := MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) + return tags.NeedsDuckInjection() + }, + }) + + // Fake + vers = append(vers, &generator.DefaultPackage{ + PackageName: "fake", + PackagePath: packagePath + "/fake", + HeaderText: boilerplate, + GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) { + // Impl + generators = append(generators, &fakeDuckGenerator{ + DefaultGen: generator.DefaultGen{ + OptionalName: "fake", + }, + outputPackage: packagePath + "/fake", + imports: generator.NewImportTracker(), + typeToGenerate: t, + groupVersion: gv, + groupGoName: groupGoName, + duckInjectionPkg: packagePath, + }) + + return generators + }, + FilterFunc: func(c *generator.Context, t *types.Type) bool { + tags := MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) + return tags.NeedsDuckInjection() }, }) } diff --git a/hack/update-codegen.sh b/hack/update-codegen.sh index 775aae911..4f4f3297e 100755 --- a/hack/update-codegen.sh +++ b/hack/update-codegen.sh @@ -36,7 +36,7 @@ ${CODEGEN_PKG}/generate-groups.sh "deepcopy,client,informer,lister" \ # Knative Injection ${REPO_ROOT_DIR}/hack/generate-knative.sh "injection" \ knative.dev/pkg/client knative.dev/pkg/apis \ - "istio:v1alpha3 istio/authentication:v1alpha1" \ + "istio:v1alpha3 istio/authentication:v1alpha1 duck:v1alpha1,v1beta1,v1" \ --go-header-file ${REPO_ROOT_DIR}/hack/boilerplate/boilerplate.go.txt OUTPUT_PKG="knative.dev/pkg/client/injection/kube" \ diff --git a/injection/ducks.go b/injection/ducks.go new file mode 100644 index 000000000..3c321f68a --- /dev/null +++ b/injection/ducks.go @@ -0,0 +1,40 @@ +/* +Copyright 2019 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package injection + +import ( + "context" +) + +// DuckFactoryInjector holds the type of a callback that attaches a particular +// duck-type informer factory to a context. +type DuckFactoryInjector func(context.Context) context.Context + +func (i *impl) RegisterDuck(ii DuckFactoryInjector) { + i.m.Lock() + defer i.m.Unlock() + + i.ducks = append(i.ducks, ii) +} + +func (i *impl) GetDucks() []DuckFactoryInjector { + i.m.RLock() + defer i.m.RUnlock() + + // Copy the slice before returning. + return append(i.ducks[:0:0], i.ducks...) +} diff --git a/injection/informers.go b/injection/informers.go index 2da9ad2c5..1140174d1 100644 --- a/injection/informers.go +++ b/injection/informers.go @@ -56,6 +56,12 @@ func (i *impl) SetupInformers(ctx context.Context, cfg *rest.Config) (context.Co ctx = ifi(ctx) } + // Based on the reconcilers we have linked, build up a set of duck informer factories + // and inject them onto the context. + for _, duck := range i.GetDucks() { + ctx = duck(ctx) + } + // Based on the reconcilers we have linked, build up a set of informers // and inject them onto the context. var inf controller.Informer diff --git a/injection/interface.go b/injection/interface.go index bf6e7eef9..85955db58 100644 --- a/injection/interface.go +++ b/injection/interface.go @@ -43,6 +43,12 @@ type Interface interface { // GetInformerFactories fetches all of the registered informer factory injectors. GetInformerFactories() []InformerFactoryInjector + // RegisterDuck registers a new duck.InformerFactory for a particular type. + RegisterDuck(ii DuckFactoryInjector) + + // GetDucks accesses the set of registered ducks. + GetDucks() []DuckFactoryInjector + // RegisterInformer registers a new injector callback for associating // a new informer with a context. RegisterInformer(InformerInjector) @@ -81,4 +87,5 @@ type impl struct { clients []ClientInjector factories []InformerFactoryInjector informers []InformerInjector + ducks []DuckFactoryInjector } diff --git a/resolver/addressable_resolver.go b/resolver/addressable_resolver.go index 3358514ac..dce33f719 100644 --- a/resolver/addressable_resolver.go +++ b/resolver/addressable_resolver.go @@ -32,7 +32,7 @@ import ( "knative.dev/pkg/network" "knative.dev/pkg/tracker" - "knative.dev/pkg/injection/clients/dynamicclient" + "knative.dev/pkg/client/injection/ducks/duck/v1beta1/addressable" ) // URIResolver resolves Destinations and ObjectReferences into a URI. @@ -48,12 +48,7 @@ func NewURIResolver(ctx context.Context, callback func(types.NamespacedName)) *U ret.tracker = tracker.New(callback, controller.GetTrackerLease(ctx)) ret.informerFactory = &pkgapisduck.CachedInformerFactory{ Delegate: &pkgapisduck.EnqueueInformerFactory{ - Delegate: &pkgapisduck.TypedInformerFactory{ - Client: dynamicclient.Get(ctx), - Type: &duckv1beta1.AddressableType{}, - ResyncPeriod: controller.GetResyncPeriod(ctx), - StopChannel: ctx.Done(), - }, + Delegate: addressable.Get(ctx), EventHandler: controller.HandleAll(ret.tracker.OnChanged), }, } diff --git a/resolver/addressable_resolver_test.go b/resolver/addressable_resolver_test.go index 2012878b7..4f0a96a81 100644 --- a/resolver/addressable_resolver_test.go +++ b/resolver/addressable_resolver_test.go @@ -30,6 +30,7 @@ import ( "knative.dev/pkg/apis" duckv1alpha1 "knative.dev/pkg/apis/duck/v1alpha1" duckv1beta1 "knative.dev/pkg/apis/duck/v1beta1" + "knative.dev/pkg/client/injection/ducks/duck/v1beta1/addressable" fakedynamicclient "knative.dev/pkg/injection/clients/dynamicclient/fake" "knative.dev/pkg/resolver" ) @@ -332,6 +333,7 @@ func TestGetURI_ObjectReference(t *testing.T) { for n, tc := range tests { t.Run(n, func(t *testing.T) { ctx, _ := fakedynamicclient.With(context.Background(), scheme.Scheme, tc.objects...) + ctx = addressable.WithDuck(ctx) r := resolver.NewURIResolver(ctx, func(types.NamespacedName) {}) // Run it twice since this should be idempotent. URI Resolver should