@@ -6,9 +6,10 @@ import (
6
6
"net/http"
7
7
"net/url"
8
8
"strings"
9
- "sync"
10
9
"time"
11
10
11
+ "github.com/sourcegraph/conc/pool"
12
+
12
13
"github.com/google/uuid"
13
14
"github.com/nais/api/internal/graph/model"
14
15
"github.com/nais/api/internal/graph/scalar"
@@ -137,28 +138,24 @@ func (c *Client) VulnerabilitySummary(ctx context.Context, app *AppInstance) (*m
137
138
}
138
139
139
140
func (c * Client ) GetVulnerabilities (ctx context.Context , apps []* AppInstance ) ([]* model.Vulnerability , error ) {
140
- var wg sync.WaitGroup
141
141
now := time .Now ()
142
-
143
142
nodes := make ([]* model.Vulnerability , 0 )
144
- for _ , a := range apps {
145
- wg .Add (1 )
146
- go func (app * AppInstance ) {
147
- defer wg .Done ()
148
- v , err := c .findingsForApp (ctx , app )
143
+ p := pool .New ().WithMaxGoroutines (10 )
144
+ for _ , app := range apps {
145
+ p .Go (func () {
146
+ appVulnNode , err := c .findingsForApp (ctx , app )
149
147
if err != nil {
150
148
c .log .Errorf ("retrieveFindings for app %q: %v" , app .ID (), err )
151
149
return
152
150
}
153
- if v == nil {
151
+ if appVulnNode == nil {
154
152
c .log .Debugf ("no findings found in DependencyTrack for app %q" , app .ID ())
155
153
return
156
154
}
157
- nodes = append (nodes , v )
158
- }( a )
155
+ nodes = append (nodes , appVulnNode )
156
+ })
159
157
}
160
- wg .Wait ()
161
-
158
+ p .Wait ()
162
159
c .log .Debugf ("DependencyTrack fetch: %v\n " , time .Since (now ))
163
160
return nodes , nil
164
161
}
@@ -186,7 +183,7 @@ func (c *Client) findingsForApp(ctx context.Context, app *AppInstance) (*model.V
186
183
findingsLink := fmt .Sprintf ("%s/projects/%s/findings" , u , p .Uuid )
187
184
188
185
v .FindingsLink = findingsLink
189
- v .HasBom = p . LastBomImportFormat != ""
186
+ v .HasBom = hasBom ( p )
190
187
191
188
if ! v .HasBom {
192
189
c .log .Debugf ("no bom found in DependencyTrack for project %s" , p .Name )
@@ -206,6 +203,13 @@ func (c *Client) findingsForApp(ctx context.Context, app *AppInstance) (*model.V
206
203
return v , nil
207
204
}
208
205
206
+ // Due to the nature of the DependencyTrack API, the 'LastBomImportFormat' is not reliable to determine if a project has a BOM.
207
+ // The 'LastBomImportFormat' can be empty even if the project has a BOM.
208
+ // As a fallback, we can check if projects has registered any components, then we assume that if a project has components, it has a BOM.
209
+ func hasBom (p * dependencytrack.Project ) bool {
210
+ return p .LastBomImportFormat != "" || p .Metrics != nil && p .Metrics .Components > 0
211
+ }
212
+
209
213
func (c * Client ) retrieveFindings (ctx context.Context , uuid string ) ([]* dependencytrack.Finding , error ) {
210
214
findings , err := c .client .GetFindings (ctx , uuid )
211
215
if err != nil {
0 commit comments