Skip to content

Commit

Permalink
Merge pull request #54660 from munnerz/namespaced-informer-factory
Browse files Browse the repository at this point in the history
Automatic merge from submit-queue (batch tested with PRs 55403, 54660, 55165). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

code-generator: add NewFilteredSharedInformerFactory function

**What this PR does / why we need it**:

Adds a `namespace` option to the SharedInformerFactory constructor. This is useful when building controllers that may need to scope themselves to a namespace due to RBAC constraints.

Workarounds for this involve losing type safety if a user wants to use it for core APIs as well as a SharedInformerFactory type interface, as we have to deal with plain SharedIndexInformers (example here: https://github.com/jetstack-experimental/cert-manager/blob/master/pkg/util/kube/factory.go)

**Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes #

Fixes kubernetes#9

**Special notes for your reviewer**:

This will require updating all uses of SharedInformerFactory throughout the codebase. I'm going to follow up with later commits in this PR with these changes, but wanted to get this here to get some feedback on the way it's implemented.

**Release note**:

```release-note
NONE
```

/cc @sttts @nikhita @deads2k

Kubernetes-commit: bab312dbcf2ea68c19bffa9f26362c86ef1987ec
  • Loading branch information
k8s-publish-robot committed Dec 7, 2017
2 parents dda3875 + 56352f6 commit 934da44
Show file tree
Hide file tree
Showing 23 changed files with 264 additions and 91 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,17 @@ type Interface interface {
}

type group struct {
internalinterfaces.SharedInformerFactory
factory internalinterfaces.SharedInformerFactory
namespace string
tweakListOptions internalinterfaces.TweakListOptionsFunc
}

// New returns a new Interface.
func New(f internalinterfaces.SharedInformerFactory) Interface {
return &group{f}
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
}

// V1 returns a new v1.Interface.
func (g *group) V1() v1.Interface {
return v1.New(g.SharedInformerFactory)
return v1.New(g.factory, g.namespace, g.tweakListOptions)
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,17 @@ type Interface interface {
}

type version struct {
internalinterfaces.SharedInformerFactory
factory internalinterfaces.SharedInformerFactory
namespace string
tweakListOptions internalinterfaces.TweakListOptionsFunc
}

// New returns a new Interface.
func New(f internalinterfaces.SharedInformerFactory) Interface {
return &version{f}
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
}

// TestTypes returns a TestTypeInformer.
func (v *version) TestTypes() TestTypeInformer {
return &testTypeInformer{factory: v.SharedInformerFactory}
return &testTypeInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,34 @@ type TestTypeInformer interface {
}

type testTypeInformer struct {
factory internalinterfaces.SharedInformerFactory
factory internalinterfaces.SharedInformerFactory
tweakListOptions internalinterfaces.TweakListOptionsFunc
namespace string
}

// NewTestTypeInformer constructs a new informer for TestType 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 NewTestTypeInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
return NewFilteredTestTypeInformer(client, namespace, resyncPeriod, indexers, nil)
}

// NewFilteredTestTypeInformer constructs a new informer for TestType 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 NewFilteredTestTypeInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
return cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options meta_v1.ListOptions) (runtime.Object, error) {
if tweakListOptions != nil {
tweakListOptions(&options)
}
return client.ExampleV1().TestTypes(namespace).List(options)
},
WatchFunc: func(options meta_v1.ListOptions) (watch.Interface, error) {
if tweakListOptions != nil {
tweakListOptions(&options)
}
return client.ExampleV1().TestTypes(namespace).Watch(options)
},
},
Expand All @@ -60,12 +75,12 @@ func NewTestTypeInformer(client versioned.Interface, namespace string, resyncPer
)
}

func defaultTestTypeInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
return NewTestTypeInformer(client, meta_v1.NamespaceAll, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
func (f *testTypeInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
return NewFilteredTestTypeInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
}

func (f *testTypeInformer) Informer() cache.SharedIndexInformer {
return f.factory.InformerFor(&example_v1.TestType{}, defaultTestTypeInformer)
return f.factory.InformerFor(&example_v1.TestType{}, f.defaultInformer)
}

func (f *testTypeInformer) Lister() v1.TestTypeLister {
Expand Down
20 changes: 16 additions & 4 deletions _examples/apiserver/informers/externalversions/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ limitations under the License.
package externalversions

import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
schema "k8s.io/apimachinery/pkg/runtime/schema"
cache "k8s.io/client-go/tools/cache"
Expand All @@ -31,9 +32,11 @@ import (
)

type sharedInformerFactory struct {
client versioned.Interface
lock sync.Mutex
defaultResync time.Duration
client versioned.Interface
namespace string
tweakListOptions internalinterfaces.TweakListOptionsFunc
lock sync.Mutex
defaultResync time.Duration

informers map[reflect.Type]cache.SharedIndexInformer
// startedInformers is used for tracking which informers have been started.
Expand All @@ -43,8 +46,17 @@ type sharedInformerFactory struct {

// NewSharedInformerFactory constructs a new instance of sharedInformerFactory
func NewSharedInformerFactory(client versioned.Interface, defaultResync time.Duration) SharedInformerFactory {
return NewFilteredSharedInformerFactory(client, defaultResync, v1.NamespaceAll, 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 versioned.Interface, defaultResync time.Duration, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerFactory {
return &sharedInformerFactory{
client: client,
namespace: namespace,
tweakListOptions: tweakListOptions,
defaultResync: defaultResync,
informers: make(map[reflect.Type]cache.SharedIndexInformer),
startedInformers: make(map[reflect.Type]bool),
Expand Down Expand Up @@ -114,5 +126,5 @@ type SharedInformerFactory interface {
}

func (f *sharedInformerFactory) Example() example.Interface {
return example.New(f)
return example.New(f, f.namespace, f.tweakListOptions)
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ limitations under the License.
package internalinterfaces

import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
cache "k8s.io/client-go/tools/cache"
versioned "k8s.io/code-generator/_examples/apiserver/clientset/versioned"
Expand All @@ -32,3 +33,5 @@ type SharedInformerFactory interface {
Start(stopCh <-chan struct{})
InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer
}

type TweakListOptionsFunc func(*v1.ListOptions)
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,17 @@ type Interface interface {
}

type group struct {
internalinterfaces.SharedInformerFactory
factory internalinterfaces.SharedInformerFactory
namespace string
tweakListOptions internalinterfaces.TweakListOptionsFunc
}

// New returns a new Interface.
func New(f internalinterfaces.SharedInformerFactory) Interface {
return &group{f}
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
}

// InternalVersion returns a new internalversion.Interface.
func (g *group) InternalVersion() internalversion.Interface {
return internalversion.New(g.SharedInformerFactory)
return internalversion.New(g.factory, g.namespace, g.tweakListOptions)
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,17 @@ type Interface interface {
}

type version struct {
internalinterfaces.SharedInformerFactory
factory internalinterfaces.SharedInformerFactory
namespace string
tweakListOptions internalinterfaces.TweakListOptionsFunc
}

// New returns a new Interface.
func New(f internalinterfaces.SharedInformerFactory) Interface {
return &version{f}
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
}

// TestTypes returns a TestTypeInformer.
func (v *version) TestTypes() TestTypeInformer {
return &testTypeInformer{factory: v.SharedInformerFactory}
return &testTypeInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,34 @@ type TestTypeInformer interface {
}

type testTypeInformer struct {
factory internalinterfaces.SharedInformerFactory
factory internalinterfaces.SharedInformerFactory
tweakListOptions internalinterfaces.TweakListOptionsFunc
namespace string
}

// NewTestTypeInformer constructs a new informer for TestType 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 NewTestTypeInformer(client clientset_internalversion.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
return NewFilteredTestTypeInformer(client, namespace, resyncPeriod, indexers, nil)
}

// NewFilteredTestTypeInformer constructs a new informer for TestType 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 NewFilteredTestTypeInformer(client clientset_internalversion.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
return cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
if tweakListOptions != nil {
tweakListOptions(&options)
}
return client.Example().TestTypes(namespace).List(options)
},
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
if tweakListOptions != nil {
tweakListOptions(&options)
}
return client.Example().TestTypes(namespace).Watch(options)
},
},
Expand All @@ -60,12 +75,12 @@ func NewTestTypeInformer(client clientset_internalversion.Interface, namespace s
)
}

func defaultTestTypeInformer(client clientset_internalversion.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
return NewTestTypeInformer(client, v1.NamespaceAll, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
func (f *testTypeInformer) defaultInformer(client clientset_internalversion.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
return NewFilteredTestTypeInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
}

func (f *testTypeInformer) Informer() cache.SharedIndexInformer {
return f.factory.InformerFor(&example.TestType{}, defaultTestTypeInformer)
return f.factory.InformerFor(&example.TestType{}, f.defaultInformer)
}

func (f *testTypeInformer) Lister() internalversion.TestTypeLister {
Expand Down
20 changes: 16 additions & 4 deletions _examples/apiserver/informers/internalversion/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ limitations under the License.
package internalversion

import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
schema "k8s.io/apimachinery/pkg/runtime/schema"
cache "k8s.io/client-go/tools/cache"
Expand All @@ -31,9 +32,11 @@ import (
)

type sharedInformerFactory struct {
client internalversion.Interface
lock sync.Mutex
defaultResync time.Duration
client internalversion.Interface
namespace string
tweakListOptions internalinterfaces.TweakListOptionsFunc
lock sync.Mutex
defaultResync time.Duration

informers map[reflect.Type]cache.SharedIndexInformer
// startedInformers is used for tracking which informers have been started.
Expand All @@ -43,8 +46,17 @@ type sharedInformerFactory struct {

// NewSharedInformerFactory constructs a new instance of sharedInformerFactory
func NewSharedInformerFactory(client internalversion.Interface, defaultResync time.Duration) SharedInformerFactory {
return NewFilteredSharedInformerFactory(client, defaultResync, v1.NamespaceAll, 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 internalversion.Interface, defaultResync time.Duration, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerFactory {
return &sharedInformerFactory{
client: client,
namespace: namespace,
tweakListOptions: tweakListOptions,
defaultResync: defaultResync,
informers: make(map[reflect.Type]cache.SharedIndexInformer),
startedInformers: make(map[reflect.Type]bool),
Expand Down Expand Up @@ -114,5 +126,5 @@ type SharedInformerFactory interface {
}

func (f *sharedInformerFactory) Example() example.Interface {
return example.New(f)
return example.New(f, f.namespace, f.tweakListOptions)
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ limitations under the License.
package internalinterfaces

import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
cache "k8s.io/client-go/tools/cache"
internalversion "k8s.io/code-generator/_examples/apiserver/clientset/internalversion"
Expand All @@ -32,3 +33,5 @@ type SharedInformerFactory interface {
Start(stopCh <-chan struct{})
InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer
}

type TweakListOptionsFunc func(*v1.ListOptions)
10 changes: 6 additions & 4 deletions _examples/crd/informers/externalversions/example/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,17 @@ type Interface interface {
}

type group struct {
internalinterfaces.SharedInformerFactory
factory internalinterfaces.SharedInformerFactory
namespace string
tweakListOptions internalinterfaces.TweakListOptionsFunc
}

// New returns a new Interface.
func New(f internalinterfaces.SharedInformerFactory) Interface {
return &group{f}
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
}

// V1 returns a new v1.Interface.
func (g *group) V1() v1.Interface {
return v1.New(g.SharedInformerFactory)
return v1.New(g.factory, g.namespace, g.tweakListOptions)
}
10 changes: 6 additions & 4 deletions _examples/crd/informers/externalversions/example/v1/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,17 @@ type Interface interface {
}

type version struct {
internalinterfaces.SharedInformerFactory
factory internalinterfaces.SharedInformerFactory
namespace string
tweakListOptions internalinterfaces.TweakListOptionsFunc
}

// New returns a new Interface.
func New(f internalinterfaces.SharedInformerFactory) Interface {
return &version{f}
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
}

// TestTypes returns a TestTypeInformer.
func (v *version) TestTypes() TestTypeInformer {
return &testTypeInformer{factory: v.SharedInformerFactory}
return &testTypeInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
}
Loading

0 comments on commit 934da44

Please sign in to comment.