1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-31 03:45:17 +00:00

Remove contains function (#2346)

* remove contains function

Signed-off-by: Maxim Goncharenko <goncharenko.maxim@apriorit.com>

* added test for contains issue case

Signed-off-by: Maxim Goncharenko <goncharenko.maxim@apriorit.com>
This commit is contained in:
Max Goncharenko 2021-09-08 22:33:41 +03:00 committed by GitHub
parent bc88916437
commit 2a375fa1b5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 218 additions and 41 deletions

View file

@ -27,7 +27,6 @@ type (
// function names
var (
compare = "compare"
contains = "contains"
equalFold = "equal_fold"
replace = "replace"
replaceAll = "replace_all"
@ -35,7 +34,6 @@ var (
toLower = "to_lower"
trim = "trim"
split = "split"
equals = "equals"
regexReplaceAll = "regex_replace_all"
regexReplaceAllLiteral = "regex_replace_all_literal"
regexMatch = "regex_match"
@ -56,14 +54,6 @@ func getFunctions() []*gojmespath.FunctionEntry {
},
Handler: jpfCompare,
},
{
Name: contains,
Arguments: []ArgSpec{
{Types: []JpType{JpString}},
{Types: []JpType{JpString}},
},
Handler: jpfContains,
},
{
Name: equalFold,
Arguments: []ArgSpec{
@ -175,21 +165,6 @@ func jpfCompare(arguments []interface{}) (interface{}, error) {
return strings.Compare(a.String(), b.String()), nil
}
func jpfContains(arguments []interface{}) (interface{}, error) {
var err error
str, err := validateArg(contains, arguments, 0, reflect.String)
if err != nil {
return nil, err
}
substr, err := validateArg(contains, arguments, 1, reflect.String)
if err != nil {
return nil, err
}
return strings.Contains(str.String(), substr.String()), nil
}
func jpfEqualFold(arguments []interface{}) (interface{}, error) {
var err error
a, err := validateArg(equalFold, arguments, 0, reflect.String)

View file

@ -1,7 +1,12 @@
package validate
// ValidateTests is E2E Test Config for validation
var ValidateTests = []struct {
import (
"github.com/kyverno/kyverno/test/e2e"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// FluxValidateTests is E2E Test Config for validation
var FluxValidateTests = []struct {
//TestName - Name of the Test
TestName string
// PolicyRaw - The Yaml file of the ClusterPolicy
@ -28,3 +33,36 @@ var ValidateTests = []struct {
MustSucceed: true,
},
}
var podGVR = e2e.GetGVR("", "v1", "pods")
var ValidateTests = []struct {
//TestDescription - Description of the Test
TestDescription string
// PolicyName - Name of the Policy
PolicyName string
// PolicyRaw - The Yaml file of the ClusterPolicy
PolicyRaw []byte
// ResourceName - Name of the Resource
ResourceName string
// ResourceNamespace - Namespace of the Resource
ResourceNamespace string
// ResourceGVR - GVR of the Resource
ResourceGVR schema.GroupVersionResource
// ResourceRaw - The Yaml file of the ClusterPolicy
ResourceRaw []byte
// MustSucceed - indicates if validation must succeed
MustSucceed bool
}{
{
// Case for https://github.com/kyverno/kyverno/issues/2345 issue
TestDescription: "checks that contains function works properly with string list",
PolicyName: "drop-cap-net-raw",
PolicyRaw: kyverno_2345_policy,
ResourceName: "test",
ResourceNamespace: "test-validate1",
ResourceGVR: podGVR,
ResourceRaw: kyverno_2345_resource,
MustSucceed: false,
},
}

View file

@ -1,5 +1,7 @@
package validate
import "fmt"
// Namespace Description
var namespaceYaml = []byte(`
apiVersion: v1
@ -8,6 +10,16 @@ metadata:
name: test-validate
`)
func newNamespaceYaml(name string) []byte {
ns := fmt.Sprintf(`
apiVersion: v1
kind: Namespace
metadata:
name: %s
`, name)
return []byte(ns)
}
// Regression: https://github.com/kyverno/kyverno/issues/2043
// Policy: https://github.com/fluxcd/flux2-multi-tenancy/blob/main/infrastructure/kyverno-policies/flux-multi-tenancy.yaml
var kyverno_2043_policy = []byte(`
@ -561,3 +573,61 @@ spec:
prune: true
validation: client
`)
var kyverno_2345_policy = []byte(`
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: drop-cap-net-raw
spec:
validationFailureAction: enforce
background: false
rules:
- name: drop-cap-net-raw
match:
resources:
kinds:
- Pod
validate:
deny:
conditions:
any:
- key: "{{ request.object.spec.containers[].securityContext.capabilities.drop[] | contains(@, 'NET_RAW') }}"
operator: Equals
value: false
`)
var kyverno_2345_resource = []byte(`
apiVersion: v1
kind: Pod
metadata:
name: test
namespace: test-validate1
spec:
initContainers:
- name: jimmy
image: defdasdabian:923
command: ["/bin/sh", "-c", "sleep infinity"]
securityContext:
capabilities:
drop:
- XXXNET_RAWYYY
- SETUID
containers:
- name: test
image: defdasdabian:923
command: ["/bin/sh", "-c", "sleep infinity"]
securityContext:
capabilities:
drop:
- XXXNET_RAWYYY
- SETUID
- CAP_FOO_BAR
- name: asdf
image: defdasdabian:923
command: ["/bin/sh", "-c", "sleep infinity"]
securityContext:
capabilities:
drop:
- CAP_SOMETHING
`)

View file

@ -8,22 +8,24 @@ import (
"time"
"github.com/kyverno/kyverno/test/e2e"
commonE2E "github.com/kyverno/kyverno/test/e2e/common"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
k8sErrors "k8s.io/apimachinery/pkg/api/errors"
)
var (
// Cluster Polict GVR
clPolGVR = e2e.GetGVR("kyverno.io", "v1", "clusterpolicies")
policyGVR = e2e.GetGVR("kyverno.io", "v1", "clusterpolicies")
// Namespace GVR
nsGVR = e2e.GetGVR("", "v1", "namespaces")
namespaceGVR = e2e.GetGVR("", "v1", "namespaces")
// ConfigMap GVR
cmGVR = e2e.GetGVR("", "v1", "configmaps")
crdGVR = e2e.GetGVR("apiextensions.k8s.io", "v1", "customresourcedefinitions")
// ClusterPolicy Namespace
clPolNS = ""
policyNamespace = ""
// Namespace Name
// Hardcoded in YAML Definition
nspace = "test-validate"
@ -31,7 +33,7 @@ var (
crdName = "kustomizations.kustomize.toolkit.fluxcd.io"
)
func Test_Validate_Sets(t *testing.T) {
func Test_Validate_Flux_Sets(t *testing.T) {
RegisterTestingT(t)
if os.Getenv("E2E") == "" {
t.Skip("Skipping E2E Test")
@ -41,21 +43,21 @@ func Test_Validate_Sets(t *testing.T) {
e2eClient, err := e2e.NewE2EClient()
Expect(err).To(BeNil())
for _, test := range ValidateTests {
for _, test := range FluxValidateTests {
By(fmt.Sprintf("Test to validate objects: \"%s\"", test.TestName))
// Clean up Resources
By(fmt.Sprintf("Cleaning Cluster Policies"))
e2eClient.CleanClusterPolicies(clPolGVR)
e2eClient.CleanClusterPolicies(policyGVR)
// Clear Namespace
By(fmt.Sprintf("Deleting Namespace: \"%s\"", nspace))
e2eClient.DeleteClusteredResource(nsGVR, nspace)
e2eClient.DeleteClusteredResource(namespaceGVR, nspace)
//CleanUp CRDs
e2eClient.DeleteClusteredResource(crdGVR, crdName)
// Wait Till Deletion of Namespace
e2e.GetWithRetry(time.Duration(1*time.Second), 15, func() error {
_, err := e2eClient.GetClusteredResource(nsGVR, nspace)
_, err := e2eClient.GetClusteredResource(namespaceGVR, nspace)
if err != nil {
return nil
}
@ -64,12 +66,12 @@ func Test_Validate_Sets(t *testing.T) {
// Create Namespace
By(fmt.Sprintf("Creating namespace \"%s\"", nspace))
_, err = e2eClient.CreateClusteredResourceYaml(nsGVR, namespaceYaml)
_, err = e2eClient.CreateClusteredResourceYaml(namespaceGVR, namespaceYaml)
Expect(err).NotTo(HaveOccurred())
// Create policy
By(fmt.Sprintf("Creating policy in \"%s\"", clPolNS))
_, err = e2eClient.CreateNamespacedResourceYaml(clPolGVR, clPolNS, test.PolicyRaw)
By(fmt.Sprintf("Creating policy in \"%s\"", policyNamespace))
_, err = e2eClient.CreateNamespacedResourceYaml(policyGVR, policyNamespace, test.PolicyRaw)
Expect(err).NotTo(HaveOccurred())
// Create Flux CRD
@ -101,16 +103,16 @@ func Test_Validate_Sets(t *testing.T) {
}
//CleanUp Resources
e2eClient.CleanClusterPolicies(clPolGVR)
e2eClient.CleanClusterPolicies(policyGVR)
//CleanUp CRDs
e2eClient.DeleteClusteredResource(crdGVR, crdName)
// Clear Namespace
e2eClient.DeleteClusteredResource(nsGVR, nspace)
e2eClient.DeleteClusteredResource(namespaceGVR, nspace)
// Wait Till Deletion of Namespace
e2e.GetWithRetry(time.Duration(1*time.Second), 15, func() error {
_, err := e2eClient.GetClusteredResource(nsGVR, nspace)
_, err := e2eClient.GetClusteredResource(namespaceGVR, nspace)
if err != nil {
return nil
}
@ -120,3 +122,95 @@ func Test_Validate_Sets(t *testing.T) {
By(fmt.Sprintf("Test %s Completed \n\n\n", test.TestName))
}
}
func TestValidate(t *testing.T) {
RegisterTestingT(t)
if os.Getenv("E2E") == "" {
t.Skip("Skipping E2E Test")
}
e2eClient, err := e2e.NewE2EClient()
Expect(err).To(BeNil())
for _, test := range ValidateTests {
By(fmt.Sprintf("Mutation Test: %s", test.TestDescription))
By("Deleting Cluster Policies...")
_ = e2eClient.CleanClusterPolicies(policyGVR)
By("Deleting Resource...")
_ = e2eClient.DeleteNamespacedResource(test.ResourceGVR, test.ResourceNamespace, test.ResourceName)
By("Deleting Namespace...")
By(fmt.Sprintf("Deleting Namespace: %s...", test.ResourceNamespace))
_ = e2eClient.DeleteClusteredResource(namespaceGVR, test.ResourceNamespace)
By("Wait Till Deletion of Namespace...")
err = e2e.GetWithRetry(1*time.Second, 15, func() error {
_, err := e2eClient.GetClusteredResource(namespaceGVR, test.ResourceNamespace)
if err != nil {
return nil
}
return fmt.Errorf("failed to delete namespace: %v", err)
})
Expect(err).NotTo(HaveOccurred())
By(fmt.Sprintf("Creating Namespace: %s...", policyNamespace))
_, err = e2eClient.CreateClusteredResourceYaml(namespaceGVR, newNamespaceYaml(test.ResourceNamespace))
Expect(err).NotTo(HaveOccurred())
By("Wait Till Creation of Namespace...")
err = e2e.GetWithRetry(1*time.Second, 15, func() error {
_, err := e2eClient.GetClusteredResource(namespaceGVR, test.ResourceNamespace)
if err != nil {
return err
}
return nil
})
Expect(err).NotTo(HaveOccurred())
By("Creating Policy...")
_, err = e2eClient.CreateNamespacedResourceYaml(policyGVR, policyNamespace, test.PolicyRaw)
Expect(err).NotTo(HaveOccurred())
err = commonE2E.PolicyCreated(test.PolicyName)
Expect(err).NotTo(HaveOccurred())
By("Creating Resource...")
_, err = e2eClient.CreateNamespacedResourceYaml(test.ResourceGVR, test.ResourceNamespace, test.ResourceRaw)
statusErr, ok := err.(*k8sErrors.StatusError)
validationError := (ok && statusErr.ErrStatus.Code == 400) // Validation error is always Bad Request
if test.MustSucceed || !validationError {
Expect(err).NotTo(HaveOccurred())
} else {
Expect(err).To(HaveOccurred())
}
By("Deleting Cluster Policies...")
err = e2eClient.CleanClusterPolicies(policyGVR)
Expect(err).NotTo(HaveOccurred())
By("Deleting Resource...") // if it is present, so ignore an error
e2eClient.DeleteNamespacedResource(test.ResourceGVR, test.ResourceNamespace, test.ResourceName)
By("Deleting Namespace...")
err = e2eClient.DeleteClusteredResource(namespaceGVR, test.ResourceNamespace)
Expect(err).NotTo(HaveOccurred())
By("Wait Till Creation of Namespace...")
e2e.GetWithRetry(1*time.Second, 15, func() error {
_, err := e2eClient.GetClusteredResource(namespaceGVR, test.ResourceNamespace)
if err != nil {
return nil
}
return fmt.Errorf("failed to delete namespace: %v", err)
})
// Do not fail if waiting fails. Sometimes namespace needs time to be deleted.
By("Done")
}
}