func()

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")
}