Skip to content
This repository has been archived by the owner on Oct 30, 2024. It is now read-only.

Commit

Permalink
refactors sarif test (#469)
Browse files Browse the repository at this point in the history
* removes fixtures - favors static report objects
* Undo breaking changes
Co-authored-by: Genevieve Luyt <[email protected]>
  • Loading branch information
dani-santos-code authored Aug 24, 2022
1 parent 7bb32c2 commit e9fce13
Show file tree
Hide file tree
Showing 10 changed files with 64 additions and 125 deletions.
7 changes: 0 additions & 7 deletions internal/sarif/fixtures/apparmor-invalid.yaml

This file was deleted.

11 changes: 0 additions & 11 deletions internal/sarif/fixtures/apparmor-valid.yaml

This file was deleted.

21 changes: 0 additions & 21 deletions internal/sarif/fixtures/capabilities-added.yaml

This file was deleted.

16 changes: 0 additions & 16 deletions internal/sarif/fixtures/image-tag-present.yaml

This file was deleted.

8 changes: 0 additions & 8 deletions internal/sarif/fixtures/limits-nil.yaml

This file was deleted.

94 changes: 46 additions & 48 deletions internal/sarif/sarif_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package sarif

import (
"os"
"path/filepath"
"testing"

"github.com/Shopify/kubeaudit"
Expand All @@ -15,66 +13,82 @@ import (
)

func TestCreateWithResults(t *testing.T) {
capabilitiesAuditable := capabilities.New(capabilities.Config{})
apparmorAuditable := apparmor.New()
imageAuditable := image.New(image.Config{Image: "scratch:1.5"})
limitsAuditable, _ := limits.New(limits.Config{})

cases := []struct {
file string
auditors []kubeaudit.Auditable
description string
auditResults []*kubeaudit.AuditResult
expectedRule string
expectedErrorLevel string
expectedMessage string
expectedURI string
expectedFilePath string
}{
{
"apparmor-invalid.yaml",
[]kubeaudit.Auditable{apparmorAuditable},
"apparmor invalid",
[]*kubeaudit.AuditResult{{
Auditor: apparmor.Name,
Rule: apparmor.AppArmorInvalidAnnotation,
Severity: kubeaudit.Error,
Message: "AppArmor annotation key refers to a container that doesn't exist",
FilePath: "apparmorPath",
}},
apparmor.AppArmorInvalidAnnotation,
"error",
"AppArmor annotation key refers to a container that doesn't exist",
"https://github.com/Shopify/kubeaudit/blob/main/docs/auditors/apparmor.md",
"apparmorPath",
},
{
"capabilities-added.yaml",
[]kubeaudit.Auditable{capabilitiesAuditable},
"capabilities added",
[]*kubeaudit.AuditResult{{
Auditor: capabilities.Name,
Rule: capabilities.CapabilityAdded,
Severity: kubeaudit.Error,
Message: "It should be removed from the capability add list",
FilePath: "capsPath",
}},
capabilities.CapabilityAdded,
"error",
"It should be removed from the capability add list",
"https://github.com/Shopify/kubeaudit/blob/main/docs/auditors/capabilities.md",
"capsPath",
},
{
"image-tag-present.yaml",
[]kubeaudit.Auditable{imageAuditable},
"image tag is present",
[]*kubeaudit.AuditResult{{
Auditor: image.Name,
Rule: image.ImageCorrect,
Severity: kubeaudit.Info,
Message: "Image tag is correct",
FilePath: "imagePath",
}},
image.ImageCorrect,
"note",
"Image tag is correct",
"https://github.com/Shopify/kubeaudit/blob/main/docs/auditors/image.md",
"imagePath",
},
{
"limits-nil.yaml",
[]kubeaudit.Auditable{limitsAuditable},
"limits is nil",
[]*kubeaudit.AuditResult{{
Auditor: limits.Name,
Rule: limits.LimitsNotSet,
Severity: kubeaudit.Warn,
Message: "Resource limits not set",
FilePath: "limitsPath",
}},
limits.LimitsNotSet,
"warning",
"Resource limits not set",
"https://github.com/Shopify/kubeaudit/blob/main/docs/auditors/limits.md",
"limitsPath",
},
}

for _, tc := range cases {
t.Run(tc.file, func(t *testing.T) {
fixture := filepath.Join("fixtures", tc.file)
auditor, err := kubeaudit.New(tc.auditors)
require.NoError(t, err)

manifest, openErr := os.Open(fixture)
require.NoError(t, openErr)

defer manifest.Close()

kubeAuditReport, err := auditor.AuditManifest(fixture, manifest)
require.NoError(t, err)
t.Run(tc.description, func(t *testing.T) {
kubeAuditReport := kubeaudit.NewReport([]kubeaudit.Result{&kubeaudit.WorkloadResult{
AuditResults: tc.auditResults,
}})

sarifReport, err := Create(kubeAuditReport)
require.NoError(t, err)
Expand All @@ -87,7 +101,7 @@ func TestCreateWithResults(t *testing.T) {

var ruleNames []string

// check for rules occurrences
//check for rules occurrences
for _, sarifRule := range sarifReport.Runs[0].Tool.Driver.Rules {
assert.Equal(t, []string{
"security",
Expand All @@ -106,32 +120,16 @@ func TestCreateWithResults(t *testing.T) {
assert.Contains(t, ruleNames, *sarifResult.RuleID)
assert.Equal(t, tc.expectedErrorLevel, *sarifResult.Level)
assert.Contains(t, *sarifResult.Message.Text, tc.expectedMessage)
assert.Contains(t, "sarif/fixtures/"+tc.file, *sarifResult.Locations[0].PhysicalLocation.ArtifactLocation.URI)
assert.Contains(t, tc.expectedFilePath, *sarifResult.Locations[0].PhysicalLocation.ArtifactLocation.URI)
}
})
}
}

func TestCreateWithNoResults(t *testing.T) {
apparmorAuditable := apparmor.New()

fixture := filepath.Join("fixtures", "apparmor-valid.yaml")
auditor, err := kubeaudit.New([]kubeaudit.Auditable{apparmorAuditable})
sarifReport, err := Create(&kubeaudit.Report{})
require.NoError(t, err)

manifest, openErr := os.Open(fixture)
require.NoError(t, openErr)

defer manifest.Close()

kubeAuditReport, err := auditor.AuditManifest(fixture, manifest)
require.NoError(t, err)

sarifReport, err := Create(kubeAuditReport)
require.NoError(t, err)

require.NotEmpty(t, *sarifReport.Runs[0])

// verify that the rules are only added as per report findings
assert.Len(t, sarifReport.Runs[0].Tool.Driver.Rules, 0)
}
20 changes: 12 additions & 8 deletions kubeaudit.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ func (a *Kubeaudit) AuditManifest(manifestPath string, manifest io.Reader) (*Rep
}
}

report := &Report{results: results}
report := NewReport(results)

return report, nil
}
Expand All @@ -193,7 +193,7 @@ func (a *Kubeaudit) AuditCluster(options AuditOptions) (*Report, error) {
return nil, err
}

report := &Report{results: results}
report := NewReport(results)

return report, nil
}
Expand All @@ -216,7 +216,7 @@ func (a *Kubeaudit) AuditLocal(configpath string, context string, options AuditO
return nil, err
}

report := &Report{results: results}
report := NewReport(results)

return report, nil
}
Expand All @@ -226,6 +226,10 @@ type Report struct {
results []Result
}

func NewReport(results []Result) *Report {
return &Report{results}
}

// RawResults returns all of the results for each Kubernetes resource, including ones that had no audit results.
// Generally, you will want to use Results() instead.
func (r *Report) RawResults() []Result {
Expand All @@ -234,8 +238,8 @@ func (r *Report) RawResults() []Result {

// Results returns the audit results for each Kubernetes resource
func (r *Report) Results() []Result {
results := make([]Result, 0, len(r.results))
for _, result := range r.results {
results := make([]Result, 0, len(r.RawResults()))
for _, result := range r.RawResults() {
if len(result.GetAuditResults()) > 0 {
results = append(results, result)
}
Expand All @@ -246,15 +250,15 @@ func (r *Report) Results() []Result {
// ResultsWithMinSeverity returns the audit results for each Kubernetes resource with a minimum severity
func (r *Report) ResultsWithMinSeverity(minSeverity SeverityLevel) []Result {
var results []Result
for _, result := range r.results {
for _, result := range r.RawResults() {
var filteredAuditResults []*AuditResult
for _, auditResult := range result.GetAuditResults() {
if auditResult.Severity >= minSeverity {
filteredAuditResults = append(filteredAuditResults, auditResult)
}
}
if len(filteredAuditResults) > 0 {
results = append(results, &workloadResult{
results = append(results, &WorkloadResult{
Resource: result.GetResource(),
AuditResults: filteredAuditResults,
})
Expand Down Expand Up @@ -284,7 +288,7 @@ func (r *Report) PrintResults(printOptions ...PrintOption) {
// Fix tries to automatically patch any security concerns and writes the resulting manifest to the provided writer.
// Only applies when audit was performed on a manifest (not local or cluster)
func (r *Report) Fix(writer io.Writer) error {
fixed, err := fix(r.results)
fixed, err := fix(r.RawResults())
if err != nil {
return err
}
Expand Down
6 changes: 3 additions & 3 deletions result.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,15 @@ type PendingFix interface {
type Metadata = map[string]string

// Implements Result
type workloadResult struct {
type WorkloadResult struct {
Resource KubeResource
AuditResults []*AuditResult
}

func (wlResult *workloadResult) GetResource() KubeResource {
func (wlResult *WorkloadResult) GetResource() KubeResource {
return wlResult.Resource
}

func (wlResult *workloadResult) GetAuditResults() []*AuditResult {
func (wlResult *WorkloadResult) GetAuditResults() []*AuditResult {
return wlResult.AuditResults
}
2 changes: 1 addition & 1 deletion util.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func auditResources(resources []KubeResource, auditable []Auditable) ([]Result,
}

func auditResource(resource KubeResource, resources []KubeResource, auditables []Auditable) (Result, error) {
result := &workloadResult{
result := &WorkloadResult{
Resource: resource,
AuditResults: []*AuditResult{},
}
Expand Down
4 changes: 2 additions & 2 deletions util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type logEntry struct {
func TestPrintResults(t *testing.T) {
report := Report{
results: []Result{
&workloadResult{
&WorkloadResult{
AuditResults: []*AuditResult{
newTestAuditResult(Error),
newTestAuditResult(Warn),
Expand Down Expand Up @@ -74,7 +74,7 @@ func TestLogAuditResult(t *testing.T) {
auditResult := newTestAuditResult(severity)
report := &Report{
results: []Result{
&workloadResult{
&WorkloadResult{
AuditResults: []*AuditResult{
auditResult,
},
Expand Down

0 comments on commit e9fce13

Please sign in to comment.