106 lines
2.1 KiB
Go
106 lines
2.1 KiB
Go
|
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
|
||
|
}
|