mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-03 09:22:44 +00:00
add support of variables for Type Checking.
This commit is contained in:
parent
21ba0d59d3
commit
dc832c6e59
@ -188,7 +188,7 @@ func (c *TypeChecker) compiler(ctx *TypeCheckingContext, typeOverwrite typeOverw
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
compiler := &plugincel.CompositedCompiler{
|
compiler := &plugincel.CompositedCompiler{
|
||||||
Compiler: &typeCheckingCompiler{typeOverwrite: typeOverwrite},
|
Compiler: &typeCheckingCompiler{typeOverwrite: typeOverwrite, compositionEnv: env},
|
||||||
CompositionEnv: env,
|
CompositionEnv: env,
|
||||||
}
|
}
|
||||||
return compiler, nil
|
return compiler, nil
|
||||||
@ -449,7 +449,8 @@ func createVariableOpts(declType *apiservercel.DeclType, variables ...string) []
|
|||||||
}
|
}
|
||||||
|
|
||||||
type typeCheckingCompiler struct {
|
type typeCheckingCompiler struct {
|
||||||
typeOverwrite typeOverwrite
|
compositionEnv *plugincel.CompositionEnv
|
||||||
|
typeOverwrite typeOverwrite
|
||||||
}
|
}
|
||||||
|
|
||||||
// CompileCELExpression compiles the given expression.
|
// CompileCELExpression compiles the given expression.
|
||||||
@ -468,20 +469,18 @@ func (c *typeCheckingCompiler) CompileCELExpression(expressionAccessor plugincel
|
|||||||
ExpressionAccessor: expressionAccessor,
|
ExpressionAccessor: expressionAccessor,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
envSet, err := buildEnvSet(options.HasParams, options.HasAuthorizer, c.typeOverwrite)
|
env, err := c.compositionEnv.Env(mode)
|
||||||
if err != nil {
|
|
||||||
return resultError(fmt.Sprintf("fail to build env set: %v", err), apiservercel.ErrorTypeInternal)
|
|
||||||
}
|
|
||||||
env, err := envSet.Env(mode)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return resultError(fmt.Sprintf("fail to build env: %v", err), apiservercel.ErrorTypeInternal)
|
return resultError(fmt.Sprintf("fail to build env: %v", err), apiservercel.ErrorTypeInternal)
|
||||||
}
|
}
|
||||||
_, issues := env.Compile(expressionAccessor.GetExpression())
|
ast, issues := env.Compile(expressionAccessor.GetExpression())
|
||||||
if issues != nil {
|
if issues != nil {
|
||||||
return resultError(issues.String(), apiservercel.ErrorTypeInvalid)
|
return resultError(issues.String(), apiservercel.ErrorTypeInvalid)
|
||||||
}
|
}
|
||||||
// type checker does not require the program, an empty result indicates successful compilation.
|
// type checker does not require the program, however the type must still be set.
|
||||||
return plugincel.CompilationResult{}
|
return plugincel.CompilationResult{
|
||||||
|
OutputType: ast.OutputType(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ plugincel.Compiler = (*typeCheckingCompiler)(nil)
|
var _ plugincel.Compiler = (*typeCheckingCompiler)(nil)
|
||||||
|
@ -413,6 +413,95 @@ func TestTypeCheck(t *testing.T) {
|
|||||||
toContain("found no matching overload for 'allowed' applied to 'kubernetes.authorization.Authorizer"),
|
toContain("found no matching overload for 'allowed' applied to 'kubernetes.authorization.Authorizer"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "variables valid",
|
||||||
|
policy: &v1beta1.ValidatingAdmissionPolicy{Spec: v1beta1.ValidatingAdmissionPolicySpec{
|
||||||
|
Variables: []v1beta1.Variable{
|
||||||
|
{
|
||||||
|
Name: "works",
|
||||||
|
Expression: "true",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Validations: []v1beta1.Validation{
|
||||||
|
{
|
||||||
|
Expression: "variables.works",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MatchConstraints: deploymentPolicy.Spec.MatchConstraints,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
schemaToReturn: &spec.Schema{
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"object"},
|
||||||
|
Properties: map[string]spec.Schema{
|
||||||
|
"foo": *spec.Int64Property(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
assertions: []assertionFunc{toHaveLengthOf(0)},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "variables missing field",
|
||||||
|
policy: &v1beta1.ValidatingAdmissionPolicy{Spec: v1beta1.ValidatingAdmissionPolicySpec{
|
||||||
|
Variables: []v1beta1.Variable{
|
||||||
|
{
|
||||||
|
Name: "works",
|
||||||
|
Expression: "true",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Validations: []v1beta1.Validation{
|
||||||
|
{
|
||||||
|
Expression: "variables.nonExisting",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MatchConstraints: deploymentPolicy.Spec.MatchConstraints,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
schemaToReturn: &spec.Schema{
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"object"},
|
||||||
|
Properties: map[string]spec.Schema{
|
||||||
|
"foo": *spec.Int64Property(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
assertions: []assertionFunc{
|
||||||
|
toHaveLengthOf(1),
|
||||||
|
toHaveFieldRef("spec.validations[0].expression"),
|
||||||
|
toContain("undefined field 'nonExisting'"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "variables field wrong type",
|
||||||
|
policy: &v1beta1.ValidatingAdmissionPolicy{Spec: v1beta1.ValidatingAdmissionPolicySpec{
|
||||||
|
Variables: []v1beta1.Variable{
|
||||||
|
{
|
||||||
|
Name: "name",
|
||||||
|
Expression: "'something'",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Validations: []v1beta1.Validation{
|
||||||
|
{
|
||||||
|
Expression: "variables.name == object.foo", // foo is int64
|
||||||
|
},
|
||||||
|
},
|
||||||
|
MatchConstraints: deploymentPolicy.Spec.MatchConstraints,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
schemaToReturn: &spec.Schema{
|
||||||
|
SchemaProps: spec.SchemaProps{
|
||||||
|
Type: []string{"object"},
|
||||||
|
Properties: map[string]spec.Schema{
|
||||||
|
"foo": *spec.Int64Property(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
assertions: []assertionFunc{
|
||||||
|
toHaveLengthOf(1),
|
||||||
|
toHaveFieldRef("spec.validations[0].expression"),
|
||||||
|
toContain("found no matching overload for '_==_' applied to '(string, int)"),
|
||||||
|
},
|
||||||
|
},
|
||||||
} {
|
} {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
typeChecker := buildTypeChecker(tc.schemaToReturn)
|
typeChecker := buildTypeChecker(tc.schemaToReturn)
|
||||||
|
Loading…
Reference in New Issue
Block a user