2021-06-06 19:14:28 +03:00
package arch
import (
"encoding/json"
"fmt"
"log"
"os"
"path/filepath"
"github.com/aquasecurity/vuln-list-update/utils"
"github.com/cheggaaa/pb/v3"
"golang.org/x/xerrors"
)
const (
archLinuxDir = "arch-linux"
securityTrackerURL = "https://security.archlinux.org/json"
retry = 3
)
type securityGroups [ ] struct {
Name string ` json:"name" `
Packages [ ] string ` json:"packages" `
Status string ` json:"status" `
Severity string ` json:"severity" `
Type string ` json:"type" `
Affected string ` json:"affected" `
Fixed string ` json:"fixed" `
Issues [ ] string ` json:"issues" `
Advisories [ ] string ` json:"advisories" `
}
type options struct {
url string
dir string
retry int
}
type option func ( * options )
func WithURL ( url string ) option {
return func ( opts * options ) { opts . url = url }
}
func WithDir ( dir string ) option {
return func ( opts * options ) { opts . dir = dir }
}
func WithRetry ( retry int ) option {
return func ( opts * options ) { opts . retry = retry }
}
type ArchLinux struct {
* options
}
func NewArchLinux ( opts ... option ) ArchLinux {
o := & options {
url : securityTrackerURL ,
dir : filepath . Join ( utils . VulnListDir ( ) , archLinuxDir ) ,
retry : retry ,
}
for _ , opt := range opts {
opt ( o )
}
return ArchLinux {
options : o ,
}
}
func ( al ArchLinux ) Update ( ) error {
log . Println ( "Fetching Arch Linux data..." )
asgs , err := al . retrieveSecurityGroups ( )
if err != nil {
return xerrors . Errorf ( "failed to retrieve Arch Linux Security Groups: %w" , err )
}
log . Printf ( "Removing old dir (%s)..." , al . dir )
if err = os . RemoveAll ( al . dir ) ; err != nil {
return xerrors . Errorf ( "failed to remove Arch Linux dir: %w" , err )
}
// Save all JSON files
log . Println ( "Saving new data..." )
bar := pb . StartNew ( len ( asgs ) )
if err = os . MkdirAll ( al . dir , os . ModePerm ) ; err != nil {
return xerrors . Errorf ( "failed to create the directory: %w" , err )
}
for _ , asg := range asgs {
filePath := filepath . Join ( al . dir , fmt . Sprintf ( "%s.json" , asg . Name ) )
if err = utils . Write ( filePath , asg ) ; err != nil {
2021-09-03 01:02:09 +03:00
return xerrors . Errorf ( "failed to write Arch Linux CVE details: %w" , err )
2021-06-06 19:14:28 +03:00
}
bar . Increment ( )
}
bar . Finish ( )
return nil
}
func ( al ArchLinux ) retrieveSecurityGroups ( ) ( securityGroups , error ) {
secJSON , err := utils . FetchURL ( al . url , "" , al . retry )
if err != nil {
return nil , xerrors . Errorf ( "failed to fetch cve data from Arch Linux. err: %w" , err )
}
var asgs securityGroups
if err = json . Unmarshal ( secJSON , & asgs ) ; err != nil {
return nil , xerrors . Errorf ( "json unmarshal error: %w" , err )
}
return asgs , nil
}