Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Admission Control: LimitRange #3751

Merged
merged 6 commits into from
Jan 27, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions cmd/kube-apiserver/plugins.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,6 @@ import (

_ "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/admit"
_ "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/deny"
_ "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/limitranger"
_ "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/admission/resourcedefaults"
)
18 changes: 18 additions & 0 deletions examples/limitrange/invalid-pod.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"id": "invalid-pod",
"kind": "Pod",
"apiVersion":"v1beta2",
"labels": {
"name": "invalid-pod"
},
"desiredState": {
"manifest": {
"version": "v1beta1",
"id": "invalid-pod",
"containers": [{
"name": "kubernetes-serve-hostname",
"image": "kubernetes/serve_hostname",
}]
}
},
}
31 changes: 31 additions & 0 deletions examples/limitrange/limit-range.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"id": "limits",
"kind": "LimitRange",
"apiVersion": "v1beta1",
"spec": {
"limits": [
{
"type": "Pod",
"max": {
"memory": "1073741824",
"cpu": "2",
},
"min": {
"memory": "1048576",
"cpu": "0.25"
}
},
{
"type": "Container",
"max": {
"memory": "1073741824",
"cpu": "2",
},
"min": {
"memory": "1048576",
"cpu": "0.25"
}
},
],
}
}
20 changes: 20 additions & 0 deletions examples/limitrange/valid-pod.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"id": "valid-pod",
"kind": "Pod",
"apiVersion":"v1beta2",
"labels": {
"name": "valid-pod"
},
"desiredState": {
"manifest": {
"version": "v1beta1",
"id": "invalid-pod",
"containers": [{
"name": "kubernetes-serve-hostname",
"image": "kubernetes/serve_hostname",
"cpu": 1000,
"memory": 1048576,
}]
}
},
}
4 changes: 4 additions & 0 deletions pkg/api/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ func init() {
&BoundPod{},
&BoundPods{},
&List{},
&LimitRange{},
&LimitRangeList{},
)
// Legacy names are supported
Scheme.AddKnownTypeWithName("", "Minion", &Node{})
Expand Down Expand Up @@ -77,3 +79,5 @@ func (*ContainerManifestList) IsAnAPIObject() {}
func (*BoundPod) IsAnAPIObject() {}
func (*BoundPods) IsAnAPIObject() {}
func (*List) IsAnAPIObject() {}
func (*LimitRange) IsAnAPIObject() {}
func (*LimitRangeList) IsAnAPIObject() {}
44 changes: 44 additions & 0 deletions pkg/api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -1138,3 +1138,47 @@ 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 LimitType = "Pod"
// Limit that applies to all containers in a namespace
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 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
Min ResourceList `json:"min,omitempty"`
}

// LimitRangeSpec defines a min/max usage limit for resources that match on kind
type LimitRangeSpec struct {
// Limits is the list of LimitRangeItem objects that are enforced
Limits []LimitRangeItem `json:"limits"`
}

// LimitRange sets resource usage limits for each kind of resource in a Namespace
type LimitRange struct {
TypeMeta `json:",inline"`
ObjectMeta `json:"metadata,omitempty"`

// Spec defines the limits enforced
Spec LimitRangeSpec `json:"spec,omitempty"`
}

// LimitRangeList is a list of LimitRange items.
type LimitRangeList struct {
TypeMeta `json:",inline"`
ListMeta `json:"metadata,omitempty"`

// Items is a list of LimitRange objects
Items []LimitRange `json:"items"`
}
67 changes: 66 additions & 1 deletion pkg/api/v1beta1/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,72 @@ func init() {
out.Status.HostIP = in.HostIP
return s.Convert(&in.NodeResources.Capacity, &out.Spec.Capacity, 0)
},

