100 lines
2.8 KiB
Go
100 lines
2.8 KiB
Go
package client
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/Azure/go-autorest/autorest/adal"
|
|
"github.com/Azure/go-autorest/autorest/azure"
|
|
"github.com/Azure/go-autorest/autorest/azure/cli"
|
|
)
|
|
|
|
// for managed identity auth
|
|
type cliOAuthTokenProvider struct {
|
|
env azure.Environment
|
|
say func(string)
|
|
tenantID string
|
|
}
|
|
|
|
func NewCliOAuthTokenProvider(env azure.Environment, say func(string), tenantID string) oAuthTokenProvider {
|
|
return &cliOAuthTokenProvider{
|
|
env: env,
|
|
say: say,
|
|
tenantID: tenantID,
|
|
}
|
|
}
|
|
|
|
func (tp *cliOAuthTokenProvider) getServicePrincipalToken() (*adal.ServicePrincipalToken, error) {
|
|
return tp.getServicePrincipalTokenWithResource(tp.env.ResourceManagerEndpoint)
|
|
}
|
|
|
|
func (tp *cliOAuthTokenProvider) getServicePrincipalTokenWithResource(resource string) (*adal.ServicePrincipalToken, error) {
|
|
token, err := cli.GetTokenFromCLI(resource)
|
|
if err != nil {
|
|
tp.say(fmt.Sprintf("unable to get token from azure cli: %v", err))
|
|
return nil, err
|
|
}
|
|
|
|
oAuthConfig, err := adal.NewOAuthConfig(resource, tp.tenantID)
|
|
if err != nil {
|
|
tp.say(fmt.Sprintf("unable to generate OAuth Config: %v", err))
|
|
return nil, err
|
|
}
|
|
|
|
adalToken, err := token.ToADALToken()
|
|
if err != nil {
|
|
tp.say(fmt.Sprintf("unable to get ADAL Token from azure cli token: %v", err))
|
|
return nil, err
|
|
}
|
|
|
|
spt, err := adal.NewServicePrincipalTokenFromManualToken(*oAuthConfig, clientIDs[tp.env.Name], resource, adalToken)
|
|
if err != nil {
|
|
tp.say(fmt.Sprintf("unable to get service principal token from adal token: %v", err))
|
|
return nil, err
|
|
}
|
|
|
|
// Custom refresh function to make it possible to use Azure CLI to refresh tokens.
|
|
// Inspired by HashiCorps go-azure-helpers: https://github.com/hashicorp/go-azure-helpers/blob/373622ce2effb0cf299051ea019cb657f357a4d8/authentication/auth_method_azure_cli_token.go#L96-L109
|
|
var customRefreshFunc adal.TokenRefresh = func(ctx context.Context, resource string) (*adal.Token, error) {
|
|
token, err := cli.GetTokenFromCLI(resource)
|
|
if err != nil {
|
|
tp.say(fmt.Sprintf("token refresh - unable to get token from azure cli: %v", err))
|
|
return nil, err
|
|
}
|
|
|
|
adalToken, err := token.ToADALToken()
|
|
if err != nil {
|
|
tp.say(fmt.Sprintf("token refresh - unable to get ADAL Token from azure cli token: %v", err))
|
|
return nil, err
|
|
}
|
|
|
|
return &adalToken, nil
|
|
}
|
|
|
|
spt.SetCustomRefreshFunc(customRefreshFunc)
|
|
|
|
return spt, nil
|
|
}
|
|
|
|
// getIDsFromAzureCLI returns the TenantID and SubscriptionID from an active Azure CLI login session
|
|
func getIDsFromAzureCLI() (string, string, error) {
|
|
profilePath, err := cli.ProfilePath()
|
|
if err != nil {
|
|
return "", "", err
|
|
}
|
|
|
|
profile, err := cli.LoadProfile(profilePath)
|
|
if err != nil {
|
|
return "", "", err
|
|
}
|
|
|
|
for _, p := range profile.Subscriptions {
|
|
if p.IsDefault {
|
|
return p.TenantID, p.ID, nil
|
|
}
|
|
}
|
|
|
|
return "", "", errors.New("Unable to find default subscription")
|
|
}
|