mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-06 16:06:56 +00:00
167 lines
4.1 KiB
Go
167 lines
4.1 KiB
Go
package resource_test
|
|
|
|
import (
|
|
"errors"
|
|
"testing"
|
|
|
|
"github.com/google/cel-go/cel"
|
|
engine "github.com/kyverno/kyverno/pkg/cel"
|
|
"github.com/kyverno/kyverno/pkg/cel/resource"
|
|
"github.com/stretchr/testify/assert"
|
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
"k8s.io/kube-openapi/pkg/validation/spec"
|
|
)
|
|
|
|
func testSchema() *spec.Schema {
|
|
// Manual construction of a schema with the following definition:
|
|
//
|
|
// schema:
|
|
// type: object
|
|
// metadata:
|
|
// custom_type: "CustomObject"
|
|
// required:
|
|
// - name
|
|
// - value
|
|
// properties:
|
|
// name:
|
|
// type: string
|
|
// nested:
|
|
// type: object
|
|
// properties:
|
|
// subname:
|
|
// type: string
|
|
// flags:
|
|
// type: object
|
|
// additionalProperties:
|
|
// type: boolean
|
|
// dates:
|
|
// type: array
|
|
// items:
|
|
// type: string
|
|
// format: date-time
|
|
// metadata:
|
|
// type: object
|
|
// additionalProperties:
|
|
// type: object
|
|
// properties:
|
|
// key:
|
|
// type: string
|
|
// values:
|
|
// type: array
|
|
// items: string
|
|
// value:
|
|
// type: integer
|
|
// format: int64
|
|
// default: 1
|
|
// enum: [1,2,3]
|
|
return &spec.Schema{
|
|
SchemaProps: spec.SchemaProps{
|
|
Type: []string{"object"},
|
|
Properties: map[string]spec.Schema{
|
|
"name": *spec.StringProperty(),
|
|
"value": {SchemaProps: spec.SchemaProps{
|
|
Type: []string{"integer"},
|
|
Default: int64(1),
|
|
Format: "int64",
|
|
Enum: []any{1, 2, 3},
|
|
}},
|
|
"nested": {SchemaProps: spec.SchemaProps{
|
|
Type: []string{"object"},
|
|
Properties: map[string]spec.Schema{
|
|
"subname": *spec.StringProperty(),
|
|
"flags": {SchemaProps: spec.SchemaProps{
|
|
Type: []string{"object"},
|
|
AdditionalProperties: &spec.SchemaOrBool{
|
|
Schema: spec.BooleanProperty(),
|
|
},
|
|
}},
|
|
"dates": {SchemaProps: spec.SchemaProps{
|
|
Type: []string{"array"},
|
|
Items: &spec.SchemaOrArray{Schema: &spec.Schema{
|
|
SchemaProps: spec.SchemaProps{
|
|
Type: []string{"string"},
|
|
Format: "date-time",
|
|
}}}}},
|
|
},
|
|
},
|
|
},
|
|
"metadata": {SchemaProps: spec.SchemaProps{
|
|
Type: []string{"object"},
|
|
Properties: map[string]spec.Schema{
|
|
"name": *spec.StringProperty(),
|
|
"value": {
|
|
SchemaProps: spec.SchemaProps{
|
|
Type: []string{"array"},
|
|
Items: &spec.SchemaOrArray{Schema: &spec.Schema{
|
|
SchemaProps: spec.SchemaProps{
|
|
Type: []string{"string"},
|
|
}}},
|
|
},
|
|
},
|
|
},
|
|
}},
|
|
}}}
|
|
}
|
|
|
|
type TestClient struct{}
|
|
|
|
func (_ TestClient) ResolveSchema(gvk schema.GroupVersionKind) (*spec.Schema, error) {
|
|
return testSchema(), nil
|
|
}
|
|
|
|
func TestOpenAPITypeResolver(t *testing.T) {
|
|
typeName := "self"
|
|
|
|
s := schema.FromAPIVersionAndKind("v1", "CustomObject")
|
|
|
|
resolver := resource.NewOpenAPITypeResolver(TestClient{})
|
|
|
|
provider, err := resolver.GetDeclProvier(s, typeName)
|
|
if err != nil {
|
|
t.Fatal(err.Error())
|
|
}
|
|
|
|
env, err := engine.NewEnv()
|
|
opts, err := provider.EnvOptions(env.CELTypeProvider())
|
|
|
|
rootType, ok := provider.FindDeclType(typeName)
|
|
if !ok {
|
|
t.Fatal("declaration type not found")
|
|
}
|
|
|
|
opts = append(opts, cel.Variable("object", rootType.CelType()))
|
|
env, err = env.Extend(opts...)
|
|
|
|
ast, issue := env.Compile(`object.name != ""`)
|
|
if issue != nil {
|
|
t.Fatal(issue.Err().Error())
|
|
}
|
|
|
|
prog, err := env.Program(ast)
|
|
if err != nil {
|
|
t.Fatal(err.Error())
|
|
}
|
|
|
|
_, _, err = prog.Eval(map[string]any{
|
|
"object": map[string]any{
|
|
"name": "test",
|
|
},
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err.Error())
|
|
}
|
|
}
|
|
|
|
type TestClientError struct{}
|
|
|
|
func (_ TestClientError) ResolveSchema(gvk schema.GroupVersionKind) (*spec.Schema, error) {
|
|
return nil, errors.New("dummy")
|
|
}
|
|
|
|
func TestOpenAPITypeResolverError(t *testing.T) {
|
|
typeName := "self"
|
|
s := schema.FromAPIVersionAndKind("v1", "CustomObject")
|
|
resolver := resource.NewOpenAPITypeResolver(TestClientError{})
|
|
_, err := resolver.GetDeclProvier(s, typeName)
|
|
assert.Error(t, err)
|
|
}
|