mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-14 18:53:35 +00:00
rebase: update K8s packages to v0.32.1
Update K8s packages in go.mod to v0.32.1 Signed-off-by: Praveen M <m.praveen@ibm.com>
This commit is contained in:
127
vendor/k8s.io/apiserver/pkg/cel/common/typeprovider.go
generated
vendored
Normal file
127
vendor/k8s.io/apiserver/pkg/cel/common/typeprovider.go
generated
vendored
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
Copyright 2024 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 common
|
||||
|
||||
import (
|
||||
"github.com/google/cel-go/cel"
|
||||
"github.com/google/cel-go/common/types"
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
)
|
||||
|
||||
// TypeResolver resolves a type by a given name.
|
||||
type TypeResolver interface {
|
||||
// Resolve resolves the type by its name.
|
||||
// This function returns false if the name does not refer to a known object type.
|
||||
Resolve(name string) (ResolvedType, bool)
|
||||
}
|
||||
|
||||
// ResolvedType refers an object type that can be looked up for its fields.
|
||||
type ResolvedType interface {
|
||||
ref.Type
|
||||
|
||||
Type() *types.Type
|
||||
|
||||
// Field finds the field by the field name, or false if the field is not known.
|
||||
// This function directly return a FieldType that is known to CEL to be more customizable.
|
||||
Field(name string) (*types.FieldType, bool)
|
||||
|
||||
// FieldNames returns the field names associated with the type, if the type
|
||||
// is found.
|
||||
FieldNames() ([]string, bool)
|
||||
|
||||
// Val creates an instance for the ResolvedType, given its fields and their values.
|
||||
Val(fields map[string]ref.Val) ref.Val
|
||||
}
|
||||
|
||||
// ResolverTypeProvider delegates type resolution first to the TypeResolver and then
|
||||
// to the underlying types.Provider for types not resolved by the TypeResolver.
|
||||
type ResolverTypeProvider struct {
|
||||
typeResolver TypeResolver
|
||||
underlyingTypeProvider types.Provider
|
||||
}
|
||||
|
||||
var _ types.Provider = (*ResolverTypeProvider)(nil)
|
||||
|
||||
// FindStructType returns the Type give a qualified type name, by looking it up with
|
||||
// the DynamicTypeResolver and translating it to CEL Type.
|
||||
// If the type is not known to the DynamicTypeResolver, the lookup falls back to the underlying
|
||||
// ResolverTypeProvider instead.
|
||||
func (p *ResolverTypeProvider) FindStructType(structType string) (*types.Type, bool) {
|
||||
t, ok := p.typeResolver.Resolve(structType)
|
||||
if ok {
|
||||
return types.NewTypeTypeWithParam(t.Type()), true
|
||||
}
|
||||
return p.underlyingTypeProvider.FindStructType(structType)
|
||||
}
|
||||
|
||||
// FindStructFieldNames returns the field names associated with the type, if the type
|
||||
// is found.
|
||||
func (p *ResolverTypeProvider) FindStructFieldNames(structType string) ([]string, bool) {
|
||||
t, ok := p.typeResolver.Resolve(structType)
|
||||
if ok {
|
||||
return t.FieldNames()
|
||||
}
|
||||
return p.underlyingTypeProvider.FindStructFieldNames(structType)
|
||||
}
|
||||
|
||||
// FindStructFieldType returns the field type for a checked type value.
|
||||
// Returns false if the field could not be found.
|
||||
func (p *ResolverTypeProvider) FindStructFieldType(structType, fieldName string) (*types.FieldType, bool) {
|
||||
t, ok := p.typeResolver.Resolve(structType)
|
||||
if ok {
|
||||
return t.Field(fieldName)
|
||||
}
|
||||
return p.underlyingTypeProvider.FindStructFieldType(structType, fieldName)
|
||||
}
|
||||
|
||||
// NewValue creates a new type value from a qualified name and map of fields.
|
||||
func (p *ResolverTypeProvider) NewValue(structType string, fields map[string]ref.Val) ref.Val {
|
||||
t, ok := p.typeResolver.Resolve(structType)
|
||||
if ok {
|
||||
return t.Val(fields)
|
||||
}
|
||||
return p.underlyingTypeProvider.NewValue(structType, fields)
|
||||
}
|
||||
|
||||
func (p *ResolverTypeProvider) EnumValue(enumName string) ref.Val {
|
||||
return p.underlyingTypeProvider.EnumValue(enumName)
|
||||
}
|
||||
|
||||
func (p *ResolverTypeProvider) FindIdent(identName string) (ref.Val, bool) {
|
||||
return p.underlyingTypeProvider.FindIdent(identName)
|
||||
}
|
||||
|
||||
// ResolverEnvOption creates the ResolverTypeProvider with a given DynamicTypeResolver,
|
||||
// and also returns the CEL ResolverEnvOption to apply it to the env.
|
||||
func ResolverEnvOption(resolver TypeResolver) cel.EnvOption {
|
||||
_, envOpt := NewResolverTypeProviderAndEnvOption(resolver)
|
||||
return envOpt
|
||||
}
|
||||
|
||||
// NewResolverTypeProviderAndEnvOption creates the ResolverTypeProvider with a given DynamicTypeResolver,
|
||||
// and also returns the CEL ResolverEnvOption to apply it to the env.
|
||||
func NewResolverTypeProviderAndEnvOption(resolver TypeResolver) (*ResolverTypeProvider, cel.EnvOption) {
|
||||
tp := &ResolverTypeProvider{typeResolver: resolver}
|
||||
var envOption cel.EnvOption = func(e *cel.Env) (*cel.Env, error) {
|
||||
// wrap the existing type provider (acquired from the env)
|
||||
// and set new type provider for the env.
|
||||
tp.underlyingTypeProvider = e.CELTypeProvider()
|
||||
typeProviderOption := cel.CustomTypeProvider(tp)
|
||||
return typeProviderOption(e)
|
||||
}
|
||||
return tp, envOption
|
||||
}
|
68
vendor/k8s.io/apiserver/pkg/cel/environment/base.go
generated
vendored
68
vendor/k8s.io/apiserver/pkg/cel/environment/base.go
generated
vendored
@ -33,7 +33,8 @@ import (
|
||||
"k8s.io/apiserver/pkg/cel/library"
|
||||
genericfeatures "k8s.io/apiserver/pkg/features"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
utilversion "k8s.io/apiserver/pkg/util/version"
|
||||
"k8s.io/component-base/featuregate"
|
||||
utilversion "k8s.io/component-base/version"
|
||||
)
|
||||
|
||||
// DefaultCompatibilityVersion returns a default compatibility version for use with EnvSet
|
||||
@ -49,7 +50,7 @@ import (
|
||||
// A default version number equal to the current Kubernetes major.minor version
|
||||
// indicates fast forward CEL features that can be used when rollback is no longer needed.
|
||||
func DefaultCompatibilityVersion() *version.Version {
|
||||
effectiveVer := utilversion.DefaultComponentGlobalsRegistry.EffectiveVersionFor(utilversion.DefaultKubeComponent)
|
||||
effectiveVer := featuregate.DefaultComponentGlobalsRegistry.EffectiveVersionFor(featuregate.DefaultKubeComponent)
|
||||
if effectiveVer == nil {
|
||||
effectiveVer = utilversion.DefaultKubeEffectiveVersion()
|
||||
}
|
||||
@ -71,9 +72,9 @@ var baseOptsWithoutStrictCost = []VersionedOptions{
|
||||
cel.EagerlyValidateDeclarations(true),
|
||||
cel.DefaultUTCTimeZone(true),
|
||||
|
||||
library.URLs(),
|
||||
library.Regex(),
|
||||
library.Lists(),
|
||||
UnversionedLib(library.URLs),
|
||||
UnversionedLib(library.Regex),
|
||||
UnversionedLib(library.Lists),
|
||||
|
||||
// cel-go v0.17.7 change the cost of has() from 0 to 1, but also provided the CostEstimatorOptions option to preserve the old behavior, so we enabled it at the same time we bumped our cel version to v0.17.7.
|
||||
// Since it is a regression fix, we apply it uniformly to all code use v0.17.7.
|
||||
@ -91,7 +92,7 @@ var baseOptsWithoutStrictCost = []VersionedOptions{
|
||||
{
|
||||
IntroducedVersion: version.MajorMinor(1, 27),
|
||||
EnvOptions: []cel.EnvOption{
|
||||
library.Authz(),
|
||||
UnversionedLib(library.Authz),
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -99,7 +100,7 @@ var baseOptsWithoutStrictCost = []VersionedOptions{
|
||||
EnvOptions: []cel.EnvOption{
|
||||
cel.CrossTypeNumericComparisons(true),
|
||||
cel.OptionalTypes(),
|
||||
library.Quantity(),
|
||||
UnversionedLib(library.Quantity),
|
||||
},
|
||||
},
|
||||
// add the new validator in 1.29
|
||||
@ -138,15 +139,15 @@ var baseOptsWithoutStrictCost = []VersionedOptions{
|
||||
{
|
||||
IntroducedVersion: version.MajorMinor(1, 30),
|
||||
EnvOptions: []cel.EnvOption{
|
||||
library.IP(),
|
||||
library.CIDR(),
|
||||
UnversionedLib(library.IP),
|
||||
UnversionedLib(library.CIDR),
|
||||
},
|
||||
},
|
||||
// Format Library
|
||||
{
|
||||
IntroducedVersion: version.MajorMinor(1, 31),
|
||||
EnvOptions: []cel.EnvOption{
|
||||
library.Format(),
|
||||
UnversionedLib(library.Format),
|
||||
},
|
||||
},
|
||||
// Authz selectors
|
||||
@ -165,7 +166,14 @@ var baseOptsWithoutStrictCost = []VersionedOptions{
|
||||
return enabled
|
||||
},
|
||||
EnvOptions: []cel.EnvOption{
|
||||
library.AuthzSelectors(),
|
||||
UnversionedLib(library.AuthzSelectors),
|
||||
},
|
||||
},
|
||||
// Two variable comprehensions
|
||||
{
|
||||
IntroducedVersion: version.MajorMinor(1, 32),
|
||||
EnvOptions: []cel.EnvOption{
|
||||
UnversionedLib(ext.TwoVarComprehensions),
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -191,6 +199,19 @@ var StrictCostOpt = VersionedOptions{
|
||||
},
|
||||
}
|
||||
|
||||
// cacheBaseEnvs controls whether calls to MustBaseEnvSet are cached.
|
||||
// Defaults to true, may be disabled by calling DisableBaseEnvSetCachingForTests.
|
||||
var cacheBaseEnvs = true
|
||||
|
||||
// DisableBaseEnvSetCachingForTests clears and disables base env caching.
|
||||
// This is only intended for unit tests exercising MustBaseEnvSet directly with different enablement options.
|
||||
// It does not clear other initialization paths that may cache results of calling MustBaseEnvSet.
|
||||
func DisableBaseEnvSetCachingForTests() {
|
||||
cacheBaseEnvs = false
|
||||
baseEnvs.Clear()
|
||||
baseEnvsWithOption.Clear()
|
||||
}
|
||||
|
||||
// MustBaseEnvSet returns the common CEL base environments for Kubernetes for Version, or panics
|
||||
// if the version is nil, or does not have major and minor components.
|
||||
//
|
||||
@ -216,7 +237,9 @@ func MustBaseEnvSet(ver *version.Version, strictCost bool) *EnvSet {
|
||||
}
|
||||
entry, _, _ = baseEnvsSingleflight.Do(key, func() (interface{}, error) {
|
||||
entry := mustNewEnvSet(ver, baseOpts)
|
||||
baseEnvs.Store(key, entry)
|
||||
if cacheBaseEnvs {
|
||||
baseEnvs.Store(key, entry)
|
||||
}
|
||||
return entry, nil
|
||||
})
|
||||
} else {
|
||||
@ -225,7 +248,9 @@ func MustBaseEnvSet(ver *version.Version, strictCost bool) *EnvSet {
|
||||
}
|
||||
entry, _, _ = baseEnvsWithOptionSingleflight.Do(key, func() (interface{}, error) {
|
||||
entry := mustNewEnvSet(ver, baseOptsWithoutStrictCost)
|
||||
baseEnvsWithOption.Store(key, entry)
|
||||
if cacheBaseEnvs {
|
||||
baseEnvsWithOption.Store(key, entry)
|
||||
}
|
||||
return entry, nil
|
||||
})
|
||||
}
|
||||
@ -239,3 +264,20 @@ var (
|
||||
baseEnvsSingleflight = &singleflight.Group{}
|
||||
baseEnvsWithOptionSingleflight = &singleflight.Group{}
|
||||
)
|
||||
|
||||
// UnversionedLib wraps library initialization calls like ext.Sets() or library.IP()
|
||||
// to force compilation errors if the call evolves to include a varadic variable option.
|
||||
//
|
||||
// This provides automatic detection of a problem that is hard to catch in review--
|
||||
// If a CEL library used in Kubernetes is unversioned and then become versioned, and we
|
||||
// fail to set a desired version, the libraries defaults to the latest version, changing
|
||||
// CEL environment without controlled rollout, bypassing the entire purpose of the base
|
||||
// environment.
|
||||
//
|
||||
// If usages of this function fail to compile: add version=1 argument to all call sites
|
||||
// that fail compilation while removing the UnversionedLib wrapper. Next, review
|
||||
// the changes in the library present in higher versions and, if needed, use VersionedOptions to
|
||||
// the base environment to roll out to a newer version safely.
|
||||
func UnversionedLib(initializer func() cel.EnvOption) cel.EnvOption {
|
||||
return initializer()
|
||||
}
|
||||
|
12
vendor/k8s.io/apiserver/pkg/cel/format.go
generated
vendored
12
vendor/k8s.io/apiserver/pkg/cel/format.go
generated
vendored
@ -41,11 +41,11 @@ type Format struct {
|
||||
MaxRegexSize int
|
||||
}
|
||||
|
||||
func (d *Format) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
|
||||
func (d Format) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
|
||||
return nil, fmt.Errorf("type conversion error from 'Format' to '%v'", typeDesc)
|
||||
}
|
||||
|
||||
func (d *Format) ConvertToType(typeVal ref.Type) ref.Val {
|
||||
func (d Format) ConvertToType(typeVal ref.Type) ref.Val {
|
||||
switch typeVal {
|
||||
case FormatType:
|
||||
return d
|
||||
@ -56,18 +56,18 @@ func (d *Format) ConvertToType(typeVal ref.Type) ref.Val {
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Format) Equal(other ref.Val) ref.Val {
|
||||
otherDur, ok := other.(*Format)
|
||||
func (d Format) Equal(other ref.Val) ref.Val {
|
||||
otherDur, ok := other.(Format)
|
||||
if !ok {
|
||||
return types.MaybeNoSuchOverloadErr(other)
|
||||
}
|
||||
return types.Bool(d.Name == otherDur.Name)
|
||||
}
|
||||
|
||||
func (d *Format) Type() ref.Type {
|
||||
func (d Format) Type() ref.Type {
|
||||
return FormatType
|
||||
}
|
||||
|
||||
func (d *Format) Value() interface{} {
|
||||
func (d Format) Value() interface{} {
|
||||
return d
|
||||
}
|
||||
|
25
vendor/k8s.io/apiserver/pkg/cel/library/authz.go
generated
vendored
25
vendor/k8s.io/apiserver/pkg/cel/library/authz.go
generated
vendored
@ -232,7 +232,20 @@ var authzLib = &authz{}
|
||||
type authz struct{}
|
||||
|
||||
func (*authz) LibraryName() string {
|
||||
return "k8s.authz"
|
||||
return "kubernetes.authz"
|
||||
}
|
||||
|
||||
func (*authz) Types() []*cel.Type {
|
||||
return []*cel.Type{
|
||||
AuthorizerType,
|
||||
PathCheckType,
|
||||
GroupCheckType,
|
||||
ResourceCheckType,
|
||||
DecisionType}
|
||||
}
|
||||
|
||||
func (*authz) declarations() map[string][]cel.FunctionOpt {
|
||||
return authzLibraryDecls
|
||||
}
|
||||
|
||||
var authzLibraryDecls = map[string][]cel.FunctionOpt{
|
||||
@ -324,7 +337,15 @@ var authzSelectorsLib = &authzSelectors{}
|
||||
type authzSelectors struct{}
|
||||
|
||||
func (*authzSelectors) LibraryName() string {
|
||||
return "k8s.authzSelectors"
|
||||
return "kubernetes.authzSelectors"
|
||||
}
|
||||
|
||||
func (*authzSelectors) Types() []*cel.Type {
|
||||
return []*cel.Type{ResourceCheckType}
|
||||
}
|
||||
|
||||
func (*authzSelectors) declarations() map[string][]cel.FunctionOpt {
|
||||
return authzSelectorsLibraryDecls
|
||||
}
|
||||
|
||||
var authzSelectorsLibraryDecls = map[string][]cel.FunctionOpt{
|
||||
|
10
vendor/k8s.io/apiserver/pkg/cel/library/cidr.go
generated
vendored
10
vendor/k8s.io/apiserver/pkg/cel/library/cidr.go
generated
vendored
@ -109,7 +109,15 @@ var cidrsLib = &cidrs{}
|
||||
type cidrs struct{}
|
||||
|
||||
func (*cidrs) LibraryName() string {
|
||||
return "net.cidr"
|
||||
return "kubernetes.net.cidr"
|
||||
}
|
||||
|
||||
func (*cidrs) declarations() map[string][]cel.FunctionOpt {
|
||||
return cidrLibraryDecls
|
||||
}
|
||||
|
||||
func (*cidrs) Types() []*cel.Type {
|
||||
return []*cel.Type{apiservercel.CIDRType, apiservercel.IPType}
|
||||
}
|
||||
|
||||
var cidrLibraryDecls = map[string][]cel.FunctionOpt{
|
||||
|
94
vendor/k8s.io/apiserver/pkg/cel/library/cost.go
generated
vendored
94
vendor/k8s.io/apiserver/pkg/cel/library/cost.go
generated
vendored
@ -18,14 +18,13 @@ package library
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"github.com/google/cel-go/checker"
|
||||
"github.com/google/cel-go/common"
|
||||
"github.com/google/cel-go/common/ast"
|
||||
"github.com/google/cel-go/common/types"
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
"github.com/google/cel-go/common/types/traits"
|
||||
"math"
|
||||
|
||||
"k8s.io/apiserver/pkg/cel"
|
||||
)
|
||||
@ -36,16 +35,25 @@ var panicOnUnknown = false
|
||||
|
||||
// builtInFunctions is a list of functions used in cost tests that are not handled by CostEstimator.
|
||||
var knownUnhandledFunctions = map[string]bool{
|
||||
"uint": true,
|
||||
"duration": true,
|
||||
"bytes": true,
|
||||
"timestamp": true,
|
||||
"value": true,
|
||||
"_==_": true,
|
||||
"_&&_": true,
|
||||
"_>_": true,
|
||||
"!_": true,
|
||||
"strings.quote": true,
|
||||
"@not_strictly_false": true,
|
||||
"uint": true,
|
||||
"duration": true,
|
||||
"bytes": true,
|
||||
"cel.@mapInsert": true,
|
||||
"timestamp": true,
|
||||
"strings.quote": true,
|
||||
"value": true,
|
||||
"_==_": true,
|
||||
"_&&_": true,
|
||||
"_||_": true,
|
||||
"_>_": true,
|
||||
"_>=_": true,
|
||||
"_<_": true,
|
||||
"_<=_": true,
|
||||
"!_": true,
|
||||
"_?_:_": true,
|
||||
"_+_": true,
|
||||
"_-_": true,
|
||||
}
|
||||
|
||||
// CostEstimator implements CEL's interpretable.ActualCostEstimator and checker.CostEstimator.
|
||||
@ -98,7 +106,7 @@ func (l *CostEstimator) CallCost(function, overloadId string, args []ref.Val, re
|
||||
cost += traversalCost(args[0]) // these O(n) operations all cost roughly the cost of a single traversal
|
||||
}
|
||||
return &cost
|
||||
case "url", "lowerAscii", "upperAscii", "substring", "trim":
|
||||
case "url", "lowerAscii", "upperAscii", "substring", "trim", "jsonpatch.escapeKey":
|
||||
if len(args) >= 1 {
|
||||
cost := uint64(math.Ceil(float64(actualSize(args[0])) * common.StringTraversalCostFactor))
|
||||
return &cost
|
||||
@ -201,7 +209,7 @@ func (l *CostEstimator) CallCost(function, overloadId string, args []ref.Val, re
|
||||
}
|
||||
case "validate":
|
||||
if len(args) >= 2 {
|
||||
format, isFormat := args[0].Value().(*cel.Format)
|
||||
format, isFormat := args[0].Value().(cel.Format)
|
||||
if isFormat {
|
||||
strSize := actualSize(args[1])
|
||||
|
||||
@ -235,6 +243,26 @@ func (l *CostEstimator) CallCost(function, overloadId string, args []ref.Val, re
|
||||
// url accessors
|
||||
cost := uint64(1)
|
||||
return &cost
|
||||
case "_==_":
|
||||
if len(args) == 2 {
|
||||
unitCost := uint64(1)
|
||||
lhs := args[0]
|
||||
switch lhs.(type) {
|
||||
case *cel.Quantity, cel.Quantity,
|
||||
*cel.IP, cel.IP,
|
||||
*cel.CIDR, cel.CIDR,
|
||||
*cel.Format, cel.Format, // Formats have a small max size. Format takes pointer receiver.
|
||||
*cel.URL, cel.URL, // TODO: Computing the actual cost is expensive, and changing this would be a breaking change
|
||||
*cel.Semver, cel.Semver,
|
||||
*authorizerVal, authorizerVal, *pathCheckVal, pathCheckVal, *groupCheckVal, groupCheckVal,
|
||||
*resourceCheckVal, resourceCheckVal, *decisionVal, decisionVal:
|
||||
return &unitCost
|
||||
default:
|
||||
if panicOnUnknown && lhs.Type() != nil && isRegisteredType(lhs.Type().TypeName()) {
|
||||
panic(fmt.Errorf("CallCost: unhandled equality for Kubernetes type %T", lhs))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if panicOnUnknown && !knownUnhandledFunctions[function] {
|
||||
panic(fmt.Errorf("CallCost: unhandled function %q or args %v", function, args))
|
||||
@ -275,10 +303,10 @@ func (l *CostEstimator) EstimateCallCost(function, overloadId string, target *ch
|
||||
return &checker.CallEstimate{CostEstimate: l.sizeEstimate(*target).MultiplyByCostFactor(common.StringTraversalCostFactor)}
|
||||
}
|
||||
}
|
||||
case "url":
|
||||
case "url", "jsonpatch.escapeKey":
|
||||
if len(args) == 1 {
|
||||
sz := l.sizeEstimate(args[0])
|
||||
return &checker.CallEstimate{CostEstimate: sz.MultiplyByCostFactor(common.StringTraversalCostFactor)}
|
||||
return &checker.CallEstimate{CostEstimate: sz.MultiplyByCostFactor(common.StringTraversalCostFactor), ResultSize: &sz}
|
||||
}
|
||||
case "lowerAscii", "upperAscii", "substring", "trim":
|
||||
if target != nil {
|
||||
@ -475,6 +503,40 @@ func (l *CostEstimator) EstimateCallCost(function, overloadId string, target *ch
|
||||
case "getScheme", "getHostname", "getHost", "getPort", "getEscapedPath", "getQuery":
|
||||
// url accessors
|
||||
return &checker.CallEstimate{CostEstimate: checker.CostEstimate{Min: 1, Max: 1}}
|
||||
case "_==_":
|
||||
if len(args) == 2 {
|
||||
lhs := args[0]
|
||||
rhs := args[1]
|
||||
if lhs.Type().Equal(rhs.Type()) == types.True {
|
||||
t := lhs.Type()
|
||||
if t.Kind() == types.OpaqueKind {
|
||||
switch t.TypeName() {
|
||||
case cel.IPType.TypeName(), cel.CIDRType.TypeName():
|
||||
return &checker.CallEstimate{CostEstimate: checker.CostEstimate{Min: 1, Max: 1}}
|
||||
}
|
||||
}
|
||||
if t.Kind() == types.StructKind {
|
||||
switch t {
|
||||
case cel.QuantityType, AuthorizerType, PathCheckType, // O(1) cost equality checks
|
||||
GroupCheckType, ResourceCheckType, DecisionType, cel.SemverType:
|
||||
return &checker.CallEstimate{CostEstimate: checker.CostEstimate{Min: 1, Max: 1}}
|
||||
case cel.FormatType:
|
||||
return &checker.CallEstimate{CostEstimate: checker.CostEstimate{Min: 1, Max: cel.MaxFormatSize}.MultiplyByCostFactor(common.StringTraversalCostFactor)}
|
||||
case cel.URLType:
|
||||
size := checker.SizeEstimate{Min: 1, Max: 1}
|
||||
rhSize := rhs.ComputedSize()
|
||||
lhSize := rhs.ComputedSize()
|
||||
if rhSize != nil && lhSize != nil {
|
||||
size = rhSize.Union(*lhSize)
|
||||
}
|
||||
return &checker.CallEstimate{CostEstimate: checker.CostEstimate{Min: 1, Max: size.Max}.MultiplyByCostFactor(common.StringTraversalCostFactor)}
|
||||
}
|
||||
}
|
||||
if panicOnUnknown && isRegisteredType(t.TypeName()) {
|
||||
panic(fmt.Errorf("EstimateCallCost: unhandled equality for Kubernetes type %v", t))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if panicOnUnknown && !knownUnhandledFunctions[function] {
|
||||
panic(fmt.Errorf("EstimateCallCost: unhandled function %q, target %v, args %v", function, target, args))
|
||||
|
15
vendor/k8s.io/apiserver/pkg/cel/library/format.go
generated
vendored
15
vendor/k8s.io/apiserver/pkg/cel/library/format.go
generated
vendored
@ -25,6 +25,7 @@ import (
|
||||
"github.com/google/cel-go/common/decls"
|
||||
"github.com/google/cel-go/common/types"
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
|
||||
apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation"
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
apiservercel "k8s.io/apiserver/pkg/cel"
|
||||
@ -90,7 +91,15 @@ var formatLib = &format{}
|
||||
type format struct{}
|
||||
|
||||
func (*format) LibraryName() string {
|
||||
return "format"
|
||||
return "kubernetes.format"
|
||||
}
|
||||
|
||||
func (*format) Types() []*cel.Type {
|
||||
return []*cel.Type{apiservercel.FormatType}
|
||||
}
|
||||
|
||||
func (*format) declarations() map[string][]cel.FunctionOpt {
|
||||
return formatLibraryDecls
|
||||
}
|
||||
|
||||
func ZeroArgumentFunctionBinding(binding func() ref.Val) decls.OverloadOpt {
|
||||
@ -124,7 +133,7 @@ func (*format) ProgramOptions() []cel.ProgramOption {
|
||||
return []cel.ProgramOption{}
|
||||
}
|
||||
|
||||
var ConstantFormats map[string]*apiservercel.Format = map[string]*apiservercel.Format{
|
||||
var ConstantFormats = map[string]apiservercel.Format{
|
||||
"dns1123Label": {
|
||||
Name: "DNS1123Label",
|
||||
ValidateFunc: func(s string) []string { return apimachineryvalidation.NameIsDNSLabel(s, false) },
|
||||
@ -252,7 +261,7 @@ var formatLibraryDecls = map[string][]cel.FunctionOpt{
|
||||
}
|
||||
|
||||
func formatValidate(arg1, arg2 ref.Val) ref.Val {
|
||||
f, ok := arg1.Value().(*apiservercel.Format)
|
||||
f, ok := arg1.Value().(apiservercel.Format)
|
||||
if !ok {
|
||||
return types.MaybeNoSuchOverloadErr(arg1)
|
||||
}
|
||||
|
10
vendor/k8s.io/apiserver/pkg/cel/library/ip.go
generated
vendored
10
vendor/k8s.io/apiserver/pkg/cel/library/ip.go
generated
vendored
@ -132,7 +132,15 @@ var ipLib = &ip{}
|
||||
type ip struct{}
|
||||
|
||||
func (*ip) LibraryName() string {
|
||||
return "net.ip"
|
||||
return "kubernetes.net.ip"
|
||||
}
|
||||
|
||||
func (*ip) declarations() map[string][]cel.FunctionOpt {
|
||||
return ipLibraryDecls
|
||||
}
|
||||
|
||||
func (*ip) Types() []*cel.Type {
|
||||
return []*cel.Type{apiservercel.IPType}
|
||||
}
|
||||
|
||||
var ipLibraryDecls = map[string][]cel.FunctionOpt{
|
||||
|
89
vendor/k8s.io/apiserver/pkg/cel/library/jsonpatch.go
generated
vendored
Normal file
89
vendor/k8s.io/apiserver/pkg/cel/library/jsonpatch.go
generated
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
Copyright 2024 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 library
|
||||
|
||||
import (
|
||||
"github.com/google/cel-go/cel"
|
||||
"github.com/google/cel-go/common/types"
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// JSONPatch provides a CEL function library extension of JSONPatch functions.
|
||||
//
|
||||
// jsonpatch.escapeKey
|
||||
//
|
||||
// Escapes a string for use as a JSONPatch path key.
|
||||
//
|
||||
// jsonpatch.escapeKey(<string>) <string>
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// "/metadata/labels/" + jsonpatch.escapeKey('k8s.io/my~label') // returns "/metadata/labels/k8s.io~1my~0label"
|
||||
func JSONPatch() cel.EnvOption {
|
||||
return cel.Lib(jsonPatchLib)
|
||||
}
|
||||
|
||||
var jsonPatchLib = &jsonPatch{}
|
||||
|
||||
type jsonPatch struct{}
|
||||
|
||||
func (*jsonPatch) LibraryName() string {
|
||||
return "kubernetes.jsonpatch"
|
||||
}
|
||||
|
||||
func (*jsonPatch) declarations() map[string][]cel.FunctionOpt {
|
||||
return jsonPatchLibraryDecls
|
||||
}
|
||||
|
||||
func (*jsonPatch) Types() []*cel.Type {
|
||||
return []*cel.Type{}
|
||||
}
|
||||
|
||||
var jsonPatchLibraryDecls = map[string][]cel.FunctionOpt{
|
||||
"jsonpatch.escapeKey": {
|
||||
cel.Overload("string_jsonpatch_escapeKey_string", []*cel.Type{cel.StringType}, cel.StringType,
|
||||
cel.UnaryBinding(escape)),
|
||||
},
|
||||
}
|
||||
|
||||
func (*jsonPatch) CompileOptions() []cel.EnvOption {
|
||||
var options []cel.EnvOption
|
||||
for name, overloads := range jsonPatchLibraryDecls {
|
||||
options = append(options, cel.Function(name, overloads...))
|
||||
}
|
||||
return options
|
||||
}
|
||||
|
||||
func (*jsonPatch) ProgramOptions() []cel.ProgramOption {
|
||||
return []cel.ProgramOption{}
|
||||
}
|
||||
|
||||
var jsonPatchReplacer = strings.NewReplacer("/", "~1", "~", "~0")
|
||||
|
||||
func escapeKey(k string) string {
|
||||
return jsonPatchReplacer.Replace(k)
|
||||
}
|
||||
|
||||
func escape(arg ref.Val) ref.Val {
|
||||
s, ok := arg.Value().(string)
|
||||
if !ok {
|
||||
return types.MaybeNoSuchOverloadErr(arg)
|
||||
}
|
||||
escaped := escapeKey(s)
|
||||
return types.String(escaped)
|
||||
}
|
61
vendor/k8s.io/apiserver/pkg/cel/library/libraries.go
generated
vendored
Normal file
61
vendor/k8s.io/apiserver/pkg/cel/library/libraries.go
generated
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
Copyright 2024 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 library
|
||||
|
||||
import (
|
||||
"github.com/google/cel-go/cel"
|
||||
)
|
||||
|
||||
// Library represents a CEL library used by kubernetes.
|
||||
type Library interface {
|
||||
// SingletonLibrary provides the library name and ensures the library can be safely registered into environments.
|
||||
cel.SingletonLibrary
|
||||
|
||||
// Types provides all custom types introduced by the library.
|
||||
Types() []*cel.Type
|
||||
|
||||
// declarations returns all function declarations provided by the library.
|
||||
declarations() map[string][]cel.FunctionOpt
|
||||
}
|
||||
|
||||
// KnownLibraries returns all libraries used in Kubernetes.
|
||||
func KnownLibraries() []Library {
|
||||
return []Library{
|
||||
authzLib,
|
||||
authzSelectorsLib,
|
||||
listsLib,
|
||||
regexLib,
|
||||
urlsLib,
|
||||
quantityLib,
|
||||
ipLib,
|
||||
cidrsLib,
|
||||
formatLib,
|
||||
semverLib,
|
||||
jsonPatchLib,
|
||||
}
|
||||
}
|
||||
|
||||
func isRegisteredType(typeName string) bool {
|
||||
for _, lib := range KnownLibraries() {
|
||||
for _, rt := range lib.Types() {
|
||||
if rt.TypeName() == typeName {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
10
vendor/k8s.io/apiserver/pkg/cel/library/lists.go
generated
vendored
10
vendor/k8s.io/apiserver/pkg/cel/library/lists.go
generated
vendored
@ -96,7 +96,15 @@ var listsLib = &lists{}
|
||||
type lists struct{}
|
||||
|
||||
func (*lists) LibraryName() string {
|
||||
return "k8s.lists"
|
||||
return "kubernetes.lists"
|
||||
}
|
||||
|
||||
func (*lists) Types() []*cel.Type {
|
||||
return []*cel.Type{}
|
||||
}
|
||||
|
||||
func (*lists) declarations() map[string][]cel.FunctionOpt {
|
||||
return listsLibraryDecls
|
||||
}
|
||||
|
||||
var paramA = cel.TypeParamType("A")
|
||||
|
10
vendor/k8s.io/apiserver/pkg/cel/library/quantity.go
generated
vendored
10
vendor/k8s.io/apiserver/pkg/cel/library/quantity.go
generated
vendored
@ -143,7 +143,15 @@ var quantityLib = &quantity{}
|
||||
type quantity struct{}
|
||||
|
||||
func (*quantity) LibraryName() string {
|
||||
return "k8s.quantity"
|
||||
return "kubernetes.quantity"
|
||||
}
|
||||
|
||||
func (*quantity) Types() []*cel.Type {
|
||||
return []*cel.Type{apiservercel.QuantityType}
|
||||
}
|
||||
|
||||
func (*quantity) declarations() map[string][]cel.FunctionOpt {
|
||||
return quantityLibraryDecls
|
||||
}
|
||||
|
||||
var quantityLibraryDecls = map[string][]cel.FunctionOpt{
|
||||
|
10
vendor/k8s.io/apiserver/pkg/cel/library/regex.go
generated
vendored
10
vendor/k8s.io/apiserver/pkg/cel/library/regex.go
generated
vendored
@ -52,7 +52,15 @@ var regexLib = ®ex{}
|
||||
type regex struct{}
|
||||
|
||||
func (*regex) LibraryName() string {
|
||||
return "k8s.regex"
|
||||
return "kubernetes.regex"
|
||||
}
|
||||
|
||||
func (*regex) Types() []*cel.Type {
|
||||
return []*cel.Type{}
|
||||
}
|
||||
|
||||
func (*regex) declarations() map[string][]cel.FunctionOpt {
|
||||
return regexLibraryDecls
|
||||
}
|
||||
|
||||
var regexLibraryDecls = map[string][]cel.FunctionOpt{
|
||||
|
247
vendor/k8s.io/apiserver/pkg/cel/library/semverlib.go
generated
vendored
Normal file
247
vendor/k8s.io/apiserver/pkg/cel/library/semverlib.go
generated
vendored
Normal file
@ -0,0 +1,247 @@
|
||||
/*
|
||||
Copyright 2024 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 library
|
||||
|
||||
import (
|
||||
"github.com/blang/semver/v4"
|
||||
"github.com/google/cel-go/cel"
|
||||
"github.com/google/cel-go/common/types"
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
|
||||
apiservercel "k8s.io/apiserver/pkg/cel"
|
||||
)
|
||||
|
||||
// Semver provides a CEL function library extension for [semver.Version].
|
||||
//
|
||||
// semver
|
||||
//
|
||||
// Converts a string to a semantic version or results in an error if the string is not a valid semantic version. Refer
|
||||
// to semver.org documentation for information on accepted patterns.
|
||||
//
|
||||
// semver(<string>) <Semver>
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// semver('1.0.0') // returns a Semver
|
||||
// semver('0.1.0-alpha.1') // returns a Semver
|
||||
// semver('200K') // error
|
||||
// semver('Three') // error
|
||||
// semver('Mi') // error
|
||||
//
|
||||
// isSemver
|
||||
//
|
||||
// Returns true if a string is a valid Semver. isSemver returns true if and
|
||||
// only if semver does not result in error.
|
||||
//
|
||||
// isSemver( <string>) <bool>
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// isSemver('1.0.0') // returns true
|
||||
// isSemver('v1.0') // returns true (tolerant parsing)
|
||||
// isSemver('hello') // returns false
|
||||
//
|
||||
// Conversion to Scalars:
|
||||
//
|
||||
// - major/minor/patch: return the major version number as int64.
|
||||
//
|
||||
// <Semver>.major() <int>
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// semver("1.2.3").major() // returns 1
|
||||
//
|
||||
// Comparisons
|
||||
//
|
||||
// - isGreaterThan: Returns true if and only if the receiver is greater than the operand
|
||||
//
|
||||
// - isLessThan: Returns true if and only if the receiver is less than the operand
|
||||
//
|
||||
// - compareTo: Compares receiver to operand and returns 0 if they are equal, 1 if the receiver is greater, or -1 if the receiver is less than the operand
|
||||
//
|
||||
//
|
||||
// <Semver>.isLessThan(<semver>) <bool>
|
||||
// <Semver>.isGreaterThan(<semver>) <bool>
|
||||
// <Semver>.compareTo(<semver>) <int>
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// semver("1.2.3").compareTo(semver("1.2.3")) // returns 0
|
||||
// semver("1.2.3").compareTo(semver("2.0.0")) // returns -1
|
||||
// semver("1.2.3").compareTo(semver("0.1.2")) // returns 1
|
||||
|
||||
func SemverLib() cel.EnvOption {
|
||||
return cel.Lib(semverLib)
|
||||
}
|
||||
|
||||
var semverLib = &semverLibType{}
|
||||
|
||||
type semverLibType struct{}
|
||||
|
||||
func (*semverLibType) LibraryName() string {
|
||||
return "kubernetes.Semver"
|
||||
}
|
||||
|
||||
func (*semverLibType) Types() []*cel.Type {
|
||||
return []*cel.Type{apiservercel.SemverType}
|
||||
}
|
||||
|
||||
func (*semverLibType) declarations() map[string][]cel.FunctionOpt {
|
||||
return map[string][]cel.FunctionOpt{
|
||||
"semver": {
|
||||
cel.Overload("string_to_semver", []*cel.Type{cel.StringType}, apiservercel.SemverType, cel.UnaryBinding((stringToSemver))),
|
||||
},
|
||||
"isSemver": {
|
||||
cel.Overload("is_semver_string", []*cel.Type{cel.StringType}, cel.BoolType, cel.UnaryBinding(isSemver)),
|
||||
},
|
||||
"isGreaterThan": {
|
||||
cel.MemberOverload("semver_is_greater_than", []*cel.Type{apiservercel.SemverType, apiservercel.SemverType}, cel.BoolType, cel.BinaryBinding(semverIsGreaterThan)),
|
||||
},
|
||||
"isLessThan": {
|
||||
cel.MemberOverload("semver_is_less_than", []*cel.Type{apiservercel.SemverType, apiservercel.SemverType}, cel.BoolType, cel.BinaryBinding(semverIsLessThan)),
|
||||
},
|
||||
"compareTo": {
|
||||
cel.MemberOverload("semver_compare_to", []*cel.Type{apiservercel.SemverType, apiservercel.SemverType}, cel.IntType, cel.BinaryBinding(semverCompareTo)),
|
||||
},
|
||||
"major": {
|
||||
cel.MemberOverload("semver_major", []*cel.Type{apiservercel.SemverType}, cel.IntType, cel.UnaryBinding(semverMajor)),
|
||||
},
|
||||
"minor": {
|
||||
cel.MemberOverload("semver_minor", []*cel.Type{apiservercel.SemverType}, cel.IntType, cel.UnaryBinding(semverMinor)),
|
||||
},
|
||||
"patch": {
|
||||
cel.MemberOverload("semver_patch", []*cel.Type{apiservercel.SemverType}, cel.IntType, cel.UnaryBinding(semverPatch)),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *semverLibType) CompileOptions() []cel.EnvOption {
|
||||
// Defined in this function to avoid an initialization order problem.
|
||||
semverLibraryDecls := s.declarations()
|
||||
options := make([]cel.EnvOption, 0, len(semverLibraryDecls))
|
||||
for name, overloads := range semverLibraryDecls {
|
||||
options = append(options, cel.Function(name, overloads...))
|
||||
}
|
||||
return options
|
||||
}
|
||||
|
||||
func (*semverLibType) ProgramOptions() []cel.ProgramOption {
|
||||
return []cel.ProgramOption{}
|
||||
}
|
||||
|
||||
func isSemver(arg ref.Val) ref.Val {
|
||||
str, ok := arg.Value().(string)
|
||||
if !ok {
|
||||
return types.MaybeNoSuchOverloadErr(arg)
|
||||
}
|
||||
|
||||
// Using semver/v4 here is okay because this function isn't
|
||||
// used to validate the Kubernetes API. In the CEL base library
|
||||
// we would have to use the regular expression from
|
||||
// pkg/apis/resource/structured/namedresources/validation/validation.go.
|
||||
_, err := semver.Parse(str)
|
||||
if err != nil {
|
||||
return types.Bool(false)
|
||||
}
|
||||
|
||||
return types.Bool(true)
|
||||
}
|
||||
|
||||
func stringToSemver(arg ref.Val) ref.Val {
|
||||
str, ok := arg.Value().(string)
|
||||
if !ok {
|
||||
return types.MaybeNoSuchOverloadErr(arg)
|
||||
}
|
||||
|
||||
// Using semver/v4 here is okay because this function isn't
|
||||
// used to validate the Kubernetes API. In the CEL base library
|
||||
// we would have to use the regular expression from
|
||||
// pkg/apis/resource/structured/namedresources/validation/validation.go
|
||||
// first before parsing.
|
||||
v, err := semver.Parse(str)
|
||||
if err != nil {
|
||||
return types.WrapErr(err)
|
||||
}
|
||||
|
||||
return apiservercel.Semver{Version: v}
|
||||
}
|
||||
|
||||
func semverMajor(arg ref.Val) ref.Val {
|
||||
v, ok := arg.Value().(semver.Version)
|
||||
if !ok {
|
||||
return types.MaybeNoSuchOverloadErr(arg)
|
||||
}
|
||||
return types.Int(v.Major)
|
||||
}
|
||||
|
||||
func semverMinor(arg ref.Val) ref.Val {
|
||||
v, ok := arg.Value().(semver.Version)
|
||||
if !ok {
|
||||
return types.MaybeNoSuchOverloadErr(arg)
|
||||
}
|
||||
return types.Int(v.Minor)
|
||||
}
|
||||
|
||||
func semverPatch(arg ref.Val) ref.Val {
|
||||
v, ok := arg.Value().(semver.Version)
|
||||
if !ok {
|
||||
return types.MaybeNoSuchOverloadErr(arg)
|
||||
}
|
||||
return types.Int(v.Patch)
|
||||
}
|
||||
|
||||
func semverIsGreaterThan(arg ref.Val, other ref.Val) ref.Val {
|
||||
v, ok := arg.Value().(semver.Version)
|
||||
if !ok {
|
||||
return types.MaybeNoSuchOverloadErr(arg)
|
||||
}
|
||||
|
||||
v2, ok := other.Value().(semver.Version)
|
||||
if !ok {
|
||||
return types.MaybeNoSuchOverloadErr(arg)
|
||||
}
|
||||
|
||||
return types.Bool(v.Compare(v2) == 1)
|
||||
}
|
||||
|
||||
func semverIsLessThan(arg ref.Val, other ref.Val) ref.Val {
|
||||
v, ok := arg.Value().(semver.Version)
|
||||
if !ok {
|
||||
return types.MaybeNoSuchOverloadErr(arg)
|
||||
}
|
||||
|
||||
v2, ok := other.Value().(semver.Version)
|
||||
if !ok {
|
||||
return types.MaybeNoSuchOverloadErr(arg)
|
||||
}
|
||||
|
||||
return types.Bool(v.Compare(v2) == -1)
|
||||
}
|
||||
|
||||
func semverCompareTo(arg ref.Val, other ref.Val) ref.Val {
|
||||
v, ok := arg.Value().(semver.Version)
|
||||
if !ok {
|
||||
return types.MaybeNoSuchOverloadErr(arg)
|
||||
}
|
||||
|
||||
v2, ok := other.Value().(semver.Version)
|
||||
if !ok {
|
||||
return types.MaybeNoSuchOverloadErr(arg)
|
||||
}
|
||||
|
||||
return types.Int(v.Compare(v2))
|
||||
}
|
2
vendor/k8s.io/apiserver/pkg/cel/library/test.go
generated
vendored
2
vendor/k8s.io/apiserver/pkg/cel/library/test.go
generated
vendored
@ -38,7 +38,7 @@ type testLib struct {
|
||||
}
|
||||
|
||||
func (*testLib) LibraryName() string {
|
||||
return "k8s.test"
|
||||
return "kubernetes.test"
|
||||
}
|
||||
|
||||
type TestOption func(*testLib) *testLib
|
||||
|
10
vendor/k8s.io/apiserver/pkg/cel/library/urls.go
generated
vendored
10
vendor/k8s.io/apiserver/pkg/cel/library/urls.go
generated
vendored
@ -113,7 +113,15 @@ var urlsLib = &urls{}
|
||||
type urls struct{}
|
||||
|
||||
func (*urls) LibraryName() string {
|
||||
return "k8s.urls"
|
||||
return "kubernetes.urls"
|
||||
}
|
||||
|
||||
func (*urls) Types() []*cel.Type {
|
||||
return []*cel.Type{apiservercel.URLType}
|
||||
}
|
||||
|
||||
func (*urls) declarations() map[string][]cel.FunctionOpt {
|
||||
return urlLibraryDecls
|
||||
}
|
||||
|
||||
var urlLibraryDecls = map[string][]cel.FunctionOpt{
|
||||
|
2
vendor/k8s.io/apiserver/pkg/cel/limits.go
generated
vendored
2
vendor/k8s.io/apiserver/pkg/cel/limits.go
generated
vendored
@ -48,5 +48,7 @@ const (
|
||||
// MinNumberSize is the length of literal 0
|
||||
MinNumberSize = 1
|
||||
|
||||
// MaxFormatSize is the maximum size we allow for format strings
|
||||
MaxFormatSize = 64
|
||||
MaxNameFormatRegexSize = 128
|
||||
)
|
||||
|
249
vendor/k8s.io/apiserver/pkg/cel/mutation/dynamic/objects.go
generated
vendored
Normal file
249
vendor/k8s.io/apiserver/pkg/cel/mutation/dynamic/objects.go
generated
vendored
Normal file
@ -0,0 +1,249 @@
|
||||
/*
|
||||
Copyright 2024 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 dynamic
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/google/cel-go/common/types"
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
"github.com/google/cel-go/common/types/traits"
|
||||
"google.golang.org/protobuf/types/known/structpb"
|
||||
)
|
||||
|
||||
// ObjectType is the implementation of the Object type for use when compiling
|
||||
// CEL expressions without schema information about the object.
|
||||
// This is to provide CEL expressions with access to Object{} types constructors.
|
||||
type ObjectType struct {
|
||||
objectType *types.Type
|
||||
}
|
||||
|
||||
func (o *ObjectType) HasTrait(trait int) bool {
|
||||
return o.objectType.HasTrait(trait)
|
||||
}
|
||||
|
||||
// TypeName returns the name of this ObjectType.
|
||||
func (o *ObjectType) TypeName() string {
|
||||
return o.objectType.TypeName()
|
||||
}
|
||||
|
||||
// Val returns an instance given the fields.
|
||||
func (o *ObjectType) Val(fields map[string]ref.Val) ref.Val {
|
||||
return NewObjectVal(o.objectType, fields)
|
||||
}
|
||||
|
||||
func (o *ObjectType) Type() *types.Type {
|
||||
return o.objectType
|
||||
}
|
||||
|
||||
// Field looks up the field by name.
|
||||
// This is the unstructured version that allows any name as the field name.
|
||||
// The returned field is of DynType type.
|
||||
func (o *ObjectType) Field(name string) (*types.FieldType, bool) {
|
||||
return &types.FieldType{
|
||||
// for unstructured, we do not check for its type,
|
||||
// use DynType for all fields.
|
||||
Type: types.DynType,
|
||||
IsSet: func(target any) bool {
|
||||
if m, ok := target.(map[string]any); ok {
|
||||
_, isSet := m[name]
|
||||
return isSet
|
||||
}
|
||||
return false
|
||||
},
|
||||
GetFrom: func(target any) (any, error) {
|
||||
if m, ok := target.(map[string]any); ok {
|
||||
return m[name], nil
|
||||
}
|
||||
return nil, fmt.Errorf("cannot get field %q", name)
|
||||
},
|
||||
}, true
|
||||
}
|
||||
|
||||
func (o *ObjectType) FieldNames() ([]string, bool) {
|
||||
return nil, true // Field names are not known for dynamic types. All field names are allowed.
|
||||
}
|
||||
|
||||
// NewObjectType creates a ObjectType by the given field name.
|
||||
func NewObjectType(name string) *ObjectType {
|
||||
return &ObjectType{
|
||||
objectType: types.NewObjectType(name),
|
||||
}
|
||||
}
|
||||
|
||||
// ObjectVal is the CEL Val for an object that is constructed via the Object{} in
|
||||
// CEL expressions without schema information about the object.
|
||||
type ObjectVal struct {
|
||||
objectType *types.Type
|
||||
fields map[string]ref.Val
|
||||
}
|
||||
|
||||
// NewObjectVal creates an ObjectVal by its ResolvedType and its fields.
|
||||
func NewObjectVal(objectType *types.Type, fields map[string]ref.Val) *ObjectVal {
|
||||
return &ObjectVal{
|
||||
objectType: objectType,
|
||||
fields: fields,
|
||||
}
|
||||
}
|
||||
|
||||
var _ ref.Val = (*ObjectVal)(nil)
|
||||
var _ traits.Zeroer = (*ObjectVal)(nil)
|
||||
|
||||
// ConvertToNative converts the object to map[string]any.
|
||||
// All nested lists are converted into []any native type.
|
||||
//
|
||||
// It returns an error if the target type is not map[string]any,
|
||||
// or any recursive conversion fails.
|
||||
func (v *ObjectVal) ConvertToNative(typeDesc reflect.Type) (any, error) {
|
||||
result := make(map[string]any, len(v.fields))
|
||||
for k, v := range v.fields {
|
||||
converted, err := convertField(v)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("fail to convert field %q: %w", k, err)
|
||||
}
|
||||
result[k] = converted
|
||||
}
|
||||
if typeDesc == reflect.TypeOf(result) {
|
||||
return result, nil
|
||||
}
|
||||
// CEL's builtin data literal values all support conversion to structpb.Value, which
|
||||
// can then be serialized to JSON. This is convenient for CEL expressions that return
|
||||
// an arbitrary JSON value, such as our MutatingAdmissionPolicy JSON Patch valueExpression
|
||||
// field, so we support the conversion here, for Object data literals, as well.
|
||||
if typeDesc == reflect.TypeOf(&structpb.Value{}) {
|
||||
return structpb.NewStruct(result)
|
||||
}
|
||||
return nil, fmt.Errorf("unable to convert to %v", typeDesc)
|
||||
}
|
||||
|
||||
// ConvertToType supports type conversions between CEL value types supported by the expression language.
|
||||
func (v *ObjectVal) ConvertToType(typeValue ref.Type) ref.Val {
|
||||
if v.objectType.TypeName() == typeValue.TypeName() {
|
||||
return v
|
||||
}
|
||||
if typeValue == types.TypeType {
|
||||
return types.NewTypeTypeWithParam(v.objectType)
|
||||
}
|
||||
return types.NewErr("unsupported conversion into %v", typeValue)
|
||||
}
|
||||
|
||||
// Equal returns true if the `other` value has the same type and content as the implementing struct.
|
||||
func (v *ObjectVal) Equal(other ref.Val) ref.Val {
|
||||
if rhs, ok := other.(*ObjectVal); ok {
|
||||
if v.objectType.Equal(rhs.objectType) != types.True {
|
||||
return types.False
|
||||
}
|
||||
return types.Bool(reflect.DeepEqual(v.fields, rhs.fields))
|
||||
}
|
||||
return types.False
|
||||
}
|
||||
|
||||
// Type returns the TypeValue of the value.
|
||||
func (v *ObjectVal) Type() ref.Type {
|
||||
return types.NewObjectType(v.objectType.TypeName())
|
||||
}
|
||||
|
||||
// Value returns its value as a map[string]any.
|
||||
func (v *ObjectVal) Value() any {
|
||||
var result any
|
||||
var object map[string]any
|
||||
result, err := v.ConvertToNative(reflect.TypeOf(object))
|
||||
if err != nil {
|
||||
return types.WrapErr(err)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// CheckTypeNamesMatchFieldPathNames transitively checks the CEL object type names of this ObjectVal. Returns all
|
||||
// found type name mismatch errors.
|
||||
// Children ObjectVal types under <field> or this ObjectVal
|
||||
// must have type names of the form "<ObjectVal.TypeName>.<field>", children of that type must have type names of the
|
||||
// form "<ObjectVal.TypeName>.<field>.<field>" and so on.
|
||||
// Intermediate maps and lists are unnamed and ignored.
|
||||
func (v *ObjectVal) CheckTypeNamesMatchFieldPathNames() error {
|
||||
return errors.Join(typeCheck(v, []string{v.Type().TypeName()})...)
|
||||
|
||||
}
|
||||
|
||||
func typeCheck(v ref.Val, typeNamePath []string) []error {
|
||||
var errs []error
|
||||
if ov, ok := v.(*ObjectVal); ok {
|
||||
tn := ov.objectType.TypeName()
|
||||
if strings.Join(typeNamePath, ".") != tn {
|
||||
errs = append(errs, fmt.Errorf("unexpected type name %q, expected %q, which matches field name path from root Object type", tn, strings.Join(typeNamePath, ".")))
|
||||
}
|
||||
for k, f := range ov.fields {
|
||||
errs = append(errs, typeCheck(f, append(typeNamePath, k))...)
|
||||
}
|
||||
}
|
||||
value := v.Value()
|
||||
if listOfVal, ok := value.([]ref.Val); ok {
|
||||
for _, v := range listOfVal {
|
||||
errs = append(errs, typeCheck(v, typeNamePath)...)
|
||||
}
|
||||
}
|
||||
|
||||
if mapOfVal, ok := value.(map[ref.Val]ref.Val); ok {
|
||||
for _, v := range mapOfVal {
|
||||
errs = append(errs, typeCheck(v, typeNamePath)...)
|
||||
}
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
// IsZeroValue indicates whether the object is the zero value for the type.
|
||||
// For the ObjectVal, it is zero value if and only if the fields map is empty.
|
||||
func (v *ObjectVal) IsZeroValue() bool {
|
||||
return len(v.fields) == 0
|
||||
}
|
||||
|
||||
// convertField converts a referred ref.Val to its expected type.
|
||||
// For objects, the expected type is map[string]any
|
||||
// For lists, the expected type is []any
|
||||
// For maps, the expected type is map[string]any
|
||||
// For anything else, it is converted via value.Value()
|
||||
//
|
||||
// It will return an error if the request type is a map but the key
|
||||
// is not a string.
|
||||
func convertField(value ref.Val) (any, error) {
|
||||
// special handling for lists, where the elements are converted with Value() instead of ConvertToNative
|
||||
// to allow them to become native value of any type.
|
||||
if listOfVal, ok := value.Value().([]ref.Val); ok {
|
||||
var result []any
|
||||
for _, v := range listOfVal {
|
||||
result = append(result, v.Value())
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
// unstructured maps, as seen in annotations
|
||||
// map keys must be strings
|
||||
if mapOfVal, ok := value.Value().(map[ref.Val]ref.Val); ok {
|
||||
result := make(map[string]any, len(mapOfVal))
|
||||
for k, v := range mapOfVal {
|
||||
stringKey, ok := k.Value().(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("map key %q is of type %T, not string", k, k)
|
||||
}
|
||||
result[stringKey] = v.Value()
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
return value.Value(), nil
|
||||
}
|
185
vendor/k8s.io/apiserver/pkg/cel/mutation/jsonpatch.go
generated
vendored
Normal file
185
vendor/k8s.io/apiserver/pkg/cel/mutation/jsonpatch.go
generated
vendored
Normal file
@ -0,0 +1,185 @@
|
||||
/*
|
||||
Copyright 2024 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 mutation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/google/cel-go/cel"
|
||||
"github.com/google/cel-go/common/types"
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
var jsonPatchType = types.NewObjectType(JSONPatchTypeName)
|
||||
|
||||
var (
|
||||
jsonPatchOp = "op"
|
||||
jsonPatchPath = "path"
|
||||
jsonPatchFrom = "from"
|
||||
jsonPatchValue = "value"
|
||||
)
|
||||
|
||||
// JSONPatchType and JSONPatchVal are defined entirely from scratch here because JSONPatchVal
|
||||
// has a dynamic 'value' field which can not be defined with an OpenAPI schema,
|
||||
// preventing us from using DeclType and UnstructuredToVal.
|
||||
|
||||
// JSONPatchType provides a CEL type for "JSONPatch" operations.
|
||||
type JSONPatchType struct{}
|
||||
|
||||
func (r *JSONPatchType) HasTrait(trait int) bool {
|
||||
return jsonPatchType.HasTrait(trait)
|
||||
}
|
||||
|
||||
// TypeName returns the name of this ObjectType.
|
||||
func (r *JSONPatchType) TypeName() string {
|
||||
return jsonPatchType.TypeName()
|
||||
}
|
||||
|
||||
// Val returns an instance given the fields.
|
||||
func (r *JSONPatchType) Val(fields map[string]ref.Val) ref.Val {
|
||||
result := &JSONPatchVal{}
|
||||
for name, value := range fields {
|
||||
switch name {
|
||||
case jsonPatchOp:
|
||||
if s, ok := value.Value().(string); ok {
|
||||
result.Op = s
|
||||
} else {
|
||||
return types.NewErr("unexpected type %T for JSONPatchType 'op' field", value.Value())
|
||||
}
|
||||
case jsonPatchPath:
|
||||
if s, ok := value.Value().(string); ok {
|
||||
result.Path = s
|
||||
} else {
|
||||
return types.NewErr("unexpected type %T for JSONPatchType 'path' field", value.Value())
|
||||
}
|
||||
case jsonPatchFrom:
|
||||
if s, ok := value.Value().(string); ok {
|
||||
result.From = s
|
||||
} else {
|
||||
return types.NewErr("unexpected type %T for JSONPatchType 'from' field", value.Value())
|
||||
}
|
||||
case jsonPatchValue:
|
||||
result.Val = value
|
||||
default:
|
||||
return types.NewErr("unexpected JSONPatchType field: %s", name)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (r *JSONPatchType) Type() *types.Type {
|
||||
return jsonPatchType
|
||||
}
|
||||
|
||||
func (r *JSONPatchType) Field(name string) (*types.FieldType, bool) {
|
||||
var fieldType *types.Type
|
||||
switch name {
|
||||
case jsonPatchOp, jsonPatchFrom, jsonPatchPath:
|
||||
fieldType = cel.StringType
|
||||
case jsonPatchValue:
|
||||
fieldType = types.DynType
|
||||
}
|
||||
return &types.FieldType{
|
||||
Type: fieldType,
|
||||
}, true
|
||||
}
|
||||
|
||||
func (r *JSONPatchType) FieldNames() ([]string, bool) {
|
||||
return []string{jsonPatchOp, jsonPatchFrom, jsonPatchPath, jsonPatchValue}, true
|
||||
}
|
||||
|
||||
// JSONPatchVal is the ref.Val for a JSONPatch.
|
||||
type JSONPatchVal struct {
|
||||
Op, From, Path string
|
||||
Val ref.Val
|
||||
}
|
||||
|
||||
func (p *JSONPatchVal) ConvertToNative(typeDesc reflect.Type) (any, error) {
|
||||
if typeDesc == reflect.TypeOf(&JSONPatchVal{}) {
|
||||
return p, nil
|
||||
}
|
||||
return nil, fmt.Errorf("cannot convert to native type: %v", typeDesc)
|
||||
}
|
||||
|
||||
func (p *JSONPatchVal) ConvertToType(typeValue ref.Type) ref.Val {
|
||||
if typeValue == jsonPatchType {
|
||||
return p
|
||||
} else if typeValue == types.TypeType {
|
||||
return types.NewTypeTypeWithParam(jsonPatchType)
|
||||
}
|
||||
return types.NewErr("unsupported type: %s", typeValue.TypeName())
|
||||
}
|
||||
|
||||
func (p *JSONPatchVal) Equal(other ref.Val) ref.Val {
|
||||
if o, ok := other.(*JSONPatchVal); ok && p != nil && o != nil {
|
||||
if p.Op != o.Op || p.From != o.From || p.Path != o.Path {
|
||||
return types.False
|
||||
}
|
||||
if (p.Val == nil) != (o.Val == nil) {
|
||||
return types.False
|
||||
}
|
||||
if p.Val == nil {
|
||||
return types.True
|
||||
}
|
||||
return p.Val.Equal(o.Val)
|
||||
}
|
||||
return types.False
|
||||
}
|
||||
|
||||
func (p *JSONPatchVal) Get(index ref.Val) ref.Val {
|
||||
if name, ok := index.Value().(string); ok {
|
||||
switch name {
|
||||
case jsonPatchOp:
|
||||
return types.String(p.Op)
|
||||
case jsonPatchPath:
|
||||
return types.String(p.Path)
|
||||
case jsonPatchFrom:
|
||||
return types.String(p.From)
|
||||
case jsonPatchValue:
|
||||
return p.Val
|
||||
default:
|
||||
|
||||
}
|
||||
}
|
||||
return types.NewErr("unsupported indexer: %s", index)
|
||||
}
|
||||
|
||||
func (p *JSONPatchVal) IsSet(field ref.Val) ref.Val {
|
||||
if name, ok := field.Value().(string); ok {
|
||||
switch name {
|
||||
case jsonPatchOp:
|
||||
return types.Bool(len(p.Op) > 0)
|
||||
case jsonPatchPath:
|
||||
return types.Bool(len(p.Path) > 0)
|
||||
case jsonPatchFrom:
|
||||
return types.Bool(len(p.From) > 0)
|
||||
case jsonPatchValue:
|
||||
return types.Bool(p.Val != nil)
|
||||
}
|
||||
}
|
||||
return types.NewErr("unsupported field: %s", field)
|
||||
}
|
||||
|
||||
func (p *JSONPatchVal) Type() ref.Type {
|
||||
return jsonPatchType
|
||||
}
|
||||
|
||||
func (p *JSONPatchVal) Value() any {
|
||||
return p
|
||||
}
|
||||
|
||||
var _ ref.Val = &JSONPatchVal{}
|
47
vendor/k8s.io/apiserver/pkg/cel/mutation/typeresolver.go
generated
vendored
Normal file
47
vendor/k8s.io/apiserver/pkg/cel/mutation/typeresolver.go
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
Copyright 2024 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 mutation
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/apiserver/pkg/cel/common"
|
||||
"k8s.io/apiserver/pkg/cel/mutation/dynamic"
|
||||
)
|
||||
|
||||
// ObjectTypeName is the name of Object types that are used to declare the types of
|
||||
// Kubernetes objects in CEL dynamically using the naming scheme "Object.<fieldName>...<fieldName>".
|
||||
// For example "Object.spec.containers" is the type of the spec.containers field of the object in scope.
|
||||
const ObjectTypeName = "Object"
|
||||
|
||||
// JSONPatchTypeName is the name of the JSONPatch type. This type is typically used to create JSON patches
|
||||
// in CEL expressions.
|
||||
const JSONPatchTypeName = "JSONPatch"
|
||||
|
||||
// DynamicTypeResolver resolves the Object and JSONPatch types when compiling
|
||||
// CEL expressions without schema information about the object.
|
||||
type DynamicTypeResolver struct{}
|
||||
|
||||
func (r *DynamicTypeResolver) Resolve(name string) (common.ResolvedType, bool) {
|
||||
if name == JSONPatchTypeName {
|
||||
return &JSONPatchType{}, true
|
||||
}
|
||||
if name == ObjectTypeName || strings.HasPrefix(name, ObjectTypeName+".") {
|
||||
return dynamic.NewObjectType(name), true
|
||||
}
|
||||
return nil, false
|
||||
}
|
73
vendor/k8s.io/apiserver/pkg/cel/semver.go
generated
vendored
Normal file
73
vendor/k8s.io/apiserver/pkg/cel/semver.go
generated
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
Copyright 2024 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 (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/blang/semver/v4"
|
||||
"github.com/google/cel-go/cel"
|
||||
"github.com/google/cel-go/common/types"
|
||||
"github.com/google/cel-go/common/types/ref"
|
||||
)
|
||||
|
||||
var (
|
||||
SemverType = cel.ObjectType("kubernetes.Semver")
|
||||
)
|
||||
|
||||
// Semver provdes a CEL representation of a [semver.Version].
|
||||
type Semver struct {
|
||||
semver.Version
|
||||
}
|
||||
|
||||
func (v Semver) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
|
||||
if reflect.TypeOf(v.Version).AssignableTo(typeDesc) {
|
||||
return v.Version, nil
|
||||
}
|
||||
if reflect.TypeOf("").AssignableTo(typeDesc) {
|
||||
return v.Version.String(), nil
|
||||
}
|
||||
return nil, fmt.Errorf("type conversion error from 'Semver' to '%v'", typeDesc)
|
||||
}
|
||||
|
||||
func (v Semver) ConvertToType(typeVal ref.Type) ref.Val {
|
||||
switch typeVal {
|
||||
case SemverType:
|
||||
return v
|
||||
case types.TypeType:
|
||||
return SemverType
|
||||
default:
|
||||
return types.NewErr("type conversion error from '%s' to '%s'", SemverType, typeVal)
|
||||
}
|
||||
}
|
||||
|
||||
func (v Semver) Equal(other ref.Val) ref.Val {
|
||||
otherDur, ok := other.(Semver)
|
||||
if !ok {
|
||||
return types.MaybeNoSuchOverloadErr(other)
|
||||
}
|
||||
return types.Bool(v.Version.EQ(otherDur.Version))
|
||||
}
|
||||
|
||||
func (v Semver) Type() ref.Type {
|
||||
return SemverType
|
||||
}
|
||||
|
||||
func (v Semver) Value() interface{} {
|
||||
return v.Version
|
||||
}
|
2
vendor/k8s.io/apiserver/pkg/cel/types.go
generated
vendored
2
vendor/k8s.io/apiserver/pkg/cel/types.go
generated
vendored
@ -429,7 +429,7 @@ func (rt *DeclTypeProvider) FindStructType(typeName string) (*types.Type, bool)
|
||||
declType, found := rt.findDeclType(typeName)
|
||||
if found {
|
||||
expT := declType.CelType()
|
||||
return expT, found
|
||||
return types.NewTypeTypeWithParam(expT), found
|
||||
}
|
||||
return rt.typeProvider.FindStructType(typeName)
|
||||
}
|
||||
|
Reference in New Issue
Block a user