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`.
This commit is contained in:
Matt Moore 2019-11-25 09:57:10 -08:00 committed by Knative Prow Robot
parent 2ec0f8da50
commit 43ca049cdb
46 changed files with 1550 additions and 80 deletions

View File

@ -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{}
}

View File

@ -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{}

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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()

View File

@ -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{}
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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}})
}
`

View File

@ -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}})
}
`

View File

@ -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
if len(typesWithInformers) != 0 {
orderer := namer.Orderer{Namer: namer.NewPrivateNamer(0)}
typesToGenerate = orderer.OrderTypes(typesToGenerate)
typesWithInformers = orderer.OrderTypes(typesWithInformers)
// Generate the informer and fake, for each type.
packageList = append(packageList, versionInformerPackages(versionPackagePath, groupPackageName, gv, groupGoNames[groupPackageName], boilerplate, typesToGenerate, customArgs)...)
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
// 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),
}
generatingForPackage = true
for _, member := range t.Members {
if member.Name == "ObjectMeta" {
return member.Type, isInternal(member), nil
}
}
}
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()
},
})
}

View File

@ -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" \

40
injection/ducks.go Normal file
View File

@ -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...)
}

View File

@ -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

View File

@ -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
}

View File

@ -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),
},
}

View File

@ -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