in providers/idefense/api/client.go [55:107]
func (c *Client) FetchAllVulnerabilities(ctx context.Context, since int64) (<-chan runner.Convertible, error) {
sinceStr := time.Unix(since, 0).Format("2006-01-02T15:04:05.000Z")
result, err := c.queryVulnerabilities(ctx, map[string]interface{}{
"last_modified.from": sinceStr,
"last_modified.inclusive": "true",
"page_size": 0,
})
if err != nil {
return nil, err
}
totalVulns := result.TotalSize
if totalVulns == 0 {
return nil, errors.New("no vulnerabilities found in given window")
}
output := make(chan runner.Convertible)
numPages := (totalVulns-1)/pageSize + 1
// fetch pages concurrently
flog.Infof("starting sync for %d vulnerabilities over %d pages\n", totalVulns, numPages)
eg, ctx := errgroup.WithContext(ctx)
for page := 1; page <= numPages; page++ {
page := page
eg.Go(func() error {
result, err := c.queryVulnerabilities(ctx, map[string]interface{}{
"last_modified.from": sinceStr,
"last_modified.inclusive": "true",
"page_size": pageSize,
"page": page,
})
if err != nil {
return client.StopOrContinue(errors.Wrapf(err, "failed to get page %d: %v", page, err))
}
for _, vuln := range result.Results {
if vuln != nil {
output <- vuln
}
}
return nil
})
}
go func() {
if err := eg.Wait(); err != nil {
flog.Errorln(err)
}
close(output)
}()
return output, nil
}