github.com/devseccon/trivy@v0.47.1-0.20231123133102-bd902a0bd996/pkg/fanal/artifact/local/fs_test.go (about)

     1  package local
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"path/filepath"
     7  	"runtime"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  	"golang.org/x/exp/slices"
    13  
    14  	"github.com/devseccon/trivy/pkg/fanal/analyzer"
    15  	"github.com/devseccon/trivy/pkg/fanal/artifact"
    16  	"github.com/devseccon/trivy/pkg/fanal/cache"
    17  	"github.com/devseccon/trivy/pkg/fanal/types"
    18  	"github.com/devseccon/trivy/pkg/misconf"
    19  
    20  	_ "github.com/devseccon/trivy/pkg/fanal/analyzer/config/all"
    21  	_ "github.com/devseccon/trivy/pkg/fanal/analyzer/language/python/pip"
    22  	_ "github.com/devseccon/trivy/pkg/fanal/analyzer/os/alpine"
    23  	_ "github.com/devseccon/trivy/pkg/fanal/analyzer/pkg/apk"
    24  	_ "github.com/devseccon/trivy/pkg/fanal/analyzer/secret"
    25  	_ "github.com/devseccon/trivy/pkg/fanal/handler/sysfile"
    26  )
    27  
    28  func TestArtifact_Inspect(t *testing.T) {
    29  	type fields struct {
    30  		dir string
    31  	}
    32  	tests := []struct {
    33  		name               string
    34  		fields             fields
    35  		artifactOpt        artifact.Option
    36  		scannerOpt         misconf.ScannerOption
    37  		disabledAnalyzers  []analyzer.Type
    38  		disabledHandlers   []types.HandlerType
    39  		putBlobExpectation cache.ArtifactCachePutBlobExpectation
    40  		want               types.ArtifactReference
    41  		wantErr            string
    42  	}{
    43  		{
    44  			name: "happy path",
    45  			fields: fields{
    46  				dir: "./testdata/alpine",
    47  			},
    48  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
    49  				Args: cache.ArtifactCachePutBlobArgs{
    50  					BlobID: "sha256:bb194ca778e3ecfa4b2addeae7b2c6b22ed10ab054b9d23e601c54e332913055",
    51  					BlobInfo: types.BlobInfo{
    52  						SchemaVersion: types.BlobJSONSchemaVersion,
    53  						OS: types.OS{
    54  							Family: "alpine",
    55  							Name:   "3.11.6",
    56  						},
    57  						PackageInfos: []types.PackageInfo{
    58  							{
    59  								FilePath: "lib/apk/db/installed",
    60  								Packages: types.Packages{
    61  									{
    62  										ID:         "musl@1.1.24-r2",
    63  										Name:       "musl",
    64  										Version:    "1.1.24-r2",
    65  										SrcName:    "musl",
    66  										SrcVersion: "1.1.24-r2",
    67  										Licenses:   []string{"MIT"},
    68  										Arch:       "x86_64",
    69  										Digest:     "sha1:cb2316a189ebee5282c4a9bd98794cc2477a74c6",
    70  										InstalledFiles: []string{
    71  											"lib/libc.musl-x86_64.so.1",
    72  											"lib/ld-musl-x86_64.so.1",
    73  										},
    74  									},
    75  								},
    76  							},
    77  						},
    78  					},
    79  				},
    80  				Returns: cache.ArtifactCachePutBlobReturns{},
    81  			},
    82  			want: types.ArtifactReference{
    83  				Name: "host",
    84  				Type: types.ArtifactFilesystem,
    85  				ID:   "sha256:bb194ca778e3ecfa4b2addeae7b2c6b22ed10ab054b9d23e601c54e332913055",
    86  				BlobIDs: []string{
    87  					"sha256:bb194ca778e3ecfa4b2addeae7b2c6b22ed10ab054b9d23e601c54e332913055",
    88  				},
    89  			},
    90  		},
    91  		{
    92  			name: "disable analyzers",
    93  			fields: fields{
    94  				dir: "./testdata/alpine",
    95  			},
    96  			artifactOpt: artifact.Option{
    97  				DisabledAnalyzers: []analyzer.Type{
    98  					analyzer.TypeAlpine,
    99  					analyzer.TypeApk,
   100  					analyzer.TypePip,
   101  				},
   102  			},
   103  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
   104  				Args: cache.ArtifactCachePutBlobArgs{
   105  					BlobID: "sha256:d5fa75cdac006582a8f6bc4e3fcc8bfb70bd9d0403c24d8c2e3230d3f38a7ff5",
   106  					BlobInfo: types.BlobInfo{
   107  						SchemaVersion: types.BlobJSONSchemaVersion,
   108  					},
   109  				},
   110  				Returns: cache.ArtifactCachePutBlobReturns{},
   111  			},
   112  			want: types.ArtifactReference{
   113  				Name: "host",
   114  				Type: types.ArtifactFilesystem,
   115  				ID:   "sha256:d5fa75cdac006582a8f6bc4e3fcc8bfb70bd9d0403c24d8c2e3230d3f38a7ff5",
   116  				BlobIDs: []string{
   117  					"sha256:d5fa75cdac006582a8f6bc4e3fcc8bfb70bd9d0403c24d8c2e3230d3f38a7ff5",
   118  				},
   119  			},
   120  		},
   121  		{
   122  			name: "sad path PutBlob returns an error",
   123  			fields: fields{
   124  				dir: "./testdata/alpine",
   125  			},
   126  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
   127  				Args: cache.ArtifactCachePutBlobArgs{
   128  					BlobID: "sha256:bb194ca778e3ecfa4b2addeae7b2c6b22ed10ab054b9d23e601c54e332913055",
   129  					BlobInfo: types.BlobInfo{
   130  						SchemaVersion: types.BlobJSONSchemaVersion,
   131  						OS: types.OS{
   132  							Family: "alpine",
   133  							Name:   "3.11.6",
   134  						},
   135  						PackageInfos: []types.PackageInfo{
   136  							{
   137  								FilePath: "lib/apk/db/installed",
   138  								Packages: types.Packages{
   139  									{
   140  										ID:         "musl@1.1.24-r2",
   141  										Name:       "musl",
   142  										Version:    "1.1.24-r2",
   143  										SrcName:    "musl",
   144  										SrcVersion: "1.1.24-r2",
   145  										Licenses:   []string{"MIT"},
   146  										Arch:       "x86_64",
   147  										Digest:     "sha1:cb2316a189ebee5282c4a9bd98794cc2477a74c6",
   148  										InstalledFiles: []string{
   149  											"lib/libc.musl-x86_64.so.1",
   150  											"lib/ld-musl-x86_64.so.1",
   151  										},
   152  									},
   153  								},
   154  							},
   155  						},
   156  					},
   157  				},
   158  				Returns: cache.ArtifactCachePutBlobReturns{
   159  					Err: errors.New("error"),
   160  				},
   161  			},
   162  			wantErr: "failed to store blob",
   163  		},
   164  		{
   165  			name: "sad path with no such directory",
   166  			fields: fields{
   167  				dir: "./testdata/unknown",
   168  			},
   169  			wantErr: "walk dir error",
   170  		},
   171  		{
   172  			name: "happy path with single file",
   173  			fields: fields{
   174  				dir: "testdata/requirements.txt",
   175  			},
   176  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
   177  				Args: cache.ArtifactCachePutBlobArgs{
   178  					BlobID: "sha256:0e0d362332d8928f71ac2c11e0813e2ec251dca9bdf1a66bd69cad8f2ef66ca1",
   179  					BlobInfo: types.BlobInfo{
   180  						SchemaVersion: types.BlobJSONSchemaVersion,
   181  						Applications: []types.Application{
   182  							{
   183  								Type:     "pip",
   184  								FilePath: "requirements.txt",
   185  								Libraries: types.Packages{
   186  									{
   187  										Name:    "Flask",
   188  										Version: "2.0.0",
   189  									},
   190  								},
   191  							},
   192  						},
   193  					},
   194  				},
   195  				Returns: cache.ArtifactCachePutBlobReturns{},
   196  			},
   197  			want: types.ArtifactReference{
   198  				Name: "testdata/requirements.txt",
   199  				Type: types.ArtifactFilesystem,
   200  				ID:   "sha256:0e0d362332d8928f71ac2c11e0813e2ec251dca9bdf1a66bd69cad8f2ef66ca1",
   201  				BlobIDs: []string{
   202  					"sha256:0e0d362332d8928f71ac2c11e0813e2ec251dca9bdf1a66bd69cad8f2ef66ca1",
   203  				},
   204  			},
   205  		},
   206  		{
   207  			name: "happy path with single file using relative path",
   208  			fields: fields{
   209  				dir: "./testdata/requirements.txt",
   210  			},
   211  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
   212  				Args: cache.ArtifactCachePutBlobArgs{
   213  					BlobID: "sha256:0e0d362332d8928f71ac2c11e0813e2ec251dca9bdf1a66bd69cad8f2ef66ca1",
   214  					BlobInfo: types.BlobInfo{
   215  						SchemaVersion: types.BlobJSONSchemaVersion,
   216  						Applications: []types.Application{
   217  							{
   218  								Type:     "pip",
   219  								FilePath: "requirements.txt",
   220  								Libraries: types.Packages{
   221  									{
   222  										Name:    "Flask",
   223  										Version: "2.0.0",
   224  									},
   225  								},
   226  							},
   227  						},
   228  					},
   229  				},
   230  				Returns: cache.ArtifactCachePutBlobReturns{},
   231  			},
   232  			want: types.ArtifactReference{
   233  				Name: "testdata/requirements.txt",
   234  				Type: types.ArtifactFilesystem,
   235  				ID:   "sha256:0e0d362332d8928f71ac2c11e0813e2ec251dca9bdf1a66bd69cad8f2ef66ca1",
   236  				BlobIDs: []string{
   237  					"sha256:0e0d362332d8928f71ac2c11e0813e2ec251dca9bdf1a66bd69cad8f2ef66ca1",
   238  				},
   239  			},
   240  		},
   241  	}
   242  	for _, tt := range tests {
   243  		t.Run(tt.name, func(t *testing.T) {
   244  			c := new(cache.MockArtifactCache)
   245  			c.ApplyPutBlobExpectation(tt.putBlobExpectation)
   246  
   247  			a, err := NewArtifact(tt.fields.dir, c, tt.artifactOpt)
   248  			require.NoError(t, err)
   249  
   250  			got, err := a.Inspect(context.Background())
   251  			if tt.wantErr != "" {
   252  				require.NotNil(t, err)
   253  				assert.Contains(t, err.Error(), tt.wantErr)
   254  				return
   255  			} else {
   256  				require.NoError(t, err)
   257  			}
   258  			assert.Equal(t, tt.want, got)
   259  		})
   260  	}
   261  }
   262  
   263  func TestBuildPathsToSkip(t *testing.T) {
   264  	tests := []struct {
   265  		name  string
   266  		oses  []string
   267  		paths []string
   268  		base  string
   269  		want  []string
   270  	}{
   271  		// Linux/macOS
   272  		{
   273  			name: "path - abs, base - abs, not joining paths",
   274  			oses: []string{
   275  				"linux",
   276  				"darwin",
   277  			},
   278  			base:  "/foo",
   279  			paths: []string{"/foo/bar"},
   280  			want:  []string{"bar"},
   281  		},
   282  		{
   283  			name: "path - abs, base - rel",
   284  			oses: []string{
   285  				"linux",
   286  				"darwin",
   287  			},
   288  			base: "foo",
   289  			paths: func() []string {
   290  				abs, err := filepath.Abs("foo/bar")
   291  				require.NoError(t, err)
   292  				return []string{abs}
   293  			}(),
   294  			want: []string{"bar"},
   295  		},
   296  		{
   297  			name: "path - rel, base - rel, joining paths",
   298  			oses: []string{
   299  				"linux",
   300  				"darwin",
   301  			},
   302  			base:  "foo",
   303  			paths: []string{"bar"},
   304  			want:  []string{"bar"},
   305  		},
   306  		{
   307  			name: "path - rel, base - rel, not joining paths",
   308  			oses: []string{
   309  				"linux",
   310  				"darwin",
   311  			},
   312  			base:  "foo",
   313  			paths: []string{"foo/bar/bar"},
   314  			want:  []string{"bar/bar"},
   315  		},
   316  		{
   317  			name: "path - rel with dot, base - rel, removing the leading dot and not joining paths",
   318  			oses: []string{
   319  				"linux",
   320  				"darwin",
   321  			},
   322  			base:  "foo",
   323  			paths: []string{"./foo/bar"},
   324  			want:  []string{"bar"},
   325  		},
   326  		{
   327  			name: "path - rel, base - dot",
   328  			oses: []string{
   329  				"linux",
   330  				"darwin",
   331  			},
   332  			base:  ".",
   333  			paths: []string{"foo/bar"},
   334  			want:  []string{"foo/bar"},
   335  		},
   336  		// Windows
   337  		{
   338  			name:  "path - rel, base - rel. Skip common prefix",
   339  			oses:  []string{"windows"},
   340  			base:  "foo",
   341  			paths: []string{"foo\\bar\\bar"},
   342  			want:  []string{"bar/bar"},
   343  		},
   344  		{
   345  			name:  "path - rel, base - dot, windows",
   346  			oses:  []string{"windows"},
   347  			base:  ".",
   348  			paths: []string{"foo\\bar"},
   349  			want:  []string{"foo/bar"},
   350  		},
   351  	}
   352  
   353  	for _, tt := range tests {
   354  		t.Run(tt.name, func(t *testing.T) {
   355  			if !slices.Contains(tt.oses, runtime.GOOS) {
   356  				t.Skipf("Skip path tests for %q", tt.oses)
   357  			}
   358  			got := buildPathsToSkip(tt.base, tt.paths)
   359  			assert.Equal(t, tt.want, got)
   360  		})
   361  	}
   362  }
   363  
   364  var policyMetadata = types.PolicyMetadata{
   365  	ID:                 "TEST001",
   366  	AVDID:              "AVD-TEST-0001",
   367  	Type:               "Terraform Security Check",
   368  	Title:              "Test policy",
   369  	Description:        "This is a test policy.",
   370  	Severity:           "LOW",
   371  	RecommendedActions: "Have a cup of tea.",
   372  	References:         []string{"https://trivy.dev/"},
   373  }
   374  
   375  func TestTerraformMisconfigurationScan(t *testing.T) {
   376  	type fields struct {
   377  		dir string
   378  	}
   379  	tests := []struct {
   380  		name               string
   381  		fields             fields
   382  		putBlobExpectation cache.ArtifactCachePutBlobExpectation
   383  		artifactOpt        artifact.Option
   384  		want               types.ArtifactReference
   385  	}{
   386  		{
   387  			name: "single failure",
   388  			fields: fields{
   389  				dir: "./testdata/misconfig/terraform/single-failure",
   390  			},
   391  			artifactOpt: artifact.Option{
   392  				MisconfScannerOption: misconf.ScannerOption{
   393  					RegoOnly:                 true,
   394  					Namespaces:               []string{"user"},
   395  					PolicyPaths:              []string{"./testdata/misconfig/terraform/rego"},
   396  					DisableEmbeddedPolicies:  true,
   397  					DisableEmbeddedLibraries: true,
   398  				},
   399  			},
   400  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
   401  				Args: cache.ArtifactCachePutBlobArgs{
   402  					BlobIDAnything: true,
   403  					BlobInfo: types.BlobInfo{
   404  						SchemaVersion: 2,
   405  						Misconfigurations: []types.Misconfiguration{
   406  							{
   407  								FileType: "terraform",
   408  								FilePath: "main.tf",
   409  								Failures: types.MisconfResults{
   410  									{
   411  										Namespace:      "user.something",
   412  										Query:          "data.user.something.deny",
   413  										Message:        "Empty bucket name!",
   414  										PolicyMetadata: policyMetadata,
   415  										CauseMetadata: types.CauseMetadata{
   416  											Resource:  "aws_s3_bucket.asd",
   417  											Provider:  "Generic",
   418  											Service:   "general",
   419  											StartLine: 1,
   420  											EndLine:   3,
   421  										},
   422  									},
   423  								},
   424  							},
   425  						},
   426  					},
   427  				},
   428  				Returns: cache.ArtifactCachePutBlobReturns{},
   429  			},
   430  			want: types.ArtifactReference{
   431  				Name: "testdata/misconfig/terraform/single-failure",
   432  				Type: types.ArtifactFilesystem,
   433  				ID:   "sha256:51123b27efc62be0db21fad4ccaf0839850f9f9162d225c6bd9d0e94089b2d8b",
   434  				BlobIDs: []string{
   435  					"sha256:51123b27efc62be0db21fad4ccaf0839850f9f9162d225c6bd9d0e94089b2d8b",
   436  				},
   437  			},
   438  		},
   439  		{
   440  			name: "multiple failures",
   441  			fields: fields{
   442  				dir: "./testdata/misconfig/terraform/multiple-failures",
   443  			},
   444  			artifactOpt: artifact.Option{
   445  				MisconfScannerOption: misconf.ScannerOption{
   446  					RegoOnly:                 true,
   447  					Namespaces:               []string{"user"},
   448  					PolicyPaths:              []string{"./testdata/misconfig/terraform/rego"},
   449  					DisableEmbeddedPolicies:  true,
   450  					DisableEmbeddedLibraries: true,
   451  				},
   452  			},
   453  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
   454  				Args: cache.ArtifactCachePutBlobArgs{
   455  					BlobIDAnything: true,
   456  					BlobInfo: types.BlobInfo{
   457  						SchemaVersion: 2,
   458  						Misconfigurations: []types.Misconfiguration{
   459  							{
   460  								FileType: "terraform",
   461  								FilePath: "main.tf",
   462  								Failures: types.MisconfResults{
   463  									{
   464  										Namespace:      "user.something",
   465  										Query:          "data.user.something.deny",
   466  										Message:        "Empty bucket name!",
   467  										PolicyMetadata: policyMetadata,
   468  										CauseMetadata: types.CauseMetadata{
   469  											Resource:  "aws_s3_bucket.one",
   470  											Provider:  "Generic",
   471  											Service:   "general",
   472  											StartLine: 1,
   473  											EndLine:   3,
   474  										},
   475  									},
   476  									{
   477  										Namespace:      "user.something",
   478  										Query:          "data.user.something.deny",
   479  										Message:        "Empty bucket name!",
   480  										PolicyMetadata: policyMetadata,
   481  										CauseMetadata: types.CauseMetadata{
   482  											Resource:  "aws_s3_bucket.two",
   483  											Provider:  "Generic",
   484  											Service:   "general",
   485  											StartLine: 5,
   486  											EndLine:   7,
   487  										},
   488  									},
   489  								},
   490  							},
   491  							{
   492  								FileType: "terraform",
   493  								FilePath: "more.tf",
   494  								Failures: types.MisconfResults{
   495  									{
   496  										Namespace:      "user.something",
   497  										Query:          "data.user.something.deny",
   498  										Message:        "Empty bucket name!",
   499  										PolicyMetadata: policyMetadata,
   500  										CauseMetadata: types.CauseMetadata{
   501  											Resource:  "aws_s3_bucket.three",
   502  											Provider:  "Generic",
   503  											Service:   "general",
   504  											StartLine: 1,
   505  											EndLine:   3,
   506  										},
   507  									},
   508  								},
   509  							},
   510  						},
   511  					},
   512  				},
   513  				Returns: cache.ArtifactCachePutBlobReturns{},
   514  			},
   515  			want: types.ArtifactReference{
   516  				Name: "testdata/misconfig/terraform/multiple-failures",
   517  				Type: types.ArtifactFilesystem,
   518  				ID:   "sha256:e5159ce9589ca0fd714cbbb757628fffff31229a52310ea151ae1410be5f1f1b",
   519  				BlobIDs: []string{
   520  					"sha256:e5159ce9589ca0fd714cbbb757628fffff31229a52310ea151ae1410be5f1f1b",
   521  				},
   522  			},
   523  		},
   524  		{
   525  			name: "no results",
   526  			fields: fields{
   527  				dir: "./testdata/misconfig/terraform/no-results",
   528  			},
   529  			artifactOpt: artifact.Option{
   530  				MisconfScannerOption: misconf.ScannerOption{
   531  					RegoOnly:    true,
   532  					Namespaces:  []string{"user"},
   533  					PolicyPaths: []string{"./testdata/misconfig/terraform/rego"},
   534  				},
   535  			},
   536  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
   537  				Args: cache.ArtifactCachePutBlobArgs{
   538  					BlobIDAnything: true,
   539  					BlobInfo: types.BlobInfo{
   540  						SchemaVersion: types.BlobJSONSchemaVersion,
   541  					},
   542  				},
   543  				Returns: cache.ArtifactCachePutBlobReturns{},
   544  			},
   545  			want: types.ArtifactReference{
   546  				Name: "testdata/misconfig/terraform/no-results",
   547  				Type: types.ArtifactFilesystem,
   548  				ID:   "sha256:0c31a344fe889e279aecf743d801ae5d40ee2841a45ed7820114c1094c41a966",
   549  				BlobIDs: []string{
   550  					"sha256:0c31a344fe889e279aecf743d801ae5d40ee2841a45ed7820114c1094c41a966",
   551  				},
   552  			},
   553  		},
   554  		{
   555  			name: "passed",
   556  			fields: fields{
   557  				dir: "./testdata/misconfig/terraform/passed",
   558  			},
   559  			artifactOpt: artifact.Option{
   560  				MisconfScannerOption: misconf.ScannerOption{
   561  					RegoOnly:                 true,
   562  					Namespaces:               []string{"user"},
   563  					PolicyPaths:              []string{"./testdata/misconfig/terraform/rego"},
   564  					DisableEmbeddedPolicies:  true,
   565  					DisableEmbeddedLibraries: true,
   566  				},
   567  			},
   568  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
   569  				Args: cache.ArtifactCachePutBlobArgs{
   570  					BlobIDAnything: true,
   571  					BlobInfo: types.BlobInfo{
   572  						SchemaVersion: 2,
   573  						Misconfigurations: []types.Misconfiguration{
   574  							{
   575  								FileType: "terraform",
   576  								FilePath: ".",
   577  								Successes: types.MisconfResults{
   578  									{
   579  										Namespace:      "user.something",
   580  										Query:          "data.user.something.deny",
   581  										PolicyMetadata: policyMetadata,
   582  										CauseMetadata: types.CauseMetadata{
   583  											Provider: "Generic",
   584  											Service:  "general",
   585  										},
   586  									},
   587  								},
   588  							},
   589  						},
   590  					},
   591  				},
   592  				Returns: cache.ArtifactCachePutBlobReturns{},
   593  			},
   594  			want: types.ArtifactReference{
   595  				Name: "testdata/misconfig/terraform/passed",
   596  				Type: types.ArtifactFilesystem,
   597  				ID:   "sha256:4e2b9cba04625f1d9cc57f74640d039779b0ee176e958aaea37883e03842056d",
   598  				BlobIDs: []string{
   599  					"sha256:4e2b9cba04625f1d9cc57f74640d039779b0ee176e958aaea37883e03842056d",
   600  				},
   601  			},
   602  		},
   603  		{
   604  			name: "multiple failures busted relative paths",
   605  			fields: fields{
   606  				dir: "./testdata/misconfig/terraform/busted-relative-paths/child/main.tf",
   607  			},
   608  			artifactOpt: artifact.Option{
   609  				MisconfScannerOption: misconf.ScannerOption{
   610  					RegoOnly:                 true,
   611  					Namespaces:               []string{"user"},
   612  					PolicyPaths:              []string{"./testdata/misconfig/terraform/rego"},
   613  					DisableEmbeddedPolicies:  true,
   614  					DisableEmbeddedLibraries: true,
   615  				},
   616  			},
   617  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
   618  				Args: cache.ArtifactCachePutBlobArgs{
   619  					BlobIDAnything: true,
   620  					BlobInfo: types.BlobInfo{
   621  						SchemaVersion: 2,
   622  						Misconfigurations: []types.Misconfiguration{
   623  							{
   624  								FileType: "terraform",
   625  								FilePath: "main.tf",
   626  								Failures: types.MisconfResults{
   627  									{
   628  										Namespace:      "user.something",
   629  										Query:          "data.user.something.deny",
   630  										Message:        "Empty bucket name!",
   631  										PolicyMetadata: policyMetadata,
   632  										CauseMetadata: types.CauseMetadata{
   633  											Resource:  "aws_s3_bucket.one",
   634  											Provider:  "Generic",
   635  											Service:   "general",
   636  											StartLine: 1,
   637  											EndLine:   3,
   638  										},
   639  									},
   640  									{
   641  										Namespace:      "user.something",
   642  										Query:          "data.user.something.deny",
   643  										Message:        "Empty bucket name!",
   644  										PolicyMetadata: policyMetadata,
   645  										CauseMetadata: types.CauseMetadata{
   646  											Resource:  "aws_s3_bucket.two",
   647  											Provider:  "Generic",
   648  											Service:   "general",
   649  											StartLine: 5,
   650  											EndLine:   7,
   651  										},
   652  									},
   653  								},
   654  							},
   655  						},
   656  					},
   657  				},
   658  				Returns: cache.ArtifactCachePutBlobReturns{},
   659  			},
   660  			want: types.ArtifactReference{
   661  				Name: "testdata/misconfig/terraform/busted-relative-paths/child/main.tf",
   662  				Type: types.ArtifactFilesystem,
   663  				ID:   "sha256:aacaabaaef04916bc31b5200617a07ca5c92a4eab1b94783cde06cc4b24412d2",
   664  				BlobIDs: []string{
   665  					"sha256:aacaabaaef04916bc31b5200617a07ca5c92a4eab1b94783cde06cc4b24412d2",
   666  				},
   667  			},
   668  		},
   669  		{
   670  			name: "tfvars outside the scan folder",
   671  			fields: fields{
   672  				dir: "./testdata/misconfig/terraform/tfvar-outside/tf",
   673  			},
   674  			artifactOpt: artifact.Option{
   675  				MisconfScannerOption: misconf.ScannerOption{
   676  					RegoOnly:                true,
   677  					Namespaces:              []string{"user"},
   678  					PolicyPaths:             []string{"./testdata/misconfig/terraform/rego"},
   679  					TerraformTFVars:         []string{"./testdata/misconfig/terraform/tfvar-outside/main.tfvars"},
   680  					TfExcludeDownloaded:     true,
   681  					DisableEmbeddedPolicies: true,
   682  				},
   683  			},
   684  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
   685  				Args: cache.ArtifactCachePutBlobArgs{
   686  					BlobIDAnything: true,
   687  					BlobInfo: types.BlobInfo{
   688  						SchemaVersion: 2,
   689  						Misconfigurations: []types.Misconfiguration{
   690  							{
   691  								FileType: types.Terraform,
   692  								FilePath: ".",
   693  								Successes: types.MisconfResults{
   694  									{
   695  										Namespace:      "user.something",
   696  										Query:          "data.user.something.deny",
   697  										PolicyMetadata: policyMetadata,
   698  										CauseMetadata: types.CauseMetadata{
   699  											Provider: "Generic",
   700  											Service:  "general",
   701  										},
   702  									},
   703  								},
   704  							},
   705  						},
   706  					},
   707  				},
   708  				Returns: cache.ArtifactCachePutBlobReturns{},
   709  			},
   710  			want: types.ArtifactReference{
   711  				Name: "testdata/misconfig/terraform/tfvar-outside/tf",
   712  				Type: types.ArtifactFilesystem,
   713  				ID:   "sha256:4e2b9cba04625f1d9cc57f74640d039779b0ee176e958aaea37883e03842056d",
   714  				BlobIDs: []string{
   715  					"sha256:4e2b9cba04625f1d9cc57f74640d039779b0ee176e958aaea37883e03842056d",
   716  				},
   717  			},
   718  		},
   719  		{
   720  			name: "relative paths",
   721  			fields: fields{
   722  				dir: "./testdata/misconfig/terraform/relative-paths/child",
   723  			},
   724  			artifactOpt: artifact.Option{
   725  				MisconfScannerOption: misconf.ScannerOption{
   726  					RegoOnly:                true,
   727  					Namespaces:              []string{"user"},
   728  					PolicyPaths:             []string{"./testdata/misconfig/terraform/rego"},
   729  					DisableEmbeddedPolicies: true,
   730  				},
   731  			},
   732  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
   733  				Args: cache.ArtifactCachePutBlobArgs{
   734  					BlobIDAnything: true,
   735  					BlobInfo: types.BlobInfo{
   736  						SchemaVersion: 2,
   737  						Misconfigurations: []types.Misconfiguration{
   738  							{
   739  								FileType: types.Terraform,
   740  								FilePath: "../parent/main.tf",
   741  								Failures: types.MisconfResults{
   742  									{
   743  										Namespace:      "user.something",
   744  										Query:          "data.user.something.deny",
   745  										Message:        "Empty bucket name!",
   746  										PolicyMetadata: policyMetadata,
   747  										CauseMetadata: types.CauseMetadata{
   748  											Resource:  "aws_s3_bucket.three",
   749  											Provider:  "Generic",
   750  											Service:   "general",
   751  											StartLine: 1,
   752  											EndLine:   3,
   753  										},
   754  									},
   755  								},
   756  							},
   757  							{
   758  								FileType: types.Terraform,
   759  								FilePath: "main.tf",
   760  								Failures: types.MisconfResults{
   761  									{
   762  										Namespace:      "user.something",
   763  										Query:          "data.user.something.deny",
   764  										Message:        "Empty bucket name!",
   765  										PolicyMetadata: policyMetadata,
   766  										CauseMetadata: types.CauseMetadata{
   767  											Resource:  "aws_s3_bucket.one",
   768  											Provider:  "Generic",
   769  											Service:   "general",
   770  											StartLine: 1,
   771  											EndLine:   3,
   772  										},
   773  									},
   774  								},
   775  							},
   776  							{
   777  								FileType: types.Terraform,
   778  								FilePath: "nested/main.tf",
   779  								Failures: types.MisconfResults{
   780  									{
   781  										Namespace:      "user.something",
   782  										Query:          "data.user.something.deny",
   783  										Message:        "Empty bucket name!",
   784  										PolicyMetadata: policyMetadata,
   785  										CauseMetadata: types.CauseMetadata{
   786  											Resource:  "aws_s3_bucket.two",
   787  											Provider:  "Generic",
   788  											Service:   "general",
   789  											StartLine: 1,
   790  											EndLine:   3,
   791  										},
   792  									},
   793  								},
   794  							},
   795  						},
   796  					},
   797  				},
   798  				Returns: cache.ArtifactCachePutBlobReturns{},
   799  			},
   800  			want: types.ArtifactReference{
   801  				Name: "testdata/misconfig/terraform/relative-paths/child",
   802  				Type: types.ArtifactFilesystem,
   803  				ID:   "sha256:9c5c0038bf41e03f878ed27c569b93198a16b0d975e7fca4e90aa2a4eaf87402",
   804  				BlobIDs: []string{
   805  					"sha256:9c5c0038bf41e03f878ed27c569b93198a16b0d975e7fca4e90aa2a4eaf87402",
   806  				},
   807  			},
   808  		},
   809  	}
   810  	for _, tt := range tests {
   811  		t.Run(tt.name, func(t *testing.T) {
   812  			c := new(cache.MockArtifactCache)
   813  			c.ApplyPutBlobExpectation(tt.putBlobExpectation)
   814  			tt.artifactOpt.DisabledHandlers = []types.HandlerType{
   815  				types.SystemFileFilteringPostHandler,
   816  			}
   817  			tt.artifactOpt.MisconfScannerOption.DisableEmbeddedPolicies = true
   818  			a, err := NewArtifact(tt.fields.dir, c, tt.artifactOpt)
   819  			require.NoError(t, err)
   820  
   821  			got, err := a.Inspect(context.Background())
   822  			require.NoError(t, err)
   823  			assert.Equal(t, tt.want, got)
   824  		})
   825  	}
   826  }
   827  
   828  func TestCloudFormationMisconfigurationScan(t *testing.T) {
   829  	type fields struct {
   830  		dir string
   831  	}
   832  	tests := []struct {
   833  		name               string
   834  		fields             fields
   835  		putBlobExpectation cache.ArtifactCachePutBlobExpectation
   836  		artifactOpt        artifact.Option
   837  		want               types.ArtifactReference
   838  	}{
   839  		{
   840  			name: "single failure",
   841  			fields: fields{
   842  				dir: "./testdata/misconfig/cloudformation/single-failure/src",
   843  			},
   844  			artifactOpt: artifact.Option{
   845  				MisconfScannerOption: misconf.ScannerOption{
   846  					RegoOnly:                 true,
   847  					Namespaces:               []string{"user"},
   848  					PolicyPaths:              []string{"./testdata/misconfig/cloudformation/single-failure/rego"},
   849  					DisableEmbeddedPolicies:  true,
   850  					DisableEmbeddedLibraries: true,
   851  				},
   852  			},
   853  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
   854  				Args: cache.ArtifactCachePutBlobArgs{
   855  					BlobIDAnything: true,
   856  					BlobInfo: types.BlobInfo{
   857  						SchemaVersion: types.BlobJSONSchemaVersion,
   858  						Misconfigurations: []types.Misconfiguration{
   859  							{
   860  								FileType: "cloudformation",
   861  								FilePath: "main.yaml",
   862  								Failures: types.MisconfResults{
   863  									{
   864  										Namespace: "user.something",
   865  										Query:     "data.user.something.deny",
   866  										Message:   "No buckets allowed!",
   867  										PolicyMetadata: types.PolicyMetadata{
   868  											ID:                 "TEST001",
   869  											AVDID:              "AVD-TEST-0001",
   870  											Type:               "CloudFormation Security Check",
   871  											Title:              "Test policy",
   872  											Description:        "This is a test policy.",
   873  											Severity:           "LOW",
   874  											RecommendedActions: "Have a cup of tea.",
   875  											References:         []string{"https://trivy.dev/"},
   876  										},
   877  										CauseMetadata: types.CauseMetadata{
   878  											Resource:  "main.yaml:3-6",
   879  											Provider:  "Generic",
   880  											Service:   "general",
   881  											StartLine: 3,
   882  											EndLine:   6,
   883  										},
   884  									},
   885  								},
   886  							},
   887  						},
   888  					},
   889  				},
   890  				Returns: cache.ArtifactCachePutBlobReturns{},
   891  			},
   892  			want: types.ArtifactReference{
   893  				Name: "testdata/misconfig/cloudformation/single-failure/src",
   894  				Type: types.ArtifactFilesystem,
   895  				ID:   "sha256:b2ae3759e901c7ba8b0aa690e551e3eec01b6e450533d5444a63969ffbb97adf",
   896  				BlobIDs: []string{
   897  					"sha256:b2ae3759e901c7ba8b0aa690e551e3eec01b6e450533d5444a63969ffbb97adf",
   898  				},
   899  			},
   900  		},
   901  		{
   902  			name: "multiple failures",
   903  			fields: fields{
   904  				dir: "./testdata/misconfig/cloudformation/multiple-failures/src",
   905  			},
   906  			artifactOpt: artifact.Option{
   907  				MisconfScannerOption: misconf.ScannerOption{
   908  					RegoOnly:                 true,
   909  					Namespaces:               []string{"user"},
   910  					PolicyPaths:              []string{"./testdata/misconfig/cloudformation/multiple-failures/rego"},
   911  					DisableEmbeddedPolicies:  true,
   912  					DisableEmbeddedLibraries: true,
   913  				},
   914  			},
   915  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
   916  				Args: cache.ArtifactCachePutBlobArgs{
   917  					BlobIDAnything: true,
   918  					BlobInfo: types.BlobInfo{
   919  						SchemaVersion: 2,
   920  						Misconfigurations: []types.Misconfiguration{
   921  							{
   922  								FileType: "cloudformation",
   923  								FilePath: "main.yaml",
   924  								Failures: types.MisconfResults{
   925  									types.MisconfResult{
   926  										Namespace: "user.something",
   927  										Query:     "data.user.something.deny",
   928  										Message:   "No buckets allowed!",
   929  										PolicyMetadata: types.PolicyMetadata{
   930  											ID:                 "TEST001",
   931  											AVDID:              "AVD-TEST-0001",
   932  											Type:               "CloudFormation Security Check",
   933  											Title:              "Test policy",
   934  											Description:        "This is a test policy.",
   935  											Severity:           "LOW",
   936  											RecommendedActions: "Have a cup of tea.",
   937  											References:         []string{"https://trivy.dev/"},
   938  										},
   939  										CauseMetadata: types.CauseMetadata{
   940  											Resource:  "main.yaml:2-5",
   941  											Provider:  "Generic",
   942  											Service:   "general",
   943  											StartLine: 2,
   944  											EndLine:   5,
   945  										},
   946  									},
   947  									{
   948  										Namespace: "user.something",
   949  										Query:     "data.user.something.deny",
   950  										Message:   "No buckets allowed!",
   951  										PolicyMetadata: types.PolicyMetadata{
   952  											ID:                 "TEST001",
   953  											AVDID:              "AVD-TEST-0001",
   954  											Type:               "CloudFormation Security Check",
   955  											Title:              "Test policy",
   956  											Description:        "This is a test policy.",
   957  											Severity:           "LOW",
   958  											RecommendedActions: "Have a cup of tea.",
   959  											References:         []string{"https://trivy.dev/"},
   960  										},
   961  										CauseMetadata: types.CauseMetadata{
   962  											Resource:  "main.yaml:6-9",
   963  											Provider:  "Generic",
   964  											Service:   "general",
   965  											StartLine: 6,
   966  											EndLine:   9,
   967  										},
   968  									},
   969  								},
   970  							},
   971  						},
   972  					},
   973  				},
   974  				Returns: cache.ArtifactCachePutBlobReturns{},
   975  			},
   976  			want: types.ArtifactReference{
   977  				Name: "testdata/misconfig/cloudformation/multiple-failures/src",
   978  				Type: types.ArtifactFilesystem,
   979  				ID:   "sha256:410c31b72c1da31a4b2974fe4405820ffe81c65880017491ca63ec6be2cd9424",
   980  				BlobIDs: []string{
   981  					"sha256:410c31b72c1da31a4b2974fe4405820ffe81c65880017491ca63ec6be2cd9424",
   982  				},
   983  			},
   984  		},
   985  		{
   986  			name: "no results",
   987  			fields: fields{
   988  				dir: "./testdata/misconfig/cloudformation/no-results/src",
   989  			},
   990  			artifactOpt: artifact.Option{
   991  				MisconfScannerOption: misconf.ScannerOption{
   992  					RegoOnly:                 true,
   993  					Namespaces:               []string{"user"},
   994  					PolicyPaths:              []string{"./testdata/misconfig/cloudformation/no-results/rego"},
   995  					DisableEmbeddedPolicies:  true,
   996  					DisableEmbeddedLibraries: true,
   997  				},
   998  			},
   999  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
  1000  				Args: cache.ArtifactCachePutBlobArgs{
  1001  					BlobIDAnything: true,
  1002  					BlobInfo: types.BlobInfo{
  1003  						SchemaVersion: types.BlobJSONSchemaVersion,
  1004  					},
  1005  				},
  1006  				Returns: cache.ArtifactCachePutBlobReturns{},
  1007  			},
  1008  			want: types.ArtifactReference{
  1009  				Name: "testdata/misconfig/cloudformation/no-results/src",
  1010  				Type: types.ArtifactFilesystem,
  1011  				ID:   "sha256:5cafcecda4322751d7b281d9546f5789a46d82d19cc2adab614122d2ce3420b9",
  1012  				BlobIDs: []string{
  1013  					"sha256:5cafcecda4322751d7b281d9546f5789a46d82d19cc2adab614122d2ce3420b9",
  1014  				},
  1015  			},
  1016  		},
  1017  		{
  1018  			name: "CloudFormation parameters outside the scan directory",
  1019  			fields: fields{
  1020  				dir: "./testdata/misconfig/cloudformation/params/code/src",
  1021  			},
  1022  			artifactOpt: artifact.Option{
  1023  				MisconfScannerOption: misconf.ScannerOption{
  1024  					RegoOnly:                 true,
  1025  					Namespaces:               []string{"user"},
  1026  					PolicyPaths:              []string{"./testdata/misconfig/cloudformation/params/code/rego"},
  1027  					CloudFormationParamVars:  []string{"./testdata/misconfig/cloudformation/params/cfparams.json"},
  1028  					DisableEmbeddedPolicies:  true,
  1029  					DisableEmbeddedLibraries: true,
  1030  				},
  1031  			},
  1032  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
  1033  				Args: cache.ArtifactCachePutBlobArgs{
  1034  					BlobIDAnything: true,
  1035  					BlobInfo: types.BlobInfo{
  1036  						SchemaVersion: types.BlobJSONSchemaVersion,
  1037  						Misconfigurations: []types.Misconfiguration{
  1038  							{
  1039  								FileType: "cloudformation",
  1040  								FilePath: "main.yaml",
  1041  								Successes: types.MisconfResults{
  1042  									{
  1043  										Namespace: "user.something",
  1044  										Query:     "data.user.something.deny",
  1045  										PolicyMetadata: types.PolicyMetadata{
  1046  											ID:                 "TEST001",
  1047  											AVDID:              "AVD-TEST-0001",
  1048  											Type:               "CloudFormation Security Check",
  1049  											Title:              "Bad stuff is bad",
  1050  											Description:        "Its not good!",
  1051  											Severity:           "HIGH",
  1052  											RecommendedActions: "Remove bad stuff",
  1053  										},
  1054  										CauseMetadata: types.CauseMetadata{
  1055  											Provider: "AWS",
  1056  											Service:  "sqs",
  1057  										},
  1058  									},
  1059  								},
  1060  							},
  1061  						},
  1062  					},
  1063  				},
  1064  				Returns: cache.ArtifactCachePutBlobReturns{},
  1065  			},
  1066  			want: types.ArtifactReference{
  1067  				Name: "testdata/misconfig/cloudformation/params/code/src",
  1068  				Type: types.ArtifactFilesystem,
  1069  				ID:   "sha256:0c66c19a4df3ecc11db9f90fbc921f1050325c05c480847369e07ee309e8a897",
  1070  				BlobIDs: []string{
  1071  					"sha256:0c66c19a4df3ecc11db9f90fbc921f1050325c05c480847369e07ee309e8a897",
  1072  				},
  1073  			},
  1074  		},
  1075  		{
  1076  			name: "passed",
  1077  			fields: fields{
  1078  				dir: "./testdata/misconfig/cloudformation/passed/src",
  1079  			},
  1080  			artifactOpt: artifact.Option{
  1081  				MisconfScannerOption: misconf.ScannerOption{
  1082  					RegoOnly:                 true,
  1083  					Namespaces:               []string{"user"},
  1084  					PolicyPaths:              []string{"./testdata/misconfig/cloudformation/passed/rego"},
  1085  					DisableEmbeddedPolicies:  true,
  1086  					DisableEmbeddedLibraries: true,
  1087  				},
  1088  			},
  1089  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
  1090  				Args: cache.ArtifactCachePutBlobArgs{
  1091  					BlobIDAnything: true,
  1092  					BlobInfo: types.BlobInfo{
  1093  						SchemaVersion: types.BlobJSONSchemaVersion,
  1094  						Misconfigurations: []types.Misconfiguration{
  1095  							{
  1096  								FileType: "cloudformation",
  1097  								FilePath: "main.yaml",
  1098  								Successes: types.MisconfResults{
  1099  									{
  1100  										Namespace: "user.something",
  1101  										Query:     "data.user.something.deny",
  1102  										PolicyMetadata: types.PolicyMetadata{
  1103  											ID:                 "TEST001",
  1104  											AVDID:              "AVD-TEST-0001",
  1105  											Type:               "CloudFormation Security Check",
  1106  											Title:              "Test policy",
  1107  											Description:        "This is a test policy.",
  1108  											Severity:           "LOW",
  1109  											RecommendedActions: "Have a cup of tea.",
  1110  											References:         []string{"https://trivy.dev/"},
  1111  										},
  1112  										CauseMetadata: types.CauseMetadata{
  1113  											Provider: "Generic",
  1114  											Service:  "general",
  1115  										},
  1116  									},
  1117  								},
  1118  							},
  1119  						},
  1120  					},
  1121  				},
  1122  				Returns: cache.ArtifactCachePutBlobReturns{},
  1123  			},
  1124  			want: types.ArtifactReference{
  1125  				Name: "testdata/misconfig/cloudformation/passed/src",
  1126  				Type: types.ArtifactFilesystem,
  1127  				ID:   "sha256:9f9b0773ca1ec4b257aae410798a635076eaed12afefac839b62efdc65d417e1",
  1128  				BlobIDs: []string{
  1129  					"sha256:9f9b0773ca1ec4b257aae410798a635076eaed12afefac839b62efdc65d417e1",
  1130  				},
  1131  			},
  1132  		},
  1133  	}
  1134  	for _, tt := range tests {
  1135  		t.Run(tt.name, func(t *testing.T) {
  1136  			c := new(cache.MockArtifactCache)
  1137  			c.ApplyPutBlobExpectation(tt.putBlobExpectation)
  1138  			tt.artifactOpt.DisabledHandlers = []types.HandlerType{
  1139  				types.SystemFileFilteringPostHandler,
  1140  			}
  1141  			tt.artifactOpt.MisconfScannerOption.DisableEmbeddedPolicies = true
  1142  			a, err := NewArtifact(tt.fields.dir, c, tt.artifactOpt)
  1143  			require.NoError(t, err)
  1144  
  1145  			got, err := a.Inspect(context.Background())
  1146  			require.NoError(t, err)
  1147  			assert.Equal(t, tt.want, got)
  1148  		})
  1149  	}
  1150  }
  1151  
  1152  func TestDockerfileMisconfigurationScan(t *testing.T) {
  1153  	type fields struct {
  1154  		dir string
  1155  	}
  1156  	tests := []struct {
  1157  		name               string
  1158  		fields             fields
  1159  		putBlobExpectation cache.ArtifactCachePutBlobExpectation
  1160  		artifactOpt        artifact.Option
  1161  		want               types.ArtifactReference
  1162  	}{
  1163  		{
  1164  			name: "single failure",
  1165  			fields: fields{
  1166  				dir: "./testdata/misconfig/dockerfile/single-failure/src",
  1167  			},
  1168  			artifactOpt: artifact.Option{
  1169  				MisconfScannerOption: misconf.ScannerOption{
  1170  					RegoOnly:                 true,
  1171  					Namespaces:               []string{"user"},
  1172  					PolicyPaths:              []string{"./testdata/misconfig/dockerfile/single-failure/rego"},
  1173  					DisableEmbeddedPolicies:  true,
  1174  					DisableEmbeddedLibraries: true,
  1175  				},
  1176  			},
  1177  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
  1178  				Args: cache.ArtifactCachePutBlobArgs{
  1179  					BlobIDAnything: true,
  1180  					BlobInfo: types.BlobInfo{
  1181  						SchemaVersion: types.BlobJSONSchemaVersion,
  1182  						Misconfigurations: []types.Misconfiguration{
  1183  							{
  1184  								FileType: "dockerfile",
  1185  								FilePath: "Dockerfile",
  1186  								Successes: types.MisconfResults{
  1187  									types.MisconfResult{
  1188  										Namespace: "user.something",
  1189  										Query:     "data.user.something.deny",
  1190  										PolicyMetadata: types.PolicyMetadata{
  1191  											ID:                 "TEST001",
  1192  											AVDID:              "AVD-TEST-0001",
  1193  											Type:               "Dockerfile Security Check",
  1194  											Title:              "Test policy",
  1195  											Description:        "This is a test policy.",
  1196  											Severity:           "LOW",
  1197  											RecommendedActions: "Have a cup of tea.",
  1198  											References:         []string{"https://trivy.dev/"},
  1199  										},
  1200  										CauseMetadata: types.CauseMetadata{
  1201  											Provider: "Generic",
  1202  											Service:  "general",
  1203  										},
  1204  									},
  1205  								},
  1206  							},
  1207  						},
  1208  					},
  1209  				},
  1210  				Returns: cache.ArtifactCachePutBlobReturns{},
  1211  			},
  1212  			want: types.ArtifactReference{
  1213  				Name: "testdata/misconfig/dockerfile/single-failure/src",
  1214  				Type: types.ArtifactFilesystem,
  1215  				ID:   "sha256:a22d246cba3476acf2a3d6cfe88b5a895ab78cb328b76fe070fce9f1c77f80c7",
  1216  				BlobIDs: []string{
  1217  					"sha256:a22d246cba3476acf2a3d6cfe88b5a895ab78cb328b76fe070fce9f1c77f80c7",
  1218  				},
  1219  			},
  1220  		},
  1221  		{
  1222  			name: "multiple failures",
  1223  			fields: fields{
  1224  				dir: "./testdata/misconfig/dockerfile/multiple-failures/src",
  1225  			},
  1226  			artifactOpt: artifact.Option{
  1227  				MisconfScannerOption: misconf.ScannerOption{
  1228  					RegoOnly:                 true,
  1229  					Namespaces:               []string{"user"},
  1230  					PolicyPaths:              []string{"./testdata/misconfig/dockerfile/multiple-failures/rego"},
  1231  					DisableEmbeddedPolicies:  true,
  1232  					DisableEmbeddedLibraries: true,
  1233  				},
  1234  			},
  1235  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
  1236  				Args: cache.ArtifactCachePutBlobArgs{
  1237  					BlobIDAnything: true,
  1238  					BlobInfo: types.BlobInfo{
  1239  						SchemaVersion: types.BlobJSONSchemaVersion,
  1240  						Misconfigurations: []types.Misconfiguration{
  1241  							{
  1242  								FileType: "dockerfile",
  1243  								FilePath: "Dockerfile",
  1244  								Successes: types.MisconfResults{
  1245  									types.MisconfResult{
  1246  										Namespace: "user.something",
  1247  										Query:     "data.user.something.deny",
  1248  										PolicyMetadata: types.PolicyMetadata{
  1249  											ID:                 "TEST001",
  1250  											AVDID:              "AVD-TEST-0001",
  1251  											Type:               "Dockerfile Security Check",
  1252  											Title:              "Test policy",
  1253  											Description:        "This is a test policy.",
  1254  											Severity:           "LOW",
  1255  											RecommendedActions: "Have a cup of tea.",
  1256  											References:         []string{"https://trivy.dev/"},
  1257  										},
  1258  										CauseMetadata: types.CauseMetadata{
  1259  											Provider: "Generic",
  1260  											Service:  "general",
  1261  										},
  1262  									},
  1263  								},
  1264  							},
  1265  						},
  1266  					},
  1267  				},
  1268  				Returns: cache.ArtifactCachePutBlobReturns{},
  1269  			},
  1270  			want: types.ArtifactReference{
  1271  				Name: "testdata/misconfig/dockerfile/multiple-failures/src",
  1272  				Type: types.ArtifactFilesystem,
  1273  				ID:   "sha256:a22d246cba3476acf2a3d6cfe88b5a895ab78cb328b76fe070fce9f1c77f80c7",
  1274  				BlobIDs: []string{
  1275  					"sha256:a22d246cba3476acf2a3d6cfe88b5a895ab78cb328b76fe070fce9f1c77f80c7",
  1276  				},
  1277  			},
  1278  		},
  1279  		{
  1280  			name: "no results",
  1281  			fields: fields{
  1282  				dir: "./testdata/misconfig/dockerfile/no-results/src",
  1283  			},
  1284  			artifactOpt: artifact.Option{
  1285  				MisconfScannerOption: misconf.ScannerOption{
  1286  					RegoOnly:    true,
  1287  					Namespaces:  []string{"user"},
  1288  					PolicyPaths: []string{"./testdata/misconfig/dockerfile/no-results/rego"},
  1289  				},
  1290  			},
  1291  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
  1292  				Args: cache.ArtifactCachePutBlobArgs{
  1293  					BlobIDAnything: true,
  1294  					BlobInfo: types.BlobInfo{
  1295  						SchemaVersion: types.BlobJSONSchemaVersion,
  1296  					},
  1297  				},
  1298  				Returns: cache.ArtifactCachePutBlobReturns{},
  1299  			},
  1300  			want: types.ArtifactReference{
  1301  				Name: "testdata/misconfig/dockerfile/no-results/src",
  1302  				Type: types.ArtifactFilesystem,
  1303  				ID:   "sha256:5cafcecda4322751d7b281d9546f5789a46d82d19cc2adab614122d2ce3420b9",
  1304  				BlobIDs: []string{
  1305  					"sha256:5cafcecda4322751d7b281d9546f5789a46d82d19cc2adab614122d2ce3420b9",
  1306  				},
  1307  			},
  1308  		},
  1309  		{
  1310  			name: "passed",
  1311  			fields: fields{
  1312  				dir: "./testdata/misconfig/dockerfile/passed/src",
  1313  			},
  1314  			artifactOpt: artifact.Option{
  1315  				MisconfScannerOption: misconf.ScannerOption{
  1316  					RegoOnly:                 true,
  1317  					Namespaces:               []string{"user"},
  1318  					PolicyPaths:              []string{"./testdata/misconfig/dockerfile/passed/rego"},
  1319  					DisableEmbeddedPolicies:  true,
  1320  					DisableEmbeddedLibraries: true,
  1321  				},
  1322  			},
  1323  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
  1324  				Args: cache.ArtifactCachePutBlobArgs{
  1325  					BlobIDAnything: true,
  1326  					BlobInfo: types.BlobInfo{
  1327  						SchemaVersion: types.BlobJSONSchemaVersion,
  1328  						Misconfigurations: []types.Misconfiguration{
  1329  							{
  1330  								FileType: "dockerfile",
  1331  								FilePath: "Dockerfile",
  1332  								Successes: []types.MisconfResult{
  1333  									{
  1334  										Namespace: "user.something",
  1335  										Query:     "data.user.something.deny",
  1336  										PolicyMetadata: types.PolicyMetadata{
  1337  											ID:                 "TEST001",
  1338  											AVDID:              "AVD-TEST-0001",
  1339  											Type:               "Dockerfile Security Check",
  1340  											Title:              "Test policy",
  1341  											Description:        "This is a test policy.",
  1342  											Severity:           "LOW",
  1343  											RecommendedActions: "Have a cup of tea.",
  1344  											References: []string{
  1345  												"https://trivy.dev/",
  1346  											},
  1347  										},
  1348  										CauseMetadata: types.CauseMetadata{
  1349  											Provider: "Generic",
  1350  											Service:  "general",
  1351  										},
  1352  									},
  1353  								},
  1354  							},
  1355  						},
  1356  					},
  1357  				},
  1358  				Returns: cache.ArtifactCachePutBlobReturns{},
  1359  			},
  1360  			want: types.ArtifactReference{
  1361  				Name: "testdata/misconfig/dockerfile/passed/src",
  1362  				Type: types.ArtifactFilesystem,
  1363  				ID:   "sha256:a9541fe2309a78505f147a688ebf8a2e107bad8351bb22e280f627d5ecf91b16",
  1364  				BlobIDs: []string{
  1365  					"sha256:a9541fe2309a78505f147a688ebf8a2e107bad8351bb22e280f627d5ecf91b16",
  1366  				},
  1367  			},
  1368  		},
  1369  	}
  1370  	for _, tt := range tests {
  1371  		t.Run(tt.name, func(t *testing.T) {
  1372  			c := new(cache.MockArtifactCache)
  1373  			c.ApplyPutBlobExpectation(tt.putBlobExpectation)
  1374  			tt.artifactOpt.DisabledHandlers = []types.HandlerType{
  1375  				types.SystemFileFilteringPostHandler,
  1376  			}
  1377  			a, err := NewArtifact(tt.fields.dir, c, tt.artifactOpt)
  1378  			require.NoError(t, err)
  1379  
  1380  			got, err := a.Inspect(context.Background())
  1381  			require.NoError(t, err)
  1382  			assert.Equal(t, tt.want, got)
  1383  		})
  1384  	}
  1385  }
  1386  
  1387  func TestKubernetesMisconfigurationScan(t *testing.T) {
  1388  	type fields struct {
  1389  		dir string
  1390  	}
  1391  	tests := []struct {
  1392  		name               string
  1393  		fields             fields
  1394  		putBlobExpectation cache.ArtifactCachePutBlobExpectation
  1395  		artifactOpt        artifact.Option
  1396  		want               types.ArtifactReference
  1397  	}{
  1398  		{
  1399  			name: "single failure",
  1400  			fields: fields{
  1401  				dir: "./testdata/misconfig/kubernetes/single-failure/src",
  1402  			},
  1403  			artifactOpt: artifact.Option{
  1404  				MisconfScannerOption: misconf.ScannerOption{
  1405  					RegoOnly:                 true,
  1406  					Namespaces:               []string{"user"},
  1407  					PolicyPaths:              []string{"./testdata/misconfig/kubernetes/single-failure/rego"},
  1408  					DisableEmbeddedPolicies:  true,
  1409  					DisableEmbeddedLibraries: true,
  1410  				},
  1411  			},
  1412  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
  1413  				Args: cache.ArtifactCachePutBlobArgs{
  1414  					BlobIDAnything: true,
  1415  					BlobInfo: types.BlobInfo{
  1416  						SchemaVersion: types.BlobJSONSchemaVersion,
  1417  						Misconfigurations: []types.Misconfiguration{
  1418  							{
  1419  								FileType: "kubernetes",
  1420  								FilePath: "test.yaml",
  1421  								Failures: []types.MisconfResult{
  1422  									{
  1423  										Namespace: "user.something",
  1424  										Query:     "data.user.something.deny",
  1425  										Message:   "No evil containers allowed!",
  1426  										PolicyMetadata: types.PolicyMetadata{
  1427  											ID:                 "TEST001",
  1428  											AVDID:              "AVD-TEST-0001",
  1429  											Type:               "Kubernetes Security Check",
  1430  											Title:              "Test policy",
  1431  											Description:        "This is a test policy.",
  1432  											Severity:           "LOW",
  1433  											RecommendedActions: "Have a cup of tea.",
  1434  											References: []string{
  1435  												"https://trivy.dev/",
  1436  											},
  1437  										},
  1438  										CauseMetadata: types.CauseMetadata{
  1439  											Provider:  "Generic",
  1440  											Service:   "general",
  1441  											StartLine: 7,
  1442  											EndLine:   9,
  1443  										},
  1444  									},
  1445  								},
  1446  							},
  1447  						},
  1448  					},
  1449  				},
  1450  				Returns: cache.ArtifactCachePutBlobReturns{},
  1451  			},
  1452  			want: types.ArtifactReference{
  1453  				Name: "testdata/misconfig/kubernetes/single-failure/src",
  1454  				Type: types.ArtifactFilesystem,
  1455  				ID:   "sha256:ee77eca0b592b90536a467b20629c017b03e627c95427a3e7f4be2a9eb55c710",
  1456  				BlobIDs: []string{
  1457  					"sha256:ee77eca0b592b90536a467b20629c017b03e627c95427a3e7f4be2a9eb55c710",
  1458  				},
  1459  			},
  1460  		},
  1461  		{
  1462  			name: "multiple failures",
  1463  			fields: fields{
  1464  				dir: "./testdata/misconfig/kubernetes/multiple-failures/src",
  1465  			},
  1466  			artifactOpt: artifact.Option{
  1467  				MisconfScannerOption: misconf.ScannerOption{
  1468  					RegoOnly:                 true,
  1469  					Namespaces:               []string{"user"},
  1470  					PolicyPaths:              []string{"./testdata/misconfig/kubernetes/multiple-failures/rego"},
  1471  					DisableEmbeddedPolicies:  true,
  1472  					DisableEmbeddedLibraries: true,
  1473  				},
  1474  			},
  1475  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
  1476  				Args: cache.ArtifactCachePutBlobArgs{
  1477  					BlobIDAnything: true,
  1478  					BlobInfo: types.BlobInfo{
  1479  						SchemaVersion: types.BlobJSONSchemaVersion,
  1480  						Misconfigurations: []types.Misconfiguration{
  1481  							{
  1482  								FileType: "kubernetes",
  1483  								FilePath: "test.yaml",
  1484  								Failures: []types.MisconfResult{
  1485  									{
  1486  										Namespace: "user.something",
  1487  										Query:     "data.user.something.deny",
  1488  										Message:   "No evil containers allowed!",
  1489  										PolicyMetadata: types.PolicyMetadata{
  1490  											ID:                 "TEST001",
  1491  											AVDID:              "AVD-TEST-0001",
  1492  											Type:               "Kubernetes Security Check",
  1493  											Title:              "Test policy",
  1494  											Description:        "This is a test policy.",
  1495  											Severity:           "LOW",
  1496  											RecommendedActions: "Have a cup of tea.",
  1497  											References: []string{
  1498  												"https://trivy.dev/",
  1499  											},
  1500  										},
  1501  										CauseMetadata: types.CauseMetadata{
  1502  											Provider:  "Generic",
  1503  											Service:   "general",
  1504  											StartLine: 7,
  1505  											EndLine:   9,
  1506  										},
  1507  									},
  1508  									{
  1509  										Namespace: "user.something",
  1510  										Query:     "data.user.something.deny",
  1511  										Message:   "No evil containers allowed!",
  1512  										PolicyMetadata: types.PolicyMetadata{
  1513  											ID:                 "TEST001",
  1514  											AVDID:              "AVD-TEST-0001",
  1515  											Type:               "Kubernetes Security Check",
  1516  											Title:              "Test policy",
  1517  											Description:        "This is a test policy.",
  1518  											Severity:           "LOW",
  1519  											RecommendedActions: "Have a cup of tea.",
  1520  											References: []string{
  1521  												"https://trivy.dev/",
  1522  											},
  1523  										},
  1524  										CauseMetadata: types.CauseMetadata{
  1525  											Provider:  "Generic",
  1526  											Service:   "general",
  1527  											StartLine: 10,
  1528  											EndLine:   12,
  1529  										},
  1530  									},
  1531  								},
  1532  							},
  1533  						},
  1534  					},
  1535  				},
  1536  				Returns: cache.ArtifactCachePutBlobReturns{},
  1537  			},
  1538  			want: types.ArtifactReference{
  1539  				Name: "testdata/misconfig/kubernetes/multiple-failures/src",
  1540  				Type: types.ArtifactFilesystem,
  1541  				ID:   "sha256:1892ab8d28210fe199dbea24de4f2073ddf5d4bf5b33aa32436d2e1f1facb588",
  1542  				BlobIDs: []string{
  1543  					"sha256:1892ab8d28210fe199dbea24de4f2073ddf5d4bf5b33aa32436d2e1f1facb588",
  1544  				},
  1545  			},
  1546  		},
  1547  		{
  1548  			name: "no results",
  1549  			fields: fields{
  1550  				dir: "./testdata/misconfig/kubernetes/no-results/src",
  1551  			},
  1552  			artifactOpt: artifact.Option{
  1553  				MisconfScannerOption: misconf.ScannerOption{
  1554  					RegoOnly:    true,
  1555  					Namespaces:  []string{"user"},
  1556  					PolicyPaths: []string{"./testdata/misconfig/kubernetes/no-results/rego"},
  1557  				},
  1558  			},
  1559  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
  1560  				Args: cache.ArtifactCachePutBlobArgs{
  1561  					BlobIDAnything: true,
  1562  					BlobInfo: types.BlobInfo{
  1563  						SchemaVersion: types.BlobJSONSchemaVersion,
  1564  					},
  1565  				},
  1566  				Returns: cache.ArtifactCachePutBlobReturns{},
  1567  			},
  1568  			want: types.ArtifactReference{
  1569  				Name: "testdata/misconfig/kubernetes/no-results/src",
  1570  				Type: types.ArtifactFilesystem,
  1571  				ID:   "sha256:70f3be8d859a21841ac42de298e9e805aa058593cf3e315e8ee0fa1f30ef5107",
  1572  				BlobIDs: []string{
  1573  					"sha256:70f3be8d859a21841ac42de298e9e805aa058593cf3e315e8ee0fa1f30ef5107",
  1574  				},
  1575  			},
  1576  		},
  1577  		{
  1578  			name: "passed",
  1579  			fields: fields{
  1580  				dir: "./testdata/misconfig/kubernetes/passed/src",
  1581  			},
  1582  			artifactOpt: artifact.Option{
  1583  				MisconfScannerOption: misconf.ScannerOption{
  1584  					RegoOnly:                 true,
  1585  					Namespaces:               []string{"user"},
  1586  					PolicyPaths:              []string{"./testdata/misconfig/kubernetes/passed/rego"},
  1587  					DisableEmbeddedPolicies:  true,
  1588  					DisableEmbeddedLibraries: true,
  1589  				},
  1590  			},
  1591  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
  1592  				Args: cache.ArtifactCachePutBlobArgs{
  1593  					BlobIDAnything: true,
  1594  					BlobInfo: types.BlobInfo{
  1595  						SchemaVersion: types.BlobJSONSchemaVersion,
  1596  						Misconfigurations: []types.Misconfiguration{
  1597  							{
  1598  								FileType: "kubernetes",
  1599  								FilePath: "test.yaml",
  1600  								Successes: []types.MisconfResult{
  1601  									{
  1602  										Namespace: "user.something",
  1603  										Query:     "data.user.something.deny",
  1604  										PolicyMetadata: types.PolicyMetadata{
  1605  											ID:                 "TEST001",
  1606  											AVDID:              "AVD-TEST-0001",
  1607  											Type:               "Kubernetes Security Check",
  1608  											Title:              "Test policy",
  1609  											Description:        "This is a test policy.",
  1610  											Severity:           "LOW",
  1611  											RecommendedActions: "Have a cup of tea.",
  1612  											References: []string{
  1613  												"https://trivy.dev/",
  1614  											},
  1615  										},
  1616  										CauseMetadata: types.CauseMetadata{
  1617  											Provider: "Generic",
  1618  											Service:  "general",
  1619  										},
  1620  									},
  1621  								},
  1622  							},
  1623  						},
  1624  					},
  1625  				},
  1626  				Returns: cache.ArtifactCachePutBlobReturns{},
  1627  			},
  1628  			want: types.ArtifactReference{
  1629  				Name: "testdata/misconfig/kubernetes/passed/src",
  1630  				Type: types.ArtifactFilesystem,
  1631  				ID:   "sha256:f0eb13ac1479d37da2bcfc7964de5f3a4d3f06982ec27f110c97e9c8cf1cde38",
  1632  				BlobIDs: []string{
  1633  					"sha256:f0eb13ac1479d37da2bcfc7964de5f3a4d3f06982ec27f110c97e9c8cf1cde38",
  1634  				},
  1635  			},
  1636  		},
  1637  	}
  1638  	for _, tt := range tests {
  1639  		t.Run(tt.name, func(t *testing.T) {
  1640  			c := new(cache.MockArtifactCache)
  1641  			c.ApplyPutBlobExpectation(tt.putBlobExpectation)
  1642  			tt.artifactOpt.DisabledHandlers = []types.HandlerType{
  1643  				types.SystemFileFilteringPostHandler,
  1644  			}
  1645  			a, err := NewArtifact(tt.fields.dir, c, tt.artifactOpt)
  1646  			require.NoError(t, err)
  1647  
  1648  			got, err := a.Inspect(context.Background())
  1649  			require.NoError(t, err)
  1650  			assert.Equal(t, tt.want, got)
  1651  		})
  1652  	}
  1653  }
  1654  
  1655  func TestAzureARMMisconfigurationScan(t *testing.T) {
  1656  	type fields struct {
  1657  		dir string
  1658  	}
  1659  	tests := []struct {
  1660  		name               string
  1661  		fields             fields
  1662  		putBlobExpectation cache.ArtifactCachePutBlobExpectation
  1663  		artifactOpt        artifact.Option
  1664  		want               types.ArtifactReference
  1665  	}{
  1666  		{
  1667  			name: "single failure",
  1668  			fields: fields{
  1669  				dir: "./testdata/misconfig/azurearm/single-failure/src",
  1670  			},
  1671  			artifactOpt: artifact.Option{
  1672  				MisconfScannerOption: misconf.ScannerOption{
  1673  					RegoOnly:    true,
  1674  					Namespaces:  []string{"user"},
  1675  					PolicyPaths: []string{"./testdata/misconfig/azurearm/single-failure/rego"},
  1676  				},
  1677  			},
  1678  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
  1679  				Args: cache.ArtifactCachePutBlobArgs{
  1680  					BlobIDAnything: true,
  1681  					BlobInfo: types.BlobInfo{
  1682  						SchemaVersion: 2,
  1683  						Misconfigurations: []types.Misconfiguration{
  1684  							{
  1685  								FileType: "azure-arm",
  1686  								FilePath: "deploy.json",
  1687  								Failures: types.MisconfResults{
  1688  									{
  1689  										Namespace: "user.something",
  1690  										Query:     "data.user.something.deny",
  1691  										Message:   "No account allowed!",
  1692  										PolicyMetadata: types.PolicyMetadata{
  1693  											ID:                 "TEST001",
  1694  											AVDID:              "AVD-TEST-0001",
  1695  											Type:               "Azure ARM Security Check",
  1696  											Title:              "Test policy",
  1697  											Description:        "This is a test policy.",
  1698  											Severity:           "LOW",
  1699  											RecommendedActions: "Have a cup of tea.",
  1700  											References:         []string{"https://trivy.dev/"},
  1701  										},
  1702  										CauseMetadata: types.CauseMetadata{
  1703  											Resource:  "resources[0]",
  1704  											Provider:  "Generic",
  1705  											Service:   "general",
  1706  											StartLine: 30,
  1707  											EndLine:   40,
  1708  										},
  1709  									},
  1710  								},
  1711  							},
  1712  						},
  1713  					},
  1714  				},
  1715  				Returns: cache.ArtifactCachePutBlobReturns{},
  1716  			},
  1717  			want: types.ArtifactReference{
  1718  				Name: "testdata/misconfig/azurearm/single-failure/src",
  1719  				Type: types.ArtifactFilesystem,
  1720  				ID:   "sha256:ca17bc98d3b2dc8e7b001877324c51d08ba1b2a6764514a9a81adb3fb11f3c08",
  1721  				BlobIDs: []string{
  1722  					"sha256:ca17bc98d3b2dc8e7b001877324c51d08ba1b2a6764514a9a81adb3fb11f3c08",
  1723  				},
  1724  			},
  1725  		},
  1726  		{
  1727  			name: "multiple failures",
  1728  			fields: fields{
  1729  				dir: "./testdata/misconfig/azurearm/multiple-failures/src",
  1730  			},
  1731  			artifactOpt: artifact.Option{
  1732  				MisconfScannerOption: misconf.ScannerOption{
  1733  					RegoOnly:    true,
  1734  					Namespaces:  []string{"user"},
  1735  					PolicyPaths: []string{"./testdata/misconfig/azurearm/multiple-failures/rego"},
  1736  				},
  1737  			},
  1738  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
  1739  				Args: cache.ArtifactCachePutBlobArgs{
  1740  					BlobIDAnything: true,
  1741  					BlobInfo: types.BlobInfo{
  1742  						SchemaVersion: 2,
  1743  						Misconfigurations: []types.Misconfiguration{
  1744  							{
  1745  								FileType: "azure-arm",
  1746  								FilePath: "deploy.json",
  1747  								Failures: types.MisconfResults{
  1748  									{
  1749  										Namespace: "user.something",
  1750  										Query:     "data.user.something.deny",
  1751  										Message:   "No account allowed!",
  1752  										PolicyMetadata: types.PolicyMetadata{
  1753  											ID:                 "TEST001",
  1754  											AVDID:              "AVD-TEST-0001",
  1755  											Type:               "Azure ARM Security Check",
  1756  											Title:              "Test policy",
  1757  											Description:        "This is a test policy.",
  1758  											Severity:           "LOW",
  1759  											RecommendedActions: "Have a cup of tea.",
  1760  											References:         []string{"https://trivy.dev/"},
  1761  										},
  1762  										CauseMetadata: types.CauseMetadata{
  1763  											Resource:  "resources[0]",
  1764  											Provider:  "Generic",
  1765  											Service:   "general",
  1766  											StartLine: 30,
  1767  											EndLine:   40,
  1768  										},
  1769  									},
  1770  									{
  1771  										Namespace: "user.something",
  1772  										Query:     "data.user.something.deny",
  1773  										Message:   "No account allowed!",
  1774  										PolicyMetadata: types.PolicyMetadata{
  1775  											ID:                 "TEST001",
  1776  											AVDID:              "AVD-TEST-0001",
  1777  											Type:               "Azure ARM Security Check",
  1778  											Title:              "Test policy",
  1779  											Description:        "This is a test policy.",
  1780  											Severity:           "LOW",
  1781  											RecommendedActions: "Have a cup of tea.",
  1782  											References:         []string{"https://trivy.dev/"},
  1783  										},
  1784  										CauseMetadata: types.CauseMetadata{
  1785  											Resource:  "resources[1]",
  1786  											Provider:  "Generic",
  1787  											Service:   "general",
  1788  											StartLine: 41,
  1789  											EndLine:   51,
  1790  										},
  1791  									},
  1792  								},
  1793  							},
  1794  						},
  1795  					},
  1796  				},
  1797  				Returns: cache.ArtifactCachePutBlobReturns{},
  1798  			},
  1799  			want: types.ArtifactReference{
  1800  				Name: "testdata/misconfig/azurearm/multiple-failures/src",
  1801  				Type: types.ArtifactFilesystem,
  1802  				ID:   "sha256:2e29f26823faf3042ff25c32734fa96bc24ebb09a4d92d5ea3ea5c60d7204114",
  1803  				BlobIDs: []string{
  1804  					"sha256:2e29f26823faf3042ff25c32734fa96bc24ebb09a4d92d5ea3ea5c60d7204114",
  1805  				},
  1806  			},
  1807  		},
  1808  		{
  1809  			name: "no results",
  1810  			fields: fields{
  1811  				dir: "./testdata/misconfig/azurearm/no-results/src",
  1812  			},
  1813  			artifactOpt: artifact.Option{
  1814  				MisconfScannerOption: misconf.ScannerOption{
  1815  					RegoOnly:    true,
  1816  					Namespaces:  []string{"user"},
  1817  					PolicyPaths: []string{"./testdata/misconfig/azurearm/no-results/rego"},
  1818  				},
  1819  			},
  1820  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
  1821  				Args: cache.ArtifactCachePutBlobArgs{
  1822  					BlobIDAnything: true,
  1823  					BlobInfo: types.BlobInfo{
  1824  						SchemaVersion: types.BlobJSONSchemaVersion,
  1825  					},
  1826  				},
  1827  				Returns: cache.ArtifactCachePutBlobReturns{},
  1828  			},
  1829  			want: types.ArtifactReference{
  1830  				Name: "testdata/misconfig/azurearm/no-results/src",
  1831  				Type: types.ArtifactFilesystem,
  1832  				ID:   "sha256:5cafcecda4322751d7b281d9546f5789a46d82d19cc2adab614122d2ce3420b9",
  1833  				BlobIDs: []string{
  1834  					"sha256:5cafcecda4322751d7b281d9546f5789a46d82d19cc2adab614122d2ce3420b9",
  1835  				},
  1836  			},
  1837  		},
  1838  		{
  1839  			name: "passed",
  1840  			fields: fields{
  1841  				dir: "./testdata/misconfig/azurearm/passed/src",
  1842  			},
  1843  			artifactOpt: artifact.Option{
  1844  				MisconfScannerOption: misconf.ScannerOption{
  1845  					RegoOnly:    true,
  1846  					Namespaces:  []string{"user"},
  1847  					PolicyPaths: []string{"./testdata/misconfig/azurearm/passed/rego"},
  1848  				},
  1849  			},
  1850  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
  1851  				Args: cache.ArtifactCachePutBlobArgs{
  1852  					BlobIDAnything: true,
  1853  					BlobInfo: types.BlobInfo{
  1854  						SchemaVersion: 2,
  1855  						Misconfigurations: []types.Misconfiguration{
  1856  							{
  1857  								FileType: "azure-arm",
  1858  								FilePath: "deploy.json",
  1859  								Successes: types.MisconfResults{
  1860  									{
  1861  										Namespace: "user.something",
  1862  										Query:     "data.user.something.deny",
  1863  										PolicyMetadata: types.PolicyMetadata{
  1864  											ID:                 "TEST001",
  1865  											AVDID:              "AVD-TEST-0001",
  1866  											Type:               "Azure ARM Security Check",
  1867  											Title:              "Test policy",
  1868  											Description:        "This is a test policy.",
  1869  											Severity:           "LOW",
  1870  											RecommendedActions: "Have a cup of tea.",
  1871  											References:         []string{"https://trivy.dev/"},
  1872  										},
  1873  										CauseMetadata: types.CauseMetadata{
  1874  											Provider: "Generic",
  1875  											Service:  "general",
  1876  										},
  1877  									},
  1878  								},
  1879  							},
  1880  						},
  1881  					},
  1882  				},
  1883  				Returns: cache.ArtifactCachePutBlobReturns{},
  1884  			},
  1885  			want: types.ArtifactReference{
  1886  				Name: "testdata/misconfig/azurearm/passed/src",
  1887  				Type: types.ArtifactFilesystem,
  1888  				ID:   "sha256:a2a781172a5d3a7c70251322696b892cf16da89c937a85f5caf7d2e8c44eede4",
  1889  				BlobIDs: []string{
  1890  					"sha256:a2a781172a5d3a7c70251322696b892cf16da89c937a85f5caf7d2e8c44eede4",
  1891  				},
  1892  			},
  1893  		},
  1894  	}
  1895  	for _, tt := range tests {
  1896  		t.Run(tt.name, func(t *testing.T) {
  1897  			c := new(cache.MockArtifactCache)
  1898  			c.ApplyPutBlobExpectation(tt.putBlobExpectation)
  1899  			tt.artifactOpt.DisabledHandlers = []types.HandlerType{
  1900  				types.SystemFileFilteringPostHandler,
  1901  			}
  1902  			a, err := NewArtifact(tt.fields.dir, c, tt.artifactOpt)
  1903  			require.NoError(t, err)
  1904  
  1905  			got, err := a.Inspect(context.Background())
  1906  			require.NoError(t, err)
  1907  			assert.Equal(t, tt.want, got)
  1908  		})
  1909  	}
  1910  }
  1911  
  1912  func TestMixedConfigurationScan(t *testing.T) {
  1913  	type fields struct {
  1914  		dir string
  1915  	}
  1916  	tests := []struct {
  1917  		name               string
  1918  		fields             fields
  1919  		putBlobExpectation cache.ArtifactCachePutBlobExpectation
  1920  		artifactOpt        artifact.Option
  1921  		want               types.ArtifactReference
  1922  	}{
  1923  		{
  1924  			name: "single failure each within terraform and cloudformation",
  1925  			fields: fields{
  1926  				dir: "./testdata/misconfig/mixed/src",
  1927  			},
  1928  			artifactOpt: artifact.Option{
  1929  				MisconfScannerOption: misconf.ScannerOption{
  1930  					RegoOnly:                 true,
  1931  					Namespaces:               []string{"user"},
  1932  					PolicyPaths:              []string{"./testdata/misconfig/mixed/rego"},
  1933  					DisableEmbeddedPolicies:  true,
  1934  					DisableEmbeddedLibraries: true,
  1935  				},
  1936  			},
  1937  			putBlobExpectation: cache.ArtifactCachePutBlobExpectation{
  1938  				Args: cache.ArtifactCachePutBlobArgs{
  1939  					BlobIDAnything: true,
  1940  					BlobInfo: types.BlobInfo{
  1941  						SchemaVersion: 2,
  1942  						Misconfigurations: []types.Misconfiguration{
  1943  							{
  1944  								FileType: "terraform",
  1945  								FilePath: "main.tf",
  1946  								Failures: types.MisconfResults{
  1947  									{
  1948  										Namespace: "user.something",
  1949  										Query:     "data.user.something.deny",
  1950  										Message:   "No buckets allowed!",
  1951  										PolicyMetadata: types.PolicyMetadata{
  1952  											ID:                 "TEST001",
  1953  											AVDID:              "AVD-TEST-0001",
  1954  											Type:               "Terraform Security Check",
  1955  											Title:              "Test policy",
  1956  											Description:        "This is a test policy.",
  1957  											Severity:           "LOW",
  1958  											RecommendedActions: "Have a cup of tea.",
  1959  											References:         []string{"https://trivy.dev/"},
  1960  										},
  1961  										CauseMetadata: types.CauseMetadata{
  1962  											Resource:  "aws_s3_bucket.asd",
  1963  											Provider:  "Generic",
  1964  											Service:   "general",
  1965  											StartLine: 1,
  1966  											EndLine:   3,
  1967  										},
  1968  									},
  1969  								},
  1970  							},
  1971  							{
  1972  								FileType: "cloudformation",
  1973  								FilePath: "main.yaml",
  1974  								Failures: types.MisconfResults{
  1975  									{
  1976  										Namespace: "user.something",
  1977  										Query:     "data.user.something.deny",
  1978  										Message:   "No buckets allowed!",
  1979  										PolicyMetadata: types.PolicyMetadata{
  1980  											ID:                 "TEST001",
  1981  											AVDID:              "AVD-TEST-0001",
  1982  											Type:               "CloudFormation Security Check",
  1983  											Title:              "Test policy",
  1984  											Description:        "This is a test policy.",
  1985  											Severity:           "LOW",
  1986  											RecommendedActions: "Have a cup of tea.",
  1987  											References:         []string{"https://trivy.dev/"},
  1988  										},
  1989  										CauseMetadata: types.CauseMetadata{
  1990  											Resource:  "main.yaml:3-6",
  1991  											Provider:  "Generic",
  1992  											Service:   "general",
  1993  											StartLine: 3,
  1994  											EndLine:   6,
  1995  										},
  1996  									},
  1997  								},
  1998  							},
  1999  						},
  2000  					},
  2001  				},
  2002  				Returns: cache.ArtifactCachePutBlobReturns{},
  2003  			},
  2004  			want: types.ArtifactReference{
  2005  				Name: "testdata/misconfig/mixed/src",
  2006  				Type: types.ArtifactFilesystem,
  2007  			},
  2008  		},
  2009  	}
  2010  
  2011  	for _, tt := range tests {
  2012  		t.Run(tt.name, func(t *testing.T) {
  2013  			c := new(cache.MockArtifactCache)
  2014  			c.ApplyPutBlobExpectation(tt.putBlobExpectation)
  2015  			tt.artifactOpt.DisabledHandlers = []types.HandlerType{
  2016  				types.SystemFileFilteringPostHandler,
  2017  			}
  2018  			a, err := NewArtifact(tt.fields.dir, c, tt.artifactOpt)
  2019  			require.NoError(t, err)
  2020  
  2021  			got, err := a.Inspect(context.Background())
  2022  			require.NoError(t, err)
  2023  			require.NotNil(t, got)
  2024  
  2025  			assert.Equal(t, tt.want.Name, got.Name)
  2026  			assert.Equal(t, tt.want.Type, got.Type)
  2027  		})
  2028  	}
  2029  
  2030  }