Files
trivy/pkg/iac/scanners/terraform/parser/resolvers/remote.go
Nikita Pivkin bfdf5cfc30 refactor(misconf): use slog (#7295)
Signed-off-by: nikpivkin <nikita.pivkin@smartforce.io>
2024-08-23 04:27:17 +00:00

98 lines
2.3 KiB
Go

package resolvers
import (
"context"
"fmt"
"io/fs"
"os"
"path/filepath"
"sync/atomic"
"github.com/hashicorp/go-getter"
"github.com/aquasecurity/trivy/pkg/log"
)
type remoteResolver struct {
count int32
}
var Remote = &remoteResolver{
count: 0,
}
func (r *remoteResolver) incrementCount(o Options) {
atomic.CompareAndSwapInt32(&r.count, r.count, r.count+1)
o.Logger.Debug("Incrementing the download counter", log.Int("count", int(r.count)))
}
func (r *remoteResolver) GetDownloadCount() int {
return int(atomic.LoadInt32(&r.count))
}
func (r *remoteResolver) Resolve(ctx context.Context, _ fs.FS, opt Options) (filesystem fs.FS, prefix, downloadPath string, applies bool, err error) {
if !opt.hasPrefix("github.com/", "bitbucket.org/", "s3:", "git@", "git:", "hg:", "https:", "gcs:") {
return nil, "", "", false, nil
}
if !opt.AllowDownloads {
return nil, "", "", false, nil
}
src, subdir := splitPackageSubdirRaw(opt.OriginalSource)
key := cacheKey(src, opt.OriginalVersion)
opt.Logger.Debug("Caching module", log.String("key", key))
baseCacheDir, err := locateCacheDir(opt.CacheDir)
if err != nil {
return nil, "", "", true, fmt.Errorf("failed to locate cache directory: %w", err)
}
cacheDir := filepath.Join(baseCacheDir, key)
if err := r.download(ctx, opt, cacheDir); err != nil {
return nil, "", "", true, err
}
r.incrementCount(opt)
opt.Logger.Debug("Successfully resolve module via remote download",
log.String("name", opt.Name),
log.String("source", opt.Source),
)
return os.DirFS(cacheDir), opt.Source, subdir, true, nil
}
func (r *remoteResolver) download(ctx context.Context, opt Options, dst string) error {
_ = os.RemoveAll(dst)
if err := os.MkdirAll(filepath.Dir(dst), 0o750); err != nil {
return err
}
var opts []getter.ClientOption
// Overwrite the file getter so that a file will be copied
getter.Getters["file"] = &getter.FileGetter{Copy: true}
opt.Logger.Debug("Downloading module", log.String("source", opt.Source))
// Build the client
client := &getter.Client{
Ctx: ctx,
Src: opt.Source,
Dst: dst,
Pwd: opt.WorkingDir,
Getters: getter.Getters,
Mode: getter.ClientModeAny,
Options: opts,
}
if err := client.Get(); err != nil {
return fmt.Errorf("failed to download: %w", err)
}
return nil
}
func (r *remoteResolver) GetSourcePrefix(source string) string {
return source
}