Skip to content

Commit 1bae2b6

Browse files
committed
Merge pull request kubernetes#12492 from derekwaynecarr/limit_range_api
LimitRange updates for Resource Requirements Requests
2 parents 09446c7 + d250822 commit 1bae2b6

File tree

18 files changed

+778
-178
lines changed

18 files changed

+778
-178
lines changed

api/swagger-spec/v1.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11575,7 +11575,15 @@
1157511575
},
1157611576
"default": {
1157711577
"type": "any",
11578-
"description": "Default usage constraints on this kind by resource name. Default values on this kind by resource name if omitted."
11578+
"description": "Default resource requirement limit value by resource name if resource limit is omitted."
11579+
},
11580+
"defaultRequest": {
11581+
"type": "any",
11582+
"description": "DefaultRequest is the default resource requirement request value by resource name if resource request is omitted."
11583+
},
11584+
"maxLimitRequestRatio": {
11585+
"type": "any",
11586+
"description": "MaxLimitRequestRatio if specified, the named resource must have a request and limit that are both non-zero where limit divided by request is less than or equal to the enumerated value; this represents the max burst for the named resource."
1157911587
}
1158011588
}
1158111589
},

cluster/saltbase/salt/kube-admission-controls/limit-range/limit-range.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ metadata:
66
spec:
77
limits:
88
- type: "Container"
9-
default:
9+
defaultRequest:
1010
cpu: "100m"

docs/design/admission_control_limit_range.md

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ The **LimitRange** resource is scoped to a **Namespace**.
5353
### Type
5454

5555
```go
56-
// A type of object that is limited
56+
// LimitType is a type of object that is limited
5757
type LimitType string
5858

5959
const (
@@ -63,52 +63,58 @@ const (
6363
LimitTypeContainer LimitType = "Container"
6464
)
6565

66-
// LimitRangeItem defines a min/max usage limit for any resource that matches on kind
66+
// LimitRangeItem defines a min/max usage limit for any resource that matches on kind.
6767
type LimitRangeItem struct {
68-
// Type of resource that this limit applies to
69-
Type LimitType `json:"type,omitempty" description:"type of resource that this limit applies to"`
70-
// Max usage constraints on this kind by resource name
71-
Max ResourceList `json:"max,omitempty" description:"max usage constraints on this kind by resource name"`
72-
// Min usage constraints on this kind by resource name
73-
Min ResourceList `json:"min,omitempty" description:"min usage constraints on this kind by resource name"`
74-
// Default resource limits on this kind by resource name
75-
Default ResourceList `json:"default,omitempty" description:"default resource limits values on this kind by resource name if omitted"`
76-
// DefaultRequests resource requests on this kind by resource name
77-
DefaultRequests ResourceList `json:"defaultRequests,omitempty" description:"default resource requests values on this kind by resource name if omitted"`
78-
// LimitRequestRatio is the ratio of limit over request that is the maximum allowed burst for the named resource
79-
LimitRequestRatio ResourceList `json:"limitRequestRatio,omitempty" description:"the ratio of limit over request that is the maximum allowed burst for the named resource. if specified, the named resource must have a request and limit that are both non-zero where limit divided by request is less than or equal to the enumerated value"`
68+
// Type of resource that this limit applies to.
69+
Type LimitType `json:"type,omitempty"`
70+
// Max usage constraints on this kind by resource name.
71+
Max ResourceList `json:"max,omitempty"`
72+
// Min usage constraints on this kind by resource name.
73+
Min ResourceList `json:"min,omitempty"`
74+
// Default resource requirement limit value by resource name if resource limit is omitted.
75+
Default ResourceList `json:"default,omitempty"`
76+
// DefaultRequest is the default resource requirement request value by resource name if resource request is omitted.
77+
DefaultRequest ResourceList `json:"defaultRequest,omitempty"`
78+
// MaxLimitRequestRatio if specified, the named resource must have a request and limit that are both non-zero where limit divided by request is less than or equal to the enumerated value; this represents the max burst for the named resource.
79+
MaxLimitRequestRatio ResourceList `json:"maxLimitRequestRatio,omitempty"`
8080
}
8181

82-
// LimitRangeSpec defines a min/max usage limit for resources that match on kind
82+
// LimitRangeSpec defines a min/max usage limit for resources that match on kind.
8383
type LimitRangeSpec struct {
84-
// Limits is the list of LimitRangeItem objects that are enforced
85-
Limits []LimitRangeItem `json:"limits" description:"limits is the list of LimitRangeItem objects that are enforced"`
84+
// Limits is the list of LimitRangeItem objects that are enforced.
85+
Limits []LimitRangeItem `json:"limits"`
8686
}
8787

88-
// LimitRange sets resource usage limits for each kind of resource in a Namespace
88+
// LimitRange sets resource usage limits for each kind of resource in a Namespace.
8989
type LimitRange struct {
90-
TypeMeta `json:",inline"`
91-
ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata"`
90+
TypeMeta `json:",inline"`
91+
// Standard object's metadata.
92+
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
93+
ObjectMeta `json:"metadata,omitempty"`
9294

