2022-08-02 07:54:02 -07:00
package resource
import (
"context"
"encoding/json"
2024-03-29 19:07:15 +05:30
"fmt"
2024-04-17 09:46:18 +02:00
"sync"
2022-08-02 07:54:02 -07:00
"testing"
2022-09-08 09:34:55 +02:00
"time"
2022-08-02 07:54:02 -07:00
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
2024-06-20 11:44:43 +02:00
kyvernov2 "github.com/kyverno/kyverno/api/kyverno/v2"
2024-03-29 19:07:15 +05:30
"github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/engine"
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/jmespath"
"github.com/kyverno/kyverno/pkg/engine/policycontext"
2022-10-02 20:45:03 +01:00
log "github.com/kyverno/kyverno/pkg/logging"
2022-08-02 07:54:02 -07:00
"github.com/kyverno/kyverno/pkg/policycache"
2023-04-04 07:11:18 +02:00
"github.com/kyverno/kyverno/pkg/webhooks/handlers"
2022-08-02 07:54:02 -07:00
"gotest.tools/assert"
2024-03-29 19:07:15 +05:30
admissionv1 "k8s.io/api/admission/v1"
2022-08-02 07:54:02 -07:00
v1 "k8s.io/api/admission/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2024-03-29 19:07:15 +05:30
apiruntime "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
2025-01-29 13:28:41 +01:00
"k8s.io/apimachinery/pkg/util/wait"
2024-03-29 19:07:15 +05:30
"k8s.io/utils/pointer"
2022-08-02 07:54:02 -07:00
)
var policyCheckLabel = ` {
"apiVersion" : "kyverno.io/v1" ,
"kind" : "ClusterPolicy" ,
"metadata" : {
"name" : "check-label-app"
} ,
"spec" : {
"validationFailureAction" : "audit" ,
"rules" : [
{
"name" : "check-label-app" ,
"match" : {
"resources" : {
"kinds" : [
"Pod"
]
}
} ,
"validate" : {
"message" : "The label 'app' is required." ,
"pattern" : {
"metadata" : {
"labels" : {
"app" : "?*"
}
}
}
}
}
]
}
}
`
var policyInvalid = ` {
"apiVersion" : "kyverno.io/v1" ,
"kind" : "ClusterPolicy" ,
"metadata" : {
"name" : "check-label-app"
} ,
"spec" : {
"validationFailureAction" : "audit" ,
"rules" : [
{
"name" : "check-label-app" ,
"match" : {
"resources" : {
"kinds" : [
"Pod"
]
}
} ,
"validate" : {
"message" : "The label 'app' is required." ,
"pattern" : {
"metadata" : {
"labels" : {
"app" : "{{ invalid-jmespath }}"
}
}
}
}
}
]
}
}
`
var policyVerifySignature = `
{
"apiVersion" : "kyverno.io/v1" ,
"kind" : "ClusterPolicy" ,
"metadata" : {
"name" : "check-image" ,
"annotations" : {
"pod-policies.kyverno.io/autogen-controllers" : "none"
}
} ,
"spec" : {
"validationFailureAction" : "enforce" ,
"background" : false ,
"webhookTimeoutSeconds" : 30 ,
"failurePolicy" : "Fail" ,
"rules" : [
{
"name" : "check-signature" ,
"match" : {
"resources" : {
"kinds" : [
"Pod"
]
}
} ,
"verifyImages" : [
{
"imageReferences" : [
"*"
] ,
"attestors" : [
{
"entries" : [
{
"keys" : {
"publicKeys" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8nXRh950IZbRj8Ra/N9sbqOPZrfM\n5/KAQN0/KjHcorm/J5yctVd7iEcnessRQjU917hmKO6JWVGHpDguIyakZA==\n-----END PUBLIC KEY-----"
}
}
]
}
]
}
]
}
]
}
}
`
2024-09-05 15:32:00 +05:30
var policyAddLabels = ` {
"apiVersion" : "kyverno.io/v1" ,
"kind" : "ClusterPolicy" ,
"metadata" : {
"name" : "add-labels"
} ,
"spec" : {
"admission" : true ,
"background" : true ,
"rules" : [
{
"match" : {
"any" : [
{
"resources" : {
"kinds" : [
"Pod"
]
}
}
]
} ,
"mutate" : {
"patchStrategicMerge" : {
"metadata" : {
"labels" : {
"foo" : "bar"
}
}
}
} ,
"name" : "add-labels"
}
]
}
} `
2022-10-18 14:08:28 +05:30
var policyMutateAndVerify = `
{
"apiVersion" : "kyverno.io/v1" ,
"kind" : "ClusterPolicy" ,
"metadata" : {
"name" : "disallow-unsigned-images"
} ,
"spec" : {
"validationFailureAction" : "enforce" ,
"background" : false ,
"rules" : [
{
"name" : "replace-image-registry" ,
"match" : {
"any" : [
{
"resources" : {
"kinds" : [
"Pod"
]
}
}
]
} ,
"mutate" : {
"foreach" : [
{
"list" : "request.object.spec.containers" ,
"patchStrategicMerge" : {
"spec" : {
"containers" : [
{
"name" : "{{ element.name }}" ,
2023-02-27 14:45:00 +01:00
"image" : "{{ regex_replace_all('^([^/]+\\.[^/]+/)?(.*)$', '{{element.image}}', 'ghcr.io/kyverno/$2' )}}"
2022-10-18 14:08:28 +05:30
}
]
}
}
}
]
}
} ,
{
"name" : "disallow-unsigned-images-rule" ,
"match" : {
"any" : [
{
"resources" : {
"kinds" : [
"Pod"
]
}
}
]
} ,
"verifyImages" : [
{
"imageReferences" : [
"*"
] ,
"verifyDigest" : false ,
"required" : null ,
"mutateDigest" : false ,
"attestors" : [
{
"count" : 1 ,
"entries" : [
{
"keys" : {
2024-04-17 09:46:18 +02:00
"publicKeys" : "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8nXRh950IZbRj8Ra/N9sbqOPZrfM\n5/KAQN0/KjHcorm/J5yctVd7iEcnessRQjU917hmKO6JWVGHpDguIyakZA==\n-----END PUBLIC KEY-----" ,
"rekor" : {
"url" : "https://rekor.sigstore.dev" ,
"ignoreTlog" : true
} ,
"ctlog" : {
"ignoreSCT" : true
}
}
2022-10-18 14:08:28 +05:30
}
]
}
]
}
]
}
]
}
}
`
var resourceMutateAndVerify = ` {
"apiVersion" : "v1" ,
"kind" : "Pod" ,
"metadata" : {
"labels" : {
"run" : "rewrite"
} ,
"name" : "rewrite"
} ,
"spec" : {
"containers" : [
{
"image" : "test-verify-image:signed" ,
"name" : "rewrite" ,
"resources" : { }
}
] ,
"dnsPolicy" : "ClusterFirst" ,
"restartPolicy" : "OnFailure"
}
}
`
2022-08-02 07:54:02 -07:00
var pod = ` {
"apiVersion" : "v1" ,
"kind" : "Pod" ,
"metadata" : {
"name" : "test-pod" ,
"namespace" : ""
} ,
"spec" : {
"containers" : [
{
"name" : "nginx" ,
"image" : "nginx:latest"
}
]
}
}
`
2024-09-05 15:32:00 +05:30
var goodPod = ` {
"apiVersion" : "v1" ,
"kind" : "Pod" ,
"metadata" : {
"name" : "test-pod" ,
"namespace" : "" ,
"labels" : {
"app" : "kyverno"
}
} ,
"spec" : {
"containers" : [
{
"name" : "nginx" ,
"image" : "nginx:latest"
}
]
}
}
`
2024-03-29 19:07:15 +05:30
var mutateAndGenerateMutatePolicy = ` {
"apiVersion" : "kyverno.io/v1" ,
"kind" : "ClusterPolicy" ,
"metadata" : {
"name" : "test-mutate"
} ,
"spec" : {
"rules" : [
{
"name" : "test-mutate" ,
"match" : {
"any" : [
{
"resources" : {
"kinds" : [
"Pod"
] ,
"operations" : [
"CREATE"
]
}
}
]
} ,
"mutate" : {
"foreach" : [
{
"list" : "request.object.spec.containers" ,
"patchStrategicMerge" : {
"spec" : {
"containers" : [
{
"name" : "{{ element.name }}" ,
"image" : "{{ regex_replace_all('^([^/]+\\.[^/]+/)?(.*)$', '{{element.image}}', 'ghcr.io/kyverno/$2' )}}"
}
]
}
}
}
]
}
}
]
}
} `
var mutateAndGenerateGeneratePolicy = ` {
"apiVersion" : "kyverno.io/v1" ,
"kind" : "ClusterPolicy" ,
"metadata" : {
"name" : "test-generate"
} ,
"spec" : {
"rules" : [
{
"name" : "test-generate" ,
"match" : {
"any" : [
{
"resources" : {
"kinds" : [
"Pod"
] ,
"operations" : [
"CREATE"
]
}
}
]
} ,
"generate" : {
"synchronize" : true ,
"apiVersion" : "v1" ,
"kind" : "Pod" ,
"name" : "pod1-{{request.name}}" ,
"namespace" : "shared-dp" ,
"data" : {
"spec" : {
"containers" : [
{
"name" : "container" ,
"image" : "nginx" ,
"volumeMounts" : [
{
"name" : "shared-volume" ,
"mountPath" : "/data"
}
]
}
]
}
}
}
}
]
}
} `
var resourceMutateandGenerate = ` {
"apiVersion" : "v1" ,
"kind" : "Pod" ,
"metadata" : {
"name" : "pod-test-1" ,
"namespace" : "shared-dp"
} ,
"spec" : {
"containers" : [
{
"name" : "container" ,
"image" : "nginx"
}
]
}
} `
2022-08-02 07:54:02 -07:00
func Test_AdmissionResponseValid ( t * testing . T ) {
policyCache := policycache . NewCache ( )
2022-10-02 20:45:03 +01:00
logger := log . WithName ( "Test_AdmissionResponseValid" )
2022-08-02 07:54:02 -07:00
ctx , cancel := context . WithCancel ( context . Background ( ) )
defer cancel ( )
2023-04-04 07:11:18 +02:00
resourceHandlers := NewFakeHandlers ( ctx , policyCache )
2022-08-02 07:54:02 -07:00
var validPolicy kyverno . ClusterPolicy
err := json . Unmarshal ( [ ] byte ( policyCheckLabel ) , & validPolicy )
assert . NilError ( t , err )
key := makeKey ( & validPolicy )
2023-03-13 15:44:39 +01:00
policyCache . Set ( key , & validPolicy , policycache . TestResourceFinder { } )
2022-08-02 07:54:02 -07:00
2023-04-04 07:11:18 +02:00
request := handlers . AdmissionRequest {
AdmissionRequest : v1 . AdmissionRequest {
Operation : v1 . Create ,
Kind : metav1 . GroupVersionKind { Group : "" , Version : "v1" , Kind : "Pod" } ,
Resource : metav1 . GroupVersionResource { Group : "" , Version : "v1" , Resource : "pods" } ,
2024-03-29 19:07:15 +05:30
Object : apiruntime . RawExtension {
2023-04-04 07:11:18 +02:00
Raw : [ ] byte ( pod ) ,
} ,
RequestResource : & metav1 . GroupVersionResource { Group : "" , Version : "v1" , Resource : "pods" } ,
2022-08-02 07:54:02 -07:00
} ,
}
2023-04-04 07:11:18 +02:00
response := resourceHandlers . Mutate ( ctx , logger , request , "" , time . Now ( ) )
2022-08-02 07:54:02 -07:00
assert . Equal ( t , response . Allowed , true )
2023-04-04 07:11:18 +02:00
response = resourceHandlers . Validate ( ctx , logger , request , "" , time . Now ( ) )
2022-08-02 07:54:02 -07:00
assert . Equal ( t , response . Allowed , true )
assert . Equal ( t , len ( response . Warnings ) , 0 )
2022-11-01 09:56:52 +00:00
validPolicy . Spec . ValidationFailureAction = "Enforce"
2023-03-13 15:44:39 +01:00
policyCache . Set ( key , & validPolicy , policycache . TestResourceFinder { } )
2022-08-02 07:54:02 -07:00
2023-04-04 07:11:18 +02:00
response = resourceHandlers . Validate ( ctx , logger , request , "" , time . Now ( ) )
2022-08-02 07:54:02 -07:00
assert . Equal ( t , response . Allowed , false )
assert . Equal ( t , len ( response . Warnings ) , 0 )
policyCache . Unset ( key )
}
func Test_AdmissionResponseInvalid ( t * testing . T ) {
policyCache := policycache . NewCache ( )
2022-10-02 20:45:03 +01:00
logger := log . WithName ( "Test_AdmissionResponseInvalid" )
2022-08-02 07:54:02 -07:00
ctx , cancel := context . WithCancel ( context . Background ( ) )
defer cancel ( )
2023-04-04 07:11:18 +02:00
resourceHandlers := NewFakeHandlers ( ctx , policyCache )
2022-08-02 07:54:02 -07:00
var invalidPolicy kyverno . ClusterPolicy
err := json . Unmarshal ( [ ] byte ( policyInvalid ) , & invalidPolicy )
assert . NilError ( t , err )
2023-04-04 07:11:18 +02:00
request := handlers . AdmissionRequest {
AdmissionRequest : v1 . AdmissionRequest {
Operation : v1 . Create ,
Kind : metav1 . GroupVersionKind { Group : "" , Version : "v1" , Kind : "Pod" } ,
Resource : metav1 . GroupVersionResource { Group : "" , Version : "v1" , Resource : "pods" } ,
2024-03-29 19:07:15 +05:30
Object : apiruntime . RawExtension {
2023-04-04 07:11:18 +02:00
Raw : [ ] byte ( pod ) ,
} ,
RequestResource : & metav1 . GroupVersionResource { Group : "" , Version : "v1" , Resource : "pods" } ,
2022-08-02 07:54:02 -07:00
} ,
}
keyInvalid := makeKey ( & invalidPolicy )
2022-11-01 09:56:52 +00:00
invalidPolicy . Spec . ValidationFailureAction = "Enforce"
2023-03-13 15:44:39 +01:00
policyCache . Set ( keyInvalid , & invalidPolicy , policycache . TestResourceFinder { } )
2022-08-02 07:54:02 -07:00
2023-04-04 07:11:18 +02:00
response := resourceHandlers . Validate ( ctx , logger , request , "" , time . Now ( ) )
2022-08-02 07:54:02 -07:00
assert . Equal ( t , response . Allowed , false )
assert . Equal ( t , len ( response . Warnings ) , 0 )
var ignore kyverno . FailurePolicyType = kyverno . Ignore
invalidPolicy . Spec . FailurePolicy = & ignore
2023-03-13 15:44:39 +01:00
policyCache . Set ( keyInvalid , & invalidPolicy , policycache . TestResourceFinder { } )
2022-08-02 07:54:02 -07:00
2023-04-04 07:11:18 +02:00
response = resourceHandlers . Validate ( ctx , logger , request , "" , time . Now ( ) )
2022-08-02 07:54:02 -07:00
assert . Equal ( t , response . Allowed , true )
assert . Equal ( t , len ( response . Warnings ) , 1 )
}
func Test_ImageVerify ( t * testing . T ) {
policyCache := policycache . NewCache ( )
2022-10-02 20:45:03 +01:00
logger := log . WithName ( "Test_ImageVerify" )
2022-08-02 07:54:02 -07:00
ctx , cancel := context . WithCancel ( context . Background ( ) )
defer cancel ( )
2023-04-04 07:11:18 +02:00
resourceHandlers := NewFakeHandlers ( ctx , policyCache )
2022-08-02 07:54:02 -07:00
var policy kyverno . ClusterPolicy
err := json . Unmarshal ( [ ] byte ( policyVerifySignature ) , & policy )
assert . NilError ( t , err )
key := makeKey ( & policy )
2023-03-13 15:44:39 +01:00
policyCache . Set ( key , & policy , policycache . TestResourceFinder { } )
2022-08-02 07:54:02 -07:00
2023-04-04 07:11:18 +02:00
request := handlers . AdmissionRequest {
AdmissionRequest : v1 . AdmissionRequest {
Operation : v1 . Create ,
Kind : metav1 . GroupVersionKind { Group : "" , Version : "v1" , Kind : "Pod" } ,
Resource : metav1 . GroupVersionResource { Group : "" , Version : "v1" , Resource : "pods" } ,
2024-03-29 19:07:15 +05:30
Object : apiruntime . RawExtension {
2023-04-04 07:11:18 +02:00
Raw : [ ] byte ( pod ) ,
} ,
RequestResource : & metav1 . GroupVersionResource { Group : "" , Version : "v1" , Resource : "pods" } ,
2022-08-02 07:54:02 -07:00
} ,
}
2022-11-01 09:56:52 +00:00
policy . Spec . ValidationFailureAction = "Enforce"
2023-03-13 15:44:39 +01:00
policyCache . Set ( key , & policy , policycache . TestResourceFinder { } )
2022-08-02 07:54:02 -07:00
2023-04-04 07:11:18 +02:00
response := resourceHandlers . Mutate ( ctx , logger , request , "" , time . Now ( ) )
2022-08-02 07:54:02 -07:00
assert . Equal ( t , response . Allowed , false )
assert . Equal ( t , len ( response . Warnings ) , 0 )
var ignore kyverno . FailurePolicyType = kyverno . Ignore
policy . Spec . FailurePolicy = & ignore
2023-03-13 15:44:39 +01:00
policyCache . Set ( key , & policy , policycache . TestResourceFinder { } )
2022-08-02 07:54:02 -07:00
2023-04-04 07:11:18 +02:00
response = resourceHandlers . Mutate ( ctx , logger , request , "" , time . Now ( ) )
2022-08-02 07:54:02 -07:00
assert . Equal ( t , response . Allowed , false )
assert . Equal ( t , len ( response . Warnings ) , 0 )
}
2022-10-18 14:08:28 +05:30
func Test_MutateAndVerify ( t * testing . T ) {
policyCache := policycache . NewCache ( )
logger := log . WithName ( "Test_MutateAndVerify" )
ctx , cancel := context . WithCancel ( context . Background ( ) )
defer cancel ( )
2023-04-04 07:11:18 +02:00
resourceHandlers := NewFakeHandlers ( ctx , policyCache )
2022-10-18 14:08:28 +05:30
var policy kyverno . ClusterPolicy
err := json . Unmarshal ( [ ] byte ( policyMutateAndVerify ) , & policy )
assert . NilError ( t , err )
key := makeKey ( & policy )
2023-03-13 15:44:39 +01:00
policyCache . Set ( key , & policy , policycache . TestResourceFinder { } )
2022-10-18 14:08:28 +05:30
2023-04-04 07:11:18 +02:00
request := handlers . AdmissionRequest {
AdmissionRequest : v1 . AdmissionRequest {
Operation : v1 . Create ,
Kind : metav1 . GroupVersionKind { Group : "" , Version : "v1" , Kind : "Pod" } ,
2024-04-17 09:46:18 +02:00
Resource : metav1 . GroupVersionResource { Group : "" , Version : "v1" , Resource : "pods" } ,
2024-03-29 19:07:15 +05:30
Object : apiruntime . RawExtension {
2023-04-04 07:11:18 +02:00
Raw : [ ] byte ( resourceMutateAndVerify ) ,
} ,
RequestResource : & metav1 . GroupVersionResource { Group : "" , Version : "v1" , Resource : "pods" } ,
2022-10-18 14:08:28 +05:30
} ,
}
2023-04-04 07:11:18 +02:00
response := resourceHandlers . Mutate ( ctx , logger , request , "" , time . Now ( ) )
2022-10-18 14:08:28 +05:30
assert . Equal ( t , response . Allowed , true )
assert . Equal ( t , len ( response . Warnings ) , 0 )
}
2024-03-29 19:07:15 +05:30
func Test_MutateAndGenerate ( t * testing . T ) {
policyCache := policycache . NewCache ( )
logger := log . WithName ( "Test_MutateAndGenerate" )
ctx , cancel := context . WithCancel ( context . Background ( ) )
defer cancel ( )
resourceHandlers := NewFakeHandlers ( ctx , policyCache )
cfg := config . NewDefaultConfiguration ( false )
jp := jmespath . New ( cfg )
mockPcBuilder := newMockPolicyContextBuilder ( cfg , jp )
resourceHandlers . pcBuilder = mockPcBuilder
var generatePolicy kyverno . ClusterPolicy
err := json . Unmarshal ( [ ] byte ( mutateAndGenerateGeneratePolicy ) , & generatePolicy )
assert . NilError ( t , err )
key := makeKey ( & generatePolicy )
policyCache . Set ( key , & generatePolicy , policycache . TestResourceFinder { } )
var mutatePolicy kyverno . ClusterPolicy
err = json . Unmarshal ( [ ] byte ( mutateAndGenerateMutatePolicy ) , & mutatePolicy )
assert . NilError ( t , err )
key = makeKey ( & mutatePolicy )
policyCache . Set ( key , & mutatePolicy , policycache . TestResourceFinder { } )
request := handlers . AdmissionRequest {
AdmissionRequest : v1 . AdmissionRequest {
Operation : v1 . Create ,
Kind : metav1 . GroupVersionKind { Group : "" , Version : "v1" , Kind : "Pod" } ,
2024-04-17 09:46:18 +02:00
Resource : metav1 . GroupVersionResource { Group : "" , Version : "v1" , Resource : "pods" } ,
2024-03-29 19:07:15 +05:30
Object : apiruntime . RawExtension {
Raw : [ ] byte ( resourceMutateandGenerate ) ,
} ,
RequestResource : & metav1 . GroupVersionResource { Group : "" , Version : "v1" , Resource : "pods" } ,
DryRun : pointer . Bool ( false ) ,
} ,
}
2024-09-05 15:32:00 +05:30
_ , mutatePolicies , generatePolicies , _ , _ , err := resourceHandlers . retrieveAndCategorizePolicies ( ctx , logger , request , "" , false )
2024-04-17 09:46:18 +02:00
assert . NilError ( t , err )
2024-03-29 19:07:15 +05:30
2025-01-29 13:28:41 +01:00
var wg wait . Group
2024-04-17 09:46:18 +02:00
resourceHandlers . handleBackgroundApplies ( ctx , logger , request , generatePolicies , mutatePolicies , time . Now ( ) , & wg )
wg . Wait ( )
2024-03-29 19:07:15 +05:30
2024-04-17 09:46:18 +02:00
assert . Assert ( t , len ( mockPcBuilder . contexts ) >= 2 , fmt . Sprint ( "expected no of context " , 2 , " received " , len ( mockPcBuilder . contexts ) ) )
2024-03-29 19:07:15 +05:30
2024-04-17 09:46:18 +02:00
mutateJSONContext := mockPcBuilder . contexts [ 0 ] . JSONContext ( )
generateJSONContext := mockPcBuilder . contexts [ 1 ] . JSONContext ( )
_ , err = enginecontext . AddMockDeferredLoader ( mutateJSONContext , "key1" , "value1" )
2024-03-29 19:07:15 +05:30
assert . NilError ( t , err )
2024-04-17 09:46:18 +02:00
_ , err = enginecontext . AddMockDeferredLoader ( generateJSONContext , "key2" , "value2" )
2024-03-29 19:07:15 +05:30
assert . NilError ( t , err )
2024-04-17 09:46:18 +02:00
_ , err = mutateJSONContext . Query ( "key2" )
2024-03-29 19:07:15 +05:30
assert . ErrorContains ( t , err , ` Unknown key "key2" in path ` )
2024-04-17 09:46:18 +02:00
_ , err = generateJSONContext . Query ( "key1" )
assert . ErrorContains ( t , err , ` Unknown key "key1" in path ` )
2024-03-29 19:07:15 +05:30
}
2024-09-05 15:32:00 +05:30
func Test_ValidateAuditWarn ( t * testing . T ) {
policyCache := policycache . NewCache ( )
logger := log . WithName ( "Test_ValidateAuditWarn" )
ctx , cancel := context . WithCancel ( context . Background ( ) )
defer cancel ( )
resourceHandlers := NewFakeHandlers ( ctx , policyCache )
var validPolicy kyverno . ClusterPolicy
err := json . Unmarshal ( [ ] byte ( policyCheckLabel ) , & validPolicy )
assert . NilError ( t , err )
key := makeKey ( & validPolicy )
policyCache . Set ( key , & validPolicy , policycache . TestResourceFinder { } )
request := handlers . AdmissionRequest {
AdmissionRequest : v1 . AdmissionRequest {
Operation : v1 . Create ,
Kind : metav1 . GroupVersionKind { Group : "" , Version : "v1" , Kind : "Pod" } ,
Resource : metav1 . GroupVersionResource { Group : "" , Version : "v1" , Resource : "pods" } ,
Object : apiruntime . RawExtension {
Raw : [ ] byte ( pod ) ,
} ,
RequestResource : & metav1 . GroupVersionResource { Group : "" , Version : "v1" , Resource : "pods" } ,
} ,
}
response := resourceHandlers . Validate ( ctx , logger , request , "" , time . Now ( ) )
assert . Equal ( t , response . Allowed , true )
assert . Equal ( t , len ( response . Warnings ) , 0 , "should not emit warning when audit warn is set to false" )
auditWarn := true
validPolicy . Spec . EmitWarning = & auditWarn
policyCache . Set ( key , & validPolicy , policycache . TestResourceFinder { } )
response = resourceHandlers . Validate ( ctx , logger , request , "" , time . Now ( ) )
assert . Equal ( t , response . Allowed , true )
assert . Equal ( t , len ( response . Warnings ) , 1 , "should emit warning when audit warn is set to true" )
policyCache . Unset ( key )
}
func Test_ValidateAuditWarnGood ( t * testing . T ) {
policyCache := policycache . NewCache ( )
logger := log . WithName ( "Test_ValidateAuditWarnGood" )
ctx , cancel := context . WithCancel ( context . Background ( ) )
defer cancel ( )
resourceHandlers := NewFakeHandlers ( ctx , policyCache )
var validPolicy kyverno . ClusterPolicy
err := json . Unmarshal ( [ ] byte ( policyCheckLabel ) , & validPolicy )
assert . NilError ( t , err )
auditWarn := true
validPolicy . Spec . EmitWarning = & auditWarn
key := makeKey ( & validPolicy )
policyCache . Set ( key , & validPolicy , policycache . TestResourceFinder { } )
request := handlers . AdmissionRequest {
AdmissionRequest : v1 . AdmissionRequest {
Operation : v1 . Create ,
Kind : metav1 . GroupVersionKind { Group : "" , Version : "v1" , Kind : "Pod" } ,
Resource : metav1 . GroupVersionResource { Group : "" , Version : "v1" , Resource : "pods" } ,
Object : apiruntime . RawExtension {
Raw : [ ] byte ( goodPod ) ,
} ,
RequestResource : & metav1 . GroupVersionResource { Group : "" , Version : "v1" , Resource : "pods" } ,
} ,
}
response := resourceHandlers . Validate ( ctx , logger , request , "" , time . Now ( ) )
assert . Equal ( t , response . Allowed , true )
assert . Equal ( t , len ( response . Warnings ) , 0 , "should emit warning for pass rule response" )
policyCache . Unset ( key )
}
func Test_MutateWarn ( t * testing . T ) {
policyCache := policycache . NewCache ( )
logger := log . WithName ( "Test_MutateWarn" )
ctx , cancel := context . WithCancel ( context . Background ( ) )
defer cancel ( )
resourceHandlers := NewFakeHandlers ( ctx , policyCache )
var policy kyverno . ClusterPolicy
err := json . Unmarshal ( [ ] byte ( policyAddLabels ) , & policy )
assert . NilError ( t , err )
key := makeKey ( & policy )
policyCache . Set ( key , & policy , policycache . TestResourceFinder { } )
request := handlers . AdmissionRequest {
AdmissionRequest : v1 . AdmissionRequest {
Operation : v1 . Create ,
Kind : metav1 . GroupVersionKind { Group : "" , Version : "v1" , Kind : "Pod" } ,
Resource : metav1 . GroupVersionResource { Group : "" , Version : "v1" , Resource : "pods" } ,
Object : apiruntime . RawExtension {
Raw : [ ] byte ( pod ) ,
} ,
RequestResource : & metav1 . GroupVersionResource { Group : "" , Version : "v1" , Resource : "pods" } ,
} ,
}
response := resourceHandlers . Mutate ( ctx , logger , request , "" , time . Now ( ) )
assert . Equal ( t , response . Allowed , true )
assert . Equal ( t , len ( response . Warnings ) , 0 )
auditWarn := true
policy . Spec . EmitWarning = & auditWarn
policyCache . Set ( key , & policy , policycache . TestResourceFinder { } )
response = resourceHandlers . Mutate ( ctx , logger , request , "" , time . Now ( ) )
assert . Equal ( t , response . Allowed , true )
assert . Equal ( t , len ( response . Warnings ) , 1 , "should emit warning when audit warn is set to true" )
}
2022-08-02 07:54:02 -07:00
func makeKey ( policy kyverno . PolicyInterface ) string {
name := policy . GetName ( )
namespace := policy . GetNamespace ( )
if namespace == "" {
return name
}
return namespace + "/" + name
}
2024-03-29 19:07:15 +05:30
type mockPolicyContextBuilder struct {
2024-04-17 14:43:19 +05:30
sync . Mutex
2024-03-29 19:07:15 +05:30
configuration config . Configuration
jp jmespath . Interface
contexts [ ] * engine . PolicyContext
}
func newMockPolicyContextBuilder (
configuration config . Configuration ,
jp jmespath . Interface ,
) * mockPolicyContextBuilder {
return & mockPolicyContextBuilder {
configuration : configuration ,
jp : jp ,
contexts : make ( [ ] * policycontext . PolicyContext , 0 ) ,
}
}
func ( b * mockPolicyContextBuilder ) Build ( request admissionv1 . AdmissionRequest , roles , clusterRoles [ ] string , gvk schema . GroupVersionKind ) ( * engine . PolicyContext , error ) {
2024-04-17 14:43:19 +05:30
b . Lock ( )
defer b . Unlock ( )
2024-06-20 11:44:43 +02:00
userRequestInfo := kyvernov2 . RequestInfo {
2024-03-29 19:07:15 +05:30
AdmissionUserInfo : * request . UserInfo . DeepCopy ( ) ,
Roles : roles ,
ClusterRoles : clusterRoles ,
}
pc , err := engine . NewPolicyContextFromAdmissionRequest ( b . jp , request , userRequestInfo , gvk , b . configuration )
if err != nil {
return nil , err
}
b . contexts = append ( b . contexts , pc )
return pc , err
}