mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-06 07:57:07 +00:00
* initial commit * background policy validation * correct message * skip non-background policy process for add/update * add Generate Request CR * generate Request Generator Initial * test generate request CR generation * initial commit gr generator * generate controller initial framework * add crd for generate request * gr cleanup controller initial commit * cleanup controller initial * generate mid-commit * generate rule processing * create PV on generate error * embed resource type * testing phase 1- generate resources with variable substitution * fix tests * comment broken test #586 * add printer column for state * return if existing resource for clone * set resync time to 2 mins & remove resource version check in update handler for gr * generate events for reporting * fix logs * initial commit * fix trailing quote in patch * remove comments * initial condition (equal & notequal) * initial support for conditions * initial support fo conditions in generate * support precondition checks * cleanup * re-evaluate GR on namespace update using dynamic informers * add status for generated resources * display loaded variable SA * support delete cleanup of generate request main resources * fix log * remove namespace from SA username * support multiple variables per statement for scalar values * fix fail variables * add check for userInfo * validation checks for conditions * update policy * refactor logs * code review * add openapispec for clusterpolicy preconditions * Update documentation * CR fixes * documentation * CR fixes * update variable * fix logs * update policy * pre-defined variables (serviceAccountName & serviceAccountNamespace) * update test
518 lines
10 KiB
Go
518 lines
10 KiB
Go
package variables
|
|
|
|
import (
|
|
"encoding/json"
|
|
"testing"
|
|
|
|
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
|
|
"github.com/nirmata/kyverno/pkg/engine/context"
|
|
)
|
|
|
|
// STRINGS
|
|
func Test_Eval_Equal_Const_String_Pass(t *testing.T) {
|
|
ctx := context.NewContext()
|
|
// no variables
|
|
condition := kyverno.Condition{
|
|
Key: "name",
|
|
Operator: kyverno.Equal,
|
|
Value: "name",
|
|
}
|
|
|
|
if !Evaluate(ctx, condition) {
|
|
t.Error("expected to pass")
|
|
}
|
|
}
|
|
|
|
func Test_Eval_Equal_Const_String_Fail(t *testing.T) {
|
|
ctx := context.NewContext()
|
|
// no variables
|
|
condition := kyverno.Condition{
|
|
Key: "name",
|
|
Operator: kyverno.Equal,
|
|
Value: "name1",
|
|
}
|
|
|
|
if Evaluate(ctx, condition) {
|
|
t.Error("expected to fail")
|
|
}
|
|
}
|
|
|
|
func Test_Eval_NoEqual_Const_String_Pass(t *testing.T) {
|
|
ctx := context.NewContext()
|
|
// no variables
|
|
condition := kyverno.Condition{
|
|
Key: "name",
|
|
Operator: kyverno.NotEqual,
|
|
Value: "name1",
|
|
}
|
|
|
|
if !Evaluate(ctx, condition) {
|
|
t.Error("expected to pass")
|
|
}
|
|
}
|
|
|
|
func Test_Eval_NoEqual_Const_String_Fail(t *testing.T) {
|
|
ctx := context.NewContext()
|
|
// no variables
|
|
condition := kyverno.Condition{
|
|
Key: "name",
|
|
Operator: kyverno.NotEqual,
|
|
Value: "name",
|
|
}
|
|
|
|
if Evaluate(ctx, condition) {
|
|
t.Error("expected to fail")
|
|
}
|
|
}
|
|
|
|
//Bool
|
|
|
|
func Test_Eval_Equal_Const_Bool_Pass(t *testing.T) {
|
|
ctx := context.NewContext()
|
|
// no variables
|
|
condition := kyverno.Condition{
|
|
Key: true,
|
|
Operator: kyverno.Equal,
|
|
Value: true,
|
|
}
|
|
|
|
if !Evaluate(ctx, condition) {
|
|
t.Error("expected to pass")
|
|
}
|
|
}
|
|
|
|
func Test_Eval_Equal_Const_Bool_Fail(t *testing.T) {
|
|
ctx := context.NewContext()
|
|
// no variables
|
|
condition := kyverno.Condition{
|
|
Key: true,
|
|
Operator: kyverno.Equal,
|
|
Value: false,
|
|
}
|
|
|
|
if Evaluate(ctx, condition) {
|
|
t.Error("expected to fail")
|
|
}
|
|
}
|
|
|
|
func Test_Eval_NoEqual_Const_Bool_Pass(t *testing.T) {
|
|
ctx := context.NewContext()
|
|
// no variables
|
|
condition := kyverno.Condition{
|
|
Key: true,
|
|
Operator: kyverno.NotEqual,
|
|
Value: false,
|
|
}
|
|
|
|
if !Evaluate(ctx, condition) {
|
|
t.Error("expected to pass")
|
|
}
|
|
}
|
|
|
|
func Test_Eval_NoEqual_Const_Bool_Fail(t *testing.T) {
|
|
ctx := context.NewContext()
|
|
// no variables
|
|
condition := kyverno.Condition{
|
|
Key: true,
|
|
Operator: kyverno.NotEqual,
|
|
Value: true,
|
|
}
|
|
|
|
if Evaluate(ctx, condition) {
|
|
t.Error("expected to fail")
|
|
}
|
|
}
|
|
|
|
// int
|
|
func Test_Eval_Equal_Const_int_Pass(t *testing.T) {
|
|
ctx := context.NewContext()
|
|
// no variables
|
|
condition := kyverno.Condition{
|
|
Key: 1,
|
|
Operator: kyverno.Equal,
|
|
Value: 1,
|
|
}
|
|
|
|
if !Evaluate(ctx, condition) {
|
|
t.Error("expected to pass")
|
|
}
|
|
}
|
|
|
|
func Test_Eval_Equal_Const_int_Fail(t *testing.T) {
|
|
ctx := context.NewContext()
|
|
// no variables
|
|
condition := kyverno.Condition{
|
|
Key: 1,
|
|
Operator: kyverno.Equal,
|
|
Value: 2,
|
|
}
|
|
|
|
if Evaluate(ctx, condition) {
|
|
t.Error("expected to fail")
|
|
}
|
|
}
|
|
|
|
func Test_Eval_NoEqual_Const_int_Pass(t *testing.T) {
|
|
ctx := context.NewContext()
|
|
// no variables
|
|
condition := kyverno.Condition{
|
|
Key: 1,
|
|
Operator: kyverno.NotEqual,
|
|
Value: 2,
|
|
}
|
|
|
|
if !Evaluate(ctx, condition) {
|
|
t.Error("expected to pass")
|
|
}
|
|
}
|
|
|
|
func Test_Eval_NoEqual_Const_int_Fail(t *testing.T) {
|
|
ctx := context.NewContext()
|
|
// no variables
|
|
condition := kyverno.Condition{
|
|
Key: 1,
|
|
Operator: kyverno.NotEqual,
|
|
Value: 1,
|
|
}
|
|
|
|
if Evaluate(ctx, condition) {
|
|
t.Error("expected to fail")
|
|
}
|
|
}
|
|
|
|
// int64
|
|
func Test_Eval_Equal_Const_int64_Pass(t *testing.T) {
|
|
ctx := context.NewContext()
|
|
// no variables
|
|
condition := kyverno.Condition{
|
|
Key: int64(1),
|
|
Operator: kyverno.Equal,
|
|
Value: int64(1),
|
|
}
|
|
|
|
if !Evaluate(ctx, condition) {
|
|
t.Error("expected to pass")
|
|
}
|
|
}
|
|
|
|
func Test_Eval_Equal_Const_int64_Fail(t *testing.T) {
|
|
ctx := context.NewContext()
|
|
// no variables
|
|
condition := kyverno.Condition{
|
|
Key: int64(1),
|
|
Operator: kyverno.Equal,
|
|
Value: int64(2),
|
|
}
|
|
|
|
if Evaluate(ctx, condition) {
|
|
t.Error("expected to fail")
|
|
}
|
|
}
|
|
|
|
func Test_Eval_NoEqual_Const_int64_Pass(t *testing.T) {
|
|
ctx := context.NewContext()
|
|
// no variables
|
|
condition := kyverno.Condition{
|
|
Key: int64(1),
|
|
Operator: kyverno.NotEqual,
|
|
Value: int64(2),
|
|
}
|
|
|
|
if !Evaluate(ctx, condition) {
|
|
t.Error("expected to pass")
|
|
}
|
|
}
|
|
|
|
func Test_Eval_NoEqual_Const_int64_Fail(t *testing.T) {
|
|
ctx := context.NewContext()
|
|
// no variables
|
|
condition := kyverno.Condition{
|
|
Key: int64(1),
|
|
Operator: kyverno.NotEqual,
|
|
Value: int64(1),
|
|
}
|
|
|
|
if Evaluate(ctx, condition) {
|
|
t.Error("expected to fail")
|
|
}
|
|
}
|
|
|
|
//float64
|
|
|
|
func Test_Eval_Equal_Const_float64_Pass(t *testing.T) {
|
|
ctx := context.NewContext()
|
|
// no variables
|
|
condition := kyverno.Condition{
|
|
Key: 1.5,
|
|
Operator: kyverno.Equal,
|
|
Value: 1.5,
|
|
}
|
|
|
|
if !Evaluate(ctx, condition) {
|
|
t.Error("expected to pass")
|
|
}
|
|
}
|
|
|
|
func Test_Eval_Equal_Const_float64_Fail(t *testing.T) {
|
|
ctx := context.NewContext()
|
|
// no variables
|
|
condition := kyverno.Condition{
|
|
Key: 1.5,
|
|
Operator: kyverno.Equal,
|
|
Value: 1.6,
|
|
}
|
|
|
|
if Evaluate(ctx, condition) {
|
|
t.Error("expected to fail")
|
|
}
|
|
}
|
|
|
|
func Test_Eval_NoEqual_Const_float64_Pass(t *testing.T) {
|
|
ctx := context.NewContext()
|
|
// no variables
|
|
condition := kyverno.Condition{
|
|
Key: 1.5,
|
|
Operator: kyverno.NotEqual,
|
|
Value: 1.6,
|
|
}
|
|
|
|
if !Evaluate(ctx, condition) {
|
|
t.Error("expected to pass")
|
|
}
|
|
}
|
|
|
|
func Test_Eval_NoEqual_Const_float64_Fail(t *testing.T) {
|
|
ctx := context.NewContext()
|
|
// no variables
|
|
condition := kyverno.Condition{
|
|
Key: 1.5,
|
|
Operator: kyverno.NotEqual,
|
|
Value: 1.5,
|
|
}
|
|
|
|
if Evaluate(ctx, condition) {
|
|
t.Error("expected to fail")
|
|
}
|
|
}
|
|
|
|
//object/map[string]interface
|
|
|
|
func Test_Eval_Equal_Const_object_Pass(t *testing.T) {
|
|
ctx := context.NewContext()
|
|
|
|
obj1Raw := []byte(`{ "dir": { "file1": "a" } }`)
|
|
obj2Raw := []byte(`{ "dir": { "file1": "a" } }`)
|
|
var obj1, obj2 interface{}
|
|
json.Unmarshal(obj1Raw, &obj1)
|
|
json.Unmarshal(obj2Raw, &obj2)
|
|
// no variables
|
|
condition := kyverno.Condition{
|
|
Key: obj1,
|
|
Operator: kyverno.Equal,
|
|
Value: obj2,
|
|
}
|
|
|
|
if !Evaluate(ctx, condition) {
|
|
t.Error("expected to pass")
|
|
}
|
|
}
|
|
|
|
func Test_Eval_Equal_Const_object_Fail(t *testing.T) {
|
|
ctx := context.NewContext()
|
|
|
|
obj1Raw := []byte(`{ "dir": { "file1": "a" } }`)
|
|
obj2Raw := []byte(`{ "dir": { "file1": "b" } }`)
|
|
var obj1, obj2 interface{}
|
|
json.Unmarshal(obj1Raw, &obj1)
|
|
json.Unmarshal(obj2Raw, &obj2)
|
|
// no variables
|
|
condition := kyverno.Condition{
|
|
Key: obj1,
|
|
Operator: kyverno.Equal,
|
|
Value: obj2,
|
|
}
|
|
|
|
if Evaluate(ctx, condition) {
|
|
t.Error("expected to fail")
|
|
}
|
|
}
|
|
|
|
func Test_Eval_NotEqual_Const_object_Pass(t *testing.T) {
|
|
ctx := context.NewContext()
|
|
|
|
obj1Raw := []byte(`{ "dir": { "file1": "a" } }`)
|
|
obj2Raw := []byte(`{ "dir": { "file1": "b" } }`)
|
|
var obj1, obj2 interface{}
|
|
json.Unmarshal(obj1Raw, &obj1)
|
|
json.Unmarshal(obj2Raw, &obj2)
|
|
// no variables
|
|
condition := kyverno.Condition{
|
|
Key: obj1,
|
|
Operator: kyverno.NotEqual,
|
|
Value: obj2,
|
|
}
|
|
|
|
if !Evaluate(ctx, condition) {
|
|
t.Error("expected to pass")
|
|
}
|
|
}
|
|
|
|
func Test_Eval_NotEqual_Const_object_Fail(t *testing.T) {
|
|
ctx := context.NewContext()
|
|
|
|
obj1Raw := []byte(`{ "dir": { "file1": "a" } }`)
|
|
obj2Raw := []byte(`{ "dir": { "file1": "a" } }`)
|
|
var obj1, obj2 interface{}
|
|
json.Unmarshal(obj1Raw, &obj1)
|
|
json.Unmarshal(obj2Raw, &obj2)
|
|
// no variables
|
|
condition := kyverno.Condition{
|
|
Key: obj1,
|
|
Operator: kyverno.NotEqual,
|
|
Value: obj2,
|
|
}
|
|
|
|
if Evaluate(ctx, condition) {
|
|
t.Error("expected to fail")
|
|
}
|
|
}
|
|
|
|
// list/ []interface{}
|
|
|
|
func Test_Eval_Equal_Const_list_Pass(t *testing.T) {
|
|
ctx := context.NewContext()
|
|
|
|
obj1Raw := []byte(`[ { "name": "a", "file": "a" }, { "name": "b", "file": "b" } ]`)
|
|
obj2Raw := []byte(`[ { "name": "a", "file": "a" }, { "name": "b", "file": "b" } ]`)
|
|
var obj1, obj2 interface{}
|
|
json.Unmarshal(obj1Raw, &obj1)
|
|
json.Unmarshal(obj2Raw, &obj2)
|
|
// no variables
|
|
condition := kyverno.Condition{
|
|
Key: obj1,
|
|
Operator: kyverno.Equal,
|
|
Value: obj2,
|
|
}
|
|
|
|
if !Evaluate(ctx, condition) {
|
|
t.Error("expected to pass")
|
|
}
|
|
}
|
|
|
|
func Test_Eval_Equal_Const_list_Fail(t *testing.T) {
|
|
ctx := context.NewContext()
|
|
|
|
obj1Raw := []byte(`[ { "name": "a", "file": "a" }, { "name": "b", "file": "b" } ]`)
|
|
obj2Raw := []byte(`[ { "name": "b", "file": "a" }, { "name": "b", "file": "b" } ]`)
|
|
var obj1, obj2 interface{}
|
|
json.Unmarshal(obj1Raw, &obj1)
|
|
json.Unmarshal(obj2Raw, &obj2)
|
|
// no variables
|
|
condition := kyverno.Condition{
|
|
Key: obj1,
|
|
Operator: kyverno.Equal,
|
|
Value: obj2,
|
|
}
|
|
|
|
if Evaluate(ctx, condition) {
|
|
t.Error("expected to fail")
|
|
}
|
|
}
|
|
|
|
func Test_Eval_NotEqual_Const_list_Pass(t *testing.T) {
|
|
ctx := context.NewContext()
|
|
|
|
obj1Raw := []byte(`[ { "name": "a", "file": "a" }, { "name": "b", "file": "b" } ]`)
|
|
obj2Raw := []byte(`[ { "name": "b", "file": "a" }, { "name": "b", "file": "b" } ]`)
|
|
var obj1, obj2 interface{}
|
|
json.Unmarshal(obj1Raw, &obj1)
|
|
json.Unmarshal(obj2Raw, &obj2)
|
|
// no variables
|
|
condition := kyverno.Condition{
|
|
Key: obj1,
|
|
Operator: kyverno.NotEqual,
|
|
Value: obj2,
|
|
}
|
|
|
|
if !Evaluate(ctx, condition) {
|
|
t.Error("expected to pass")
|
|
}
|
|
}
|
|
|
|
func Test_Eval_NotEqual_Const_list_Fail(t *testing.T) {
|
|
ctx := context.NewContext()
|
|
|
|
obj1Raw := []byte(`[ { "name": "a", "file": "a" }, { "name": "b", "file": "b" } ]`)
|
|
obj2Raw := []byte(`[ { "name": "a", "file": "a" }, { "name": "b", "file": "b" } ]`)
|
|
var obj1, obj2 interface{}
|
|
json.Unmarshal(obj1Raw, &obj1)
|
|
json.Unmarshal(obj2Raw, &obj2)
|
|
// no variables
|
|
condition := kyverno.Condition{
|
|
Key: obj1,
|
|
Operator: kyverno.NotEqual,
|
|
Value: obj2,
|
|
}
|
|
|
|
if Evaluate(ctx, condition) {
|
|
t.Error("expected to fail")
|
|
}
|
|
}
|
|
|
|
// Variables
|
|
|
|
func Test_Eval_Equal_Var_Pass(t *testing.T) {
|
|
resourceRaw := []byte(`
|
|
{
|
|
"metadata": {
|
|
"name": "temp",
|
|
"namespace": "n1"
|
|
},
|
|
"spec": {
|
|
"namespace": "n1",
|
|
"name": "temp1"
|
|
}
|
|
}
|
|
`)
|
|
|
|
// context
|
|
ctx := context.NewContext()
|
|
ctx.AddResource(resourceRaw)
|
|
condition := kyverno.Condition{
|
|
Key: "{{request.object.metadata.name}}",
|
|
Operator: kyverno.Equal,
|
|
Value: "temp",
|
|
}
|
|
|
|
if !Evaluate(ctx, condition) {
|
|
t.Error("expected to pass")
|
|
}
|
|
}
|
|
|
|
func Test_Eval_Equal_Var_Fail(t *testing.T) {
|
|
resourceRaw := []byte(`
|
|
{
|
|
"metadata": {
|
|
"name": "temp",
|
|
"namespace": "n1"
|
|
},
|
|
"spec": {
|
|
"namespace": "n1",
|
|
"name": "temp1"
|
|
}
|
|
}
|
|
`)
|
|
|
|
// context
|
|
ctx := context.NewContext()
|
|
ctx.AddResource(resourceRaw)
|
|
condition := kyverno.Condition{
|
|
Key: "{{request.object.metadata.name}}",
|
|
Operator: kyverno.Equal,
|
|
Value: "temp1",
|
|
}
|
|
|
|
if Evaluate(ctx, condition) {
|
|
t.Error("expected to fail")
|
|
}
|
|
}
|