func()

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
}