93-
// Spec defines the limits enforced
94-
Spec LimitRangeSpec `json:"spec,omitempty" description:"spec defines the limits enforced; http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status"`
95+
// Spec defines the limits enforced.
96+
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status
97+
Spec LimitRangeSpec `json:"spec,omitempty"`
9598
}
9699

97100
// LimitRangeList is a list of LimitRange items.
98101
type LimitRangeList struct {
99102
TypeMeta `json:",inline"`
100-
ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata"`
103+
// Standard list metadata.
104+
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds
105+
ListMeta `json:"metadata,omitempty"`
101106

102-
// Items is a list of LimitRange objects
103-
Items []LimitRange `json:"items" description:"items is a list of LimitRange objects; see http://releases.k8s.io/HEAD/docs/design/admission_control_limit_range.md"`
107+
// Items is a list of LimitRange objects.
108+
// More info: http://releases.k8s.io/HEAD/docs/design/admission_control_limit_range.md
109+
Items []LimitRange `json:"items"`
104110
}
105111
```
106112

107113
### Validation
108114

109115
Validation of a **LimitRange** enforces that for a given named resource the following rules apply:
110116

111-
Min (if specified) <= DefaultRequests (if specified) <= Default (if specified) <= Max (if specified)
117+
Min (if specified) <= DefaultRequest (if specified) <= Default (if specified) <= Max (if specified)
112118

113119
### Default Value Behavior
114120

@@ -121,11 +127,11 @@ if LimitRangeItem.Default[resourceName] is undefined
121127
```
122128

123129
```
124-
if LimitRangeItem.DefaultRequests[resourceName] is undefined
130+
if LimitRangeItem.DefaultRequest[resourceName] is undefined
125131
if LimitRangeItem.Default[resourceName] is defined
126-
LimitRangeItem.DefaultRequests[resourceName] = LimitRangeItem.Default[resourceName]
132+
LimitRangeItem.DefaultRequest[resourceName] = LimitRangeItem.Default[resourceName]
127133
else if LimitRangeItem.Min[resourceName] is defined
128-
LimitRangeItem.DefaultRequests[resourceName] = LimitRangeItem.Min[resourceName]
134+
LimitRangeItem.DefaultRequest[resourceName] = LimitRangeItem.Min[resourceName]
129135
```
130136

131137
## AdmissionControl plugin: LimitRanger

docs/devel/api_changes.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,22 @@ generator to create it from scratch.
345345
Unsurprisingly, adding manually written conversion also requires you to add tests to
346346
`pkg/api/<version>/conversion_test.go`.
347347

348+
## Edit deep copy files
349+
350+
At this point you have both the versioned API changes and the internal
351+
structure changes done. You now need to generate code to handle deep copy
352+
of your versioned api objects.
353+
354+
The deep copy code resides with each versioned API:
355+
- `pkg/api/<version>/deep_copy_generated.go` containing auto-generated copy functions
356+
357+
To regenerate them:
358+
- run
359+
360+
```sh
361+
hack/update-generated-deep-copies.sh
362+
```
363+
348364
## Update the fuzzer
349365

350366
Part of our testing regimen for APIs is to "fuzz" (fill with random values) API

