k8s.io/apiserver@v0.31.1/pkg/cel/mutation/typeprovider.go (about) 1 /* 2 Copyright 2024 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package mutation 18 19 import ( 20 "k8s.io/apiserver/pkg/cel/mutation/common" 21 22 "github.com/google/cel-go/cel" 23 "github.com/google/cel-go/common/types" 24 "github.com/google/cel-go/common/types/ref" 25 ) 26 27 // TypeProvider is a specialized CEL type provider that understands 28 // the Object type alias that is used to construct an Apply configuration for 29 // a mutation operation. 30 type TypeProvider struct { 31 typeResolver common.TypeResolver 32 underlyingTypeProvider types.Provider 33 } 34 35 var _ types.Provider = (*TypeProvider)(nil) 36 37 // EnumValue returns the numeric value of the given enum value name. 38 // This TypeProvider does not have special handling for EnumValue and thus directly delegate 39 // to its underlying type provider. 40 func (p *TypeProvider) EnumValue(enumName string) ref.Val { 41 return p.underlyingTypeProvider.EnumValue(enumName) 42 } 43 44 // FindIdent takes a qualified identifier name and returns a ref.ObjectVal if one exists. 45 // This TypeProvider does not have special handling for FindIdent and thus directly delegate 46 // to its underlying type provider. 47 func (p *TypeProvider) FindIdent(identName string) (ref.Val, bool) { 48 return p.underlyingTypeProvider.FindIdent(identName) 49 } 50 51 // FindStructType returns the Type give a qualified type name, by looking it up with 52 // the TypeResolver and translating it to CEL Type. 53 // If the type is not known to the TypeResolver, the lookup falls back to the underlying 54 // TypeProvider instead. 55 func (p *TypeProvider) FindStructType(structType string) (*types.Type, bool) { 56 t, ok := p.typeResolver.Resolve(structType) 57 if ok { 58 return t.CELType(), true 59 } 60 return p.underlyingTypeProvider.FindStructType(structType) 61 } 62 63 // FindStructFieldNames returns the field names associated with the type, if the type 64 // is found. 65 func (p *TypeProvider) FindStructFieldNames(structType string) ([]string, bool) { 66 return nil, true 67 } 68 69 // FindStructFieldType returns the field type for a checked type value. 70 // Returns false if the field could not be found. 71 func (p *TypeProvider) FindStructFieldType(structType, fieldName string) (*types.FieldType, bool) { 72 t, ok := p.typeResolver.Resolve(structType) 73 if ok { 74 return t.Field(fieldName) 75 } 76 return p.underlyingTypeProvider.FindStructFieldType(structType, fieldName) 77 } 78 79 // NewValue creates a new type value from a qualified name and map of fields. 80 func (p *TypeProvider) NewValue(structType string, fields map[string]ref.Val) ref.Val { 81 t, ok := p.typeResolver.Resolve(structType) 82 if ok { 83 return t.Val(fields) 84 } 85 return p.underlyingTypeProvider.NewValue(structType, fields) 86 } 87 88 // NewTypeProviderAndEnvOption creates the TypeProvider with a given TypeResolver, 89 // and also returns the CEL EnvOption to apply it to the env. 90 func NewTypeProviderAndEnvOption(resolver common.TypeResolver) (*TypeProvider, cel.EnvOption) { 91 tp := &TypeProvider{typeResolver: resolver} 92 var envOption cel.EnvOption = func(e *cel.Env) (*cel.Env, error) { 93 // wrap the existing type provider (acquired from the env) 94 // and set new type provider for the env. 95 tp.underlyingTypeProvider = e.CELTypeProvider() 96 typeProviderOption := cel.CustomTypeProvider(tp) 97 return typeProviderOption(e) 98 } 99 return tp, envOption 100 }