a128f2f876
* Ignore dev version * Review commit
110 lines
2.6 KiB
Go
110 lines
2.6 KiB
Go
package photon
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/aquasecurity/vuln-list-update/utils"
|
|
"github.com/cheggaaa/pb"
|
|
"github.com/spf13/afero"
|
|
"golang.org/x/xerrors"
|
|
)
|
|
|
|
const (
|
|
advisoryURL = "https://vmware.bintray.com/photon_cve_metadata/"
|
|
versionsFile = "photon_versions.json"
|
|
advisoryFormat = "cve_data_photon%s.json"
|
|
|
|
photonDir = "photon"
|
|
retry = 5
|
|
)
|
|
|
|
type Config struct {
|
|
VulnListDir string
|
|
URL string
|
|
AppFs afero.Fs
|
|
Retry int
|
|
}
|
|
|
|
func NewConfig() Config {
|
|
return Config{
|
|
VulnListDir: utils.VulnListDir(),
|
|
URL: advisoryURL,
|
|
AppFs: afero.NewOsFs(),
|
|
Retry: retry,
|
|
}
|
|
}
|
|
|
|
func (c Config) getPhotonVersion() ([]string, error) {
|
|
var versions Versions
|
|
res, err := utils.FetchURL(c.URL+versionsFile, "", c.Retry)
|
|
if err != nil {
|
|
return nil, xerrors.Errorf("failed to fetch Photon versions: %w", err)
|
|
}
|
|
if err := json.Unmarshal(res, &versions); err != nil {
|
|
return nil, xerrors.Errorf("failed to decode Photon versions: %w", err)
|
|
}
|
|
|
|
return versions.Branches, nil
|
|
}
|
|
|
|
func (c Config) Update() error {
|
|
log.Printf("Fetching Photon")
|
|
|
|
versions, err := c.getPhotonVersion()
|
|
if err != nil {
|
|
return xerrors.Errorf("failed to get Photon versions: %w", err)
|
|
}
|
|
for _, version := range versions {
|
|
if strings.ToLower(version) == "dev" {
|
|
continue
|
|
}
|
|
res, err := utils.FetchURL(c.URL+fmt.Sprintf(advisoryFormat, version), "", c.Retry)
|
|
if err != nil {
|
|
return xerrors.Errorf("failed to fetch Photon advisory: %w", err)
|
|
}
|
|
var cves []PhotonCVE
|
|
if err := json.Unmarshal(res, &cves); err != nil {
|
|
return xerrors.Errorf("failed to unmarshal Photon advisory: %w", err)
|
|
}
|
|
dir := filepath.Join(photonDir, version)
|
|
|
|
bar := pb.StartNew(len(cves))
|
|
for _, def := range cves {
|
|
def.OSVersion = version
|
|
if err = c.saveCVEPerPkg(dir, def.Pkg, def.CveID, def); err != nil {
|
|
return xerrors.Errorf("failed to save CVE-ID per package name: %w", err)
|
|
}
|
|
bar.Increment()
|
|
}
|
|
bar.Finish()
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c Config) saveCVEPerPkg(dirName, pkgName, cveID string, data interface{}) error {
|
|
s := strings.Split(cveID, "-")
|
|
if len(s) != 3 {
|
|
log.Printf("invalid CVE-ID: %s", cveID)
|
|
return xerrors.Errorf("invalid CVE-ID format: %s", cveID)
|
|
}
|
|
|
|
pkgDir := filepath.Join(c.VulnListDir, dirName, pkgName)
|
|
if err := c.AppFs.MkdirAll(pkgDir, os.ModePerm); err != nil {
|
|
return xerrors.Errorf("failed to create dir: %w", err)
|
|
}
|
|
|
|
filePath := filepath.Join(pkgDir, fmt.Sprintf("%s.json", cveID))
|
|
|
|
fs := utils.NewFs(c.AppFs)
|
|
if err := fs.WriteJSON(filePath, data); err != nil {
|
|
return xerrors.Errorf("failed to write file: %w", err)
|
|
}
|
|
return nil
|
|
}
|