upgrade to latest dependencies (#512)

bumping knative.dev/pkg 21eb4c1...7b5ecbc:
  > 7b5ecbc Sketch out an alternate way of injecting clients/informers (# 2210)
  > 8c88fa2 Revert "Remove the unused file (# 1935)" (# 2213)
  > 50410e0 Use consistent case for "Deprecated" comments (# 2216)
  > 35bcd16 Drop redundant pointers and decoders (# 2211)
  > bf176d5 Sink two codegen passes below loop. (# 2209)
  > 2c8a7b6 Update community files (# 2208)
  > 23b0147 Update actions (# 2206)
bumping knative.dev/hack e28525d...815cd31:
  > 815cd31 Stop performing pre-releases (# 77)

Signed-off-by: Knative Automation <automation@knative.team>
This commit is contained in:
knative-automation 2021-08-18 22:45:04 -07:00 committed by GitHub
parent 09262d85c8
commit 389c38e8d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 14587 additions and 42 deletions

4
go.mod
View File

@ -18,6 +18,6 @@ require (
k8s.io/client-go v0.20.7 k8s.io/client-go v0.20.7
k8s.io/code-generator v0.20.7 k8s.io/code-generator v0.20.7
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd
knative.dev/hack v0.0.0-20210622141627-e28525d8d260 knative.dev/hack v0.0.0-20210806075220-815cd312d65c
knative.dev/pkg v0.0.0-20210803160015-21eb4c167cc5 knative.dev/pkg v0.0.0-20210818135208-7b5ecbc0e477
) )

7
go.sum
View File

@ -1060,10 +1060,11 @@ k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd h1:sOHNzJIkytDF6qadMNKhhD
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
k8s.io/utils v0.0.0-20201110183641-67b214c5f920 h1:CbnUZsM497iRC5QMVkHwyl8s2tB3g7yaSHkYPkpgelw= k8s.io/utils v0.0.0-20201110183641-67b214c5f920 h1:CbnUZsM497iRC5QMVkHwyl8s2tB3g7yaSHkYPkpgelw=
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
knative.dev/hack v0.0.0-20210622141627-e28525d8d260 h1:f2eMtOubAOc/Q7JlvFPDKXiPlJVK+VpX2Cot8hRzCgQ=
knative.dev/hack v0.0.0-20210622141627-e28525d8d260/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI= knative.dev/hack v0.0.0-20210622141627-e28525d8d260/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
knative.dev/pkg v0.0.0-20210803160015-21eb4c167cc5 h1:jpOTmAXg1oLS8u5HPBrFP1XsOSFCQIvlTRxP8TDGg2E= knative.dev/hack v0.0.0-20210806075220-815cd312d65c h1:nOXoDWAAItwr4o0dp3nHr6skgpVD4IvME/UX84YNl5k=
knative.dev/pkg v0.0.0-20210803160015-21eb4c167cc5/go.mod h1:RPk5txNA3apR9X40D4MpUOP9/VqOG8CrtABWfOwGVS4= knative.dev/hack v0.0.0-20210806075220-815cd312d65c/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI=
knative.dev/pkg v0.0.0-20210818135208-7b5ecbc0e477 h1:oHKwxMz8dV5pKXTAUOMbmZA0kgLkXKR11ISysegU/L8=
knative.dev/pkg v0.0.0-20210818135208-7b5ecbc0e477/go.mod h1:RPk5txNA3apR9X40D4MpUOP9/VqOG8CrtABWfOwGVS4=
pgregory.net/rapid v0.3.3/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU= pgregory.net/rapid v0.3.3/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=

View File

@ -20,27 +20,46 @@ package client
import ( import (
context "context" context "context"
json "encoding/json"
errors "errors"
fmt "fmt"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
unstructured "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
runtime "k8s.io/apimachinery/pkg/runtime"
schema "k8s.io/apimachinery/pkg/runtime/schema"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
discovery "k8s.io/client-go/discovery"
dynamic "k8s.io/client-go/dynamic"
rest "k8s.io/client-go/rest" rest "k8s.io/client-go/rest"
v1alpha1 "knative.dev/caching/pkg/apis/caching/v1alpha1"
versioned "knative.dev/caching/pkg/client/clientset/versioned" versioned "knative.dev/caching/pkg/client/clientset/versioned"
typedcachingv1alpha1 "knative.dev/caching/pkg/client/clientset/versioned/typed/caching/v1alpha1"
injection "knative.dev/pkg/injection" injection "knative.dev/pkg/injection"
dynamicclient "knative.dev/pkg/injection/clients/dynamicclient"
logging "knative.dev/pkg/logging" logging "knative.dev/pkg/logging"
) )
func init() { func init() {
injection.Default.RegisterClient(withClient) injection.Default.RegisterClient(withClientFromConfig)
injection.Default.RegisterClientFetcher(func(ctx context.Context) interface{} { injection.Default.RegisterClientFetcher(func(ctx context.Context) interface{} {
return Get(ctx) return Get(ctx)
}) })
injection.Dynamic.RegisterDynamicClient(withClientFromDynamic)
} }
// Key is used as the key for associating information with a context.Context. // Key is used as the key for associating information with a context.Context.
type Key struct{} type Key struct{}
func withClient(ctx context.Context, cfg *rest.Config) context.Context { func withClientFromConfig(ctx context.Context, cfg *rest.Config) context.Context {
return context.WithValue(ctx, Key{}, versioned.NewForConfigOrDie(cfg)) return context.WithValue(ctx, Key{}, versioned.NewForConfigOrDie(cfg))
} }
func withClientFromDynamic(ctx context.Context) context.Context {
return context.WithValue(ctx, Key{}, &wrapClient{dyn: dynamicclient.Get(ctx)})
}
// Get extracts the versioned.Interface client from the context. // Get extracts the versioned.Interface client from the context.
func Get(ctx context.Context) versioned.Interface { func Get(ctx context.Context) versioned.Interface {
untyped := ctx.Value(Key{}) untyped := ctx.Value(Key{})
@ -55,3 +74,170 @@ func Get(ctx context.Context) versioned.Interface {
} }
return untyped.(versioned.Interface) return untyped.(versioned.Interface)
} }
type wrapClient struct {
dyn dynamic.Interface
}
var _ versioned.Interface = (*wrapClient)(nil)
func (w *wrapClient) Discovery() discovery.DiscoveryInterface {
panic("Discovery called on dynamic client!")
}
func convert(from interface{}, to runtime.Object) error {
bs, err := json.Marshal(from)
if err != nil {
return fmt.Errorf("Marshal() = %w", err)
}
if err := json.Unmarshal(bs, to); err != nil {
return fmt.Errorf("Unmarshal() = %w", err)
}
return nil
}
// CachingV1alpha1 retrieves the CachingV1alpha1Client
func (w *wrapClient) CachingV1alpha1() typedcachingv1alpha1.CachingV1alpha1Interface {
return &wrapCachingV1alpha1{
dyn: w.dyn,
}
}
type wrapCachingV1alpha1 struct {
dyn dynamic.Interface
}
func (w *wrapCachingV1alpha1) RESTClient() rest.Interface {
panic("RESTClient called on dynamic client!")
}
func (w *wrapCachingV1alpha1) Images(namespace string) typedcachingv1alpha1.ImageInterface {
return &wrapCachingV1alpha1ImageImpl{
dyn: w.dyn.Resource(schema.GroupVersionResource{
Group: "caching.internal.knative.dev",
Version: "v1alpha1",
Resource: "images",
}),
namespace: namespace,
}
}
type wrapCachingV1alpha1ImageImpl struct {
dyn dynamic.NamespaceableResourceInterface
namespace string
}
var _ typedcachingv1alpha1.ImageInterface = (*wrapCachingV1alpha1ImageImpl)(nil)
func (w *wrapCachingV1alpha1ImageImpl) Create(ctx context.Context, in *v1alpha1.Image, opts v1.CreateOptions) (*v1alpha1.Image, error) {
in.SetGroupVersionKind(schema.GroupVersionKind{
Group: "caching.internal.knative.dev",
Version: "v1alpha1",
Kind: "Image",
})
uo := &unstructured.Unstructured{}
if err := convert(in, uo); err != nil {
return nil, err
}
uo, err := w.dyn.Namespace(w.namespace).Create(ctx, uo, opts)
if err != nil {
return nil, err
}
out := &v1alpha1.Image{}
if err := convert(uo, out); err != nil {
return nil, err
}
return out, nil
}
func (w *wrapCachingV1alpha1ImageImpl) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
return w.dyn.Namespace(w.namespace).Delete(ctx, name, opts)
}
func (w *wrapCachingV1alpha1ImageImpl) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
return w.dyn.Namespace(w.namespace).DeleteCollection(ctx, opts, listOpts)
}
func (w *wrapCachingV1alpha1ImageImpl) Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.Image, error) {
uo, err := w.dyn.Namespace(w.namespace).Get(ctx, name, opts)
if err != nil {
return nil, err
}
out := &v1alpha1.Image{}
if err := convert(uo, out); err != nil {
return nil, err
}
return out, nil
}
func (w *wrapCachingV1alpha1ImageImpl) List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.ImageList, error) {
uo, err := w.dyn.Namespace(w.namespace).List(ctx, opts)
if err != nil {
return nil, err
}
out := &v1alpha1.ImageList{}
if err := convert(uo, out); err != nil {
return nil, err
}
return out, nil
}
func (w *wrapCachingV1alpha1ImageImpl) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.Image, err error) {
uo, err := w.dyn.Namespace(w.namespace).Patch(ctx, name, pt, data, opts)
if err != nil {
return nil, err
}
out := &v1alpha1.Image{}
if err := convert(uo, out); err != nil {
return nil, err
}
return out, nil
}
func (w *wrapCachingV1alpha1ImageImpl) Update(ctx context.Context, in *v1alpha1.Image, opts v1.UpdateOptions) (*v1alpha1.Image, error) {
in.SetGroupVersionKind(schema.GroupVersionKind{
Group: "caching.internal.knative.dev",
Version: "v1alpha1",
Kind: "Image",
})
uo := &unstructured.Unstructured{}
if err := convert(in, uo); err != nil {
return nil, err
}
uo, err := w.dyn.Namespace(w.namespace).Update(ctx, uo, opts)
if err != nil {
return nil, err
}
out := &v1alpha1.Image{}
if err := convert(uo, out); err != nil {
return nil, err
}
return out, nil
}
func (w *wrapCachingV1alpha1ImageImpl) UpdateStatus(ctx context.Context, in *v1alpha1.Image, opts v1.UpdateOptions) (*v1alpha1.Image, error) {
in.SetGroupVersionKind(schema.GroupVersionKind{
Group: "caching.internal.knative.dev",
Version: "v1alpha1",
Kind: "Image",
})
uo := &unstructured.Unstructured{}
if err := convert(in, uo); err != nil {
return nil, err
}
uo, err := w.dyn.Namespace(w.namespace).UpdateStatus(ctx, uo, opts)
if err != nil {
return nil, err
}
out := &v1alpha1.Image{}
if err := convert(uo, out); err != nil {
return nil, err
}
return out, nil
}
func (w *wrapCachingV1alpha1ImageImpl) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
return nil, errors.New("NYI: Watch")
}

View File

@ -21,8 +21,15 @@ package filtered
import ( import (
context "context" context "context"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
cache "k8s.io/client-go/tools/cache"
apiscachingv1alpha1 "knative.dev/caching/pkg/apis/caching/v1alpha1"
versioned "knative.dev/caching/pkg/client/clientset/versioned"
v1alpha1 "knative.dev/caching/pkg/client/informers/externalversions/caching/v1alpha1" v1alpha1 "knative.dev/caching/pkg/client/informers/externalversions/caching/v1alpha1"
client "knative.dev/caching/pkg/client/injection/client"
filtered "knative.dev/caching/pkg/client/injection/informers/factory/filtered" filtered "knative.dev/caching/pkg/client/injection/informers/factory/filtered"
cachingv1alpha1 "knative.dev/caching/pkg/client/listers/caching/v1alpha1"
controller "knative.dev/pkg/controller" controller "knative.dev/pkg/controller"
injection "knative.dev/pkg/injection" injection "knative.dev/pkg/injection"
logging "knative.dev/pkg/logging" logging "knative.dev/pkg/logging"
@ -30,6 +37,7 @@ import (
func init() { func init() {
injection.Default.RegisterFilteredInformers(withInformer) injection.Default.RegisterFilteredInformers(withInformer)
injection.Dynamic.RegisterDynamicInformer(withDynamicInformer)
} }
// Key is used for associating the Informer inside the context.Context. // Key is used for associating the Informer inside the context.Context.
@ -54,6 +62,20 @@ func withInformer(ctx context.Context) (context.Context, []controller.Informer)
return ctx, infs return ctx, infs
} }
func withDynamicInformer(ctx context.Context) context.Context {
untyped := ctx.Value(filtered.LabelKey{})
if untyped == nil {
logging.FromContext(ctx).Panic(
"Unable to fetch labelkey from context.")
}
labelSelectors := untyped.([]string)
for _, selector := range labelSelectors {
inf := &wrapper{client: client.Get(ctx), selector: selector}
ctx = context.WithValue(ctx, Key{Selector: selector}, inf)
}
return ctx
}
// Get extracts the typed informer from the context. // Get extracts the typed informer from the context.
func Get(ctx context.Context, selector string) v1alpha1.ImageInformer { func Get(ctx context.Context, selector string) v1alpha1.ImageInformer {
untyped := ctx.Value(Key{Selector: selector}) untyped := ctx.Value(Key{Selector: selector})
@ -63,3 +85,52 @@ func Get(ctx context.Context, selector string) v1alpha1.ImageInformer {
} }
return untyped.(v1alpha1.ImageInformer) return untyped.(v1alpha1.ImageInformer)
} }
type wrapper struct {
client versioned.Interface
namespace string
selector string
}
var _ v1alpha1.ImageInformer = (*wrapper)(nil)
var _ cachingv1alpha1.ImageLister = (*wrapper)(nil)
func (w *wrapper) Informer() cache.SharedIndexInformer {
return cache.NewSharedIndexInformer(nil, &apiscachingv1alpha1.Image{}, 0, nil)
}
func (w *wrapper) Lister() cachingv1alpha1.ImageLister {
return w
}
func (w *wrapper) Images(namespace string) cachingv1alpha1.ImageNamespaceLister {
return &wrapper{client: w.client, namespace: namespace, selector: w.selector}
}
func (w *wrapper) List(selector labels.Selector) (ret []*apiscachingv1alpha1.Image, err error) {
reqs, err := labels.ParseToRequirements(w.selector)
if err != nil {
return nil, err
}
selector = selector.Add(reqs...)
lo, err := w.client.CachingV1alpha1().Images(w.namespace).List(context.TODO(), v1.ListOptions{
LabelSelector: selector.String(),
// TODO(mattmoor): Incorporate resourceVersion bounds based on staleness criteria.
})
if err != nil {
return nil, err
}
for idx := range lo.Items {
ret = append(ret, &lo.Items[idx])
}
return ret, nil
}
func (w *wrapper) Get(name string) (*apiscachingv1alpha1.Image, error) {
// TODO(mattmoor): Check that the fetched object matches the selector.
return w.client.CachingV1alpha1().Images(w.namespace).Get(context.TODO(), name, v1.GetOptions{
// TODO(mattmoor): Incorporate resourceVersion bounds based on staleness criteria.
})
}

View File

@ -21,8 +21,15 @@ package image
import ( import (
context "context" context "context"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
cache "k8s.io/client-go/tools/cache"
apiscachingv1alpha1 "knative.dev/caching/pkg/apis/caching/v1alpha1"
versioned "knative.dev/caching/pkg/client/clientset/versioned"
v1alpha1 "knative.dev/caching/pkg/client/informers/externalversions/caching/v1alpha1" v1alpha1 "knative.dev/caching/pkg/client/informers/externalversions/caching/v1alpha1"
client "knative.dev/caching/pkg/client/injection/client"
factory "knative.dev/caching/pkg/client/injection/informers/factory" factory "knative.dev/caching/pkg/client/injection/informers/factory"
cachingv1alpha1 "knative.dev/caching/pkg/client/listers/caching/v1alpha1"
controller "knative.dev/pkg/controller" controller "knative.dev/pkg/controller"
injection "knative.dev/pkg/injection" injection "knative.dev/pkg/injection"
logging "knative.dev/pkg/logging" logging "knative.dev/pkg/logging"
@ -30,6 +37,7 @@ import (
func init() { func init() {
injection.Default.RegisterInformer(withInformer) injection.Default.RegisterInformer(withInformer)
injection.Dynamic.RegisterDynamicInformer(withDynamicInformer)
} }
// Key is used for associating the Informer inside the context.Context. // Key is used for associating the Informer inside the context.Context.
@ -41,6 +49,11 @@ func withInformer(ctx context.Context) (context.Context, controller.Informer) {
return context.WithValue(ctx, Key{}, inf), inf.Informer() return context.WithValue(ctx, Key{}, inf), inf.Informer()
} }
func withDynamicInformer(ctx context.Context) context.Context {
inf := &wrapper{client: client.Get(ctx)}
return context.WithValue(ctx, Key{}, inf)
}
// Get extracts the typed informer from the context. // Get extracts the typed informer from the context.
func Get(ctx context.Context) v1alpha1.ImageInformer { func Get(ctx context.Context) v1alpha1.ImageInformer {
untyped := ctx.Value(Key{}) untyped := ctx.Value(Key{})
@ -50,3 +63,44 @@ func Get(ctx context.Context) v1alpha1.ImageInformer {
} }
return untyped.(v1alpha1.ImageInformer) return untyped.(v1alpha1.ImageInformer)
} }
type wrapper struct {
client versioned.Interface
namespace string
}
var _ v1alpha1.ImageInformer = (*wrapper)(nil)
var _ cachingv1alpha1.ImageLister = (*wrapper)(nil)
func (w *wrapper) Informer() cache.SharedIndexInformer {
return cache.NewSharedIndexInformer(nil, &apiscachingv1alpha1.Image{}, 0, nil)
}
func (w *wrapper) Lister() cachingv1alpha1.ImageLister {
return w
}
func (w *wrapper) Images(namespace string) cachingv1alpha1.ImageNamespaceLister {
return &wrapper{client: w.client, namespace: namespace}
}
func (w *wrapper) List(selector labels.Selector) (ret []*apiscachingv1alpha1.Image, err error) {
lo, err := w.client.CachingV1alpha1().Images(w.namespace).List(context.TODO(), v1.ListOptions{
LabelSelector: selector.String(),
// TODO(mattmoor): Incorporate resourceVersion bounds based on staleness criteria.
})
if err != nil {
return nil, err
}
for idx := range lo.Items {
ret = append(ret, &lo.Items[idx])
}
return ret, nil
}
func (w *wrapper) Get(name string) (*apiscachingv1alpha1.Image, error) {
return w.client.CachingV1alpha1().Images(w.namespace).Get(context.TODO(), name, v1.GetOptions{
// TODO(mattmoor): Incorporate resourceVersion bounds based on staleness criteria.
})
}

View File

@ -610,7 +610,6 @@ function publish_to_github() {
[[ -n "${RELEASE_BRANCH}" ]] && commitish="--commitish=${RELEASE_BRANCH}" [[ -n "${RELEASE_BRANCH}" ]] && commitish="--commitish=${RELEASE_BRANCH}"
for i in {2..0}; do for i in {2..0}; do
hub_tool release create \ hub_tool release create \
--prerelease \
${attachments[@]} \ ${attachments[@]} \
--file="${description}" \ --file="${description}" \
"${commitish}" \ "${commitish}" \

View File

@ -53,7 +53,8 @@ type Listable interface {
} }
// Annotatable indicates that a particular type applies various annotations. // Annotatable indicates that a particular type applies various annotations.
// DEPRECATED: Use WithUserInfo / GetUserInfo from within SetDefaults instead. //
// Deprecated: Use WithUserInfo / GetUserInfo from within SetDefaults instead.
// The webhook functionality for this has been turned down, which is why this // The webhook functionality for this has been turned down, which is why this
// interface is empty. // interface is empty.
type Annotatable interface{} type Annotatable interface{}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,103 @@
/*
Copyright 2021 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 client
import (
context "context"
certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
corev1 "k8s.io/api/core/v1"
eventsv1beta1 "k8s.io/api/events/v1beta1"
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
policyv1beta1 "k8s.io/api/policy/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/runtime"
restclient "k8s.io/client-go/rest"
)
func (*wrapCoreV1NamespaceImpl) Finalize(context.Context, *corev1.Namespace, metav1.UpdateOptions) (*corev1.Namespace, error) {
panic("NYI")
}
func (*wrapCoreV1ServiceImpl) ProxyGet(string, string, string, string, map[string]string) restclient.ResponseWrapper {
panic("NYI")
}
func (*wrapEventsV1beta1EventImpl) CreateWithEventNamespace(*eventsv1beta1.Event) (*eventsv1beta1.Event, error) {
panic("NYI")
}
func (*wrapEventsV1beta1EventImpl) UpdateWithEventNamespace(*eventsv1beta1.Event) (*eventsv1beta1.Event, error) {
panic("NYI")
}
func (*wrapEventsV1beta1EventImpl) PatchWithEventNamespace(*eventsv1beta1.Event, []byte) (*eventsv1beta1.Event, error) {
panic("NYI")
}
func (*wrapCoreV1EventImpl) CreateWithEventNamespace(*corev1.Event) (*corev1.Event, error) {
panic("NYI")
}
func (*wrapCoreV1EventImpl) UpdateWithEventNamespace(*corev1.Event) (*corev1.Event, error) {
panic("NYI")
}
func (*wrapCoreV1EventImpl) PatchWithEventNamespace(*corev1.Event, []byte) (*corev1.Event, error) {
panic("NYI")
}
func (*wrapCoreV1EventImpl) Search(*runtime.Scheme, runtime.Object) (*corev1.EventList, error) {
panic("NYI")
}
func (*wrapCoreV1EventImpl) GetFieldSelector(*string, *string, *string, *string) fields.Selector {
panic("NYI")
}
func (*wrapCoreV1NodeImpl) PatchStatus(context.Context, string, []byte) (*corev1.Node, error) {
panic("NYI")
}
func (*wrapCoreV1PodImpl) Bind(context.Context, *corev1.Binding, metav1.CreateOptions) error {
panic("NYI")
}
func (*wrapCoreV1PodImpl) Evict(context.Context, *policyv1beta1.Eviction) error {
panic("NYI")
}
func (*wrapCoreV1PodImpl) GetLogs(string, *corev1.PodLogOptions) *restclient.Request {
panic("NYI")
}
func (*wrapCoreV1PodImpl) ProxyGet(string, string, string, string, map[string]string) restclient.ResponseWrapper {
panic("NYI")
}
func (*wrapExtensionsV1beta1DeploymentImpl) Rollback(context.Context, *extensionsv1beta1.DeploymentRollback, metav1.CreateOptions) error {
panic("NYI")
}
func (*wrapPolicyV1beta1EvictionImpl) Evict(context.Context, *policyv1beta1.Eviction) error {
panic("NYI")
}
func (*wrapCertificatesV1beta1CertificateSigningRequestImpl) UpdateApproval(context.Context, *certificatesv1beta1.CertificateSigningRequest, metav1.UpdateOptions) (*certificatesv1beta1.CertificateSigningRequest, error) {
panic("NYI")
}

View File

@ -17,8 +17,15 @@ limitations under the License.
package generators package generators
import ( import (
"fmt"
"io" "io"
"path/filepath"
"sort"
"strings"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/code-generator/cmd/client-gen/generators/util"
clientgentypes "k8s.io/code-generator/cmd/client-gen/types"
"k8s.io/gengo/generator" "k8s.io/gengo/generator"
"k8s.io/gengo/namer" "k8s.io/gengo/namer"
"k8s.io/gengo/types" "k8s.io/gengo/types"
@ -29,6 +36,11 @@ import (
// type. // type.
type clientGenerator struct { type clientGenerator struct {
generator.DefaultGen generator.DefaultGen
groupVersions map[string]clientgentypes.GroupVersions
groupGoNames map[string]string
groupVersionTypes map[string]map[clientgentypes.Version][]*types.Type
outputPackage string outputPackage string
imports namer.ImportTracker imports namer.ImportTracker
clientSetPackage string clientSetPackage string
@ -46,14 +58,37 @@ func (g *clientGenerator) Filter(c *generator.Context, t *types.Type) bool {
return false return false
} }
var 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",
}),
}
func (g *clientGenerator) Namers(c *generator.Context) namer.NameSystems { func (g *clientGenerator) Namers(c *generator.Context) namer.NameSystems {
return namer.NameSystems{ return namer.NameSystems{
"raw": namer.NewRawNamer(g.outputPackage, g.imports), "raw": namer.NewRawNamer(g.outputPackage, g.imports),
"publicPlural": publicPluralNamer,
} }
} }
func (g *clientGenerator) Imports(c *generator.Context) (imports []string) { func (g *clientGenerator) Imports(c *generator.Context) (imports []string) {
imports = append(imports, g.imports.ImportLines()...) imports = append(imports, g.imports.ImportLines()...)
for gpn, group := range g.groupVersions {
for _, version := range group.Versions {
typedClientPath := filepath.Join(g.clientSetPackage, "typed", strings.ToLower(group.PackageName), strings.ToLower(version.NonEmpty()))
imports = append(imports, fmt.Sprintf("%s \"%s\"", strings.ToLower("typed"+g.groupGoNames[gpn]+version.NonEmpty()), typedClientPath))
}
}
imports = sets.NewString(imports...).List()
return return
} }
@ -63,9 +98,10 @@ func (g *clientGenerator) GenerateType(c *generator.Context, t *types.Type, w io
klog.V(5).Info("processing type ", t) klog.V(5).Info("processing type ", t)
m := map[string]interface{}{ m := map[string]interface{}{
"clientSetNewForConfigOrDie": c.Universe.Function(types.Name{Package: g.clientSetPackage, Name: "NewForConfigOrDie"}), "clientSetNewForConfigOrDie": c.Universe.Function(types.Name{Package: g.clientSetPackage, Name: "NewForConfigOrDie"}),
"clientSetInterface": c.Universe.Type(types.Name{Package: g.clientSetPackage, Name: "Interface"}), "clientSetInterface": c.Universe.Type(types.Name{Package: g.clientSetPackage, Name: "Interface"}),
"injectionRegisterClient": c.Universe.Function(types.Name{Package: "knative.dev/pkg/injection", Name: "Default.RegisterClient"}), "injectionRegisterClient": c.Universe.Function(types.Name{Package: "knative.dev/pkg/injection", Name: "Default.RegisterClient"}),
"injectionRegisterDynamicClient": c.Universe.Function(types.Name{Package: "knative.dev/pkg/injection", Name: "Dynamic.RegisterDynamicClient"}),
"injectionRegisterClientFetcher": c.Universe.Function(types.Name{ "injectionRegisterClientFetcher": c.Universe.Function(types.Name{
Package: "knative.dev/pkg/injection", Package: "knative.dev/pkg/injection",
Name: "Default.RegisterClientFetcher", Name: "Default.RegisterClientFetcher",
@ -79,28 +115,231 @@ func (g *clientGenerator) GenerateType(c *generator.Context, t *types.Type, w io
Package: "context", Package: "context",
Name: "Context", Name: "Context",
}), }),
"dynamicInterface": c.Universe.Type(types.Name{
Package: "k8s.io/client-go/dynamic",
Name: "Interface",
}),
"dynamicclientGet": c.Universe.Function(types.Name{
Package: "knative.dev/pkg/injection/clients/dynamicclient",
Name: "Get",
}),
"discoveryInterface": c.Universe.Type(types.Name{
Package: "k8s.io/client-go/discovery",
Name: "DiscoveryInterface",
}),
"runtimeObject": c.Universe.Type(types.Name{
Package: "k8s.io/apimachinery/pkg/runtime",
Name: "Object",
}),
"jsonMarshal": c.Universe.Function(types.Name{
Package: "encoding/json",
Name: "Marshal",
}),
"jsonUnmarshal": c.Universe.Function(types.Name{
Package: "encoding/json",
Name: "Unmarshal",
}),
"fmtErrorf": c.Universe.Function(types.Name{
Package: "fmt",
Name: "Errorf",
}),
} }
sw.Do(injectionClient, m) sw.Do(injectionClient, m)
gpns := make(sets.String, len(g.groupGoNames))
for gpn := range g.groupGoNames {
gpns.Insert(gpn)
}
for _, gpn := range gpns.List() {
ggn := g.groupGoNames[gpn]
gv := g.groupVersions[gpn]
verTypes := g.groupVersionTypes[gpn]
for _, version := range gv.Versions {
vts := verTypes[version.Version]
if len(vts) == 0 {
// Skip things with zero types.
continue
}
sw.Do(clientsetInterfaceImplTemplate, map[string]interface{}{
"dynamicInterface": c.Universe.Type(types.Name{
Package: "k8s.io/client-go/dynamic",
Name: "Interface",
}),
"restInterface": c.Universe.Type(types.Name{
Package: "k8s.io/client-go/rest",
Name: "Interface",
}),
"GroupGoName": ggn,
"Version": namer.IC(version.String()),
"PackageAlias": strings.ToLower("typed" + g.groupGoNames[gpn] + version.NonEmpty()),
})
sort.Slice(vts, func(i, j int) bool {
lhs, rhs := vts[i], vts[j]
return lhs.String() < rhs.String()
})
for _, t := range vts {
tags, err := util.ParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...))
if err != nil {
return err
}
// Don't use the literal group "core", these should be left blank.
group := gv.Group
if group == "core" {
group = ""
}
sw.Do(typeImplTemplate, map[string]interface{}{
"dynamicNamespaceableResourceInterface": c.Universe.Type(types.Name{
Package: "k8s.io/client-go/dynamic",
Name: "NamespaceableResourceInterface",
}),
"schemaGroupVersionResource": c.Universe.Type(types.Name{
Package: "k8s.io/apimachinery/pkg/runtime/schema",
Name: "GroupVersionResource",
}),
"contextContext": c.Universe.Type(types.Name{
Package: "context",
Name: "Context",
}),
"GroupGoName": ggn,
"Version": namer.IC(version.String()),
"PackageAlias": strings.ToLower("typed" + g.groupGoNames[gpn] + version.NonEmpty()),
"Type": t,
"Namespaced": !tags.NonNamespaced,
"Group": group,
"VersionLower": version,
"Resource": strings.ToLower(publicPluralNamer.Name(t)),
})
opts := map[string]interface{}{
"contextContext": c.Universe.Type(types.Name{
Package: "context",
Name: "Context",
}),
"unstructuredUnstructured": c.Universe.Type(types.Name{
Package: "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured",
Name: "Unstructured",
}),
"metav1CreateOptions": c.Universe.Type(types.Name{
Package: "k8s.io/apimachinery/pkg/apis/meta/v1",
Name: "CreateOptions",
}),
"metav1UpdateOptions": c.Universe.Type(types.Name{
Package: "k8s.io/apimachinery/pkg/apis/meta/v1",
Name: "UpdateOptions",
}),
"metav1GetOptions": c.Universe.Type(types.Name{
Package: "k8s.io/apimachinery/pkg/apis/meta/v1",
Name: "GetOptions",
}),
"metav1ListOptions": c.Universe.Type(types.Name{
Package: "k8s.io/apimachinery/pkg/apis/meta/v1",
Name: "ListOptions",
}),
"metav1DeleteOptions": c.Universe.Type(types.Name{
Package: "k8s.io/apimachinery/pkg/apis/meta/v1",
Name: "DeleteOptions",
}),
"metav1PatchOptions": c.Universe.Type(types.Name{
Package: "k8s.io/apimachinery/pkg/apis/meta/v1",
Name: "PatchOptions",
}),
"typesPatchType": c.Universe.Type(types.Name{
Package: "k8s.io/apimachinery/pkg/types",
Name: "PatchType",
}),
"watchInterface": c.Universe.Type(types.Name{
Package: "k8s.io/apimachinery/pkg/watch",
Name: "Interface",
}),
"errorsNew": c.Universe.Function(types.Name{
Package: "errors",
Name: "New",
}),
"GroupGoName": ggn,
"Version": namer.IC(version.String()),
"Type": t,
"InputType": t,
"ResultType": t,
"Namespaced": !tags.NonNamespaced,
"Subresource": "",
"schemaGroupVersionKind": c.Universe.Type(types.Name{
Package: "k8s.io/apimachinery/pkg/runtime/schema",
Name: "GroupVersionKind",
}),
"Group": group,
"VersionLower": version,
"Kind": t.Name.Name,
}
for _, v := range verbs.List() {
tmpl := verbMap[v]
if tags.NoVerbs || !tags.HasVerb(v) {
continue
}
sw.Do(tmpl, opts)
}
for _, e := range tags.Extensions {
for _, v := range extensionVerbs.List() {
tmpl := extensionVerbMap[v]
if !e.HasVerb(v) {
continue
}
inputType := *t
resultType := *t
if len(e.InputTypeOverride) > 0 {
if name, pkg := e.Input(); len(pkg) > 0 {
// _, inputGVString = util.ParsePathGroupVersion(pkg)
newType := c.Universe.Type(types.Name{Package: pkg, Name: name})
inputType = *newType
} else {
inputType.Name.Name = e.InputTypeOverride
}
}
if len(e.ResultTypeOverride) > 0 {
if name, pkg := e.Result(); len(pkg) > 0 {
newType := c.Universe.Type(types.Name{Package: pkg, Name: name})
resultType = *newType
} else {
resultType.Name.Name = e.ResultTypeOverride
}
}
opts["InputType"] = &inputType
opts["ResultType"] = &resultType
if e.IsSubresource() {
opts["Subresource"] = e.SubResourcePath
}
sw.Do(strings.Replace(tmpl, " "+strings.Title(e.VerbType), " "+e.VerbName, -1), opts)
}
}
}
}
}
return sw.Error() return sw.Error()
} }
var injectionClient = ` var injectionClient = `
func init() { func init() {
{{.injectionRegisterClient|raw}}(withClient) {{.injectionRegisterClient|raw}}(withClientFromConfig)
{{.injectionRegisterClientFetcher|raw}}(func(ctx context.Context) interface{} { {{.injectionRegisterClientFetcher|raw}}(func(ctx context.Context) interface{} {
return Get(ctx) return Get(ctx)
}) })
{{.injectionRegisterDynamicClient|raw}}(withClientFromDynamic)
} }
// Key is used as the key for associating information with a context.Context. // Key is used as the key for associating information with a context.Context.
type Key struct{} type Key struct{}
func withClient(ctx {{.contextContext|raw}}, cfg *{{.restConfig|raw}}) context.Context { func withClientFromConfig(ctx {{.contextContext|raw}}, cfg *{{.restConfig|raw}}) context.Context {
return context.WithValue(ctx, Key{}, {{.clientSetNewForConfigOrDie|raw}}(cfg)) return context.WithValue(ctx, Key{}, {{.clientSetNewForConfigOrDie|raw}}(cfg))
} }
func withClientFromDynamic(ctx {{.contextContext|raw}}) context.Context {
return context.WithValue(ctx, Key{}, &wrapClient{dyn: {{.dynamicclientGet|raw}}(ctx)})
}
// Get extracts the {{.clientSetInterface|raw}} client from the context. // Get extracts the {{.clientSetInterface|raw}} client from the context.
func Get(ctx {{.contextContext|raw}}) {{.clientSetInterface|raw}} { func Get(ctx {{.contextContext|raw}}) {{.clientSetInterface|raw}} {
untyped := ctx.Value(Key{}) untyped := ctx.Value(Key{})
@ -115,4 +354,258 @@ func Get(ctx {{.contextContext|raw}}) {{.clientSetInterface|raw}} {
} }
return untyped.({{.clientSetInterface|raw}}) return untyped.({{.clientSetInterface|raw}})
} }
type wrapClient struct {
dyn {{.dynamicInterface|raw}}
}
var _ {{.clientSetInterface|raw}} = (*wrapClient)(nil)
func (w *wrapClient) Discovery() {{.discoveryInterface|raw}} {
panic("Discovery called on dynamic client!")
}
func convert(from interface{}, to {{ .runtimeObject|raw }}) error {
bs, err := {{ .jsonMarshal|raw }}(from)
if err != nil {
return {{ .fmtErrorf|raw }}("Marshal() = %w", err)
}
if err := {{ .jsonUnmarshal|raw }}(bs, to); err != nil {
return {{ .fmtErrorf|raw }}("Unmarshal() = %w", err)
}
return nil
}
` `
var clientsetInterfaceImplTemplate = `
// {{.GroupGoName}}{{.Version}} retrieves the {{.GroupGoName}}{{.Version}}Client
func (w *wrapClient) {{.GroupGoName}}{{.Version}}() {{.PackageAlias}}.{{.GroupGoName}}{{.Version}}Interface {
return &wrap{{.GroupGoName}}{{.Version}}{
dyn: w.dyn,
}
}
type wrap{{.GroupGoName}}{{.Version}} struct {
dyn {{.dynamicInterface|raw}}
}
func (w *wrap{{.GroupGoName}}{{.Version}}) RESTClient() {{.restInterface|raw}} {
panic("RESTClient called on dynamic client!")
}
`
var typeImplTemplate = `
func (w *wrap{{ .GroupGoName }}{{ .Version }}) {{ .Type|publicPlural }}({{if .Namespaced}}namespace string{{end}}) {{ .PackageAlias }}.{{ .Type.Name.Name }}Interface {
return &wrap{{.GroupGoName}}{{.Version}}{{ .Type.Name.Name }}Impl{
dyn: w.dyn.Resource({{ .schemaGroupVersionResource|raw }}{
Group: "{{ .Group }}",
Version: "{{ .VersionLower }}",
Resource: "{{ .Resource }}",
}),
{{if .Namespaced}}
namespace: namespace,
{{end}}
}
}
type wrap{{.GroupGoName}}{{.Version}}{{ .Type.Name.Name }}Impl struct {
dyn {{.dynamicNamespaceableResourceInterface|raw}}
{{if .Namespaced}}
namespace string
{{end}}}
var _ {{ .PackageAlias }}.{{ .Type.Name.Name }}Interface = (*wrap{{.GroupGoName}}{{.Version}}{{ .Type.Name.Name }}Impl)(nil)
`
var verbs = sets.NewString( /* Populated from verbMap during init */ )
var verbMap = map[string]string{
"create": `
func (w *wrap{{.GroupGoName}}{{.Version}}{{ .Type.Name.Name }}Impl) Create(ctx {{ .contextContext|raw }}, {{ if .Subresource }}_ string, {{ end }}in *{{ .InputType|raw }}, opts {{ .metav1CreateOptions|raw }}) (*{{ .ResultType|raw }}, error) {
in.SetGroupVersionKind({{ .schemaGroupVersionKind|raw }}{
Group: "{{ .Group }}",
Version: "{{ .VersionLower }}",
Kind: "{{ .Kind }}",
})
uo := &{{ .unstructuredUnstructured|raw }}{}
if err := convert(in, uo); err != nil {
return nil, err
}
uo, err := w.dyn{{if .Namespaced}}{{if .Namespaced}}.Namespace(w.namespace){{end}}{{end}}.Create(ctx, uo, opts)
if err != nil {
return nil, err
}
out := &{{ .ResultType|raw }}{}
if err := convert(uo, out); err != nil {
return nil, err
}
return out, nil
}
`,
"update": `
func (w *wrap{{.GroupGoName}}{{.Version}}{{ .Type.Name.Name }}Impl) Update(ctx {{ .contextContext|raw }}, {{ if .Subresource }}_ string, {{ end }}in *{{ .InputType|raw }}, opts {{ .metav1UpdateOptions|raw }}) (*{{ .ResultType|raw }}, error) {
in.SetGroupVersionKind({{ .schemaGroupVersionKind|raw }}{
Group: "{{ .Group }}",
Version: "{{ .VersionLower }}",
Kind: "{{ .Kind }}",
})
uo := &{{ .unstructuredUnstructured|raw }}{}
if err := convert(in, uo); err != nil {
return nil, err
}
uo, err := w.dyn{{if .Namespaced}}.Namespace(w.namespace){{end}}.Update(ctx, uo, opts)
if err != nil {
return nil, err
}
out := &{{ .ResultType|raw }}{}
if err := convert(uo, out); err != nil {
return nil, err
}
return out, nil
}
`,
"updateStatus": `
func (w *wrap{{.GroupGoName}}{{.Version}}{{ .Type.Name.Name }}Impl) UpdateStatus(ctx {{ .contextContext|raw }}, in *{{ .InputType|raw }}, opts {{ .metav1UpdateOptions|raw }}) (*{{ .ResultType|raw }}, error) {
in.SetGroupVersionKind({{ .schemaGroupVersionKind|raw }}{
Group: "{{ .Group }}",
Version: "{{ .VersionLower }}",
Kind: "{{ .Kind }}",
})
uo := &{{ .unstructuredUnstructured|raw }}{}
if err := convert(in, uo); err != nil {
return nil, err
}
uo, err := w.dyn{{if .Namespaced}}.Namespace(w.namespace){{end}}.UpdateStatus(ctx, uo, opts)
if err != nil {
return nil, err
}
out := &{{ .ResultType|raw }}{}
if err := convert(uo, out); err != nil {
return nil, err
}
return out, nil
}
`,
"delete": `
func (w *wrap{{.GroupGoName}}{{.Version}}{{ .Type.Name.Name }}Impl) Delete(ctx {{ .contextContext|raw }}, name string, opts {{ .metav1DeleteOptions|raw }}) error {
return w.dyn{{if .Namespaced}}.Namespace(w.namespace){{end}}.Delete(ctx, name, opts)
}
`,
"deleteCollection": `
func (w *wrap{{.GroupGoName}}{{.Version}}{{ .Type.Name.Name }}Impl) DeleteCollection(ctx {{ .contextContext|raw }}, opts {{ .metav1DeleteOptions|raw }}, listOpts {{ .metav1ListOptions|raw }}) error {
return w.dyn{{if .Namespaced}}.Namespace(w.namespace){{end}}.DeleteCollection(ctx, opts, listOpts)
}
`,
"get": `
func (w *wrap{{.GroupGoName}}{{.Version}}{{ .Type.Name.Name }}Impl) Get(ctx {{ .contextContext|raw }}, name string, opts {{ .metav1GetOptions|raw }}) (*{{ .ResultType|raw }}, error) {
uo, err := w.dyn{{if .Namespaced}}.Namespace(w.namespace){{end}}.Get(ctx, name, opts)
if err != nil {
return nil, err
}
out := &{{ .ResultType|raw }}{}
if err := convert(uo, out); err != nil {
return nil, err
}
return out, nil
}
`,
"list": `
func (w *wrap{{.GroupGoName}}{{.Version}}{{ .Type.Name.Name }}Impl) List(ctx {{ .contextContext|raw }}, opts {{ .metav1ListOptions|raw }}) (*{{ .ResultType|raw }}List, error) {
uo, err := w.dyn{{if .Namespaced}}.Namespace(w.namespace){{end}}.List(ctx, opts)
if err != nil {
return nil, err
}
out := &{{ .ResultType|raw }}List{}
if err := convert(uo, out); err != nil {
return nil, err
}
return out, nil
}
`,
"watch": `
func (w *wrap{{.GroupGoName}}{{.Version}}{{ .Type.Name.Name }}Impl) Watch(ctx {{ .contextContext|raw }}, opts {{ .metav1ListOptions|raw }}) ({{ .watchInterface|raw }}, error) {
return nil, {{ .errorsNew|raw }}("NYI: Watch")
}
`,
"patch": `
func (w *wrap{{.GroupGoName}}{{.Version}}{{ .Type.Name.Name }}Impl) Patch(ctx {{ .contextContext|raw }}, name string, pt {{ .typesPatchType|raw }}, data []byte, opts {{ .metav1PatchOptions|raw }}, subresources ...string) (result *{{ .ResultType|raw }}, err error) {
uo, err := w.dyn{{if .Namespaced}}.Namespace(w.namespace){{end}}.Patch(ctx, name, pt, data, opts)
if err != nil {
return nil, err
}
out := &{{ .ResultType|raw }}{}
if err := convert(uo, out); err != nil {
return nil, err
}
return out, nil
}
`,
}
var extensionVerbs = sets.NewString( /* Populated from extensionVerbMap during init */ )
var extensionVerbMap = map[string]string{
"create": `
func (w *wrap{{.GroupGoName}}{{.Version}}{{ .Type.Name.Name }}Impl) Create(ctx {{ .contextContext|raw }}, {{ if .Subresource }}_ string, {{ end }}in *{{ .InputType|raw }}, opts {{ .metav1CreateOptions|raw }}) (*{{ .ResultType|raw }}, error) {
panic("NYI")
}
`,
"update": `
func (w *wrap{{.GroupGoName}}{{.Version}}{{ .Type.Name.Name }}Impl) Update(ctx {{ .contextContext|raw }}, {{ if .Subresource }}_ string, {{ end }}in *{{ .InputType|raw }}, opts {{ .metav1UpdateOptions|raw }}) (*{{ .ResultType|raw }}, error) {
panic("NYI")
}
`,
"updateStatus": `
func (w *wrap{{.GroupGoName}}{{.Version}}{{ .Type.Name.Name }}Impl) UpdateStatus(ctx {{ .contextContext|raw }}, in *{{ .InputType|raw }}, opts {{ .metav1UpdateOptions|raw }}) (*{{ .ResultType|raw }}, error) {
panic("NYI")
}
`,
"delete": `
func (w *wrap{{.GroupGoName}}{{.Version}}{{ .Type.Name.Name }}Impl) Delete(ctx {{ .contextContext|raw }}, name string, opts {{ .metav1DeleteOptions|raw }}) error {
panic("NYI")
}
`,
"deleteCollection": `
func (w *wrap{{.GroupGoName}}{{.Version}}{{ .Type.Name.Name }}Impl) DeleteCollection(ctx {{ .contextContext|raw }}, opts {{ .metav1DeleteOptions|raw }}, listOpts {{ .metav1ListOptions|raw }}) error {
panic("NYI")
}
`,
"get": `
func (w *wrap{{.GroupGoName}}{{.Version}}{{ .Type.Name.Name }}Impl) Get(ctx {{ .contextContext|raw }}, name string, opts {{ .metav1GetOptions|raw }}) (*{{ .ResultType|raw }}, error) {
panic("NYI")
}
`,
"list": `
func (w *wrap{{.GroupGoName}}{{.Version}}{{ .Type.Name.Name }}Impl) List(ctx {{ .contextContext|raw }}, opts {{ .metav1ListOptions|raw }}) (*{{ .ResultType|raw }}List, error) {
panic("NYI")
}
`,
"watch": `
func (w *wrap{{.GroupGoName}}{{.Version}}{{ .Type.Name.Name }}Impl) Watch(ctx {{ .contextContext|raw }}, opts {{ .metav1ListOptions|raw }}) ({{ .watchInterface|raw }}, error) {
panic("NYI")
}
`,
"patch": `
func (w *wrap{{.GroupGoName}}{{.Version}}{{ .Type.Name.Name }}Impl) Patch(ctx {{ .contextContext|raw }}, name string, pt {{ .typesPatchType|raw }}, data []byte, opts {{ .metav1PatchOptions|raw }}, subresources ...string) (result *{{ .ResultType|raw }}, err error) {
panic("NYI")
}
`,
}
func init() {
for v := range verbMap {
verbs.Insert(v)
}
for ev := range extensionVerbMap {
extensionVerbs.Insert(ev)
}
}

View File

@ -19,6 +19,7 @@ package generators
import ( import (
"io" "io"
"k8s.io/code-generator/cmd/client-gen/generators/util"
clientgentypes "k8s.io/code-generator/cmd/client-gen/types" clientgentypes "k8s.io/code-generator/cmd/client-gen/types"
"k8s.io/gengo/generator" "k8s.io/gengo/generator"
"k8s.io/gengo/namer" "k8s.io/gengo/namer"
@ -37,6 +38,9 @@ type filteredInjectionGenerator struct {
imports namer.ImportTracker imports namer.ImportTracker
typedInformerPackage string typedInformerPackage string
groupInformerFactoryPackage string groupInformerFactoryPackage string
injectionClientSetPackage string
clientSetPackage string
listerPkg string
} }
var _ generator.Generator = (*filteredInjectionGenerator)(nil) var _ generator.Generator = (*filteredInjectionGenerator)(nil)
@ -78,11 +82,23 @@ func (g *filteredInjectionGenerator) GenerateType(c *generator.Context, t *types
klog.V(5).Info("processing type ", t) klog.V(5).Info("processing type ", t)
tags, err := util.ParseClientGenTags(append(g.typeToGenerate.SecondClosestCommentLines, g.typeToGenerate.CommentLines...))
if err != nil {
return err
}
m := map[string]interface{}{ m := map[string]interface{}{
"clientGet": c.Universe.Type(types.Name{Package: g.injectionClientSetPackage, Name: "Get"}),
"clientSetInterface": c.Universe.Type(types.Name{Package: g.clientSetPackage, Name: "Interface"}),
"resourceLister": c.Universe.Type(types.Name{Name: g.typeToGenerate.Name.Name + "Lister", Package: g.listerPkg}),
"resourceNamespaceLister": c.Universe.Type(types.Name{Name: g.typeToGenerate.Name.Name + "NamespaceLister", Package: g.listerPkg}),
"groupGoName": namer.IC(g.groupGoName),
"versionGoName": namer.IC(g.groupVersion.Version.String()),
"group": namer.IC(g.groupGoName), "group": namer.IC(g.groupGoName),
"type": t, "type": t,
"version": namer.IC(g.groupVersion.Version.String()), "version": namer.IC(g.groupVersion.Version.String()),
"injectionRegisterFilteredInformers": c.Universe.Type(types.Name{Package: "knative.dev/pkg/injection", Name: "Default.RegisterFilteredInformers"}), "injectionRegisterFilteredInformers": c.Universe.Type(types.Name{Package: "knative.dev/pkg/injection", Name: "Default.RegisterFilteredInformers"}),
"injectionRegisterDynamicInformer": c.Universe.Type(types.Name{Package: "knative.dev/pkg/injection", Name: "Dynamic.RegisterDynamicInformer"}),
"controllerInformer": c.Universe.Type(types.Name{Package: "knative.dev/pkg/controller", Name: "Informer"}), "controllerInformer": c.Universe.Type(types.Name{Package: "knative.dev/pkg/controller", Name: "Informer"}),
"informersTypedInformer": c.Universe.Type(types.Name{Package: g.typedInformerPackage, Name: t.Name.Name + "Informer"}), "informersTypedInformer": c.Universe.Type(types.Name{Package: g.typedInformerPackage, Name: t.Name.Name + "Informer"}),
"factoryLabelKey": c.Universe.Type(types.Name{Package: g.groupInformerFactoryPackage, Name: "LabelKey"}), "factoryLabelKey": c.Universe.Type(types.Name{Package: g.groupInformerFactoryPackage, Name: "LabelKey"}),
@ -95,6 +111,43 @@ func (g *filteredInjectionGenerator) GenerateType(c *generator.Context, t *types
Package: "context", Package: "context",
Name: "Context", Name: "Context",
}), }),
"contextWithValue": c.Universe.Function(types.Name{
Package: "context",
Name: "WithValue",
}),
"schemaGVR": c.Universe.Type(types.Name{
Package: "k8s.io/apimachinery/pkg/runtime/schema",
Name: "GroupVersionResource",
}),
"labelsSelector": c.Universe.Type(types.Name{
Package: "k8s.io/apimachinery/pkg/labels",
Name: "Selector",
}),
"labelsParseToRequirements": c.Universe.Type(types.Name{
Package: "k8s.io/apimachinery/pkg/labels",
Name: "ParseToRequirements",
}),
"contextTODO": c.Universe.Function(types.Name{
Package: "context",
Name: "TODO",
}),
"metav1GetOptions": c.Universe.Type(types.Name{
Package: "k8s.io/apimachinery/pkg/apis/meta/v1",
Name: "GetOptions",
}),
"metav1ListOptions": c.Universe.Type(types.Name{
Package: "k8s.io/apimachinery/pkg/apis/meta/v1",
Name: "ListOptions",
}),
"cacheSharedIndexInformer": c.Universe.Type(types.Name{
Package: "k8s.io/client-go/tools/cache",
Name: "SharedIndexInformer",
}),
"cacheNewSharedIndexInformer": c.Universe.Function(types.Name{
Package: "k8s.io/client-go/tools/cache",
Name: "NewSharedIndexInformer",
}),
"Namespaced": !tags.NonNamespaced,
} }
sw.Do(filteredInjectionInformer, m) sw.Do(filteredInjectionInformer, m)
@ -105,6 +158,7 @@ func (g *filteredInjectionGenerator) GenerateType(c *generator.Context, t *types
var filteredInjectionInformer = ` var filteredInjectionInformer = `
func init() { func init() {
{{.injectionRegisterFilteredInformers|raw}}(withInformer) {{.injectionRegisterFilteredInformers|raw}}(withInformer)
{{.injectionRegisterDynamicInformer|raw}}(withDynamicInformer)
} }
// Key is used for associating the Informer inside the context.Context. // Key is used for associating the Informer inside the context.Context.
@ -123,12 +177,26 @@ func withInformer(ctx {{.contextContext|raw}}) ({{.contextContext|raw}}, []{{.co
for _, selector := range labelSelectors { for _, selector := range labelSelectors {
f := {{.factoryGet|raw}}(ctx, selector) f := {{.factoryGet|raw}}(ctx, selector)
inf := f.{{.group}}().{{.version}}().{{.type|publicPlural}}() inf := f.{{.group}}().{{.version}}().{{.type|publicPlural}}()
ctx = context.WithValue(ctx, Key{Selector: selector}, inf) ctx = {{ .contextWithValue|raw }}(ctx, Key{Selector: selector}, inf)
infs = append(infs, inf.Informer()) infs = append(infs, inf.Informer())
} }
return ctx, infs return ctx, infs
} }
func withDynamicInformer(ctx {{.contextContext|raw}}) {{.contextContext|raw}} {
untyped := ctx.Value({{.factoryLabelKey|raw}}{})
if untyped == nil {
{{.loggingFromContext|raw}}(ctx).Panic(
"Unable to fetch labelkey from context.")
}
labelSelectors := untyped.([]string)
for _, selector := range labelSelectors {
inf := &wrapper{client: {{ .clientGet|raw }}(ctx), selector: selector}
ctx = {{ .contextWithValue|raw }}(ctx, Key{Selector: selector}, inf)
}
return ctx
}
// Get extracts the typed informer from the context. // Get extracts the typed informer from the context.
func Get(ctx {{.contextContext|raw}}, selector string) {{.informersTypedInformer|raw}} { func Get(ctx {{.contextContext|raw}}, selector string) {{.informersTypedInformer|raw}} {
untyped := ctx.Value(Key{Selector: selector}) untyped := ctx.Value(Key{Selector: selector})
@ -138,4 +206,55 @@ func Get(ctx {{.contextContext|raw}}, selector string) {{.informersTypedInformer
} }
return untyped.({{.informersTypedInformer|raw}}) return untyped.({{.informersTypedInformer|raw}})
} }
type wrapper struct {
client {{.clientSetInterface|raw}}
{{ if .Namespaced }}
namespace string
{{ end }}
selector string
}
var _ {{.informersTypedInformer|raw}} = (*wrapper)(nil)
var _ {{.resourceLister|raw}} = (*wrapper)(nil)
func (w *wrapper) Informer() {{ .cacheSharedIndexInformer|raw }} {
return {{ .cacheNewSharedIndexInformer|raw }}(nil, &{{ .type|raw }}{}, 0, nil)
}
func (w *wrapper) Lister() {{ .resourceLister|raw }} {
return w
}
{{if .Namespaced}}
func (w *wrapper) {{ .type|publicPlural }}(namespace string) {{ .resourceNamespaceLister|raw }} {
return &wrapper{client: w.client, namespace: namespace, selector: w.selector}
}
{{end}}
func (w *wrapper) List(selector {{ .labelsSelector|raw }}) (ret []*{{ .type|raw }}, err error) {
reqs, err := {{ .labelsParseToRequirements|raw }}(w.selector)
if err != nil {
return nil, err
}
selector = selector.Add(reqs...)
lo, err := w.client.{{.groupGoName}}{{.versionGoName}}().{{.type|publicPlural}}({{if .Namespaced}}w.namespace{{end}}).List({{ .contextTODO|raw }}(), {{ .metav1ListOptions|raw }}{
LabelSelector: selector.String(),
// TODO(mattmoor): Incorporate resourceVersion bounds based on staleness criteria.
})
if err != nil {
return nil, err
}
for idx := range lo.Items {
ret = append(ret, &lo.Items[idx])
}
return ret, nil
}
func (w *wrapper) Get(name string) (*{{ .type|raw }}, error) {
// TODO(mattmoor): Check that the fetched object matches the selector.
return w.client.{{.groupGoName}}{{.versionGoName}}().{{.type|publicPlural}}({{if .Namespaced}}w.namespace{{end}}).Get({{ .contextTODO|raw }}(), name, {{ .metav1GetOptions|raw }}{
// TODO(mattmoor): Incorporate resourceVersion bounds based on staleness criteria.
})
}
` `

View File

@ -19,6 +19,7 @@ package generators
import ( import (
"io" "io"
"k8s.io/code-generator/cmd/client-gen/generators/util"
clientgentypes "k8s.io/code-generator/cmd/client-gen/types" clientgentypes "k8s.io/code-generator/cmd/client-gen/types"
"k8s.io/gengo/generator" "k8s.io/gengo/generator"
"k8s.io/gengo/namer" "k8s.io/gengo/namer"
@ -37,6 +38,9 @@ type injectionGenerator struct {
imports namer.ImportTracker imports namer.ImportTracker
typedInformerPackage string typedInformerPackage string
groupInformerFactoryPackage string groupInformerFactoryPackage string
injectionClientSetPackage string
clientSetPackage string
listerPkg string
} }
var _ generator.Generator = (*injectionGenerator)(nil) var _ generator.Generator = (*injectionGenerator)(nil)
@ -78,14 +82,26 @@ func (g *injectionGenerator) GenerateType(c *generator.Context, t *types.Type, w
klog.V(5).Info("processing type ", t) klog.V(5).Info("processing type ", t)
tags, err := util.ParseClientGenTags(append(g.typeToGenerate.SecondClosestCommentLines, g.typeToGenerate.CommentLines...))
if err != nil {
return err
}
m := map[string]interface{}{ m := map[string]interface{}{
"group": namer.IC(g.groupGoName), "clientGet": c.Universe.Type(types.Name{Package: g.injectionClientSetPackage, Name: "Get"}),
"type": t, "clientSetInterface": c.Universe.Type(types.Name{Package: g.clientSetPackage, Name: "Interface"}),
"version": namer.IC(g.groupVersion.Version.String()), "resourceLister": c.Universe.Type(types.Name{Name: g.typeToGenerate.Name.Name + "Lister", Package: g.listerPkg}),
"injectionRegisterInformer": c.Universe.Type(types.Name{Package: "knative.dev/pkg/injection", Name: "Default.RegisterInformer"}), "resourceNamespaceLister": c.Universe.Type(types.Name{Name: g.typeToGenerate.Name.Name + "NamespaceLister", Package: g.listerPkg}),
"controllerInformer": c.Universe.Type(types.Name{Package: "knative.dev/pkg/controller", Name: "Informer"}), "groupGoName": namer.IC(g.groupGoName),
"informersTypedInformer": c.Universe.Type(types.Name{Package: g.typedInformerPackage, Name: t.Name.Name + "Informer"}), "versionGoName": namer.IC(g.groupVersion.Version.String()),
"factoryGet": c.Universe.Type(types.Name{Package: g.groupInformerFactoryPackage, Name: "Get"}), "group": g.groupVersion.Group.String(),
"version": g.groupVersion.Version.String(),
"type": t,
"injectionRegisterInformer": c.Universe.Type(types.Name{Package: "knative.dev/pkg/injection", Name: "Default.RegisterInformer"}),
"injectionRegisterDynamicInformer": c.Universe.Type(types.Name{Package: "knative.dev/pkg/injection", Name: "Dynamic.RegisterDynamicInformer"}),
"controllerInformer": c.Universe.Type(types.Name{Package: "knative.dev/pkg/controller", Name: "Informer"}),
"informersTypedInformer": c.Universe.Type(types.Name{Package: g.typedInformerPackage, Name: t.Name.Name + "Informer"}),
"factoryGet": c.Universe.Type(types.Name{Package: g.groupInformerFactoryPackage, Name: "Get"}),
"loggingFromContext": c.Universe.Function(types.Name{ "loggingFromContext": c.Universe.Function(types.Name{
Package: "knative.dev/pkg/logging", Package: "knative.dev/pkg/logging",
Name: "FromContext", Name: "FromContext",
@ -94,6 +110,39 @@ func (g *injectionGenerator) GenerateType(c *generator.Context, t *types.Type, w
Package: "context", Package: "context",
Name: "Context", Name: "Context",
}), }),
"contextWithValue": c.Universe.Function(types.Name{
Package: "context",
Name: "WithValue",
}),
"schemaGVR": c.Universe.Type(types.Name{
Package: "k8s.io/apimachinery/pkg/runtime/schema",
Name: "GroupVersionResource",
}),
"labelsSelector": c.Universe.Type(types.Name{
Package: "k8s.io/apimachinery/pkg/labels",
Name: "Selector",
}),
"contextTODO": c.Universe.Function(types.Name{
Package: "context",
Name: "TODO",
}),
"metav1GetOptions": c.Universe.Type(types.Name{
Package: "k8s.io/apimachinery/pkg/apis/meta/v1",
Name: "GetOptions",
}),
"metav1ListOptions": c.Universe.Type(types.Name{
Package: "k8s.io/apimachinery/pkg/apis/meta/v1",
Name: "ListOptions",
}),
"cacheSharedIndexInformer": c.Universe.Type(types.Name{
Package: "k8s.io/client-go/tools/cache",
Name: "SharedIndexInformer",
}),
"cacheNewSharedIndexInformer": c.Universe.Function(types.Name{
Package: "k8s.io/client-go/tools/cache",
Name: "NewSharedIndexInformer",
}),
"Namespaced": !tags.NonNamespaced,
} }
sw.Do(injectionInformer, m) sw.Do(injectionInformer, m)
@ -104,6 +153,7 @@ func (g *injectionGenerator) GenerateType(c *generator.Context, t *types.Type, w
var injectionInformer = ` var injectionInformer = `
func init() { func init() {
{{.injectionRegisterInformer|raw}}(withInformer) {{.injectionRegisterInformer|raw}}(withInformer)
{{.injectionRegisterDynamicInformer|raw}}(withDynamicInformer)
} }
// Key is used for associating the Informer inside the context.Context. // Key is used for associating the Informer inside the context.Context.
@ -111,8 +161,13 @@ type Key struct{}
func withInformer(ctx {{.contextContext|raw}}) ({{.contextContext|raw}}, {{.controllerInformer|raw}}) { func withInformer(ctx {{.contextContext|raw}}) ({{.contextContext|raw}}, {{.controllerInformer|raw}}) {
f := {{.factoryGet|raw}}(ctx) f := {{.factoryGet|raw}}(ctx)
inf := f.{{.group}}().{{.version}}().{{.type|publicPlural}}() inf := f.{{.groupGoName}}().{{.versionGoName}}().{{.type|publicPlural}}()
return context.WithValue(ctx, Key{}, inf), inf.Informer() return {{ .contextWithValue|raw }}(ctx, Key{}, inf), inf.Informer()
}
func withDynamicInformer(ctx {{.contextContext|raw}}) {{.contextContext|raw}} {
inf := &wrapper{client: {{ .clientGet|raw }}(ctx)}
return {{ .contextWithValue|raw }}(ctx, Key{}, inf)
} }
// Get extracts the typed informer from the context. // Get extracts the typed informer from the context.
@ -124,4 +179,49 @@ func Get(ctx {{.contextContext|raw}}) {{.informersTypedInformer|raw}} {
} }
return untyped.({{.informersTypedInformer|raw}}) return untyped.({{.informersTypedInformer|raw}})
} }
type wrapper struct {
client {{.clientSetInterface|raw}}
{{ if .Namespaced }}
namespace string
{{ end }}
}
var _ {{.informersTypedInformer|raw}} = (*wrapper)(nil)
var _ {{.resourceLister|raw}} = (*wrapper)(nil)
func (w *wrapper) Informer() {{ .cacheSharedIndexInformer|raw }} {
return {{ .cacheNewSharedIndexInformer|raw }}(nil, &{{ .type|raw }}{}, 0, nil)
}
func (w *wrapper) Lister() {{ .resourceLister|raw }} {
return w
}
{{if .Namespaced}}
func (w *wrapper) {{ .type|publicPlural }}(namespace string) {{ .resourceNamespaceLister|raw }} {
return &wrapper{client: w.client, namespace: namespace}
}
{{end}}
func (w *wrapper) List(selector {{ .labelsSelector|raw }}) (ret []*{{ .type|raw }}, err error) {
lo, err := w.client.{{.groupGoName}}{{.versionGoName}}().{{.type|publicPlural}}({{if .Namespaced}}w.namespace{{end}}).List({{ .contextTODO|raw }}(), {{ .metav1ListOptions|raw }}{
LabelSelector: selector.String(),
// TODO(mattmoor): Incorporate resourceVersion bounds based on staleness criteria.
})
if err != nil {
return nil, err
}
for idx := range lo.Items {
ret = append(ret, &lo.Items[idx])
}
return ret, nil
}
func (w *wrapper) Get(name string) (*{{ .type|raw }}, error) {
return w.client.{{.groupGoName}}{{.versionGoName}}().{{.type|publicPlural}}({{if .Namespaced}}w.namespace{{end}}).Get({{ .contextTODO|raw }}(), name, {{ .metav1GetOptions|raw }}{
// TODO(mattmoor): Incorporate resourceVersion bounds based on staleness criteria.
})
}
` `

View File

@ -50,6 +50,7 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
groupVersions := make(map[string]clientgentypes.GroupVersions) groupVersions := make(map[string]clientgentypes.GroupVersions)
groupGoNames := make(map[string]string) groupGoNames := make(map[string]string)
groupVersionTypes := make(map[string]map[clientgentypes.Version][]*types.Type)
for _, inputDir := range arguments.InputDirs { for _, inputDir := range arguments.InputDirs {
p := context.Universe.Package(vendorless(inputDir)) p := context.Universe.Package(vendorless(inputDir))
@ -78,15 +79,10 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
groupGoNames[groupPackageName] = namer.IC(override[0]) groupGoNames[groupPackageName] = namer.IC(override[0])
} }
// Generate the client and fake.
packageList = append(packageList, versionClientsPackages(versionPackagePath, boilerplate, customArgs)...)
// Generate the informer factory and fake.
packageList = append(packageList, versionFactoryPackages(versionPackagePath, boilerplate, customArgs)...)
var typesWithInformers []*types.Type var typesWithInformers []*types.Type
var duckTypes []*types.Type var duckTypes []*types.Type
var reconcilerTypes []*types.Type var reconcilerTypes []*types.Type
var clientTypes []*types.Type
for _, t := range p.Types { for _, t := range p.Types {
tags := MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...)) tags := MustParseClientGenTags(append(t.SecondClosestCommentLines, t.CommentLines...))
if tags.NeedsInformerInjection() { if tags.NeedsInformerInjection() {
@ -98,6 +94,9 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
if tags.NeedsReconciler(t, customArgs) { if tags.NeedsReconciler(t, customArgs) {
reconcilerTypes = append(reconcilerTypes, t) reconcilerTypes = append(reconcilerTypes, t)
} }
if tags.GenerateClient {
clientTypes = append(clientTypes, t)
}
} }
groupVersionsEntry, ok := targetGroupVersions[groupPackageName] groupVersionsEntry, ok := targetGroupVersions[groupPackageName]
@ -109,6 +108,12 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
} }
groupVersionsEntry.Versions = append(groupVersionsEntry.Versions, clientgentypes.PackageVersion{Version: gv.Version, Package: gvPackage}) groupVersionsEntry.Versions = append(groupVersionsEntry.Versions, clientgentypes.PackageVersion{Version: gv.Version, Package: gvPackage})
targetGroupVersions[groupPackageName] = groupVersionsEntry targetGroupVersions[groupPackageName] = groupVersionsEntry
verTypes, ok := groupVersionTypes[groupPackageName]
if !ok {
verTypes = make(map[clientgentypes.Version][]*types.Type)
}
verTypes[gv.Version] = clientTypes
groupVersionTypes[groupPackageName] = verTypes
if len(typesWithInformers) != 0 { if len(typesWithInformers) != 0 {
orderer := namer.Orderer{Namer: namer.NewPrivateNamer(0)} orderer := namer.Orderer{Namer: namer.NewPrivateNamer(0)}
@ -135,6 +140,12 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
} }
} }
// Generate the client and fake.
packageList = append(packageList, versionClientsPackages(versionPackagePath, boilerplate, customArgs, groupVersions, groupGoNames, groupVersionTypes)...)
// Generate the informer factory and fake.
packageList = append(packageList, versionFactoryPackages(versionPackagePath, boilerplate, customArgs)...)
return packageList return packageList
} }
@ -233,7 +244,7 @@ func typedInformerPackage(groupPkgName string, gv clientgentypes.GroupVersion, e
return filepath.Join(externalVersionsInformersPackage, groupPkgName, gv.Version.String()) return filepath.Join(externalVersionsInformersPackage, groupPkgName, gv.Version.String())
} }
func versionClientsPackages(basePackage string, boilerplate []byte, customArgs *informergenargs.CustomArgs) []generator.Package { func versionClientsPackages(basePackage string, boilerplate []byte, customArgs *informergenargs.CustomArgs, groupVersions map[string]clientgentypes.GroupVersions, groupGoNames map[string]string, groupVersionTypes map[string]map[clientgentypes.Version][]*types.Type) []generator.Package {
packagePath := filepath.Join(basePackage, "client") packagePath := filepath.Join(basePackage, "client")
return []generator.Package{ return []generator.Package{
@ -248,6 +259,11 @@ func versionClientsPackages(basePackage string, boilerplate []byte, customArgs *
DefaultGen: generator.DefaultGen{ DefaultGen: generator.DefaultGen{
OptionalName: "client", OptionalName: "client",
}, },
groupVersions: groupVersions,
groupGoNames: groupGoNames,
groupVersionTypes: groupVersionTypes,
outputPackage: packagePath, outputPackage: packagePath,
imports: generator.NewImportTracker(), imports: generator.NewImportTracker(),
clientSetPackage: customArgs.VersionedClientSetPackage, clientSetPackage: customArgs.VersionedClientSetPackage,
@ -392,6 +408,7 @@ func versionInformerPackages(basePackage string, groupPkgName string, gv clientg
filteredFactoryPackagePath := filepath.Join(basePackage, "informers", "factory", "filtered") filteredFactoryPackagePath := filepath.Join(basePackage, "informers", "factory", "filtered")
packagePath := filepath.Join(basePackage, "informers", groupPkgName, strings.ToLower(gv.Version.NonEmpty())) packagePath := filepath.Join(basePackage, "informers", groupPkgName, strings.ToLower(gv.Version.NonEmpty()))
listerPackagePath := filepath.Join(customArgs.ListersPackage, groupPkgName, strings.ToLower(gv.Version.NonEmpty()))
vers := make([]generator.Package, 0, 2*len(typesToGenerate)) vers := make([]generator.Package, 0, 2*len(typesToGenerate))
@ -419,6 +436,9 @@ func versionInformerPackages(basePackage string, groupPkgName string, gv clientg
imports: generator.NewImportTracker(), imports: generator.NewImportTracker(),
typedInformerPackage: typedInformerPackage, typedInformerPackage: typedInformerPackage,
groupInformerFactoryPackage: factoryPackagePath, groupInformerFactoryPackage: factoryPackagePath,
clientSetPackage: customArgs.VersionedClientSetPackage,
injectionClientSetPackage: filepath.Join(basePackage, "client"),
listerPkg: listerPackagePath,
}) })
return generators return generators
}, },
@ -472,6 +492,9 @@ func versionInformerPackages(basePackage string, groupPkgName string, gv clientg
imports: generator.NewImportTracker(), imports: generator.NewImportTracker(),
typedInformerPackage: typedInformerPackage, typedInformerPackage: typedInformerPackage,
groupInformerFactoryPackage: filteredFactoryPackagePath, groupInformerFactoryPackage: filteredFactoryPackagePath,
clientSetPackage: customArgs.VersionedClientSetPackage,
injectionClientSetPackage: filepath.Join(basePackage, "client"),
listerPkg: listerPackagePath,
}) })
return generators return generators
}, },

