Merge pull request #112926 from jiahuif-forks/refactor/cel-out-of-apiextensions

split and move CEL package
This commit is contained in:
Kubernetes Prow Robot 2022-10-12 15:03:03 -07:00 committed by GitHub
commit 61ca612cbb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 268 additions and 193 deletions

View File

@ -25,6 +25,7 @@ import (
structuralschema "k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
"k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/model"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/apiserver/pkg/cel"
)
// unbounded uses nil to represent an unbounded cardinality value.
@ -109,7 +110,7 @@ type CELTypeInfo struct {
// Schema is a structural schema for this CELSchemaContext node. It must be non-nil.
Schema *structuralschema.Structural
// DeclType is a CEL declaration representation of Schema of this CELSchemaContext node. It must be non-nil.
DeclType *model.DeclType
DeclType *cel.DeclType
}
// converter converts from JSON schema to a structural schema and a CEL declType, or returns an error if the conversion
@ -224,7 +225,7 @@ type propertyTypeInfoAccessor struct {
func (c propertyTypeInfoAccessor) accessTypeInfo(parentTypeInfo *CELTypeInfo) *CELTypeInfo {
if parentTypeInfo.Schema.Properties != nil {
propSchema := parentTypeInfo.Schema.Properties[c.propertyName]
if escapedPropName, ok := model.Escape(c.propertyName); ok {
if escapedPropName, ok := cel.Escape(c.propertyName); ok {
if fieldDeclType, ok := parentTypeInfo.DeclType.Fields[escapedPropName]; ok {
return &CELTypeInfo{Schema: &propSchema, DeclType: fieldDeclType.Type}
} // else fields with unknown types are omitted from CEL validation entirely

View File

@ -34,6 +34,7 @@ import (
"k8s.io/apimachinery/pkg/util/sets"
utilvalidation "k8s.io/apimachinery/pkg/util/validation"
"k8s.io/apimachinery/pkg/util/validation/field"
apiservercel "k8s.io/apiserver/pkg/cel"
"k8s.io/apiserver/pkg/util/webhook"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
@ -1038,7 +1039,7 @@ func ValidateCustomResourceDefinitionOpenAPISchema(schema *apiextensions.JSONSch
celContext.TotalCost.ObserveExpressionCost(fldPath.Child("x-kubernetes-validations").Index(i).Child("rule"), expressionCost)
}
if cr.Error != nil {
if cr.Error.Type == cel.ErrorTypeRequired {
if cr.Error.Type == apiservercel.ErrorTypeRequired {
allErrs.CELErrors = append(allErrs.CELErrors, field.Required(fldPath.Child("x-kubernetes-validations").Index(i).Child("rule"), cr.Error.Detail))
} else {
allErrs.CELErrors = append(allErrs.CELErrors, field.Invalid(fldPath.Child("x-kubernetes-validations").Index(i).Child("rule"), schema.XValidations[i], cr.Error.Detail))

View File

@ -24,11 +24,13 @@ import (
"github.com/google/cel-go/cel"
"github.com/google/cel-go/checker"
apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
"k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/library"
"k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/metrics"
celmodel "k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/model"
apiservercel "k8s.io/apiserver/pkg/cel"
"k8s.io/apiserver/pkg/cel/library"
"k8s.io/apiserver/pkg/cel/metrics"
)
const (
@ -56,7 +58,7 @@ const (
// CompilationResult represents the cel compilation result for one rule
type CompilationResult struct {
Program cel.Program
Error *Error
Error *apiservercel.Error
// If true, the compiled expression contains a reference to the identifier "oldSelf", and its corresponding rule
// is implicitly a transition rule.
TransitionRule bool
@ -97,7 +99,7 @@ func getBaseEnv() (*cel.Env, error) {
// - nil Program, nil Error: The provided rule was empty so compilation was not attempted
//
// perCallLimit was added for testing purpose only. Callers should always use const PerCallLimit as input.
func Compile(s *schema.Structural, declType *celmodel.DeclType, perCallLimit uint64) ([]CompilationResult, error) {
func Compile(s *schema.Structural, declType *apiservercel.DeclType, perCallLimit uint64) ([]CompilationResult, error) {
t := time.Now()
defer metrics.Metrics.ObserveCompilation(time.Since(t))
if len(s.Extensions.XValidations) == 0 {
@ -106,15 +108,15 @@ func Compile(s *schema.Structural, declType *celmodel.DeclType, perCallLimit uin
celRules := s.Extensions.XValidations
var propDecls []cel.EnvOption
var root *celmodel.DeclType
var root *apiservercel.DeclType
var ok bool
baseEnv, err := getBaseEnv()
if err != nil {
return nil, err
}
reg := celmodel.NewRegistry(baseEnv)
reg := apiservercel.NewRegistry(baseEnv)
scopedTypeName := generateUniqueSelfTypeName()
rt, err := celmodel.NewRuleTypes(scopedTypeName, declType, reg)
rt, err := apiservercel.NewRuleTypes(scopedTypeName, declType, reg)
if err != nil {
return nil, err
}
@ -158,18 +160,18 @@ func compileRule(rule apiextensions.ValidationRule, env *cel.Env, perCallLimit u
}
ast, issues := env.Compile(rule.Rule)
if issues != nil {
compilationResult.Error = &Error{ErrorTypeInvalid, "compilation failed: " + issues.String()}
compilationResult.Error = &apiservercel.Error{apiservercel.ErrorTypeInvalid, "compilation failed: " + issues.String()}
return
}
if ast.OutputType() != cel.BoolType {
compilationResult.Error = &Error{ErrorTypeInvalid, "cel expression must evaluate to a bool"}
compilationResult.Error = &apiservercel.Error{apiservercel.ErrorTypeInvalid, "cel expression must evaluate to a bool"}
return
}
checkedExpr, err := cel.AstToCheckedExpr(ast)
if err != nil {
// should be impossible since env.Compile returned no issues
compilationResult.Error = &Error{ErrorTypeInternal, "unexpected compilation error: " + err.Error()}
compilationResult.Error = &apiservercel.Error{apiservercel.ErrorTypeInternal, "unexpected compilation error: " + err.Error()}
return
}
for _, ref := range checkedExpr.ReferenceMap {
@ -188,12 +190,12 @@ func compileRule(rule apiextensions.ValidationRule, env *cel.Env, perCallLimit u
cel.InterruptCheckFrequency(checkFrequency),
)
if err != nil {
compilationResult.Error = &Error{ErrorTypeInvalid, "program instantiation failed: " + err.Error()}
compilationResult.Error = &apiservercel.Error{apiservercel.ErrorTypeInvalid, "program instantiation failed: " + err.Error()}
return
}
costEst, err := env.EstimateCost(ast, estimator)
if err != nil {
compilationResult.Error = &Error{ErrorTypeInternal, "cost estimation failed: " + err.Error()}
compilationResult.Error = &apiservercel.Error{apiservercel.ErrorTypeInternal, "cost estimation failed: " + err.Error()}
return
}
compilationResult.MaxCost = costEst.Max
@ -210,12 +212,12 @@ func generateUniqueSelfTypeName() string {
return fmt.Sprintf("selfType%d", time.Now().Nanosecond())
}
func newCostEstimator(root *celmodel.DeclType) *library.CostEstimator {
func newCostEstimator(root *apiservercel.DeclType) *library.CostEstimator {
return &library.CostEstimator{SizeEstimator: &sizeEstimator{root: root}}
}
type sizeEstimator struct {
root *celmodel.DeclType
root *apiservercel.DeclType
}
func (c *sizeEstimator) EstimateSize(element checker.AstNode) *checker.SizeEstimate {

View File

@ -22,6 +22,8 @@ import (
"strings"
"testing"
"k8s.io/apiserver/pkg/cel"
apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
"k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/model"
@ -79,12 +81,12 @@ func (m fnMatcher) String() string {
}
type errorMatcher struct {
errorType ErrorType
errorType cel.ErrorType
contains string
}
func invalidError(contains string) validationMatcher {
return errorMatcher{errorType: ErrorTypeInvalid, contains: contains}
return errorMatcher{errorType: cel.ErrorTypeInvalid, contains: contains}
}
func (v errorMatcher) matches(cr CompilationResult) bool {

View File

@ -1,4 +0,0 @@
This directory contains a port of https://github.com/google/cel-policy-templates-go/tree/master/policy/model modified in a few ways:
- Uses the Structural schema types
- All template related code has been removed

View File

@ -22,37 +22,16 @@ import (
"github.com/google/cel-go/cel"
"github.com/google/cel-go/common/types"
apiservercel "k8s.io/apiserver/pkg/cel"
"k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
)
const (
// the largest request that will be accepted is 3MB
// TODO(DangerOnTheRanger): wire in MaxRequestBodyBytes from apiserver/pkg/server/options/server_run_options.go to make this configurable
maxRequestSizeBytes = int64(3 * 1024 * 1024)
// OpenAPI duration strings follow RFC 3339, section 5.6 - see the comment on maxDatetimeSizeJSON
maxDurationSizeJSON = 32
// OpenAPI datetime strings follow RFC 3339, section 5.6, and the longest possible
// such string is 9999-12-31T23:59:59.999999999Z, which has length 30 - we add 2
// to allow for quotation marks
maxDatetimeSizeJSON = 32
// Golang allows a string of 0 to be parsed as a duration, so that plus 2 to account for
// quotation marks makes 3
minDurationSizeJSON = 3
// RFC 3339 dates require YYYY-MM-DD, and then we add 2 to allow for quotation marks
dateSizeJSON = 12
// RFC 3339 datetimes require a full date (YYYY-MM-DD) and full time (HH:MM:SS), and we add 3 for
// quotation marks like always in addition to the capital T that separates the date and time
minDatetimeSizeJSON = 21
// ""
minStringSize = 2
// true
minBoolSize = 4
// 0
minNumberSize = 1
)
// TODO(DangerOnTheRanger): wire in MaxRequestBodyBytes from apiserver/pkg/server/options/server_run_options.go to make this configurable
const maxRequestSizeBytes = apiservercel.DefaultMaxRequestSizeBytes
// SchemaDeclType converts the structural schema to a CEL declaration, or returns nil if the
// the structural schema should not be exposed in CEL expressions.
// structural schema should not be exposed in CEL expressions.
// Set isResourceRoot to true for the root of a custom resource or embedded resource.
//
// Schemas with XPreserveUnknownFields not exposed unless they are objects. Array and "maps" schemas
@ -60,7 +39,7 @@ const (
// if their schema is not exposed.
//
// The CEL declaration for objects with XPreserveUnknownFields does not expose unknown fields.
func SchemaDeclType(s *schema.Structural, isResourceRoot bool) *DeclType {
func SchemaDeclType(s *schema.Structural, isResourceRoot bool) *apiservercel.DeclType {
if s == nil {
return nil
}
@ -77,7 +56,7 @@ func SchemaDeclType(s *schema.Structural, isResourceRoot bool) *DeclType {
// To validate requirements on both the int and string representation:
// `type(intOrStringField) == int ? intOrStringField < 5 : double(intOrStringField.replace('%', '')) < 0.5
//
dyn := newSimpleTypeWithMinSize("dyn", cel.DynType, nil, 1) // smallest value for a serialied x-kubernetes-int-or-string is 0
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
return dyn
@ -106,7 +85,7 @@ func SchemaDeclType(s *schema.Structural, isResourceRoot bool) *DeclType {
} else {
maxItems = estimateMaxArrayItemsFromMinSize(itemsType.MinSerializedSize)
}
return NewListType(itemsType, maxItems)
return apiservercel.NewListType(itemsType, maxItems)
}
return nil
case "object":
@ -119,11 +98,11 @@ func SchemaDeclType(s *schema.Structural, isResourceRoot bool) *DeclType {
} else {
maxProperties = estimateMaxAdditionalPropertiesFromMinSize(propsType.MinSerializedSize)
}
return NewMapType(StringType, propsType, maxProperties)
return apiservercel.NewMapType(apiservercel.StringType, propsType, maxProperties)
}
return nil
}
fields := make(map[string]*DeclField, len(s.Properties))
fields := make(map[string]*apiservercel.DeclField, len(s.Properties))
required := map[string]bool{}
if s.ValueValidation != nil {
@ -141,14 +120,8 @@ func SchemaDeclType(s *schema.Structural, isResourceRoot bool) *DeclType {
}
}
if fieldType := SchemaDeclType(&prop, prop.XEmbeddedResource); fieldType != nil {
if propName, ok := Escape(name); ok {
fields[propName] = &DeclField{
Name: propName,
Required: required[name],
Type: fieldType,
defaultValue: prop.Default.Object,
enumValues: enumValues, // Enum values are represented as strings in CEL
}
if propName, ok := apiservercel.Escape(name); ok {
fields[propName] = apiservercel.NewDeclField(propName, fieldType, required[name], enumValues, prop.Default.Object)
}
// the min serialized size for an object is 2 (for {}) plus the min size of all its required
// properties
@ -159,14 +132,14 @@ func SchemaDeclType(s *schema.Structural, isResourceRoot bool) *DeclType {
}
}
}
objType := NewObjectType("object", fields)
objType := apiservercel.NewObjectType("object", fields)
objType.MinSerializedSize = minSerializedSize
return objType
case "string":
if s.ValueValidation != nil {
switch s.ValueValidation.Format {
case "byte":
byteWithMaxLength := newSimpleTypeWithMinSize("bytes", cel.BytesType, types.Bytes([]byte{}), minStringSize)
byteWithMaxLength := apiservercel.NewSimpleTypeWithMinSize("bytes", cel.BytesType, types.Bytes([]byte{}), apiservercel.MinStringSize)
if s.ValueValidation.MaxLength != nil {
byteWithMaxLength.MaxElements = zeroIfNegative(*s.ValueValidation.MaxLength)
} else {
@ -174,20 +147,20 @@ func SchemaDeclType(s *schema.Structural, isResourceRoot bool) *DeclType {
}
return byteWithMaxLength
case "duration":
durationWithMaxLength := newSimpleTypeWithMinSize("duration", cel.DurationType, types.Duration{Duration: time.Duration(0)}, int64(minDurationSizeJSON))
durationWithMaxLength := apiservercel.NewSimpleTypeWithMinSize("duration", cel.DurationType, types.Duration{Duration: time.Duration(0)}, int64(apiservercel.MinDurationSizeJSON))
durationWithMaxLength.MaxElements = estimateMaxStringLengthPerRequest(s)
return durationWithMaxLength
case "date":
timestampWithMaxLength := newSimpleTypeWithMinSize("timestamp", cel.TimestampType, types.Timestamp{Time: time.Time{}}, int64(dateSizeJSON))
timestampWithMaxLength := apiservercel.NewSimpleTypeWithMinSize("timestamp", cel.TimestampType, types.Timestamp{Time: time.Time{}}, int64(apiservercel.JSONDateSize))
timestampWithMaxLength.MaxElements = estimateMaxStringLengthPerRequest(s)
return timestampWithMaxLength
case "date-time":
timestampWithMaxLength := newSimpleTypeWithMinSize("timestamp", cel.TimestampType, types.Timestamp{Time: time.Time{}}, int64(minDatetimeSizeJSON))
timestampWithMaxLength := apiservercel.NewSimpleTypeWithMinSize("timestamp", cel.TimestampType, types.Timestamp{Time: time.Time{}}, int64(apiservercel.MinDatetimeSizeJSON))
timestampWithMaxLength.MaxElements = estimateMaxStringLengthPerRequest(s)
return timestampWithMaxLength
}
}
strWithMaxLength := newSimpleTypeWithMinSize("string", cel.StringType, types.String(""), minStringSize)
strWithMaxLength := apiservercel.NewSimpleTypeWithMinSize("string", cel.StringType, types.String(""), apiservercel.MinStringSize)
if s.ValueValidation != nil && s.ValueValidation.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,
@ -199,11 +172,11 @@ func SchemaDeclType(s *schema.Structural, isResourceRoot bool) *DeclType {
}
return strWithMaxLength
case "boolean":
return BoolType
return apiservercel.BoolType
case "number":
return DoubleType
return apiservercel.DoubleType
case "integer":
return IntType
return apiservercel.IntType
}
return nil
}
@ -268,18 +241,18 @@ func MaxCardinality(minSize int64) uint64 {
func estimateMaxStringLengthPerRequest(s *schema.Structural) int64 {
if s.ValueValidation == nil || s.XIntOrString {
// subtract 2 to account for ""
return (maxRequestSizeBytes - 2)
return maxRequestSizeBytes - 2
}
switch s.ValueValidation.Format {
case "duration":
return maxDurationSizeJSON
return apiservercel.MaxDurationSizeJSON
case "date":
return dateSizeJSON
return apiservercel.JSONDateSize
case "date-time":
return maxDatetimeSizeJSON
return apiservercel.MaxDatetimeSizeJSON
default:
// subtract 2 to account for ""
return (maxRequestSizeBytes - 2)
return maxRequestSizeBytes - 2
}
}

View File

@ -25,6 +25,7 @@ import (
"google.golang.org/protobuf/proto"
"k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
apiservercel "k8s.io/apiserver/pkg/cel"
)
func TestSchemaDeclType(t *testing.T) {
@ -86,15 +87,15 @@ func TestSchemaDeclType(t *testing.T) {
func TestSchemaDeclTypes(t *testing.T) {
ts := testSchema()
cust := SchemaDeclType(ts, true).MaybeAssignTypeName("CustomObject")
typeMap := FieldTypeMap("CustomObject", cust)
typeMap := apiservercel.FieldTypeMap("CustomObject", cust)
nested, _ := cust.FindField("nested")
metadata, _ := cust.FindField("metadata")
expectedObjTypeMap := map[string]*DeclType{
expectedObjTypeMap := map[string]*apiservercel.DeclType{
"CustomObject": cust,
"CustomObject.nested": nested.Type,
"CustomObject.metadata": metadata.Type,
}
objTypeMap := map[string]*DeclType{}
objTypeMap := map[string]*apiservercel.DeclType{}
for name, t := range typeMap {
if t.IsObject() {
objTypeMap[name] = t
@ -406,7 +407,7 @@ func TestEstimateMaxLengthJSON(t *testing.T) {
},
},
// should be exactly equal to maxDurationSizeJSON
ExpectedMaxElements: maxDurationSizeJSON,
ExpectedMaxElements: apiservercel.MaxDurationSizeJSON,
},
{
Name: "dateSize",
@ -419,7 +420,7 @@ func TestEstimateMaxLengthJSON(t *testing.T) {
},
},
// should be exactly equal to dateSizeJSON
ExpectedMaxElements: dateSizeJSON,
ExpectedMaxElements: apiservercel.JSONDateSize,
},
{
Name: "maxdatetimeSize",
@ -432,7 +433,7 @@ func TestEstimateMaxLengthJSON(t *testing.T) {
},
},
// should be exactly equal to maxDatetimeSizeJSON
ExpectedMaxElements: maxDatetimeSizeJSON,
ExpectedMaxElements: apiservercel.MaxDatetimeSizeJSON,
},
{
Name: "maxintOrStringSize",
@ -442,7 +443,7 @@ func TestEstimateMaxLengthJSON(t *testing.T) {
},
},
// should be exactly equal to maxRequestSizeBytes - 2 (to allow for quotes in the case of a string)
ExpectedMaxElements: maxRequestSizeBytes - 2,
ExpectedMaxElements: apiservercel.DefaultMaxRequestSizeBytes - 2,
},
{
Name: "objectDefaultFieldArray",
@ -495,7 +496,7 @@ func TestEstimateMaxLengthJSON(t *testing.T) {
},
},
// note that unlike regular strings we don't have to take unicode into account,
// so we we expect the max length to be exactly equal to the user-supplied one
// so we expect the max length to be exactly equal to the user-supplied one
ExpectedMaxElements: 20,
},
}

View File

@ -23,61 +23,14 @@ import (
"github.com/google/cel-go/common/types"
exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
apiservercel "k8s.io/apiserver/pkg/cel"
)
func TestTypes_ListType(t *testing.T) {
list := NewListType(StringType, -1)
if !list.IsList() {
t.Error("list type not identifiable as list")
}
if list.TypeName() != "list" {
t.Errorf("got %s, wanted list", list.TypeName())
}
if list.DefaultValue() == nil {
t.Error("got nil zero value for list type")
}
if list.ElemType.TypeName() != "string" {
t.Errorf("got %s, wanted elem type of string", list.ElemType.TypeName())
}
expT, err := list.ExprType()
if err != nil {
t.Errorf("fail to get cel type: %s", err)
}
if expT.GetListType() == nil {
t.Errorf("got %v, wanted CEL list type", expT)
}
}
func TestTypes_MapType(t *testing.T) {
mp := NewMapType(StringType, IntType, -1)
if !mp.IsMap() {
t.Error("map type not identifiable as map")
}
if mp.TypeName() != "map" {
t.Errorf("got %s, wanted map", mp.TypeName())
}
if mp.DefaultValue() == nil {
t.Error("got nil zero value for map type")
}
if mp.KeyType.TypeName() != "string" {
t.Errorf("got %s, wanted key type of string", mp.KeyType.TypeName())
}
if mp.ElemType.TypeName() != "int" {
t.Errorf("got %s, wanted elem type of int", mp.ElemType.TypeName())
}
expT, err := mp.ExprType()
if err != nil {
t.Errorf("fail to get cel type: %s", err)
}
if expT.GetMapType() == nil {
t.Errorf("got %v, wanted CEL map type", expT)
}
}
func TestTypes_RuleTypesFieldMapping(t *testing.T) {
stdEnv, _ := cel.NewEnv()
reg := NewRegistry(stdEnv)
rt, err := NewRuleTypes("CustomObject", SchemaDeclType(testSchema(), true), reg)
reg := apiservercel.NewRegistry(stdEnv)
rt, err := apiservercel.NewRuleTypes("CustomObject", SchemaDeclType(testSchema(), true), reg)
if err != nil {
t.Fatal(err)
}
@ -112,22 +65,22 @@ func TestTypes_RuleTypesFieldMapping(t *testing.T) {
}
// Manually constructed instance of the schema.
name := NewField(1, "name")
name := apiservercel.NewField(1, "name")
name.Ref = testValue(t, 2, "test-instance")
nestedVal := NewMapValue()
flags := NewField(5, "flags")
flagsVal := NewMapValue()
myFlag := NewField(6, "my_flag")
nestedVal := apiservercel.NewMapValue()
flags := apiservercel.NewField(5, "flags")
flagsVal := apiservercel.NewMapValue()
myFlag := apiservercel.NewField(6, "my_flag")
myFlag.Ref = testValue(t, 7, true)
flagsVal.AddField(myFlag)
flags.Ref = testValue(t, 8, flagsVal)
dates := NewField(9, "dates")
dates.Ref = testValue(t, 10, NewListValue())
dates := apiservercel.NewField(9, "dates")
dates.Ref = testValue(t, 10, apiservercel.NewListValue())
nestedVal.AddField(flags)
nestedVal.AddField(dates)
nested := NewField(3, "nested")
nested := apiservercel.NewField(3, "nested")
nested.Ref = testValue(t, 4, nestedVal)
mapVal := NewMapValue()
mapVal := apiservercel.NewMapValue()
mapVal.AddField(name)
mapVal.AddField(nested)
//rule := rt.ConvertToRule(testValue(t, 11, mapVal))
@ -156,11 +109,11 @@ func TestTypes_RuleTypesFieldMapping(t *testing.T) {
}
}
func testValue(t *testing.T, id int64, val interface{}) *DynValue {
func testValue(t *testing.T, id int64, val interface{}) *apiservercel.DynValue {
t.Helper()
dv, err := NewDynValue(id, val)
dv, err := apiservercel.NewDynValue(id, val)
if err != nil {
t.Fatalf("model.NewDynValue(%d, %v) failed: %v", id, val, err)
t.Fatalf("NewDynValue(%d, %v) failed: %v", id, val, err)
}
return dv
}

View File

@ -30,9 +30,10 @@ import (
apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
"k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/metrics"
"k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/model"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/apiserver/pkg/cel"
"k8s.io/apiserver/pkg/cel/metrics"
)
// Validator parallels the structure of schema.Structural and includes the compiled CEL programs
@ -74,7 +75,7 @@ func NewValidator(s *schema.Structural, isResourceRoot bool, perCallLimit uint64
// validator creates a Validator for all x-kubernetes-validations at the level of the provided schema and lower and
// returns the Validator if any x-kubernetes-validations exist in the schema, or nil if no x-kubernetes-validations
// exist. declType is expected to be a CEL DeclType corresponding to the structural schema.
func validator(s *schema.Structural, isResourceRoot bool, declType *model.DeclType, perCallLimit uint64) *Validator {
func validator(s *schema.Structural, isResourceRoot bool, declType *cel.DeclType, perCallLimit uint64) *Validator {
compiledRules, err := Compile(s, declType, perCallLimit)
var itemsValidator, additionalPropertiesValidator *Validator
var propertiesValidators map[string]Validator
@ -85,8 +86,8 @@ func validator(s *schema.Structural, isResourceRoot bool, declType *model.DeclTy
propertiesValidators = make(map[string]Validator, len(s.Properties))
for k, p := range s.Properties {
prop := p
var fieldType *model.DeclType
if escapedPropName, ok := model.Escape(k); ok {
var fieldType *cel.DeclType
if escapedPropName, ok := cel.Escape(k); ok {
if f, ok := declType.Fields[escapedPropName]; ok {
fieldType = f.Type
} else {

View File

@ -25,10 +25,11 @@ import (
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
"github.com/google/cel-go/common/types/traits"
"k8s.io/apimachinery/pkg/api/equality"
structuralschema "k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
"k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/model"
"k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apiserver/pkg/cel"
"k8s.io/kube-openapi/pkg/validation/strfmt"
)
@ -343,7 +344,7 @@ func (t *unstructuredMapList) Add(other ref.Val) ref.Val {
func escapeKeyProps(idents []string) []string {
result := make([]string, len(idents))
for i, prop := range idents {
if escaped, ok := model.Escape(prop); ok {
if escaped, ok := cel.Escape(prop); ok {
result[i] = escaped
} else {
result[i] = prop
@ -644,7 +645,7 @@ func (t *unstructuredMap) Iterator() traits.Iterator {
if _, ok := t.propSchema(k); ok {
mapKey := k
if isObject {
if escaped, ok := model.Escape(k); ok {
if escaped, ok := cel.Escape(k); ok {
mapKey = escaped
}
}
@ -683,7 +684,7 @@ func (t *unstructuredMap) Find(key ref.Val) (ref.Val, bool) {
}
k := keyStr.Value().(string)
if isObject {
k, ok = model.Unescape(k)
k, ok = cel.Unescape(k)
if !ok {
return nil, false
}

View File

@ -12,6 +12,7 @@ require (
github.com/evanphx/json-patch v4.12.0+incompatible
github.com/fsnotify/fsnotify v1.5.4
github.com/gogo/protobuf v1.3.2
github.com/google/cel-go v0.12.5
github.com/google/gnostic v0.5.7-v3refs
github.com/google/go-cmp v0.5.9
github.com/google/gofuzz v1.1.0
@ -36,7 +37,9 @@ require (
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8
google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21
google.golang.org/grpc v1.49.0
google.golang.org/protobuf v1.28.1
gopkg.in/natefinch/lumberjack.v2 v2.0.0
gopkg.in/square/go-jose.v2 v2.2.2
k8s.io/api v0.0.0
@ -56,6 +59,7 @@ require (
require (
cloud.google.com/go v0.97.0 // indirect
github.com/NYTimes/gziphandler v1.1.1 // indirect
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
@ -95,6 +99,7 @@ require (
github.com/sirupsen/logrus v1.8.1 // indirect
github.com/soheilhy/cmux v0.1.5 // indirect
github.com/spf13/cobra v1.5.0 // indirect
github.com/stoewer/go-strcase v1.2.0 // indirect
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 // indirect
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
go.etcd.io/bbolt v1.3.6 // indirect
@ -111,8 +116,6 @@ require (
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
golang.org/x/text v0.3.8 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect

View File

@ -57,6 +57,8 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 h1:yL7+Jz0jTC6yykIK/Wh74gnTJnrGr5AyrNMXuA0gves=
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
@ -220,6 +222,8 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
github.com/google/cel-go v0.12.5 h1:DmzaiSgoaqGCjtpPQWl26/gND+yRpim56H1jCVev6d8=
github.com/google/cel-go v0.12.5/go.mod h1:Jk7ljRzLBhkmiAwBoUxB1sZSCVBAzkqPF25olK/iRDw=
github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54=
github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
@ -439,6 +443,7 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU=
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package model
package cel
import (
"regexp"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package model
package cel
import (
"fmt"

View File

@ -22,7 +22,8 @@ import (
"github.com/google/cel-go/cel"
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
"k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/model"
apiservercel "k8s.io/apiserver/pkg/cel"
)
// URLs provides a CEL function library extension of URL parsing functions.
@ -113,25 +114,25 @@ type urls struct{}
var urlLibraryDecls = map[string][]cel.FunctionOpt{
"url": {
cel.Overload("string_to_url", []*cel.Type{cel.StringType}, model.URLType,
cel.Overload("string_to_url", []*cel.Type{cel.StringType}, apiservercel.URLType,
cel.UnaryBinding(stringToUrl))},
"getScheme": {
cel.MemberOverload("url_get_scheme", []*cel.Type{model.URLType}, cel.StringType,
cel.MemberOverload("url_get_scheme", []*cel.Type{apiservercel.URLType}, cel.StringType,
cel.UnaryBinding(getScheme))},
"getHost": {
cel.MemberOverload("url_get_host", []*cel.Type{model.URLType}, cel.StringType,
cel.MemberOverload("url_get_host", []*cel.Type{apiservercel.URLType}, cel.StringType,
cel.UnaryBinding(getHost))},
"getHostname": {
cel.MemberOverload("url_get_hostname", []*cel.Type{model.URLType}, cel.StringType,
cel.MemberOverload("url_get_hostname", []*cel.Type{apiservercel.URLType}, cel.StringType,
cel.UnaryBinding(getHostname))},
"getPort": {
cel.MemberOverload("url_get_port", []*cel.Type{model.URLType}, cel.StringType,
cel.MemberOverload("url_get_port", []*cel.Type{apiservercel.URLType}, cel.StringType,
cel.UnaryBinding(getPort))},
"getEscapedPath": {
cel.MemberOverload("url_get_escaped_path", []*cel.Type{model.URLType}, cel.StringType,
cel.MemberOverload("url_get_escaped_path", []*cel.Type{apiservercel.URLType}, cel.StringType,
cel.UnaryBinding(getEscapedPath))},
"getQuery": {
cel.MemberOverload("url_get_query", []*cel.Type{model.URLType},
cel.MemberOverload("url_get_query", []*cel.Type{apiservercel.URLType},
cel.MapType(cel.StringType, cel.ListType(cel.StringType)),
cel.UnaryBinding(getQuery))},
"isURL": {
@ -169,7 +170,7 @@ func stringToUrl(arg ref.Val) ref.Val {
// Errors are not expected here since Parse is a more lenient parser than ParseRequestURI.
return types.NewErr("URL parse error during conversion from string: %v", err)
}
return model.URL{URL: u}
return apiservercel.URL{URL: u}
}
func getScheme(arg ref.Val) ref.Val {

View File

@ -0,0 +1,48 @@
/*
Copyright 2022 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cel
const (
// DefaultMaxRequestSizeBytes is the size of the largest request that will be accepted
DefaultMaxRequestSizeBytes = int64(3 * 1024 * 1024)
// MaxDurationSizeJSON
// OpenAPI duration strings follow RFC 3339, section 5.6 - see the comment on maxDatetimeSizeJSON
MaxDurationSizeJSON = 32
// MaxDatetimeSizeJSON
// OpenAPI datetime strings follow RFC 3339, section 5.6, and the longest possible
// such string is 9999-12-31T23:59:59.999999999Z, which has length 30 - we add 2
// to allow for quotation marks
MaxDatetimeSizeJSON = 32
// MinDurationSizeJSON
// Golang allows a string of 0 to be parsed as a duration, so that plus 2 to account for
// quotation marks makes 3
MinDurationSizeJSON = 3
// JSONDateSize is the size of a date serialized as part of a JSON object
// RFC 3339 dates require YYYY-MM-DD, and then we add 2 to allow for quotation marks
JSONDateSize = 12
// MinDatetimeSizeJSON is the minimal length of a datetime formatted as RFC 3339
// RFC 3339 datetimes require a full date (YYYY-MM-DD) and full time (HH:MM:SS), and we add 3 for
// quotation marks like always in addition to the capital T that separates the date and time
MinDatetimeSizeJSON = 21
// MinStringSize is the size of literal ""
MinStringSize = 2
// MinBoolSize is the length of literal true
MinBoolSize = 4
// MinNumberSize is the length of literal 0
MinNumberSize = 1
)

View File

@ -14,13 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package model
package cel
import (
"sync"
"github.com/google/cel-go/cel"
"k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
)
// Resolver declares methods to find policy templates and related configuration objects.
@ -30,12 +29,11 @@ type Resolver interface {
FindType(name string) (*DeclType, bool)
}
// NewRegistry create a registry for keeping track of environments, schemas, templates, and more
// NewRegistry create a registry for keeping track of environments and types
// from a base cel.Env expression environment.
func NewRegistry(stdExprEnv *cel.Env) *Registry {
return &Registry{
exprEnvs: map[string]*cel.Env{"": stdExprEnv},
schemas: map[string]*schema.Structural{},
types: map[string]*DeclType{
BoolType.TypeName(): BoolType,
BytesType.TypeName(): BytesType,
@ -58,7 +56,6 @@ func NewRegistry(stdExprEnv *cel.Env) *Registry {
type Registry struct {
rwMux sync.RWMutex
exprEnvs map[string]*cel.Env
schemas map[string]*schema.Structural
types map[string]*DeclType
}

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package model
package cel
import (
"fmt"
@ -79,7 +79,7 @@ func NewObjectType(name string, fields map[string]*DeclField) *DeclType {
return t
}
func newSimpleTypeWithMinSize(name string, celType *cel.Type, zeroVal ref.Val, minSize int64) *DeclType {
func NewSimpleTypeWithMinSize(name string, celType *cel.Type, zeroVal ref.Val, minSize int64) *DeclType {
return &DeclType{
name: name,
celType: celType,
@ -284,6 +284,16 @@ type DeclField struct {
defaultValue interface{}
}
func NewDeclField(name string, declType *DeclType, required bool, enumValues []interface{}, defaultValue interface{}) *DeclField {
return &DeclField{
Name: name,
Type: declType,
Required: required,
enumValues: enumValues,
defaultValue: defaultValue,
}
}
// TypeName returns the string type name of the field.
func (f *DeclField) TypeName() string {
return f.Type.TypeName()
@ -495,44 +505,44 @@ type schemaTypeProvider struct {
var (
// AnyType is equivalent to the CEL 'protobuf.Any' type in that the value may have any of the
// types supported.
AnyType = newSimpleTypeWithMinSize("any", cel.AnyType, nil, 1)
AnyType = NewSimpleTypeWithMinSize("any", cel.AnyType, nil, 1)
// BoolType is equivalent to the CEL 'bool' type.
BoolType = newSimpleTypeWithMinSize("bool", cel.BoolType, types.False, minBoolSize)
BoolType = NewSimpleTypeWithMinSize("bool", cel.BoolType, types.False, MinBoolSize)
// BytesType is equivalent to the CEL 'bytes' type.
BytesType = newSimpleTypeWithMinSize("bytes", cel.BytesType, types.Bytes([]byte{}), minStringSize)
BytesType = NewSimpleTypeWithMinSize("bytes", cel.BytesType, types.Bytes([]byte{}), MinStringSize)
// DoubleType is equivalent to the CEL 'double' type which is a 64-bit floating point value.
DoubleType = newSimpleTypeWithMinSize("double", cel.DoubleType, types.Double(0), minNumberSize)
DoubleType = NewSimpleTypeWithMinSize("double", cel.DoubleType, types.Double(0), MinNumberSize)
// DurationType is equivalent to the CEL 'duration' type.
DurationType = newSimpleTypeWithMinSize("duration", cel.DurationType, types.Duration{Duration: time.Duration(0)}, minDurationSizeJSON)
DurationType = NewSimpleTypeWithMinSize("duration", cel.DurationType, types.Duration{Duration: time.Duration(0)}, MinDurationSizeJSON)
// DateType is equivalent to the CEL 'date' type.
DateType = newSimpleTypeWithMinSize("date", cel.TimestampType, types.Timestamp{Time: time.Time{}}, dateSizeJSON)
DateType = NewSimpleTypeWithMinSize("date", cel.TimestampType, types.Timestamp{Time: time.Time{}}, JSONDateSize)
// DynType is the equivalent of the CEL 'dyn' concept which indicates that the type will be
// determined at runtime rather than compile time.
DynType = newSimpleTypeWithMinSize("dyn", cel.DynType, nil, 1)
DynType = NewSimpleTypeWithMinSize("dyn", cel.DynType, nil, 1)
// IntType is equivalent to the CEL 'int' type which is a 64-bit signed int.
IntType = newSimpleTypeWithMinSize("int", cel.IntType, types.IntZero, minNumberSize)
IntType = NewSimpleTypeWithMinSize("int", cel.IntType, types.IntZero, MinNumberSize)
// NullType is equivalent to the CEL 'null_type'.
NullType = newSimpleTypeWithMinSize("null_type", cel.NullType, types.NullValue, 4)
NullType = NewSimpleTypeWithMinSize("null_type", cel.NullType, types.NullValue, 4)
// StringType is equivalent to the CEL 'string' type which is expected to be a UTF-8 string.
// StringType values may either be string literals or expression strings.
StringType = newSimpleTypeWithMinSize("string", cel.StringType, types.String(""), minStringSize)
StringType = NewSimpleTypeWithMinSize("string", cel.StringType, types.String(""), MinStringSize)
// TimestampType corresponds to the well-known protobuf.Timestamp type supported within CEL.
// Note that both the OpenAPI date and date-time types map onto TimestampType, so not all types
// labeled as Timestamp will necessarily have the same MinSerializedSize.
TimestampType = newSimpleTypeWithMinSize("timestamp", cel.TimestampType, types.Timestamp{Time: time.Time{}}, dateSizeJSON)
TimestampType = NewSimpleTypeWithMinSize("timestamp", cel.TimestampType, types.Timestamp{Time: time.Time{}}, JSONDateSize)
// UintType is equivalent to the CEL 'uint' type.
UintType = newSimpleTypeWithMinSize("uint", cel.UintType, types.Uint(0), 1)
UintType = NewSimpleTypeWithMinSize("uint", cel.UintType, types.Uint(0), 1)
// ListType is equivalent to the CEL 'list' type.
ListType = NewListType(AnyType, noMaxLength)

View File

@ -0,0 +1,79 @@
/*
Copyright 2022 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cel
import (
"testing"
)
func TestTypes_ListType(t *testing.T) {
list := NewListType(StringType, -1)
if !list.IsList() {
t.Error("list type not identifiable as list")
}
if list.TypeName() != "list" {
t.Errorf("got %s, wanted list", list.TypeName())
}
if list.DefaultValue() == nil {
t.Error("got nil zero value for list type")
}
if list.ElemType.TypeName() != "string" {
t.Errorf("got %s, wanted elem type of string", list.ElemType.TypeName())
}
expT, err := list.ExprType()
if err != nil {
t.Errorf("fail to get cel type: %s", err)
}
if expT.GetListType() == nil {
t.Errorf("got %v, wanted CEL list type", expT)
}
}
func TestTypes_MapType(t *testing.T) {
mp := NewMapType(StringType, IntType, -1)
if !mp.IsMap() {
t.Error("map type not identifiable as map")
}
if mp.TypeName() != "map" {
t.Errorf("got %s, wanted map", mp.TypeName())
}
if mp.DefaultValue() == nil {
t.Error("got nil zero value for map type")
}
if mp.KeyType.TypeName() != "string" {
t.Errorf("got %s, wanted key type of string", mp.KeyType.TypeName())
}
if mp.ElemType.TypeName() != "int" {
t.Errorf("got %s, wanted elem type of int", mp.ElemType.TypeName())
}
expT, err := mp.ExprType()
if err != nil {
t.Errorf("fail to get cel type: %s", err)
}
if expT.GetMapType() == nil {
t.Errorf("got %v, wanted CEL map type", expT)
}
}
func testValue(t *testing.T, id int64, val interface{}) *DynValue {
t.Helper()
dv, err := NewDynValue(id, val)
if err != nil {
t.Fatalf("NewDynValue(%d, %v) failed: %v", id, val, err)
}
return dv
}

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package model
package cel
import (
"fmt"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package model
package cel
import (
"fmt"

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package model
package cel
import (
"fmt"

View File

@ -366,7 +366,7 @@ func NewConfig(codecs serializer.CodecFactory) *Config {
// A request body might be encoded in json, and is converted to
// proto when persisted in etcd, so we allow 2x as the largest request
// body size to be accepted and decoded in a write request.
// If this constant is changed, maxRequestSizeBytes in apiextensions-apiserver/pkg/apiserver/schema/cel/model/schemas.go
// If this constant is changed, DefaultMaxRequestSizeBytes in k8s.io/apiserver/pkg/cel/limits.go
// should be changed to reflect the new value, if the two haven't
// been wired together already somehow.
MaxRequestBodyBytes: int64(3 * 1024 * 1024),

5
vendor/modules.txt vendored
View File

@ -1321,8 +1321,6 @@ k8s.io/apiextensions-apiserver/pkg/apiserver
k8s.io/apiextensions-apiserver/pkg/apiserver/conversion
k8s.io/apiextensions-apiserver/pkg/apiserver/schema
k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel
k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/library
k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/metrics
k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/model
k8s.io/apiextensions-apiserver/pkg/apiserver/schema/defaulting
k8s.io/apiextensions-apiserver/pkg/apiserver/schema/listtype
@ -1492,6 +1490,9 @@ k8s.io/apiserver/pkg/authorization/authorizer
k8s.io/apiserver/pkg/authorization/authorizerfactory
k8s.io/apiserver/pkg/authorization/path
k8s.io/apiserver/pkg/authorization/union
k8s.io/apiserver/pkg/cel
k8s.io/apiserver/pkg/cel/library
k8s.io/apiserver/pkg/cel/metrics
k8s.io/apiserver/pkg/endpoints
k8s.io/apiserver/pkg/endpoints/deprecation
k8s.io/apiserver/pkg/endpoints/discovery