rebase: bump the k8s-dependencies group in /e2e with 3 updates

Bumps the k8s-dependencies group in /e2e with 3 updates: [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery), [k8s.io/cloud-provider](https://github.com/kubernetes/cloud-provider) and [k8s.io/pod-security-admission](https://github.com/kubernetes/pod-security-admission).


Updates `k8s.io/apimachinery` from 0.32.3 to 0.33.0
- [Commits](https://github.com/kubernetes/apimachinery/compare/v0.32.3...v0.33.0)

Updates `k8s.io/cloud-provider` from 0.32.3 to 0.33.0
- [Commits](https://github.com/kubernetes/cloud-provider/compare/v0.32.3...v0.33.0)

Updates `k8s.io/pod-security-admission` from 0.32.3 to 0.33.0
- [Commits](https://github.com/kubernetes/pod-security-admission/compare/v0.32.3...v0.33.0)

---
updated-dependencies:
- dependency-name: k8s.io/apimachinery
  dependency-version: 0.33.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: k8s-dependencies
- dependency-name: k8s.io/cloud-provider
  dependency-version: 0.33.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: k8s-dependencies
- dependency-name: k8s.io/pod-security-admission
  dependency-version: 0.33.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: k8s-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
dependabot[bot]
2025-05-06 11:20:01 +00:00
committed by mergify[bot]
parent d52dc2c4ba
commit dd77e72800
359 changed files with 11145 additions and 18557 deletions

View File

@ -156,6 +156,11 @@ type PartialActivation interface {
UnknownAttributePatterns() []*AttributePattern
}
// partialActivationConverter indicates whether an Activation implementation supports conversion to a PartialActivation
type partialActivationConverter interface {
asPartialActivation() (PartialActivation, bool)
}
// partActivation is the default implementations of the PartialActivation interface.
type partActivation struct {
Activation
@ -166,3 +171,20 @@ type partActivation struct {
func (a *partActivation) UnknownAttributePatterns() []*AttributePattern {
return a.unknowns
}
// asPartialActivation returns the partActivation as a PartialActivation interface.
func (a *partActivation) asPartialActivation() (PartialActivation, bool) {
return a, true
}
func asPartialActivation(vars Activation) (PartialActivation, bool) {
// Only internal activation instances may implement this interface
if pv, ok := vars.(partialActivationConverter); ok {
return pv.asPartialActivation()
}
// Since Activations may be hierarchical, test whether a parent converts to a PartialActivation
if vars.Parent() != nil {
return asPartialActivation(vars.Parent())
}
return nil, false
}

View File

@ -358,7 +358,7 @@ func (m *attributeMatcher) AddQualifier(qual Qualifier) (Attribute, error) {
func (m *attributeMatcher) Resolve(vars Activation) (any, error) {
id := m.NamespacedAttribute.ID()
// Bug in how partial activation is resolved, should search parents as well.
partial, isPartial := toPartialActivation(vars)
partial, isPartial := asPartialActivation(vars)
if isPartial {
unk, err := m.fac.matchesUnknownPatterns(
partial,
@ -384,14 +384,3 @@ func (m *attributeMatcher) Qualify(vars Activation, obj any) (any, error) {
func (m *attributeMatcher) QualifyIfPresent(vars Activation, obj any, presenceOnly bool) (any, bool, error) {
return attrQualifyIfPresent(m.fac, vars, obj, m, presenceOnly)
}
func toPartialActivation(vars Activation) (PartialActivation, bool) {
pv, ok := vars.(PartialActivation)
if ok {
return pv, true
}
if vars.Parent() != nil {
return toPartialActivation(vars.Parent())
}
return nil, false
}

View File

@ -762,6 +762,9 @@ func (fold *evalFold) Eval(ctx Activation) ref.Val {
defer releaseFolder(f)
foldRange := fold.iterRange.Eval(ctx)
if types.IsUnknownOrError(foldRange) {
return foldRange
}
if fold.iterVar2 != "" {
var foldable traits.Foldable
switch r := foldRange.(type) {
@ -1241,7 +1244,7 @@ func invalidOptionalElementInit(value ref.Val) ref.Val {
func newFolder(eval *evalFold, ctx Activation) *folder {
f := folderPool.Get().(*folder)
f.evalFold = eval
f.Activation = ctx
f.activation = ctx
return f
}
@ -1262,7 +1265,7 @@ func releaseFolder(f *folder) {
// cel.bind or cel.@block.
type folder struct {
*evalFold
Activation
activation Activation
// fold state objects.
accuVal ref.Val
@ -1290,7 +1293,7 @@ func (f *folder) foldIterable(iterable traits.Iterable) ref.Val {
// Update the accumulation value and check for eval interuption.
f.accuVal = f.step.Eval(f)
f.initialized = true
if f.interruptable && checkInterrupt(f.Activation) {
if f.interruptable && checkInterrupt(f.activation) {
f.interrupted = true
return f.evalResult()
}
@ -1316,7 +1319,7 @@ func (f *folder) FoldEntry(key, val any) bool {
// Update the accumulation value and check for eval interuption.
f.accuVal = f.step.Eval(f)
f.initialized = true
if f.interruptable && checkInterrupt(f.Activation) {
if f.interruptable && checkInterrupt(f.activation) {
f.interrupted = true
return false
}
@ -1330,7 +1333,7 @@ func (f *folder) ResolveName(name string) (any, bool) {
if name == f.accuVar {
if !f.initialized {
f.initialized = true
initVal := f.accu.Eval(f.Activation)
initVal := f.accu.Eval(f.activation)
if !f.exhaustive {
if l, isList := initVal.(traits.Lister); isList && l.Size() == types.IntZero {
initVal = types.NewMutableList(f.adapter)
@ -1355,7 +1358,32 @@ func (f *folder) ResolveName(name string) (any, bool) {
return f.iterVar2Val, true
}
}
return f.Activation.ResolveName(name)
return f.activation.ResolveName(name)
}
// Parent returns the activation embedded into the folder.
func (f *folder) Parent() Activation {
return f.activation
}
// UnknownAttributePatterns implements the PartialActivation interface returning the unknown patterns
// if they were provided to the input activation, or an empty set if the proxied activation is not partial.
func (f *folder) UnknownAttributePatterns() []*AttributePattern {
if pv, ok := f.activation.(partialActivationConverter); ok {
if partial, isPartial := pv.asPartialActivation(); isPartial {
return partial.UnknownAttributePatterns()
}
}
return []*AttributePattern{}
}
func (f *folder) asPartialActivation() (PartialActivation, bool) {
if pv, ok := f.activation.(partialActivationConverter); ok {
if _, isPartial := pv.asPartialActivation(); isPartial {
return f, true
}
}
return nil, false
}
// evalResult computes the final result of the fold after all entries have been folded and accumulated.
@ -1381,7 +1409,7 @@ func (f *folder) evalResult() ref.Val {
// reset clears any state associated with folder evaluation.
func (f *folder) reset() {
f.evalFold = nil
f.Activation = nil
f.activation = nil
f.accuVal = nil
f.iterVar1Val = nil
f.iterVar2Val = nil

View File

@ -506,7 +506,7 @@ func (p *planner) planCreateList(expr ast.Expr) (Interpretable, error) {
id: expr.ID(),
elems: elems,
optionals: optionals,
hasOptionals: len(optionals) != 0,
hasOptionals: len(optionalIndices) != 0,
adapter: p.adapter,
}, nil
}
@ -518,6 +518,7 @@ func (p *planner) planCreateMap(expr ast.Expr) (Interpretable, error) {
optionals := make([]bool, len(entries))
keys := make([]Interpretable, len(entries))
vals := make([]Interpretable, len(entries))
hasOptionals := false
for i, e := range entries {
entry := e.AsMapEntry()
keyVal, err := p.Plan(entry.Key())
@ -532,13 +533,14 @@ func (p *planner) planCreateMap(expr ast.Expr) (Interpretable, error) {
}
vals[i] = valVal
optionals[i] = entry.IsOptional()
hasOptionals = hasOptionals || entry.IsOptional()
}
return &evalMap{
id: expr.ID(),
keys: keys,
vals: vals,
optionals: optionals,
hasOptionals: len(optionals) != 0,
hasOptionals: hasOptionals,
adapter: p.adapter,
}, nil
}
@ -554,6 +556,7 @@ func (p *planner) planCreateStruct(expr ast.Expr) (Interpretable, error) {
optionals := make([]bool, len(objFields))
fields := make([]string, len(objFields))
vals := make([]Interpretable, len(objFields))
hasOptionals := false
for i, f := range objFields {
field := f.AsStructField()
fields[i] = field.Name()
@ -563,6 +566,7 @@ func (p *planner) planCreateStruct(expr ast.Expr) (Interpretable, error) {
}
vals[i] = val
optionals[i] = field.IsOptional()
hasOptionals = hasOptionals || field.IsOptional()
}
return &evalObj{
id: expr.ID(),
@ -570,7 +574,7 @@ func (p *planner) planCreateStruct(expr ast.Expr) (Interpretable, error) {
fields: fields,
vals: vals,
optionals: optionals,
hasOptionals: len(optionals) != 0,
hasOptionals: hasOptionals,
provider: p.provider,
}, nil
}

View File

@ -88,7 +88,7 @@ func PruneAst(expr ast.Expr, macroCalls map[int64]ast.Expr, state EvalState) *as
func (p *astPruner) maybeCreateLiteral(id int64, val ref.Val) (ast.Expr, bool) {
switch v := val.(type) {
case types.Bool, types.Bytes, types.Double, types.Int, types.Null, types.String, types.Uint:
case types.Bool, types.Bytes, types.Double, types.Int, types.Null, types.String, types.Uint, *types.Optional:
p.state.SetValue(id, val)
return p.NewLiteral(id, val), true
case types.Duration:
@ -281,13 +281,29 @@ func (p *astPruner) prune(node ast.Expr) (ast.Expr, bool) {
}
if macro, found := p.macroCalls[node.ID()]; found {
// Ensure that intermediate values for the comprehension are cleared during pruning
pruneMacroCall := node.Kind() != ast.UnspecifiedExprKind
if node.Kind() == ast.ComprehensionKind {
compre := node.AsComprehension()
visit(macro, clearIterVarVisitor(compre.IterVar(), p.state))
// Only prune cel.bind() calls since the variables of the comprehension are all
// visible to the user, so there's no chance of an incorrect value being observed
// as a result of looking at intermediate computations within a comprehension.
pruneMacroCall = isCelBindMacro(macro)
}
// prune the expression in terms of the macro call instead of the expanded form.
if newMacro, pruned := p.prune(macro); pruned {
p.macroCalls[node.ID()] = newMacro
if pruneMacroCall {
// prune the expression in terms of the macro call instead of the expanded form when
// dealing with macro call tracking references.
if newMacro, pruned := p.prune(macro); pruned {
p.macroCalls[node.ID()] = newMacro
}
} else {
// Otherwise just prune the macro target in keeping with the pruning behavior of the
// comprehensions later in the call graph.
macroCall := macro.AsCall()
if macroCall.Target() != nil {
if newTarget, pruned := p.prune(macroCall.Target()); pruned {
macro = p.NewMemberCall(macro.ID(), macroCall.FunctionName(), newTarget, macroCall.Args()...)
p.macroCalls[node.ID()] = macro
}
}
}
}
@ -421,6 +437,19 @@ func (p *astPruner) prune(node ast.Expr) (ast.Expr, bool) {
// the last iteration of the comprehension and not each step in the evaluation which
// means that the any residuals computed in between might be inaccurate.
if newRange, pruned := p.maybePrune(compre.IterRange()); pruned {
if compre.HasIterVar2() {
return p.NewComprehensionTwoVar(
node.ID(),
newRange,
compre.IterVar(),
compre.IterVar2(),
compre.AccuVar(),
compre.AccuInit(),
compre.LoopCondition(),
compre.LoopStep(),
compre.Result(),
), true
}
return p.NewComprehension(
node.ID(),
newRange,
@ -468,16 +497,6 @@ func getMaxID(expr ast.Expr) int64 {
return maxID
}
func clearIterVarVisitor(varName string, state EvalState) astVisitor {
return astVisitor{
visitExpr: func(e ast.Expr) {
if e.Kind() == ast.IdentKind && e.AsIdent() == varName {
state.SetValue(e.ID(), nil)
}
},
}
}
func maxIDVisitor(maxID *int64) astVisitor {
return astVisitor{
visitExpr: func(e ast.Expr) {
@ -541,3 +560,15 @@ func visit(expr ast.Expr, visitor astVisitor) {
}
}
}
func isCelBindMacro(macro ast.Expr) bool {
if macro.Kind() != ast.CallKind {
return false
}
macroCall := macro.AsCall()
target := macroCall.Target()
return macroCall.FunctionName() == "bind" &&
macroCall.IsMemberFunction() &&
target.Kind() == ast.IdentKind &&
target.AsIdent() == "cel"
}

View File

@ -198,20 +198,20 @@ func (c *CostTracker) costCall(call InterpretableCall, args []ref.Val, result re
switch call.OverloadID() {
// O(n) functions
case overloads.StartsWithString, overloads.EndsWithString, overloads.StringToBytes, overloads.BytesToString, overloads.ExtQuoteString, overloads.ExtFormatString:
cost += uint64(math.Ceil(float64(c.actualSize(args[0])) * common.StringTraversalCostFactor))
cost += uint64(math.Ceil(float64(actualSize(args[0])) * common.StringTraversalCostFactor))
case overloads.InList:
// If a list is composed entirely of constant values this is O(1), but we don't account for that here.
// We just assume all list containment checks are O(n).
cost += c.actualSize(args[1])
cost += actualSize(args[1])
// O(min(m, n)) functions
case overloads.LessString, overloads.GreaterString, overloads.LessEqualsString, overloads.GreaterEqualsString,
overloads.LessBytes, overloads.GreaterBytes, overloads.LessEqualsBytes, overloads.GreaterEqualsBytes,
overloads.Equals, overloads.NotEquals:
// When we check the equality of 2 scalar values (e.g. 2 integers, 2 floating-point numbers, 2 booleans etc.),
// the CostTracker.actualSize() function by definition returns 1 for each operand, resulting in an overall cost
// the CostTracker.ActualSize() function by definition returns 1 for each operand, resulting in an overall cost
// of 1.
lhsSize := c.actualSize(args[0])
rhsSize := c.actualSize(args[1])
lhsSize := actualSize(args[0])
rhsSize := actualSize(args[1])
minSize := lhsSize
if rhsSize < minSize {
minSize = rhsSize
@ -220,23 +220,23 @@ func (c *CostTracker) costCall(call InterpretableCall, args []ref.Val, result re
// O(m+n) functions
case overloads.AddString, overloads.AddBytes:
// In the worst case scenario, we would need to reallocate a new backing store and copy both operands over.
cost += uint64(math.Ceil(float64(c.actualSize(args[0])+c.actualSize(args[1])) * common.StringTraversalCostFactor))
cost += uint64(math.Ceil(float64(actualSize(args[0])+actualSize(args[1])) * common.StringTraversalCostFactor))
// O(nm) functions
case overloads.MatchesString:
// https://swtch.com/~rsc/regexp/regexp1.html applies to RE2 implementation supported by CEL
// Add one to string length for purposes of cost calculation to prevent product of string and regex to be 0
// in case where string is empty but regex is still expensive.
strCost := uint64(math.Ceil((1.0 + float64(c.actualSize(args[0]))) * common.StringTraversalCostFactor))
strCost := uint64(math.Ceil((1.0 + float64(actualSize(args[0]))) * common.StringTraversalCostFactor))
// We don't know how many expressions are in the regex, just the string length (a huge
// improvement here would be to somehow get a count the number of expressions in the regex or
// how many states are in the regex state machine and use that to measure regex cost).
// For now, we're making a guess that each expression in a regex is typically at least 4 chars
// in length.
regexCost := uint64(math.Ceil(float64(c.actualSize(args[1])) * common.RegexStringLengthCostFactor))
regexCost := uint64(math.Ceil(float64(actualSize(args[1])) * common.RegexStringLengthCostFactor))
cost += strCost * regexCost
case overloads.ContainsString:
strCost := uint64(math.Ceil(float64(c.actualSize(args[0])) * common.StringTraversalCostFactor))
substrCost := uint64(math.Ceil(float64(c.actualSize(args[1])) * common.StringTraversalCostFactor))
strCost := uint64(math.Ceil(float64(actualSize(args[0])) * common.StringTraversalCostFactor))
substrCost := uint64(math.Ceil(float64(actualSize(args[1])) * common.StringTraversalCostFactor))
cost += strCost * substrCost
default:
@ -253,11 +253,15 @@ func (c *CostTracker) costCall(call InterpretableCall, args []ref.Val, result re
return cost
}
// actualSize returns the size of value
func (c *CostTracker) actualSize(value ref.Val) uint64 {
// actualSize returns the size of the value for all traits.Sizer values, a fixed size for all proto-based
// objects, and a size of 1 for all other value types.
func actualSize(value ref.Val) uint64 {
if sz, ok := value.(traits.Sizer); ok {
return uint64(sz.Size().(types.Int))
}
if opt, ok := value.(*types.Optional); ok && opt.HasValue() {
return actualSize(opt.GetValue())
}
return 1
}