pkg/api/deep_copy_generated.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -689,6 +689,30 @@ func deepCopy_api_LimitRangeItem(in LimitRangeItem, out *LimitRangeItem, c *conv
689689
} else {
690690
out.Default = nil
691691
}
692+
if in.DefaultRequest != nil {
693+
out.DefaultRequest = make(ResourceList)
694+
for key, val := range in.DefaultRequest {
695+
newVal := new(resource.Quantity)
696+
if err := deepCopy_resource_Quantity(val, newVal, c); err != nil {
697+
return err
698+
}
699+
out.DefaultRequest[key] = *newVal
700+
}
701+
} else {
702+
out.DefaultRequest = nil
703+
}
704+
if in.MaxLimitRequestRatio != nil {
705+
out.MaxLimitRequestRatio = make(ResourceList)
706+
for key, val := range in.MaxLimitRequestRatio {
707+
newVal := new(resource.Quantity)
708+
if err := deepCopy_resource_Quantity(val, newVal, c); err != nil {
709+
return err
710+
}
711+
out.MaxLimitRequestRatio[key] = *newVal
712+
}
713+
} else {
714+
out.MaxLimitRequestRatio = nil
715+
}
692716
return nil
693717
}
694718

pkg/api/testing/fuzzer.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,28 @@ func FuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer {
183183
q.Limits[api.ResourceStorage] = *storageLimit.Copy()
184184
q.Requests[api.ResourceStorage] = *storageLimit.Copy()
185185
},
186+
func(q *api.LimitRangeItem, c fuzz.Continue) {
187+
randomQuantity := func() resource.Quantity {
188+
return *resource.NewQuantity(c.Int63n(1000), resource.DecimalExponent)
189+
}
190+
cpuLimit := randomQuantity()
191+
192+
q.Type = api.LimitTypeContainer
193+
q.Default = make(api.ResourceList)
194+
q.Default[api.ResourceCPU] = *(cpuLimit.Copy())
195+
196+
q.DefaultRequest = make(api.ResourceList)
197+
q.DefaultRequest[api.ResourceCPU] = *(cpuLimit.Copy())
198+
199+
q.Max = make(api.ResourceList)
200+
q.Max[api.ResourceCPU] = *(cpuLimit.Copy())
201+
202+
q.Min = make(api.ResourceList)
203+
q.Min[api.ResourceCPU] = *(cpuLimit.Copy())
204+
205+
q.MaxLimitRequestRatio = make(api.ResourceList)
206+
q.MaxLimitRequestRatio[api.ResourceCPU] = resource.MustParse("10")
207+
},
186208
func(p *api.PullPolicy, c fuzz.Continue) {
187209
policies := []api.PullPolicy{api.PullAlways, api.PullNever, api.PullIfNotPresent}
188210
*p = policies[c.Rand.Intn(len(policies))]

pkg/api/types.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1942,8 +1942,12 @@ type LimitRangeItem struct {
19421942
Max ResourceList `json:"max,omitempty"`
19431943
// Min usage constraints on this kind by resource name
19441944
Min ResourceList `json:"min,omitempty"`
1945-
// Default usage constraints on this kind by resource name
1945+
// Default resource requirement limit value by resource name.
19461946
Default ResourceList `json:"default,omitempty"`
1947+
// DefaultRequest resource requirement request value by resource name.
1948+
DefaultRequest ResourceList `json:"defaultRequest,omitempty"`
1949+
// MaxLimitRequestRatio represents the max burst value for the named resource
1950+
MaxLimitRequestRatio ResourceList `json:"maxLimitRequestRatio,omitempty"`
19471951
}
19481952

19491953
// LimitRangeSpec defines a min/max usage limit for resources that match on kind

pkg/api/v1/conversion_generated.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,30 @@ func convert_api_LimitRangeItem_To_v1_LimitRangeItem(in *api.LimitRangeItem, out
805805
} else {
806806
out.Default = nil
807807
}
808+
if in.DefaultRequest != nil {
809+
out.DefaultRequest = make(ResourceList)
810+
for key, val := range in.DefaultRequest {
811+
newVal := resource.Quantity{}
812+
if err := s.Convert(&val, &newVal, 0); err != nil {
813+
return err
814+
}
815+
out.DefaultRequest[ResourceName(key)] = newVal
816+
}
817+
} else {
818+
out.DefaultRequest = nil
819+
}
820+
if in.MaxLimitRequestRatio != nil {
821+
out.MaxLimitRequestRatio = make(ResourceList)
822+
for key, val := range in.MaxLimitRequestRatio {
823+
newVal := resource.Quantity{}
824+
if err := s.Convert(&val, &newVal, 0); err != nil {
825+
return err
826+
}
827+
out.MaxLimitRequestRatio[ResourceName(key)] = newVal
828+
}
829+
} else {
830+
out.MaxLimitRequestRatio = nil
831+
}
808832
return nil
809833
}
810834

