Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(aws): apply filter options to result #6367

Merged
merged 1 commit into from
Mar 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions pkg/cloud/aws/commands/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,63 @@ const expectedS3ScanResult = `{
}
`

const expectedS3ScanResultWithExceptions = `{
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactName": "12345678",
"ArtifactType": "aws_account",
"Metadata": {
"ImageConfig": {
"architecture": "",
"created": "0001-01-01T00:00:00Z",
"os": "",
"rootfs": {
"type": "",
"diff_ids": null
},
"config": {}
}
},
"Results": [
{
"Target": "arn:aws:s3:::examplebucket",
"Class": "config",
"Type": "cloud",
"MisconfSummary": {
"Successes": 0,
"Failures": 1,
"Exceptions": 8
},
"Misconfigurations": [
{
"Type": "AWS",
"ID": "AVD-AWS-0094",
"AVDID": "AVD-AWS-0094",
"Title": "S3 buckets should each define an aws_s3_bucket_public_access_block",
"Description": "The \"block public access\" settings in S3 override individual policies that apply to a given bucket, meaning that all public access can be controlled in one central types for that bucket. It is therefore good practice to define these settings for each bucket in order to clearly define the public access that can be allowed for it.",
"Message": "Bucket does not have a corresponding public access block.",
"Resolution": "Define a aws_s3_bucket_public_access_block for the given bucket to control public access policies",
"Severity": "LOW",
"PrimaryURL": "https://avd.aquasec.com/misconfig/avd-aws-0094",
"References": [
"https://avd.aquasec.com/misconfig/avd-aws-0094"
],
"Status": "FAIL",
"Layer": {},
"CauseMetadata": {
"Resource": "arn:aws:s3:::examplebucket",
"Provider": "aws",
"Service": "s3",
"Code": {
"Lines": null
}
}
}
]
}
]
}
`

const expectedCustomScanResult = `{
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactName": "12345678",
Expand Down Expand Up @@ -915,6 +972,7 @@ func Test_Run(t *testing.T) {
regoPolicy string
allServices []string
inputData string
ignoreFile string
}{
{
name: "succeed with cached infra",
Expand Down Expand Up @@ -1140,6 +1198,25 @@ Summary Report for compliance: my-custom-spec
cacheContent: "testdata/s3andcloudtrailcache.json",
expectErr: true,
},
{
name: "ignore findings with .trivyignore",
options: flag.Options{
RegoOptions: flag.RegoOptions{SkipPolicyUpdate: true},
AWSOptions: flag.AWSOptions{
Region: "us-east-1",
Services: []string{"s3"},
Account: "12345678",
},
CloudOptions: flag.CloudOptions{
MaxCacheAge: time.Hour * 24 * 365 * 100,
},
MisconfOptions: flag.MisconfOptions{IncludeNonFailures: true},
},
cacheContent: "testdata/s3onlycache.json",
allServices: []string{"s3"},
ignoreFile: "testdata/.trivyignore",
want: expectedS3ScanResultWithExceptions,
},
}

ctx := clock.With(context.Background(), time.Date(2021, 8, 25, 12, 20, 30, 5, time.UTC))
Expand Down Expand Up @@ -1192,6 +1269,10 @@ Summary Report for compliance: my-custom-spec
require.NoError(t, os.WriteFile(cacheFile, cacheData, 0600))
}

if test.ignoreFile != "" {
test.options.ReportOptions.IgnoreFile = test.ignoreFile
}

err := Run(ctx, test.options)
if test.expectErr {
assert.Error(t, err)
Expand Down
8 changes: 8 additions & 0 deletions pkg/cloud/aws/commands/testdata/.trivyignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
AVD-AWS-0086
AVD-AWS-0087
AVD-AWS-0088
AVD-AWS-0090
AVD-AWS-0132
AVD-AWS-0091
AVD-AWS-0092
AVD-AWS-0093
10 changes: 6 additions & 4 deletions pkg/cloud/report/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,18 @@ func Write(ctx context.Context, rep *Report, opt flag.Options, fromCache bool) e
return writeCompliance(ctx, rep, opt, output)
}

ignoreConf, err := result.ParseIgnoreFile(ctx, opt.IgnoreFile)
if err != nil {
return xerrors.Errorf("%s error: %w", opt.IgnoreFile, err)
}

var filtered []types.Result

// filter results
for _, resultsAtTime := range rep.Results {
for _, res := range resultsAtTime.Results {
resCopy := res
if err := result.FilterResult(ctx, &resCopy, result.IgnoreConfig{}, result.FilterOption{
Severities: opt.Severities,
IncludeNonFailures: opt.IncludeNonFailures,
}); err != nil {
if err := result.FilterResult(ctx, &resCopy, ignoreConf, opt.FilterOpts()); err != nil {
return err
}
sort.Slice(resCopy.Misconfigurations, func(i, j int) bool {
Expand Down
2 changes: 1 addition & 1 deletion pkg/result/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type FilterOption struct {

// Filter filters out the report
func Filter(ctx context.Context, report types.Report, opt FilterOption) error {
ignoreConf, err := parseIgnoreFile(ctx, opt.IgnoreFile)
ignoreConf, err := ParseIgnoreFile(ctx, opt.IgnoreFile)
if err != nil {
return xerrors.Errorf("%s error: %w", opt.IgnoreFile, err)
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/result/ignore.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ func (c *IgnoreConfig) MatchLicense(licenseID, filePath string) *IgnoreFinding {
return c.Licenses.Match(licenseID, filePath, nil)
}

func parseIgnoreFile(ctx context.Context, ignoreFile string) (IgnoreConfig, error) {
func ParseIgnoreFile(ctx context.Context, ignoreFile string) (IgnoreConfig, error) {
var conf IgnoreConfig
if _, err := os.Stat(ignoreFile); errors.Is(err, fs.ErrNotExist) {
// .trivyignore doesn't necessarily exist
Expand Down