code-generator: add NewFilteredSharedInformerFactory function

Refactor to not change New*Informer constructors

Separate namespace and ListOptions filter
This commit is contained in:
James Munnelly 2017-10-26 23:44:07 +01:00
parent c2a5a79ed6
commit e4d9f3bbb4
5 changed files with 84 additions and 32 deletions

View File

@ -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"}) gvNewFuncs[groupPkgName] = c.Universe.Function(types.Name{Package: path.Join(g.outputPackage, groupPkgName), Name: "New"})
} }
m := map[string]interface{}{ m := map[string]interface{}{
"cacheSharedIndexInformer": c.Universe.Type(cacheSharedIndexInformer), "cacheSharedIndexInformer": c.Universe.Type(cacheSharedIndexInformer),
"groupVersions": g.groupVersions, "groupVersions": g.groupVersions,
"gvInterfaces": gvInterfaces, "gvInterfaces": gvInterfaces,
"gvNewFuncs": gvNewFuncs, "gvNewFuncs": gvNewFuncs,
"gvGoNames": g.gvGoNames, "gvGoNames": g.gvGoNames,
"interfacesNewInformerFunc": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "NewInformerFunc"}), "interfacesNewInformerFunc": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "NewInformerFunc"}),
"informerFactoryInterface": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "SharedInformerFactory"}), "interfacesTweakListOptionsFunc": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "TweakListOptionsFunc"}),
"clientSetInterface": c.Universe.Type(types.Name{Package: g.clientSetPackage, Name: "Interface"}), "informerFactoryInterface": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "SharedInformerFactory"}),
"reflectType": c.Universe.Type(reflectType), "clientSetInterface": c.Universe.Type(types.Name{Package: g.clientSetPackage, Name: "Interface"}),
"runtimeObject": c.Universe.Type(runtimeObject), "reflectType": c.Universe.Type(reflectType),
"schemaGroupVersionResource": c.Universe.Type(schemaGroupVersionResource), "runtimeObject": c.Universe.Type(runtimeObject),
"syncMutex": c.Universe.Type(syncMutex), "schemaGroupVersionResource": c.Universe.Type(schemaGroupVersionResource),
"timeDuration": c.Universe.Type(timeDuration), "syncMutex": c.Universe.Type(syncMutex),
"timeDuration": c.Universe.Type(timeDuration),
"namespaceAll": c.Universe.Type(metav1NamespaceAll),
} }
sw.Do(sharedInformerFactoryStruct, m) sw.Do(sharedInformerFactoryStruct, m)
@ -98,6 +100,8 @@ func (g *factoryGenerator) GenerateType(c *generator.Context, t *types.Type, w i
var sharedInformerFactoryStruct = ` var sharedInformerFactoryStruct = `
type sharedInformerFactory struct { type sharedInformerFactory struct {
client {{.clientSetInterface|raw}} client {{.clientSetInterface|raw}}
namespace string
tweakListOptions {{.interfacesTweakListOptionsFunc|raw}}
lock {{.syncMutex|raw}} lock {{.syncMutex|raw}}
defaultResync {{.timeDuration|raw}} defaultResync {{.timeDuration|raw}}
@ -109,8 +113,17 @@ type sharedInformerFactory struct {
// NewSharedInformerFactory constructs a new instance of sharedInformerFactory // NewSharedInformerFactory constructs a new instance of sharedInformerFactory
func NewSharedInformerFactory(client {{.clientSetInterface|raw}}, defaultResync {{.timeDuration|raw}}) 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{ return &sharedInformerFactory{
client: client, client: client,
namespace: namespace,
tweakListOptions: tweakListOptions,
defaultResync: defaultResync, defaultResync: defaultResync,
informers: make(map[{{.reflectType|raw}}]{{.cacheSharedIndexInformer|raw}}), informers: make(map[{{.reflectType|raw}}]{{.cacheSharedIndexInformer|raw}}),
startedInformers: make(map[{{.reflectType|raw}}]bool), startedInformers: make(map[{{.reflectType|raw}}]bool),
@ -189,7 +202,7 @@ type SharedInformerFactory interface {
{{$gvGoNames := .gvGoNames}} {{$gvGoNames := .gvGoNames}}
{{range $groupPkgName, $group := .groupVersions}} {{range $groupPkgName, $group := .groupVersions}}
func (f *sharedInformerFactory) {{index $gvGoNames $groupPkgName}}() {{index $gvInterfaces $groupPkgName|raw}} { 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}} {{end}}
` `

View File

@ -67,6 +67,7 @@ func (g *factoryInterfaceGenerator) GenerateType(c *generator.Context, t *types.
"clientSetPackage": c.Universe.Type(types.Name{Package: g.clientSetPackage, Name: "Interface"}), "clientSetPackage": c.Universe.Type(types.Name{Package: g.clientSetPackage, Name: "Interface"}),
"runtimeObject": c.Universe.Type(runtimeObject), "runtimeObject": c.Universe.Type(runtimeObject),
"timeDuration": c.Universe.Type(timeDuration), "timeDuration": c.Universe.Type(timeDuration),
"v1ListOptions": c.Universe.Type(v1ListOptions),
} }
sw.Do(externalSharedInformerFactoryInterface, m) sw.Do(externalSharedInformerFactoryInterface, m)
@ -82,4 +83,6 @@ type SharedInformerFactory interface {
Start(stopCh <-chan struct{}) Start(stopCh <-chan struct{})
InformerFor(obj {{.runtimeObject|raw}}, newFunc NewInformerFunc) {{.cacheSharedIndexInformer|raw}} InformerFor(obj {{.runtimeObject|raw}}, newFunc NewInformerFunc) {{.cacheSharedIndexInformer|raw}}
} }
type TweakListOptionsFunc func(*{{.v1ListOptions|raw}})
` `

View File

@ -79,6 +79,7 @@ func (g *groupInterfaceGenerator) GenerateType(c *generator.Context, t *types.Ty
}) })
} }
m := map[string]interface{}{ 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"}), "interfacesSharedInformerFactory": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "SharedInformerFactory"}),
"versions": versions, "versions": versions,
} }
@ -98,18 +99,20 @@ type Interface interface {
} }
type group struct { type group struct {
$.interfacesSharedInformerFactory|raw$ factory $.interfacesSharedInformerFactory|raw$
namespace string
tweakListOptions $.interfacesTweakListOptionsFunc|raw$
} }
// New returns a new Interface. // New returns a new Interface.
func New(f $.interfacesSharedInformerFactory|raw$) Interface { func New(f $.interfacesSharedInformerFactory|raw$, namespace string, tweakListOptions $.interfacesTweakListOptionsFunc|raw$) Interface {
return &group{f} return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
} }
$range .versions$ $range .versions$
// $.Name$ returns a new $.Interface|raw$. // $.Name$ returns a new $.Interface|raw$.
func (g *group) $.Name$() $.Interface|raw$ { func (g *group) $.Name$() $.Interface|raw$ {
return $.New|raw$(g.SharedInformerFactory) return $.New|raw$(g.factory, g.namespace, g.tweakListOptions)
} }
$end$ $end$
` `