View File

@ -487,7 +487,8 @@ func (c *Impl) RunContext(ctx context.Context, threadiness int) error {
} }
// Run runs the controller. // Run runs the controller.
// DEPRECATED: Use RunContext instead. //
// Deprecated: Use RunContext instead.
func (c *Impl) Run(threadiness int, stopCh <-chan struct{}) error { func (c *Impl) Run(threadiness int, stopCh <-chan struct{}) error {
// Create a context that is cancelled when the stopCh is called. // Create a context that is cancelled when the stopCh is called.
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())

View File

@ -38,13 +38,18 @@ ${REPO_ROOT_DIR}/hack/generate-knative.sh "injection" \
"duck:v1alpha1,v1beta1,v1" \ "duck:v1alpha1,v1beta1,v1" \
--go-header-file ${REPO_ROOT_DIR}/hack/boilerplate/boilerplate.go.txt --go-header-file ${REPO_ROOT_DIR}/hack/boilerplate/boilerplate.go.txt
# Based on: https://github.com/kubernetes/kubernetes/blob/8ddabd0da5cc54761f3216c08e99fa1a9f7ee2c5/hack/lib/init.sh#L116
# The '-path' is a hack to workaround the lack of portable `-depth 2`.
K8S_TYPES=$(find ./vendor/k8s.io/api -type d -path '*/*/*/*/*/*' | cut -d'/' -f 5-6 | sort | sed 's@/@:@g' |
grep -v "admission:" | grep -v "imagepolicy:" | grep -v "abac:" | grep -v "componentconfig:")
OUTPUT_PKG="knative.dev/pkg/client/injection/kube" \ OUTPUT_PKG="knative.dev/pkg/client/injection/kube" \
VERSIONED_CLIENTSET_PKG="k8s.io/client-go/kubernetes" \ VERSIONED_CLIENTSET_PKG="k8s.io/client-go/kubernetes" \
EXTERNAL_INFORMER_PKG="k8s.io/client-go/informers" \ EXTERNAL_INFORMER_PKG="k8s.io/client-go/informers" \
${REPO_ROOT_DIR}/hack/generate-knative.sh "injection" \ ${REPO_ROOT_DIR}/hack/generate-knative.sh "injection" \
k8s.io/client-go \ k8s.io/client-go \
k8s.io/api \ k8s.io/api \
"admissionregistration:v1beta1,v1 apps:v1 autoscaling:v1,v2beta1 batch:v1,v1beta1 core:v1 rbac:v1 coordination:v1" \ "${K8S_TYPES}" \
--go-header-file ${REPO_ROOT_DIR}/hack/boilerplate/boilerplate.go.txt \ --go-header-file ${REPO_ROOT_DIR}/hack/boilerplate/boilerplate.go.txt \
--force-genreconciler-kinds "Namespace,Deployment,Secret" --force-genreconciler-kinds "Namespace,Deployment,Secret"

View File

@ -62,3 +62,22 @@ func (i *impl) FetchAllClients(ctx context.Context) []interface{} {
} }
return clients return clients
} }
// DynamicClientInjector holds the type of a callback that attaches a particular
// client type to a context.
type DynamicClientInjector func(context.Context) context.Context
func (i *impl) RegisterDynamicClient(ci DynamicClientInjector) {
i.m.Lock()
defer i.m.Unlock()
i.dynamicClients = append(i.dynamicClients, ci)
}
func (i *impl) GetDynamicClients() []DynamicClientInjector {
i.m.RLock()
defer i.m.RUnlock()
// Copy the slice before returning.
return append(i.dynamicClients[:0:0], i.dynamicClients...)
}

