Skip to content

Commit

Permalink
refactor: add scanResponse
Browse files Browse the repository at this point in the history
  • Loading branch information
DmitriyLewen committed Feb 18, 2025
1 parent 75c8c64 commit 945ddc3
Show file tree
Hide file tree
Showing 8 changed files with 566 additions and 535 deletions.
11 changes: 7 additions & 4 deletions pkg/rpc/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"github.com/twitchtv/twirp"
"golang.org/x/xerrors"

ftypes "github.com/aquasecurity/trivy/pkg/fanal/types"
r "github.com/aquasecurity/trivy/pkg/rpc"
"github.com/aquasecurity/trivy/pkg/types"
xstrings "github.com/aquasecurity/trivy/pkg/x/strings"
Expand Down Expand Up @@ -68,7 +67,7 @@ func NewScanner(scannerOptions ScannerOption, opts ...Option) Scanner {
}

// Scan scans the image
func (s Scanner) Scan(ctx context.Context, target, artifactKey string, blobKeys []string, opts types.ScanOptions) (types.Results, ftypes.OS, ftypes.LayersMetadata, error) {
func (s Scanner) Scan(ctx context.Context, target, artifactKey string, blobKeys []string, opts types.ScanOptions) (types.ScanResponse, error) {
ctx = WithCustomHeaders(ctx, s.customHeaders)

// Convert to the rpc struct
Expand Down Expand Up @@ -104,8 +103,12 @@ func (s Scanner) Scan(ctx context.Context, target, artifactKey string, blobKeys
return err
})
if err != nil {
return nil, ftypes.OS{}, nil, xerrors.Errorf("failed to detect vulnerabilities via RPC: %w", err)
return types.ScanResponse{}, xerrors.Errorf("failed to detect vulnerabilities via RPC: %w", err)
}

return r.ConvertFromRPCResults(res.Results), r.ConvertFromRPCOS(res.Os), r.ConvertFromRPCLayersMetadata(res.LayersMetadata), nil
return types.ScanResponse{
Results: r.ConvertFromRPCResults(res.Results),
OS: r.ConvertFromRPCOS(res.Os),
LayersMetadata: r.ConvertFromRPCLayersMetadata(res.LayersMetadata),
}, nil
}
94 changes: 47 additions & 47 deletions pkg/rpc/client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ func TestScanner_Scan(t *testing.T) {
customHeaders http.Header
args args
expectation *rpc.ScanResponse
wantResults types.Results
wantOS ftypes.OS
want types.ScanResponse
wantEosl bool
wantErr string
}{
Expand Down Expand Up @@ -106,54 +105,56 @@ func TestScanner_Scan(t *testing.T) {
},
},
},
wantResults: types.Results{
{
Target: "alpine:3.11",
Vulnerabilities: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2020-0001",
PkgName: "musl",
InstalledVersion: "1.2.3",
FixedVersion: "1.2.4",
Vulnerability: dbTypes.Vulnerability{
Title: "DoS",
Description: "Denial os Service",
Severity: "CRITICAL",
References: []string{"http://example.com"},
VendorSeverity: dbTypes.VendorSeverity{
vulnerability.NVD: dbTypes.SeverityMedium,
vulnerability.RedHat: dbTypes.SeverityMedium,
},
CVSS: dbTypes.VendorCVSS{
"nvd": {
V2Vector: "AV:L/AC:L/Au:N/C:C/I:C/A:C",
V3Vector: "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
V2Score: 7.2,
V3Score: 7.8,
want: types.ScanResponse{
Results: types.Results{
{
Target: "alpine:3.11",
Vulnerabilities: []types.DetectedVulnerability{
{
VulnerabilityID: "CVE-2020-0001",
PkgName: "musl",
InstalledVersion: "1.2.3",
FixedVersion: "1.2.4",
Vulnerability: dbTypes.Vulnerability{
Title: "DoS",
Description: "Denial os Service",
Severity: "CRITICAL",
References: []string{"http://example.com"},
VendorSeverity: dbTypes.VendorSeverity{
vulnerability.NVD: dbTypes.SeverityMedium,
vulnerability.RedHat: dbTypes.SeverityMedium,
},
"redhat": {
V2Vector: "AV:H/AC:L/Au:N/C:C/I:C/A:C",
V3Vector: "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
V2Score: 4.2,
V3Score: 2.8,
CVSS: dbTypes.VendorCVSS{
"nvd": {
V2Vector: "AV:L/AC:L/Au:N/C:C/I:C/A:C",
V3Vector: "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
V2Score: 7.2,
V3Score: 7.8,
},
"redhat": {
V2Vector: "AV:H/AC:L/Au:N/C:C/I:C/A:C",
V3Vector: "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
V2Score: 4.2,
V3Score: 2.8,
},
},
CweIDs: []string{"CWE-78"},
LastModifiedDate: utils.MustTimeParse("2020-01-01T01:01:00Z"),
PublishedDate: utils.MustTimeParse("2001-01-01T01:01:00Z"),
},
SeveritySource: "nvd",
Layer: ftypes.Layer{
DiffID: "sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10",
},
CweIDs: []string{"CWE-78"},
LastModifiedDate: utils.MustTimeParse("2020-01-01T01:01:00Z"),
PublishedDate: utils.MustTimeParse("2001-01-01T01:01:00Z"),
},
SeveritySource: "nvd",
Layer: ftypes.Layer{
DiffID: "sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10",
},
},
},
},
},
wantOS: ftypes.OS{
Family: "alpine",
Name: "3.11",
Eosl: true,
OS: ftypes.OS{
Family: "alpine",
Name: "3.11",
Eosl: true,
},
},
},
{
Expand Down Expand Up @@ -198,7 +199,7 @@ func TestScanner_Scan(t *testing.T) {

s := NewScanner(ScannerOption{CustomHeaders: tt.customHeaders}, WithRPCClient(client))

gotResults, gotOS, _, err := s.Scan(context.Background(), tt.args.target, tt.args.imageID, tt.args.layerIDs, tt.args.options)
gotResponse, err := s.Scan(context.Background(), tt.args.target, tt.args.imageID, tt.args.layerIDs, tt.args.options)

if tt.wantErr != "" {
require.Error(t, err, tt.name)
Expand All @@ -207,8 +208,7 @@ func TestScanner_Scan(t *testing.T) {
}

require.NoError(t, err, tt.name)
assert.Equal(t, tt.wantResults, gotResults)
assert.Equal(t, tt.wantOS, gotOS)
assert.Equal(t, tt.want, gotResponse)
})
}
}
Expand Down Expand Up @@ -242,7 +242,7 @@ func TestScanner_ScanServerInsecure(t *testing.T) {
},
})
s := NewScanner(ScannerOption{Insecure: tt.insecure}, WithRPCClient(c))
_, _, _, err := s.Scan(context.Background(), "dummy", "", nil, types.ScanOptions{})
_, err := s.Scan(context.Background(), "dummy", "", nil, types.ScanOptions{})

if tt.wantErr != "" {
require.Error(t, err)
Expand Down
8 changes: 4 additions & 4 deletions pkg/rpc/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -973,9 +973,9 @@ func ConvertToMissingBlobsRequest(imageID string, layerIDs []string) *cache.Miss
}

// ConvertToRPCScanResponse converts types.Result to ScanResponse
func ConvertToRPCScanResponse(results types.Results, fos ftypes.OS, layersMetadata ftypes.LayersMetadata) *scanner.ScanResponse {
func ConvertToRPCScanResponse(response types.ScanResponse) *scanner.ScanResponse {
var rpcResults []*scanner.Result
for _, result := range results {
for _, result := range response.Results {
secretFindings := lo.Map(result.Secrets, func(s types.DetectedSecret, _ int) ftypes.SecretFinding {
return ftypes.SecretFinding(s)
})
Expand All @@ -993,8 +993,8 @@ func ConvertToRPCScanResponse(results types.Results, fos ftypes.OS, layersMetada
}

return &scanner.ScanResponse{
Os: ConvertToRPCOS(fos),
LayersMetadata: ConvertToRPCLayersMetadata(layersMetadata),
Os: ConvertToRPCOS(response.OS),
LayersMetadata: ConvertToRPCLayersMetadata(response.LayersMetadata),
Results: rpcResults,
}
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/rpc/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ func teeError(err error) error {
// Scan scans and return response
func (s *ScanServer) Scan(ctx context.Context, in *rpcScanner.ScanRequest) (*rpcScanner.ScanResponse, error) {
options := s.ToOptions(in.Options)
results, os, layersMetadata, err := s.localScanner.Scan(ctx, in.Target, in.ArtifactId, in.BlobIds, options)
scanResponse, err := s.localScanner.Scan(ctx, in.Target, in.ArtifactId, in.BlobIds, options)
if err != nil {
return nil, teeError(xerrors.Errorf("failed scan, %s: %w", in.Target, err))
}

return rpc.ConvertToRPCScanResponse(results, os, layersMetadata), nil
return rpc.ConvertToRPCScanResponse(scanResponse), nil
}

func (s *ScanServer) ToOptions(in *rpcScanner.ScanOptions) types.ScanOptions {
Expand Down
12 changes: 8 additions & 4 deletions pkg/scanner/local/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func NewScanner(a applier.Applier, osPkgScanner ospkg.Scanner, langPkgScanner la

// Scan scans the artifact and return results.
func (s Scanner) Scan(ctx context.Context, targetName, artifactKey string, blobKeys []string, options types.ScanOptions) (
types.Results, ftypes.OS, ftypes.LayersMetadata, error) {
types.ScanResponse, error) {
detail, err := s.applier.ApplyLayers(artifactKey, blobKeys)
switch {
case errors.Is(err, analyzer.ErrUnknownOS):
Expand All @@ -88,7 +88,7 @@ func (s Scanner) Scan(ctx context.Context, targetName, artifactKey string, blobK
log.Warn("No OS package is detected. Make sure you haven't deleted any files that contain information about the installed packages.")
log.Warn(`e.g. files under "/lib/apk/db/", "/var/lib/dpkg/" and "/var/lib/rpm"`)
case err != nil:
return nil, ftypes.OS{}, nil, xerrors.Errorf("failed to apply layers: %w", err)
return types.ScanResponse{}, xerrors.Errorf("failed to apply layers: %w", err)
}

if !lo.IsEmpty(options.Distro) && !lo.IsEmpty(detail.OS) {
Expand All @@ -111,9 +111,13 @@ func (s Scanner) Scan(ctx context.Context, targetName, artifactKey string, blobK

results, os, err := s.ScanTarget(ctx, target, options)
if err != nil {
return nil, ftypes.OS{}, ftypes.LayersMetadata{}, err
return types.ScanResponse{}, err
}
return results, os, detail.LayersMetadata, nil
return types.ScanResponse{
Results: results,
OS: os,
LayersMetadata: detail.LayersMetadata,
}, nil
}

func (s Scanner) ScanTarget(ctx context.Context, target types.ScanTarget, options types.ScanOptions) (types.Results, ftypes.OS, error) {
Expand Down
Loading

0 comments on commit 945ddc3

Please sign in to comment.