1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00

test: add test case for duplicate check and report unused resources (#6653)

* add test case

Signed-off-by: bakito <github@bakito.ch>

* also print obsolete resources

Signed-off-by: bakito <github@bakito.ch>

---------

Signed-off-by: bakito <github@bakito.ch>
Co-authored-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
Marc Brugger 2023-03-23 10:32:01 +01:00 committed by GitHub
parent 893c22b96b
commit cdf79daa44
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 292 additions and 12 deletions

View file

@ -230,7 +230,7 @@ type testFilter struct {
enabled bool
}
var ftable = []Table{}
var ftable []Table
func testCommandExecute(dirPath []string, fileName string, gitBranch string, testCase string, failOnly bool, removeColor bool) (rc *resultCounts, err error) {
var errors []error
@ -756,7 +756,7 @@ func applyPoliciesFromPath(fs billy.Filesystem, policyBytes []byte, isGit bool,
return nil
}
fmt.Printf("\nExecuting %s...", values.Name)
fmt.Printf("\nExecuting %s...\n", values.Name)
valuesFile := values.Variables
userInfoFile := values.UserInfo
@ -802,7 +802,7 @@ func applyPoliciesFromPath(fs billy.Filesystem, policyBytes []byte, isGit bool,
os.Exit(1)
}
filteredPolicies := []kyvernov1.PolicyInterface{}
var filteredPolicies []kyvernov1.PolicyInterface
for _, p := range policies {
for _, res := range values.Results {
if p.GetName() == res.Policy {
@ -814,7 +814,7 @@ func applyPoliciesFromPath(fs billy.Filesystem, policyBytes []byte, isGit bool,
ruleToCloneSourceResource := map[string]string{}
for _, p := range filteredPolicies {
filteredRules := []kyvernov1.Rule{}
var filteredRules []kyvernov1.Rule
for _, rule := range autogen.ComputeRules(p) {
for _, res := range values.Results {
@ -869,7 +869,7 @@ func applyPoliciesFromPath(fs billy.Filesystem, policyBytes []byte, isGit bool,
}
if len(policies) > 0 && len(checkableResources) > 0 {
fmt.Printf("\napplying %s to %s... \n", msgPolicies, msgResources)
fmt.Printf("applying %s to %s... \n", msgPolicies, msgResources)
}
for _, policy := range policies {
@ -929,6 +929,14 @@ func applyPoliciesFromPath(fs billy.Filesystem, policyBytes []byte, isGit bool,
}
func selectResourcesForCheck(resources []*unstructured.Unstructured, values *api.Test) []*unstructured.Unstructured {
res, _, _ := selectResourcesForCheckInternal(resources, values)
return res
}
// selectResourcesForCheckInternal internal method to test duplicates and unused
func selectResourcesForCheckInternal(resources []*unstructured.Unstructured, values *api.Test) ([]*unstructured.Unstructured, int, int) {
var duplicates int
var unused int
uniqResources := make(map[string]*unstructured.Unstructured)
for i := range resources {
@ -936,6 +944,7 @@ func selectResourcesForCheck(resources []*unstructured.Unstructured, values *api
key := fmt.Sprintf("%s/%s/%s", r.GetKind(), r.GetName(), r.GetNamespace())
if _, ok := uniqResources[key]; ok {
fmt.Println("skipping duplicate resource, resource :", r)
duplicates++
} else {
uniqResources[key] = r
}
@ -945,14 +954,16 @@ func selectResourcesForCheck(resources []*unstructured.Unstructured, values *api
for key := range uniqResources {
r := uniqResources[key]
for _, res := range values.Results {
for _, testr := range res.Resources {
if r.GetName() == testr {
if res.Kind == r.GetKind() {
for _, testr := range res.Resources {
if r.GetName() == testr {
selectedResources[key] = r
}
}
if r.GetName() == res.Resource {
selectedResources[key] = r
}
}
if r.GetName() == res.Resource {
selectedResources[key] = r
}
}
}
@ -960,13 +971,18 @@ func selectResourcesForCheck(resources []*unstructured.Unstructured, values *api
for key := range selectedResources {
checkableResources = append(checkableResources, selectedResources[key])
delete(uniqResources, key)
}
return checkableResources
for _, r := range uniqResources {
fmt.Println("skipping unused resource, resource :", r)
unused++
}
return checkableResources, duplicates, unused
}
func printTestResult(resps map[string]policyreportv1alpha2.PolicyReportResult, testResults []api.TestResults, rc *resultCounts, failOnly, removeColor bool) error {
printer := newTablePrinter(removeColor)
table := []Table{}
var table []Table
var countDeprecatedResource int
testCount := 1

View file

@ -0,0 +1,92 @@
package test
import (
"os"
"path/filepath"
"testing"
"github.com/go-git/go-billy/v5/memfs"
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/test/api"
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/common"
"gotest.tools/assert"
"sigs.k8s.io/yaml"
)
func Test_selectResourcesForCheck(t *testing.T) {
type TestCase struct {
testFile string
expectedResources int
expectedDuplicates int
expectedUnused int
}
baseTestDir := "../../../../test/cli/test-unit/selectResourcesForCheck/"
testcases := []*TestCase{
{
testFile: "kyverno-test-duplicated-with-resource.yaml",
expectedResources: 3,
expectedDuplicates: 1,
expectedUnused: 3,
},
{
testFile: "kyverno-test-duplicated-with-resources.yaml",
expectedResources: 3,
expectedDuplicates: 1,
expectedUnused: 3,
},
{
testFile: "kyverno-test-uniq-with-resource.yaml",
expectedResources: 3,
expectedDuplicates: 0,
expectedUnused: 3,
},
{
testFile: "kyverno-test-uniq-with-resources.yaml",
expectedResources: 3,
expectedDuplicates: 0,
expectedUnused: 3,
},
}
fs := memfs.New()
for _, tc := range testcases {
// read test spec
values := &api.Test{}
testBytes, err := os.ReadFile(filepath.Join(baseTestDir, tc.testFile))
assert.NilError(t, err)
err = yaml.Unmarshal(testBytes, values)
assert.NilError(t, err)
// read policies
policies, err := common.GetPoliciesFromPaths(
fs,
[]string{filepath.Join(baseTestDir, values.Policies[0])},
false,
filepath.Join(baseTestDir, values.Resources[0]),
)
assert.NilError(t, err)
// read resources
resources, err := common.GetResourceAccordingToResourcePath(
fs,
[]string{filepath.Join(baseTestDir, values.Resources[0])},
false,
policies,
nil,
"",
false,
false,
filepath.Join(baseTestDir, values.Policies[0]),
)
assert.NilError(t, err)
selected, duplicates, unused := selectResourcesForCheckInternal(resources, values)
assert.Equal(t, len(selected), tc.expectedResources,
"Did not get the expected number of resources for test %s", tc.testFile)
assert.Equal(t, duplicates, tc.expectedDuplicates,
"Did not get the expected number of duplicates for test %s", tc.testFile)
assert.Equal(t, unused, tc.expectedUnused,
"Did not get the expected number of unused resources for test %s", tc.testFile)
}
}

View file

@ -0,0 +1,8 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: just a dummy policy
spec:
rules:
- name: dummy-rule-1
- name: dummy-rule-2

View file

@ -0,0 +1,17 @@
name: dummy-policy
policies:
- dummy-policy.yaml
resources:
- resource-duplicates.yaml
results:
- policy: dummy-policy
rule: require-image-tag
resource: myapp-pod1
kind: Pod
result: pass
- policy: dummy-policy
rule: require-image-tag
resource: myapp-pod2
kind: Pod
result: pass

View file

@ -0,0 +1,19 @@
name: dummy-policy
policies:
- dummy-policy.yaml
resources:
- resource-duplicates.yaml
results:
- policy: dummy-policy
rule: require-image-tag
resources:
- myapp-pod1
kind: Pod
result: pass
- policy: dummy-policy
rule: require-image-tag
resources:
- myapp-pod2
kind: Pod
result: pass

View file

@ -0,0 +1,19 @@
name: dummy-policy
policies:
- dummy-policy.yaml
resources:
- resource-uniq.yaml
results:
- policy: dummy-policy
rule: require-image-tag
resources:
- myapp-pod1
kind: Pod
result: pass
- policy: dummy-policy
rule: require-image-tag
resources:
- myapp-pod2
kind: Pod
result: pass

View file

@ -0,0 +1,19 @@
name: dummy-policy
policies:
- dummy-policy.yaml
resources:
- resource-uniq.yaml
results:
- policy: dummy-policy
rule: require-image-tag
resources:
- myapp-pod1
kind: Pod
result: pass
- policy: dummy-policy
rule: require-image-tag
resources:
- myapp-pod2
kind: Pod
result: pass

View file

@ -0,0 +1,49 @@
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod1
namespace: foo
---
# duplicate pod
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod1
namespace: foo
---
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod2
namespace: foo
---
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod2
namespace: bar
---
# will not be used
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod3
namespace: bar
---
# will not be used
apiVersion: v1
kind: Namespace
metadata:
name: myapp-pod2 # reuse the name of the pod to check duplicate check
---
# will not be used
apiVersion: v1
kind: Namespace
metadata:
name: myns

View file

@ -0,0 +1,41 @@
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod1
namespace: foo
---
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod2
namespace: foo
---
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod2
namespace: bar
---
# will not be used
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod3
namespace: bar
---
# will not be used
apiVersion: v1
kind: Namespace
metadata:
name: myapp-pod2 # reuse the name of the pod to check duplicate check
---
# will not be used
apiVersion: v1
kind: Namespace
metadata:
name: myns