@@ -19,7 +19,6 @@ import (
1919 "github.com/coder/coder/v2/coderd/pproflabel"
2020 "github.com/coder/coder/v2/coderd/usage/usagetypes"
2121 "github.com/coder/coder/v2/cryptorand"
22- "github.com/coder/coder/v2/enterprise/coderd/license"
2322 "github.com/coder/coder/v2/enterprise/coderd/usage/tallymansdk"
2423 "github.com/coder/quartz"
2524)
@@ -33,8 +32,6 @@ const (
3332 tallymanPublishBatchSize = 100
3433)
3534
36- var errUsagePublishingDisabled = xerrors .New ("usage publishing is not enabled by any license" )
37-
3835// Publisher publishes usage events ***somewhere***.
3936type Publisher interface {
4037 // Close closes the publisher and waits for it to finish.
@@ -203,11 +200,17 @@ func (p *tallymanPublisher) publish(ctx context.Context, deploymentID uuid.UUID)
203200// publishOnce publishes up to tallymanPublishBatchSize usage events to
204201// tallyman. It returns the number of successfully published events.
205202func (p * tallymanPublisher ) publishOnce (ctx context.Context , deploymentID uuid.UUID ) (int , error ) {
206- licenseJwt , err := p .getBestLicenseJWT (ctx )
207- if xerrors .Is (err , errUsagePublishingDisabled ) {
203+ sdkClient , err := tallymansdk .New (ctx , tallymansdk.NewOptions {
204+ DB : p .db ,
205+ DeploymentID : deploymentID ,
206+ LicenseKeys : p .licenseKeys ,
207+ BaseURL : p .baseURL ,
208+ HTTPClient : p .httpClient ,
209+ })
210+ if xerrors .Is (err , tallymansdk .ErrNoLicenseSupportsPublishing ) {
208211 return 0 , nil
209212 } else if err != nil {
210- return 0 , xerrors .Errorf ("find usage publishing license : %w" , err )
213+ return 0 , xerrors .Errorf ("create tallyman client : %w" , err )
211214 }
212215
213216 events , err := p .db .SelectUsageEventsForPublishing (ctx , dbtime .Time (p .clock .Now ()))
@@ -246,7 +249,7 @@ func (p *tallymanPublisher) publishOnce(ctx context.Context, deploymentID uuid.U
246249 return 0 , xerrors .Errorf ("duplicate event IDs found in events for publishing" )
247250 }
248251
249- resp , err := p .sendPublishRequest (ctx , deploymentID , licenseJwt , tallymanReq )
252+ resp , err := p .sendPublishRequest (ctx , sdkClient , tallymanReq )
250253 allFailed := err != nil
251254 if err != nil {
252255 p .log .Warn (ctx , "failed to send publish request to tallyman" , slog .F ("count" , len (events )), slog .Error (err ))
@@ -336,72 +339,7 @@ func (p *tallymanPublisher) publishOnce(ctx context.Context, deploymentID uuid.U
336339 return len (resp .AcceptedEvents ), returnErr
337340}
338341
339- // getBestLicenseJWT returns the best license JWT to use for the request. The
340- // criteria is as follows:
341- // - The license must be valid and active (after nbf, before exp)
342- // - The license must have usage publishing enabled
343- // The most recently issued (iat) license is chosen.
344- //
345- // If no licenses are found or none have usage publishing enabled,
346- // errUsagePublishingDisabled is returned.
347- func (p * tallymanPublisher ) getBestLicenseJWT (ctx context.Context ) (string , error ) {
348- licenses , err := p .db .GetUnexpiredLicenses (ctx )
349- if err != nil {
350- return "" , xerrors .Errorf ("get unexpired licenses: %w" , err )
351- }
352- if len (licenses ) == 0 {
353- return "" , errUsagePublishingDisabled
354- }
355-
356- type licenseJWTWithClaims struct {
357- Claims * license.Claims
358- Raw string
359- }
360-
361- var bestLicense licenseJWTWithClaims
362- for _ , dbLicense := range licenses {
363- claims , err := license .ParseClaims (dbLicense .JWT , p .licenseKeys )
364- if err != nil {
365- p .log .Warn (ctx , "failed to parse license claims" , slog .F ("license_id" , dbLicense .ID ), slog .Error (err ))
366- continue
367- }
368- if claims .AccountType != license .AccountTypeSalesforce {
369- // Non-Salesforce accounts cannot be tracked as they do not have a
370- // trusted Salesforce opportunity ID encoded in the license.
371- continue
372- }
373- if ! claims .PublishUsageData {
374- // Publishing is disabled.
375- continue
376- }
377-
378- // Otherwise, if it's issued more recently, it's the best license.
379- // IssuedAt is verified to be non-nil in license.ParseClaims.
380- if bestLicense .Claims == nil || claims .IssuedAt .Time .After (bestLicense .Claims .IssuedAt .Time ) {
381- bestLicense = licenseJWTWithClaims {
382- Claims : claims ,
383- Raw : dbLicense .JWT ,
384- }
385- }
386- }
387-
388- if bestLicense .Raw == "" {
389- return "" , errUsagePublishingDisabled
390- }
391-
392- return bestLicense .Raw , nil
393- }
394-
395- func (p * tallymanPublisher ) sendPublishRequest (ctx context.Context , deploymentID uuid.UUID , licenseJwt string , req usagetypes.TallymanV1IngestRequest ) (usagetypes.TallymanV1IngestResponse , error ) {
396- // Create a new SDK client for this request.
397- // We create it per-request since the license key may change.
398- sdkClient := tallymansdk .New (
399- p .baseURL ,
400- licenseJwt ,
401- deploymentID ,
402- tallymansdk .WithHTTPClient (p .httpClient ),
403- )
404-
342+ func (* tallymanPublisher ) sendPublishRequest (ctx context.Context , sdkClient * tallymansdk.Client , req usagetypes.TallymanV1IngestRequest ) (usagetypes.TallymanV1IngestResponse , error ) {
405343 return sdkClient .PublishUsageEvents (ctx , req )
406344}
407345
0 commit comments