1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00
kyverno/cmd/cli/kubectl-kyverno/fix/test.go
shuting fb9c66f455
feat(perf): add new linter prealloc to enforce slice declarations best practice (#10250)
* feat(perf): add new linter prealloc to enforce slice declarations best practice

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* fix(linter): prealloac slices

Signed-off-by: ShutingZhao <shuting@nirmata.com>

---------

Signed-off-by: ShutingZhao <shuting@nirmata.com>
2024-05-20 14:46:35 +05:30

123 lines
3.8 KiB
Go

package fix
import (
"cmp"
"errors"
"fmt"
"slices"
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/apis/v1alpha1"
"k8s.io/apimachinery/pkg/util/sets"
)
func FixTest(test v1alpha1.Test, compress bool) (v1alpha1.Test, []string, error) {
var messages []string
if test.APIVersion == "" {
messages = append(messages, "api version is not set, setting `cli.kyverno.io/v1alpha1`")
test.APIVersion = "cli.kyverno.io/v1alpha1"
}
if test.Kind == "" {
messages = append(messages, "kind is not set, setting `Test`")
test.Kind = "Test"
}
if test.Name != "" {
messages = append(messages, "name is deprecated, moving it into `metadata.name`")
test.ObjectMeta.Name = test.Name
test.Name = ""
}
if len(test.Policies) == 0 {
messages = append(messages, "test has no policies")
}
if len(test.Resources) == 0 {
messages = append(messages, "test has no resources")
}
results := make([]v1alpha1.TestResult, 0, len(test.Results))
for _, result := range test.Results {
if result.Resource != "" && len(result.Resources) != 0 {
messages = append(messages, "test result should not use both `resource` and `resources` fields")
}
if result.Resource != "" {
var resources []string
messages = append(messages, "test result uses deprecated `resource` field, moving it into the `resources` field")
resources = append(resources, result.Resources...)
resources = append(resources, result.Resource)
result.Resources = resources
result.Resource = ""
}
unique := sets.New(result.Resources...)
if len(result.Resources) != len(unique) {
messages = append(messages, "test results contains duplicate resources")
result.Resources = unique.UnsortedList()
}
if result.Namespace != "" {
messages = append(messages, "test result uses deprecated `namespace` field, replacing `policy` with a `<namespace>/<name>` pattern")
result.Policy = fmt.Sprintf("%s/%s", result.Namespace, result.Policy)
result.Namespace = ""
}
if result.Status != "" && result.Result != "" {
return test, messages, errors.New("test result should not use both `status` and `result` fields")
}
if result.Status != "" && result.Result == "" {
messages = append(messages, "test result uses deprecated `status` field, moving it into the `result` field")
result.Result = result.Status
result.Status = ""
}
results = append(results, result)
}
if compress {
compressed := map[v1alpha1.TestResultBase][]string{}
for _, result := range results {
compressed[result.TestResultBase] = append(compressed[result.TestResultBase], result.Resources...)
}
results = nil
for k, v := range compressed {
unique := sets.New(v...)
if len(v) != len(unique) {
messages = append(messages, "test results contains duplicate resources")
v = unique.UnsortedList()
}
results = append(results, v1alpha1.TestResult{
TestResultBase: k,
Resources: v,
})
}
}
slices.SortFunc(results, func(a, b v1alpha1.TestResult) int {
if x := cmp.Compare(a.Policy, b.Policy); x != 0 {
return x
}
if x := cmp.Compare(a.Rule, b.Rule); x != 0 {
return x
}
if x := cmp.Compare(a.Result, b.Result); x != 0 {
return x
}
if x := cmp.Compare(a.Kind, b.Kind); x != 0 {
return x
}
if x := cmp.Compare(a.PatchedResource, b.PatchedResource); x != 0 {
return x
}
if x := cmp.Compare(a.GeneratedResource, b.GeneratedResource); x != 0 {
return x
}
if x := cmp.Compare(a.CloneSourceResource, b.CloneSourceResource); x != 0 {
return x
}
slices.Sort(a.Resources)
slices.Sort(b.Resources)
if x := cmp.Compare(len(a.Resources), len(b.Resources)); x != 0 {
return x
}
if len(a.Resources) == len(b.Resources) {
for i := range a.Resources {
if x := cmp.Compare(a.Resources[i], b.Resources[i]); x != 0 {
return x
}
}
}
return 0
})
test.Results = results
return test, messages, nil
}