From b19a8a61a86e0ffefb9d94fb39a54d92e134bfbf Mon Sep 17 00:00:00 2001 From: derekwaynecarr Date: Tue, 27 Jan 2015 16:54:50 -0500 Subject: [PATCH] Simplify min/max evaluation, make limitType a type --- pkg/api/types.go | 9 +- pkg/api/v1beta1/conversion.go | 4 +- pkg/api/v1beta1/types.go | 9 +- pkg/api/v1beta2/conversion.go | 4 +- pkg/api/v1beta2/types.go | 9 +- pkg/api/v1beta3/types.go | 9 +- plugin/pkg/admission/limitranger/admission.go | 99 ++++++++----------- 7 files changed, 70 insertions(+), 73 deletions(-) diff --git a/pkg/api/types.go b/pkg/api/types.go index a9e6694fc7c..7a85d4209fb 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -1139,17 +1139,20 @@ type List struct { Items []runtime.Object `json:"items"` } +// A type of object that is limited +type LimitType string + const ( // Limit that applies to all pods in a namespace - LimitTypePod string = "Pod" + LimitTypePod LimitType = "Pod" // Limit that applies to all containers in a namespace - LimitTypeContainer string = "Container" + LimitTypeContainer LimitType = "Container" ) // LimitRangeItem defines a min/max usage limit for any resource that matches on kind type LimitRangeItem struct { // Type of resource that this limit applies to - Type string `json:"type,omitempty"` + Type LimitType `json:"type,omitempty"` // Max usage constraints on this kind by resource name Max ResourceList `json:"max,omitempty"` // Min usage constraints on this kind by resource name diff --git a/pkg/api/v1beta1/conversion.go b/pkg/api/v1beta1/conversion.go index 309afcdb7ef..3e581da3d9a 100644 --- a/pkg/api/v1beta1/conversion.go +++ b/pkg/api/v1beta1/conversion.go @@ -614,7 +614,7 @@ func init() { }, func(in *newer.LimitRangeItem, out *LimitRangeItem, s conversion.Scope) error { *out = LimitRangeItem{} - out.Type = in.Type + out.Type = LimitType(in.Type) if err := s.Convert(&in.Max, &out.Max, 0); err != nil { return err } @@ -625,7 +625,7 @@ func init() { }, func(in *LimitRangeItem, out *newer.LimitRangeItem, s conversion.Scope) error { *out = newer.LimitRangeItem{} - out.Type = in.Type + out.Type = newer.LimitType(in.Type) if err := s.Convert(&in.Max, &out.Max, 0); err != nil { return err } diff --git a/pkg/api/v1beta1/types.go b/pkg/api/v1beta1/types.go index 0cb70ddd008..e45d135a191 100644 --- a/pkg/api/v1beta1/types.go +++ b/pkg/api/v1beta1/types.go @@ -905,17 +905,20 @@ type List struct { Items []runtime.RawExtension `json:"items" description:"list of objects"` } +// A type of object that is limited +type LimitType string + const ( // Limit that applies to all pods in a namespace - LimitTypePod string = "Pod" + LimitTypePod LimitType = "Pod" // Limit that applies to all containers in a namespace - LimitTypeContainer string = "Container" + LimitTypeContainer LimitType = "Container" ) // LimitRangeItem defines a min/max usage limit for any resource that matches on kind type LimitRangeItem struct { // Type of resource that this limit applies to - Type string `json:"type,omitempty"` + Type LimitType `json:"type,omitempty"` // Max usage constraints on this kind by resource name Max ResourceList `json:"max,omitempty"` // Min usage constraints on this kind by resource name diff --git a/pkg/api/v1beta2/conversion.go b/pkg/api/v1beta2/conversion.go index 6c69682251a..d373212c516 100644 --- a/pkg/api/v1beta2/conversion.go +++ b/pkg/api/v1beta2/conversion.go @@ -531,7 +531,7 @@ func init() { }, func(in *newer.LimitRangeItem, out *LimitRangeItem, s conversion.Scope) error { *out = LimitRangeItem{} - out.Type = in.Type + out.Type = LimitType(in.Type) if err := s.Convert(&in.Max, &out.Max, 0); err != nil { return err } @@ -542,7 +542,7 @@ func init() { }, func(in *LimitRangeItem, out *newer.LimitRangeItem, s conversion.Scope) error { *out = newer.LimitRangeItem{} - out.Type = in.Type + out.Type = newer.LimitType(in.Type) if err := s.Convert(&in.Max, &out.Max, 0); err != nil { return err } diff --git a/pkg/api/v1beta2/types.go b/pkg/api/v1beta2/types.go index f584bc5b75f..a19f11cbd2f 100644 --- a/pkg/api/v1beta2/types.go +++ b/pkg/api/v1beta2/types.go @@ -907,17 +907,20 @@ type List struct { Items []runtime.RawExtension `json:"items" description:"list of objects"` } +// A type of object that is limited +type LimitType string + const ( // Limit that applies to all pods in a namespace - LimitTypePod string = "Pod" + LimitTypePod LimitType = "Pod" // Limit that applies to all containers in a namespace - LimitTypeContainer string = "Container" + LimitTypeContainer LimitType = "Container" ) // LimitRangeItem defines a min/max usage limit for any resource that matches on kind type LimitRangeItem struct { // Type of resource that this limit applies to - Type string `json:"type,omitempty"` + Type LimitType `json:"type,omitempty"` // Max usage constraints on this kind by resource name Max ResourceList `json:"max,omitempty"` // Min usage constraints on this kind by resource name diff --git a/pkg/api/v1beta3/types.go b/pkg/api/v1beta3/types.go index 1e7b76c8a9d..314521b6618 100644 --- a/pkg/api/v1beta3/types.go +++ b/pkg/api/v1beta3/types.go @@ -1067,17 +1067,20 @@ type List struct { Items []runtime.RawExtension `json:"items" description:"list of objects"` } +// A type of object that is limited +type LimitType string + const ( // Limit that applies to all pods in a namespace - LimitTypePod string = "Pod" + LimitTypePod LimitType = "Pod" // Limit that applies to all containers in a namespace - LimitTypeContainer string = "Container" + LimitTypeContainer LimitType = "Container" ) // LimitRangeItem defines a min/max usage limit for any resource that matches on kind type LimitRangeItem struct { // Type of resource that this limit applies to - Type string `json:"type,omitempty"` + Type LimitType `json:"type,omitempty"` // Max usage constraints on this kind by resource name Max ResourceList `json:"max,omitempty"` // Min usage constraints on this kind by resource name diff --git a/plugin/pkg/admission/limitranger/admission.go b/plugin/pkg/admission/limitranger/admission.go index a404e25abda..5af414cd5a8 100644 --- a/plugin/pkg/admission/limitranger/admission.go +++ b/plugin/pkg/admission/limitranger/admission.go @@ -49,6 +49,7 @@ func (l *limitRanger) Admit(a admission.Attributes) (err error) { } // look for a limit range in current namespace that requires enforcement + // TODO: Move to cache when issue is resolved: https://github.com/GoogleCloudPlatform/kubernetes/issues/2294 items, err := l.client.LimitRanges(a.GetNamespace()).List(labels.Everything()) if err != nil { return err @@ -123,68 +124,52 @@ func PodLimitFunc(limitRange *api.LimitRange, kind string, obj runtime.Object) e for i := range limitRange.Spec.Limits { limit := limitRange.Spec.Limits[i] - // enforce max - for k, v := range limit.Max { - observed := int64(0) - enforced := int64(0) - var err error - switch k { - case api.ResourceMemory: - enforced = v.Value() - switch limit.Type { - case api.LimitTypePod: - observed = podMem - err = fmt.Errorf("Maximum memory usage per pod is %s", v.String()) - case api.LimitTypeContainer: - observed = maxContainerMem - err = fmt.Errorf("Maximum memory usage per container is %s", v.String()) - } - case api.ResourceCPU: - enforced = v.MilliValue() - switch limit.Type { - case api.LimitTypePod: - observed = podCPU - err = fmt.Errorf("Maximum CPU usage per pod is %s, but requested %s", v.String(), resource.NewMilliQuantity(observed, resource.DecimalSI)) - case api.LimitTypeContainer: - observed = maxContainerCPU - err = fmt.Errorf("Maximum CPU usage per container is %s", v.String()) - } + for _, minOrMax := range []string{"Min", "Max"} { + var rl api.ResourceList + switch minOrMax { + case "Min": + rl = limit.Min + case "Max": + rl = limit.Max } - if observed > enforced { - return apierrors.NewForbidden(kind, pod.Name, err) - } - } - for k, v := range limit.Min { - observed := int64(0) - enforced := int64(0) - var err error - switch k { - case api.ResourceMemory: - enforced = v.Value() - switch limit.Type { - case api.LimitTypePod: - observed = podMem - err = fmt.Errorf("Minimum memory usage per pod is %s", v.String()) - case api.LimitTypeContainer: - observed = maxContainerMem - err = fmt.Errorf("Minimum memory usage per container is %s", v.String()) + for k, v := range rl { + observed := int64(0) + enforced := int64(0) + var err error + switch k { + case api.ResourceMemory: + enforced = v.Value() + switch limit.Type { + case api.LimitTypePod: + observed = podMem + err = fmt.Errorf("%simum memory usage per pod is %s", minOrMax, v.String()) + case api.LimitTypeContainer: + observed = maxContainerMem + err = fmt.Errorf("%simum memory usage per container is %s", minOrMax, v.String()) + } + case api.ResourceCPU: + enforced = v.MilliValue() + switch limit.Type { + case api.LimitTypePod: + observed = podCPU + err = fmt.Errorf("%simum CPU usage per pod is %s, but requested %s", minOrMax, v.String(), resource.NewMilliQuantity(observed, resource.DecimalSI)) + case api.LimitTypeContainer: + observed = maxContainerCPU + err = fmt.Errorf("%simum CPU usage per container is %s", minOrMax, v.String()) + } } - case api.ResourceCPU: - enforced = v.MilliValue() - switch limit.Type { - case api.LimitTypePod: - observed = podCPU - err = fmt.Errorf("Minimum CPU usage per pod is %s", v.String()) - case api.LimitTypeContainer: - observed = maxContainerCPU - err = fmt.Errorf("Minimum CPU usage per container is %s", v.String()) + switch minOrMax { + case "Min": + if observed < enforced { + return apierrors.NewForbidden(kind, pod.Name, err) + } + case "Max": + if observed > enforced { + return apierrors.NewForbidden(kind, pod.Name, err) + } } } - if observed < enforced { - return apierrors.NewForbidden(kind, pod.Name, err) - } } } - return nil }