From 0feb44bf9577ac872719ed2e38fea76bbfc5155e Mon Sep 17 00:00:00 2001 From: James Munnelly Date: Thu, 26 Oct 2017 23:44:07 +0100 Subject: [PATCH] code-generator: add NewFilteredSharedInformerFactory function Refactor to not change New*Informer constructors Separate namespace and ListOptions filter Kubernetes-commit: e4d9f3bbb4a5dd34283c5c111cdb9783cb146e36 --- cmd/informer-gen/generators/factory.go | 43 ++++++++++++------- .../generators/factoryinterface.go | 3 ++ cmd/informer-gen/generators/groupinterface.go | 11 +++-- cmd/informer-gen/generators/informer.go | 25 +++++++++-- .../generators/versioninterface.go | 30 +++++++++---- 5 files changed, 82 insertions(+), 30 deletions(-) diff --git a/cmd/informer-gen/generators/factory.go b/cmd/informer-gen/generators/factory.go index 593f5334..2a91aaa9 100644 --- a/cmd/informer-gen/generators/factory.go +++ b/cmd/informer-gen/generators/factory.go @@ -74,19 +74,21 @@ func (g *factoryGenerator) GenerateType(c *generator.Context, t *types.Type, w i gvNewFuncs[groupPkgName] = c.Universe.Function(types.Name{Package: path.Join(g.outputPackage, groupPkgName), Name: "New"}) } m := map[string]interface{}{ - "cacheSharedIndexInformer": c.Universe.Type(cacheSharedIndexInformer), - "groupVersions": g.groupVersions, - "gvInterfaces": gvInterfaces, - "gvNewFuncs": gvNewFuncs, - "gvGoNames": g.gvGoNames, - "interfacesNewInformerFunc": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "NewInformerFunc"}), - "informerFactoryInterface": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "SharedInformerFactory"}), - "clientSetInterface": c.Universe.Type(types.Name{Package: g.clientSetPackage, Name: "Interface"}), - "reflectType": c.Universe.Type(reflectType), - "runtimeObject": c.Universe.Type(runtimeObject), - "schemaGroupVersionResource": c.Universe.Type(schemaGroupVersionResource), - "syncMutex": c.Universe.Type(syncMutex), - "timeDuration": c.Universe.Type(timeDuration), + "cacheSharedIndexInformer": c.Universe.Type(cacheSharedIndexInformer), + "groupVersions": g.groupVersions, + "gvInterfaces": gvInterfaces, + "gvNewFuncs": gvNewFuncs, + "gvGoNames": g.gvGoNames, + "interfacesNewInformerFunc": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "NewInformerFunc"}), + "interfacesTweakListOptionsFunc": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "TweakListOptionsFunc"}), + "informerFactoryInterface": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "SharedInformerFactory"}), + "clientSetInterface": c.Universe.Type(types.Name{Package: g.clientSetPackage, Name: "Interface"}), + "reflectType": c.Universe.Type(reflectType), + "runtimeObject": c.Universe.Type(runtimeObject), + "schemaGroupVersionResource": c.Universe.Type(schemaGroupVersionResource), + "syncMutex": c.Universe.Type(syncMutex), + "timeDuration": c.Universe.Type(timeDuration), + "namespaceAll": c.Universe.Type(metav1NamespaceAll), } sw.Do(sharedInformerFactoryStruct, m) @@ -98,6 +100,8 @@ func (g *factoryGenerator) GenerateType(c *generator.Context, t *types.Type, w i var sharedInformerFactoryStruct = ` type sharedInformerFactory struct { client {{.clientSetInterface|raw}} + namespace string + tweakListOptions {{.interfacesTweakListOptionsFunc|raw}} lock {{.syncMutex|raw}} defaultResync {{.timeDuration|raw}} @@ -109,8 +113,17 @@ type sharedInformerFactory struct { // NewSharedInformerFactory constructs a new instance of sharedInformerFactory func NewSharedInformerFactory(client {{.clientSetInterface|raw}}, defaultResync {{.timeDuration|raw}}) SharedInformerFactory { + return NewFilteredSharedInformerFactory(client, defaultResync, {{.namespaceAll|raw}}, nil) +} + +// NewFilteredSharedInformerFactory constructs a new instance of sharedInformerFactory. +// Listers obtained via this SharedInformerFactory will be subject to the same filters +// as specified here. +func NewFilteredSharedInformerFactory(client {{.clientSetInterface|raw}}, defaultResync {{.timeDuration|raw}}, namespace string, tweakListOptions {{.interfacesTweakListOptionsFunc|raw}}) SharedInformerFactory { return &sharedInformerFactory{ - client: client, + client: client, + namespace: namespace, + tweakListOptions: tweakListOptions, defaultResync: defaultResync, informers: make(map[{{.reflectType|raw}}]{{.cacheSharedIndexInformer|raw}}), startedInformers: make(map[{{.reflectType|raw}}]bool), @@ -189,7 +202,7 @@ type SharedInformerFactory interface { {{$gvGoNames := .gvGoNames}} {{range $groupPkgName, $group := .groupVersions}} func (f *sharedInformerFactory) {{index $gvGoNames $groupPkgName}}() {{index $gvInterfaces $groupPkgName|raw}} { - return {{index $gvNewFuncs $groupPkgName|raw}}(f) + return {{index $gvNewFuncs $groupPkgName|raw}}(f, f.namespace, f.tweakListOptions) } {{end}} ` diff --git a/cmd/informer-gen/generators/factoryinterface.go b/cmd/informer-gen/generators/factoryinterface.go index 011fea20..c7818043 100644 --- a/cmd/informer-gen/generators/factoryinterface.go +++ b/cmd/informer-gen/generators/factoryinterface.go @@ -67,6 +67,7 @@ func (g *factoryInterfaceGenerator) GenerateType(c *generator.Context, t *types. "clientSetPackage": c.Universe.Type(types.Name{Package: g.clientSetPackage, Name: "Interface"}), "runtimeObject": c.Universe.Type(runtimeObject), "timeDuration": c.Universe.Type(timeDuration), + "v1ListOptions": c.Universe.Type(v1ListOptions), } sw.Do(externalSharedInformerFactoryInterface, m) @@ -82,4 +83,6 @@ type SharedInformerFactory interface { Start(stopCh <-chan struct{}) InformerFor(obj {{.runtimeObject|raw}}, newFunc NewInformerFunc) {{.cacheSharedIndexInformer|raw}} } + +type TweakListOptionsFunc func(*{{.v1ListOptions|raw}}) ` diff --git a/cmd/informer-gen/generators/groupinterface.go b/cmd/informer-gen/generators/groupinterface.go index bc6468ea..253b79f3 100644 --- a/cmd/informer-gen/generators/groupinterface.go +++ b/cmd/informer-gen/generators/groupinterface.go @@ -79,6 +79,7 @@ func (g *groupInterfaceGenerator) GenerateType(c *generator.Context, t *types.Ty }) } m := map[string]interface{}{ + "interfacesTweakListOptionsFunc": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "TweakListOptionsFunc"}), "interfacesSharedInformerFactory": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "SharedInformerFactory"}), "versions": versions, } @@ -98,18 +99,20 @@ type Interface interface { } type group struct { - $.interfacesSharedInformerFactory|raw$ + factory $.interfacesSharedInformerFactory|raw$ + namespace string + tweakListOptions $.interfacesTweakListOptionsFunc|raw$ } // New returns a new Interface. -func New(f $.interfacesSharedInformerFactory|raw$) Interface { - return &group{f} +func New(f $.interfacesSharedInformerFactory|raw$, namespace string, tweakListOptions $.interfacesTweakListOptionsFunc|raw$) Interface { + return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} } $range .versions$ // $.Name$ returns a new $.Interface|raw$. func (g *group) $.Name$() $.Interface|raw$ { - return $.New|raw$(g.SharedInformerFactory) + return $.New|raw$(g.factory, g.namespace, g.tweakListOptions) } $end$ ` diff --git a/cmd/informer-gen/generators/informer.go b/cmd/informer-gen/generators/informer.go index 57c4c63f..22b09fd5 100644 --- a/cmd/informer-gen/generators/informer.go +++ b/cmd/informer-gen/generators/informer.go @@ -88,6 +88,7 @@ func (g *informerGenerator) GenerateType(c *generator.Context, t *types.Type, w "clientSetInterface": clientSetInterface, "group": namer.IC(g.groupGoName), "informerFor": informerFor, + "interfacesTweakListOptionsFunc": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "TweakListOptionsFunc"}), "interfacesSharedInformerFactory": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "SharedInformerFactory"}), "listOptions": c.Universe.Type(listOptions), "lister": c.Universe.Type(types.Name{Package: listerPackage, Name: t.Name.Name + "Lister"}), @@ -105,6 +106,7 @@ func (g *informerGenerator) GenerateType(c *generator.Context, t *types.Type, w sw.Do(typeInformerInterface, m) sw.Do(typeInformerStruct, m) sw.Do(typeInformerPublicConstructor, m) + sw.Do(typeFilteredInformerPublicConstructor, m) sw.Do(typeInformerConstructor, m) sw.Do(typeInformerInformer, m) sw.Do(typeInformerLister, m) @@ -124,6 +126,8 @@ type $.type|public$Informer interface { var typeInformerStruct = ` type $.type|private$Informer struct { factory $.interfacesSharedInformerFactory|raw$ + tweakListOptions $.interfacesTweakListOptionsFunc|raw$ + $if .namespaced$namespace string$end$ } ` @@ -132,12 +136,27 @@ var typeInformerPublicConstructor = ` // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. func New$.type|public$Informer(client $.clientSetInterface|raw$$if .namespaced$, namespace string$end$, resyncPeriod $.timeDuration|raw$, indexers $.cacheIndexers|raw$) $.cacheSharedIndexInformer|raw$ { + return NewFiltered$.type|public$Informer(client$if .namespaced$, namespace$end$, resyncPeriod, indexers, nil) +} +` + +var typeFilteredInformerPublicConstructor = ` +// NewFiltered$.type|public$Informer constructs a new informer for $.type|public$ type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFiltered$.type|public$Informer(client $.clientSetInterface|raw$$if .namespaced$, namespace string$end$, resyncPeriod $.timeDuration|raw$, indexers $.cacheIndexers|raw$, tweakListOptions $.interfacesTweakListOptionsFunc|raw$) $.cacheSharedIndexInformer|raw$ { return $.cacheNewSharedIndexInformer|raw$( &$.cacheListWatch|raw${ ListFunc: func(options $.v1ListOptions|raw$) ($.runtimeObject|raw$, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } return client.$.group$$.version$().$.type|publicPlural$($if .namespaced$namespace$end$).List(options) }, WatchFunc: func(options $.v1ListOptions|raw$) ($.watchInterface|raw$, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } return client.$.group$$.version$().$.type|publicPlural$($if .namespaced$namespace$end$).Watch(options) }, }, @@ -149,14 +168,14 @@ func New$.type|public$Informer(client $.clientSetInterface|raw$$if .namespaced$, ` var typeInformerConstructor = ` -func default$.type|public$Informer(client $.clientSetInterface|raw$, resyncPeriod $.timeDuration|raw$) $.cacheSharedIndexInformer|raw$ { - return New$.type|public$Informer(client, $if .namespaced$$.namespaceAll|raw$, $end$resyncPeriod, $.cacheIndexers|raw${$.cacheNamespaceIndex|raw$: $.cacheMetaNamespaceIndexFunc|raw$}) +func (f *$.type|private$Informer) defaultInformer(client $.clientSetInterface|raw$, resyncPeriod $.timeDuration|raw$) $.cacheSharedIndexInformer|raw$ { + return NewFiltered$.type|public$Informer(client$if .namespaced$, f.namespace$end$, resyncPeriod, $.cacheIndexers|raw${$.cacheNamespaceIndex|raw$: $.cacheMetaNamespaceIndexFunc|raw$}, f.tweakListOptions) } ` var typeInformerInformer = ` func (f *$.type|private$Informer) Informer() $.cacheSharedIndexInformer|raw$ { - return f.factory.$.informerFor$(&$.type|raw${}, default$.type|public$Informer) + return f.factory.$.informerFor$(&$.type|raw${}, f.defaultInformer) } ` diff --git a/cmd/informer-gen/generators/versioninterface.go b/cmd/informer-gen/generators/versioninterface.go index 23f7286f..1cd27d5c 100644 --- a/cmd/informer-gen/generators/versioninterface.go +++ b/cmd/informer-gen/generators/versioninterface.go @@ -22,6 +22,8 @@ import ( "k8s.io/gengo/generator" "k8s.io/gengo/namer" "k8s.io/gengo/types" + + "k8s.io/code-generator/cmd/client-gen/generators/util" ) // versionInterfaceGenerator generates the per-version interface file. @@ -59,11 +61,21 @@ func (g *versionInterfaceGenerator) GenerateType(c *generator.Context, t *types. sw := generator.NewSnippetWriter(w, c, "$", "$") m := map[string]interface{}{ + "interfacesTweakListOptionsFunc": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "TweakListOptionsFunc"}), "interfacesSharedInformerFactory": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "SharedInformerFactory"}), "types": g.types, } sw.Do(versionTemplate, m) + for _, typeDef := range g.types { + tags, err := util.ParseClientGenTags(typeDef.SecondClosestCommentLines) + if err != nil { + return err + } + m["namespaced"] = !tags.NonNamespaced + m["type"] = typeDef + sw.Do(versionFuncTemplate, m) + } return sw.Error() } @@ -78,18 +90,20 @@ type Interface interface { } type version struct { - $.interfacesSharedInformerFactory|raw$ + factory $.interfacesSharedInformerFactory|raw$ + namespace string + tweakListOptions $.interfacesTweakListOptionsFunc|raw$ } // New returns a new Interface. -func New(f $.interfacesSharedInformerFactory|raw$) Interface { - return &version{f} +func New(f $.interfacesSharedInformerFactory|raw$, namespace string, tweakListOptions $.interfacesTweakListOptionsFunc|raw$) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} } +` -$range .types$ -// $.|publicPlural$ returns a $.|public$Informer. -func (v *version) $.|publicPlural$() $.|public$Informer { - return &$.|private$Informer{factory: v.SharedInformerFactory} +var versionFuncTemplate = ` +// $.type|publicPlural$ returns a $.type|public$Informer. +func (v *version) $.type|publicPlural$() $.type|public$Informer { + return &$.type|private$Informer{factory: v.factory$if .namespaced$, namespace: v.namespace$end$, tweakListOptions: v.tweakListOptions} } -$end$ `