Skip to content

Commit

Permalink
Hot fix for panic on schema conversion.
Browse files Browse the repository at this point in the history
Kubernetes-commit: 1e76729a21a4be41727dcdccbab20e095866aed1
  • Loading branch information
cici37 authored and k8s-publishing-bot committed Jul 17, 2024
1 parent 803669d commit acd049c
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 3 deletions.
4 changes: 4 additions & 0 deletions pkg/apiserver/schema/cel/compilation.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package cel

import (
"errors"
"fmt"
"strings"
"time"
Expand Down Expand Up @@ -125,6 +126,9 @@ func Compile(s *schema.Structural, declType *apiservercel.DeclType, perCallLimit
if len(s.Extensions.XValidations) == 0 {
return nil, nil
}
if declType == nil {
return nil, errors.New("failed to convert to declType for CEL validation rules")
}
celRules := s.Extensions.XValidations

oldSelfEnvSet, optionalOldSelfEnvSet, err := prepareEnvSet(baseEnvSet, declType)
Expand Down
3 changes: 3 additions & 0 deletions pkg/apiserver/schema/cel/model/adaptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ func (s *Structural) Pattern() string {
}

func (s *Structural) Items() common.Schema {
if s.Structural.Items == nil {
return nil
}
return &Structural{Structural: s.Structural.Items}
}

Expand Down
51 changes: 50 additions & 1 deletion pkg/apiserver/schema/cel/model/schemas_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ func TestEstimateMaxLengthJSON(t *testing.T) {
Name string
InputSchema *schema.Structural
ExpectedMaxElements int64
ExpectNilType bool
}
tests := []maxLengthTest{
{
Expand Down Expand Up @@ -499,13 +500,61 @@ func TestEstimateMaxLengthJSON(t *testing.T) {
// so we expect the max length to be exactly equal to the user-supplied one
ExpectedMaxElements: 20,
},
{
Name: "Property under array",
InputSchema: &schema.Structural{
Generic: schema.Generic{
Type: "array",
},
Properties: map[string]schema.Structural{
"field": {
Generic: schema.Generic{
Type: "string",
Default: schema.JSON{Object: "default"},
},
},
},
},
// Got nil for delType
ExpectedMaxElements: 0,
ExpectNilType: true,
},
{
Name: "Items under object",
InputSchema: &schema.Structural{
Generic: schema.Generic{
Type: "object",
},
Items: &schema.Structural{
Generic: schema.Generic{
Type: "array",
},
Properties: map[string]schema.Structural{
"field": {
Generic: schema.Generic{
Type: "string",
Default: schema.JSON{Object: "default"},
},
},
},
ValueValidation: &schema.ValueValidation{
Required: []string{"field"},
},
},
},
// Skip items under object for schema conversion.
ExpectedMaxElements: 0,
},
}
for _, testCase := range tests {
t.Run(testCase.Name, func(t *testing.T) {
decl := SchemaDeclType(testCase.InputSchema, false)
if decl.MaxElements != testCase.ExpectedMaxElements {
if decl != nil && decl.MaxElements != testCase.ExpectedMaxElements {
t.Errorf("wrong maxElements (got %d, expected %d)", decl.MaxElements, testCase.ExpectedMaxElements)
}
if testCase.ExpectNilType && decl != nil {
t.Errorf("expected nil type, got %v", decl)
}
})
}
}
Expand Down
13 changes: 11 additions & 2 deletions pkg/apiserver/schema/cel/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,15 +94,24 @@ func validator(s *schema.Structural, isResourceRoot bool, declType *cel.DeclType
compiledRules, err := Compile(s, declType, perCallLimit, environment.MustBaseEnvSet(environment.DefaultCompatibilityVersion(), true), StoredExpressionsEnvLoader())
var itemsValidator, additionalPropertiesValidator *Validator
var propertiesValidators map[string]Validator
var elemType *cel.DeclType
if declType != nil {
elemType = declType.ElemType
} else {
elemType = declType
}
if s.Items != nil {
itemsValidator = validator(s.Items, s.Items.XEmbeddedResource, declType.ElemType, perCallLimit)
itemsValidator = validator(s.Items, s.Items.XEmbeddedResource, elemType, perCallLimit)
}
if len(s.Properties) > 0 {
propertiesValidators = make(map[string]Validator, len(s.Properties))
for k, p := range s.Properties {
prop := p
var fieldType *cel.DeclType
if escapedPropName, ok := cel.Escape(k); ok {
if declType == nil {
continue
}
if f, ok := declType.Fields[escapedPropName]; ok {
fieldType = f.Type
} else {
Expand All @@ -123,7 +132,7 @@ func validator(s *schema.Structural, isResourceRoot bool, declType *cel.DeclType
}
}
if s.AdditionalProperties != nil && s.AdditionalProperties.Structural != nil {
additionalPropertiesValidator = validator(s.AdditionalProperties.Structural, s.AdditionalProperties.Structural.XEmbeddedResource, declType.ElemType, perCallLimit)
additionalPropertiesValidator = validator(s.AdditionalProperties.Structural, s.AdditionalProperties.Structural.XEmbeddedResource, elemType, perCallLimit)
}
if len(compiledRules) > 0 || err != nil || itemsValidator != nil || additionalPropertiesValidator != nil || len(propertiesValidators) > 0 {
activationFactory := validationActivationWithoutOldSelf
Expand Down

0 comments on commit acd049c

Please sign in to comment.