Simplify min/max evaluation, make limitType a type

This commit is contained in:
derekwaynecarr 2015-01-27 16:54:50 -05:00
parent 4faf27e63d
commit b19a8a61a8
7 changed files with 70 additions and 73 deletions

View File

@ -1139,17 +1139,20 @@ type List struct {
Items []runtime.Object `json:"items"` Items []runtime.Object `json:"items"`
} }
// A type of object that is limited
type LimitType string
const ( const (
// Limit that applies to all pods in a namespace // Limit that applies to all pods in a namespace
LimitTypePod string = "Pod" LimitTypePod LimitType = "Pod"
// Limit that applies to all containers in a namespace // 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 // LimitRangeItem defines a min/max usage limit for any resource that matches on kind
type LimitRangeItem struct { type LimitRangeItem struct {
// Type of resource that this limit applies to // 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 usage constraints on this kind by resource name
Max ResourceList `json:"max,omitempty"` Max ResourceList `json:"max,omitempty"`
// Min usage constraints on this kind by resource name // Min usage constraints on this kind by resource name

View File

@ -614,7 +614,7 @@ func init() {
}, },
func(in *newer.LimitRangeItem, out *LimitRangeItem, s conversion.Scope) error { func(in *newer.LimitRangeItem, out *LimitRangeItem, s conversion.Scope) error {
*out = LimitRangeItem{} *out = LimitRangeItem{}
out.Type = in.Type out.Type = LimitType(in.Type)
if err := s.Convert(&in.Max, &out.Max, 0); err != nil { if err := s.Convert(&in.Max, &out.Max, 0); err != nil {
return err return err
} }
@ -625,7 +625,7 @@ func init() {
}, },
func(in *LimitRangeItem, out *newer.LimitRangeItem, s conversion.Scope) error { func(in *LimitRangeItem, out *newer.LimitRangeItem, s conversion.Scope) error {
*out = newer.LimitRangeItem{} *out = newer.LimitRangeItem{}
out.Type = in.Type out.Type = newer.LimitType(in.Type)
if err := s.Convert(&in.Max, &out.Max, 0); err != nil { if err := s.Convert(&in.Max, &out.Max, 0); err != nil {
return err return err
} }

View File

@ -905,17 +905,20 @@ type List struct {
Items []runtime.RawExtension `json:"items" description:"list of objects"` Items []runtime.RawExtension `json:"items" description:"list of objects"`
} }
// A type of object that is limited
type LimitType string
const ( const (
// Limit that applies to all pods in a namespace // Limit that applies to all pods in a namespace
LimitTypePod string = "Pod" LimitTypePod LimitType = "Pod"
// Limit that applies to all containers in a namespace // 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 // LimitRangeItem defines a min/max usage limit for any resource that matches on kind
type LimitRangeItem struct { type LimitRangeItem struct {
// Type of resource that this limit applies to // 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 usage constraints on this kind by resource name
Max ResourceList `json:"max,omitempty"` Max ResourceList `json:"max,omitempty"`
// Min usage constraints on this kind by resource name // Min usage constraints on this kind by resource name

View File

@ -531,7 +531,7 @@ func init() {
}, },
func(in *newer.LimitRangeItem, out *LimitRangeItem, s conversion.Scope) error { func(in *newer.LimitRangeItem, out *LimitRangeItem, s conversion.Scope) error {
*out = LimitRangeItem{} *out = LimitRangeItem{}
out.Type = in.Type out.Type = LimitType(in.Type)
if err := s.Convert(&in.Max, &out.Max, 0); err != nil { if err := s.Convert(&in.Max, &out.Max, 0); err != nil {
return err return err
} }
@ -542,7 +542,7 @@ func init() {
}, },
func(in *LimitRangeItem, out *newer.LimitRangeItem, s conversion.Scope) error { func(in *LimitRangeItem, out *newer.LimitRangeItem, s conversion.Scope) error {
*out = newer.LimitRangeItem{} *out = newer.LimitRangeItem{}
out.Type = in.Type out.Type = newer.LimitType(in.Type)
if err := s.Convert(&in.Max, &out.Max, 0); err != nil { if err := s.Convert(&in.Max, &out.Max, 0); err != nil {
return err return err
} }

View File

@ -907,17 +907,20 @@ type List struct {
Items []runtime.RawExtension `json:"items" description:"list of objects"` Items []runtime.RawExtension `json:"items" description:"list of objects"`
} }
// A type of object that is limited
type LimitType string
const ( const (
// Limit that applies to all pods in a namespace // Limit that applies to all pods in a namespace
LimitTypePod string = "Pod" LimitTypePod LimitType = "Pod"
// Limit that applies to all containers in a namespace // 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 // LimitRangeItem defines a min/max usage limit for any resource that matches on kind
type LimitRangeItem struct { type LimitRangeItem struct {
// Type of resource that this limit applies to // 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 usage constraints on this kind by resource name
Max ResourceList `json:"max,omitempty"` Max ResourceList `json:"max,omitempty"`
// Min usage constraints on this kind by resource name // Min usage constraints on this kind by resource name

View File

@ -1067,17 +1067,20 @@ type List struct {
Items []runtime.RawExtension `json:"items" description:"list of objects"` Items []runtime.RawExtension `json:"items" description:"list of objects"`
} }
// A type of object that is limited
type LimitType string
const ( const (
// Limit that applies to all pods in a namespace // Limit that applies to all pods in a namespace
LimitTypePod string = "Pod" LimitTypePod LimitType = "Pod"
// Limit that applies to all containers in a namespace // 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 // LimitRangeItem defines a min/max usage limit for any resource that matches on kind
type LimitRangeItem struct { type LimitRangeItem struct {
// Type of resource that this limit applies to // 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 usage constraints on this kind by resource name
Max ResourceList `json:"max,omitempty"` Max ResourceList `json:"max,omitempty"`
// Min usage constraints on this kind by resource name // Min usage constraints on this kind by resource name

View File

@ -49,6 +49,7 @@ func (l *limitRanger) Admit(a admission.Attributes) (err error) {
} }
// look for a limit range in current namespace that requires enforcement // 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()) items, err := l.client.LimitRanges(a.GetNamespace()).List(labels.Everything())
if err != nil { if err != nil {
return err return err
@ -123,68 +124,52 @@ func PodLimitFunc(limitRange *api.LimitRange, kind string, obj runtime.Object) e
for i := range limitRange.Spec.Limits { for i := range limitRange.Spec.Limits {
limit := limitRange.Spec.Limits[i] limit := limitRange.Spec.Limits[i]
// enforce max for _, minOrMax := range []string{"Min", "Max"} {
for k, v := range limit.Max { var rl api.ResourceList
observed := int64(0) switch minOrMax {
enforced := int64(0) case "Min":
var err error rl = limit.Min
switch k { case "Max":
case api.ResourceMemory: rl = limit.Max
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())
}
} }
if observed > enforced { for k, v := range rl {
return apierrors.NewForbidden(kind, pod.Name, err) observed := int64(0)
} enforced := int64(0)
} var err error
for k, v := range limit.Min { switch k {
observed := int64(0) case api.ResourceMemory:
enforced := int64(0) enforced = v.Value()
var err error switch limit.Type {
switch k { case api.LimitTypePod:
case api.ResourceMemory: observed = podMem
enforced = v.Value() err = fmt.Errorf("%simum memory usage per pod is %s", minOrMax, v.String())
switch limit.Type { case api.LimitTypeContainer:
case api.LimitTypePod: observed = maxContainerMem
observed = podMem err = fmt.Errorf("%simum memory usage per container is %s", minOrMax, v.String())
err = fmt.Errorf("Minimum memory usage per pod is %s", v.String()) }
case api.LimitTypeContainer: case api.ResourceCPU:
observed = maxContainerMem enforced = v.MilliValue()
err = fmt.Errorf("Minimum memory usage per container is %s", v.String()) 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: switch minOrMax {
enforced = v.MilliValue() case "Min":
switch limit.Type { if observed < enforced {
case api.LimitTypePod: return apierrors.NewForbidden(kind, pod.Name, err)
observed = podCPU }
err = fmt.Errorf("Minimum CPU usage per pod is %s", v.String()) case "Max":
case api.LimitTypeContainer: if observed > enforced {
observed = maxContainerCPU return apierrors.NewForbidden(kind, pod.Name, err)
err = fmt.Errorf("Minimum CPU usage per container is %s", v.String()) }
} }
} }
if observed < enforced {
return apierrors.NewForbidden(kind, pod.Name, err)
}
} }
} }
return nil return nil
} }