in providers/rbs/api/client.go [74:128]
func (c *Client) fetchAllVulnerabilities(getEndpoint func() string) (<-chan runner.Convertible, error) {
fetch := func(page, size int) (*schema.VulnerabilityResult, error) {
u, err := url.Parse(fmt.Sprintf("%s/api/v1/vulnerabilities/%s", c.baseURL, getEndpoint()))
if err != nil {
return nil, fmt.Errorf("can't parse url: %v", err)
}
values := u.Query()
values.Set("page", fmt.Sprintf("%d", page))
values.Set("size", fmt.Sprintf("%d", size))
u.RawQuery = values.Encode()
return c.getResult(u.String())
}
result, err := fetch(1, 1)
if err != nil {
return nil, err
}
totalVulns := result.TotalEntries
if totalVulns == 0 {
return nil, fmt.Errorf("no vulnerabilities found")
}
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)
wg := sync.WaitGroup{}
for page := 1; page <= numPages; page++ {
page := page
wg.Add(1)
go func() {
defer wg.Done()
result, err := fetch(page, pageSize)
if err != nil {
flog.Errorf("failed to get page %d: %v", page, err)
return
}
for _, vuln := range result.Vulnerabilities {
if vuln != nil {
output <- vuln
}
}
}()
}
go func() {
wg.Wait()
close(output)
}()
return output, nil
}