github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/cmd/roachprod/vm/azure/auth.go (about) 1 // Copyright 2019 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package azure 12 13 import ( 14 "net/http" 15 16 "github.com/Azure/go-autorest/autorest" 17 "github.com/Azure/go-autorest/autorest/azure/auth" 18 "github.com/cockroachdb/errors" 19 ) 20 21 // getAuthorizer returns an Authorizer, which uses the Azure CLI 22 // to log into the portal. 23 // 24 // It would be possible to implement an OAuth2 flow, avoiding the need 25 // to install the Azure CLI. 26 // 27 // The Authorizer is memoized in the Provider. 28 func (p *Provider) getAuthorizer() (ret autorest.Authorizer, err error) { 29 p.mu.Lock() 30 ret = p.mu.authorizer 31 p.mu.Unlock() 32 if ret != nil { 33 return 34 } 35 36 // Use the azure CLI to bootstrap our authentication. 37 // https://docs.microsoft.com/en-us/go/azure/azure-sdk-go-authorization 38 ret, err = auth.NewAuthorizerFromCLI() 39 if err == nil { 40 p.mu.Lock() 41 p.mu.authorizer = ret 42 p.mu.Unlock() 43 } else { 44 err = errors.Wrap(err, "could got get Azure auth token") 45 } 46 return 47 } 48 49 // getAuthToken extracts the JWT token from the active Authorizer. 50 func (p *Provider) getAuthToken() (string, error) { 51 auth, err := p.getAuthorizer() 52 if err != nil { 53 return "", err 54 } 55 56 // We'll steal the auth Bearer token by creating a fake HTTP request. 57 fake := &http.Request{} 58 if _, err := auth.WithAuthorization()(&stealAuth{}).Prepare(fake); err != nil { 59 return "", err 60 } 61 return fake.Header.Get("Authorization")[7:], nil 62 } 63 64 type stealAuth struct { 65 } 66 67 var _ autorest.Preparer = &stealAuth{} 68 69 // Prepare implements the autorest.Preparer interface. 70 func (*stealAuth) Prepare(r *http.Request) (*http.Request, error) { 71 return r, nil 72 }