@@ -3170,6 +3194,30 @@ func convert_v1_LimitRangeItem_To_api_LimitRangeItem(in *LimitRangeItem, out *ap
31703194
} else {
31713195
out.Default = nil
31723196
}
3197+
if in.DefaultRequest != nil {
3198+
out.DefaultRequest = make(api.ResourceList)
3199+
for key, val := range in.DefaultRequest {
3200+
newVal := resource.Quantity{}
3201+
if err := s.Convert(&val, &newVal, 0); err != nil {
3202+
return err
3203+
}
3204+
out.DefaultRequest[api.ResourceName(key)] = newVal
3205+
}
3206+
} else {
3207+
out.DefaultRequest = nil
3208+
}
3209+
if in.MaxLimitRequestRatio != nil {
3210+
out.MaxLimitRequestRatio = make(api.ResourceList)
3211+
for key, val := range in.MaxLimitRequestRatio {
3212+
newVal := resource.Quantity{}
3213+
if err := s.Convert(&val, &newVal, 0); err != nil {
3214+
return err
3215+
}
3216+
out.MaxLimitRequestRatio[api.ResourceName(key)] = newVal
3217+
}
3218+
} else {
3219+
out.MaxLimitRequestRatio = nil
3220+
}
31733221
return nil
31743222
}
31753223

pkg/api/v1/deep_copy_generated.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,30 @@ func deepCopy_v1_LimitRangeItem(in LimitRangeItem, out *LimitRangeItem, c *conve
704704
} else {
705705
out.Default = nil
706706
}
707+
if in.DefaultRequest != nil {
708+
out.DefaultRequest = make(ResourceList)
709+
for key, val := range in.DefaultRequest {
710+
newVal := new(resource.Quantity)
711+
if err := deepCopy_resource_Quantity(val, newVal, c); err != nil {
712+
return err
713+
}
714+
out.DefaultRequest[key] = *newVal
715+
}
716+
} else {
717+
out.DefaultRequest = nil
718+
}
719+
if in.MaxLimitRequestRatio != nil {
720+
out.MaxLimitRequestRatio = make(ResourceList)
721+
for key, val := range in.MaxLimitRequestRatio {
722+
newVal := new(resource.Quantity)
723+
if err := deepCopy_resource_Quantity(val, newVal, c); err != nil {
724+
return err
725+
}
726+
out.MaxLimitRequestRatio[key] = *newVal
727+
}
728+
} else {
729+
out.MaxLimitRequestRatio = nil
730+
}
707731
return nil
708732
}
709733

pkg/api/v1/defaults.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,37 @@ func addDefaultingFuncs() {
188188
}
189189
}
190190
},
191+
func(obj *LimitRangeItem) {
192+
// for container limits, we apply default values
193+
if obj.Type == LimitTypeContainer {
194+
195+
if obj.Default == nil {
196+
obj.Default = make(ResourceList)
197+
}
198+
if obj.DefaultRequest == nil {
199+
obj.DefaultRequest = make(ResourceList)
200+
}
201+
202+
// If a default limit is unspecified, but the max is specified, default the limit to the max
203+
for key, value := range obj.Max {
204+
if _, exists := obj.Default[key]; !exists {
205+
obj.Default[key] = *(value.Copy())
206+
}
207+
}
208+
// If a default limit is specified, but the default request is not, default request to limit
209+
for key, value := range obj.Default {
210+
if _, exists := obj.DefaultRequest[key]; !exists {
211+
obj.DefaultRequest[key] = *(value.Copy())
212+
}
213+
}
214+
// If a default request is not specified, but the min is provided, default request to the min
215+
for key, value := range obj.Min {
216+
if _, exists := obj.DefaultRequest[key]; !exists {
217+
obj.DefaultRequest[key] = *(value.Copy())
218+
}
219+
}
220+
}
221+
},
191222
)
192223
}
193224

0 commit comments

Comments
 (0)