View File

@ -0,0 +1,49 @@
/*
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 dynamicclient
import (
"context"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/rest"
"knative.dev/pkg/injection"
"knative.dev/pkg/logging"
)
func init() {
injection.Default.RegisterClient(withClient)
}
// Key is used as the key for associating information
// with a context.Context.
type Key struct{}
func withClient(ctx context.Context, cfg *rest.Config) context.Context {
return context.WithValue(ctx, Key{}, dynamic.NewForConfigOrDie(cfg))
}
// Get extracts the Dynamic client from the context.
func Get(ctx context.Context) dynamic.Interface {
untyped := ctx.Value(Key{})
if untyped == nil {
logging.FromContext(ctx).Panic(
"Unable to fetch k8s.io/client-go/dynamic.Interface from context.")
}
return untyped.(dynamic.Interface)
}

View File

@ -28,6 +28,10 @@ import (
// informer type to a context. // informer type to a context.
type InformerInjector func(context.Context) (context.Context, controller.Informer) type InformerInjector func(context.Context) (context.Context, controller.Informer)
// DynamicInformerInjector holds the type of a callback that attaches a particular
// informer type (backed by a Dynamic) to a context.
type DynamicInformerInjector func(context.Context) context.Context
// FilteredInformersInjector holds the type of a callback that attaches a set of particular // FilteredInformersInjector holds the type of a callback that attaches a set of particular
// filtered informers type to a context. // filtered informers type to a context.
type FilteredInformersInjector func(context.Context) (context.Context, []controller.Informer) type FilteredInformersInjector func(context.Context) (context.Context, []controller.Informer)
@ -39,6 +43,13 @@ func (i *impl) RegisterInformer(ii InformerInjector) {
i.informers = append(i.informers, ii) i.informers = append(i.informers, ii)
} }
func (i *impl) RegisterDynamicInformer(ii DynamicInformerInjector) {
i.m.Lock()
defer i.m.Unlock()
i.dynamicInformers = append(i.dynamicInformers, ii)
}
func (i *impl) RegisterFilteredInformers(fii FilteredInformersInjector) { func (i *impl) RegisterFilteredInformers(fii FilteredInformersInjector) {
i.m.Lock() i.m.Lock()
defer i.m.Unlock() defer i.m.Unlock()
@ -54,6 +65,14 @@ func (i *impl) GetInformers() []InformerInjector {
return append(i.informers[:0:0], i.informers...) return append(i.informers[:0:0], i.informers...)
} }
func (i *impl) GetDynamicInformers() []DynamicInformerInjector {
i.m.RLock()
defer i.m.RUnlock()
// Copy the slice before returning.
return append(i.dynamicInformers[:0:0], i.dynamicInformers...)
}
func (i *impl) GetFilteredInformers() []FilteredInformersInjector { func (i *impl) GetFilteredInformers() []FilteredInformersInjector {
i.m.RLock() i.m.RLock()
defer i.m.RUnlock() defer i.m.RUnlock()
@ -62,6 +81,22 @@ func (i *impl) GetFilteredInformers() []FilteredInformersInjector {
return append(i.filteredInformers[:0:0], i.filteredInformers...) return append(i.filteredInformers[:0:0], i.filteredInformers...)
} }
func (i *impl) SetupDynamic(ctx context.Context) context.Context {
// Based on the reconcilers we have linked, build up a set of clients and inject
// them onto the context.
for _, ci := range i.GetDynamicClients() {
ctx = ci(ctx)
}
// Based on the reconcilers we have linked, build up a set of informers
// and inject them onto the context.
for _, ii := range i.GetDynamicInformers() {
ctx = ii(ctx)
}
return ctx
}
func (i *impl) SetupInformers(ctx context.Context, cfg *rest.Config) (context.Context, []controller.Informer) { func (i *impl) SetupInformers(ctx context.Context, cfg *rest.Config) (context.Context, []controller.Informer) {
// Based on the reconcilers we have linked, build up a set of clients and inject // Based on the reconcilers we have linked, build up a set of clients and inject
// them onto the context. // them onto the context.

View File

@ -78,6 +78,29 @@ type Interface interface {
SetupInformers(context.Context, *rest.Config) (context.Context, []controller.Informer) SetupInformers(context.Context, *rest.Config) (context.Context, []controller.Informer)
} }
// DynamicInterface is the interface for interacting with dynamicclient-based injection
// implementations, such as Dynamic below.
type DynamicInterface interface {
// RegisterDynamicClient registers a new injector callback for associating
// a new dynamicclient-based client with a context.
RegisterDynamicClient(DynamicClientInjector)
// GetDynamicClients fetches all of the registered dynamicclient-based client injectors.
GetDynamicClients() []DynamicClientInjector
// RegisterDynamicInformer registers a new injector callback for associating
// a new dynamicclient-based informer with a context.
RegisterDynamicInformer(DynamicInformerInjector)
// GetDynamicInformers fetches all of the registered dynamicclient-based informer injectors.
GetDynamicInformers() []DynamicInformerInjector
// SetupDynamic runs all of the injectors against a context, starting with
// the clients and the given stream. A context infused with the various elements
// is returned.
SetupDynamic(context.Context) context.Context
}
type ControllerConstructor func(context.Context, configmap.Watcher) *controller.Impl type ControllerConstructor func(context.Context, configmap.Watcher) *controller.Impl
var ( var (
@ -89,6 +112,10 @@ var (
// are being run for real. // are being run for real.
Default Interface = &impl{} Default Interface = &impl{}
// Dynamic is the injection interface to use when bootstrapping a version
// of things based on the prototype dynamicclient-based reconciler framework.
Dynamic DynamicInterface = &impl{}
// Fake is the injection interface with which informers should register // Fake is the injection interface with which informers should register
// to make themselves available to the controller process when it is being // to make themselves available to the controller process when it is being
// unit tested. // unit tested.
@ -99,9 +126,11 @@ type impl struct {
m sync.RWMutex m sync.RWMutex
clients []ClientInjector clients []ClientInjector
dynamicClients []DynamicClientInjector
clientFetchers []ClientFetcher clientFetchers []ClientFetcher
factories []InformerFactoryInjector factories []InformerFactoryInjector
informers []InformerInjector informers []InformerInjector
dynamicInformers []DynamicInformerInjector
filteredInformers []FilteredInformersInjector filteredInformers []FilteredInformersInjector
ducks []DuckFactoryInjector ducks []DuckFactoryInjector
} }

View File

@ -89,7 +89,8 @@ type ExporterOptions struct {
// UpdateExporterFromConfigMap returns a helper func that can be used to update the exporter // UpdateExporterFromConfigMap returns a helper func that can be used to update the exporter
// when a config map is updated. // when a config map is updated.
// DEPRECATED: Callers should migrate to ConfigMapWatcher. //
// Deprecated: Callers should migrate to ConfigMapWatcher.
func UpdateExporterFromConfigMap(ctx context.Context, component string, logger *zap.SugaredLogger) func(configMap *corev1.ConfigMap) { func UpdateExporterFromConfigMap(ctx context.Context, component string, logger *zap.SugaredLogger) func(configMap *corev1.ConfigMap) {
return ConfigMapWatcher(ctx, component, nil, logger) return ConfigMapWatcher(ctx, component, nil, logger)
} }

View File

@ -25,8 +25,8 @@ import (
// ErrorHandler sets up a handler suitable for use with the ErrorHandler field on // ErrorHandler sets up a handler suitable for use with the ErrorHandler field on
// httputil's reverse proxy. // httputil's reverse proxy.
// TODO(mattmoor): Move the implementation into handlers/error.go once downstream consumers //
// have adopted the alias. // Deprecated: Use handler.Error instead.
func ErrorHandler(logger *zap.SugaredLogger) func(http.ResponseWriter, *http.Request, error) { func ErrorHandler(logger *zap.SugaredLogger) func(http.ResponseWriter, *http.Request, error) {
return func(w http.ResponseWriter, req *http.Request, err error) { return func(w http.ResponseWriter, req *http.Request, err error) {
ss := readSockStat(logger) ss := readSockStat(logger)

View File

@ -61,7 +61,8 @@ type Reference struct {
type Interface interface { type Interface interface {
// Track tells us that "obj" is tracking changes to the // Track tells us that "obj" is tracking changes to the
// referenced object. // referenced object.
// DEPRECATED: use TrackReference //
// Deprecated: use TrackReference.
Track(ref corev1.ObjectReference, obj interface{}) error Track(ref corev1.ObjectReference, obj interface{}) error
// Track tells us that "obj" is tracking changes to the // Track tells us that "obj" is tracking changes to the

5
vendor/modules.txt vendored
View File

@ -575,10 +575,10 @@ k8s.io/kube-openapi/pkg/util/sets
k8s.io/utils/buffer k8s.io/utils/buffer
k8s.io/utils/integer k8s.io/utils/integer
k8s.io/utils/trace k8s.io/utils/trace
# knative.dev/hack v0.0.0-20210622141627-e28525d8d260 # knative.dev/hack v0.0.0-20210806075220-815cd312d65c
## explicit ## explicit
knative.dev/hack knative.dev/hack
# knative.dev/pkg v0.0.0-20210803160015-21eb4c167cc5 # knative.dev/pkg v0.0.0-20210818135208-7b5ecbc0e477
## explicit ## explicit
knative.dev/pkg/apis knative.dev/pkg/apis
knative.dev/pkg/apis/duck knative.dev/pkg/apis/duck
@ -596,6 +596,7 @@ knative.dev/pkg/environment
knative.dev/pkg/hack knative.dev/pkg/hack
knative.dev/pkg/hash knative.dev/pkg/hash
knative.dev/pkg/injection knative.dev/pkg/injection
knative.dev/pkg/injection/clients/dynamicclient
knative.dev/pkg/kmeta knative.dev/pkg/kmeta
knative.dev/pkg/kmp knative.dev/pkg/kmp
knative.dev/pkg/leaderelection knative.dev/pkg/leaderelection