func(in *newer.LimitRange, out *LimitRange, s conversion.Scope) error {
if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil {
return err
}
if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil {
return err
}
if err := s.Convert(&in.Spec, &out.Spec, 0); err != nil {
return err
}
return nil
},
func(in *LimitRange, out *newer.LimitRange, s conversion.Scope) error {
if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil {
return err
}
if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil {
return err
}
if err := s.Convert(&in.Spec, &out.Spec, 0); err != nil {
return err
}
return nil
},
func(in *newer.LimitRangeSpec, out *LimitRangeSpec, s conversion.Scope) error {
*out = LimitRangeSpec{}
out.Limits = make([]LimitRangeItem, len(in.Limits), len(in.Limits))
for i := range in.Limits {
if err := s.Convert(&in.Limits[i], &out.Limits[i], 0); err != nil {
return err
}
}
return nil
},
func(in *LimitRangeSpec, out *newer.LimitRangeSpec, s conversion.Scope) error {
*out = newer.LimitRangeSpec{}
out.Limits = make([]newer.LimitRangeItem, len(in.Limits), len(in.Limits))
for i := range in.Limits {
if err := s.Convert(&in.Limits[i], &out.Limits[i], 0); err != nil {
return err
}
}
return nil
},
func(in *newer.LimitRangeItem, out *LimitRangeItem, s conversion.Scope) error {
*out = LimitRangeItem{}
out.Type = LimitType(in.Type)
if err := s.Convert(&in.Max, &out.Max, 0); err != nil {
return err
}
if err := s.Convert(&in.Min, &out.Min, 0); err != nil {
return err
}
return nil
},
func(in *LimitRangeItem, out *newer.LimitRangeItem, s conversion.Scope) error {
*out = newer.LimitRangeItem{}
out.Type = newer.LimitType(in.Type)
if err := s.Convert(&in.Max, &out.Max, 0); err != nil {
return err
}
if err := s.Convert(&in.Min, &out.Min, 0); err != nil {
return err
}
return nil
},
// Object ID <-> Name
// TODO: amend the conversion package to allow overriding specific fields.
func(in *ObjectReference, out *newer.ObjectReference, s conversion.Scope) error {
Expand Down
4 changes: 4 additions & 0 deletions pkg/api/v1beta1/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ func init() {
&BoundPod{},
&BoundPods{},
&List{},
&LimitRange{},
&LimitRangeList{},
)
// Future names are supported
api.Scheme.AddKnownTypeWithName("v1beta1", "Node", &Minion{})
Expand Down Expand Up @@ -78,3 +80,5 @@ func (*ContainerManifestList) IsAnAPIObject() {}
func (*BoundPod) IsAnAPIObject() {}
func (*BoundPods) IsAnAPIObject() {}
func (*List) IsAnAPIObject() {}
func (*LimitRange) IsAnAPIObject() {}
func (*LimitRangeList) IsAnAPIObject() {}
42 changes: 42 additions & 0 deletions pkg/api/v1beta1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -904,3 +904,45 @@ type List struct {
TypeMeta `json:",inline"`
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 LimitType = "Pod"
// Limit that applies to all containers in a namespace
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 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
Min ResourceList `json:"min,omitempty"`
}

// LimitRangeSpec defines a min/max usage limit for resources that match on kind
type LimitRangeSpec struct {
// Limits is the list of LimitRangeItem objects that are enforced
Limits []LimitRangeItem `json:"limits"`
}

// LimitRange sets resource usage limits for each kind of resource in a Namespace
type LimitRange struct {
TypeMeta `json:",inline"`

// Spec defines the limits enforced
Spec LimitRangeSpec `json:"spec,omitempty"`
}

// LimitRangeList is a list of LimitRange items.
type LimitRangeList struct {
TypeMeta `json:",inline"`

// Items is a list of LimitRange objects
Items []LimitRange `json:"items"`
}
67 changes: 66 additions & 1 deletion pkg/api/v1beta2/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,72 @@ func init() {
out.Status.HostIP = in.HostIP
return s.Convert(&in.NodeResources.Capacity, &out.Spec.Capacity, 0)
},

func(in *newer.LimitRange, out *LimitRange, s conversion.Scope) error {
if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil {
return err
}
if err := s.Convert(&in.ObjectMeta, &out.TypeMeta, 0); err != nil {
return err
}
if err := s.Convert(&in.Spec, &out.Spec, 0); err != nil {
return err
}
return nil
},
func(in *LimitRange, out *newer.LimitRange, s conversion.Scope) error {
if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil {
return err
}
if err := s.Convert(&in.TypeMeta, &out.ObjectMeta, 0); err != nil {
return err
}
if err := s.Convert(&in.Spec, &out.Spec, 0); err != nil {
return err
}
return nil
},
func(in *newer.LimitRangeSpec, out *LimitRangeSpec, s conversion.Scope) error {
*out = LimitRangeSpec{}
out.Limits = make([]LimitRangeItem, len(in.Limits), len(in.Limits))
for i := range in.Limits {
if err := s.Convert(&in.Limits[i], &out.Limits[i], 0); err != nil {
return err
}
}
return nil
},
func(in *LimitRangeSpec, out *newer.LimitRangeSpec, s conversion.Scope) error {
*out = newer.LimitRangeSpec{}
out.Limits = make([]newer.LimitRangeItem, len(in.Limits), len(in.Limits))
for i := range in.Limits {
if err := s.Convert(&in.Limits[i], &out.Limits[i], 0); err != nil {
return err
}
}
return nil
},
func(in *newer.LimitRangeItem, out *LimitRangeItem, s conversion.Scope) error {
*out = LimitRangeItem{}
out.Type = LimitType(in.Type)
if err := s.Convert(&in.Max, &out.Max, 0); err != nil {
return err
}
if err := s.Convert(&in.Min, &out.Min, 0); err != nil {
return err
}
return nil
},
func(in *LimitRangeItem, out *newer.LimitRangeItem, s conversion.Scope) error {
*out = newer.LimitRangeItem{}
out.Type = newer.LimitType(in.Type)
if err := s.Convert(&in.Max, &out.Max, 0); err != nil {
return err
}
if err := s.Convert(&in.Min, &out.Min, 0); err != nil {
return err
}
return nil
},
// Object ID <-> Name
// TODO: amend the conversion package to allow overriding specific fields.
func(in *ObjectReference, out *newer.ObjectReference, s conversion.Scope) error {
Expand Down
4 changes: 4 additions & 0 deletions pkg/api/v1beta2/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ func init() {
&BoundPod{},
&BoundPods{},
&List{},
&LimitRange{},
&LimitRangeList{},
)
// Future names are supported
api.Scheme.AddKnownTypeWithName("v1beta2", "Node", &Minion{})
Expand Down Expand Up @@ -78,3 +80,5 @@ func (*ContainerManifestList) IsAnAPIObject() {}
func (*BoundPod) IsAnAPIObject() {}
func (*BoundPods) IsAnAPIObject() {}
func (*List) IsAnAPIObject() {}
func (*LimitRange) IsAnAPIObject() {}
func (*LimitRangeList) IsAnAPIObject() {}