mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-31 23:37:01 +00:00
Merge pull request #23280 from pweil-/limitrange-supportsfunc
Auto commit by PR queue bot
This commit is contained in:
commit
6441e1fc33
@ -43,16 +43,16 @@ const (
|
||||
|
||||
func init() {
|
||||
admission.RegisterPlugin("LimitRanger", func(client clientset.Interface, config io.Reader) (admission.Interface, error) {
|
||||
return NewLimitRanger(client, Limit)
|
||||
return NewLimitRanger(client, &DefaultLimitRangerActions{})
|
||||
})
|
||||
}
|
||||
|
||||
// limitRanger enforces usage limits on a per resource basis in the namespace
|
||||
type limitRanger struct {
|
||||
*admission.Handler
|
||||
client clientset.Interface
|
||||
limitFunc LimitFunc
|
||||
indexer cache.Indexer
|
||||
client clientset.Interface
|
||||
actions LimitRangerActions
|
||||
indexer cache.Indexer
|
||||
|
||||
// liveLookups holds the last few live lookups we've done to help ammortize cost on repeated lookup failures.
|
||||
// This let's us handle the case of latent caches, by looking up actual results for a namespace on cache miss/no results.
|
||||
@ -68,14 +68,7 @@ type liveLookupEntry struct {
|
||||
|
||||
// Admit admits resources into cluster that do not violate any defined LimitRange in the namespace
|
||||
func (l *limitRanger) Admit(a admission.Attributes) (err error) {
|
||||
|
||||
// Ignore all calls to subresources
|
||||
if a.GetSubresource() != "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ignore all calls that do not deal with pod resources since that is all this supports now.
|
||||
if a.GetKind() != api.Kind("Pod") {
|
||||
if !l.actions.SupportsAttributes(a) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -130,7 +123,12 @@ func (l *limitRanger) Admit(a admission.Attributes) (err error) {
|
||||
// ensure it meets each prescribed min/max
|
||||
for i := range items {
|
||||
limitRange := items[i].(*api.LimitRange)
|
||||
err = l.limitFunc(limitRange, a.GetResource().Resource, a.GetObject())
|
||||
|
||||
if !l.actions.SupportsLimit(limitRange) {
|
||||
continue
|
||||
}
|
||||
|
||||
err = l.actions.Limit(limitRange, a.GetResource().Resource, a.GetObject())
|
||||
if err != nil {
|
||||
return admission.NewForbidden(a, err)
|
||||
}
|
||||
@ -139,7 +137,7 @@ func (l *limitRanger) Admit(a admission.Attributes) (err error) {
|
||||
}
|
||||
|
||||
// NewLimitRanger returns an object that enforces limits based on the supplied limit function
|
||||
func NewLimitRanger(client clientset.Interface, limitFunc LimitFunc) (admission.Interface, error) {
|
||||
func NewLimitRanger(client clientset.Interface, actions LimitRangerActions) (admission.Interface, error) {
|
||||
liveLookupCache, err := lru.New(10000)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -155,10 +153,15 @@ func NewLimitRanger(client clientset.Interface, limitFunc LimitFunc) (admission.
|
||||
}
|
||||
indexer, reflector := cache.NewNamespaceKeyedIndexerAndReflector(lw, &api.LimitRange{}, 0)
|
||||
reflector.Run()
|
||||
|
||||
if actions == nil {
|
||||
actions = &DefaultLimitRangerActions{}
|
||||
}
|
||||
|
||||
return &limitRanger{
|
||||
Handler: admission.NewHandler(admission.Create, admission.Update),
|
||||
client: client,
|
||||
limitFunc: limitFunc,
|
||||
actions: actions,
|
||||
indexer: indexer,
|
||||
liveLookupCache: liveLookupCache,
|
||||
liveTTL: time.Duration(30 * time.Second),
|
||||
@ -181,17 +184,6 @@ func Max(a int64, b int64) int64 {
|
||||
return b
|
||||
}
|
||||
|
||||
// Limit enforces resource requirements of incoming resources against enumerated constraints
|
||||
// on the LimitRange. It may modify the incoming object to apply default resource requirements
|
||||
// if not specified, and enumerated on the LimitRange
|
||||
func Limit(limitRange *api.LimitRange, resourceName string, obj runtime.Object) error {
|
||||
switch resourceName {
|
||||
case "pods":
|
||||
return PodLimitFunc(limitRange, obj.(*api.Pod))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// defaultContainerResourceRequirements returns the default requirements for a container
|
||||
// the requirement.Limits are taken from the LimitRange defaults (if specified)
|
||||
// the requirement.Requests are taken from the LimitRange default request (if specified)
|
||||
@ -383,6 +375,38 @@ func sum(inputs []api.ResourceList) api.ResourceList {
|
||||
return result
|
||||
}
|
||||
|
||||
// DefaultLimitRangerActions is the default implementatation of LimitRangerActions.
|
||||
type DefaultLimitRangerActions struct{}
|
||||
|
||||
// ensure DefaultLimitRangerActions implements the LimitRangerActions interface.
|
||||
var _ LimitRangerActions = &DefaultLimitRangerActions{}
|
||||
|
||||
// Limit enforces resource requirements of incoming resources against enumerated constraints
|
||||
// on the LimitRange. It may modify the incoming object to apply default resource requirements
|
||||
// if not specified, and enumerated on the LimitRange
|
||||
func (d *DefaultLimitRangerActions) Limit(limitRange *api.LimitRange, resourceName string, obj runtime.Object) error {
|
||||
switch resourceName {
|
||||
case "pods":
|
||||
return PodLimitFunc(limitRange, obj.(*api.Pod))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SupportsAttributes ignores all calls that do not deal with pod resources since that is
|
||||
// all this supports now. Also ignores any call that has a subresource defined.
|
||||
func (d *DefaultLimitRangerActions) SupportsAttributes(a admission.Attributes) bool {
|
||||
if a.GetSubresource() != "" {
|
||||
return false
|
||||
}
|
||||
|
||||
return a.GetKind() == api.Kind("Pod")
|
||||
}
|
||||
|
||||
// SupportsLimit always returns true.
|
||||
func (d *DefaultLimitRangerActions) SupportsLimit(limitRange *api.LimitRange) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// PodLimitFunc enforces resource requirements enumerated by the pod against
|
||||
// the specified LimitRange. The pod may be modified to apply default resource
|
||||
// requirements if not specified, and enumerated on the LimitRange
|
||||
|
@ -435,10 +435,10 @@ func TestLimitRangerIgnoresSubresource(t *testing.T) {
|
||||
client := fake.NewSimpleClientset()
|
||||
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{"namespace": cache.MetaNamespaceIndexFunc})
|
||||
handler := &limitRanger{
|
||||
Handler: admission.NewHandler(admission.Create, admission.Update),
|
||||
client: client,
|
||||
limitFunc: Limit,
|
||||
indexer: indexer,
|
||||
Handler: admission.NewHandler(admission.Create, admission.Update),
|
||||
client: client,
|
||||
actions: &DefaultLimitRangerActions{},
|
||||
indexer: indexer,
|
||||
}
|
||||
|
||||
limitRange := validLimitRangeNoDefaults()
|
||||
@ -468,7 +468,7 @@ func TestLimitRangerCacheMisses(t *testing.T) {
|
||||
handler := &limitRanger{
|
||||
Handler: admission.NewHandler(admission.Create, admission.Update),
|
||||
client: client,
|
||||
limitFunc: Limit,
|
||||
actions: &DefaultLimitRangerActions{},
|
||||
indexer: indexer,
|
||||
liveLookupCache: liveLookupCache,
|
||||
}
|
||||
@ -502,7 +502,7 @@ func TestLimitRangerCacheAndLRUMisses(t *testing.T) {
|
||||
handler := &limitRanger{
|
||||
Handler: admission.NewHandler(admission.Create, admission.Update),
|
||||
client: client,
|
||||
limitFunc: Limit,
|
||||
actions: &DefaultLimitRangerActions{},
|
||||
indexer: indexer,
|
||||
liveLookupCache: liveLookupCache,
|
||||
}
|
||||
@ -532,7 +532,7 @@ func TestLimitRangerCacheAndLRUExpiredMisses(t *testing.T) {
|
||||
handler := &limitRanger{
|
||||
Handler: admission.NewHandler(admission.Create, admission.Update),
|
||||
client: client,
|
||||
limitFunc: Limit,
|
||||
actions: &DefaultLimitRangerActions{},
|
||||
indexer: indexer,
|
||||
liveLookupCache: liveLookupCache,
|
||||
}
|
||||
|
@ -17,9 +17,18 @@ limitations under the License.
|
||||
package limitranger
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/admission"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
// LimitFunc is a pluggable function to enforce limits on the object
|
||||
type LimitFunc func(limitRange *api.LimitRange, kind string, obj runtime.Object) error
|
||||
type LimitRangerActions interface {
|
||||
// Limit is a pluggable function to enforce limits on the object.
|
||||
Limit(limitRange *api.LimitRange, kind string, obj runtime.Object) error
|
||||
// SupportsAttributes is a pluggable function to allow overridding what resources the limitranger
|
||||
// supports.
|
||||
SupportsAttributes(attr admission.Attributes) bool
|
||||
// SupportsLimit is a pluggable function to allow ignoring limits that should not be applied
|
||||
// for any reason.
|
||||
SupportsLimit(limitRange *api.LimitRange) bool
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user