Skip to content

Commit

Permalink
Hot fix for panic on schema conversion. (#126167)
Browse files Browse the repository at this point in the history
Kubernetes-commit: 5420b2fe9a84af57cc24793c8f8ac8821b65f42f
  • Loading branch information
cici37 authored and k8s-publishing-bot committed Jul 23, 2024
1 parent 21fdbb3 commit 876df11
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 19 deletions.
12 changes: 6 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ require (
github.com/google/go-cmp v0.6.0
github.com/google/gofuzz v1.2.0
github.com/google/uuid v1.6.0
github.com/pkg/errors v0.9.1
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.9.0
Expand All @@ -24,12 +25,12 @@ require (
google.golang.org/protobuf v1.34.2
gopkg.in/evanphx/json-patch.v4 v4.12.0
gopkg.in/yaml.v2 v2.4.0
k8s.io/api v0.0.0-20240720022854-7d5e5eaf3aef
k8s.io/apimachinery v0.0.0-20240719223001-62791ecbc514
k8s.io/apiserver v0.0.0-20240720104541-d681845e4f6a
k8s.io/client-go v0.0.0-20240719063343-5130bd9e7862
k8s.io/api v0.0.0-20240722223049-b689d905290f
k8s.io/apimachinery v0.0.0-20240720202316-95b78024e3fe
k8s.io/apiserver v0.0.0-20240723030233-2b2a4b0fa8e4
k8s.io/client-go v0.0.0-20240723023642-bad8f77ca6ef
k8s.io/code-generator v0.0.0-20240720023521-ec3cc888df4c
k8s.io/component-base v0.0.0-20240715183844-6f32dbe8ef25
k8s.io/component-base v0.0.0-20240722183709-6cc953a9d440
k8s.io/klog/v2 v2.130.1
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8
Expand Down Expand Up @@ -78,7 +79,6 @@ require (
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.19.1 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
Expand Down
20 changes: 10 additions & 10 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -365,18 +365,18 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
k8s.io/api v0.0.0-20240720022854-7d5e5eaf3aef h1:srEy4lds3ddDhT+cxFy68Uvt3GVRTo3fwnw+Us/Nqqs=
k8s.io/api v0.0.0-20240720022854-7d5e5eaf3aef/go.mod h1:SvpyE6bmVBf1ly5BaD4y6yym4ZpHrV2pa8tTRjcglaA=
k8s.io/apimachinery v0.0.0-20240719223001-62791ecbc514 h1:r9/8IzTbEU+H8bAZ4DtiN8A4Lr7UXnfPoPsnbe50zZ8=
k8s.io/apimachinery v0.0.0-20240719223001-62791ecbc514/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
k8s.io/apiserver v0.0.0-20240720104541-d681845e4f6a h1:Hcn+rrkkCCMuRxtWTpGdVZhrkfKiQkZI+peIJIRuqnM=
k8s.io/apiserver v0.0.0-20240720104541-d681845e4f6a/go.mod h1:UFdCOgZ0UgBzrSbF5rc3eVHS4OhIdbnIFYEITre8ZT8=
k8s.io/client-go v0.0.0-20240719063343-5130bd9e7862 h1:7pxBn9PlLxKT4L7sh5YE3nUt6dBajHFY6MitAvQ0K4E=
k8s.io/client-go v0.0.0-20240719063343-5130bd9e7862/go.mod h1:Ku8rB5ecknMAlxaO9IDX/HkHUBKk6ku4yWmXJ3o4Uaw=
k8s.io/api v0.0.0-20240722223049-b689d905290f h1:wtqzslJEcheiQ7hXjw1yGfqUyMCb7G4j72aL64Bzpbo=
k8s.io/api v0.0.0-20240722223049-b689d905290f/go.mod h1:ytlEzqC2wOTwYET71W7+J+k7O2V7vrDuzmNLBSpgT+k=
k8s.io/apimachinery v0.0.0-20240720202316-95b78024e3fe h1:V9MwpYUwbKlfLKVrhpVuKWiat/LBIhm1pGB9/xdHm5Q=
k8s.io/apimachinery v0.0.0-20240720202316-95b78024e3fe/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
k8s.io/apiserver v0.0.0-20240723030233-2b2a4b0fa8e4 h1:7nrffLiDUbMAXLKzBvyU8rwLHw5WpCw2AjhDO5IZYRs=
k8s.io/apiserver v0.0.0-20240723030233-2b2a4b0fa8e4/go.mod h1:R1HYbPCD+ClvTmzeLBYaS4aktC3entK1o4hyD+WemtA=
k8s.io/client-go v0.0.0-20240723023642-bad8f77ca6ef h1:+munBmXPvgGM5AFzdZh7Xe7S2LJ9udXYRfBDfm+0Eac=
k8s.io/client-go v0.0.0-20240723023642-bad8f77ca6ef/go.mod h1:L1rDFyPUkmS0j6WXGYh5v/iWsfIFYH+LWnFOT1LCsf4=
k8s.io/code-generator v0.0.0-20240720023521-ec3cc888df4c h1:oiNPH9Y/YrQfxo8eTW/w71aBrSyr9MX/wGBKTwDSZsc=
k8s.io/code-generator v0.0.0-20240720023521-ec3cc888df4c/go.mod h1:TVAwbna2B36D+IsWJ5oHqKZKSU8ZBtxeiMTb7uKM6Z0=
k8s.io/component-base v0.0.0-20240715183844-6f32dbe8ef25 h1:9SIVS17h6glmGM2G4ILkpQRUYc/zZ7y15gD2uaby0rM=
k8s.io/component-base v0.0.0-20240715183844-6f32dbe8ef25/go.mod h1:YYWVx/ele54LQcShCdQpmsIqiHgZ+KjWY7WGMzTjKGk=
k8s.io/component-base v0.0.0-20240722183709-6cc953a9d440 h1:14X+5sRQRsul6tLxIKTP0/DotvWlMd9DFCgMqHP1hZY=
k8s.io/component-base v0.0.0-20240722183709-6cc953a9d440/go.mod h1:dj2Pl05aLcVMZi2NXcwv+M/WdUVPEkisFPjDze7rbSk=
k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70 h1:NGrVE502P0s0/1hudf8zjgwki1X/TByhmAoILTarmzo=
k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70/go.mod h1:VH3AT8AaQOqiGjMF9p0/IM1Dj+82ZwjfxUP1IxaHE+8=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
Expand Down
4 changes: 4 additions & 0 deletions pkg/apiserver/schema/cel/compilation.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/google/cel-go/cel"
"github.com/google/cel-go/checker"
"github.com/google/cel-go/common/types"
"github.com/pkg/errors"

apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
Expand Down Expand Up @@ -125,6 +126,9 @@ func Compile(s *schema.Structural, declType *apiservercel.DeclType, perCallLimit
if len(s.XValidations) == 0 {
return nil, nil
}
if declType == nil {
return nil, errors.New("Failed to convert to declType for CEL validation rules")
}
celRules := s.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 @@ -100,9 +100,15 @@ func validator(validationSchema, nodeSchema *schema.Structural, isResourceRoot b
var itemsValidator, additionalPropertiesValidator *Validator
var propertiesValidators map[string]Validator
var allOfValidators []*Validator
var elemType *cel.DeclType
if declType != nil {
elemType = declType.ElemType
} else {
elemType = declType
}

if validationSchema.Items != nil && nodeSchema.Items != nil {
itemsValidator = validator(validationSchema.Items, nodeSchema.Items, nodeSchema.Items.XEmbeddedResource, declType.ElemType, perCallLimit)
itemsValidator = validator(validationSchema.Items, nodeSchema.Items, nodeSchema.Items.XEmbeddedResource, elemType, perCallLimit)
}

if len(validationSchema.Properties) > 0 {
Expand All @@ -117,6 +123,9 @@ func validator(validationSchema, nodeSchema *schema.Structural, isResourceRoot b

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 @@ -138,7 +147,7 @@ func validator(validationSchema, nodeSchema *schema.Structural, isResourceRoot b
}
if validationSchema.AdditionalProperties != nil && validationSchema.AdditionalProperties.Structural != nil &&
nodeSchema.AdditionalProperties != nil && nodeSchema.AdditionalProperties.Structural != nil {
additionalPropertiesValidator = validator(validationSchema.AdditionalProperties.Structural, nodeSchema.AdditionalProperties.Structural, nodeSchema.AdditionalProperties.Structural.XEmbeddedResource, declType.ElemType, perCallLimit)
additionalPropertiesValidator = validator(validationSchema.AdditionalProperties.Structural, nodeSchema.AdditionalProperties.Structural, nodeSchema.AdditionalProperties.Structural.XEmbeddedResource, elemType, perCallLimit)
}

if validationSchema.ValueValidation != nil && len(validationSchema.ValueValidation.AllOf) > 0 {
Expand Down

0 comments on commit 876df11

Please sign in to comment.