View File

@ -88,6 +88,7 @@ func (g *informerGenerator) GenerateType(c *generator.Context, t *types.Type, w
"clientSetInterface": clientSetInterface, "clientSetInterface": clientSetInterface,
"group": namer.IC(g.groupGoName), "group": namer.IC(g.groupGoName),
"informerFor": informerFor, "informerFor": informerFor,
"interfacesTweakListOptionsFunc": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "TweakListOptionsFunc"}),
"interfacesSharedInformerFactory": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "SharedInformerFactory"}), "interfacesSharedInformerFactory": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "SharedInformerFactory"}),
"listOptions": c.Universe.Type(listOptions), "listOptions": c.Universe.Type(listOptions),
"lister": c.Universe.Type(types.Name{Package: listerPackage, Name: t.Name.Name + "Lister"}), "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(typeInformerInterface, m)
sw.Do(typeInformerStruct, m) sw.Do(typeInformerStruct, m)
sw.Do(typeInformerPublicConstructor, m) sw.Do(typeInformerPublicConstructor, m)
sw.Do(typeFilteredInformerPublicConstructor, m)
sw.Do(typeInformerConstructor, m) sw.Do(typeInformerConstructor, m)
sw.Do(typeInformerInformer, m) sw.Do(typeInformerInformer, m)
sw.Do(typeInformerLister, m) sw.Do(typeInformerLister, m)
@ -124,6 +126,8 @@ type $.type|public$Informer interface {
var typeInformerStruct = ` var typeInformerStruct = `
type $.type|private$Informer struct { type $.type|private$Informer struct {
factory $.interfacesSharedInformerFactory|raw$ 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 // 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. // 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$ { 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$( return $.cacheNewSharedIndexInformer|raw$(
&$.cacheListWatch|raw${ &$.cacheListWatch|raw${
ListFunc: func(options $.v1ListOptions|raw$) ($.runtimeObject|raw$, error) { 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) return client.$.group$$.version$().$.type|publicPlural$($if .namespaced$namespace$end$).List(options)
}, },
WatchFunc: func(options $.v1ListOptions|raw$) ($.watchInterface|raw$, error) { 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) 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 = ` var typeInformerConstructor = `
func default$.type|public$Informer(client $.clientSetInterface|raw$, resyncPeriod $.timeDuration|raw$) $.cacheSharedIndexInformer|raw$ { func (f *$.type|private$Informer) defaultInformer(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$}) return NewFiltered$.type|public$Informer(client$if .namespaced$, f.namespace$end$, resyncPeriod, $.cacheIndexers|raw${$.cacheNamespaceIndex|raw$: $.cacheMetaNamespaceIndexFunc|raw$}, f.tweakListOptions)
} }
` `
var typeInformerInformer = ` var typeInformerInformer = `
func (f *$.type|private$Informer) Informer() $.cacheSharedIndexInformer|raw$ { 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)
} }
` `

