vuln-list-update/alpine-unfixed/alpine.go

106 lines
2.1 KiB
Go
Raw Normal View History

package alpineunfixed
import (
"context"
"encoding/json"
"io/fs"
"log"
"os"
"path/filepath"
"golang.org/x/xerrors"
"github.com/aquasecurity/vuln-list-update/utils"
)
const (
alpineDir = "alpine-unfixed"
secFixUrl = "https://aquasecurity.github.io/secfixes-tracker/all.tar.gz"
)
type Updater struct {
*options
}
type options struct {
vulnListDir string
url string
}
type option func(*options)
func WithVulnListDir(dir string) option {
return func(opts *options) {
opts.vulnListDir = dir
}
}
func WithURL(url string) option {
return func(opts *options) {
opts.url = url
}
}
func NewUpdater(opts ...option) Updater {
o := &options{
vulnListDir: utils.VulnListDir(),
url: secFixUrl,
}
for _, opt := range opts {
opt(o)
}
return Updater{
options: o,
}
}
func (u Updater) Update() error {
dir := filepath.Join(u.vulnListDir, alpineDir)
log.Printf("Remove Alpine directory %s", dir)
if err := os.RemoveAll(dir); err != nil {
return xerrors.Errorf("failed to remove Alpine unfixed directory: %w", err)
}
if err := os.MkdirAll(dir, 0755); err != nil {
return xerrors.Errorf("mkdir error: %w", err)
}
log.Println("Fetching Alpine unfixed data...")
ctx := context.Background()
tmpDir, err := utils.DownloadToTempDir(ctx, u.url)
if err != nil {
return xerrors.Errorf("alpine secfixes download error: %w", err)
}
defer os.RemoveAll(tmpDir) // nolint: errcheck
log.Println("Saving Alpine unfixed data...")
err = filepath.Walk(tmpDir, func(path string, info fs.FileInfo, err error) error {
if err != nil {
return err
} else if info.IsDir() {
return nil
}
f, err := os.Open(path)
if err != nil {
return xerrors.Errorf("file open error: %w", err)
}
var vuln unfixedVulnerability
if err = json.NewDecoder(f).Decode(&vuln); err != nil {
return xerrors.Errorf("JSON decode error: %w", err)
}
filePath := filepath.Join(dir, vuln.ID) + ".json"
if err = utils.Write(filePath, vuln); err != nil {
return xerrors.Errorf("write error: %w", err)
}
return nil
})
if err != nil {
return xerrors.Errorf("walk error: %w", err)
}
return nil
}