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

refactor: introduce report utils package and use it in cli apply (#8203)

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
Charles-Edouard Brétéché 2023-09-01 11:20:39 +02:00 committed by GitHub
parent b6c1718479
commit 33d5c81a7d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 612 additions and 720 deletions

View file

@ -22,20 +22,20 @@ import (
// Status specifies state of a policy result
const (
StatusPass = "pass"
StatusFail = "fail"
StatusWarn = "warn"
StatusError = "error"
StatusSkip = "skip"
StatusPass PolicyResult = "pass"
StatusFail PolicyResult = "fail"
StatusWarn PolicyResult = "warn"
StatusError PolicyResult = "error"
StatusSkip PolicyResult = "skip"
)
// Severity specifies priority of a policy result
const (
SeverityCritical = "critical"
SeverityHigh = "high"
SeverityMedium = "medium"
SeverityLow = "low"
SeverityInfo = "info"
SeverityCritical PolicySeverity = "critical"
SeverityHigh PolicySeverity = "high"
SeverityMedium PolicySeverity = "medium"
SeverityLow PolicySeverity = "low"
SeverityInfo PolicySeverity = "info"
)
// PolicyReportSummary provides a status count summary

View file

@ -15,6 +15,7 @@ import (
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/test/api"
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/color"
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/common"
reportutils "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/report"
sanitizederror "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/sanitizedError"
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/store"
"github.com/kyverno/kyverno/pkg/autogen"
@ -509,12 +510,12 @@ func printSkippedAndInvalidPolicies(skipInvalidPolicies SkippedInvalidPolicies)
}
func printReport(engineResponses []engineapi.EngineResponse, auditWarn bool) {
clustered, namespaced := buildPolicyReports(auditWarn, engineResponses...)
clustered, namespaced := reportutils.ComputePolicyReports(auditWarn, engineResponses...)
if len(clustered) > 0 || len(namespaced) > 0 {
fmt.Println(divider)
fmt.Println("POLICY REPORT:")
fmt.Println(divider)
report := mergeClusterReport(clustered, namespaced)
report := reportutils.MergeClusterReports(clustered, namespaced)
yamlReport, _ := yaml.Marshal(report)
fmt.Println(string(yamlReport))
} else {

View file

@ -7,14 +7,15 @@ import (
"strings"
"testing"
preport "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
reportutils "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/report"
"gotest.tools/assert"
)
func Test_Apply(t *testing.T) {
type TestCase struct {
gitBranch string
expectedPolicyReports []preport.PolicyReport
expectedPolicyReports []policyreportv1alpha2.PolicyReport
config ApplyCommandConfig
stdinFile string
}
@ -23,334 +24,282 @@ func Test_Apply(t *testing.T) {
assert.NilError(t, err)
defer func() { _ = os.Remove(localFileName) }()
testcases := []*TestCase{
{
config: ApplyCommandConfig{
PolicyPaths: []string{"../../../../test/best_practices/disallow_latest_tag.yaml"},
ResourcePaths: []string{"../../../../test/resources/pod_with_version_tag.yaml"},
PolicyReport: true,
},
expectedPolicyReports: []preport.PolicyReport{
{
Summary: preport.PolicyReportSummary{
Pass: 2,
Fail: 0,
Skip: 0,
Error: 0,
Warn: 0,
},
},
},
testcases := []*TestCase{{
config: ApplyCommandConfig{
PolicyPaths: []string{"../../../../test/best_practices/disallow_latest_tag.yaml"},
ResourcePaths: []string{"../../../../test/resources/pod_with_version_tag.yaml"},
PolicyReport: true,
},
{
config: ApplyCommandConfig{
PolicyPaths: []string{localFileName},
ResourcePaths: []string{"../../../../test/resources/pod_with_version_tag.yaml"},
PolicyReport: true,
},
expectedPolicyReports: []preport.PolicyReport{
{
Summary: preport.PolicyReportSummary{
Pass: 2,
Fail: 0,
Skip: 0,
Error: 0,
Warn: 0,
},
},
expectedPolicyReports: []policyreportv1alpha2.PolicyReport{{
Summary: policyreportv1alpha2.PolicyReportSummary{
Pass: 2,
Fail: 0,
Skip: 0,
Error: 0,
Warn: 0,
},
}},
}, {
config: ApplyCommandConfig{
PolicyPaths: []string{localFileName},
ResourcePaths: []string{"../../../../test/resources/pod_with_version_tag.yaml"},
PolicyReport: true,
},
{
config: ApplyCommandConfig{
PolicyPaths: []string{"../../../../test/best_practices/disallow_latest_tag.yaml"},
ResourcePaths: []string{"../../../../test/resources/pod_with_latest_tag.yaml"},
PolicyReport: true,
},
expectedPolicyReports: []preport.PolicyReport{
{
Summary: preport.PolicyReportSummary{
Pass: 1,
Fail: 1,
Skip: 0,
Error: 0,
Warn: 0,
},
},
expectedPolicyReports: []policyreportv1alpha2.PolicyReport{{
Summary: policyreportv1alpha2.PolicyReportSummary{
Pass: 2,
Fail: 0,
Skip: 0,
Error: 0,
Warn: 0,
},
}},
}, {
config: ApplyCommandConfig{
PolicyPaths: []string{"../../../../test/best_practices/disallow_latest_tag.yaml"},
ResourcePaths: []string{"../../../../test/resources/pod_with_latest_tag.yaml"},
PolicyReport: true,
},
{
config: ApplyCommandConfig{
PolicyPaths: []string{"../../../../test/cli/apply/policies"},
ResourcePaths: []string{"../../../../test/cli/apply/resource"},
PolicyReport: true,
},
expectedPolicyReports: []preport.PolicyReport{
{
Summary: preport.PolicyReportSummary{
Pass: 1,
Fail: 1,
Skip: 8,
Error: 0,
Warn: 2,
},
},
expectedPolicyReports: []policyreportv1alpha2.PolicyReport{{
Summary: policyreportv1alpha2.PolicyReportSummary{
Pass: 1,
Fail: 1,
Skip: 0,
Error: 0,
Warn: 0,
},
}},
}, {
config: ApplyCommandConfig{
PolicyPaths: []string{"../../../../test/cli/apply/policies"},
ResourcePaths: []string{"../../../../test/cli/apply/resource"},
PolicyReport: true,
},
{
config: ApplyCommandConfig{
PolicyPaths: []string{"../../../../test/best_practices/disallow_latest_tag.yaml"},
ResourcePaths: []string{"../../../../test/resources/pod_with_latest_tag.yaml"},
PolicyReport: true,
AuditWarn: true,
},
expectedPolicyReports: []preport.PolicyReport{
{
Summary: preport.PolicyReportSummary{
Pass: 1,
Fail: 0,
Skip: 0,
Error: 0,
Warn: 1,
},
},
expectedPolicyReports: []policyreportv1alpha2.PolicyReport{{
Summary: policyreportv1alpha2.PolicyReportSummary{
Pass: 1,
Fail: 1,
Skip: 8,
Error: 0,
Warn: 2,
},
}},
}, {
config: ApplyCommandConfig{
PolicyPaths: []string{"../../../../test/best_practices/disallow_latest_tag.yaml"},
ResourcePaths: []string{"../../../../test/resources/pod_with_latest_tag.yaml"},
PolicyReport: true,
AuditWarn: true,
},
{
config: ApplyCommandConfig{
PolicyPaths: []string{"-"},
ResourcePaths: []string{"../../../../test/resources/pod_with_latest_tag.yaml"},
PolicyReport: true,
AuditWarn: true,
},
stdinFile: "../../../../test/best_practices/disallow_latest_tag.yaml",
expectedPolicyReports: []preport.PolicyReport{
{
Summary: preport.PolicyReportSummary{
Pass: 1,
Fail: 0,
Skip: 0,
Error: 0,
Warn: 1,
},
},
expectedPolicyReports: []policyreportv1alpha2.PolicyReport{{
Summary: policyreportv1alpha2.PolicyReportSummary{
Pass: 1,
Fail: 0,
Skip: 0,
Error: 0,
Warn: 1,
},
}},
}, {
config: ApplyCommandConfig{
PolicyPaths: []string{"-"},
ResourcePaths: []string{"../../../../test/resources/pod_with_latest_tag.yaml"},
PolicyReport: true,
AuditWarn: true,
},
{
config: ApplyCommandConfig{
PolicyPaths: []string{"../../../../test/best_practices/disallow_latest_tag.yaml"},
ResourcePaths: []string{"-"},
PolicyReport: true,
AuditWarn: true,
},
stdinFile: "../../../../test/resources/pod_with_latest_tag.yaml",
expectedPolicyReports: []preport.PolicyReport{
{
Summary: preport.PolicyReportSummary{
Pass: 1,
Fail: 0,
Skip: 0,
Error: 0,
Warn: 1,
},
},
stdinFile: "../../../../test/best_practices/disallow_latest_tag.yaml",
expectedPolicyReports: []policyreportv1alpha2.PolicyReport{{
Summary: policyreportv1alpha2.PolicyReportSummary{
Pass: 1,
Fail: 0,
Skip: 0,
Error: 0,
Warn: 1,
},
}},
}, {
config: ApplyCommandConfig{
PolicyPaths: []string{"../../../../test/best_practices/disallow_latest_tag.yaml"},
ResourcePaths: []string{"-"},
PolicyReport: true,
AuditWarn: true,
},
{
config: ApplyCommandConfig{
PolicyPaths: []string{"https://github.com/kyverno/policies/openshift/team-validate-ns-name/"},
ResourcePaths: []string{"../../../../test/openshift/team-validate-ns-name.yaml"},
GitBranch: "main",
PolicyReport: true,
},
expectedPolicyReports: []preport.PolicyReport{
{
Summary: preport.PolicyReportSummary{
Pass: 2,
Fail: 0,
Skip: 0,
Error: 0,
Warn: 0,
},
},
stdinFile: "../../../../test/resources/pod_with_latest_tag.yaml",
expectedPolicyReports: []policyreportv1alpha2.PolicyReport{{
Summary: policyreportv1alpha2.PolicyReportSummary{
Pass: 1,
Fail: 0,
Skip: 0,
Error: 0,
Warn: 1,
},
}},
}, {
config: ApplyCommandConfig{
PolicyPaths: []string{"https://github.com/kyverno/policies/openshift/team-validate-ns-name/"},
ResourcePaths: []string{"../../../../test/openshift/team-validate-ns-name.yaml"},
GitBranch: "main",
PolicyReport: true,
},
{
config: ApplyCommandConfig{
PolicyPaths: []string{"../../../../test/cli/apply/policies-set"},
ResourcePaths: []string{"../../../../test/cli/apply/resources-set"},
Variables: []string{"request.operation=UPDATE"},
PolicyReport: true,
},
expectedPolicyReports: []preport.PolicyReport{
{
Summary: preport.PolicyReportSummary{
Pass: 2,
Fail: 0,
Skip: 4,
Error: 0,
Warn: 0,
},
},
expectedPolicyReports: []policyreportv1alpha2.PolicyReport{{
Summary: policyreportv1alpha2.PolicyReportSummary{
Pass: 2,
Fail: 0,
Skip: 0,
Error: 0,
Warn: 0,
},
}},
}, {
config: ApplyCommandConfig{
PolicyPaths: []string{"../../../../test/cli/apply/policies-set"},
ResourcePaths: []string{"../../../../test/cli/apply/resources-set"},
Variables: []string{"request.operation=UPDATE"},
PolicyReport: true,
},
{
config: ApplyCommandConfig{
PolicyPaths: []string{"../../../../test/cli/test-validating-admission-policy/check-deployments-replica/policy.yaml"},
ResourcePaths: []string{"../../../../test/cli/test-validating-admission-policy/check-deployments-replica/deployment1.yaml"},
PolicyReport: true,
},
expectedPolicyReports: []preport.PolicyReport{
{
Summary: preport.PolicyReportSummary{
Pass: 1,
Fail: 0,
Skip: 0,
Error: 0,
Warn: 0,
},
},
expectedPolicyReports: []policyreportv1alpha2.PolicyReport{{
Summary: policyreportv1alpha2.PolicyReportSummary{
Pass: 2,
Fail: 0,
Skip: 4,
Error: 0,
Warn: 0,
},
}},
}, {
config: ApplyCommandConfig{
PolicyPaths: []string{"../../../../test/cli/test-validating-admission-policy/check-deployments-replica/policy.yaml"},
ResourcePaths: []string{"../../../../test/cli/test-validating-admission-policy/check-deployments-replica/deployment1.yaml"},
PolicyReport: true,
},
{
config: ApplyCommandConfig{
PolicyPaths: []string{"../../../../test/cli/test-validating-admission-policy/check-deployments-replica/policy.yaml"},
ResourcePaths: []string{"../../../../test/cli/test-validating-admission-policy/check-deployments-replica/deployment2.yaml"},
PolicyReport: true,
},
expectedPolicyReports: []preport.PolicyReport{
{
Summary: preport.PolicyReportSummary{
Pass: 0,
Fail: 1,
Skip: 0,
Error: 0,
Warn: 0,
},
},
expectedPolicyReports: []policyreportv1alpha2.PolicyReport{{
Summary: policyreportv1alpha2.PolicyReportSummary{
Pass: 1,
Fail: 0,
Skip: 0,
Error: 0,
Warn: 0,
},
}},
}, {
config: ApplyCommandConfig{
PolicyPaths: []string{"../../../../test/cli/test-validating-admission-policy/check-deployments-replica/policy.yaml"},
ResourcePaths: []string{"../../../../test/cli/test-validating-admission-policy/check-deployments-replica/deployment2.yaml"},
PolicyReport: true,
},
{
config: ApplyCommandConfig{
PolicyPaths: []string{"../../../../test/cli/test-validating-admission-policy/disallow-host-path/policy.yaml"},
ResourcePaths: []string{"../../../../test/cli/test-validating-admission-policy/disallow-host-path/pod1.yaml"},
PolicyReport: true,
},
expectedPolicyReports: []preport.PolicyReport{
{
Summary: preport.PolicyReportSummary{
Pass: 1,
Fail: 0,
Skip: 0,
Error: 0,
Warn: 0,
},
},
expectedPolicyReports: []policyreportv1alpha2.PolicyReport{{
Summary: policyreportv1alpha2.PolicyReportSummary{
Pass: 0,
Fail: 1,
Skip: 0,
Error: 0,
Warn: 0,
},
}},
}, {
config: ApplyCommandConfig{
PolicyPaths: []string{"../../../../test/cli/test-validating-admission-policy/disallow-host-path/policy.yaml"},
ResourcePaths: []string{"../../../../test/cli/test-validating-admission-policy/disallow-host-path/pod1.yaml"},
PolicyReport: true,
},
{
config: ApplyCommandConfig{
PolicyPaths: []string{"../../../../test/cli/test-validating-admission-policy/disallow-host-path/policy.yaml"},
ResourcePaths: []string{"../../../../test/cli/test-validating-admission-policy/disallow-host-path/pod2.yaml"},
PolicyReport: true,
},
expectedPolicyReports: []preport.PolicyReport{
{
Summary: preport.PolicyReportSummary{
Pass: 0,
Fail: 1,
Skip: 0,
Error: 0,
Warn: 0,
},
},
expectedPolicyReports: []policyreportv1alpha2.PolicyReport{{
Summary: policyreportv1alpha2.PolicyReportSummary{
Pass: 1,
Fail: 0,
Skip: 0,
Error: 0,
Warn: 0,
},
}},
}, {
config: ApplyCommandConfig{
PolicyPaths: []string{"../../../../test/cli/test-validating-admission-policy/disallow-host-path/policy.yaml"},
ResourcePaths: []string{"../../../../test/cli/test-validating-admission-policy/disallow-host-path/pod2.yaml"},
PolicyReport: true,
},
{
config: ApplyCommandConfig{
PolicyPaths: []string{"../../../../test/cli/test-validating-admission-policy/check-deployment-labels/policy.yaml"},
ResourcePaths: []string{"../../../../test/cli/test-validating-admission-policy/check-deployment-labels/deployment1.yaml"},
PolicyReport: true,
},
expectedPolicyReports: []preport.PolicyReport{
{
Summary: preport.PolicyReportSummary{
Pass: 1,
Fail: 0,
Skip: 0,
Error: 0,
Warn: 0,
},
},
expectedPolicyReports: []policyreportv1alpha2.PolicyReport{{
Summary: policyreportv1alpha2.PolicyReportSummary{
Pass: 0,
Fail: 1,
Skip: 0,
Error: 0,
Warn: 0,
},
}},
}, {
config: ApplyCommandConfig{
PolicyPaths: []string{"../../../../test/cli/test-validating-admission-policy/check-deployment-labels/policy.yaml"},
ResourcePaths: []string{"../../../../test/cli/test-validating-admission-policy/check-deployment-labels/deployment1.yaml"},
PolicyReport: true,
},
{
config: ApplyCommandConfig{
PolicyPaths: []string{"../../../../test/cli/test-validating-admission-policy/check-deployment-labels/policy.yaml"},
ResourcePaths: []string{"../../../../test/cli/test-validating-admission-policy/check-deployment-labels/deployment2.yaml"},
PolicyReport: true,
},
expectedPolicyReports: []preport.PolicyReport{
{
Summary: preport.PolicyReportSummary{
Pass: 0,
Fail: 1,
Skip: 0,
Error: 0,
Warn: 0,
},
},
expectedPolicyReports: []policyreportv1alpha2.PolicyReport{{
Summary: policyreportv1alpha2.PolicyReportSummary{
Pass: 1,
Fail: 0,
Skip: 0,
Error: 0,
Warn: 0,
},
}},
}, {
config: ApplyCommandConfig{
PolicyPaths: []string{"../../../../test/cli/test-validating-admission-policy/check-deployment-labels/policy.yaml"},
ResourcePaths: []string{"../../../../test/cli/test-validating-admission-policy/check-deployment-labels/deployment2.yaml"},
PolicyReport: true,
},
{
config: ApplyCommandConfig{
PolicyPaths: []string{"https://github.com/kyverno/policies/best-practices/require-labels/", "../../../../test/best_practices/disallow_latest_tag.yaml"},
ResourcePaths: []string{"../../../../test/resources/pod_with_version_tag.yaml"},
GitBranch: "main",
PolicyReport: true,
},
expectedPolicyReports: []preport.PolicyReport{
{
Summary: preport.PolicyReportSummary{
Pass: 2,
Fail: 1,
Skip: 2,
Error: 0,
Warn: 0,
},
},
expectedPolicyReports: []policyreportv1alpha2.PolicyReport{{
Summary: policyreportv1alpha2.PolicyReportSummary{
Pass: 0,
Fail: 1,
Skip: 0,
Error: 0,
Warn: 0,
},
}},
}, {
config: ApplyCommandConfig{
PolicyPaths: []string{"https://github.com/kyverno/policies/best-practices/require-labels/", "../../../../test/best_practices/disallow_latest_tag.yaml"},
ResourcePaths: []string{"../../../../test/resources/pod_with_version_tag.yaml"},
GitBranch: "main",
PolicyReport: true,
},
{
// Same as the above test case but the policy paths are reordered
config: ApplyCommandConfig{
PolicyPaths: []string{"../../../../test/best_practices/disallow_latest_tag.yaml", "https://github.com/kyverno/policies/best-practices/require-labels/"},
ResourcePaths: []string{"../../../../test/resources/pod_with_version_tag.yaml"},
GitBranch: "main",
PolicyReport: true,
},
expectedPolicyReports: []preport.PolicyReport{
{
Summary: preport.PolicyReportSummary{
Pass: 2,
Fail: 1,
Skip: 2,
Error: 0,
Warn: 0,
},
},
expectedPolicyReports: []policyreportv1alpha2.PolicyReport{{
Summary: policyreportv1alpha2.PolicyReportSummary{
Pass: 2,
Fail: 1,
Skip: 2,
Error: 0,
Warn: 0,
},
}},
}, {
// Same as the above test case but the policy paths are reordered
config: ApplyCommandConfig{
PolicyPaths: []string{"../../../../test/best_practices/disallow_latest_tag.yaml", "https://github.com/kyverno/policies/best-practices/require-labels/"},
ResourcePaths: []string{"../../../../test/resources/pod_with_version_tag.yaml"},
GitBranch: "main",
PolicyReport: true,
},
expectedPolicyReports: []policyreportv1alpha2.PolicyReport{{
Summary: policyreportv1alpha2.PolicyReportSummary{
Pass: 2,
Fail: 1,
Skip: 2,
Error: 0,
Warn: 0,
},
}},
}}
compareSummary := func(expected policyreportv1alpha2.PolicyReportSummary, actual policyreportv1alpha2.PolicyReportSummary, desc string) {
assert.Equal(t, actual.Pass, expected.Pass, desc)
assert.Equal(t, actual.Fail, expected.Fail, desc)
assert.Equal(t, actual.Skip, expected.Skip, desc)
assert.Equal(t, actual.Warn, expected.Warn, desc)
assert.Equal(t, actual.Error, expected.Error, desc)
}
compareSummary := func(expected preport.PolicyReportSummary, actual preport.PolicyReportSummary, desc string) {
assert.Equal(t, int64(actual.Pass), int64(expected.Pass), desc)
assert.Equal(t, int64(actual.Fail), int64(expected.Fail), desc)
assert.Equal(t, int64(actual.Skip), int64(expected.Skip), desc)
assert.Equal(t, int64(actual.Warn), int64(expected.Warn), desc)
assert.Equal(t, int64(actual.Error), int64(expected.Error), desc)
}
verifyTestcase := func(t *testing.T, tc *TestCase, compareSummary func(preport.PolicyReportSummary, preport.PolicyReportSummary, string)) {
verifyTestcase := func(t *testing.T, tc *TestCase, compareSummary func(policyreportv1alpha2.PolicyReportSummary, policyreportv1alpha2.PolicyReportSummary, string)) {
if tc.stdinFile != "" {
oldStdin := os.Stdin
input, err := os.OpenFile(tc.stdinFile, os.O_RDONLY, 0)
@ -369,12 +318,16 @@ func Test_Apply(t *testing.T) {
}
defer func() { osExit = os.Exit }()
_, _, _, info, err := tc.config.applyCommandHelper()
_, _, _, responses, err := tc.config.applyCommandHelper()
assert.NilError(t, err, desc)
clustered, _ := buildPolicyReports(tc.config.AuditWarn, info...)
clustered, _ := reportutils.ComputePolicyReports(tc.config.AuditWarn, responses...)
assert.Assert(t, len(clustered) > 0, "policy reports should not be empty: %s", desc)
for i, resp := range clustered {
combined := []policyreportv1alpha2.ClusterPolicyReport{
reportutils.MergeClusterReports(clustered, nil),
}
assert.Equal(t, len(combined), len(tc.expectedPolicyReports))
for i, resp := range combined {
compareSummary(tc.expectedPolicyReports[i].Summary, resp.Summary, desc)
}
}

View file

@ -1,34 +0,0 @@
package apply
import (
policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
reportutils "github.com/kyverno/kyverno/pkg/utils/report"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func mergeClusterReport(
clustered []policyreportv1alpha2.ClusterPolicyReport,
namespaced []policyreportv1alpha2.PolicyReport,
) policyreportv1alpha2.ClusterPolicyReport {
var results []policyreportv1alpha2.PolicyReportResult
for _, report := range clustered {
results = append(results, report.Results...)
}
for _, report := range namespaced {
if report.GetNamespace() != "" {
continue
}
results = append(results, report.Results...)
}
return policyreportv1alpha2.ClusterPolicyReport{
TypeMeta: metav1.TypeMeta{
Kind: "ClusterPolicyReport",
APIVersion: policyreportv1alpha2.SchemeGroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: clusterpolicyreport,
},
Results: results,
Summary: reportutils.CalculateSummary(results),
}
}

View file

@ -1,130 +0,0 @@
package apply
import (
"reflect"
"testing"
policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
report "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
"gotest.tools/assert"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func Test_mergeClusterReport(t *testing.T) {
clustered := []policyreportv1alpha2.ClusterPolicyReport{
{
TypeMeta: metav1.TypeMeta{
Kind: "ClusterPolicyReport",
APIVersion: report.SchemeGroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "cpolr-4",
},
Results: []policyreportv1alpha2.PolicyReportResult{
{
Policy: "cpolr-4",
Result: report.StatusFail,
},
},
},
{
TypeMeta: metav1.TypeMeta{
Kind: "ClusterPolicyReport",
APIVersion: report.SchemeGroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "cpolr-5",
},
Results: []policyreportv1alpha2.PolicyReportResult{
{
Policy: "cpolr-5",
Result: report.StatusFail,
},
},
},
}
namespaced := []policyreportv1alpha2.PolicyReport{
{
TypeMeta: metav1.TypeMeta{
Kind: "PolicyReport",
APIVersion: report.SchemeGroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "ns-polr-1",
Namespace: "ns-polr",
},
Results: []policyreportv1alpha2.PolicyReportResult{
{
Policy: "ns-polr-1",
Result: report.StatusPass,
Resources: make([]corev1.ObjectReference, 10),
},
},
},
{
TypeMeta: metav1.TypeMeta{
Kind: "PolicyReport",
APIVersion: report.SchemeGroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "ns-polr-2",
},
Results: []policyreportv1alpha2.PolicyReportResult{
{
Policy: "ns-polr-2",
Result: report.StatusPass,
Resources: make([]corev1.ObjectReference, 5),
},
},
},
{
TypeMeta: metav1.TypeMeta{
Kind: "PolicyReport",
APIVersion: report.SchemeGroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "polr-3",
},
Results: []policyreportv1alpha2.PolicyReportResult{
{
Policy: "polr-3",
Result: report.StatusPass,
Resources: make([]corev1.ObjectReference, 1),
},
},
},
}
expectedResults := []policyreportv1alpha2.PolicyReportResult{
{
Policy: "cpolr-4",
Result: report.StatusFail,
},
{
Policy: "cpolr-5",
Result: report.StatusFail,
},
{
Policy: "ns-polr-2",
Result: report.StatusPass,
Resources: make([]corev1.ObjectReference, 5),
},
{
Policy: "polr-3",
Result: report.StatusPass,
Resources: make([]corev1.ObjectReference, 1),
},
}
cpolr := mergeClusterReport(clustered, namespaced)
assert.Assert(t, cpolr.APIVersion == report.SchemeGroupVersion.String(), cpolr.Kind)
assert.Assert(t, cpolr.Kind == "ClusterPolicyReport", cpolr.Kind)
assert.Assert(t, reflect.DeepEqual(cpolr.Results, expectedResults), cpolr.Results)
assert.Assert(t, cpolr.Summary.Pass == 2, cpolr.Summary.Pass)
assert.Assert(t, cpolr.Summary.Fail == 2, cpolr.Summary.Fail)
}

View file

@ -1,153 +0,0 @@
package apply
import (
"encoding/json"
"testing"
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
preport "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"gotest.tools/assert"
)
var rawPolicy = []byte(`
{
"apiVersion": "kyverno.io/v1",
"kind": "ClusterPolicy",
"metadata": {
"name": "pod-requirements",
"annotations": {
"pod-policies.kyverno.io/autogen-controllers": "none",
"policies.kyverno.io/severity": "medium",
"policies.kyverno.io/category": "Pod Security Standards (Restricted)"
}
},
"spec": {
"background": false,
"validationFailureAction": "audit",
"rules": [
{
"name": "pods-require-account",
"match": {
"resources": {
"kinds": [
"Pod"
]
}
},
"validate": {
"message": "User pods must include an account for charging",
"pattern": {
"metadata": {
"labels": {
"account": "*?"
}
}
}
}
},
{
"name": "pods-require-limits",
"match": {
"resources": {
"kinds": [
"Pod"
]
}
},
"validate": {
"message": "CPU and memory resource requests and limits are required for user pods",
"pattern": {
"spec": {
"containers": [
{
"resources": {
"requests": {
"memory": "?*",
"cpu": "?*"
},
"limits": {
"memory": "?*",
"cpu": "?*"
}
}
}
]
}
}
}
}
]
}
}
`)
func Test_buildPolicyReports(t *testing.T) {
var policy kyverno.ClusterPolicy
err := json.Unmarshal(rawPolicy, &policy)
assert.NilError(t, err)
er := engineapi.EngineResponse{}
er = er.WithPolicy(engineapi.NewKyvernoPolicy(&policy))
er.PolicyResponse.Add(
engineapi.ExecutionStats{},
*engineapi.RuleFail(
"pods-require-account",
engineapi.Validation,
"validation error: User pods must include an account for charging. Rule pods-require-account failed at path /metadata/labels/",
),
*engineapi.RulePass(
"pods-require-limits",
engineapi.Validation,
"validation rule 'pods-require-limits' passed.",
),
)
clustered, namespaced := buildPolicyReports(false, er)
assert.Assert(t, len(clustered) == 1, len(clustered))
assert.Assert(t, len(namespaced) == 0, len(namespaced))
{
report := clustered[0]
assert.Assert(t, report.GetName() == clusterpolicyreport)
assert.Assert(t, report.Kind == "ClusterPolicyReport")
assert.Assert(t, len(report.Results) == 2)
assert.Equal(t, string(report.Results[0].Severity), "medium")
assert.Equal(t, report.Results[0].Category, "Pod Security Standards (Restricted)")
assert.Assert(t, report.Summary.Pass == 1, report.Summary.Pass)
}
}
func Test_buildPolicyResults(t *testing.T) {
var policy kyverno.ClusterPolicy
err := json.Unmarshal(rawPolicy, &policy)
assert.NilError(t, err)
er := engineapi.EngineResponse{}
er = er.WithPolicy(engineapi.NewKyvernoPolicy(&policy))
er.PolicyResponse.Add(
engineapi.ExecutionStats{}, *engineapi.RuleFail(
"pods-require-account",
engineapi.Validation,
"validation error: User pods must include an account for charging. Rule pods-require-account failed at path /metadata/labels/",
),
*engineapi.RulePass(
"pods-require-limits",
engineapi.Validation,
"validation rule 'pods-require-limits' passed.",
),
)
results := buildPolicyResults(false, er)
for _, result := range results {
assert.Assert(t, len(result) == 2, len(result))
for _, r := range result {
switch r.Rule {
case "pods-require-limits":
assert.Assert(t, r.Result == preport.StatusPass)
case "pods-require-account":
assert.Assert(t, r.Result == preport.StatusFail)
}
}
}
}

View file

@ -77,31 +77,31 @@ func TestSeverity(t *testing.T) {
}, {
name: "critical",
annotations: map[string]string{
kyverno.AnnotationPolicySeverity: policyreportv1alpha2.SeverityCritical,
kyverno.AnnotationPolicySeverity: "critical",
},
want: policyreportv1alpha2.SeverityCritical,
}, {
name: "high",
annotations: map[string]string{
kyverno.AnnotationPolicySeverity: policyreportv1alpha2.SeverityHigh,
kyverno.AnnotationPolicySeverity: "high",
},
want: policyreportv1alpha2.SeverityHigh,
}, {
name: "medium",
annotations: map[string]string{
kyverno.AnnotationPolicySeverity: policyreportv1alpha2.SeverityMedium,
kyverno.AnnotationPolicySeverity: "medium",
},
want: policyreportv1alpha2.SeverityMedium,
}, {
name: "low",
annotations: map[string]string{
kyverno.AnnotationPolicySeverity: policyreportv1alpha2.SeverityLow,
kyverno.AnnotationPolicySeverity: "low",
},
want: policyreportv1alpha2.SeverityLow,
}, {
name: "info",
annotations: map[string]string{
kyverno.AnnotationPolicySeverity: policyreportv1alpha2.SeverityInfo,
kyverno.AnnotationPolicySeverity: "info",
},
want: policyreportv1alpha2.SeverityInfo,
}, {

View file

@ -1,10 +1,6 @@
package apply
package report
import (
"fmt"
"strings"
"time"
"github.com/kyverno/kyverno/api/kyverno"
policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
annotationsutils "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/annotations"
@ -14,71 +10,25 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
const clusterpolicyreport = "clusterpolicyreport"
// resps is the engine responses generated for a single policy
func buildPolicyReports(auditWarn bool, engineResponses ...engineapi.EngineResponse) ([]policyreportv1alpha2.ClusterPolicyReport, []policyreportv1alpha2.PolicyReport) {
var clustered []policyreportv1alpha2.ClusterPolicyReport
var namespaced []policyreportv1alpha2.PolicyReport
resultsMap := buildPolicyResults(auditWarn, engineResponses...)
for scope, result := range resultsMap {
if scope == clusterpolicyreport {
report := policyreportv1alpha2.ClusterPolicyReport{
TypeMeta: metav1.TypeMeta{
APIVersion: policyreportv1alpha2.SchemeGroupVersion.String(),
Kind: "ClusterPolicyReport",
},
Results: result,
Summary: reportutils.CalculateSummary(result),
}
report.SetName(scope)
clustered = append(clustered, report)
} else {
report := policyreportv1alpha2.PolicyReport{
TypeMeta: metav1.TypeMeta{
APIVersion: policyreportv1alpha2.SchemeGroupVersion.String(),
Kind: "PolicyReport",
},
Results: result,
Summary: reportutils.CalculateSummary(result),
}
policyNamespace := strings.ReplaceAll(scope, "policyreport-ns-", "")
report.SetName(scope)
report.SetNamespace(policyNamespace)
namespaced = append(namespaced, report)
}
}
return clustered, namespaced
}
// buildPolicyResults returns a string-PolicyReportResult map
// the key of the map is one of "clusterpolicyreport", "policyreport-ns-<namespace>"
func buildPolicyResults(auditWarn bool, engineResponses ...engineapi.EngineResponse) map[string][]policyreportv1alpha2.PolicyReportResult {
results := make(map[string][]policyreportv1alpha2.PolicyReportResult)
now := metav1.Timestamp{Seconds: time.Now().Unix()}
func ComputePolicyReportResultsPerPolicy(auditWarn bool, engineResponses ...engineapi.EngineResponse) map[engineapi.GenericPolicy][]policyreportv1alpha2.PolicyReportResult {
results := make(map[engineapi.GenericPolicy][]policyreportv1alpha2.PolicyReportResult)
for _, engineResponse := range engineResponses {
if len(engineResponse.PolicyResponse.Rules) == 0 {
continue
}
policy := engineResponse.Policy()
policyName := policy.GetName()
policyNamespace := policy.GetNamespace()
audit := engineResponse.GetValidationFailureAction().Audit()
scored := annotationsutils.Scored(policy.GetAnnotations())
category := annotationsutils.Category(policy.GetAnnotations())
severity := annotationsutils.Severity(policy.GetAnnotations())
var appname string
if policyNamespace != "" {
appname = fmt.Sprintf("policyreport-ns-%s", policyNamespace)
} else {
appname = clusterpolicyreport
}
for _, ruleResponse := range engineResponse.PolicyResponse.Rules {
// TODO only validation is managed here ?
if ruleResponse.RuleType() != engineapi.Validation {
continue
}
result := policyreportv1alpha2.PolicyReportResult{
// TODO policy name looks wrong, it should consider the namespace too
Policy: policyName,
Resources: []corev1.ObjectReference{
{
@ -89,11 +39,10 @@ func buildPolicyResults(auditWarn bool, engineResponses ...engineapi.EngineRespo
UID: engineResponse.Resource.GetUID(),
},
},
Scored: true,
Scored: scored,
Category: category,
Severity: severity,
}
if ruleResponse.Status() == engineapi.RuleStatusSkip {
result.Result = policyreportv1alpha2.StatusSkip
} else if ruleResponse.Status() == engineapi.RuleStatusError {
@ -101,25 +50,80 @@ func buildPolicyResults(auditWarn bool, engineResponses ...engineapi.EngineRespo
} else if ruleResponse.Status() == engineapi.RuleStatusPass {
result.Result = policyreportv1alpha2.StatusPass
} else if ruleResponse.Status() == engineapi.RuleStatusFail {
if !scored {
result.Result = policyreportv1alpha2.StatusWarn
} else if auditWarn && engineResponse.GetValidationFailureAction().Audit() {
if !scored || (audit && auditWarn) {
result.Result = policyreportv1alpha2.StatusWarn
} else {
result.Result = policyreportv1alpha2.StatusFail
}
} else {
fmt.Println(ruleResponse)
result.Result = policyreportv1alpha2.StatusError
}
if policy.GetType() == engineapi.KyvernoPolicyType {
result.Rule = ruleResponse.Name()
}
result.Message = ruleResponse.Message()
result.Source = kyverno.ValueKyvernoApp
result.Timestamp = now
results[appname] = append(results[appname], result)
result.Timestamp = metav1.Timestamp{Seconds: ruleResponse.Stats().Timestamp()}
results[policy] = append(results[policy], result)
}
}
return results
}
func ComputePolicyReports(auditWarn bool, engineResponses ...engineapi.EngineResponse) ([]policyreportv1alpha2.ClusterPolicyReport, []policyreportv1alpha2.PolicyReport) {
var clustered []policyreportv1alpha2.ClusterPolicyReport
var namespaced []policyreportv1alpha2.PolicyReport
perPolicyResults := ComputePolicyReportResultsPerPolicy(auditWarn, engineResponses...)
for policy, results := range perPolicyResults {
if policy.GetNamespace() == "" {
report := policyreportv1alpha2.ClusterPolicyReport{
TypeMeta: metav1.TypeMeta{
APIVersion: policyreportv1alpha2.SchemeGroupVersion.String(),
Kind: "ClusterPolicyReport",
},
Results: results,
Summary: reportutils.CalculateSummary(results),
}
report.SetName(policy.GetName())
clustered = append(clustered, report)
} else {
report := policyreportv1alpha2.PolicyReport{
TypeMeta: metav1.TypeMeta{
APIVersion: policyreportv1alpha2.SchemeGroupVersion.String(),
Kind: "PolicyReport",
},
Results: results,
Summary: reportutils.CalculateSummary(results),
}
report.SetName(policy.GetName())
report.SetNamespace(policy.GetNamespace())
namespaced = append(namespaced, report)
}
}
return clustered, namespaced
}
func MergeClusterReports(clustered []policyreportv1alpha2.ClusterPolicyReport, namespaced []policyreportv1alpha2.PolicyReport) policyreportv1alpha2.ClusterPolicyReport {
var results []policyreportv1alpha2.PolicyReportResult
for _, report := range clustered {
results = append(results, report.Results...)
}
// TODO why this ?
for _, report := range namespaced {
if report.GetNamespace() != "" {
continue
}
results = append(results, report.Results...)
}
return policyreportv1alpha2.ClusterPolicyReport{
TypeMeta: metav1.TypeMeta{
Kind: "ClusterPolicyReport",
APIVersion: policyreportv1alpha2.SchemeGroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "merged",
},
Results: results,
Summary: reportutils.CalculateSummary(results),
}
}

View file

@ -0,0 +1,251 @@
package report
import (
"encoding/json"
"testing"
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
report "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"gotest.tools/assert"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
var rawPolicy = []byte(`
{
"apiVersion": "kyverno.io/v1",
"kind": "ClusterPolicy",
"metadata": {
"name": "pod-requirements",
"annotations": {
"pod-policies.kyverno.io/autogen-controllers": "none",
"policies.kyverno.io/severity": "medium",
"policies.kyverno.io/category": "Pod Security Standards (Restricted)"
}
},
"spec": {
"background": false,
"validationFailureAction": "audit",
"rules": [
{
"name": "pods-require-account",
"match": {
"resources": {
"kinds": [
"Pod"
]
}
},
"validate": {
"message": "User pods must include an account for charging",
"pattern": {
"metadata": {
"labels": {
"account": "*?"
}
}
}
}
},
{
"name": "pods-require-limits",
"match": {
"resources": {
"kinds": [
"Pod"
]
}
},
"validate": {
"message": "CPU and memory resource requests and limits are required for user pods",
"pattern": {
"spec": {
"containers": [
{
"resources": {
"requests": {
"memory": "?*",
"cpu": "?*"
},
"limits": {
"memory": "?*",
"cpu": "?*"
}
}
}
]
}
}
}
}
]
}
}
`)
func TestComputePolicyReports(t *testing.T) {
var policy kyverno.ClusterPolicy
err := json.Unmarshal(rawPolicy, &policy)
assert.NilError(t, err)
er := engineapi.EngineResponse{}
er = er.WithPolicy(engineapi.NewKyvernoPolicy(&policy))
er.PolicyResponse.Add(
engineapi.ExecutionStats{},
*engineapi.RuleFail(
"pods-require-account",
engineapi.Validation,
"validation error: User pods must include an account for charging. Rule pods-require-account failed at path /metadata/labels/",
),
*engineapi.RulePass(
"pods-require-limits",
engineapi.Validation,
"validation rule 'pods-require-limits' passed.",
),
)
clustered, namespaced := ComputePolicyReports(false, er)
assert.Equal(t, len(clustered), 1)
assert.Equal(t, len(namespaced), 0)
{
report := clustered[0]
assert.Equal(t, report.GetName(), policy.GetName())
assert.Equal(t, report.Kind, "ClusterPolicyReport")
assert.Equal(t, len(report.Results), 2)
assert.Equal(t, report.Results[0].Severity, policyreportv1alpha2.SeverityMedium)
assert.Equal(t, report.Results[0].Category, "Pod Security Standards (Restricted)")
assert.Equal(t, report.Summary.Pass, 1)
}
}
func TestComputePolicyReportResultsPerPolicy(t *testing.T) {
var policy kyverno.ClusterPolicy
err := json.Unmarshal(rawPolicy, &policy)
assert.NilError(t, err)
er := engineapi.EngineResponse{}
er = er.WithPolicy(engineapi.NewKyvernoPolicy(&policy))
er.PolicyResponse.Add(
engineapi.ExecutionStats{}, *engineapi.RuleFail(
"pods-require-account",
engineapi.Validation,
"validation error: User pods must include an account for charging. Rule pods-require-account failed at path /metadata/labels/",
),
*engineapi.RulePass(
"pods-require-limits",
engineapi.Validation,
"validation rule 'pods-require-limits' passed.",
),
)
results := ComputePolicyReportResultsPerPolicy(false, er)
for _, result := range results {
assert.Equal(t, len(result), 2)
for _, r := range result {
switch r.Rule {
case "pods-require-limits":
assert.Equal(t, r.Result, policyreportv1alpha2.StatusPass)
case "pods-require-account":
assert.Equal(t, r.Result, policyreportv1alpha2.StatusFail)
}
}
}
}
func TestMergeClusterReport(t *testing.T) {
clustered := []policyreportv1alpha2.ClusterPolicyReport{{
TypeMeta: metav1.TypeMeta{
Kind: "ClusterPolicyReport",
APIVersion: report.SchemeGroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "cpolr-4",
},
Results: []policyreportv1alpha2.PolicyReportResult{
{
Policy: "cpolr-4",
Result: report.StatusFail,
},
},
}, {
TypeMeta: metav1.TypeMeta{
Kind: "ClusterPolicyReport",
APIVersion: report.SchemeGroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "cpolr-5",
},
Results: []policyreportv1alpha2.PolicyReportResult{
{
Policy: "cpolr-5",
Result: report.StatusFail,
},
},
}}
namespaced := []policyreportv1alpha2.PolicyReport{{
TypeMeta: metav1.TypeMeta{
Kind: "PolicyReport",
APIVersion: report.SchemeGroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "ns-polr-1",
Namespace: "ns-polr",
},
Results: []policyreportv1alpha2.PolicyReportResult{
{
Policy: "ns-polr-1",
Result: report.StatusPass,
Resources: make([]corev1.ObjectReference, 10),
},
},
}, {
TypeMeta: metav1.TypeMeta{
Kind: "PolicyReport",
APIVersion: report.SchemeGroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "ns-polr-2",
},
Results: []policyreportv1alpha2.PolicyReportResult{
{
Policy: "ns-polr-2",
Result: report.StatusPass,
Resources: make([]corev1.ObjectReference, 5),
},
},
}, {
TypeMeta: metav1.TypeMeta{
Kind: "PolicyReport",
APIVersion: report.SchemeGroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: "polr-3",
},
Results: []policyreportv1alpha2.PolicyReportResult{
{
Policy: "polr-3",
Result: report.StatusPass,
Resources: make([]corev1.ObjectReference, 1),
},
},
}}
expectedResults := []policyreportv1alpha2.PolicyReportResult{{
Policy: "cpolr-4",
Result: report.StatusFail,
}, {
Policy: "cpolr-5",
Result: report.StatusFail,
}, {
Policy: "ns-polr-2",
Result: report.StatusPass,
Resources: make([]corev1.ObjectReference, 5),
}, {
Policy: "polr-3",
Result: report.StatusPass,
Resources: make([]corev1.ObjectReference, 1),
}}
cpolr := MergeClusterReports(clustered, namespaced)
assert.Equal(t, cpolr.APIVersion, report.SchemeGroupVersion.String())
assert.Equal(t, cpolr.Kind, "ClusterPolicyReport")
assert.DeepEqual(t, cpolr.Results, expectedResults)
assert.Equal(t, cpolr.Summary.Pass, 2)
assert.Equal(t, cpolr.Summary.Fail, 2)
}

View file

@ -34,28 +34,28 @@ type KyvernoPolicy struct {
policy kyvernov1.PolicyInterface
}
func (p KyvernoPolicy) GetPolicy() interface{} {
func (p *KyvernoPolicy) GetPolicy() interface{} {
return p.policy
}
func (p KyvernoPolicy) GetType() PolicyType {
func (p *KyvernoPolicy) GetType() PolicyType {
return KyvernoPolicyType
}
func (p KyvernoPolicy) GetName() string {
func (p *KyvernoPolicy) GetName() string {
return p.policy.GetName()
}
func (p KyvernoPolicy) GetNamespace() string {
func (p *KyvernoPolicy) GetNamespace() string {
return p.policy.GetNamespace()
}
func (p KyvernoPolicy) GetAnnotations() map[string]string {
func (p *KyvernoPolicy) GetAnnotations() map[string]string {
return p.policy.GetAnnotations()
}
func NewKyvernoPolicy(pol kyvernov1.PolicyInterface) KyvernoPolicy {
return KyvernoPolicy{
func NewKyvernoPolicy(pol kyvernov1.PolicyInterface) GenericPolicy {
return &KyvernoPolicy{
policy: pol,
}
}
@ -64,28 +64,28 @@ type ValidatingAdmissionPolicy struct {
policy v1alpha1.ValidatingAdmissionPolicy
}
func (p ValidatingAdmissionPolicy) GetPolicy() interface{} {
func (p *ValidatingAdmissionPolicy) GetPolicy() interface{} {
return p.policy
}
func (p ValidatingAdmissionPolicy) GetType() PolicyType {
func (p *ValidatingAdmissionPolicy) GetType() PolicyType {
return ValidatingAdmissionPolicyType
}
func (p ValidatingAdmissionPolicy) GetName() string {
func (p *ValidatingAdmissionPolicy) GetName() string {
return p.policy.GetName()
}
func (p ValidatingAdmissionPolicy) GetNamespace() string {
func (p *ValidatingAdmissionPolicy) GetNamespace() string {
return p.policy.GetNamespace()
}
func (p ValidatingAdmissionPolicy) GetAnnotations() map[string]string {
func (p *ValidatingAdmissionPolicy) GetAnnotations() map[string]string {
return p.policy.GetAnnotations()
}
func NewValidatingAdmissionPolicy(pol v1alpha1.ValidatingAdmissionPolicy) ValidatingAdmissionPolicy {
return ValidatingAdmissionPolicy{
func NewValidatingAdmissionPolicy(pol v1alpha1.ValidatingAdmissionPolicy) GenericPolicy {
return &ValidatingAdmissionPolicy{
policy: pol,
}
}

View file

@ -38,7 +38,7 @@ func SortReportResults(results []policyreportv1alpha2.PolicyReportResult) {
func CalculateSummary(results []policyreportv1alpha2.PolicyReportResult) (summary policyreportv1alpha2.PolicyReportSummary) {
for _, res := range results {
switch string(res.Result) {
switch res.Result {
case policyreportv1alpha2.StatusPass:
summary.Pass++
case policyreportv1alpha2.StatusFail:
@ -72,15 +72,15 @@ func toPolicyResult(status engineapi.RuleStatus) policyreportv1alpha2.PolicyResu
func SeverityFromString(severity string) policyreportv1alpha2.PolicySeverity {
switch severity {
case policyreportv1alpha2.SeverityCritical:
case "critical":
return policyreportv1alpha2.SeverityCritical
case policyreportv1alpha2.SeverityHigh:
case "high":
return policyreportv1alpha2.SeverityHigh
case policyreportv1alpha2.SeverityMedium:
case "medium":
return policyreportv1alpha2.SeverityMedium
case policyreportv1alpha2.SeverityLow:
case "low":
return policyreportv1alpha2.SeverityLow
case policyreportv1alpha2.SeverityInfo:
case "info":
return policyreportv1alpha2.SeverityInfo
}
return ""