@@ -14,11 +14,14 @@ import (
1414 "github.com/google/uuid"
1515 "github.com/urfave/cli"
1616
17+ "github.com/smallstep/certificates/ca"
1718 "github.com/smallstep/cli-utils/errs"
1819 "github.com/smallstep/cli-utils/ui"
1920 "go.step.sm/crypto/pemutil"
21+ "go.step.sm/crypto/randutil"
2022
2123 "github.com/smallstep/cli/internal/cryptoutil"
24+ "github.com/smallstep/cli/internal/httptransport"
2225)
2326
2427func createCommand () cli.Command {
@@ -98,27 +101,23 @@ func createAction(ctx *cli.Context) (err error) {
98101 return err
99102 }
100103
101- b := & bytes.Buffer {}
102- r := & createTokenReq {
104+ b := new ( bytes.Buffer )
105+ r := createTokenReq {
103106 Bundle : clientCert .Certificate ,
104107 Audience : audience ,
105108 }
109+
106110 if err := uuid .Validate (teamID ); err != nil {
107111 r .TeamSlug = teamID
108112 } else {
109113 r .TeamID = teamID
110114 }
111- err = json .NewEncoder (b ).Encode (r )
112- if err != nil {
113- return err
114- }
115115
116- post , err := http .NewRequest ("POST" , apiURL , b )
117- if err != nil {
116+ if err := json .NewEncoder (b ).Encode (r ); err != nil {
118117 return err
119118 }
120- post . Header . Set ( "Content-Type" , "application/json" )
121- transport := http . DefaultTransport .( * http. Transport ). Clone ()
119+
120+ transport := httptransport . New ()
122121 transport .TLSClientConfig = & tls.Config {
123122 GetClientCertificate : func (* tls.CertificateRequestInfo ) (* tls.Certificate , error ) {
124123 return clientCert , nil
@@ -128,7 +127,16 @@ func createAction(ctx *cli.Context) (err error) {
128127 client := http.Client {
129128 Transport : transport ,
130129 }
131- resp , err := client .Do (post )
130+
131+ req , err := http .NewRequest ("POST" , apiURL , b )
132+ if err != nil {
133+ return err
134+ }
135+ req .Header .Set ("Content-Type" , "application/json" )
136+ req .Header .Set ("User-Agent" , ca .UserAgent ) // this is set to step.Version() during init; i.e. "Smallstep CLI/vX.X.X (os/arch)"
137+ req .Header .Set (requestIDHeader , newRequestID ())
138+
139+ resp , err := client .Do (req )
132140 if err != nil {
133141 return err
134142 }
@@ -152,6 +160,21 @@ func createAction(ctx *cli.Context) (err error) {
152160 return nil
153161}
154162
163+ // requestIDHeader is the header name used for propagating request IDs from
164+ // the client to the server and back again.
165+ const requestIDHeader = "X-Request-Id"
166+
167+ // newRequestID generates a new random UUIDv4 request ID. If it fails,
168+ // the request ID will be the empty string.
169+ func newRequestID () string {
170+ requestID , err := randutil .UUIDv4 ()
171+ if err != nil {
172+ return ""
173+ }
174+
175+ return requestID
176+ }
177+
155178func createClientCertificate (crtFile , keyFile string ) (* tls.Certificate , error ) {
156179 certs , err := pemutil .ReadCertificateBundle (crtFile )
157180 if err != nil {
0 commit comments