Files
trivy/pkg/k8s/report/report_test.go
2022-07-09 19:40:31 +03:00

257 lines
7.3 KiB
Go

package report
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/aquasecurity/trivy/pkg/flag"
"github.com/aquasecurity/trivy/pkg/types"
)
var (
deployOrionWithMisconfigs = Resource{
Namespace: "default",
Kind: "Deploy",
Name: "orion",
Results: types.Results{
{Misconfigurations: []types.DetectedMisconfiguration{{ID: "ID100", Status: types.StatusFailure}}},
},
}
deployOrionWithVulns = Resource{
Namespace: "default",
Kind: "Deploy",
Name: "orion",
Results: types.Results{
{Vulnerabilities: []types.DetectedVulnerability{{VulnerabilityID: "CVE-2020-8888"}}},
},
}
deployOrionWithBothVulnsAndMisconfigs = Resource{
Namespace: "default",
Kind: "Deploy",
Name: "orion",
Results: types.Results{
{Misconfigurations: []types.DetectedMisconfiguration{{ID: "ID100", Status: types.StatusFailure}}},
{Vulnerabilities: []types.DetectedVulnerability{{VulnerabilityID: "CVE-2020-8888"}}},
},
}
cronjobHelloWithVulns = Resource{
Namespace: "default",
Kind: "Cronjob",
Name: "hello",
Results: types.Results{
{Vulnerabilities: []types.DetectedVulnerability{{VulnerabilityID: "CVE-2020-9999"}}},
},
}
podPrometheusWithMisconfigs = Resource{
Namespace: "default",
Kind: "Pod",
Name: "prometheus",
Results: types.Results{
{Misconfigurations: []types.DetectedMisconfiguration{{ID: "ID100"}}},
},
}
)
func TestReport_consolidate(t *testing.T) {
tests := []struct {
name string
report Report
expectedFindings map[string]Resource
}{
{
name: "report with both misconfigs and vulnerabilities",
report: Report{
Vulnerabilities: []Resource{deployOrionWithVulns, cronjobHelloWithVulns},
Misconfigurations: []Resource{deployOrionWithMisconfigs, podPrometheusWithMisconfigs},
},
expectedFindings: map[string]Resource{
"default/deploy/orion": deployOrionWithBothVulnsAndMisconfigs,
"default/cronjob/hello": cronjobHelloWithVulns,
"default/pod/prometheus": podPrometheusWithMisconfigs,
},
},
{
name: "report with only misconfigurations",
report: Report{
Misconfigurations: []Resource{deployOrionWithMisconfigs, podPrometheusWithMisconfigs},
},
expectedFindings: map[string]Resource{
"default/deploy/orion": deployOrionWithMisconfigs,
"default/pod/prometheus": podPrometheusWithMisconfigs,
},
},
{
name: "report with only vulnerabilities",
report: Report{
Vulnerabilities: []Resource{deployOrionWithVulns, cronjobHelloWithVulns},
},
expectedFindings: map[string]Resource{
"default/deploy/orion": deployOrionWithVulns,
"default/cronjob/hello": cronjobHelloWithVulns,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
consolidateReport := tt.report.consolidate()
for _, f := range consolidateReport.Findings {
key := f.fullname()
expected, found := tt.expectedFindings[key]
if !found {
t.Errorf("key not found: %s", key)
}
assert.Equal(t, expected, f)
}
})
}
}
func TestResource_fullname(t *testing.T) {
tests := []struct {
expected string
resource Resource
}{
{"default/deploy/orion", deployOrionWithBothVulnsAndMisconfigs},
{"default/deploy/orion", deployOrionWithMisconfigs},
{"default/cronjob/hello", cronjobHelloWithVulns},
{"default/pod/prometheus", podPrometheusWithMisconfigs},
}
for _, tt := range tests {
t.Run(tt.expected, func(t *testing.T) {
assert.Equal(t, tt.expected, tt.resource.fullname())
})
}
}
func TestResourceFailed(t *testing.T) {
tests := []struct {
name string
report Report
expected bool
}{
{
name: "report with both misconfigs and vulnerabilities",
report: Report{
Vulnerabilities: []Resource{deployOrionWithVulns, cronjobHelloWithVulns},
Misconfigurations: []Resource{deployOrionWithMisconfigs, podPrometheusWithMisconfigs},
},
expected: true,
},
{
name: "report with only misconfigurations",
report: Report{
Misconfigurations: []Resource{deployOrionWithMisconfigs, podPrometheusWithMisconfigs},
},
expected: true,
},
{
name: "report with only vulnerabilities",
report: Report{
Vulnerabilities: []Resource{deployOrionWithVulns, cronjobHelloWithVulns},
},
expected: true,
},
{
name: "report without vulnerabilities and misconfigurations",
report: Report{},
expected: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.expected, tt.report.Failed())
})
}
}
func Test_rbacResource(t *testing.T) {
tests := []struct {
name string
misConfig Resource
want bool
}{
{
name: "rbac Role resources",
misConfig: Resource{Kind: "Role"},
want: true,
},
{
name: "rbac ClusterRole resources",
misConfig: Resource{Kind: "ClusterRole"},
want: true,
},
{
name: "rbac RoleBinding resources",
misConfig: Resource{Kind: "RoleBinding"},
want: true,
},
{
name: "rbac ClusterRoleBinding resources",
misConfig: Resource{Kind: "ClusterRoleBinding"},
want: true,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
got := rbacResource(test.misConfig)
assert.Equal(t, test.want, got)
})
}
}
func Test_separateMisConfigRoleAssessment(t *testing.T) {
tests := []struct {
name string
k8sReport Report
opts flag.ScanOptions
wantRbacReport Report
wantMisConfigReport Report
}{
{
name: "Role and Deployment Reports",
k8sReport: Report{Misconfigurations: []Resource{{Kind: "Role"}, {Kind: "Deployment"}}},
opts: flag.ScanOptions{SecurityChecks: []string{"config", "rbac"}},
wantRbacReport: Report{Misconfigurations: []Resource{{Kind: "Role"}}},
wantMisConfigReport: Report{Misconfigurations: []Resource{{Kind: "Deployment"}}},
},
{
name: "Role Report Only",
k8sReport: Report{Misconfigurations: []Resource{{Kind: "Role"}, {Kind: "Deployment"}}},
opts: flag.ScanOptions{SecurityChecks: []string{"rbac"}},
wantRbacReport: Report{Misconfigurations: []Resource{{Kind: "Role"}}},
wantMisConfigReport: Report{Misconfigurations: []Resource{}},
},
{
name: "Deployment Report Only",
k8sReport: Report{Misconfigurations: []Resource{{Kind: "Role"}, {Kind: "Deployment"}}},
opts: flag.ScanOptions{SecurityChecks: []string{"config"}},
wantRbacReport: Report{Misconfigurations: []Resource{}},
wantMisConfigReport: Report{Misconfigurations: []Resource{{Kind: "Deployment"}}},
},
{
name: "No Deployment & No Role Reports",
k8sReport: Report{Misconfigurations: []Resource{{Kind: "Role"}, {Kind: "Deployment"}}},
opts: flag.ScanOptions{SecurityChecks: []string{"vuln"}},
wantRbacReport: Report{Misconfigurations: []Resource{}},
wantMisConfigReport: Report{Misconfigurations: []Resource{}},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
misConfig, rbac := separateMisConfigRoleAssessment(tt.k8sReport, tt.opts.SecurityChecks)
assert.Equal(t, len(tt.wantMisConfigReport.Misconfigurations), len(misConfig.Misconfigurations))
assert.Equal(t, len(tt.wantRbacReport.Misconfigurations), len(rbac.Misconfigurations))
})
}
}