View File

@ -22,6 +22,8 @@ import (
"k8s.io/gengo/generator" "k8s.io/gengo/generator"
"k8s.io/gengo/namer" "k8s.io/gengo/namer"
"k8s.io/gengo/types" "k8s.io/gengo/types"
"k8s.io/code-generator/cmd/client-gen/generators/util"
) )
// versionInterfaceGenerator generates the per-version interface file. // 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, "$", "$") sw := generator.NewSnippetWriter(w, c, "$", "$")
m := map[string]interface{}{ 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"}), "interfacesSharedInformerFactory": c.Universe.Type(types.Name{Package: g.internalInterfacesPackage, Name: "SharedInformerFactory"}),
"types": g.types, "types": g.types,
} }
sw.Do(versionTemplate, m) 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() return sw.Error()
} }
@ -78,18 +90,20 @@ type Interface interface {
} }
type version struct { type version struct {
$.interfacesSharedInformerFactory|raw$ factory $.interfacesSharedInformerFactory|raw$
namespace string
tweakListOptions $.interfacesTweakListOptionsFunc|raw$
} }
// New returns a new Interface. // New returns a new Interface.
func New(f $.interfacesSharedInformerFactory|raw$) Interface { func New(f $.interfacesSharedInformerFactory|raw$, namespace string, tweakListOptions $.interfacesTweakListOptionsFunc|raw$) Interface {
return &version{f} return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
}
`
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}
} }
$range .types$
// $.|publicPlural$ returns a $.|public$Informer.
func (v *version) $.|publicPlural$() $.|public$Informer {
return &$.|private$Informer{factory: v.SharedInformerFactory}
}
$end$
` `