github.com/devseccon/trivy@v0.47.1-0.20231123133102-bd902a0bd996/pkg/cache/remote.go (about)

     1  package cache
     2  
     3  import (
     4  	"context"
     5  	"crypto/tls"
     6  	"net/http"
     7  
     8  	"golang.org/x/xerrors"
     9  
    10  	"github.com/devseccon/trivy/pkg/fanal/cache"
    11  	"github.com/devseccon/trivy/pkg/fanal/types"
    12  	"github.com/devseccon/trivy/pkg/rpc"
    13  	"github.com/devseccon/trivy/pkg/rpc/client"
    14  	rpcCache "github.com/devseccon/trivy/rpc/cache"
    15  )
    16  
    17  // RemoteCache implements remote cache
    18  type RemoteCache struct {
    19  	ctx    context.Context // for custom header
    20  	client rpcCache.Cache
    21  }
    22  
    23  // NewRemoteCache is the factory method for RemoteCache
    24  func NewRemoteCache(url string, customHeaders http.Header, insecure bool) cache.ArtifactCache {
    25  	ctx := client.WithCustomHeaders(context.Background(), customHeaders)
    26  
    27  	httpClient := &http.Client{
    28  		Transport: &http.Transport{
    29  			Proxy: http.ProxyFromEnvironment,
    30  			TLSClientConfig: &tls.Config{
    31  				InsecureSkipVerify: insecure,
    32  			},
    33  		},
    34  	}
    35  	c := rpcCache.NewCacheProtobufClient(url, httpClient)
    36  	return &RemoteCache{ctx: ctx, client: c}
    37  }
    38  
    39  // PutArtifact sends artifact to remote client
    40  func (c RemoteCache) PutArtifact(imageID string, artifactInfo types.ArtifactInfo) error {
    41  	err := rpc.Retry(func() error {
    42  		var err error
    43  		_, err = c.client.PutArtifact(c.ctx, rpc.ConvertToRPCArtifactInfo(imageID, artifactInfo))
    44  		return err
    45  	})
    46  	if err != nil {
    47  		return xerrors.Errorf("unable to store cache on the server: %w", err)
    48  	}
    49  	return nil
    50  }
    51  
    52  // PutBlob sends blobInfo to remote client
    53  func (c RemoteCache) PutBlob(diffID string, blobInfo types.BlobInfo) error {
    54  	err := rpc.Retry(func() error {
    55  		var err error
    56  		_, err = c.client.PutBlob(c.ctx, rpc.ConvertToRPCPutBlobRequest(diffID, blobInfo))
    57  		return err
    58  	})
    59  	if err != nil {
    60  		return xerrors.Errorf("unable to store cache on the server: %w", err)
    61  	}
    62  	return nil
    63  }
    64  
    65  // MissingBlobs fetches missing blobs from RemoteCache
    66  func (c RemoteCache) MissingBlobs(imageID string, layerIDs []string) (bool, []string, error) {
    67  	var layers *rpcCache.MissingBlobsResponse
    68  	err := rpc.Retry(func() error {
    69  		var err error
    70  		layers, err = c.client.MissingBlobs(c.ctx, rpc.ConvertToMissingBlobsRequest(imageID, layerIDs))
    71  		return err
    72  	})
    73  	if err != nil {
    74  		return false, nil, xerrors.Errorf("unable to fetch missing layers: %w", err)
    75  	}
    76  	return layers.MissingArtifact, layers.MissingBlobIds, nil
    77  }
    78  
    79  // DeleteBlobs removes blobs by IDs from RemoteCache
    80  func (c RemoteCache) DeleteBlobs(blobIDs []string) error {
    81  	err := rpc.Retry(func() error {
    82  		var err error
    83  		_, err = c.client.DeleteBlobs(c.ctx, rpc.ConvertToDeleteBlobsRequest(blobIDs))
    84  		return err
    85  	})
    86  	if err != nil {
    87  		return xerrors.Errorf("unable to delete blobs on the server: %w", err)
    88  	}
    89  	return nil
    90  }