mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-01-05 07:27:21 +00:00
Merge pull request #26709 from hodovska/master
Automatic merge from submit-queue Allow shareable resources for admission control plugins. Changes allow admission control plugins to share resources. This is done via new PluginInitialization structure. The structure can be extended for other resources, for now it is an shared informer for namespace plugins (NamespiceLifecycle, NamespaceAutoProvisioning, NamespaceExists). If a plugins needs some kind of shared resource e.g. client, the client shall be added to PluginInitializer and Wants methods implemented to every plugin which will use it.
This commit is contained in:
273
pkg/controller/framework/informers/core.go
Normal file
273
pkg/controller/framework/informers/core.go
Normal file
@@ -0,0 +1,273 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package informers
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/client/cache"
|
||||
"k8s.io/kubernetes/pkg/controller/framework"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// PodInformer is type of SharedIndexInformer which watches and lists all pods.
|
||||
// Interface provides constructor for informer and lister for pods
|
||||
type PodInformer interface {
|
||||
Informer() framework.SharedIndexInformer
|
||||
Lister() *cache.StoreToPodLister
|
||||
}
|
||||
|
||||
type podInformer struct {
|
||||
*sharedInformerFactory
|
||||
}
|
||||
|
||||
// Informer checks whether podInformer exists in sharedInformerFactory and if not, it creates new informer of type
|
||||
// podInformer and connects it to sharedInformerFactory
|
||||
func (f *podInformer) Informer() framework.SharedIndexInformer {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
|
||||
informerObj := &api.Pod{}
|
||||
informerType := reflect.TypeOf(informerObj)
|
||||
informer, exists := f.informers[informerType]
|
||||
if exists {
|
||||
return informer
|
||||
}
|
||||
|
||||
informer = framework.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options api.ListOptions) (runtime.Object, error) {
|
||||
return f.client.Core().Pods(api.NamespaceAll).List(options)
|
||||
},
|
||||
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
|
||||
return f.client.Core().Pods(api.NamespaceAll).Watch(options)
|
||||
},
|
||||
},
|
||||
informerObj,
|
||||
f.defaultResync,
|
||||
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
|
||||
)
|
||||
f.informers[informerType] = informer
|
||||
|
||||
return informer
|
||||
}
|
||||
|
||||
// Lister returns lister for podInformer
|
||||
func (f *podInformer) Lister() *cache.StoreToPodLister {
|
||||
informer := f.Informer()
|
||||
return &cache.StoreToPodLister{Indexer: informer.GetIndexer()}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
|
||||
// NamespaceInformer is type of SharedIndexInformer which watches and lists all namespaces.
|
||||
// Interface provides constructor for informer and lister for namsespaces
|
||||
type NamespaceInformer interface {
|
||||
Informer() framework.SharedIndexInformer
|
||||
Lister() *cache.IndexerToNamespaceLister
|
||||
}
|
||||
|
||||
type namespaceInformer struct {
|
||||
*sharedInformerFactory
|
||||
}
|
||||
|
||||
// Informer checks whether namespaceInformer exists in sharedInformerFactory and if not, it creates new informer of type
|
||||
// namespaceInformer and connects it to sharedInformerFactory
|
||||
func (f *namespaceInformer) Informer() framework.SharedIndexInformer {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
informerObj := &api.Namespace{}
|
||||
informerType := reflect.TypeOf(informerObj)
|
||||
informer, exists := f.informers[informerType]
|
||||
if exists {
|
||||
return informer
|
||||
}
|
||||
informer = framework.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options api.ListOptions) (runtime.Object, error) {
|
||||
return f.client.Core().Namespaces().List(options)
|
||||
},
|
||||
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
|
||||
return f.client.Core().Namespaces().Watch(options)
|
||||
},
|
||||
},
|
||||
informerObj,
|
||||
f.defaultResync,
|
||||
cache.Indexers{},
|
||||
)
|
||||
f.informers[informerType] = informer
|
||||
|
||||
return informer
|
||||
}
|
||||
|
||||
// Lister returns lister for namespaceInformer
|
||||
func (f *namespaceInformer) Lister() *cache.IndexerToNamespaceLister {
|
||||
informer := f.Informer()
|
||||
return &cache.IndexerToNamespaceLister{Indexer: informer.GetIndexer()}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
|
||||
// NodeInformer is type of SharedIndexInformer which watches and lists all nodes.
|
||||
// Interface provides constructor for informer and lister for nodes
|
||||
type NodeInformer interface {
|
||||
Informer() framework.SharedIndexInformer
|
||||
Lister() *cache.StoreToNodeLister
|
||||
}
|
||||
|
||||
type nodeInformer struct {
|
||||
*sharedInformerFactory
|
||||
}
|
||||
|
||||
// Informer checks whether nodeInformer exists in sharedInformerFactory and if not, it creates new informer of type
|
||||
// nodeInformer and connects it to sharedInformerFactory
|
||||
func (f *nodeInformer) Informer() framework.SharedIndexInformer {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
|
||||
informerObj := &api.Node{}
|
||||
informerType := reflect.TypeOf(informerObj)
|
||||
informer, exists := f.informers[informerType]
|
||||
if exists {
|
||||
return informer
|
||||
}
|
||||
|
||||
informer = framework.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options api.ListOptions) (runtime.Object, error) {
|
||||
return f.client.Core().Nodes().List(options)
|
||||
},
|
||||
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
|
||||
return f.client.Core().Nodes().Watch(options)
|
||||
},
|
||||
},
|
||||
informerObj,
|
||||
f.defaultResync,
|
||||
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
|
||||
)
|
||||
f.informers[informerType] = informer
|
||||
|
||||
return informer
|
||||
}
|
||||
|
||||
// Lister returns lister for nodeInformer
|
||||
func (f *nodeInformer) Lister() *cache.StoreToNodeLister {
|
||||
informer := f.Informer()
|
||||
return &cache.StoreToNodeLister{Store: informer.GetStore()}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
|
||||
// PVCInformer is type of SharedIndexInformer which watches and lists all persistent volume claims.
|
||||
// Interface provides constructor for informer and lister for persistent volume claims
|
||||
type PVCInformer interface {
|
||||
Informer() framework.SharedIndexInformer
|
||||
Lister() *cache.StoreToPVCFetcher
|
||||
}
|
||||
|
||||
type pvcInformer struct {
|
||||
*sharedInformerFactory
|
||||
}
|
||||
|
||||
// Informer checks whether pvcInformer exists in sharedInformerFactory and if not, it creates new informer of type
|
||||
// pvcInformer and connects it to sharedInformerFactory
|
||||
func (f *pvcInformer) Informer() framework.SharedIndexInformer {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
|
||||
informerObj := &api.PersistentVolumeClaim{}
|
||||
informerType := reflect.TypeOf(informerObj)
|
||||
informer, exists := f.informers[informerType]
|
||||
if exists {
|
||||
return informer
|
||||
}
|
||||
|
||||
informer = framework.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options api.ListOptions) (runtime.Object, error) {
|
||||
return f.client.Core().PersistentVolumeClaims(api.NamespaceAll).List(options)
|
||||
},
|
||||
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
|
||||
return f.client.Core().PersistentVolumeClaims(api.NamespaceAll).Watch(options)
|
||||
},
|
||||
},
|
||||
informerObj,
|
||||
f.defaultResync,
|
||||
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
|
||||
)
|
||||
f.informers[informerType] = informer
|
||||
|
||||
return informer
|
||||
}
|
||||
|
||||
// Lister returns lister for pvcInformer
|
||||
func (f *pvcInformer) Lister() *cache.StoreToPVCFetcher {
|
||||
informer := f.Informer()
|
||||
return &cache.StoreToPVCFetcher{Store: informer.GetStore()}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
|
||||
// PVInformer is type of SharedIndexInformer which watches and lists all persistent volumes.
|
||||
// Interface provides constructor for informer and lister for persistent volumes
|
||||
type PVInformer interface {
|
||||
Informer() framework.SharedIndexInformer
|
||||
Lister() *cache.StoreToPVFetcher
|
||||
}
|
||||
|
||||
type pvInformer struct {
|
||||
*sharedInformerFactory
|
||||
}
|
||||
|
||||
// Informer checks whether pvInformer exists in sharedInformerFactory and if not, it creates new informer of type
|
||||
// pvInformer and connects it to sharedInformerFactory
|
||||
func (f *pvInformer) Informer() framework.SharedIndexInformer {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
|
||||
informerObj := &api.PersistentVolume{}
|
||||
informerType := reflect.TypeOf(informerObj)
|
||||
informer, exists := f.informers[informerType]
|
||||
if exists {
|
||||
return informer
|
||||
}
|
||||
|
||||
informer = framework.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options api.ListOptions) (runtime.Object, error) {
|
||||
return f.client.Core().PersistentVolumes().List(options)
|
||||
},
|
||||
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
|
||||
return f.client.Core().PersistentVolumes().Watch(options)
|
||||
},
|
||||
},
|
||||
informerObj,
|
||||
f.defaultResync,
|
||||
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
|
||||
)
|
||||
f.informers[informerType] = informer
|
||||
|
||||
return informer
|
||||
}
|
||||
|
||||
// Lister returns lister for pvInformer
|
||||
func (f *pvInformer) Lister() *cache.StoreToPVFetcher {
|
||||
informer := f.Informer()
|
||||
return &cache.StoreToPVFetcher{Store: informer.GetStore()}
|
||||
}
|
||||
@@ -17,6 +17,8 @@ limitations under the License.
|
||||
package informers
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
@@ -27,6 +29,70 @@ import (
|
||||
"k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// SharedInformerFactory provides interface which holds unique informers for pods, nodes, namespaces, persistent volume
|
||||
// claims and persistent volumes
|
||||
type SharedInformerFactory interface {
|
||||
// Start starts informers that can start AFTER the API server and controllers have started
|
||||
Start(stopCh <-chan struct{})
|
||||
|
||||
Pods() PodInformer
|
||||
Nodes() NodeInformer
|
||||
Namespaces() NamespaceInformer
|
||||
PersistentVolumeClaims() PVCInformer
|
||||
PersistentVolumes() PVInformer
|
||||
}
|
||||
|
||||
type sharedInformerFactory struct {
|
||||
client clientset.Interface
|
||||
lock sync.Mutex
|
||||
defaultResync time.Duration
|
||||
informers map[reflect.Type]framework.SharedIndexInformer
|
||||
}
|
||||
|
||||
// NewSharedInformerFactory constructs a new instance of sharedInformerFactory
|
||||
func NewSharedInformerFactory(client clientset.Interface, defaultResync time.Duration) SharedInformerFactory {
|
||||
return &sharedInformerFactory{
|
||||
client: client,
|
||||
defaultResync: defaultResync,
|
||||
informers: make(map[reflect.Type]framework.SharedIndexInformer),
|
||||
}
|
||||
}
|
||||
|
||||
// Start initializes all requested informers.
|
||||
func (s *sharedInformerFactory) Start(stopCh <-chan struct{}) {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
|
||||
for _, informer := range s.informers {
|
||||
go informer.Run(stopCh)
|
||||
}
|
||||
}
|
||||
|
||||
// Pods returns a SharedIndexInformer that lists and watches all pods
|
||||
func (f *sharedInformerFactory) Pods() PodInformer {
|
||||
return &podInformer{sharedInformerFactory: f}
|
||||
}
|
||||
|
||||
// Nodes returns a SharedIndexInformer that lists and watches all nodes
|
||||
func (f *sharedInformerFactory) Nodes() NodeInformer {
|
||||
return &nodeInformer{sharedInformerFactory: f}
|
||||
}
|
||||
|
||||
// Namespaces returns a SharedIndexInformer that lists and watches all namespaces
|
||||
func (f *sharedInformerFactory) Namespaces() NamespaceInformer {
|
||||
return &namespaceInformer{sharedInformerFactory: f}
|
||||
}
|
||||
|
||||
// PersistentVolumeClaims returns a SharedIndexInformer that lists and watches all persistent volume claims
|
||||
func (f *sharedInformerFactory) PersistentVolumeClaims() PVCInformer {
|
||||
return &pvcInformer{sharedInformerFactory: f}
|
||||
}
|
||||
|
||||
// PersistentVolumes returns a SharedIndexInformer that lists and watches all persistent volumes
|
||||
func (f *sharedInformerFactory) PersistentVolumes() PVInformer {
|
||||
return &pvInformer{sharedInformerFactory: f}
|
||||
}
|
||||
|
||||
// CreateSharedPodInformer returns a SharedIndexInformer that lists and watches all pods
|
||||
func CreateSharedPodInformer(client clientset.Interface, resyncPeriod time.Duration) framework.SharedIndexInformer {
|
||||
sharedInformer := framework.NewSharedIndexInformer(
|
||||
@@ -118,3 +184,21 @@ func CreateSharedPVIndexInformer(client clientset.Interface, resyncPeriod time.D
|
||||
|
||||
return sharedIndexInformer
|
||||
}
|
||||
|
||||
// CreateSharedNamespaceIndexInformer returns a SharedIndexInformer that lists and watches namespaces
|
||||
func CreateSharedNamespaceIndexInformer(client clientset.Interface, resyncPeriod time.Duration) framework.SharedIndexInformer {
|
||||
sharedIndexInformer := framework.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options api.ListOptions) (runtime.Object, error) {
|
||||
return client.Core().Namespaces().List(options)
|
||||
},
|
||||
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
|
||||
return client.Core().Namespaces().Watch(options)
|
||||
},
|
||||
},
|
||||
&api.Namespace{},
|
||||
resyncPeriod,
|
||||
cache.Indexers{})
|
||||
|
||||
return sharedIndexInformer
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user