mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-13 00:00:19 -08:00
2532 lines
76 KiB
Go
2532 lines
76 KiB
Go
package local
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/aquasecurity/trivy/internal/cachetest"
|
|
"github.com/aquasecurity/trivy/pkg/cache"
|
|
"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
|
|
"github.com/aquasecurity/trivy/pkg/fanal/artifact"
|
|
"github.com/aquasecurity/trivy/pkg/fanal/types"
|
|
"github.com/aquasecurity/trivy/pkg/fanal/walker"
|
|
"github.com/aquasecurity/trivy/pkg/misconf"
|
|
"github.com/aquasecurity/trivy/pkg/uuid"
|
|
|
|
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/config/all"
|
|
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/language/python/pip"
|
|
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/os/alpine"
|
|
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/pkg/apk"
|
|
_ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/secret"
|
|
_ "github.com/aquasecurity/trivy/pkg/fanal/handler/sysfile"
|
|
)
|
|
|
|
func TestArtifact_Inspect(t *testing.T) {
|
|
type fields struct {
|
|
dir string
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
fields fields
|
|
setupCache func(t *testing.T) cache.Cache
|
|
artifactOpt artifact.Option
|
|
scannerOpt misconf.ScannerOption
|
|
disabledAnalyzers []analyzer.Type
|
|
disabledHandlers []types.HandlerType
|
|
wantBlobs []cachetest.WantBlob
|
|
want artifact.Reference
|
|
wantErr string
|
|
}{
|
|
{
|
|
name: "happy path",
|
|
fields: fields{
|
|
dir: "./testdata/alpine",
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: types.BlobJSONSchemaVersion,
|
|
OS: types.OS{
|
|
Family: "alpine",
|
|
Name: "3.11.6",
|
|
},
|
|
PackageInfos: []types.PackageInfo{
|
|
{
|
|
FilePath: "lib/apk/db/installed",
|
|
Packages: types.Packages{
|
|
{
|
|
ID: "musl@1.1.24-r2",
|
|
Name: "musl",
|
|
Version: "1.1.24-r2",
|
|
SrcName: "musl",
|
|
SrcVersion: "1.1.24-r2",
|
|
Licenses: []string{"MIT"},
|
|
Arch: "x86_64",
|
|
Digest: "sha1:cb2316a189ebee5282c4a9bd98794cc2477a74c6",
|
|
InstalledFiles: []string{
|
|
"lib/libc.musl-x86_64.so.1",
|
|
"lib/ld-musl-x86_64.so.1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "host",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "disable analyzers",
|
|
fields: fields{
|
|
dir: "./testdata/alpine",
|
|
},
|
|
artifactOpt: artifact.Option{
|
|
DisabledAnalyzers: []analyzer.Type{
|
|
analyzer.TypeAlpine,
|
|
analyzer.TypeApk,
|
|
analyzer.TypePip,
|
|
analyzer.TypeNpmPkgLock,
|
|
},
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: types.BlobJSONSchemaVersion,
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "host",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "sad path PutBlob returns an error",
|
|
fields: fields{
|
|
dir: "./testdata/alpine",
|
|
},
|
|
setupCache: func(_ *testing.T) cache.Cache {
|
|
return cachetest.NewErrorCache(cachetest.ErrorCacheOptions{
|
|
PutBlob: true,
|
|
})
|
|
},
|
|
wantErr: "PutBlob failed",
|
|
},
|
|
{
|
|
name: "sad path with no such directory",
|
|
fields: fields{
|
|
dir: "./testdata/unknown",
|
|
},
|
|
wantErr: "walk dir error",
|
|
},
|
|
{
|
|
name: "happy path with single file",
|
|
fields: fields{
|
|
dir: "testdata/requirements.txt",
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: types.BlobJSONSchemaVersion,
|
|
Applications: []types.Application{
|
|
{
|
|
Type: "pip",
|
|
FilePath: "requirements.txt",
|
|
Packages: types.Packages{
|
|
{
|
|
Name: "Flask",
|
|
Version: "2.0.0",
|
|
Locations: []types.Location{
|
|
{
|
|
StartLine: 1,
|
|
EndLine: 1,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/requirements.txt",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "happy path with single file using relative path",
|
|
fields: fields{
|
|
dir: "./testdata/requirements.txt",
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: types.BlobJSONSchemaVersion,
|
|
Applications: []types.Application{
|
|
{
|
|
Type: "pip",
|
|
FilePath: "requirements.txt",
|
|
Packages: types.Packages{
|
|
{
|
|
Name: "Flask",
|
|
Version: "2.0.0",
|
|
Locations: []types.Location{
|
|
{
|
|
StartLine: 1,
|
|
EndLine: 1,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/requirements.txt",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Set fake UUID for consistent test results
|
|
uuid.SetFakeUUID(t, "3ff14136-e09f-4df9-80ea-%012d")
|
|
|
|
c := cachetest.NewCache(t, tt.setupCache)
|
|
|
|
a, err := NewArtifact(tt.fields.dir, c, walker.NewFS(), tt.artifactOpt)
|
|
require.NoError(t, err)
|
|
|
|
got, err := a.Inspect(t.Context())
|
|
if tt.wantErr != "" {
|
|
require.ErrorContains(t, err, tt.wantErr)
|
|
return
|
|
}
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tt.want, got)
|
|
cachetest.AssertBlobs(t, c, tt.wantBlobs)
|
|
})
|
|
}
|
|
}
|
|
|
|
var terraformPolicyMetadata = types.PolicyMetadata{
|
|
ID: "TEST001",
|
|
AVDID: "AVD-TEST-0001",
|
|
Type: "Terraform Security Check",
|
|
Title: "Test policy",
|
|
Description: "This is a test policy.",
|
|
Severity: "LOW",
|
|
RecommendedActions: "Have a cup of tea.",
|
|
References: []string{"https://trivy.dev/"},
|
|
}
|
|
|
|
func TestTerraformMisconfigurationScan(t *testing.T) {
|
|
type fields struct {
|
|
dir string
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
fields fields
|
|
wantBlobs []cachetest.WantBlob
|
|
artifactOpt artifact.Option
|
|
want artifact.Reference
|
|
}{
|
|
{
|
|
name: "single failure",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/terraform/single-failure",
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: 2,
|
|
Misconfigurations: []types.Misconfiguration{
|
|
{
|
|
FileType: "terraform",
|
|
FilePath: "main.tf",
|
|
Failures: types.MisconfResults{
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
Message: "Empty bucket name!",
|
|
PolicyMetadata: terraformPolicyMetadata,
|
|
CauseMetadata: types.CauseMetadata{
|
|
Resource: "aws_s3_bucket.asd",
|
|
Provider: "Generic",
|
|
Service: "general",
|
|
StartLine: 1,
|
|
EndLine: 3,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/terraform/single-failure",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "multiple failures",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/terraform/multiple-failures",
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: 2,
|
|
Misconfigurations: []types.Misconfiguration{
|
|
{
|
|
FileType: "terraform",
|
|
FilePath: "main.tf",
|
|
Failures: types.MisconfResults{
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
Message: "Empty bucket name!",
|
|
PolicyMetadata: terraformPolicyMetadata,
|
|
CauseMetadata: types.CauseMetadata{
|
|
Resource: "aws_s3_bucket.one",
|
|
Provider: "Generic",
|
|
Service: "general",
|
|
StartLine: 1,
|
|
EndLine: 3,
|
|
},
|
|
},
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
Message: "Empty bucket name!",
|
|
PolicyMetadata: terraformPolicyMetadata,
|
|
CauseMetadata: types.CauseMetadata{
|
|
Resource: "aws_s3_bucket.two",
|
|
Provider: "Generic",
|
|
Service: "general",
|
|
StartLine: 5,
|
|
EndLine: 7,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
FileType: "terraform",
|
|
FilePath: "more.tf",
|
|
Failures: types.MisconfResults{
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
Message: "Empty bucket name!",
|
|
PolicyMetadata: terraformPolicyMetadata,
|
|
CauseMetadata: types.CauseMetadata{
|
|
Resource: "aws_s3_bucket.three",
|
|
Provider: "Generic",
|
|
Service: "general",
|
|
StartLine: 1,
|
|
EndLine: 3,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/terraform/multiple-failures",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "no results",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/terraform/no-results",
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: types.BlobJSONSchemaVersion,
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/terraform/no-results",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "passed",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/terraform/passed",
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: 2,
|
|
Misconfigurations: []types.Misconfiguration{
|
|
{
|
|
FileType: "terraform",
|
|
FilePath: ".",
|
|
Successes: types.MisconfResults{
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
PolicyMetadata: terraformPolicyMetadata,
|
|
CauseMetadata: types.CauseMetadata{
|
|
Provider: "Generic",
|
|
Service: "general",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/terraform/passed",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "multiple failures busted relative paths",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/terraform/busted-relative-paths/child/main.tf",
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: 2,
|
|
Misconfigurations: []types.Misconfiguration{
|
|
{
|
|
FileType: "terraform",
|
|
FilePath: "main.tf",
|
|
Failures: types.MisconfResults{
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
Message: "Empty bucket name!",
|
|
PolicyMetadata: terraformPolicyMetadata,
|
|
CauseMetadata: types.CauseMetadata{
|
|
Resource: "aws_s3_bucket.one",
|
|
Provider: "Generic",
|
|
Service: "general",
|
|
StartLine: 1,
|
|
EndLine: 3,
|
|
},
|
|
},
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
Message: "Empty bucket name!",
|
|
PolicyMetadata: terraformPolicyMetadata,
|
|
CauseMetadata: types.CauseMetadata{
|
|
Resource: "aws_s3_bucket.two",
|
|
Provider: "Generic",
|
|
Service: "general",
|
|
StartLine: 5,
|
|
EndLine: 7,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/terraform/busted-relative-paths/child/main.tf",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "tfvars outside the scan folder",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/terraform/tfvar-outside/tf",
|
|
},
|
|
artifactOpt: artifact.Option{
|
|
MisconfScannerOption: misconf.ScannerOption{
|
|
TerraformTFVars: []string{"./testdata/misconfig/terraform/tfvar-outside/main.tfvars"},
|
|
},
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: 2,
|
|
Misconfigurations: []types.Misconfiguration{
|
|
{
|
|
FileType: types.Terraform,
|
|
FilePath: ".",
|
|
Successes: types.MisconfResults{
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
PolicyMetadata: terraformPolicyMetadata,
|
|
CauseMetadata: types.CauseMetadata{
|
|
Provider: "Generic",
|
|
Service: "general",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/terraform/tfvar-outside/tf",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "relative paths",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/terraform/relative-paths/child",
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: 2,
|
|
Misconfigurations: []types.Misconfiguration{
|
|
{
|
|
FileType: types.Terraform,
|
|
FilePath: "../parent/main.tf",
|
|
Failures: types.MisconfResults{
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
Message: "Empty bucket name!",
|
|
PolicyMetadata: terraformPolicyMetadata,
|
|
CauseMetadata: types.CauseMetadata{
|
|
Resource: "aws_s3_bucket.three",
|
|
Provider: "Generic",
|
|
Service: "general",
|
|
StartLine: 1,
|
|
EndLine: 3,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
FileType: types.Terraform,
|
|
FilePath: "main.tf",
|
|
Failures: types.MisconfResults{
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
Message: "Empty bucket name!",
|
|
PolicyMetadata: terraformPolicyMetadata,
|
|
CauseMetadata: types.CauseMetadata{
|
|
Resource: "aws_s3_bucket.one",
|
|
Provider: "Generic",
|
|
Service: "general",
|
|
StartLine: 1,
|
|
EndLine: 3,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
FileType: types.Terraform,
|
|
FilePath: "nested/main.tf",
|
|
Failures: types.MisconfResults{
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
Message: "Empty bucket name!",
|
|
PolicyMetadata: terraformPolicyMetadata,
|
|
CauseMetadata: types.CauseMetadata{
|
|
Resource: "aws_s3_bucket.two",
|
|
Provider: "Generic",
|
|
Service: "general",
|
|
StartLine: 1,
|
|
EndLine: 3,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/terraform/relative-paths/child",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "scan raw config",
|
|
artifactOpt: artifact.Option{
|
|
MisconfScannerOption: misconf.ScannerOption{
|
|
RawConfigScanners: []types.ConfigType{types.Terraform},
|
|
},
|
|
},
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/terraform/single-failure",
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: 2,
|
|
Misconfigurations: []types.Misconfiguration{
|
|
{
|
|
FileType: "terraform",
|
|
FilePath: "main.tf",
|
|
Failures: types.MisconfResults{
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
Message: "Empty bucket name!",
|
|
PolicyMetadata: terraformPolicyMetadata,
|
|
CauseMetadata: types.CauseMetadata{
|
|
Resource: "aws_s3_bucket.asd",
|
|
Provider: "Generic",
|
|
Service: "general",
|
|
StartLine: 1,
|
|
EndLine: 3,
|
|
},
|
|
},
|
|
{
|
|
Namespace: "user.test002",
|
|
Query: "data.user.test002.deny",
|
|
Message: "Empty bucket name!",
|
|
PolicyMetadata: types.PolicyMetadata{
|
|
ID: "TEST002",
|
|
AVDID: "AVD-TEST-0002",
|
|
Type: "Terraform Security Check",
|
|
Title: "Test policy",
|
|
Severity: "LOW",
|
|
},
|
|
CauseMetadata: types.CauseMetadata{
|
|
Resource: "aws_s3_bucket.asd",
|
|
Provider: "Terraform-Raw",
|
|
Service: "general",
|
|
StartLine: 1,
|
|
EndLine: 3,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/terraform/single-failure",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Set fake UUID for consistent test results
|
|
uuid.SetFakeUUID(t, "3ff14136-e09f-4df9-80ea-%012d")
|
|
|
|
c := cachetest.NewCache(t, nil)
|
|
tt.artifactOpt.DisabledHandlers = []types.HandlerType{
|
|
types.SystemFileFilteringPostHandler,
|
|
}
|
|
tt.artifactOpt.MisconfScannerOption.DisableEmbeddedPolicies = true
|
|
tt.artifactOpt.MisconfScannerOption.Namespaces = []string{"user"}
|
|
tt.artifactOpt.MisconfScannerOption.PolicyPaths = []string{"./testdata/misconfig/terraform/rego"}
|
|
a, err := NewArtifact(tt.fields.dir, c, walker.NewFS(), tt.artifactOpt)
|
|
require.NoError(t, err)
|
|
|
|
got, err := a.Inspect(t.Context())
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tt.want, got)
|
|
cachetest.AssertBlobs(t, c, tt.wantBlobs)
|
|
})
|
|
}
|
|
}
|
|
|
|
const emptyBucketCheck = `package user.something
|
|
|
|
__rego_metadata__ := {
|
|
"id": "TEST001",
|
|
"avd_id": "AVD-TEST-0001",
|
|
"title": "Test policy",
|
|
"short_code": "empty-bucket-name",
|
|
"severity": "LOW",
|
|
"description": "This is a test policy.",
|
|
"recommended_actions": "Have a cup of tea.",
|
|
"url": "https://trivy.dev/",
|
|
}
|
|
|
|
# taken from defsec rego lib to mimic behaviour
|
|
result(msg, cause) = result {
|
|
metadata := object.get(cause, "__defsec_metadata", cause)
|
|
result := {
|
|
"msg": msg,
|
|
"startline": object.get(metadata, "startline", 0),
|
|
"endline": object.get(metadata, "endline", 0),
|
|
"filepath": object.get(metadata, "filepath", ""),
|
|
"explicit": object.get(metadata, "explicit", false),
|
|
"managed": object.get(metadata, "managed", true),
|
|
"fskey": object.get(metadata, "fskey", ""),
|
|
"resource": object.get(metadata, "resource", ""),
|
|
}
|
|
}
|
|
|
|
deny[res] {
|
|
bucket := input.aws.s3.buckets[_]
|
|
bucket.name.value == ""
|
|
res := result("Empty bucket name!", bucket)
|
|
}`
|
|
|
|
var terraformPlanPolicyMetadata = types.PolicyMetadata{
|
|
ID: "TEST001",
|
|
AVDID: "AVD-TEST-0001",
|
|
Type: "Terraform Plan Snapshot Security Check",
|
|
Title: "Test policy",
|
|
Description: "This is a test policy.",
|
|
Severity: "LOW",
|
|
RecommendedActions: "Have a cup of tea.",
|
|
References: []string{"https://trivy.dev/"},
|
|
}
|
|
|
|
func TestTerraformPlanSnapshotMisconfScan(t *testing.T) {
|
|
type fields struct {
|
|
dir string
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
fields fields
|
|
wantBlobs []cachetest.WantBlob
|
|
want artifact.Reference
|
|
}{
|
|
{
|
|
name: "single failure",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/terraformplan/snapshots/single-failure",
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: 2,
|
|
Misconfigurations: []types.Misconfiguration{
|
|
{
|
|
FileType: types.TerraformPlanSnapshot,
|
|
FilePath: "main.tf",
|
|
Failures: types.MisconfResults{
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
Message: "Empty bucket name!",
|
|
PolicyMetadata: terraformPlanPolicyMetadata,
|
|
CauseMetadata: types.CauseMetadata{
|
|
Resource: "aws_s3_bucket.this",
|
|
Provider: "Generic",
|
|
Service: "general",
|
|
StartLine: 10,
|
|
EndLine: 12,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/terraformplan/snapshots/single-failure",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "multiple failures",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/terraformplan/snapshots/multiple-failures",
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: 2,
|
|
Misconfigurations: []types.Misconfiguration{
|
|
{
|
|
FileType: types.TerraformPlanSnapshot,
|
|
FilePath: "main.tf",
|
|
Failures: types.MisconfResults{
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
Message: "Empty bucket name!",
|
|
PolicyMetadata: terraformPlanPolicyMetadata,
|
|
CauseMetadata: types.CauseMetadata{
|
|
Resource: "aws_s3_bucket.one",
|
|
Provider: "Generic",
|
|
Service: "general",
|
|
StartLine: 10,
|
|
EndLine: 12,
|
|
},
|
|
},
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
Message: "Empty bucket name!",
|
|
PolicyMetadata: terraformPlanPolicyMetadata,
|
|
CauseMetadata: types.CauseMetadata{
|
|
Resource: "aws_s3_bucket.two",
|
|
Provider: "Generic",
|
|
Service: "general",
|
|
StartLine: 14,
|
|
EndLine: 16,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
FileType: types.TerraformPlanSnapshot,
|
|
FilePath: "more.tf",
|
|
Failures: types.MisconfResults{
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
Message: "Empty bucket name!",
|
|
PolicyMetadata: terraformPlanPolicyMetadata,
|
|
CauseMetadata: types.CauseMetadata{
|
|
Resource: "aws_s3_bucket.three",
|
|
Provider: "Generic",
|
|
Service: "general",
|
|
StartLine: 1,
|
|
EndLine: 3,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/terraformplan/snapshots/multiple-failures",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "passed",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/terraformplan/snapshots/passed",
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: 2,
|
|
Misconfigurations: []types.Misconfiguration{
|
|
{
|
|
FileType: types.TerraformPlanSnapshot,
|
|
FilePath: ".",
|
|
Successes: types.MisconfResults{
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
PolicyMetadata: terraformPlanPolicyMetadata,
|
|
CauseMetadata: types.CauseMetadata{
|
|
Provider: "Generic",
|
|
Service: "general",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/terraformplan/snapshots/passed",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Set fake UUID for consistent test results
|
|
uuid.SetFakeUUID(t, "3ff14136-e09f-4df9-80ea-%012d")
|
|
|
|
tmpDir := t.TempDir()
|
|
f, err := os.Create(filepath.Join(tmpDir, "policy.rego"))
|
|
require.NoError(t, err)
|
|
defer f.Close()
|
|
|
|
_, err = f.WriteString(emptyBucketCheck)
|
|
require.NoError(t, err)
|
|
|
|
c := cachetest.NewCache(t, nil)
|
|
|
|
opt := artifact.Option{
|
|
DisabledHandlers: []types.HandlerType{
|
|
types.SystemFileFilteringPostHandler,
|
|
},
|
|
MisconfScannerOption: misconf.ScannerOption{
|
|
DisableEmbeddedPolicies: true,
|
|
DisableEmbeddedLibraries: false,
|
|
Namespaces: []string{"user"},
|
|
PolicyPaths: []string{tmpDir},
|
|
},
|
|
WalkerOption: walker.Option{
|
|
SkipFiles: []string{"*.tf"},
|
|
},
|
|
}
|
|
a, err := NewArtifact(tt.fields.dir, c, walker.NewFS(), opt)
|
|
require.NoError(t, err)
|
|
|
|
got, err := a.Inspect(t.Context())
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tt.want, got)
|
|
cachetest.AssertBlobs(t, c, tt.wantBlobs)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCloudFormationMisconfigurationScan(t *testing.T) {
|
|
type fields struct {
|
|
dir string
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
fields fields
|
|
wantBlobs []cachetest.WantBlob
|
|
artifactOpt artifact.Option
|
|
want artifact.Reference
|
|
}{
|
|
{
|
|
name: "single failure",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/cloudformation/single-failure/src",
|
|
},
|
|
artifactOpt: artifact.Option{
|
|
MisconfScannerOption: misconf.ScannerOption{
|
|
Namespaces: []string{"user"},
|
|
PolicyPaths: []string{"./testdata/misconfig/cloudformation/single-failure/rego"},
|
|
DisableEmbeddedLibraries: true,
|
|
},
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: types.BlobJSONSchemaVersion,
|
|
Misconfigurations: []types.Misconfiguration{
|
|
{
|
|
FileType: "cloudformation",
|
|
FilePath: "main.yaml",
|
|
Failures: types.MisconfResults{
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
Message: "No buckets allowed!",
|
|
PolicyMetadata: types.PolicyMetadata{
|
|
ID: "TEST001",
|
|
AVDID: "AVD-TEST-0001",
|
|
Type: "CloudFormation Security Check",
|
|
Title: "Test policy",
|
|
Description: "This is a test policy.",
|
|
Severity: "LOW",
|
|
RecommendedActions: "Have a cup of tea.",
|
|
References: []string{"https://trivy.dev/"},
|
|
},
|
|
CauseMetadata: types.CauseMetadata{
|
|
Resource: "main.yaml:3-6",
|
|
Provider: "Cloud",
|
|
Service: "general",
|
|
StartLine: 3,
|
|
EndLine: 6,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/cloudformation/single-failure/src",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "multiple failures",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/cloudformation/multiple-failures/src",
|
|
},
|
|
artifactOpt: artifact.Option{
|
|
MisconfScannerOption: misconf.ScannerOption{
|
|
Namespaces: []string{"user"},
|
|
PolicyPaths: []string{"./testdata/misconfig/cloudformation/multiple-failures/rego"},
|
|
DisableEmbeddedLibraries: true,
|
|
},
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: 2,
|
|
Misconfigurations: []types.Misconfiguration{
|
|
{
|
|
FileType: "cloudformation",
|
|
FilePath: "main.yaml",
|
|
Failures: types.MisconfResults{
|
|
types.MisconfResult{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
Message: "No buckets allowed!",
|
|
PolicyMetadata: types.PolicyMetadata{
|
|
ID: "TEST001",
|
|
AVDID: "AVD-TEST-0001",
|
|
Type: "CloudFormation Security Check",
|
|
Title: "Test policy",
|
|
Description: "This is a test policy.",
|
|
Severity: "LOW",
|
|
RecommendedActions: "Have a cup of tea.",
|
|
References: []string{"https://trivy.dev/"},
|
|
},
|
|
CauseMetadata: types.CauseMetadata{
|
|
Resource: "main.yaml:2-5",
|
|
Provider: "Cloud",
|
|
Service: "general",
|
|
StartLine: 2,
|
|
EndLine: 5,
|
|
},
|
|
},
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
Message: "No buckets allowed!",
|
|
PolicyMetadata: types.PolicyMetadata{
|
|
ID: "TEST001",
|
|
AVDID: "AVD-TEST-0001",
|
|
Type: "CloudFormation Security Check",
|
|
Title: "Test policy",
|
|
Description: "This is a test policy.",
|
|
Severity: "LOW",
|
|
RecommendedActions: "Have a cup of tea.",
|
|
References: []string{"https://trivy.dev/"},
|
|
},
|
|
CauseMetadata: types.CauseMetadata{
|
|
Resource: "main.yaml:6-9",
|
|
Provider: "Cloud",
|
|
Service: "general",
|
|
StartLine: 6,
|
|
EndLine: 9,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/cloudformation/multiple-failures/src",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "no results",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/cloudformation/no-results/src",
|
|
},
|
|
artifactOpt: artifact.Option{
|
|
MisconfScannerOption: misconf.ScannerOption{
|
|
Namespaces: []string{"user"},
|
|
PolicyPaths: []string{"./testdata/misconfig/cloudformation/no-results/rego"},
|
|
DisableEmbeddedLibraries: true,
|
|
},
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: types.BlobJSONSchemaVersion,
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/cloudformation/no-results/src",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "CloudFormation parameters outside the scan directory",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/cloudformation/params/code/src",
|
|
},
|
|
artifactOpt: artifact.Option{
|
|
MisconfScannerOption: misconf.ScannerOption{
|
|
Namespaces: []string{"user"},
|
|
PolicyPaths: []string{"./testdata/misconfig/cloudformation/params/code/rego"},
|
|
CloudFormationParamVars: []string{"./testdata/misconfig/cloudformation/params/cfparams.json"},
|
|
DisableEmbeddedLibraries: true,
|
|
},
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: types.BlobJSONSchemaVersion,
|
|
Misconfigurations: []types.Misconfiguration{
|
|
{
|
|
FileType: "cloudformation",
|
|
FilePath: "main.yaml",
|
|
Successes: types.MisconfResults{
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
PolicyMetadata: types.PolicyMetadata{
|
|
ID: "TEST001",
|
|
AVDID: "AVD-TEST-0001",
|
|
Type: "CloudFormation Security Check",
|
|
Title: "Bad stuff is bad",
|
|
Description: "Its not good!",
|
|
Severity: "HIGH",
|
|
RecommendedActions: "Remove bad stuff",
|
|
},
|
|
CauseMetadata: types.CauseMetadata{
|
|
Provider: "AWS",
|
|
Service: "sqs",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/cloudformation/params/code/src",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "passed",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/cloudformation/passed/src",
|
|
},
|
|
artifactOpt: artifact.Option{
|
|
MisconfScannerOption: misconf.ScannerOption{
|
|
Namespaces: []string{"user"},
|
|
PolicyPaths: []string{"./testdata/misconfig/cloudformation/passed/rego"},
|
|
DisableEmbeddedLibraries: true,
|
|
},
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: types.BlobJSONSchemaVersion,
|
|
Misconfigurations: []types.Misconfiguration{
|
|
{
|
|
FileType: "cloudformation",
|
|
FilePath: "main.yaml",
|
|
Successes: types.MisconfResults{
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
PolicyMetadata: types.PolicyMetadata{
|
|
ID: "TEST001",
|
|
AVDID: "AVD-TEST-0001",
|
|
Type: "CloudFormation Security Check",
|
|
Title: "Test policy",
|
|
Description: "This is a test policy.",
|
|
Severity: "LOW",
|
|
RecommendedActions: "Have a cup of tea.",
|
|
References: []string{"https://trivy.dev/"},
|
|
},
|
|
CauseMetadata: types.CauseMetadata{
|
|
Provider: "Cloud",
|
|
Service: "general",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/cloudformation/passed/src",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Set fake UUID for consistent test results
|
|
uuid.SetFakeUUID(t, "3ff14136-e09f-4df9-80ea-%012d")
|
|
|
|
c := cachetest.NewCache(t, nil)
|
|
tt.artifactOpt.DisabledHandlers = []types.HandlerType{
|
|
types.SystemFileFilteringPostHandler,
|
|
}
|
|
tt.artifactOpt.MisconfScannerOption.DisableEmbeddedPolicies = true
|
|
a, err := NewArtifact(tt.fields.dir, c, walker.NewFS(), tt.artifactOpt)
|
|
require.NoError(t, err)
|
|
|
|
got, err := a.Inspect(t.Context())
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tt.want, got)
|
|
cachetest.AssertBlobs(t, c, tt.wantBlobs)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDockerfileMisconfigurationScan(t *testing.T) {
|
|
type fields struct {
|
|
dir string
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
fields fields
|
|
wantBlobs []cachetest.WantBlob
|
|
artifactOpt artifact.Option
|
|
want artifact.Reference
|
|
}{
|
|
{
|
|
name: "single failure",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/dockerfile/single-failure/src",
|
|
},
|
|
artifactOpt: artifact.Option{
|
|
MisconfScannerOption: misconf.ScannerOption{
|
|
Namespaces: []string{"user"},
|
|
PolicyPaths: []string{"./testdata/misconfig/dockerfile/single-failure/rego"},
|
|
DisableEmbeddedLibraries: true,
|
|
},
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: types.BlobJSONSchemaVersion,
|
|
Misconfigurations: []types.Misconfiguration{
|
|
{
|
|
FileType: "dockerfile",
|
|
FilePath: "Dockerfile",
|
|
Successes: types.MisconfResults{
|
|
types.MisconfResult{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
PolicyMetadata: types.PolicyMetadata{
|
|
ID: "TEST001",
|
|
AVDID: "AVD-TEST-0001",
|
|
Type: "Dockerfile Security Check",
|
|
Title: "Test policy",
|
|
Description: "This is a test policy.",
|
|
Severity: "LOW",
|
|
RecommendedActions: "Have a cup of tea.",
|
|
References: []string{"https://trivy.dev/"},
|
|
},
|
|
CauseMetadata: types.CauseMetadata{
|
|
Provider: "Generic",
|
|
Service: "general",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/dockerfile/single-failure/src",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "multiple failures",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/dockerfile/multiple-failures/src",
|
|
},
|
|
artifactOpt: artifact.Option{
|
|
MisconfScannerOption: misconf.ScannerOption{
|
|
Namespaces: []string{"user"},
|
|
PolicyPaths: []string{"./testdata/misconfig/dockerfile/multiple-failures/rego"},
|
|
DisableEmbeddedLibraries: true,
|
|
},
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: types.BlobJSONSchemaVersion,
|
|
Misconfigurations: []types.Misconfiguration{
|
|
{
|
|
FileType: "dockerfile",
|
|
FilePath: "Dockerfile",
|
|
Successes: types.MisconfResults{
|
|
types.MisconfResult{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
PolicyMetadata: types.PolicyMetadata{
|
|
ID: "TEST001",
|
|
AVDID: "AVD-TEST-0001",
|
|
Type: "Dockerfile Security Check",
|
|
Title: "Test policy",
|
|
Description: "This is a test policy.",
|
|
Severity: "LOW",
|
|
RecommendedActions: "Have a cup of tea.",
|
|
References: []string{"https://trivy.dev/"},
|
|
},
|
|
CauseMetadata: types.CauseMetadata{
|
|
Provider: "Generic",
|
|
Service: "general",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/dockerfile/multiple-failures/src",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "no results",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/dockerfile/no-results/src",
|
|
},
|
|
artifactOpt: artifact.Option{
|
|
MisconfScannerOption: misconf.ScannerOption{
|
|
Namespaces: []string{"user"},
|
|
PolicyPaths: []string{"./testdata/misconfig/dockerfile/no-results/rego"},
|
|
},
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: types.BlobJSONSchemaVersion,
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/dockerfile/no-results/src",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "passed",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/dockerfile/passed/src",
|
|
},
|
|
artifactOpt: artifact.Option{
|
|
MisconfScannerOption: misconf.ScannerOption{
|
|
Namespaces: []string{"user"},
|
|
PolicyPaths: []string{"./testdata/misconfig/dockerfile/passed/rego"},
|
|
DisableEmbeddedLibraries: true,
|
|
},
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: types.BlobJSONSchemaVersion,
|
|
Misconfigurations: []types.Misconfiguration{
|
|
{
|
|
FileType: "dockerfile",
|
|
FilePath: "Dockerfile",
|
|
Successes: []types.MisconfResult{
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
PolicyMetadata: types.PolicyMetadata{
|
|
ID: "TEST001",
|
|
AVDID: "AVD-TEST-0001",
|
|
Type: "Dockerfile Security Check",
|
|
Title: "Test policy",
|
|
Description: "This is a test policy.",
|
|
Severity: "LOW",
|
|
RecommendedActions: "Have a cup of tea.",
|
|
References: []string{
|
|
"https://trivy.dev/",
|
|
},
|
|
},
|
|
CauseMetadata: types.CauseMetadata{
|
|
Provider: "Generic",
|
|
Service: "general",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/dockerfile/passed/src",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Set fake UUID for consistent test results
|
|
uuid.SetFakeUUID(t, "3ff14136-e09f-4df9-80ea-%012d")
|
|
|
|
c := cachetest.NewCache(t, nil)
|
|
tt.artifactOpt.DisabledHandlers = []types.HandlerType{
|
|
types.SystemFileFilteringPostHandler,
|
|
}
|
|
tt.artifactOpt.MisconfScannerOption.DisableEmbeddedPolicies = true
|
|
a, err := NewArtifact(tt.fields.dir, c, walker.NewFS(), tt.artifactOpt)
|
|
require.NoError(t, err)
|
|
|
|
got, err := a.Inspect(t.Context())
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tt.want, got)
|
|
cachetest.AssertBlobs(t, c, tt.wantBlobs)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestKubernetesMisconfigurationScan(t *testing.T) {
|
|
type fields struct {
|
|
dir string
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
fields fields
|
|
wantBlobs []cachetest.WantBlob
|
|
artifactOpt artifact.Option
|
|
want artifact.Reference
|
|
}{
|
|
{
|
|
name: "single failure",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/kubernetes/single-failure/src",
|
|
},
|
|
artifactOpt: artifact.Option{
|
|
MisconfScannerOption: misconf.ScannerOption{
|
|
Namespaces: []string{"user"},
|
|
PolicyPaths: []string{"./testdata/misconfig/kubernetes/single-failure/rego"},
|
|
DisableEmbeddedLibraries: true,
|
|
},
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: types.BlobJSONSchemaVersion,
|
|
Misconfigurations: []types.Misconfiguration{
|
|
{
|
|
FileType: "kubernetes",
|
|
FilePath: "test.yaml",
|
|
Failures: []types.MisconfResult{
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
Message: "No evil containers allowed!",
|
|
PolicyMetadata: types.PolicyMetadata{
|
|
ID: "TEST001",
|
|
AVDID: "AVD-TEST-0001",
|
|
Type: "Kubernetes Security Check",
|
|
Title: "Test policy",
|
|
Description: "This is a test policy.",
|
|
Severity: "LOW",
|
|
RecommendedActions: "Have a cup of tea.",
|
|
References: []string{
|
|
"https://trivy.dev/",
|
|
},
|
|
},
|
|
CauseMetadata: types.CauseMetadata{
|
|
Provider: "Kubernetes",
|
|
Service: "general",
|
|
StartLine: 7,
|
|
EndLine: 9,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/kubernetes/single-failure/src",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "multiple failures",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/kubernetes/multiple-failures/src",
|
|
},
|
|
artifactOpt: artifact.Option{
|
|
MisconfScannerOption: misconf.ScannerOption{
|
|
Namespaces: []string{"user"},
|
|
PolicyPaths: []string{"./testdata/misconfig/kubernetes/multiple-failures/rego"},
|
|
DisableEmbeddedLibraries: true,
|
|
},
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: types.BlobJSONSchemaVersion,
|
|
Misconfigurations: []types.Misconfiguration{
|
|
{
|
|
FileType: "kubernetes",
|
|
FilePath: "test.yaml",
|
|
Failures: []types.MisconfResult{
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
Message: "No evil containers allowed!",
|
|
PolicyMetadata: types.PolicyMetadata{
|
|
ID: "TEST001",
|
|
AVDID: "AVD-TEST-0001",
|
|
Type: "Kubernetes Security Check",
|
|
Title: "Test policy",
|
|
Description: "This is a test policy.",
|
|
Severity: "LOW",
|
|
RecommendedActions: "Have a cup of tea.",
|
|
References: []string{
|
|
"https://trivy.dev/",
|
|
},
|
|
},
|
|
CauseMetadata: types.CauseMetadata{
|
|
Provider: "Kubernetes",
|
|
Service: "general",
|
|
StartLine: 7,
|
|
EndLine: 9,
|
|
},
|
|
},
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
Message: "No evil containers allowed!",
|
|
PolicyMetadata: types.PolicyMetadata{
|
|
ID: "TEST001",
|
|
AVDID: "AVD-TEST-0001",
|
|
Type: "Kubernetes Security Check",
|
|
Title: "Test policy",
|
|
Description: "This is a test policy.",
|
|
Severity: "LOW",
|
|
RecommendedActions: "Have a cup of tea.",
|
|
References: []string{
|
|
"https://trivy.dev/",
|
|
},
|
|
},
|
|
CauseMetadata: types.CauseMetadata{
|
|
Provider: "Kubernetes",
|
|
Service: "general",
|
|
StartLine: 10,
|
|
EndLine: 12,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/kubernetes/multiple-failures/src",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "no results",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/kubernetes/no-results/src",
|
|
},
|
|
artifactOpt: artifact.Option{
|
|
MisconfScannerOption: misconf.ScannerOption{
|
|
Namespaces: []string{"user"},
|
|
PolicyPaths: []string{"./testdata/misconfig/kubernetes/no-results/rego"},
|
|
},
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: types.BlobJSONSchemaVersion,
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/kubernetes/no-results/src",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "passed",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/kubernetes/passed/src",
|
|
},
|
|
artifactOpt: artifact.Option{
|
|
MisconfScannerOption: misconf.ScannerOption{
|
|
Namespaces: []string{"user"},
|
|
PolicyPaths: []string{"./testdata/misconfig/kubernetes/passed/rego"},
|
|
DisableEmbeddedLibraries: true,
|
|
},
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: types.BlobJSONSchemaVersion,
|
|
Misconfigurations: []types.Misconfiguration{
|
|
{
|
|
FileType: "kubernetes",
|
|
FilePath: "test.yaml",
|
|
Successes: []types.MisconfResult{
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
PolicyMetadata: types.PolicyMetadata{
|
|
ID: "TEST001",
|
|
AVDID: "AVD-TEST-0001",
|
|
Type: "Kubernetes Security Check",
|
|
Title: "Test policy",
|
|
Description: "This is a test policy.",
|
|
Severity: "LOW",
|
|
RecommendedActions: "Have a cup of tea.",
|
|
References: []string{
|
|
"https://trivy.dev/",
|
|
},
|
|
},
|
|
CauseMetadata: types.CauseMetadata{
|
|
Provider: "Kubernetes",
|
|
Service: "general",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/kubernetes/passed/src",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Set fake UUID for consistent test results
|
|
uuid.SetFakeUUID(t, "3ff14136-e09f-4df9-80ea-%012d")
|
|
|
|
c := cachetest.NewCache(t, nil)
|
|
tt.artifactOpt.DisabledHandlers = []types.HandlerType{
|
|
types.SystemFileFilteringPostHandler,
|
|
}
|
|
tt.artifactOpt.MisconfScannerOption.DisableEmbeddedPolicies = true
|
|
a, err := NewArtifact(tt.fields.dir, c, walker.NewFS(), tt.artifactOpt)
|
|
require.NoError(t, err)
|
|
|
|
got, err := a.Inspect(t.Context())
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tt.want, got)
|
|
cachetest.AssertBlobs(t, c, tt.wantBlobs)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAzureARMMisconfigurationScan(t *testing.T) {
|
|
type fields struct {
|
|
dir string
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
fields fields
|
|
wantBlobs []cachetest.WantBlob
|
|
artifactOpt artifact.Option
|
|
want artifact.Reference
|
|
}{
|
|
{
|
|
name: "single failure",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/azurearm/single-failure/src",
|
|
},
|
|
artifactOpt: artifact.Option{
|
|
MisconfScannerOption: misconf.ScannerOption{
|
|
Namespaces: []string{"user"},
|
|
PolicyPaths: []string{"./testdata/misconfig/azurearm/single-failure/rego"},
|
|
},
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: 2,
|
|
Misconfigurations: []types.Misconfiguration{
|
|
{
|
|
FileType: "azure-arm",
|
|
FilePath: "deploy.json",
|
|
Failures: types.MisconfResults{
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
Message: "No account allowed!",
|
|
PolicyMetadata: types.PolicyMetadata{
|
|
ID: "TEST001",
|
|
AVDID: "AVD-TEST-0001",
|
|
Type: "Azure ARM Security Check",
|
|
Title: "Test policy",
|
|
Description: "This is a test policy.",
|
|
Severity: "LOW",
|
|
RecommendedActions: "Have a cup of tea.",
|
|
References: []string{"https://trivy.dev/"},
|
|
},
|
|
CauseMetadata: types.CauseMetadata{
|
|
Resource: "resources[0]",
|
|
Provider: "Cloud",
|
|
Service: "general",
|
|
StartLine: 30,
|
|
EndLine: 40,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/azurearm/single-failure/src",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "multiple failures",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/azurearm/multiple-failures/src",
|
|
},
|
|
artifactOpt: artifact.Option{
|
|
MisconfScannerOption: misconf.ScannerOption{
|
|
Namespaces: []string{"user"},
|
|
PolicyPaths: []string{"./testdata/misconfig/azurearm/multiple-failures/rego"},
|
|
},
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: 2,
|
|
Misconfigurations: []types.Misconfiguration{
|
|
{
|
|
FileType: "azure-arm",
|
|
FilePath: "deploy.json",
|
|
Failures: types.MisconfResults{
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
Message: "No account allowed!",
|
|
PolicyMetadata: types.PolicyMetadata{
|
|
ID: "TEST001",
|
|
AVDID: "AVD-TEST-0001",
|
|
Type: "Azure ARM Security Check",
|
|
Title: "Test policy",
|
|
Description: "This is a test policy.",
|
|
Severity: "LOW",
|
|
RecommendedActions: "Have a cup of tea.",
|
|
References: []string{"https://trivy.dev/"},
|
|
},
|
|
CauseMetadata: types.CauseMetadata{
|
|
Resource: "resources[0]",
|
|
Provider: "Cloud",
|
|
Service: "general",
|
|
StartLine: 30,
|
|
EndLine: 40,
|
|
},
|
|
},
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
Message: "No account allowed!",
|
|
PolicyMetadata: types.PolicyMetadata{
|
|
ID: "TEST001",
|
|
AVDID: "AVD-TEST-0001",
|
|
Type: "Azure ARM Security Check",
|
|
Title: "Test policy",
|
|
Description: "This is a test policy.",
|
|
Severity: "LOW",
|
|
RecommendedActions: "Have a cup of tea.",
|
|
References: []string{"https://trivy.dev/"},
|
|
},
|
|
CauseMetadata: types.CauseMetadata{
|
|
Resource: "resources[1]",
|
|
Provider: "Cloud",
|
|
Service: "general",
|
|
StartLine: 41,
|
|
EndLine: 51,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/azurearm/multiple-failures/src",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "no results",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/azurearm/no-results/src",
|
|
},
|
|
artifactOpt: artifact.Option{
|
|
MisconfScannerOption: misconf.ScannerOption{
|
|
Namespaces: []string{"user"},
|
|
PolicyPaths: []string{"./testdata/misconfig/azurearm/no-results/rego"},
|
|
},
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: types.BlobJSONSchemaVersion,
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/azurearm/no-results/src",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "passed",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/azurearm/passed/src",
|
|
},
|
|
artifactOpt: artifact.Option{
|
|
MisconfScannerOption: misconf.ScannerOption{
|
|
Namespaces: []string{"user"},
|
|
PolicyPaths: []string{"./testdata/misconfig/azurearm/passed/rego"},
|
|
},
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: 2,
|
|
Misconfigurations: []types.Misconfiguration{
|
|
{
|
|
FileType: "azure-arm",
|
|
FilePath: "deploy.json",
|
|
Successes: types.MisconfResults{
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
PolicyMetadata: types.PolicyMetadata{
|
|
ID: "TEST001",
|
|
AVDID: "AVD-TEST-0001",
|
|
Type: "Azure ARM Security Check",
|
|
Title: "Test policy",
|
|
Description: "This is a test policy.",
|
|
Severity: "LOW",
|
|
RecommendedActions: "Have a cup of tea.",
|
|
References: []string{"https://trivy.dev/"},
|
|
},
|
|
CauseMetadata: types.CauseMetadata{
|
|
Provider: "Cloud",
|
|
Service: "general",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/azurearm/passed/src",
|
|
Type: types.TypeFilesystem,
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobIDs: []string{
|
|
"sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Set fake UUID for consistent test results
|
|
uuid.SetFakeUUID(t, "3ff14136-e09f-4df9-80ea-%012d")
|
|
|
|
c := cachetest.NewCache(t, nil)
|
|
tt.artifactOpt.DisabledHandlers = []types.HandlerType{
|
|
types.SystemFileFilteringPostHandler,
|
|
}
|
|
tt.artifactOpt.MisconfScannerOption.DisableEmbeddedPolicies = true
|
|
a, err := NewArtifact(tt.fields.dir, c, walker.NewFS(), tt.artifactOpt)
|
|
require.NoError(t, err)
|
|
|
|
got, err := a.Inspect(t.Context())
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tt.want, got)
|
|
cachetest.AssertBlobs(t, c, tt.wantBlobs)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMixedConfigurationScan(t *testing.T) {
|
|
type fields struct {
|
|
dir string
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
fields fields
|
|
wantBlobs []cachetest.WantBlob
|
|
artifactOpt artifact.Option
|
|
want artifact.Reference
|
|
}{
|
|
{
|
|
name: "single failure each within terraform and cloudformation",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/mixed/src",
|
|
},
|
|
artifactOpt: artifact.Option{
|
|
MisconfScannerOption: misconf.ScannerOption{
|
|
Namespaces: []string{"user"},
|
|
PolicyPaths: []string{"./testdata/misconfig/mixed/rego"},
|
|
DisableEmbeddedLibraries: true,
|
|
},
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: 2,
|
|
Misconfigurations: []types.Misconfiguration{
|
|
{
|
|
FileType: "cloudformation",
|
|
FilePath: "main.yaml",
|
|
Failures: types.MisconfResults{
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
Message: "No buckets allowed!",
|
|
PolicyMetadata: types.PolicyMetadata{
|
|
ID: "TEST001",
|
|
AVDID: "AVD-TEST-0001",
|
|
Type: "CloudFormation Security Check",
|
|
Title: "Test policy",
|
|
Description: "This is a test policy.",
|
|
Severity: "LOW",
|
|
RecommendedActions: "Have a cup of tea.",
|
|
References: []string{"https://trivy.dev/"},
|
|
},
|
|
CauseMetadata: types.CauseMetadata{
|
|
Resource: "main.yaml:3-6",
|
|
Provider: "Cloud",
|
|
Service: "general",
|
|
StartLine: 3,
|
|
EndLine: 6,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
FileType: "terraform",
|
|
FilePath: "main.tf",
|
|
Failures: types.MisconfResults{
|
|
{
|
|
Namespace: "user.something",
|
|
Query: "data.user.something.deny",
|
|
Message: "No buckets allowed!",
|
|
PolicyMetadata: types.PolicyMetadata{
|
|
ID: "TEST001",
|
|
AVDID: "AVD-TEST-0001",
|
|
Type: "Terraform Security Check",
|
|
Title: "Test policy",
|
|
Description: "This is a test policy.",
|
|
Severity: "LOW",
|
|
RecommendedActions: "Have a cup of tea.",
|
|
References: []string{"https://trivy.dev/"},
|
|
},
|
|
CauseMetadata: types.CauseMetadata{
|
|
Resource: "aws_s3_bucket.asd",
|
|
Provider: "Cloud",
|
|
Service: "general",
|
|
StartLine: 1,
|
|
EndLine: 3,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/mixed/src",
|
|
Type: types.TypeFilesystem,
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Set fake UUID for consistent test results
|
|
uuid.SetFakeUUID(t, "3ff14136-e09f-4df9-80ea-%012d")
|
|
|
|
c := cachetest.NewCache(t, nil)
|
|
tt.artifactOpt.DisabledHandlers = []types.HandlerType{
|
|
types.SystemFileFilteringPostHandler,
|
|
}
|
|
tt.artifactOpt.MisconfScannerOption.DisableEmbeddedPolicies = true
|
|
a, err := NewArtifact(tt.fields.dir, c, walker.NewFS(), tt.artifactOpt)
|
|
require.NoError(t, err)
|
|
|
|
got, err := a.Inspect(t.Context())
|
|
require.NoError(t, err)
|
|
require.NotNil(t, got)
|
|
|
|
assert.Equal(t, tt.want.Name, got.Name)
|
|
assert.Equal(t, tt.want.Type, got.Type)
|
|
cachetest.AssertBlobs(t, c, tt.wantBlobs)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestJSONConfigScan(t *testing.T) {
|
|
type fields struct {
|
|
dir string
|
|
schemas []string
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
fields fields
|
|
artifactOpt artifact.Option
|
|
wantBlobs []cachetest.WantBlob
|
|
want artifact.Reference
|
|
}{
|
|
{
|
|
name: "happy path without custom schema",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/json/passed/src",
|
|
},
|
|
artifactOpt: artifact.Option{
|
|
MisconfScannerOption: misconf.ScannerOption{
|
|
Namespaces: []string{"user"},
|
|
PolicyPaths: []string{"./testdata/misconfig/json/passed/checks"},
|
|
},
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: types.BlobJSONSchemaVersion,
|
|
Misconfigurations: []types.Misconfiguration{
|
|
{
|
|
FileType: types.JSON,
|
|
FilePath: "test1.json",
|
|
Failures: types.MisconfResults{
|
|
{
|
|
Namespace: "user.test_json_check",
|
|
Query: "data.user.test_json_check.deny",
|
|
Message: `Service "foo" should not be used`,
|
|
PolicyMetadata: types.PolicyMetadata{
|
|
ID: "TEST001",
|
|
AVDID: "TEST001",
|
|
Type: "JSON Security Check",
|
|
Title: "Test check",
|
|
Severity: "LOW",
|
|
},
|
|
CauseMetadata: types.CauseMetadata{
|
|
Provider: "Generic",
|
|
Service: "general",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
FileType: types.JSON,
|
|
FilePath: "test2.json",
|
|
Failures: types.MisconfResults{
|
|
{
|
|
Namespace: "user.test_json_check",
|
|
Query: "data.user.test_json_check.deny",
|
|
Message: `Provider "bar" should not be used`,
|
|
PolicyMetadata: types.PolicyMetadata{
|
|
ID: "TEST001",
|
|
AVDID: "TEST001",
|
|
Type: "JSON Security Check",
|
|
Title: "Test check",
|
|
Severity: "LOW",
|
|
},
|
|
CauseMetadata: types.CauseMetadata{
|
|
Provider: "Generic",
|
|
Service: "general",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/json/passed/src",
|
|
Type: types.TypeFilesystem,
|
|
},
|
|
},
|
|
{
|
|
name: "happy path with custom schema",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/json/with-schema/src",
|
|
schemas: []string{"./testdata/misconfig/json/with-schema/schemas"},
|
|
},
|
|
artifactOpt: artifact.Option{
|
|
MisconfScannerOption: misconf.ScannerOption{
|
|
Namespaces: []string{"user"},
|
|
PolicyPaths: []string{"./testdata/misconfig/json/with-schema/checks"},
|
|
},
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: types.BlobJSONSchemaVersion,
|
|
Misconfigurations: []types.Misconfiguration{
|
|
{
|
|
FileType: types.JSON,
|
|
FilePath: "test1.json",
|
|
Failures: types.MisconfResults{
|
|
{
|
|
Namespace: "user.test_json_check",
|
|
Query: "data.user.test_json_check.deny",
|
|
Message: `Service "foo" should not be used`,
|
|
PolicyMetadata: types.PolicyMetadata{
|
|
ID: "TEST001",
|
|
AVDID: "TEST001",
|
|
Type: "JSON Security Check",
|
|
Title: "Test check",
|
|
Severity: "LOW",
|
|
},
|
|
CauseMetadata: types.CauseMetadata{
|
|
Provider: "Generic",
|
|
Service: "general",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/json/with-schema/src",
|
|
Type: types.TypeFilesystem,
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Set fake UUID for consistent test results
|
|
uuid.SetFakeUUID(t, "3ff14136-e09f-4df9-80ea-%012d")
|
|
|
|
c := cachetest.NewCache(t, nil)
|
|
|
|
tt.artifactOpt.MisconfScannerOption.DisableEmbeddedPolicies = true
|
|
if len(tt.fields.schemas) > 0 {
|
|
schemas, err := misconf.LoadConfigSchemas(tt.fields.schemas)
|
|
require.NoError(t, err)
|
|
tt.artifactOpt.MisconfScannerOption.ConfigFileSchemas = schemas
|
|
}
|
|
|
|
a, err := NewArtifact(tt.fields.dir, c, walker.NewFS(), tt.artifactOpt)
|
|
require.NoError(t, err)
|
|
|
|
got, err := a.Inspect(t.Context())
|
|
require.NoError(t, err)
|
|
require.NotNil(t, got)
|
|
|
|
assert.Equal(t, tt.want.Name, got.Name)
|
|
assert.Equal(t, tt.want.Type, got.Type)
|
|
cachetest.AssertBlobs(t, c, tt.wantBlobs)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestYAMLConfigScan(t *testing.T) {
|
|
type fields struct {
|
|
dir string
|
|
schemas []string
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
fields fields
|
|
artifactOpt artifact.Option
|
|
wantBlobs []cachetest.WantBlob
|
|
want artifact.Reference
|
|
}{
|
|
{
|
|
name: "happy path without custom schema",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/yaml/passed/src",
|
|
},
|
|
artifactOpt: artifact.Option{
|
|
MisconfScannerOption: misconf.ScannerOption{
|
|
Namespaces: []string{"user"},
|
|
PolicyPaths: []string{"./testdata/misconfig/yaml/passed/checks"},
|
|
},
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: types.BlobJSONSchemaVersion,
|
|
Misconfigurations: []types.Misconfiguration{
|
|
{
|
|
FileType: types.YAML,
|
|
FilePath: "test1.yaml",
|
|
Failures: types.MisconfResults{
|
|
{
|
|
Namespace: "user.test_yaml_check",
|
|
Query: "data.user.test_yaml_check.deny",
|
|
Message: `Service "foo" should not be used`,
|
|
PolicyMetadata: types.PolicyMetadata{
|
|
ID: "TEST001",
|
|
AVDID: "TEST001",
|
|
Type: "YAML Security Check",
|
|
Title: "Test check",
|
|
Severity: "LOW",
|
|
},
|
|
CauseMetadata: types.CauseMetadata{
|
|
Provider: "Generic",
|
|
Service: "general",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
FileType: types.YAML,
|
|
FilePath: "test2.yml",
|
|
Failures: types.MisconfResults{
|
|
{
|
|
Namespace: "user.test_yaml_check",
|
|
Query: "data.user.test_yaml_check.deny",
|
|
Message: `Provider "bar" should not be used`,
|
|
PolicyMetadata: types.PolicyMetadata{
|
|
ID: "TEST001",
|
|
AVDID: "TEST001",
|
|
Type: "YAML Security Check",
|
|
Title: "Test check",
|
|
Severity: "LOW",
|
|
},
|
|
CauseMetadata: types.CauseMetadata{
|
|
Provider: "Generic",
|
|
Service: "general",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/yaml/passed/src",
|
|
Type: types.TypeFilesystem,
|
|
},
|
|
},
|
|
{
|
|
name: "happy path with custom schema",
|
|
fields: fields{
|
|
dir: "./testdata/misconfig/yaml/with-schema/src",
|
|
schemas: []string{"./testdata/misconfig/yaml/with-schema/schemas"},
|
|
},
|
|
artifactOpt: artifact.Option{
|
|
MisconfScannerOption: misconf.ScannerOption{
|
|
Namespaces: []string{"user"},
|
|
PolicyPaths: []string{"./testdata/misconfig/yaml/with-schema/checks"},
|
|
},
|
|
},
|
|
wantBlobs: []cachetest.WantBlob{
|
|
{
|
|
ID: "sha256:6f4672e139d4066fd00391df614cdf42bda5f7a3f005d39e1d8600be86157098",
|
|
BlobInfo: types.BlobInfo{
|
|
SchemaVersion: types.BlobJSONSchemaVersion,
|
|
Misconfigurations: []types.Misconfiguration{
|
|
{
|
|
FileType: types.YAML,
|
|
FilePath: "test1.yaml",
|
|
Failures: types.MisconfResults{
|
|
{
|
|
Namespace: "user.test_yaml_check",
|
|
Query: "data.user.test_yaml_check.deny",
|
|
Message: `Service "foo" should not be used`,
|
|
PolicyMetadata: types.PolicyMetadata{
|
|
ID: "TEST001",
|
|
AVDID: "TEST001",
|
|
Type: "YAML Security Check",
|
|
Title: "Test check",
|
|
Severity: "LOW",
|
|
},
|
|
CauseMetadata: types.CauseMetadata{
|
|
Provider: "Generic",
|
|
Service: "general",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: artifact.Reference{
|
|
Name: "testdata/misconfig/yaml/with-schema/src",
|
|
Type: types.TypeFilesystem,
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Set fake UUID for consistent test results
|
|
uuid.SetFakeUUID(t, "3ff14136-e09f-4df9-80ea-%012d")
|
|
|
|
c := cachetest.NewCache(t, nil)
|
|
|
|
tt.artifactOpt.MisconfScannerOption.DisableEmbeddedPolicies = true
|
|
if len(tt.fields.schemas) > 0 {
|
|
schemas, err := misconf.LoadConfigSchemas(tt.fields.schemas)
|
|
require.NoError(t, err)
|
|
tt.artifactOpt.MisconfScannerOption.ConfigFileSchemas = schemas
|
|
}
|
|
|
|
a, err := NewArtifact(tt.fields.dir, c, walker.NewFS(), tt.artifactOpt)
|
|
require.NoError(t, err)
|
|
|
|
got, err := a.Inspect(t.Context())
|
|
require.NoError(t, err)
|
|
require.NotNil(t, got)
|
|
|
|
assert.Equal(t, tt.want.Name, got.Name)
|
|
assert.Equal(t, tt.want.Type, got.Type)
|
|
cachetest.AssertBlobs(t, c, tt.wantBlobs)
|
|
})
|
|
}
|
|
}
|
|
|
|
// recordingWalker wraps an existing walker and records which paths were walked
|
|
type recordingWalker struct {
|
|
base Walker
|
|
walkedRoots []string
|
|
}
|
|
|
|
func newRecordingWalker(base Walker) *recordingWalker {
|
|
return &recordingWalker{
|
|
base: base,
|
|
}
|
|
}
|
|
|
|
func (w *recordingWalker) Walk(root string, option walker.Option, walkFn walker.WalkFunc) error {
|
|
w.walkedRoots = append(w.walkedRoots, filepath.ToSlash(root))
|
|
// Call the original walker
|
|
return w.base.Walk(root, option, walkFn)
|
|
}
|
|
|
|
// TestArtifact_AnalysisStrategy tests the different analysis strategies
|
|
func TestArtifact_AnalysisStrategy(t *testing.T) {
|
|
// Use testdata/alpine directly
|
|
testDir := "testdata/alpine"
|
|
|
|
tests := []struct {
|
|
name string
|
|
disabledAnalyzers []analyzer.Type
|
|
wantRoots []string
|
|
}{
|
|
{
|
|
name: "static paths",
|
|
disabledAnalyzers: append(analyzer.TypeConfigFiles, analyzer.TypePip, analyzer.TypeSecret),
|
|
wantRoots: []string{
|
|
"testdata/alpine/etc/alpine-release",
|
|
"testdata/alpine/lib/apk/db/installed",
|
|
},
|
|
},
|
|
{
|
|
name: "traversing root dir",
|
|
wantRoots: []string{
|
|
testDir, // only the root directory is walked
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Create a new artifact with the recording walker
|
|
baseWalker := walker.NewFS()
|
|
rw := newRecordingWalker(baseWalker)
|
|
|
|
// Create artifact with recording walker
|
|
a, err := NewArtifact(testDir, cache.NewMemoryCache(), rw, artifact.Option{
|
|
DisabledAnalyzers: tt.disabledAnalyzers,
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Run the inspection
|
|
_, err = a.Inspect(t.Context())
|
|
require.NoError(t, err)
|
|
|
|
// Check if the walked roots match the expected roots
|
|
assert.ElementsMatch(t, tt.wantRoots, rw.walkedRoots)
|
|
})
|
|
}
|
|
}
|