@@ -2,6 +2,8 @@ package cli
2
2
3
3
import (
4
4
"context"
5
+ "encoding/base64"
6
+ "encoding/json"
5
7
"errors"
6
8
"flag"
7
9
"fmt"
@@ -33,6 +35,7 @@ import (
33
35
"github.com/coder/coder/cli/config"
34
36
"github.com/coder/coder/coderd"
35
37
"github.com/coder/coder/coderd/gitauth"
38
+ "github.com/coder/coder/coderd/telemetry"
36
39
"github.com/coder/coder/codersdk"
37
40
"github.com/coder/coder/codersdk/agentsdk"
38
41
)
@@ -425,6 +428,24 @@ type RootCmd struct {
425
428
noFeatureWarning bool
426
429
}
427
430
431
+ func telemetryInvocation (i * clibase.Invocation ) telemetry.CLIInvocation {
432
+ var topts []telemetry.CLIOption
433
+ for _ , opt := range i .Command .FullOptions () {
434
+ if opt .ValueSource == clibase .ValueSourceNone || opt .ValueSource == clibase .ValueSourceDefault {
435
+ continue
436
+ }
437
+ topts = append (topts , telemetry.CLIOption {
438
+ Name : opt .Name ,
439
+ ValueSource : string (opt .ValueSource ),
440
+ })
441
+ }
442
+ return telemetry.CLIInvocation {
443
+ Command : i .Command .FullName (),
444
+ Options : topts ,
445
+ InvokedAt : time .Now (),
446
+ }
447
+ }
448
+
428
449
// InitClient sets client to a new client.
429
450
// It reads from global configuration files if flags are not set.
430
451
func (r * RootCmd ) InitClient (client * codersdk.Client ) clibase.MiddlewareFunc {
@@ -465,7 +486,18 @@ func (r *RootCmd) InitClient(client *codersdk.Client) clibase.MiddlewareFunc {
465
486
}
466
487
}
467
488
468
- err = r .setClient (client , r .clientURL )
489
+ telemInv := telemetryInvocation (i )
490
+ byt , err := json .Marshal (telemInv )
491
+ if err != nil {
492
+ // Should be impossible
493
+ panic (err )
494
+ }
495
+ err = r .setClient (
496
+ client , r .clientURL ,
497
+ append (r .header , codersdk .CLITelemetryHeader + "=" +
498
+ base64 .StdEncoding .EncodeToString (byt ),
499
+ ),
500
+ )
469
501
if err != nil {
470
502
return err
471
503
}
@@ -512,12 +544,12 @@ func (r *RootCmd) InitClient(client *codersdk.Client) clibase.MiddlewareFunc {
512
544
}
513
545
}
514
546
515
- func (r * RootCmd ) setClient (client * codersdk.Client , serverURL * url.URL ) error {
547
+ func (* RootCmd ) setClient (client * codersdk.Client , serverURL * url.URL , headers [] string ) error {
516
548
transport := & headerTransport {
517
549
transport : http .DefaultTransport ,
518
550
header : http.Header {},
519
551
}
520
- for _ , header := range r . header {
552
+ for _ , header := range headers {
521
553
parts := strings .SplitN (header , "=" , 2 )
522
554
if len (parts ) < 2 {
523
555
return xerrors .Errorf ("split header %q had less than two parts" , header )
@@ -533,7 +565,7 @@ func (r *RootCmd) setClient(client *codersdk.Client, serverURL *url.URL) error {
533
565
534
566
func (r * RootCmd ) createUnauthenticatedClient (serverURL * url.URL ) (* codersdk.Client , error ) {
535
567
var client codersdk.Client
536
- err := r .setClient (& client , serverURL )
568
+ err := r .setClient (& client , serverURL , r . header )
537
569
return & client , err
538
570
}
539
571
0 commit comments