1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-15 17:51:20 +00:00
kyverno/pkg/engine/variables/variables_test.go
Shivkumar Dudhani 3cf9141f4d
593 feature (#594)
* 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
2020-01-07 15:13:57 -08:00

476 lines
9.2 KiB
Go

package variables
import (
"encoding/json"
"reflect"
"testing"
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
authenticationv1 "k8s.io/api/authentication/v1"
"github.com/nirmata/kyverno/pkg/engine/context"
)
func Test_variablesub1(t *testing.T) {
patternMap := []byte(`
{
"kind": "ClusterRole",
"name": "ns-owner-{{request.userInfo.username}}",
"data": {
"rules": [
{
"apiGroups": [
""
],
"resources": [
"namespaces"
],
"verbs": [
"*"
],
"resourceNames": [
"{{request.object.metadata.name}}"
]
}
]
}
}
`)
resourceRaw := []byte(`
{
"metadata": {
"name": "temp",
"namespace": "n1"
},
"spec": {
"namespace": "n1",
"name": "temp1"
}
}
`)
// userInfo
userReqInfo := kyverno.RequestInfo{
AdmissionUserInfo: authenticationv1.UserInfo{
Username: "user1",
},
}
resultMap := []byte(`{"data":{"rules":[{"apiGroups":[""],"resourceNames":["temp"],"resources":["namespaces"],"verbs":["*"]}]},"kind":"ClusterRole","name":"ns-owner-user1"}`)
var pattern, resource interface{}
json.Unmarshal(patternMap, &pattern)
json.Unmarshal(resourceRaw, &resource)
// context
ctx := context.NewContext()
ctx.AddResource(resourceRaw)
ctx.AddUserInfo(userReqInfo)
value := SubstituteVariables(ctx, pattern)
resultRaw, err := json.Marshal(value)
if err != nil {
t.Error(err)
}
if !reflect.DeepEqual(resultMap, resultRaw) {
t.Log(string(resultMap))
t.Log(string(resultRaw))
t.Error("result does not match")
}
}
func Test_variablesub_multiple(t *testing.T) {
patternMap := []byte(`
{
"kind": "ClusterRole",
"name": "ns-owner-{{request.object.metadata.namespace}}-{{request.userInfo.username}}-bindings",
"data": {
"rules": [
{
"apiGroups": [
""
],
"resources": [
"namespaces"
],
"verbs": [
"*"
],
"resourceNames": [
"{{request.object.metadata.name}}"
]
}
]
}
}
`)
resourceRaw := []byte(`
{
"metadata": {
"name": "temp",
"namespace": "n1"
},
"spec": {
"namespace": "n1",
"name": "temp1"
}
}
`)
// userInfo
userReqInfo := kyverno.RequestInfo{
AdmissionUserInfo: authenticationv1.UserInfo{
Username: "user1",
},
}
resultMap := []byte(`{"data":{"rules":[{"apiGroups":[""],"resourceNames":["temp"],"resources":["namespaces"],"verbs":["*"]}]},"kind":"ClusterRole","name":"ns-owner-n1-user1-bindings"}`)
var pattern, resource interface{}
json.Unmarshal(patternMap, &pattern)
json.Unmarshal(resourceRaw, &resource)
// context
ctx := context.NewContext()
ctx.AddResource(resourceRaw)
ctx.AddUserInfo(userReqInfo)
value := SubstituteVariables(ctx, pattern)
resultRaw, err := json.Marshal(value)
if err != nil {
t.Error(err)
}
if !reflect.DeepEqual(resultMap, resultRaw) {
t.Log(string(resultMap))
t.Log(string(resultRaw))
t.Error("result does not match")
}
}
func Test_variablesubstitution(t *testing.T) {
patternMap := []byte(`
{
"name": "ns-owner-{{request.userInfo.username}}",
"data": {
"rules": [
{
"apiGroups": [
""
],
"resources": [
"namespaces"
],
"verbs": [
"*"
],
"resourceNames": [
"{{request.object.metadata.name}}"
]
}
]
}
}
`)
resourceRaw := []byte(`
{
"metadata": {
"name": "temp",
"namespace": "n1"
},
"spec": {
"namespace": "n1",
"name": "temp1"
}
}
`)
resultMap := []byte(`{"data":{"rules":[{"apiGroups":[""],"resourceNames":["temp"],"resources":["namespaces"],"verbs":["*"]}]},"name":"ns-owner-user1"}`)
// userInfo
userReqInfo := kyverno.RequestInfo{
AdmissionUserInfo: authenticationv1.UserInfo{
Username: "user1",
},
}
var pattern, resource interface{}
json.Unmarshal(patternMap, &pattern)
json.Unmarshal(resourceRaw, &resource)
// context
ctx := context.NewContext()
ctx.AddResource(resourceRaw)
ctx.AddUserInfo(userReqInfo)
value := SubstituteVariables(ctx, pattern)
resultRaw, err := json.Marshal(value)
if err != nil {
t.Error(err)
}
if !reflect.DeepEqual(resultMap, resultRaw) {
t.Log(string(resultMap))
t.Log(string(resultRaw))
t.Error("result does not match")
}
}
func Test_variableSubstitutionValue(t *testing.T) {
resourceRaw := []byte(`
{
"metadata": {
"name": "temp",
"namespace": "n1"
},
"spec": {
"namespace": "n1",
"name": "temp1"
}
}
`)
patternMap := []byte(`
{
"spec": {
"name": "{{request.object.metadata.name}}"
}
}
`)
resultMap := []byte(`{"spec":{"name":"temp"}}`)
var pattern, resource interface{}
json.Unmarshal(patternMap, &pattern)
json.Unmarshal(resourceRaw, &resource)
// context
ctx := context.NewContext()
ctx.AddResource(resourceRaw)
value := SubstituteVariables(ctx, pattern)
resultRaw, err := json.Marshal(value)
if err != nil {
t.Error(err)
}
if !reflect.DeepEqual(resultMap, resultRaw) {
t.Error("result does not match")
}
}
func Test_variableSubstitutionValueOperatorNotEqual(t *testing.T) {
resourceRaw := []byte(`
{
"metadata": {
"name": "temp",
"namespace": "n1"
},
"spec": {
"namespace": "n1",
"name": "temp1"
}
}
`)
patternMap := []byte(`
{
"spec": {
"name": "!{{request.object.metadata.name}}"
}
}
`)
resultMap := []byte(`{"spec":{"name":"!temp"}}`)
var pattern, resource interface{}
json.Unmarshal(patternMap, &pattern)
json.Unmarshal(resourceRaw, &resource)
// context
ctx := context.NewContext()
ctx.AddResource(resourceRaw)
value := SubstituteVariables(ctx, pattern)
resultRaw, err := json.Marshal(value)
if err != nil {
t.Error(err)
}
t.Log(string(resultRaw))
t.Log(string(resultMap))
if !reflect.DeepEqual(resultMap, resultRaw) {
t.Error("result does not match")
}
}
func Test_variableSubstitutionValueFail(t *testing.T) {
resourceRaw := []byte(`
{
"metadata": {
"name": "temp",
"namespace": "n1"
},
"spec": {
"namespace": "n1",
"name": "temp1"
}
}
`)
patternMap := []byte(`
{
"spec": {
"name": "{{request.object.metadata.name1}}"
}
}
`)
resultMap := []byte(`{"spec":{"name":null}}`)
var pattern, resource interface{}
json.Unmarshal(patternMap, &pattern)
json.Unmarshal(resourceRaw, &resource)
// context
ctx := context.NewContext()
ctx.AddResource(resourceRaw)
value := SubstituteVariables(ctx, pattern)
resultRaw, err := json.Marshal(value)
if err != nil {
t.Error(err)
}
t.Log(string(resultRaw))
t.Log(string(resultMap))
if !reflect.DeepEqual(resultMap, resultRaw) {
t.Error("result does not match")
}
}
func Test_variableSubstitutionObject(t *testing.T) {
resourceRaw := []byte(`
{
"metadata": {
"name": "temp",
"namespace": "n1"
},
"spec": {
"namespace": "n1",
"variable": {
"var1": "temp1",
"var2": "temp2",
"varNested": {
"var1": "temp1"
}
}
}
}
`)
patternMap := []byte(`
{
"spec": {
"variable": "{{request.object.spec.variable}}"
}
}
`)
resultMap := []byte(`{"spec":{"variable":{"var1":"temp1","var2":"temp2","varNested":{"var1":"temp1"}}}}`)
var pattern, resource interface{}
json.Unmarshal(patternMap, &pattern)
json.Unmarshal(resourceRaw, &resource)
// context
ctx := context.NewContext()
ctx.AddResource(resourceRaw)
value := SubstituteVariables(ctx, pattern)
resultRaw, err := json.Marshal(value)
if err != nil {
t.Error(err)
}
t.Log(string(resultRaw))
t.Log(string(resultMap))
if !reflect.DeepEqual(resultMap, resultRaw) {
t.Error("result does not match")
}
}
func Test_variableSubstitutionObjectOperatorNotEqualFail(t *testing.T) {
resourceRaw := []byte(`
{
"metadata": {
"name": "temp",
"namespace": "n1"
},
"spec": {
"namespace": "n1",
"variable": {
"var1": "temp1",
"var2": "temp2",
"varNested": {
"var1": "temp1"
}
}
}
}
`)
patternMap := []byte(`
{
"spec": {
"variable": "!{{request.object.spec.variable}}"
}
}
`)
resultMap := []byte(`{"spec":{"variable":null}}`)
var pattern, resource interface{}
json.Unmarshal(patternMap, &pattern)
json.Unmarshal(resourceRaw, &resource)
// context
ctx := context.NewContext()
ctx.AddResource(resourceRaw)
value := SubstituteVariables(ctx, pattern)
resultRaw, err := json.Marshal(value)
if err != nil {
t.Error(err)
}
t.Log(string(resultRaw))
t.Log(string(resultMap))
if !reflect.DeepEqual(resultMap, resultRaw) {
t.Error("result does not match")
}
}
func Test_variableSubstitutionMultipleObject(t *testing.T) {
resourceRaw := []byte(`
{
"metadata": {
"name": "temp",
"namespace": "n1"
},
"spec": {
"namespace": "n1",
"variable": {
"var1": "temp1",
"var2": "temp2",
"varNested": {
"var1": "temp1"
}
}
}
}
`)
patternMap := []byte(`
{
"spec": {
"var": "{{request.object.spec.variable.varNested.var1}}",
"variable": "{{request.object.spec.variable}}"
}
}
`)
resultMap := []byte(`{"spec":{"var":"temp1","variable":{"var1":"temp1","var2":"temp2","varNested":{"var1":"temp1"}}}}`)
var pattern, resource interface{}
json.Unmarshal(patternMap, &pattern)
json.Unmarshal(resourceRaw, &resource)
// context
ctx := context.NewContext()
ctx.AddResource(resourceRaw)
value := SubstituteVariables(ctx, pattern)
resultRaw, err := json.Marshal(value)
if err != nil {
t.Error(err)
}
t.Log(string(resultRaw))
t.Log(string(resultMap))
if !reflect.DeepEqual(resultMap, resultRaw) {
t.Error("result does not match")
}
}