Merge pull request #132837 from JoelSpeed/fix-max-elements-x-int-or-string
Fix IntOrString cost estimation when schema has a MaxLength constraint Kubernetes-commit: f9fde2dfbdfb73c25e0a17d675313748948cd78c
This commit is contained in:
commit
4f018447f7
4
go.mod
4
go.mod
|
@ -48,9 +48,9 @@ require (
|
|||
gopkg.in/evanphx/json-patch.v4 v4.12.0
|
||||
gopkg.in/go-jose/go-jose.v2 v2.6.3
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||
k8s.io/api v0.0.0-20250724064529-b87ac725dbf9
|
||||
k8s.io/api v0.0.0-20250724104226-1560b8c850a7
|
||||
k8s.io/apimachinery v0.0.0-20250723005633-58c4eb072ebf
|
||||
k8s.io/client-go v0.0.0-20250724024901-5f1f878e5cd4
|
||||
k8s.io/client-go v0.0.0-20250724144911-764374b3242b
|
||||
k8s.io/component-base v0.0.0-20250724065244-07ee182722a1
|
||||
k8s.io/klog/v2 v2.130.1
|
||||
k8s.io/kms v0.0.0-20250716213631-bbefe5cb7a2e
|
||||
|
|
8
go.sum
8
go.sum
|
@ -296,12 +296,12 @@ gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYs
|
|||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
k8s.io/api v0.0.0-20250724064529-b87ac725dbf9 h1:szZeh22FWBBbJjDCHrh8P35J6afaiuPOpaTsgaEyX4Q=
|
||||
k8s.io/api v0.0.0-20250724064529-b87ac725dbf9/go.mod h1:70o+sJgHYrO2nPMKeEsmpidpEUMobuxHMhjK/ud9+og=
|
||||
k8s.io/api v0.0.0-20250724104226-1560b8c850a7 h1:Y5FVeGr2IQ3fbv6GeQAeiZKIyBwxyr7Nv0tWJog9OEo=
|
||||
k8s.io/api v0.0.0-20250724104226-1560b8c850a7/go.mod h1:70o+sJgHYrO2nPMKeEsmpidpEUMobuxHMhjK/ud9+og=
|
||||
k8s.io/apimachinery v0.0.0-20250723005633-58c4eb072ebf h1:R1l0xAevbhH2Bg0iJuabo8/i9m31D1ehh2ZJPFKh9bc=
|
||||
k8s.io/apimachinery v0.0.0-20250723005633-58c4eb072ebf/go.mod h1:v1p1Jsze3IHLy5gU17yVqR2qLO7jgYeX6mw3HZy2AEU=
|
||||
k8s.io/client-go v0.0.0-20250724024901-5f1f878e5cd4 h1:cUaPGCS7dfX5d85Q8ZJBD2rdK5C6tbWEtGFdBcH+bxo=
|
||||
k8s.io/client-go v0.0.0-20250724024901-5f1f878e5cd4/go.mod h1:kgDY5crqhNpktphA+cjWLcLLjrF5apg7TWTtaVyhUm8=
|
||||
k8s.io/client-go v0.0.0-20250724144911-764374b3242b h1:7RltffV2NgCQA9jJNMHs2Xnn/vFTNHj+MFY34v6dg7w=
|
||||
k8s.io/client-go v0.0.0-20250724144911-764374b3242b/go.mod h1:cgK+6wG3u4eub4z04TjSa9Y2WD320ZageTzIr5+E5Cg=
|
||||
k8s.io/component-base v0.0.0-20250724065244-07ee182722a1 h1:OSPZY89+U2JKPaQnluxgzhsbY+L+gG/cxgYVFY5gYA0=
|
||||
k8s.io/component-base v0.0.0-20250724065244-07ee182722a1/go.mod h1:w6VkDvQYhgRcM0VZp+pAMPfhFPflGqAAik6tDGgIyq0=
|
||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||
|
|
|
@ -55,8 +55,15 @@ func SchemaDeclType(s Schema, isResourceRoot bool) *apiservercel.DeclType {
|
|||
// `type(intOrStringField) == int ? intOrStringField < 5 : double(intOrStringField.replace('%', '')) < 0.5
|
||||
//
|
||||
dyn := apiservercel.NewSimpleTypeWithMinSize("dyn", cel.DynType, nil, 1) // smallest value for a serialized x-kubernetes-int-or-string is 0
|
||||
// handle x-kubernetes-int-or-string by returning the max length/min serialized size of the largest possible string
|
||||
dyn.MaxElements = maxRequestSizeBytes - 2
|
||||
|
||||
// If the schema has a maxlength constraint, bound the max elements based on the max length.
|
||||
// Otherwise, fallback to the max request size.
|
||||
if s.MaxLength() != nil {
|
||||
dyn.MaxElements = estimateMaxElementsFromMaxLength(s)
|
||||
} else {
|
||||
dyn.MaxElements = estimateMaxStringLengthPerRequest(s)
|
||||
}
|
||||
|
||||
return dyn
|
||||
}
|
||||
|
||||
|
@ -159,11 +166,7 @@ func SchemaDeclType(s Schema, isResourceRoot bool) *apiservercel.DeclType {
|
|||
|
||||
strWithMaxLength := apiservercel.NewSimpleTypeWithMinSize("string", cel.StringType, types.String(""), apiservercel.MinStringSize)
|
||||
if s.MaxLength() != nil {
|
||||
// multiply the user-provided max length by 4 in the case of an otherwise-untyped string
|
||||
// we do this because the OpenAPIv3 spec indicates that maxLength is specified in runes/code points,
|
||||
// but we need to reason about length for things like request size, so we use bytes in this code (and an individual
|
||||
// unicode code point can be up to 4 bytes long)
|
||||
strWithMaxLength.MaxElements = zeroIfNegative(*s.MaxLength()) * 4
|
||||
strWithMaxLength.MaxElements = estimateMaxElementsFromMaxLength(s)
|
||||
} else {
|
||||
if len(s.Enum()) > 0 {
|
||||
strWithMaxLength.MaxElements = estimateMaxStringEnumLength(s)
|
||||
|
@ -228,6 +231,7 @@ func WithTypeAndObjectMeta(s *spec.Schema) *spec.Schema {
|
|||
// must only be called on schemas of type "string" or x-kubernetes-int-or-string: true
|
||||
func estimateMaxStringLengthPerRequest(s Schema) int64 {
|
||||
if s.IsXIntOrString() {
|
||||
// handle x-kubernetes-int-or-string by returning the max length/min serialized size of the largest possible string
|
||||
return maxRequestSizeBytes - 2
|
||||
}
|
||||
switch s.Format() {
|
||||
|
@ -272,3 +276,13 @@ func estimateMaxAdditionalPropertiesFromMinSize(minSize int64) int64 {
|
|||
// subtract 2 to account for { and }
|
||||
return (maxRequestSizeBytes - 2) / keyValuePairSize
|
||||
}
|
||||
|
||||
// estimateMaxElementsFromMaxLength estimates the maximum number of elements for a string schema
|
||||
// that is bound with a maxLength constraint.
|
||||
func estimateMaxElementsFromMaxLength(s Schema) int64 {
|
||||
// multiply the user-provided max length by 4 in the case of an otherwise-untyped string
|
||||
// we do this because the OpenAPIv3 spec indicates that maxLength is specified in runes/code points,
|
||||
// but we need to reason about length for things like request size, so we use bytes in this code (and an individual
|
||||
// unicode code point can be up to 4 bytes long)
|
||||
return zeroIfNegative(*s.MaxLength()) * 4
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue