Files
aquasecurity-trivy/pkg/rpc/server/server.go
Teppei Fukuda 2f2d1a908b feat: support repository and filesystem scan (#503)
* refactor: embed config

* refactor: replace image and layer with artifact and blob

* feat(config): add ArtifactConfig

* fix(scanner): use Artifact

* test(scanner): update mocks

* feat: add repo and fs subcommands

* chore(mod): update

* refactor: fix warn message

* feat(cli): add --no-progress to repo and fs

* mod: Update fanal dependency

Signed-off-by: Simarpreet Singh <simar@linux.com>

Co-authored-by: Simarpreet Singh <simar@linux.com>
2020-05-30 19:46:12 +03:00

95 lines
3.0 KiB
Go

package server
import (
"context"
google_protobuf "github.com/golang/protobuf/ptypes/empty"
"github.com/google/wire"
"golang.org/x/xerrors"
"github.com/aquasecurity/fanal/cache"
ftypes "github.com/aquasecurity/fanal/types"
"github.com/aquasecurity/trivy/pkg/rpc"
"github.com/aquasecurity/trivy/pkg/scanner"
"github.com/aquasecurity/trivy/pkg/scanner/local"
"github.com/aquasecurity/trivy/pkg/types"
"github.com/aquasecurity/trivy/pkg/vulnerability"
rpcCache "github.com/aquasecurity/trivy/rpc/cache"
rpcScanner "github.com/aquasecurity/trivy/rpc/scanner"
)
var ScanSuperSet = wire.NewSet(
local.SuperSet,
wire.Bind(new(scanner.Driver), new(local.Scanner)),
vulnerability.SuperSet,
NewScanServer,
)
type ScanServer struct {
localScanner scanner.Driver
vulnClient vulnerability.Operation
}
func NewScanServer(s scanner.Driver, vulnClient vulnerability.Operation) *ScanServer {
return &ScanServer{localScanner: s, vulnClient: vulnClient}
}
func (s *ScanServer) Scan(_ context.Context, in *rpcScanner.ScanRequest) (*rpcScanner.ScanResponse, error) {
options := types.ScanOptions{VulnType: in.Options.VulnType}
results, os, eosl, err := s.localScanner.Scan(in.Target, in.ArtifactId, in.BlobIds, options)
if err != nil {
return nil, xerrors.Errorf("failed scan, %s: %w", in.Target, err)
}
for i := range results {
s.vulnClient.FillInfo(results[i].Vulnerabilities, results[i].Type)
}
return rpc.ConvertToRpcScanResponse(results, os, eosl), nil
}
type CacheServer struct {
cache cache.Cache
}
func NewCacheServer(c cache.Cache) *CacheServer {
return &CacheServer{cache: c}
}
func (s *CacheServer) PutArtifact(_ context.Context, in *rpcCache.PutArtifactRequest) (*google_protobuf.Empty, error) {
if in.ArtifactInfo == nil {
return nil, xerrors.Errorf("empty image info")
}
imageInfo := rpc.ConvertFromRpcPutArtifactRequest(in)
if err := s.cache.PutArtifact(in.ArtifactId, imageInfo); err != nil {
return nil, xerrors.Errorf("unable to store image info in cache: %w", err)
}
return &google_protobuf.Empty{}, nil
}
func (s *CacheServer) PutBlob(_ context.Context, in *rpcCache.PutBlobRequest) (*google_protobuf.Empty, error) {
if in.BlobInfo == nil {
return nil, xerrors.Errorf("empty layer info")
}
layerInfo := rpc.ConvertFromRpcPutBlobRequest(in)
if err := s.cache.PutBlob(in.DiffId, layerInfo); err != nil {
return nil, xerrors.Errorf("unable to store layer info in cache: %w", err)
}
return &google_protobuf.Empty{}, nil
}
func (s *CacheServer) MissingBlobs(_ context.Context, in *rpcCache.MissingBlobsRequest) (*rpcCache.MissingBlobsResponse, error) {
var layerIDs []string
for _, blobID := range in.BlobIds {
l, err := s.cache.GetBlob(blobID)
if err != nil || l.SchemaVersion != ftypes.BlobJSONSchemaVersion {
layerIDs = append(layerIDs, blobID)
}
}
var missingImage bool
img, err := s.cache.GetArtifact(in.ArtifactId)
if err != nil || img.SchemaVersion != ftypes.ArtifactJSONSchemaVersion {
missingImage = true
}
return &rpcCache.MissingBlobsResponse{MissingArtifact: missingImage, MissingBlobIds: layerIDs}, nil
}