in internal/vulnerability/scanner.go [100:218]
func (f VulnerabilityScanner) scan(ctx context.Context, snap ec2.EBSSnapshot) {
f.log.Infof("Starting VulnerabilityScanner.scan, %s", snap.SnapshotId)
defer func() {
if r := recover(); r != nil {
f.log.Errorf("vulnerability scanner recovered from panic: %v", r)
}
}()
o, err := os.CreateTemp("", "")
if err != nil {
f.log.Error("VulnerabilityScanner.scan.TempFile error: ", err)
return
}
defer func(name string) {
err = os.Remove(name)
if err != nil {
f.log.Warnf("Failed to remove temporary file %s: %v", name, err)
}
}(o.Name())
opts := flag.Options{
GlobalOptions: flag.GlobalOptions{
// TODO: Make configurable
Timeout: 1 * time.Hour,
Quiet: false,
Debug: true,
},
PackageOptions: flag.PackageOptions{
PkgTypes: []string{trivy_types.PkgTypeOS, trivy_types.PkgTypeLibrary},
PkgRelationships: fanal_types.Relationships,
},
ScanOptions: flag.ScanOptions{
Target: fmt.Sprint("ebs:", snap.SnapshotId),
Scanners: []trivy_types.Scanner{trivy_types.VulnerabilityScanner},
RekorURL: "https://rekor.sigstore.dev",
},
AWSOptions: flag.AWSOptions{
Region: snap.Region,
},
DBOptions: flag.DBOptions{
SkipDBUpdate: true,
SkipJavaDBUpdate: true,
},
ReportOptions: flag.ReportOptions{
Output: o.Name(),
Format: "json",
Severities: []db_types.Severity{0, 1, 2, 3, 4},
},
}
now := time.Now()
report, err := f.runner.ScanVM(ctx, opts)
f.log.Infof(
"VulnerabilityScanner.scan.ScanVM took %s to scan %s, volume size: %d, isEncrypted: %t, instanceId: %s",
time.Since(now),
snap.SnapshotId,
snap.VolumeSize,
snap.IsEncrypted,
*snap.Instance.InstanceId,
)
if err != nil {
f.log.Errorf("VulnerabilityScanner.scan.ScanVM, snapshotId: %s, instanceId: %s, error: %v", snap.SnapshotId, *snap.Instance.InstanceId, err)
return
}
f.log.Info("VulnerabilityScanner.scan.Filter")
report, err = f.runner.Filter(ctx, opts, report)
if err != nil {
f.log.Error("VulnerabilityScanner.scan.Filter error: ", err)
return
}
f.log.Info("VulnerabilityScanner.scan.Report")
err = f.runner.Report(ctx, opts, report)
if err != nil {
f.log.Error("VulnerabilityScanner.scan.Report error: ", err)
return
}
f.log.Info("VulnerabilityScanner.scan.jsonFile")
jsonFile, err := os.Open(o.Name())
if err != nil {
f.log.Error("VulnerabilityScanner.scan.jsonFile error: ", err)
return
}
defer jsonFile.Close()
f.log.Info("VulnerabilityScanner.scan.ReadAll")
byteValue, _ := io.ReadAll(jsonFile)
var unmarshalledReport trivy_types.Report
err = json.Unmarshal(byteValue, &unmarshalledReport)
if err != nil {
f.log.Error("VulnerabilityScanner.scan.Unmarshal error: ", err)
return
}
results := []Result{}
for _, result := range unmarshalledReport.Results {
for _, vul := range result.Vulnerabilities {
// TODO: Replace sequence with more generic approach
result := Result{
reportResult: result,
vulnerability: vul,
snapshot: snap,
seq: f.seq,
}
results = append(results, result)
}
}
select {
case <-ctx.Done():
f.log.Info("VulnerabilityScanner.scan context canceled while sending vulnerabilities")
return
case f.ch <- results:
}
f.log.Info("VulnerabilityScanner.scan.DONE")
}