2019-10-18 17:45:24 -07:00
package policy
2019-10-01 11:50:10 -07:00
import (
"encoding/json"
2021-04-29 22:21:23 +05:30
"fmt"
2019-10-01 11:50:10 -07:00
"testing"
2021-10-29 18:13:20 +02:00
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
2021-02-22 17:22:34 -08:00
"github.com/kyverno/kyverno/pkg/openapi"
2021-03-02 10:01:06 +05:30
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
2021-04-29 22:21:23 +05:30
"sigs.k8s.io/controller-runtime/pkg/log"
2021-03-02 10:01:06 +05:30
2019-10-01 11:50:10 -07:00
"gotest.tools/assert"
)
func Test_Validate_UniqueRuleName ( t * testing . T ) {
rawPolicy := [ ] byte ( `
{
"spec" : {
"validationFailureAction" : "audit" ,
"rules" : [
{
"name" : "deny-privileged-disallowpriviligedescalation" ,
"match" : {
"resources" : {
"kinds" : [
"Pod"
]
}
} ,
"validate" : { }
} ,
{
"name" : "deny-privileged-disallowpriviligedescalation" ,
"match" : {
"resources" : {
"kinds" : [
"Pod"
]
}
} ,
"validate" : { }
}
]
}
}
` )
2019-10-18 17:45:24 -07:00
var policy * kyverno . ClusterPolicy
2019-10-01 11:50:10 -07:00
err := json . Unmarshal ( rawPolicy , & policy )
assert . NilError ( t , err )
2019-10-21 14:22:31 -07:00
_ , err = validateUniqueRuleName ( * policy )
2019-10-01 11:50:10 -07:00
assert . Assert ( t , err != nil )
}
func Test_Validate_RuleType_EmptyRule ( t * testing . T ) {
rawPolicy := [ ] byte ( `
{
"spec" : {
"rules" : [
{
"name" : "validate-user-privilege" ,
"match" : {
"resources" : {
"kinds" : [
"Deployment"
] ,
"selector" : {
"matchLabels" : {
"app.type" : "prod"
}
}
}
} ,
"mutate" : { } ,
"validate" : { }
}
]
}
}
` )
2019-10-18 17:45:24 -07:00
var policy * kyverno . ClusterPolicy
2019-10-01 11:50:10 -07:00
err := json . Unmarshal ( rawPolicy , & policy )
assert . NilError ( t , err )
for _ , rule := range policy . Spec . Rules {
2019-10-18 17:45:24 -07:00
err := validateRuleType ( rule )
2019-10-01 11:50:10 -07:00
assert . Assert ( t , err != nil )
}
}
func Test_Validate_RuleType_MultipleRule ( t * testing . T ) {
rawPolicy := [ ] byte ( `
{
"spec" : {
"rules" : [
{
"name" : "validate-user-privilege" ,
"match" : {
"resources" : {
"kinds" : [
"Deployment"
] ,
"selector" : {
"matchLabels" : {
"app.type" : "prod"
}
}
}
} ,
"mutate" : {
2022-01-04 17:36:33 -08:00
"patchStrategicMerge" : {
2019-10-01 11:50:10 -07:00
"spec" : {
"template" : {
"spec" : {
"containers" : [
{
"(name)" : "*" ,
"resources" : {
"limits" : {
"+(memory)" : "300Mi" ,
"+(cpu)" : "100"
}
}
}
]
}
}
}
}
} ,
"validate" : {
"message" : "validate container security contexts" ,
"anyPattern" : [
{
"spec" : {
"template" : {
"spec" : {
"containers" : [
{
"securityContext" : {
"runAsNonRoot" : true
}
}
]
}
}
}
}
]
}
}
]
}
} ` )
2019-10-18 17:45:24 -07:00
var policy * kyverno . ClusterPolicy
2019-10-01 11:50:10 -07:00
err := json . Unmarshal ( rawPolicy , & policy )
assert . NilError ( t , err )
for _ , rule := range policy . Spec . Rules {
2019-10-18 17:45:24 -07:00
err := validateRuleType ( rule )
2019-10-01 11:50:10 -07:00
assert . Assert ( t , err != nil )
}
}
func Test_Validate_RuleType_SingleRule ( t * testing . T ) {
rawPolicy := [ ] byte ( `
{
"spec" : {
"rules" : [
{
"name" : "validate-user-privilege" ,
"match" : {
"resources" : {
"kinds" : [
"Deployment"
] ,
"selector" : {
"matchLabels" : {
"app.type" : "prod"
}
}
}
} ,
"validate" : {
"message" : "validate container security contexts" ,
"anyPattern" : [
{
"spec" : {
"template" : {
"spec" : {
"containers" : [
{
"securityContext" : {
"runAsNonRoot" : "true"
}
}
]
}
}
}
}
]
}
}
]
}
}
` )
2019-10-18 17:45:24 -07:00
var policy * kyverno . ClusterPolicy
2019-10-01 11:50:10 -07:00
err := json . Unmarshal ( rawPolicy , & policy )
assert . NilError ( t , err )
for _ , rule := range policy . Spec . Rules {
2019-10-18 17:45:24 -07:00
err := validateRuleType ( rule )
2019-10-01 11:50:10 -07:00
assert . NilError ( t , err )
}
}
func Test_Validate_ResourceDescription_Empty ( t * testing . T ) {
2019-10-21 14:22:31 -07:00
var err error
2019-10-01 11:50:10 -07:00
rawResourcedescirption := [ ] byte ( ` { } ` )
2019-10-18 17:45:24 -07:00
var rd kyverno . ResourceDescription
2019-10-21 14:22:31 -07:00
err = json . Unmarshal ( rawResourcedescirption , & rd )
2019-10-01 11:50:10 -07:00
assert . NilError ( t , err )
2019-10-21 14:22:31 -07:00
_ , err = validateMatchedResourceDescription ( rd )
assert . Assert ( t , err != nil )
2019-10-01 11:50:10 -07:00
}
2019-10-21 14:22:31 -07:00
func Test_Validate_ResourceDescription_MatchedValid ( t * testing . T ) {
rawResourcedescirption := [ ] byte ( `
2019-10-01 11:50:10 -07:00
{
2019-10-21 14:22:31 -07:00
"kinds" : [
"Deployment"
] ,
2019-10-01 11:50:10 -07:00
"selector" : {
"matchLabels" : {
"app.type" : "prod"
}
}
} ` )
2019-10-18 17:45:24 -07:00
var rd kyverno . ResourceDescription
2019-10-21 14:22:31 -07:00
err := json . Unmarshal ( rawResourcedescirption , & rd )
2019-10-01 11:50:10 -07:00
assert . NilError ( t , err )
2019-10-21 14:22:31 -07:00
_ , err = validateMatchedResourceDescription ( rd )
assert . NilError ( t , err )
2019-10-01 11:50:10 -07:00
}
2019-10-01 15:01:24 -07:00
2021-02-02 02:57:16 +05:30
func Test_Validate_DenyConditions_KeyRequestOperation_Empty ( t * testing . T ) {
denyConditions := [ ] byte ( ` [] ` )
2021-03-02 10:01:06 +05:30
var dcs apiextensions . JSON
2021-02-02 02:57:16 +05:30
err := json . Unmarshal ( denyConditions , & dcs )
assert . NilError ( t , err )
_ , err = validateConditions ( dcs , "conditions" )
assert . NilError ( t , err )
2021-03-02 10:01:06 +05:30
_ , err = validateConditions ( dcs , "conditions" )
assert . NilError ( t , err )
2021-02-02 02:57:16 +05:30
}
func Test_Validate_Preconditions_KeyRequestOperation_Empty ( t * testing . T ) {
preConditions := [ ] byte ( ` [] ` )
2021-03-02 10:01:06 +05:30
var pcs apiextensions . JSON
2021-02-02 02:57:16 +05:30
err := json . Unmarshal ( preConditions , & pcs )
assert . NilError ( t , err )
_ , err = validateConditions ( pcs , "preconditions" )
assert . NilError ( t , err )
2021-03-02 10:01:06 +05:30
_ , err = validateConditions ( pcs , "preconditions" )
assert . NilError ( t , err )
2021-02-02 02:57:16 +05:30
}
func Test_Validate_DenyConditionsValuesString_KeyRequestOperation_ExpectedValue ( t * testing . T ) {
denyConditions := [ ] byte ( `
[
{
"key" : "{{request.operation}}" ,
"operator" : "Equals" ,
"value" : "DELETE"
} ,
{
"key" : "{{request.operation}}" ,
"operator" : "NotEquals" ,
"value" : "CREATE"
} ,
{
"key" : "{{request.operation}}" ,
"operator" : "NotEquals" ,
"value" : "CONNECT"
} ,
{
"key" : "{{ request.operation }}" ,
"operator" : "NotEquals" ,
"value" : "UPDATE"
} ,
{
"key" : "{{lbServiceCount}}" ,
"operator" : "Equals" ,
"value" : "2"
}
]
` )
2021-03-02 10:01:06 +05:30
var dcs apiextensions . JSON
2021-02-02 02:57:16 +05:30
err := json . Unmarshal ( denyConditions , & dcs )
assert . NilError ( t , err )
_ , err = validateConditions ( dcs , "conditions" )
assert . NilError ( t , err )
2021-03-02 10:01:06 +05:30
_ , err = validateConditions ( dcs , "conditions" )
assert . NilError ( t , err )
2021-02-02 02:57:16 +05:30
}
2021-02-17 02:36:07 +05:30
func Test_Validate_DenyConditionsValuesString_KeyRequestOperation_RightfullyTemplatizedValue ( t * testing . T ) {
denyConditions := [ ] byte ( `
[
{
"key" : "{{request.operation}}" ,
"operator" : "Equals" ,
"value" : "{{ \"ops-cm\".data.\"deny-ops\"}}"
} ,
{
"key" : "{{ request.operation }}" ,
"operator" : "NotEquals" ,
"value" : "UPDATE"
}
]
` )
2021-03-02 10:01:06 +05:30
var dcs apiextensions . JSON
2021-02-17 02:36:07 +05:30
err := json . Unmarshal ( denyConditions , & dcs )
assert . NilError ( t , err )
_ , err = validateConditions ( dcs , "conditions" )
assert . NilError ( t , err )
2021-03-02 10:01:06 +05:30
_ , err = validateConditions ( dcs , "conditions" )
assert . NilError ( t , err )
2021-02-17 02:36:07 +05:30
}
func Test_Validate_DenyConditionsValuesString_KeyRequestOperation_WrongfullyTemplatizedValue ( t * testing . T ) {
denyConditions := [ ] byte ( `
[
{
"key" : "{{request.operation}}" ,
"operator" : "Equals" ,
"value" : "{{ \"ops-cm\".data.\"deny-ops\" }"
} ,
{
"key" : "{{ request.operation }}" ,
"operator" : "NotEquals" ,
"value" : "UPDATE"
}
]
` )
var dcs [ ] kyverno . Condition
err := json . Unmarshal ( denyConditions , & dcs )
assert . NilError ( t , err )
_ , err = validateConditions ( dcs , "conditions" )
assert . Assert ( t , err != nil )
}
2021-02-02 02:57:16 +05:30
func Test_Validate_PreconditionsValuesString_KeyRequestOperation_UnknownValue ( t * testing . T ) {
preConditions := [ ] byte ( `
[
{
"key" : "{{request.operation}}" ,
"operator" : "Equals" ,
"value" : "foobar"
} ,
{
"key" : "{{request.operation}}" ,
"operator" : "NotEquals" ,
"value" : "CREATE"
}
]
` )
2021-03-02 10:01:06 +05:30
var pcs apiextensions . JSON
2021-02-02 02:57:16 +05:30
err := json . Unmarshal ( preConditions , & pcs )
assert . NilError ( t , err )
_ , err = validateConditions ( pcs , "preconditions" )
assert . Assert ( t , err != nil )
2021-03-02 10:01:06 +05:30
_ , err = validateConditions ( pcs , "preconditions" )
assert . Assert ( t , err != nil )
2021-02-02 02:57:16 +05:30
}
func Test_Validate_DenyConditionsValuesList_KeyRequestOperation_ExpectedItem ( t * testing . T ) {
denyConditions := [ ] byte ( `
[
{
"key" : "{{request.operation}}" ,
"operator" : "Equals" ,
"value" : [
"CREATE" ,
"DELETE" ,
"CONNECT"
]
} ,
{
"key" : "{{request.operation}}" ,
"operator" : "NotEquals" ,
"value" : [
"UPDATE"
]
} ,
{
"key" : "{{lbServiceCount}}" ,
"operator" : "Equals" ,
"value" : "2"
}
]
` )
var dcs [ ] kyverno . Condition
err := json . Unmarshal ( denyConditions , & dcs )
assert . NilError ( t , err )
_ , err = validateConditions ( dcs , "conditions" )
assert . NilError ( t , err )
}
func Test_Validate_PreconditionsValuesList_KeyRequestOperation_UnknownItem ( t * testing . T ) {
preConditions := [ ] byte ( `
[
{
"key" : "{{request.operation}}" ,
"operator" : "Equals" ,
"value" : [
"foobar" ,
"CREATE"
]
} ,
{
"key" : "{{request.operation}}" ,
"operator" : "NotEquals" ,
"value" : [
"foobar"
]
}
]
` )
2021-03-02 10:01:06 +05:30
var pcs apiextensions . JSON
2021-02-02 02:57:16 +05:30
err := json . Unmarshal ( preConditions , & pcs )
assert . NilError ( t , err )
_ , err = validateConditions ( pcs , "preconditions" )
assert . Assert ( t , err != nil )
2021-03-02 10:01:06 +05:30
_ , err = validateConditions ( pcs , "preconditions" )
assert . Assert ( t , err != nil )
2021-02-02 02:57:16 +05:30
}
2019-10-21 14:22:31 -07:00
func Test_Validate_ResourceDescription_MissingKindsOnExclude ( t * testing . T ) {
var err error
excludeResourcedescirption := [ ] byte ( `
2019-10-01 11:50:10 -07:00
{
"selector" : {
2019-10-21 14:22:31 -07:00
"matchLabels" : {
"app.type" : "prod"
}
2019-10-01 11:50:10 -07:00
}
} ` )
2019-10-18 17:45:24 -07:00
var rd kyverno . ResourceDescription
2019-10-21 14:22:31 -07:00
err = json . Unmarshal ( excludeResourcedescirption , & rd )
2019-10-01 11:50:10 -07:00
assert . NilError ( t , err )
2019-10-21 14:22:31 -07:00
_ , err = validateExcludeResourceDescription ( rd )
assert . NilError ( t , err )
2019-10-01 11:50:10 -07:00
}
2019-10-21 14:22:31 -07:00
func Test_Validate_ResourceDescription_InvalidSelector ( t * testing . T ) {
2019-10-01 11:50:10 -07:00
rawResourcedescirption := [ ] byte ( `
{
"kinds" : [
"Deployment"
] ,
"selector" : {
2019-10-21 14:22:31 -07:00
"app.type" : "prod"
2019-10-01 11:50:10 -07:00
}
} ` )
2019-10-18 17:45:24 -07:00
var rd kyverno . ResourceDescription
2019-10-01 11:50:10 -07:00
err := json . Unmarshal ( rawResourcedescirption , & rd )
assert . NilError ( t , err )
2019-10-21 14:22:31 -07:00
err = validateResourceDescription ( rd )
assert . Assert ( t , err != nil )
2019-10-01 11:50:10 -07:00
}
func Test_Validate_Policy ( t * testing . T ) {
rawPolicy := [ ] byte ( `
{
2019-11-13 13:56:07 -08:00
"apiVersion" : "kyverno.io/v1" ,
2019-10-01 11:50:10 -07:00
"kind" : "ClusterPolicy" ,
"metadata" : {
"name" : "container-security-context"
} ,
"spec" : {
"rules" : [
{
2019-10-03 14:47:50 -07:00
"name" : "validate-runAsNonRoot" ,
2019-10-01 11:50:10 -07:00
"match" : {
"resources" : {
"kinds" : [
"Deployment"
] ,
"selector" : {
"matchLabels" : {
"app.type" : "prod"
}
}
}
} ,
"validate" : {
"message" : "validate container security contexts" ,
"anyPattern" : [
{
"spec" : {
"template" : {
"spec" : {
"^(containers)" : [
{
"securityContext" : {
2019-10-03 14:47:50 -07:00
"runAsNonRoot" : "true"
2019-10-01 11:50:10 -07:00
}
}
]
}
}
}
}
]
}
2019-10-03 14:47:50 -07:00
} ,
{
"name" : "validate-allowPrivilegeEscalation" ,
"match" : {
"resources" : {
"kinds" : [
"Deployment"
] ,
"selector" : {
"matchLabels" : {
"app.type" : "prod"
}
}
}
} ,
"validate" : {
"message" : "validate container security contexts" ,
"pattern" : {
"spec" : {
"template" : {
"spec" : {
"^(containers)" : [
{
"securityContext" : {
"allowPrivilegeEscalation" : "false"
}
}
]
}
}
}
}
}
2019-10-01 11:50:10 -07:00
}
]
}
} ` )
2020-03-27 19:06:06 +05:30
openAPIController , _ := openapi . NewOpenAPIController ( )
2021-01-06 16:32:02 -08:00
var policy * kyverno . ClusterPolicy
err := json . Unmarshal ( rawPolicy , & policy )
assert . NilError ( t , err )
2019-10-03 12:52:58 -07:00
2021-01-06 16:32:02 -08:00
err = Validate ( policy , nil , true , openAPIController )
2019-10-03 12:52:58 -07:00
assert . NilError ( t , err )
2019-10-03 16:49:41 -07:00
}
func Test_Validate_ErrorFormat ( t * testing . T ) {
rawPolicy := [ ] byte ( `
{
2019-11-13 13:56:07 -08:00
"apiVersion" : "kyverno.io/v1" ,
2019-10-03 16:49:41 -07:00
"kind" : "ClusterPolicy" ,
"metadata" : {
"name" : "test-error-format"
} ,
"spec" : {
"rules" : [
{
"name" : "image-pull-policy" ,
"match" : {
"resources" : {
"kinds" : [
"Deployment"
] ,
"selector" : {
"matchLabels" : {
"app" : "nginxlatest"
}
}
}
} ,
"exclude" : {
"resources" : {
"selector" : {
"app" : "nginxlatest"
}
}
} ,
"mutate" : {
2022-01-04 17:36:33 -08:00
"patchStrategicMerge" : {
2019-10-03 16:49:41 -07:00
"spec" : {
"template" : {
"spec" : {
"containers" : [
{
"=(image)" : "*latest" ,
"imagePullPolicy" : "IfNotPresent"
}
]
}
}
}
}
}
} ,
{
"name" : "validate-user-privilege" ,
"match" : {
"resources" : {
"kinds" : [ ] ,
"selector" : {
"matchLabels" : {
"app.type" : "prod"
}
}
}
} ,
"validate" : {
"message" : "validate container security contexts" ,
"anyPattern" : [
{
"spec" : {
"template" : {
"spec" : {
"^(containers)" : [
{
"securityContext" : {
"runAsNonRoot" : "true"
}
}
]
}
}
}
}
]
}
} ,
{
"name" : "validate-user-privilege" ,
"match" : {
"resources" : {
"kinds" : [
"Deployment"
] ,
"selector" : {
"matchLabels" : {
"app.type" : "prod"
}
}
}
} ,
"validate" : {
"message" : "validate container security contexts" ,
"pattern" : {
"spec" : {
"template" : {
"spec" : {
"containers" : [
{
"^(securityContext)" : {
"allowPrivilegeEscalation" : "false"
}
}
]
}
}
}
}
}
} ,
{
"name" : "default-networkpolicy" ,
"match" : {
"resources" : {
"kinds" : [
"Namespace"
] ,
"name" : "devtest"
}
} ,
"generate" : {
"kind" : "ConfigMap" ,
"name" : "copied-cm" ,
"clone" : {
"^(namespace)" : "default" ,
"name" : "game-config"
}
}
}
]
}
}
` )
2021-01-06 16:32:02 -08:00
var policy * kyverno . ClusterPolicy
err := json . Unmarshal ( rawPolicy , & policy )
assert . NilError ( t , err )
2020-03-27 19:06:06 +05:30
openAPIController , _ := openapi . NewOpenAPIController ( )
2021-01-06 16:32:02 -08:00
err = Validate ( policy , nil , true , openAPIController )
2019-10-21 14:22:31 -07:00
assert . Assert ( t , err != nil )
2019-10-03 14:47:50 -07:00
}
2019-12-05 11:55:00 -08:00
func Test_Validate_EmptyUserInfo ( t * testing . T ) {
rawRule := [ ] byte ( `
{
"name" : "test" ,
"match" : {
"subjects" : null
}
} ` )
var rule kyverno . Rule
err := json . Unmarshal ( rawRule , & rule )
assert . NilError ( t , err )
_ , errNew := validateUserInfo ( rule )
assert . NilError ( t , errNew )
}
func Test_Validate_Roles ( t * testing . T ) {
rawRule := [ ] byte ( ` {
"name" : "test" ,
"match" : {
"roles" : [
"namespace1:name1" ,
"name2"
]
}
} ` )
var rule kyverno . Rule
err := json . Unmarshal ( rawRule , & rule )
assert . NilError ( t , err )
path , err := validateUserInfo ( rule )
assert . Assert ( t , err != nil )
assert . Assert ( t , path == "match.roles" )
}
func Test_Validate_ServiceAccount ( t * testing . T ) {
rawRule := [ ] byte ( `
{
"name" : "test" ,
"exclude" : {
"subjects" : [
{
"kind" : "ServiceAccount" ,
"name" : "testname"
}
]
}
} ` )
var rule kyverno . Rule
err := json . Unmarshal ( rawRule , & rule )
assert . NilError ( t , err )
path , err := validateUserInfo ( rule )
assert . Assert ( t , err != nil )
assert . Assert ( t , path == "exclude.subjects" )
}
2019-12-30 17:08:50 -08:00
func Test_BackGroundUserInfo_match_roles ( t * testing . T ) {
var err error
rawPolicy := [ ] byte ( `
{
"apiVersion" : "kyverno.io/v1" ,
"kind" : "ClusterPolicy" ,
"metadata" : {
"name" : "disallow-root-user"
} ,
"spec" : {
"rules" : [
{
"name" : "match.roles" ,
"match" : {
"roles" : [
"a" ,
"b"
]
}
}
]
}
}
` )
var policy * kyverno . ClusterPolicy
err = json . Unmarshal ( rawPolicy , & policy )
assert . NilError ( t , err )
2021-11-03 11:16:55 -07:00
err = containsUserVariables ( policy , nil )
2020-05-06 19:46:32 +05:30
assert . Equal ( t , err . Error ( ) , "invalid variable used at path: spec/rules[0]/match/roles" )
2019-12-30 17:08:50 -08:00
}
func Test_BackGroundUserInfo_match_clusterRoles ( t * testing . T ) {
var err error
rawPolicy := [ ] byte ( `
{
"apiVersion" : "kyverno.io/v1" ,
"kind" : "ClusterPolicy" ,
"metadata" : {
"name" : "disallow-root-user"
} ,
"spec" : {
"rules" : [
{
"name" : "match.clusterRoles" ,
"match" : {
"clusterRoles" : [
"a" ,
"b"
]
}
}
]
}
}
` )
var policy * kyverno . ClusterPolicy
err = json . Unmarshal ( rawPolicy , & policy )
assert . NilError ( t , err )
2021-11-03 11:16:55 -07:00
err = containsUserVariables ( policy , nil )
2020-05-06 19:46:32 +05:30
assert . Equal ( t , err . Error ( ) , "invalid variable used at path: spec/rules[0]/match/clusterRoles" )
2019-12-30 17:08:50 -08:00
}
func Test_BackGroundUserInfo_match_subjects ( t * testing . T ) {
var err error
rawPolicy := [ ] byte ( `
{
"apiVersion" : "kyverno.io/v1" ,
"kind" : "ClusterPolicy" ,
"metadata" : {
"name" : "disallow-root-user"
} ,
"spec" : {
"rules" : [
{
"name" : "match.subjects" ,
"match" : {
"subjects" : [
{
"Name" : "a"
} ,
{
"Name" : "b"
}
]
}
}
]
}
} ` )
var policy * kyverno . ClusterPolicy
err = json . Unmarshal ( rawPolicy , & policy )
assert . NilError ( t , err )
2021-11-03 11:16:55 -07:00
err = containsUserVariables ( policy , nil )
2020-05-06 19:46:32 +05:30
assert . Equal ( t , err . Error ( ) , "invalid variable used at path: spec/rules[0]/match/subjects" )
2019-12-30 17:08:50 -08:00
}
2022-01-04 17:36:33 -08:00
func Test_BackGroundUserInfo_mutate_patchStrategicMerge1 ( t * testing . T ) {
2019-12-30 17:08:50 -08:00
var err error
rawPolicy := [ ] byte ( `
{
"apiVersion" : "kyverno.io/v1" ,
"kind" : "ClusterPolicy" ,
"metadata" : {
"name" : "disallow-root-user"
} ,
"spec" : {
"rules" : [
{
"name" : "mutate.overlay1" ,
"mutate" : {
2022-01-04 17:36:33 -08:00
"patchStrategicMerge" : {
2019-12-30 17:08:50 -08:00
"var1" : "{{request.userInfo}}"
}
}
}
]
}
}
` )
var policy * kyverno . ClusterPolicy
err = json . Unmarshal ( rawPolicy , & policy )
assert . NilError ( t , err )
2021-11-03 11:16:55 -07:00
err = ValidateVariables ( policy , true )
2021-02-22 17:22:34 -08:00
assert . Assert ( t , err != nil )
2019-12-30 17:08:50 -08:00
}
2022-01-04 17:36:33 -08:00
func Test_BackGroundUserInfo_mutate_patchStrategicMerge2 ( t * testing . T ) {
2019-12-30 17:08:50 -08:00
var err error
rawPolicy := [ ] byte ( `
{
"apiVersion" : "kyverno.io/v1" ,
"kind" : "ClusterPolicy" ,
"metadata" : {
"name" : "disallow-root-user"
} ,
"spec" : {
"rules" : [
{
"name" : "mutate.overlay2" ,
"mutate" : {
2022-01-04 17:36:33 -08:00
"patchStrategicMerge" : {
2019-12-30 17:08:50 -08:00
"var1" : "{{request.userInfo.userName}}"
}
}
}
]
}
}
` )
var policy * kyverno . ClusterPolicy
err = json . Unmarshal ( rawPolicy , & policy )
assert . NilError ( t , err )
2021-11-03 11:16:55 -07:00
err = ValidateVariables ( policy , true )
2021-02-22 17:22:34 -08:00
assert . Assert ( t , err != nil )
2019-12-30 17:08:50 -08:00
}
func Test_BackGroundUserInfo_validate_pattern ( t * testing . T ) {
var err error
rawPolicy := [ ] byte ( `
{
"apiVersion" : "kyverno.io/v1" ,
"kind" : "ClusterPolicy" ,
"metadata" : {
"name" : "disallow-root-user"
} ,
"spec" : {
"rules" : [
{
2022-01-04 17:36:33 -08:00
"name" : "validate-patch-strategic-merge" ,
2019-12-30 17:08:50 -08:00
"validate" : {
"pattern" : {
"var1" : "{{request.userInfo}}"
}
}
}
]
}
}
` )
var policy * kyverno . ClusterPolicy
err = json . Unmarshal ( rawPolicy , & policy )
assert . NilError ( t , err )
2021-11-03 11:16:55 -07:00
err = ValidateVariables ( policy , true )
2021-02-22 12:08:26 -08:00
assert . Assert ( t , err != nil , err )
2019-12-30 17:08:50 -08:00
}
func Test_BackGroundUserInfo_validate_anyPattern ( t * testing . T ) {
var err error
rawPolicy := [ ] byte ( `
{
"apiVersion" : "kyverno.io/v1" ,
"kind" : "ClusterPolicy" ,
"metadata" : {
"name" : "disallow-root-user"
} ,
"spec" : {
"rules" : [
{
"name" : "validate.anyPattern" ,
"validate" : {
"anyPattern" : [
{
"var1" : "temp"
} ,
{
"var1" : "{{request.userInfo}}"
}
]
}
}
]
}
} ` )
var policy * kyverno . ClusterPolicy
err = json . Unmarshal ( rawPolicy , & policy )
assert . NilError ( t , err )
2021-11-03 11:16:55 -07:00
err = ValidateVariables ( policy , true )
2021-02-22 17:22:34 -08:00
assert . Assert ( t , err != nil )
2019-12-30 17:08:50 -08:00
}
2020-01-13 18:56:11 -08:00
func Test_BackGroundUserInfo_validate_anyPattern_multiple_var ( t * testing . T ) {
var err error
rawPolicy := [ ] byte ( `
{
"apiVersion" : "kyverno.io/v1" ,
"kind" : "ClusterPolicy" ,
"metadata" : {
"name" : "disallow-root-user"
} ,
"spec" : {
"rules" : [
{
"name" : "validate.anyPattern" ,
"validate" : {
"anyPattern" : [
{
"var1" : "temp"
} ,
{
"var1" : "{{request.userInfo}}-{{temp}}"
}
]
}
}
]
}
} ` )
var policy * kyverno . ClusterPolicy
err = json . Unmarshal ( rawPolicy , & policy )
assert . NilError ( t , err )
2021-11-03 11:16:55 -07:00
err = ValidateVariables ( policy , true )
2021-02-22 17:22:34 -08:00
assert . Assert ( t , err != nil )
2020-01-13 18:56:11 -08:00
}
func Test_BackGroundUserInfo_validate_anyPattern_serviceAccount ( t * testing . T ) {
var err error
rawPolicy := [ ] byte ( `
{
"apiVersion" : "kyverno.io/v1" ,
"kind" : "ClusterPolicy" ,
"metadata" : {
"name" : "disallow-root-user"
} ,
"spec" : {
"rules" : [
{
"name" : "validate.anyPattern" ,
"validate" : {
"anyPattern" : [
{
"var1" : "temp"
} ,
{
"var1" : "{{serviceAccountName}}"
}
]
}
}
]
}
} ` )
var policy * kyverno . ClusterPolicy
err = json . Unmarshal ( rawPolicy , & policy )
assert . NilError ( t , err )
2021-11-03 11:16:55 -07:00
err = ValidateVariables ( policy , true )
2021-02-22 17:22:34 -08:00
assert . Assert ( t , err != nil )
2020-01-13 18:56:11 -08:00
}
2020-02-26 16:08:56 +05:30
func Test_ruleOnlyDealsWithResourceMetaData ( t * testing . T ) {
testcases := [ ] struct {
description string
rule [ ] byte
expectedOutput bool
} {
{
2022-01-04 17:36:33 -08:00
description : "Test mutate patchStrategicMerge - pass" ,
rule : [ ] byte ( ` { "name":"testPatches1","mutate": { "patchStrategicMerge": { "metadata": { "containers":[ { "(image)":"*","imagePullPolicy":"IfNotPresent"}]}}}} ` ) ,
2020-02-26 16:08:56 +05:30
expectedOutput : true ,
} ,
{
2022-01-04 17:36:33 -08:00
description : "Test mutate patchStrategicMerge - fail" ,
rule : [ ] byte ( ` { "name":"testPatches2","mutate": { "patchStrategicMerge": { "spec": { "containers":[ { "(image)":"*","imagePullPolicy":"IfNotPresent"}]}}}} ` ) ,
2020-02-26 16:08:56 +05:30
expectedOutput : false ,
} ,
{
description : "Test mutate patch - pass" ,
2022-01-04 17:36:33 -08:00
rule : [ ] byte ( ` { "name":"testPatches3","mutate": { "patchesJson6902": "[ { \"path\":\"/metadata/labels/isMutated\",\"op\":\"add\",\"value\":\"true\"}, { \"path\":\"/metadata/labels/app\",\"op\":\"replace\",\"value\":\"nginx_is_mutated\"}]"}} ` ) ,
2020-02-26 16:08:56 +05:30
expectedOutput : true ,
} ,
{
description : "Test mutate patch - fail" ,
2022-01-04 17:36:33 -08:00
rule : [ ] byte ( ` { "name":"testPatches4","mutate": { "patchesJson6902": "[ { \"path\":\"/spec/labels/isMutated\",\"op\":\"add\",\"value\":\"true\"}, { \"path\":\"/metadata/labels/app\",\"op\":\"replace\",\"value\":\"nginx_is_mutated\"}]" }} ` ) ,
2020-02-26 16:08:56 +05:30
expectedOutput : false ,
} ,
{
description : "Test validate - pass" ,
2022-01-04 17:36:33 -08:00
rule : [ ] byte ( ` { "name":"testValidate1","validate": { "message":"CPU and memory resource requests and limits are required","pattern": { "metadata": { "containers":[ { "(name)":"*","ports":[ { "containerPort":80}]}]}}}} ` ) ,
2020-02-26 16:08:56 +05:30
expectedOutput : true ,
} ,
{
description : "Test validate - fail" ,
2022-01-04 17:36:33 -08:00
rule : [ ] byte ( ` { "name":"testValidate2","validate": { "message":"CPU and memory resource requests and limits are required","pattern": { "spec": { "containers":[ { "(name)":"*","ports":[ { "containerPort":80}]}]}}}} ` ) ,
2020-02-26 16:08:56 +05:30
expectedOutput : false ,
} ,
{
description : "Test validate any pattern - pass" ,
2022-01-04 17:36:33 -08:00
rule : [ ] byte ( ` { "name":"testValidateAnyPattern1","validate": { "message":"Volumes white list","anyPattern":[ { "metadata": { "volumes":[ { "hostPath":"*"}]}}, { "metadata": { "volumes":[ { "emptyDir":"*"}]}}, { "metadata": { "volumes":[ { "configMap":"*"}]}}]}} ` ) ,
2020-02-26 16:08:56 +05:30
expectedOutput : true ,
} ,
{
description : "Test validate any pattern - fail" ,
2022-01-04 17:36:33 -08:00
rule : [ ] byte ( ` { "name":"testValidateAnyPattern2","validate": { "message":"Volumes white list","anyPattern":[ { "spec": { "volumes":[ { "hostPath":"*"}]}}, { "metadata": { "volumes":[ { "emptyDir":"*"}]}}, { "metadata": { "volumes":[ { "configMap":"*"}]}}]}} ` ) ,
2020-02-26 16:08:56 +05:30
expectedOutput : false ,
} ,
}
for i , testcase := range testcases {
var rule kyverno . Rule
_ = json . Unmarshal ( testcase . rule , & rule )
output := ruleOnlyDealsWithResourceMetaData ( rule )
if output != testcase . expectedOutput {
2022-01-04 17:36:33 -08:00
t . Errorf ( "Testcase [%d] (%s) failed" , i + 1 , testcase . description )
2020-02-26 16:08:56 +05:30
}
}
}
2020-03-20 20:23:34 +05:30
2020-04-04 14:49:50 +05:30
func Test_doesMatchExcludeConflict ( t * testing . T ) {
2020-03-20 20:23:34 +05:30
testcases := [ ] struct {
2020-04-04 14:49:50 +05:30
description string
rule [ ] byte
expectedOutput bool
2020-03-20 20:23:34 +05:30
} {
{
2020-04-04 14:49:50 +05:30
description : "Same match and exclude" ,
rule : [ ] byte ( ` { "name":"set-image-pull-policy-2","match": { "resources": { "kinds":["Pod","Namespace"],"name":"something","namespaces":["something","something1"],"selector": { "matchLabels": { "memory":"high"},"matchExpressions":[ { "key":"tier","operator":"In","values":["database"]}]}},"subjects":[ { "name":"something","kind":"something","Namespace":"something","apiGroup":"something"}, { "name":"something1","kind":"something1","Namespace":"something1","apiGroup":"something1"}],"clusterroles":["something","something1"],"roles":["something","something1"]},"exclude": { "resources": { "kinds":["Pod","Namespace"],"name":"something","namespaces":["something","something1"],"selector": { "matchLabels": { "memory":"high"},"matchExpressions":[ { "key":"tier","operator":"In","values":["database"]}]}},"subjects":[ { "name":"something","kind":"something","Namespace":"something","apiGroup":"something"}, { "name":"something1","kind":"something1","Namespace":"something1","apiGroup":"something1"}],"clusterroles":["something","something1"],"roles":["something","something1"]}} ` ) ,
expectedOutput : true ,
2020-03-20 20:23:34 +05:30
} ,
{
2020-04-04 14:49:50 +05:30
description : "Failed to exclude kind" ,
rule : [ ] byte ( ` { "name":"set-image-pull-policy-2","match": { "resources": { "kinds":["Pod","Namespace"],"name":"something","namespaces":["something","something1"],"selector": { "matchLabels": { "memory":"high"},"matchExpressions":[ { "key":"tier","operator":"In","values":["database"]}]}},"subjects":[ { "name":"something","kind":"something","Namespace":"something","apiGroup":"something"}, { "name":"something1","kind":"something1","Namespace":"something1","apiGroup":"something1"}],"clusterroles":["something","something1"],"roles":["something","something1"]},"exclude": { "resources": { "kinds":["Namespace"],"name":"something","namespaces":["something","something1"],"selector": { "matchLabels": { "memory":"high"},"matchExpressions":[ { "key":"tier","operator":"In","values":["database"]}]}},"subjects":[ { "name":"something","kind":"something","Namespace":"something","apiGroup":"something"}, { "name":"something1","kind":"something1","Namespace":"something1","apiGroup":"something1"}],"clusterroles":["something","something1"],"roles":["something","something1"]}} ` ) ,
expectedOutput : false ,
2020-03-20 20:23:34 +05:30
} ,
{
2020-04-04 14:49:50 +05:30
description : "Failed to exclude name" ,
rule : [ ] byte ( ` { "name":"set-image-pull-policy-2","match": { "resources": { "kinds":["Pod","Namespace"],"name":"something","namespaces":["something","something1"],"selector": { "matchLabels": { "memory":"high"},"matchExpressions":[ { "key":"tier","operator":"In","values":["database"]}]}},"subjects":[ { "name":"something","kind":"something","Namespace":"something","apiGroup":"something"}, { "name":"something1","kind":"something1","Namespace":"something1","apiGroup":"something1"}],"clusterroles":["something","something1"],"roles":["something","something1"]},"exclude": { "resources": { "kinds":["Pod","Namespace"],"name":"something-*","namespaces":["something","something1"],"selector": { "matchLabels": { "memory":"high"},"matchExpressions":[ { "key":"tier","operator":"In","values":["database"]}]}},"subjects":[ { "name":"something","kind":"something","Namespace":"something","apiGroup":"something"}, { "name":"something1","kind":"something1","Namespace":"something1","apiGroup":"something1"}],"clusterroles":["something","something1"],"roles":["something","something1"]}} ` ) ,
expectedOutput : false ,
2020-03-20 20:23:34 +05:30
} ,
{
2020-04-04 14:49:50 +05:30
description : "Failed to exclude namespace" ,
rule : [ ] byte ( ` { "name":"set-image-pull-policy-2","match": { "resources": { "kinds":["Pod","Namespace"],"name":"something","namespaces":["something","something1"],"selector": { "matchLabels": { "memory":"high"},"matchExpressions":[ { "key":"tier","operator":"In","values":["database"]}]}},"subjects":[ { "name":"something","kind":"something","Namespace":"something","apiGroup":"something"}, { "name":"something1","kind":"something1","Namespace":"something1","apiGroup":"something1"}],"clusterroles":["something","something1"],"roles":["something","something1"]},"exclude": { "resources": { "kinds":["Pod","Namespace"],"name":"something","namespaces":["something3","something1"],"selector": { "matchLabels": { "memory":"high"},"matchExpressions":[ { "key":"tier","operator":"In","values":["database"]}]}},"subjects":[ { "name":"something","kind":"something","Namespace":"something","apiGroup":"something"}, { "name":"something1","kind":"something1","Namespace":"something1","apiGroup":"something1"}],"clusterroles":["something","something1"],"roles":["something","something1"]}} ` ) ,
expectedOutput : false ,
2020-03-20 20:23:34 +05:30
} ,
{
2020-04-04 14:49:50 +05:30
description : "Failed to exclude labels" ,
rule : [ ] byte ( ` { "name":"set-image-pull-policy-2","match": { "resources": { "kinds":["Pod","Namespace"],"name":"something","namespaces":["something","something1"],"selector": { "matchLabels": { "memory":"high"},"matchExpressions":[ { "key":"tier","operator":"In","values":["database"]}]}},"subjects":[ { "name":"something","kind":"something","Namespace":"something","apiGroup":"something"}, { "name":"something1","kind":"something1","Namespace":"something1","apiGroup":"something1"}],"clusterroles":["something","something1"],"roles":["something","something1"]},"exclude": { "resources": { "kinds":["Pod","Namespace"],"name":"something","namespaces":["something","something1"],"selector": { "matchLabels": { "memory":"higha"},"matchExpressions":[ { "key":"tier","operator":"In","values":["database"]}]}},"subjects":[ { "name":"something","kind":"something","Namespace":"something","apiGroup":"something"}, { "name":"something1","kind":"something1","Namespace":"something1","apiGroup":"something1"}],"clusterroles":["something","something1"],"roles":["something","something1"]}} ` ) ,
expectedOutput : false ,
2020-03-20 20:23:34 +05:30
} ,
{
2020-04-04 14:49:50 +05:30
description : "Failed to exclude expression" ,
rule : [ ] byte ( ` { "name":"set-image-pull-policy-2","match": { "resources": { "kinds":["Pod","Namespace"],"name":"something","namespaces":["something","something1"],"selector": { "matchLabels": { "memory":"high"},"matchExpressions":[ { "key":"tier","operator":"In","values":["database"]}]}},"subjects":[ { "name":"something","kind":"something","Namespace":"something","apiGroup":"something"}, { "name":"something1","kind":"something1","Namespace":"something1","apiGroup":"something1"}],"clusterroles":["something","something1"],"roles":["something","something1"]},"exclude": { "resources": { "kinds":["Pod","Namespace"],"name":"something","namespaces":["something","something1"],"selector": { "matchLabels": { "memory":"high"},"matchExpressions":[ { "key":"tier","operator":"In","values":["databases"]}]}},"subjects":[ { "name":"something","kind":"something","Namespace":"something","apiGroup":"something"}, { "name":"something1","kind":"something1","Namespace":"something1","apiGroup":"something1"}],"clusterroles":["something","something1"],"roles":["something","something1"]}} ` ) ,
expectedOutput : false ,
2020-03-20 20:23:34 +05:30
} ,
{
2020-04-04 14:49:50 +05:30
description : "Failed to exclude subjects" ,
rule : [ ] byte ( ` { "name":"set-image-pull-policy-2","match": { "resources": { "kinds":["Pod","Namespace"],"name":"something","namespaces":["something","something1"],"selector": { "matchLabels": { "memory":"high"},"matchExpressions":[ { "key":"tier","operator":"In","values":["database"]}]}},"subjects":[ { "name":"something","kind":"something","Namespace":"something","apiGroup":"something"}, { "name":"something1","kind":"something1","Namespace":"something1","apiGroup":"something1"}],"clusterroles":["something","something1"],"roles":["something","something1"]},"exclude": { "resources": { "kinds":["Pod","Namespace"],"name":"something","namespaces":["something","something1"],"selector": { "matchLabels": { "memory":"high"},"matchExpressions":[ { "key":"tier","operator":"In","values":["database"]}]}},"subjects":[ { "name":"something2","kind":"something","Namespace":"something","apiGroup":"something"}, { "name":"something1","kind":"something1","Namespace":"something1","apiGroup":"something1"}],"clusterroles":["something","something1"],"roles":["something","something1"]}} ` ) ,
expectedOutput : false ,
2020-03-20 20:23:34 +05:30
} ,
{
2020-04-04 14:49:50 +05:30
description : "Failed to exclude clusterroles" ,
rule : [ ] byte ( ` { "name":"set-image-pull-policy-2","match": { "resources": { "kinds":["Pod","Namespace"],"name":"something","namespaces":["something","something1"],"selector": { "matchLabels": { "memory":"high"},"matchExpressions":[ { "key":"tier","operator":"In","values":["database"]}]}},"subjects":[ { "name":"something","kind":"something","Namespace":"something","apiGroup":"something"}, { "name":"something1","kind":"something1","Namespace":"something1","apiGroup":"something1"}],"clusterroles":["something","something1"],"roles":["something","something1"]},"exclude": { "resources": { "kinds":["Pod","Namespace"],"name":"something","namespaces":["something","something1"],"selector": { "matchLabels": { "memory":"high"},"matchExpressions":[ { "key":"tier","operator":"In","values":["database"]}]}},"subjects":[ { "name":"something","kind":"something","Namespace":"something","apiGroup":"something"}, { "name":"something1","kind":"something1","Namespace":"something1","apiGroup":"something1"}],"clusterroles":["something3","something1"],"roles":["something","something1"]}} ` ) ,
expectedOutput : false ,
2020-03-20 20:23:34 +05:30
} ,
{
2020-04-04 14:49:50 +05:30
description : "Failed to exclude roles" ,
rule : [ ] byte ( ` { "name":"set-image-pull-policy-2","match": { "resources": { "kinds":["Pod","Namespace"],"name":"something","namespaces":["something","something1"],"selector": { "matchLabels": { "memory":"high"},"matchExpressions":[ { "key":"tier","operator":"In","values":["database"]}]}},"subjects":[ { "name":"something","kind":"something","Namespace":"something","apiGroup":"something"}, { "name":"something1","kind":"something1","Namespace":"something1","apiGroup":"something1"}],"clusterroles":["something","something1"],"roles":["something","something1"]},"exclude": { "resources": { "kinds":["Pod","Namespace"],"name":"something","namespaces":["something","something1"],"selector": { "matchLabels": { "memory":"high"},"matchExpressions":[ { "key":"tier","operator":"In","values":["database"]}]}},"subjects":[ { "name":"something","kind":"something","Namespace":"something","apiGroup":"something"}, { "name":"something1","kind":"something1","Namespace":"something1","apiGroup":"something1"}],"clusterroles":["something","something1"],"roles":["something3","something1"]}} ` ) ,
expectedOutput : false ,
2020-03-20 20:23:34 +05:30
} ,
{
2020-04-04 14:49:50 +05:30
description : "simple" ,
rule : [ ] byte ( ` { "name":"set-image-pull-policy-2","match": { "resources": { "kinds":["Pod","Namespace"],"name":"something","namespaces":["something","something1"]}},"exclude": { "resources": { "kinds":["Pod","Namespace","Job"],"name":"some*","namespaces":["something","something1","something2"]}}} ` ) ,
expectedOutput : true ,
2020-03-20 20:23:34 +05:30
} ,
{
2020-04-04 14:49:50 +05:30
description : "simple - fail" ,
rule : [ ] byte ( ` { "name":"set-image-pull-policy-2","match": { "resources": { "kinds":["Pod","Namespace"],"name":"somxething","namespaces":["something","something1"]}},"exclude": { "resources": { "kinds":["Pod","Namespace","Job"],"name":"some*","namespaces":["something","something1","something2"]}}} ` ) ,
expectedOutput : false ,
2020-03-20 20:23:34 +05:30
} ,
2020-04-27 15:05:10 +05:30
{
description : "empty case" ,
2021-03-02 10:01:06 +05:30
rule : [ ] byte ( ` { "name":"check-allow-deletes","match": { "resources": { "selector": { "matchLabels": { "allow-deletes":"false"}}}},"exclude": { "clusterRoles":["random"]},"validate": { "message":"Deleting {{ request .object .kind }} / {{ request .object .metadata .name }} is not allowed","deny": { "conditions": { "all":[ { "key":" {{ request .operation }} ","operator":"Equal","value":"DELETE"}]}}}} ` ) ,
2020-04-27 15:05:10 +05:30
expectedOutput : false ,
} ,
2020-03-20 20:23:34 +05:30
}
for i , testcase := range testcases {
var rule kyverno . Rule
_ = json . Unmarshal ( testcase . rule , & rule )
2020-10-14 18:30:18 -07:00
if doMatchAndExcludeConflict ( rule ) != testcase . expectedOutput {
2020-03-20 20:23:34 +05:30
t . Errorf ( "Testcase [%d] failed - description - %v" , i + 1 , testcase . description )
}
}
}
2021-04-29 22:21:23 +05:30
2021-04-29 23:44:55 +05:30
func Test_Validate_Kind ( t * testing . T ) {
rawPolicy := [ ] byte ( `
{
"apiVersion" : "kyverno.io/v1" ,
"kind" : "ClusterPolicy" ,
"metadata" : {
"name" : "policy-to-monitor-root-user-access"
} ,
"spec" : {
"validationFailureAction" : "audit" ,
"rules" : [
{
"name" : "monitor-annotation-for-root-user-access" ,
"match" : {
"resources" : {
"selector" : {
"matchLabels" : {
"AllowRootUserAccess" : "true"
}
}
}
} ,
"validate" : {
"message" : "Label provisioner.wg.net/cloudprovider is required" ,
"pattern" : {
"metadata" : {
"labels" : {
"provisioner.wg.net/cloudprovider" : "*"
}
}
}
}
}
]
}
}
` )
var policy * kyverno . ClusterPolicy
err := json . Unmarshal ( rawPolicy , & policy )
assert . NilError ( t , err )
openAPIController , _ := openapi . NewOpenAPIController ( )
err = Validate ( policy , nil , true , openAPIController )
assert . Assert ( t , err != nil )
}
2021-05-04 18:28:30 +02:00
2021-07-29 01:29:53 +05:30
func Test_Validate_Any_Kind ( t * testing . T ) {
rawPolicy := [ ] byte ( ` {
"apiVersion" : "kyverno.io/v1" ,
"kind" : "ClusterPolicy" ,
"metadata" : {
"name" : "policy-to-monitor-root-user-access"
} ,
"spec" : {
"validationFailureAction" : "audit" ,
"rules" : [
{
"name" : "monitor-annotation-for-root-user-access" ,
"match" : {
"any" : [
{
"resources" : {
"selector" : {
"matchLabels" : {
"AllowRootUserAccess" : "true"
}
}
}
}
]
} ,
"validate" : {
"message" : "Label provisioner.wg.net/cloudprovider is required" ,
"pattern" : {
"metadata" : {
"labels" : {
"provisioner.wg.net/cloudprovider" : "*"
}
}
}
}
}
]
}
} ` )
var policy * kyverno . ClusterPolicy
err := json . Unmarshal ( rawPolicy , & policy )
assert . NilError ( t , err )
openAPIController , _ := openapi . NewOpenAPIController ( )
err = Validate ( policy , nil , true , openAPIController )
assert . Assert ( t , err != nil )
}
2021-04-29 22:21:23 +05:30
func Test_checkAutoGenRules ( t * testing . T ) {
testCases := [ ] struct {
name string
policy [ ] byte
expectedResult bool
} {
{
2021-04-29 14:59:37 -07:00
name : "rule-missing-autogen-cronjob" ,
policy : [ ] byte ( ` { "apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata": { "name":"test","annotations": { "pod-policies.kyverno.io/autogen-controllers":"Deployment,CronJob"}},"spec": { "rules":[ { "match": { "resources": { "kinds":["Pod"]}},"name":"block-old-flux","validate": { "message":"CannotuseoldFluxv1annotation.","pattern": { "metadata": { "=(annotations)": { "X(fluxcd.io/*)":"*?"}}}}}, { "match": { "resources": { "kinds":["Deployment"]}},"name":"autogen-block-old-flux","validate": { "message":"CannotuseoldFluxv1annotation.","pattern": { "spec": { "template": { "metadata": { "=(annotations)": { "X(fluxcd.io/*)":"*?"}}}}}}}]}} ` ) ,
expectedResult : true ,
2021-04-29 22:21:23 +05:30
} ,
{
2021-04-29 14:59:37 -07:00
name : "rule-missing-autogen-deployment" ,
policy : [ ] byte ( ` { "apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata": { "name":"test","annotations": { "pod-policies.kyverno.io/autogen-controllers":"Deployment,CronJob"}},"spec": { "rules":[ { "match": { "resources": { "kinds":["Pod"]}},"name":"block-old-flux","validate": { "message":"CannotuseoldFluxv1annotation.","pattern": { "metadata": { "=(annotations)": { "X(fluxcd.io/*)":"*?"}}}}}, { "match": { "resources": { "kinds":["CronJob"]}},"name":"autogen-cronjob-block-old-flux","validate": { "message":"CannotuseoldFluxv1annotation.","pattern": { "spec": { "jobTemplate": { "spec": { "template": { "metadata": { "=(annotations)": { "X(fluxcd.io/*)":"*?"}}}}}}}}}]}} ` ) ,
expectedResult : true ,
2021-04-29 22:21:23 +05:30
} ,
{
2021-04-29 14:59:37 -07:00
name : "rule-missing-autogen-all" ,
policy : [ ] byte ( ` { "apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata": { "name":"test","annotations": { "pod-policies.kyverno.io/autogen-controllers":"Deployment,CronJob,StatefulSet,Job,DaemonSet"}},"spec": { "rules":[ { "match": { "resources": { "kinds":["Pod"]}},"name":"block-old-flux","validate": { "message":"CannotuseoldFluxv1annotation.","pattern": { "metadata": { "=(annotations)": { "X(fluxcd.io/*)":"*?"}}}}}]}} ` ) ,
2021-04-29 22:21:23 +05:30
expectedResult : true ,
} ,
{
2021-04-29 14:59:37 -07:00
name : "rule-with-autogen-disabled" ,
policy : [ ] byte ( ` { "apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata": { "name":"test","annotations": { "pod-policies.kyverno.io/autogen-controllers":"none"}},"spec": { "rules":[ { "match": { "resources": { "kinds":["Pod"]}},"name":"block-old-flux","validate": { "message":"CannotuseoldFluxv1annotation.","pattern": { "metadata": { "=(annotations)": { "X(fluxcd.io/*)":"*?"}}}}}]}} ` ) ,
expectedResult : false ,
2021-04-29 22:21:23 +05:30
} ,
}
for _ , test := range testCases {
var policy kyverno . ClusterPolicy
err := json . Unmarshal ( test . policy , & policy )
assert . NilError ( t , err )
2021-04-29 14:59:37 -07:00
res := missingAutoGenRules ( & policy , log . Log )
2021-04-29 22:21:23 +05:30
assert . Equal ( t , test . expectedResult , res , fmt . Sprintf ( "test %s failed" , test . name ) )
}
}
2021-05-04 18:28:30 +02:00
func Test_Validate_ApiCall ( t * testing . T ) {
testCases := [ ] struct {
resource kyverno . ContextEntry
expectedResult interface { }
} {
{
resource : kyverno . ContextEntry {
APICall : & kyverno . APICall {
URLPath : "/apis/networking.k8s.io/v1/namespaces/{{request.namespace}}/networkpolicies" ,
JMESPath : "" ,
} ,
} ,
expectedResult : nil ,
} ,
{
resource : kyverno . ContextEntry {
APICall : & kyverno . APICall {
URLPath : "/apis/networking.k8s.io/v1/namespaces/{{request.namespace}}/networkpolicies" ,
JMESPath : "items[" ,
} ,
} ,
expectedResult : "failed to parse JMESPath items[: SyntaxError: Expected tStar, received: tEOF" ,
} ,
{
resource : kyverno . ContextEntry {
APICall : & kyverno . APICall {
URLPath : "/apis/networking.k8s.io/v1/namespaces/{{request.namespace}}/networkpolicies" ,
JMESPath : "items[{{request.namespace}}" ,
} ,
} ,
expectedResult : nil ,
} ,
}
for _ , testCase := range testCases {
err := validateAPICall ( testCase . resource )
if err == nil {
assert . Equal ( t , err , testCase . expectedResult )
} else {
assert . Equal ( t , err . Error ( ) , testCase . expectedResult )
}
}
}
2021-07-14 23:49:15 +05:30
func Test_Wildcards_Kind ( t * testing . T ) {
rawPolicy := [ ] byte ( `
{
"apiVersion" : "kyverno.io/v1" ,
"kind" : "ClusterPolicy" ,
"metadata" : {
"name" : "require-labels"
} ,
"spec" : {
"validationFailureAction" : "enforce" ,
"rules" : [
{
"name" : "check-for-labels" ,
"match" : {
"resources" : {
"kinds" : [
"*"
]
}
} ,
"validate" : {
"message" : "label 'app.kubernetes.io/name' is required" ,
"pattern" : {
"metadata" : {
"labels" : {
"app.kubernetes.io/name" : "?*"
}
}
}
}
}
]
}
}
` )
var policy * kyverno . ClusterPolicy
err := json . Unmarshal ( rawPolicy , & policy )
assert . NilError ( t , err )
openAPIController , _ := openapi . NewOpenAPIController ( )
err = Validate ( policy , nil , true , openAPIController )
assert . Assert ( t , err != nil )
}
2021-10-22 01:48:22 +05:30
func Test_Namespced_Policy ( t * testing . T ) {
rawPolicy := [ ] byte ( `
{
"apiVersion" : "kyverno.io/v1" ,
"kind" : "Policy" ,
"metadata" : {
"name" : "evil-policy-match-foreign-pods" ,
"namespace" : "customer-foo"
} ,
"spec" : {
"validationFailureAction" : "enforce" ,
"background" : false ,
"rules" : [
{
"name" : "evil-validation" ,
"match" : {
"resources" : {
"kinds" : [
"Pod"
] ,
"namespaces" : [
"customer-bar"
]
}
} ,
"validate" : {
"message" : "Mua ah ah ... you've been pwned by customer-foo" ,
"pattern" : {
"metadata" : {
"annotations" : {
"pwned-by-customer-foo" : "true"
}
}
}
}
}
]
}
}
` )
var policy * kyverno . ClusterPolicy
err := json . Unmarshal ( rawPolicy , & policy )
assert . NilError ( t , err )
openAPIController , _ := openapi . NewOpenAPIController ( )
err = Validate ( policy , nil , true , openAPIController )
assert . Assert ( t , err != nil )
}
2021-11-30 18:14:58 +01:00
func Test_patchesJson6902_Policy ( t * testing . T ) {
rawPolicy := [ ] byte ( `
{
"apiVersion" : "kyverno.io/v1" ,
"kind" : "ClusterPolicy" ,
"metadata" : {
"name" : "set-max-surge-yaml-to-json"
} ,
"spec" : {
"background" : false ,
"schemaValidation" : false ,
"rules" : [
{
"name" : "set-max-surge" ,
"context" : [
{
"name" : "source" ,
"configMap" : {
"name" : "source-yaml-to-json" ,
"namespace" : "default"
}
}
] ,
"match" : {
"resources" : {
"kinds" : [
"Deployment"
]
}
} ,
"mutate" : {
"patchesJson6902" : "- op: replace\n path: /spec/strategy\n value: {{ source.data.strategy }}"
}
}
]
}
}
` )
var policy * kyverno . ClusterPolicy
err := json . Unmarshal ( rawPolicy , & policy )
assert . NilError ( t , err )
openAPIController , _ := openapi . NewOpenAPIController ( )
err = Validate ( policy , nil , false , openAPIController )
assert . NilError ( t , err )
}