build(deps): bump github.com/Azure/go-autorest/autorest
Bumps [github.com/Azure/go-autorest/autorest](https://github.com/Azure/go-autorest) from 0.10.0 to 0.11.20. - [Release notes](https://github.com/Azure/go-autorest/releases) - [Changelog](https://github.com/Azure/go-autorest/blob/master/CHANGELOG.md) - [Commits](https://github.com/Azure/go-autorest/compare/autorest/v0.10.0...autorest/v0.11.20) --- updated-dependencies: - dependency-name: github.com/Azure/go-autorest/autorest dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
parent
3ccdf85295
commit
23f1526160
52 changed files with 1005 additions and 353 deletions
2
go.mod
2
go.mod
|
|
@ -8,7 +8,7 @@ require (
|
|||
github.com/Azure/azure-pipeline-go v0.2.3
|
||||
github.com/Azure/azure-sdk-for-go v41.3.0+incompatible
|
||||
github.com/Azure/azure-storage-blob-go v0.13.0
|
||||
github.com/Azure/go-autorest/autorest v0.10.0
|
||||
github.com/Azure/go-autorest/autorest v0.11.20
|
||||
github.com/Azure/go-autorest/autorest/azure/auth v0.4.2
|
||||
github.com/Azure/go-autorest/autorest/to v0.3.0 // indirect
|
||||
github.com/Azure/go-autorest/autorest/validation v0.2.0 // indirect
|
||||
|
|
|
|||
15
go.sum
15
go.sum
|
|
@ -45,14 +45,14 @@ github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK
|
|||
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
|
||||
github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0=
|
||||
github.com/Azure/go-autorest/autorest v0.10.0 h1:mvdtztBqcL8se7MdrUweNieTNi4kfNG6GOJuurQJpuY=
|
||||
github.com/Azure/go-autorest/autorest v0.10.0/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630=
|
||||
github.com/Azure/go-autorest/autorest v0.11.20 h1:s8H1PbCZSqg/DH7JMlOz6YMig6htWLNPsjDdlLqCx3M=
|
||||
github.com/Azure/go-autorest/autorest v0.11.20/go.mod h1:o3tqFY+QR40VOlk+pV4d77mORO64jOXSgEnPQgLK6JY=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.1/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.2 h1:Aze/GQeAN1RRbGmnUJvUj+tFGBzFdIg3293/A9rbxC4=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.2/go.mod h1:/3SMAM86bP6wC9Ev35peQDUeqFZBMH07vvUOmg4z/fE=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.13 h1:Mp5hbtOePIzM8pJVRa3YLrWWmZtoxRXqUEzCfJt3+/Q=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M=
|
||||
github.com/Azure/go-autorest/autorest/azure/auth v0.4.2 h1:iM6UAvjR97ZIeR93qTcwpKNMpV+/FTWjwEbuPD495Tk=
|
||||
github.com/Azure/go-autorest/autorest/azure/auth v0.4.2/go.mod h1:90gmfKdlmKgfjUpnCEpOJzsUEjrWDSLwHIG73tSXddM=
|
||||
github.com/Azure/go-autorest/autorest/azure/cli v0.3.1 h1:LXl088ZQlP0SBppGFsRZonW6hSvwgL5gRByMbvUbx8U=
|
||||
|
|
@ -70,8 +70,9 @@ github.com/Azure/go-autorest/autorest/to v0.3.0 h1:zebkZaadz7+wIQYgC7GXaz3Wb28yK
|
|||
github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA=
|
||||
github.com/Azure/go-autorest/autorest/validation v0.2.0 h1:15vMO4y76dehZSq7pAaOLQxC6dZYsSrj2GQpflyM/L4=
|
||||
github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI=
|
||||
github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY=
|
||||
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
|
||||
github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg=
|
||||
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||
|
|
@ -138,7 +139,6 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
|||
github.com/davecgh/go-xdr v0.0.0-20161123171359-e6a2ba005892/go.mod h1:CTDl0pzVzE5DEzZhPfvhY/9sPFMQIxaJ9VAMs9AagrE=
|
||||
github.com/deepmap/oapi-codegen v1.3.12 h1:HiWZO0qMhSmqZH9VdbtsBK7lOSYYJ7jsa26DpydbEEw=
|
||||
github.com/deepmap/oapi-codegen v1.3.12/go.mod h1:suMvK7+rKlx3+tpa8ByptmvoXbAV70wERKTOGH3hLp0=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dimchansky/utfbom v1.1.0 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TRo4=
|
||||
github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
|
||||
|
|
@ -154,6 +154,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
|
|||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk=
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
|
||||
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
|
|
@ -572,6 +574,7 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
|||
golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
|
|
|
|||
5
vendor/github.com/Azure/go-autorest/autorest/adal/go.mod
generated
vendored
5
vendor/github.com/Azure/go-autorest/autorest/adal/go.mod
generated
vendored
|
|
@ -6,7 +6,8 @@ require (
|
|||
github.com/Azure/go-autorest v14.2.0+incompatible
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.1
|
||||
github.com/Azure/go-autorest/logger v0.2.1
|
||||
github.com/Azure/go-autorest/tracing v0.6.0
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0
|
||||
)
|
||||
|
|
|
|||
10
vendor/github.com/Azure/go-autorest/autorest/adal/go.sum
generated
vendored
10
vendor/github.com/Azure/go-autorest/autorest/adal/go.sum
generated
vendored
|
|
@ -4,14 +4,16 @@ github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8K
|
|||
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.1 h1:K0laFcLE6VLTOwNgSxaGbUcLPuGXlNkbVvq4cW4nIHk=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
||||
github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg=
|
||||
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk=
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 h1:hb9wdF1z5waM+dSIICn1l0DkLVDT3hqhhQsDNUmHPRE=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
|
|
|||
1
vendor/github.com/Azure/go-autorest/autorest/adal/sender.go
generated
vendored
1
vendor/github.com/Azure/go-autorest/autorest/adal/sender.go
generated
vendored
|
|
@ -28,6 +28,7 @@ const (
|
|||
mimeTypeFormPost = "application/x-www-form-urlencoded"
|
||||
)
|
||||
|
||||
// DO NOT ACCESS THIS DIRECTLY. go through sender()
|
||||
var defaultSender Sender
|
||||
var defaultSenderInit = &sync.Once{}
|
||||
|
||||
|
|
|
|||
465
vendor/github.com/Azure/go-autorest/autorest/adal/token.go
generated
vendored
465
vendor/github.com/Azure/go-autorest/autorest/adal/token.go
generated
vendored
|
|
@ -30,12 +30,14 @@ import (
|
|||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest/date"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"github.com/Azure/go-autorest/logger"
|
||||
"github.com/form3tech-oss/jwt-go"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -69,13 +71,22 @@ const (
|
|||
defaultMaxMSIRefreshAttempts = 5
|
||||
|
||||
// asMSIEndpointEnv is the environment variable used to store the endpoint on App Service and Functions
|
||||
asMSIEndpointEnv = "MSI_ENDPOINT"
|
||||
msiEndpointEnv = "MSI_ENDPOINT"
|
||||
|
||||
// asMSISecretEnv is the environment variable used to store the request secret on App Service and Functions
|
||||
asMSISecretEnv = "MSI_SECRET"
|
||||
msiSecretEnv = "MSI_SECRET"
|
||||
|
||||
// the API version to use for the App Service MSI endpoint
|
||||
appServiceAPIVersion = "2017-09-01"
|
||||
// the API version to use for the legacy App Service MSI endpoint
|
||||
appServiceAPIVersion2017 = "2017-09-01"
|
||||
|
||||
// secret header used when authenticating against app service MSI endpoint
|
||||
secretHeader = "Secret"
|
||||
|
||||
// the format for expires_on in UTC with AM/PM
|
||||
expiresOnDateFormatPM = "1/2/2006 15:04:05 PM +00:00"
|
||||
|
||||
// the format for expires_on in UTC without AM/PM
|
||||
expiresOnDateFormat = "1/2/2006 15:04:05 +00:00"
|
||||
)
|
||||
|
||||
// OAuthTokenProvider is an interface which should be implemented by an access token retriever
|
||||
|
|
@ -282,6 +293,8 @@ func (secret ServicePrincipalCertificateSecret) MarshalJSON() ([]byte, error) {
|
|||
|
||||
// ServicePrincipalMSISecret implements ServicePrincipalSecret for machines running the MSI Extension.
|
||||
type ServicePrincipalMSISecret struct {
|
||||
msiType msiType
|
||||
clientResourceID string
|
||||
}
|
||||
|
||||
// SetAuthenticationValues is a method of the interface ServicePrincipalSecret.
|
||||
|
|
@ -652,94 +665,173 @@ func NewServicePrincipalTokenFromAuthorizationCode(oauthConfig OAuthConfig, clie
|
|||
)
|
||||
}
|
||||
|
||||
type msiType int
|
||||
|
||||
const (
|
||||
msiTypeUnavailable msiType = iota
|
||||
msiTypeAppServiceV20170901
|
||||
msiTypeCloudShell
|
||||
msiTypeIMDS
|
||||
)
|
||||
|
||||
func (m msiType) String() string {
|
||||
switch m {
|
||||
case msiTypeUnavailable:
|
||||
return "unavailable"
|
||||
case msiTypeAppServiceV20170901:
|
||||
return "AppServiceV20170901"
|
||||
case msiTypeCloudShell:
|
||||
return "CloudShell"
|
||||
case msiTypeIMDS:
|
||||
return "IMDS"
|
||||
default:
|
||||
return fmt.Sprintf("unhandled MSI type %d", m)
|
||||
}
|
||||
}
|
||||
|
||||
// returns the MSI type and endpoint, or an error
|
||||
func getMSIType() (msiType, string, error) {
|
||||
if endpointEnvVar := os.Getenv(msiEndpointEnv); endpointEnvVar != "" {
|
||||
// if the env var MSI_ENDPOINT is set
|
||||
if secretEnvVar := os.Getenv(msiSecretEnv); secretEnvVar != "" {
|
||||
// if BOTH the env vars MSI_ENDPOINT and MSI_SECRET are set the msiType is AppService
|
||||
return msiTypeAppServiceV20170901, endpointEnvVar, nil
|
||||
}
|
||||
// if ONLY the env var MSI_ENDPOINT is set the msiType is CloudShell
|
||||
return msiTypeCloudShell, endpointEnvVar, nil
|
||||
} else if msiAvailableHook(context.Background(), sender()) {
|
||||
// if MSI_ENDPOINT is NOT set AND the IMDS endpoint is available the msiType is IMDS. This will timeout after 500 milliseconds
|
||||
return msiTypeIMDS, msiEndpoint, nil
|
||||
} else {
|
||||
// if MSI_ENDPOINT is NOT set and IMDS endpoint is not available Managed Identity is not available
|
||||
return msiTypeUnavailable, "", errors.New("MSI not available")
|
||||
}
|
||||
}
|
||||
|
||||
// GetMSIVMEndpoint gets the MSI endpoint on Virtual Machines.
|
||||
// NOTE: this always returns the IMDS endpoint, it does not work for app services or cloud shell.
|
||||
// Deprecated: NewServicePrincipalTokenFromMSI() and variants will automatically detect the endpoint.
|
||||
func GetMSIVMEndpoint() (string, error) {
|
||||
return msiEndpoint, nil
|
||||
}
|
||||
|
||||
// NOTE: this only indicates if the ASE environment credentials have been set
|
||||
// which does not necessarily mean that the caller is authenticating via ASE!
|
||||
func isAppService() bool {
|
||||
_, asMSIEndpointEnvExists := os.LookupEnv(asMSIEndpointEnv)
|
||||
_, asMSISecretEnvExists := os.LookupEnv(asMSISecretEnv)
|
||||
|
||||
return asMSIEndpointEnvExists && asMSISecretEnvExists
|
||||
}
|
||||
|
||||
// GetMSIAppServiceEndpoint get the MSI endpoint for App Service and Functions
|
||||
// GetMSIAppServiceEndpoint get the MSI endpoint for App Service and Functions.
|
||||
// It will return an error when not running in an app service/functions environment.
|
||||
// Deprecated: NewServicePrincipalTokenFromMSI() and variants will automatically detect the endpoint.
|
||||
func GetMSIAppServiceEndpoint() (string, error) {
|
||||
asMSIEndpoint, asMSIEndpointEnvExists := os.LookupEnv(asMSIEndpointEnv)
|
||||
|
||||
if asMSIEndpointEnvExists {
|
||||
return asMSIEndpoint, nil
|
||||
msiType, endpoint, err := getMSIType()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
switch msiType {
|
||||
case msiTypeAppServiceV20170901:
|
||||
return endpoint, nil
|
||||
default:
|
||||
return "", fmt.Errorf("%s is not app service environment", msiType)
|
||||
}
|
||||
return "", errors.New("MSI endpoint not found")
|
||||
}
|
||||
|
||||
// GetMSIEndpoint get the appropriate MSI endpoint depending on the runtime environment
|
||||
// Deprecated: NewServicePrincipalTokenFromMSI() and variants will automatically detect the endpoint.
|
||||
func GetMSIEndpoint() (string, error) {
|
||||
if isAppService() {
|
||||
return GetMSIAppServiceEndpoint()
|
||||
}
|
||||
return GetMSIVMEndpoint()
|
||||
_, endpoint, err := getMSIType()
|
||||
return endpoint, err
|
||||
}
|
||||
|
||||
// NewServicePrincipalTokenFromMSI creates a ServicePrincipalToken via the MSI VM Extension.
|
||||
// It will use the system assigned identity when creating the token.
|
||||
// msiEndpoint - empty string, or pass a non-empty string to override the default value.
|
||||
// Deprecated: use NewServicePrincipalTokenFromManagedIdentity() instead.
|
||||
func NewServicePrincipalTokenFromMSI(msiEndpoint, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
return newServicePrincipalTokenFromMSI(msiEndpoint, resource, nil, nil, callbacks...)
|
||||
return newServicePrincipalTokenFromMSI(msiEndpoint, resource, "", "", callbacks...)
|
||||
}
|
||||
|
||||
// NewServicePrincipalTokenFromMSIWithUserAssignedID creates a ServicePrincipalToken via the MSI VM Extension.
|
||||
// It will use the clientID of specified user assigned identity when creating the token.
|
||||
// msiEndpoint - empty string, or pass a non-empty string to override the default value.
|
||||
// Deprecated: use NewServicePrincipalTokenFromManagedIdentity() instead.
|
||||
func NewServicePrincipalTokenFromMSIWithUserAssignedID(msiEndpoint, resource string, userAssignedID string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
return newServicePrincipalTokenFromMSI(msiEndpoint, resource, &userAssignedID, nil, callbacks...)
|
||||
if err := validateStringParam(userAssignedID, "userAssignedID"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newServicePrincipalTokenFromMSI(msiEndpoint, resource, userAssignedID, "", callbacks...)
|
||||
}
|
||||
|
||||
// NewServicePrincipalTokenFromMSIWithIdentityResourceID creates a ServicePrincipalToken via the MSI VM Extension.
|
||||
// It will use the azure resource id of user assigned identity when creating the token.
|
||||
// msiEndpoint - empty string, or pass a non-empty string to override the default value.
|
||||
// Deprecated: use NewServicePrincipalTokenFromManagedIdentity() instead.
|
||||
func NewServicePrincipalTokenFromMSIWithIdentityResourceID(msiEndpoint, resource string, identityResourceID string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
return newServicePrincipalTokenFromMSI(msiEndpoint, resource, nil, &identityResourceID, callbacks...)
|
||||
}
|
||||
|
||||
func newServicePrincipalTokenFromMSI(msiEndpoint, resource string, userAssignedID *string, identityResourceID *string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
if err := validateStringParam(msiEndpoint, "msiEndpoint"); err != nil {
|
||||
if err := validateStringParam(identityResourceID, "identityResourceID"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newServicePrincipalTokenFromMSI(msiEndpoint, resource, "", identityResourceID, callbacks...)
|
||||
}
|
||||
|
||||
// ManagedIdentityOptions contains optional values for configuring managed identity authentication.
|
||||
type ManagedIdentityOptions struct {
|
||||
// ClientID is the user-assigned identity to use during authentication.
|
||||
// It is mutually exclusive with IdentityResourceID.
|
||||
ClientID string
|
||||
|
||||
// IdentityResourceID is the resource ID of the user-assigned identity to use during authentication.
|
||||
// It is mutually exclusive with ClientID.
|
||||
IdentityResourceID string
|
||||
}
|
||||
|
||||
// NewServicePrincipalTokenFromManagedIdentity creates a ServicePrincipalToken using a managed identity.
|
||||
// It supports the following managed identity environments.
|
||||
// - App Service Environment (API version 2017-09-01 only)
|
||||
// - Cloud shell
|
||||
// - IMDS with a system or user assigned identity
|
||||
func NewServicePrincipalTokenFromManagedIdentity(resource string, options *ManagedIdentityOptions, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
if options == nil {
|
||||
options = &ManagedIdentityOptions{}
|
||||
}
|
||||
return newServicePrincipalTokenFromMSI("", resource, options.ClientID, options.IdentityResourceID, callbacks...)
|
||||
}
|
||||
|
||||
func newServicePrincipalTokenFromMSI(msiEndpoint, resource, userAssignedID, identityResourceID string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
if err := validateStringParam(resource, "resource"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if userAssignedID != nil {
|
||||
if err := validateStringParam(*userAssignedID, "userAssignedID"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if userAssignedID != "" && identityResourceID != "" {
|
||||
return nil, errors.New("cannot specify userAssignedID and identityResourceID")
|
||||
}
|
||||
if identityResourceID != nil {
|
||||
if err := validateStringParam(*identityResourceID, "identityResourceID"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
msiType, endpoint, err := getMSIType()
|
||||
if err != nil {
|
||||
logger.Instance.Writef(logger.LogError, "Error determining managed identity environment: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
// We set the oauth config token endpoint to be MSI's endpoint
|
||||
msiEndpointURL, err := url.Parse(msiEndpoint)
|
||||
logger.Instance.Writef(logger.LogInfo, "Managed identity environment is %s, endpoint is %s", msiType, endpoint)
|
||||
if msiEndpoint != "" {
|
||||
endpoint = msiEndpoint
|
||||
logger.Instance.Writef(logger.LogInfo, "Managed identity custom endpoint is %s", endpoint)
|
||||
}
|
||||
msiEndpointURL, err := url.Parse(endpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
v := url.Values{}
|
||||
v.Set("resource", resource)
|
||||
// App Service MSI currently only supports token API version 2017-09-01
|
||||
if isAppService() {
|
||||
v.Set("api-version", appServiceAPIVersion)
|
||||
} else {
|
||||
v.Set("api-version", msiAPIVersion)
|
||||
// cloud shell sends its data in the request body
|
||||
if msiType != msiTypeCloudShell {
|
||||
v := url.Values{}
|
||||
v.Set("resource", resource)
|
||||
clientIDParam := "client_id"
|
||||
switch msiType {
|
||||
case msiTypeAppServiceV20170901:
|
||||
clientIDParam = "clientid"
|
||||
v.Set("api-version", appServiceAPIVersion2017)
|
||||
break
|
||||
case msiTypeIMDS:
|
||||
v.Set("api-version", msiAPIVersion)
|
||||
}
|
||||
if userAssignedID != "" {
|
||||
v.Set(clientIDParam, userAssignedID)
|
||||
} else if identityResourceID != "" {
|
||||
v.Set("mi_res_id", identityResourceID)
|
||||
}
|
||||
msiEndpointURL.RawQuery = v.Encode()
|
||||
}
|
||||
if userAssignedID != nil {
|
||||
v.Set("client_id", *userAssignedID)
|
||||
}
|
||||
if identityResourceID != nil {
|
||||
v.Set("mi_res_id", *identityResourceID)
|
||||
}
|
||||
msiEndpointURL.RawQuery = v.Encode()
|
||||
|
||||
spt := &ServicePrincipalToken{
|
||||
inner: servicePrincipalToken{
|
||||
|
|
@ -747,10 +839,14 @@ func newServicePrincipalTokenFromMSI(msiEndpoint, resource string, userAssignedI
|
|||
OauthConfig: OAuthConfig{
|
||||
TokenEndpoint: *msiEndpointURL,
|
||||
},
|
||||
Secret: &ServicePrincipalMSISecret{},
|
||||
Secret: &ServicePrincipalMSISecret{
|
||||
msiType: msiType,
|
||||
clientResourceID: identityResourceID,
|
||||
},
|
||||
Resource: resource,
|
||||
AutoRefresh: true,
|
||||
RefreshWithin: defaultRefresh,
|
||||
ClientID: userAssignedID,
|
||||
},
|
||||
refreshLock: &sync.RWMutex{},
|
||||
sender: sender(),
|
||||
|
|
@ -758,10 +854,6 @@ func newServicePrincipalTokenFromMSI(msiEndpoint, resource string, userAssignedI
|
|||
MaxMSIRefreshAttempts: defaultMaxMSIRefreshAttempts,
|
||||
}
|
||||
|
||||
if userAssignedID != nil {
|
||||
spt.inner.ClientID = *userAssignedID
|
||||
}
|
||||
|
||||
return spt, nil
|
||||
}
|
||||
|
||||
|
|
@ -858,31 +950,6 @@ func (spt *ServicePrincipalToken) getGrantType() string {
|
|||
}
|
||||
}
|
||||
|
||||
func isIMDS(u url.URL) bool {
|
||||
return isMSIEndpoint(u) == true || isASEEndpoint(u) == true
|
||||
}
|
||||
|
||||
func isMSIEndpoint(endpoint url.URL) bool {
|
||||
msi, err := url.Parse(msiEndpoint)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return endpoint.Host == msi.Host && endpoint.Path == msi.Path
|
||||
}
|
||||
|
||||
func isASEEndpoint(endpoint url.URL) bool {
|
||||
aseEndpoint, err := GetMSIAppServiceEndpoint()
|
||||
if err != nil {
|
||||
// app service environment isn't enabled
|
||||
return false
|
||||
}
|
||||
ase, err := url.Parse(aseEndpoint)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return endpoint.Host == ase.Host && endpoint.Path == ase.Path
|
||||
}
|
||||
|
||||
func (spt *ServicePrincipalToken) refreshInternal(ctx context.Context, resource string) error {
|
||||
if spt.customRefreshFunc != nil {
|
||||
token, err := spt.customRefreshFunc(ctx, resource)
|
||||
|
|
@ -892,19 +959,45 @@ func (spt *ServicePrincipalToken) refreshInternal(ctx context.Context, resource
|
|||
spt.inner.Token = *token
|
||||
return spt.InvokeRefreshCallbacks(spt.inner.Token)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(http.MethodPost, spt.inner.OauthConfig.TokenEndpoint.String(), nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("adal: Failed to build the refresh request. Error = '%v'", err)
|
||||
}
|
||||
req.Header.Add("User-Agent", UserAgent())
|
||||
// Add header when runtime is on App Service or Functions
|
||||
if isASEEndpoint(spt.inner.OauthConfig.TokenEndpoint) {
|
||||
asMSISecret, _ := os.LookupEnv(asMSISecretEnv)
|
||||
req.Header.Add("Secret", asMSISecret)
|
||||
}
|
||||
req = req.WithContext(ctx)
|
||||
if !isIMDS(spt.inner.OauthConfig.TokenEndpoint) {
|
||||
var resp *http.Response
|
||||
authBodyFilter := func(b []byte) []byte {
|
||||
if logger.Level() != logger.LogAuth {
|
||||
return []byte("**REDACTED** authentication body")
|
||||
}
|
||||
return b
|
||||
}
|
||||
if msiSecret, ok := spt.inner.Secret.(*ServicePrincipalMSISecret); ok {
|
||||
switch msiSecret.msiType {
|
||||
case msiTypeAppServiceV20170901:
|
||||
req.Method = http.MethodGet
|
||||
req.Header.Set("secret", os.Getenv(msiSecretEnv))
|
||||
break
|
||||
case msiTypeCloudShell:
|
||||
req.Header.Set("Metadata", "true")
|
||||
data := url.Values{}
|
||||
data.Set("resource", spt.inner.Resource)
|
||||
if spt.inner.ClientID != "" {
|
||||
data.Set("client_id", spt.inner.ClientID)
|
||||
} else if msiSecret.clientResourceID != "" {
|
||||
data.Set("msi_res_id", msiSecret.clientResourceID)
|
||||
}
|
||||
req.Body = ioutil.NopCloser(strings.NewReader(data.Encode()))
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
break
|
||||
case msiTypeIMDS:
|
||||
req.Method = http.MethodGet
|
||||
req.Header.Set("Metadata", "true")
|
||||
break
|
||||
}
|
||||
logger.Instance.WriteRequest(req, logger.Filter{Body: authBodyFilter})
|
||||
resp, err = retryForIMDS(spt.sender, req, spt.MaxMSIRefreshAttempts)
|
||||
} else {
|
||||
v := url.Values{}
|
||||
v.Set("client_id", spt.inner.ClientID)
|
||||
v.Set("resource", resource)
|
||||
|
|
@ -933,36 +1026,26 @@ func (spt *ServicePrincipalToken) refreshInternal(ctx context.Context, resource
|
|||
req.ContentLength = int64(len(s))
|
||||
req.Header.Set(contentType, mimeTypeFormPost)
|
||||
req.Body = body
|
||||
}
|
||||
|
||||
if _, ok := spt.inner.Secret.(*ServicePrincipalMSISecret); ok {
|
||||
req.Method = http.MethodGet
|
||||
req.Header.Set(metadataHeader, "true")
|
||||
}
|
||||
|
||||
var resp *http.Response
|
||||
if isMSIEndpoint(spt.inner.OauthConfig.TokenEndpoint) && !MSIAvailable(ctx, spt.sender) {
|
||||
// return a TokenRefreshError here so that we don't keep retrying
|
||||
return newTokenRefreshError("the MSI endpoint is not available", nil)
|
||||
}
|
||||
if isIMDS(spt.inner.OauthConfig.TokenEndpoint) {
|
||||
resp, err = retryForIMDS(spt.sender, req, spt.MaxMSIRefreshAttempts)
|
||||
} else {
|
||||
logger.Instance.WriteRequest(req, logger.Filter{Body: authBodyFilter})
|
||||
resp, err = spt.sender.Do(req)
|
||||
}
|
||||
|
||||
// don't return a TokenRefreshError here; this will allow retry logic to apply
|
||||
if err != nil {
|
||||
// don't return a TokenRefreshError here; this will allow retry logic to apply
|
||||
return fmt.Errorf("adal: Failed to execute the refresh request. Error = '%v'", err)
|
||||
} else if resp == nil {
|
||||
return fmt.Errorf("adal: received nil response and error")
|
||||
}
|
||||
|
||||
logger.Instance.WriteResponse(resp, logger.Filter{Body: authBodyFilter})
|
||||
defer resp.Body.Close()
|
||||
rb, err := ioutil.ReadAll(resp.Body)
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
if err != nil {
|
||||
return newTokenRefreshError(fmt.Sprintf("adal: Refresh request failed. Status Code = '%d'. Failed reading response body: %v", resp.StatusCode, err), resp)
|
||||
return newTokenRefreshError(fmt.Sprintf("adal: Refresh request failed. Status Code = '%d'. Failed reading response body: %v Endpoint %s", resp.StatusCode, err, req.URL.String()), resp)
|
||||
}
|
||||
return newTokenRefreshError(fmt.Sprintf("adal: Refresh request failed. Status Code = '%d'. Response body: %s", resp.StatusCode, string(rb)), resp)
|
||||
return newTokenRefreshError(fmt.Sprintf("adal: Refresh request failed. Status Code = '%d'. Response body: %s Endpoint %s", resp.StatusCode, string(rb), req.URL.String()), resp)
|
||||
}
|
||||
|
||||
// for the following error cases don't return a TokenRefreshError. the operation succeeded
|
||||
|
|
@ -975,15 +1058,60 @@ func (spt *ServicePrincipalToken) refreshInternal(ctx context.Context, resource
|
|||
if len(strings.Trim(string(rb), " ")) == 0 {
|
||||
return fmt.Errorf("adal: Empty service principal token received during refresh")
|
||||
}
|
||||
var token Token
|
||||
token := struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
|
||||
// AAD returns expires_in as a string, ADFS returns it as an int
|
||||
ExpiresIn json.Number `json:"expires_in"`
|
||||
// expires_on can be in two formats, a UTC time stamp or the number of seconds.
|
||||
ExpiresOn string `json:"expires_on"`
|
||||
NotBefore json.Number `json:"not_before"`
|
||||
|
||||
Resource string `json:"resource"`
|
||||
Type string `json:"token_type"`
|
||||
}{}
|
||||
// return a TokenRefreshError in the follow error cases as the token is in an unexpected format
|
||||
err = json.Unmarshal(rb, &token)
|
||||
if err != nil {
|
||||
return fmt.Errorf("adal: Failed to unmarshal the service principal token during refresh. Error = '%v' JSON = '%s'", err, string(rb))
|
||||
return newTokenRefreshError(fmt.Sprintf("adal: Failed to unmarshal the service principal token during refresh. Error = '%v' JSON = '%s'", err, string(rb)), resp)
|
||||
}
|
||||
expiresOn := json.Number("")
|
||||
// ADFS doesn't include the expires_on field
|
||||
if token.ExpiresOn != "" {
|
||||
if expiresOn, err = parseExpiresOn(token.ExpiresOn); err != nil {
|
||||
return newTokenRefreshError(fmt.Sprintf("adal: failed to parse expires_on: %v value '%s'", err, token.ExpiresOn), resp)
|
||||
}
|
||||
}
|
||||
spt.inner.Token.AccessToken = token.AccessToken
|
||||
spt.inner.Token.RefreshToken = token.RefreshToken
|
||||
spt.inner.Token.ExpiresIn = token.ExpiresIn
|
||||
spt.inner.Token.ExpiresOn = expiresOn
|
||||
spt.inner.Token.NotBefore = token.NotBefore
|
||||
spt.inner.Token.Resource = token.Resource
|
||||
spt.inner.Token.Type = token.Type
|
||||
|
||||
spt.inner.Token = token
|
||||
return spt.InvokeRefreshCallbacks(spt.inner.Token)
|
||||
}
|
||||
|
||||
return spt.InvokeRefreshCallbacks(token)
|
||||
// converts expires_on to the number of seconds
|
||||
func parseExpiresOn(s string) (json.Number, error) {
|
||||
// convert the expiration date to the number of seconds from now
|
||||
timeToDuration := func(t time.Time) json.Number {
|
||||
dur := t.Sub(time.Now().UTC())
|
||||
return json.Number(strconv.FormatInt(int64(dur.Round(time.Second).Seconds()), 10))
|
||||
}
|
||||
if _, err := strconv.ParseInt(s, 10, 64); err == nil {
|
||||
// this is the number of seconds case, no conversion required
|
||||
return json.Number(s), nil
|
||||
} else if eo, err := time.Parse(expiresOnDateFormatPM, s); err == nil {
|
||||
return timeToDuration(eo), nil
|
||||
} else if eo, err := time.Parse(expiresOnDateFormat, s); err == nil {
|
||||
return timeToDuration(eo), nil
|
||||
} else {
|
||||
// unknown format
|
||||
return json.Number(""), err
|
||||
}
|
||||
}
|
||||
|
||||
// retry logic specific to retrieving a token from the IMDS endpoint
|
||||
|
|
@ -1114,46 +1242,6 @@ func (mt *MultiTenantServicePrincipalToken) AuxiliaryOAuthTokens() []string {
|
|||
return tokens
|
||||
}
|
||||
|
||||
// EnsureFreshWithContext will refresh the token if it will expire within the refresh window (as set by
|
||||
// RefreshWithin) and autoRefresh flag is on. This method is safe for concurrent use.
|
||||
func (mt *MultiTenantServicePrincipalToken) EnsureFreshWithContext(ctx context.Context) error {
|
||||
if err := mt.PrimaryToken.EnsureFreshWithContext(ctx); err != nil {
|
||||
return fmt.Errorf("failed to refresh primary token: %v", err)
|
||||
}
|
||||
for _, aux := range mt.AuxiliaryTokens {
|
||||
if err := aux.EnsureFreshWithContext(ctx); err != nil {
|
||||
return fmt.Errorf("failed to refresh auxiliary token: %v", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RefreshWithContext obtains a fresh token for the Service Principal.
|
||||
func (mt *MultiTenantServicePrincipalToken) RefreshWithContext(ctx context.Context) error {
|
||||
if err := mt.PrimaryToken.RefreshWithContext(ctx); err != nil {
|
||||
return fmt.Errorf("failed to refresh primary token: %v", err)
|
||||
}
|
||||
for _, aux := range mt.AuxiliaryTokens {
|
||||
if err := aux.RefreshWithContext(ctx); err != nil {
|
||||
return fmt.Errorf("failed to refresh auxiliary token: %v", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RefreshExchangeWithContext refreshes the token, but for a different resource.
|
||||
func (mt *MultiTenantServicePrincipalToken) RefreshExchangeWithContext(ctx context.Context, resource string) error {
|
||||
if err := mt.PrimaryToken.RefreshExchangeWithContext(ctx, resource); err != nil {
|
||||
return fmt.Errorf("failed to refresh primary token: %v", err)
|
||||
}
|
||||
for _, aux := range mt.AuxiliaryTokens {
|
||||
if err := aux.RefreshExchangeWithContext(ctx, resource); err != nil {
|
||||
return fmt.Errorf("failed to refresh auxiliary token: %v", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewMultiTenantServicePrincipalToken creates a new MultiTenantServicePrincipalToken with the specified credentials and resource.
|
||||
func NewMultiTenantServicePrincipalToken(multiTenantCfg MultiTenantOAuthConfig, clientID string, secret string, resource string) (*MultiTenantServicePrincipalToken, error) {
|
||||
if err := validateStringParam(clientID, "clientID"); err != nil {
|
||||
|
|
@ -1184,16 +1272,65 @@ func NewMultiTenantServicePrincipalToken(multiTenantCfg MultiTenantOAuthConfig,
|
|||
return &m, nil
|
||||
}
|
||||
|
||||
// NewMultiTenantServicePrincipalTokenFromCertificate creates a new MultiTenantServicePrincipalToken with the specified certificate credentials and resource.
|
||||
func NewMultiTenantServicePrincipalTokenFromCertificate(multiTenantCfg MultiTenantOAuthConfig, clientID string, certificate *x509.Certificate, privateKey *rsa.PrivateKey, resource string) (*MultiTenantServicePrincipalToken, error) {
|
||||
if err := validateStringParam(clientID, "clientID"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(resource, "resource"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if certificate == nil {
|
||||
return nil, fmt.Errorf("parameter 'certificate' cannot be nil")
|
||||
}
|
||||
if privateKey == nil {
|
||||
return nil, fmt.Errorf("parameter 'privateKey' cannot be nil")
|
||||
}
|
||||
auxTenants := multiTenantCfg.AuxiliaryTenants()
|
||||
m := MultiTenantServicePrincipalToken{
|
||||
AuxiliaryTokens: make([]*ServicePrincipalToken, len(auxTenants)),
|
||||
}
|
||||
primary, err := NewServicePrincipalTokenWithSecret(
|
||||
*multiTenantCfg.PrimaryTenant(),
|
||||
clientID,
|
||||
resource,
|
||||
&ServicePrincipalCertificateSecret{
|
||||
PrivateKey: privateKey,
|
||||
Certificate: certificate,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create SPT for primary tenant: %v", err)
|
||||
}
|
||||
m.PrimaryToken = primary
|
||||
for i := range auxTenants {
|
||||
aux, err := NewServicePrincipalTokenWithSecret(
|
||||
*auxTenants[i],
|
||||
clientID,
|
||||
resource,
|
||||
&ServicePrincipalCertificateSecret{
|
||||
PrivateKey: privateKey,
|
||||
Certificate: certificate,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create SPT for auxiliary tenant: %v", err)
|
||||
}
|
||||
m.AuxiliaryTokens[i] = aux
|
||||
}
|
||||
return &m, nil
|
||||
}
|
||||
|
||||
// MSIAvailable returns true if the MSI endpoint is available for authentication.
|
||||
func MSIAvailable(ctx context.Context, sender Sender) bool {
|
||||
// this cannot fail, the return sig is due to legacy reasons
|
||||
msiEndpoint, _ := GetMSIVMEndpoint()
|
||||
tempCtx, cancel := context.WithTimeout(ctx, 500*time.Millisecond)
|
||||
defer cancel()
|
||||
req, _ := http.NewRequestWithContext(tempCtx, http.MethodGet, msiEndpoint, nil)
|
||||
q := req.URL.Query()
|
||||
q.Add("api-version", msiAPIVersion)
|
||||
req.URL.RawQuery = q.Encode()
|
||||
_, err := sender.Do(req)
|
||||
resp, err := getMSIEndpoint(ctx, sender)
|
||||
if err == nil {
|
||||
resp.Body.Close()
|
||||
}
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// used for testing purposes
|
||||
var msiAvailableHook = func(ctx context.Context, sender Sender) bool {
|
||||
return MSIAvailable(ctx, sender)
|
||||
}
|
||||
|
|
|
|||
75
vendor/github.com/Azure/go-autorest/autorest/adal/token_1.13.go
generated
vendored
Normal file
75
vendor/github.com/Azure/go-autorest/autorest/adal/token_1.13.go
generated
vendored
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
// +build go1.13
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package adal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
func getMSIEndpoint(ctx context.Context, sender Sender) (*http.Response, error) {
|
||||
tempCtx, cancel := context.WithTimeout(ctx, 500*time.Millisecond)
|
||||
defer cancel()
|
||||
// http.NewRequestWithContext() was added in Go 1.13
|
||||
req, _ := http.NewRequestWithContext(tempCtx, http.MethodGet, msiEndpoint, nil)
|
||||
q := req.URL.Query()
|
||||
q.Add("api-version", msiAPIVersion)
|
||||
req.URL.RawQuery = q.Encode()
|
||||
return sender.Do(req)
|
||||
}
|
||||
|
||||
// EnsureFreshWithContext will refresh the token if it will expire within the refresh window (as set by
|
||||
// RefreshWithin) and autoRefresh flag is on. This method is safe for concurrent use.
|
||||
func (mt *MultiTenantServicePrincipalToken) EnsureFreshWithContext(ctx context.Context) error {
|
||||
if err := mt.PrimaryToken.EnsureFreshWithContext(ctx); err != nil {
|
||||
return fmt.Errorf("failed to refresh primary token: %w", err)
|
||||
}
|
||||
for _, aux := range mt.AuxiliaryTokens {
|
||||
if err := aux.EnsureFreshWithContext(ctx); err != nil {
|
||||
return fmt.Errorf("failed to refresh auxiliary token: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RefreshWithContext obtains a fresh token for the Service Principal.
|
||||
func (mt *MultiTenantServicePrincipalToken) RefreshWithContext(ctx context.Context) error {
|
||||
if err := mt.PrimaryToken.RefreshWithContext(ctx); err != nil {
|
||||
return fmt.Errorf("failed to refresh primary token: %w", err)
|
||||
}
|
||||
for _, aux := range mt.AuxiliaryTokens {
|
||||
if err := aux.RefreshWithContext(ctx); err != nil {
|
||||
return fmt.Errorf("failed to refresh auxiliary token: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RefreshExchangeWithContext refreshes the token, but for a different resource.
|
||||
func (mt *MultiTenantServicePrincipalToken) RefreshExchangeWithContext(ctx context.Context, resource string) error {
|
||||
if err := mt.PrimaryToken.RefreshExchangeWithContext(ctx, resource); err != nil {
|
||||
return fmt.Errorf("failed to refresh primary token: %w", err)
|
||||
}
|
||||
for _, aux := range mt.AuxiliaryTokens {
|
||||
if err := aux.RefreshExchangeWithContext(ctx, resource); err != nil {
|
||||
return fmt.Errorf("failed to refresh auxiliary token: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
74
vendor/github.com/Azure/go-autorest/autorest/adal/token_legacy.go
generated
vendored
Normal file
74
vendor/github.com/Azure/go-autorest/autorest/adal/token_legacy.go
generated
vendored
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
// +build !go1.13
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package adal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
func getMSIEndpoint(ctx context.Context, sender Sender) (*http.Response, error) {
|
||||
tempCtx, cancel := context.WithTimeout(ctx, 500*time.Millisecond)
|
||||
defer cancel()
|
||||
req, _ := http.NewRequest(http.MethodGet, msiEndpoint, nil)
|
||||
req = req.WithContext(tempCtx)
|
||||
q := req.URL.Query()
|
||||
q.Add("api-version", msiAPIVersion)
|
||||
req.URL.RawQuery = q.Encode()
|
||||
return sender.Do(req)
|
||||
}
|
||||
|
||||
// EnsureFreshWithContext will refresh the token if it will expire within the refresh window (as set by
|
||||
// RefreshWithin) and autoRefresh flag is on. This method is safe for concurrent use.
|
||||
func (mt *MultiTenantServicePrincipalToken) EnsureFreshWithContext(ctx context.Context) error {
|
||||
if err := mt.PrimaryToken.EnsureFreshWithContext(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, aux := range mt.AuxiliaryTokens {
|
||||
if err := aux.EnsureFreshWithContext(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RefreshWithContext obtains a fresh token for the Service Principal.
|
||||
func (mt *MultiTenantServicePrincipalToken) RefreshWithContext(ctx context.Context) error {
|
||||
if err := mt.PrimaryToken.RefreshWithContext(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, aux := range mt.AuxiliaryTokens {
|
||||
if err := aux.RefreshWithContext(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RefreshExchangeWithContext refreshes the token, but for a different resource.
|
||||
func (mt *MultiTenantServicePrincipalToken) RefreshExchangeWithContext(ctx context.Context, resource string) error {
|
||||
if err := mt.PrimaryToken.RefreshExchangeWithContext(ctx, resource); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, aux := range mt.AuxiliaryTokens {
|
||||
if err := aux.RefreshExchangeWithContext(ctx, resource); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
24
vendor/github.com/Azure/go-autorest/autorest/authorization.go
generated
vendored
24
vendor/github.com/Azure/go-autorest/autorest/authorization.go
generated
vendored
|
|
@ -138,6 +138,11 @@ func (ba *BearerAuthorizer) WithAuthorization() PrepareDecorator {
|
|||
}
|
||||
}
|
||||
|
||||
// TokenProvider returns OAuthTokenProvider so that it can be used for authorization outside the REST.
|
||||
func (ba *BearerAuthorizer) TokenProvider() adal.OAuthTokenProvider {
|
||||
return ba.tokenProvider
|
||||
}
|
||||
|
||||
// BearerAuthorizerCallbackFunc is the authentication callback signature.
|
||||
type BearerAuthorizerCallbackFunc func(tenantID, resource string) (*BearerAuthorizer, error)
|
||||
|
||||
|
|
@ -294,18 +299,24 @@ type MultiTenantServicePrincipalTokenAuthorizer interface {
|
|||
|
||||
// NewMultiTenantServicePrincipalTokenAuthorizer crates a BearerAuthorizer using the given token provider
|
||||
func NewMultiTenantServicePrincipalTokenAuthorizer(tp adal.MultitenantOAuthTokenProvider) MultiTenantServicePrincipalTokenAuthorizer {
|
||||
return &multiTenantSPTAuthorizer{tp: tp}
|
||||
return NewMultiTenantBearerAuthorizer(tp)
|
||||
}
|
||||
|
||||
type multiTenantSPTAuthorizer struct {
|
||||
// MultiTenantBearerAuthorizer implements bearer authorization across multiple tenants.
|
||||
type MultiTenantBearerAuthorizer struct {
|
||||
tp adal.MultitenantOAuthTokenProvider
|
||||
}
|
||||
|
||||
// NewMultiTenantBearerAuthorizer creates a MultiTenantBearerAuthorizer using the given token provider.
|
||||
func NewMultiTenantBearerAuthorizer(tp adal.MultitenantOAuthTokenProvider) *MultiTenantBearerAuthorizer {
|
||||
return &MultiTenantBearerAuthorizer{tp: tp}
|
||||
}
|
||||
|
||||
// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header using the
|
||||
// primary token along with the auxiliary authorization header using the auxiliary tokens.
|
||||
//
|
||||
// By default, the token will be automatically refreshed through the Refresher interface.
|
||||
func (mt multiTenantSPTAuthorizer) WithAuthorization() PrepareDecorator {
|
||||
func (mt *MultiTenantBearerAuthorizer) WithAuthorization() PrepareDecorator {
|
||||
return func(p Preparer) Preparer {
|
||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
||||
r, err := p.Prepare(r)
|
||||
|
|
@ -331,7 +342,12 @@ func (mt multiTenantSPTAuthorizer) WithAuthorization() PrepareDecorator {
|
|||
for i := range auxTokens {
|
||||
auxTokens[i] = fmt.Sprintf("Bearer %s", auxTokens[i])
|
||||
}
|
||||
return Prepare(r, WithHeader(headerAuxAuthorization, strings.Join(auxTokens, "; ")))
|
||||
return Prepare(r, WithHeader(headerAuxAuthorization, strings.Join(auxTokens, ", ")))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TokenProvider returns the underlying MultitenantOAuthTokenProvider for this authorizer.
|
||||
func (mt *MultiTenantBearerAuthorizer) TokenProvider() adal.MultitenantOAuthTokenProvider {
|
||||
return mt.tp
|
||||
}
|
||||
|
|
|
|||
7
vendor/github.com/Azure/go-autorest/autorest/authorization_sas.go
generated
vendored
7
vendor/github.com/Azure/go-autorest/autorest/authorization_sas.go
generated
vendored
|
|
@ -54,13 +54,12 @@ func (sas *SASTokenAuthorizer) WithAuthorization() PrepareDecorator {
|
|||
return r, err
|
||||
}
|
||||
|
||||
if r.URL.RawQuery != "" {
|
||||
r.URL.RawQuery = fmt.Sprintf("%s&%s", r.URL.RawQuery, sas.sasToken)
|
||||
} else {
|
||||
if r.URL.RawQuery == "" {
|
||||
r.URL.RawQuery = sas.sasToken
|
||||
} else if !strings.Contains(r.URL.RawQuery, sas.sasToken) {
|
||||
r.URL.RawQuery = fmt.Sprintf("%s&%s", r.URL.RawQuery, sas.sasToken)
|
||||
}
|
||||
|
||||
r.RequestURI = r.URL.String()
|
||||
return Prepare(r)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
3
vendor/github.com/Azure/go-autorest/autorest/authorization_storage.go
generated
vendored
3
vendor/github.com/Azure/go-autorest/autorest/authorization_storage.go
generated
vendored
|
|
@ -152,6 +152,9 @@ func buildCanonicalizedResource(accountName, uri string, keyType SharedKeyType)
|
|||
// the resource's URI should be encoded exactly as it is in the URI.
|
||||
// -- https://msdn.microsoft.com/en-gb/library/azure/dd179428.aspx
|
||||
cr.WriteString(u.EscapedPath())
|
||||
} else {
|
||||
// a slash is required to indicate the root path
|
||||
cr.WriteString("/")
|
||||
}
|
||||
|
||||
params, err := url.ParseQuery(u.RawQuery)
|
||||
|
|
|
|||
69
vendor/github.com/Azure/go-autorest/autorest/azure/async.go
generated
vendored
69
vendor/github.com/Azure/go-autorest/autorest/azure/async.go
generated
vendored
|
|
@ -26,6 +26,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/logger"
|
||||
"github.com/Azure/go-autorest/tracing"
|
||||
)
|
||||
|
||||
|
|
@ -42,6 +43,52 @@ const (
|
|||
|
||||
var pollingCodes = [...]int{http.StatusNoContent, http.StatusAccepted, http.StatusCreated, http.StatusOK}
|
||||
|
||||
// FutureAPI contains the set of methods on the Future type.
|
||||
type FutureAPI interface {
|
||||
// Response returns the last HTTP response.
|
||||
Response() *http.Response
|
||||
|
||||
// Status returns the last status message of the operation.
|
||||
Status() string
|
||||
|
||||
// PollingMethod returns the method used to monitor the status of the asynchronous operation.
|
||||
PollingMethod() PollingMethodType
|
||||
|
||||
// DoneWithContext queries the service to see if the operation has completed.
|
||||
DoneWithContext(context.Context, autorest.Sender) (bool, error)
|
||||
|
||||
// GetPollingDelay returns a duration the application should wait before checking
|
||||
// the status of the asynchronous request and true; this value is returned from
|
||||
// the service via the Retry-After response header. If the header wasn't returned
|
||||
// then the function returns the zero-value time.Duration and false.
|
||||
GetPollingDelay() (time.Duration, bool)
|
||||
|
||||
// WaitForCompletionRef will return when one of the following conditions is met: the long
|
||||
// running operation has completed, the provided context is cancelled, or the client's
|
||||
// polling duration has been exceeded. It will retry failed polling attempts based on
|
||||
// the retry value defined in the client up to the maximum retry attempts.
|
||||
// If no deadline is specified in the context then the client.PollingDuration will be
|
||||
// used to determine if a default deadline should be used.
|
||||
// If PollingDuration is greater than zero the value will be used as the context's timeout.
|
||||
// If PollingDuration is zero then no default deadline will be used.
|
||||
WaitForCompletionRef(context.Context, autorest.Client) error
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
MarshalJSON() ([]byte, error)
|
||||
|
||||
// MarshalJSON implements the json.Unmarshaler interface.
|
||||
UnmarshalJSON([]byte) error
|
||||
|
||||
// PollingURL returns the URL used for retrieving the status of the long-running operation.
|
||||
PollingURL() string
|
||||
|
||||
// GetResult should be called once polling has completed successfully.
|
||||
// It makes the final GET call to retrieve the resultant payload.
|
||||
GetResult(autorest.Sender) (*http.Response, error)
|
||||
}
|
||||
|
||||
var _ FutureAPI = (*Future)(nil)
|
||||
|
||||
// Future provides a mechanism to access the status and results of an asynchronous request.
|
||||
// Since futures are stateful they should be passed by value to avoid race conditions.
|
||||
type Future struct {
|
||||
|
|
@ -167,7 +214,14 @@ func (f *Future) WaitForCompletionRef(ctx context.Context, client autorest.Clien
|
|||
cancelCtx, cancel = context.WithTimeout(ctx, d)
|
||||
defer cancel()
|
||||
}
|
||||
|
||||
// if the initial response has a Retry-After, sleep for the specified amount of time before starting to poll
|
||||
if delay, ok := f.GetPollingDelay(); ok {
|
||||
logger.Instance.Writeln(logger.LogInfo, "WaitForCompletionRef: initial polling delay")
|
||||
if delayElapsed := autorest.DelayForBackoff(delay, 0, cancelCtx.Done()); !delayElapsed {
|
||||
err = cancelCtx.Err()
|
||||
return
|
||||
}
|
||||
}
|
||||
done, err := f.DoneWithContext(ctx, client)
|
||||
for attempts := 0; !done; done, err = f.DoneWithContext(ctx, client) {
|
||||
if attempts >= client.RetryAttempts {
|
||||
|
|
@ -182,12 +236,14 @@ func (f *Future) WaitForCompletionRef(ctx context.Context, client autorest.Clien
|
|||
var ok bool
|
||||
delay, ok = f.GetPollingDelay()
|
||||
if !ok {
|
||||
logger.Instance.Writeln(logger.LogInfo, "WaitForCompletionRef: Using client polling delay")
|
||||
delay = client.PollingDelay
|
||||
}
|
||||
} else {
|
||||
// there was an error polling for status so perform exponential
|
||||
// back-off based on the number of attempts using the client's retry
|
||||
// duration. update attempts after delayAttempt to avoid off-by-one.
|
||||
logger.Instance.Writef(logger.LogError, "WaitForCompletionRef: %s\n", err)
|
||||
delayAttempt = attempts
|
||||
delay = client.RetryDuration
|
||||
attempts++
|
||||
|
|
@ -407,12 +463,12 @@ func (pt *pollingTrackerBase) updateRawBody() error {
|
|||
if err != nil {
|
||||
return autorest.NewErrorWithError(err, "pollingTrackerBase", "updateRawBody", nil, "failed to read response body")
|
||||
}
|
||||
// put the body back so it's available to other callers
|
||||
pt.resp.Body = ioutil.NopCloser(bytes.NewReader(b))
|
||||
// observed in 204 responses over HTTP/2.0; the content length is -1 but body is empty
|
||||
if len(b) == 0 {
|
||||
return nil
|
||||
}
|
||||
// put the body back so it's available to other callers
|
||||
pt.resp.Body = ioutil.NopCloser(bytes.NewReader(b))
|
||||
if err = json.Unmarshal(b, &pt.rawBody); err != nil {
|
||||
return autorest.NewErrorWithError(err, "pollingTrackerBase", "updateRawBody", nil, "failed to unmarshal response body")
|
||||
}
|
||||
|
|
@ -460,7 +516,12 @@ func (pt *pollingTrackerBase) updateErrorFromResponse() {
|
|||
re := respErr{}
|
||||
defer pt.resp.Body.Close()
|
||||
var b []byte
|
||||
if b, err = ioutil.ReadAll(pt.resp.Body); err != nil || len(b) == 0 {
|
||||
if b, err = ioutil.ReadAll(pt.resp.Body); err != nil {
|
||||
goto Default
|
||||
}
|
||||
// put the body back so it's available to other callers
|
||||
pt.resp.Body = ioutil.NopCloser(bytes.NewReader(b))
|
||||
if len(b) == 0 {
|
||||
goto Default
|
||||
}
|
||||
if err = json.Unmarshal(b, &re); err != nil {
|
||||
|
|
|
|||
135
vendor/github.com/Azure/go-autorest/autorest/azure/azure.go
generated
vendored
135
vendor/github.com/Azure/go-autorest/autorest/azure/azure.go
generated
vendored
|
|
@ -37,6 +37,9 @@ const (
|
|||
// should be included in the response.
|
||||
HeaderReturnClientID = "x-ms-return-client-request-id"
|
||||
|
||||
// HeaderContentType is the type of the content in the HTTP response.
|
||||
HeaderContentType = "Content-Type"
|
||||
|
||||
// HeaderRequestID is the Azure extension header of the service generated request ID returned
|
||||
// in the response.
|
||||
HeaderRequestID = "x-ms-request-id"
|
||||
|
|
@ -89,54 +92,85 @@ func (se ServiceError) Error() string {
|
|||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface for the ServiceError type.
|
||||
func (se *ServiceError) UnmarshalJSON(b []byte) error {
|
||||
// per the OData v4 spec the details field must be an array of JSON objects.
|
||||
// unfortunately not all services adhear to the spec and just return a single
|
||||
// object instead of an array with one object. so we have to perform some
|
||||
// shenanigans to accommodate both cases.
|
||||
// http://docs.oasis-open.org/odata/odata-json-format/v4.0/os/odata-json-format-v4.0-os.html#_Toc372793091
|
||||
|
||||
type serviceError1 struct {
|
||||
type serviceErrorInternal struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Target *string `json:"target"`
|
||||
Details []map[string]interface{} `json:"details"`
|
||||
InnerError map[string]interface{} `json:"innererror"`
|
||||
AdditionalInfo []map[string]interface{} `json:"additionalInfo"`
|
||||
Target *string `json:"target,omitempty"`
|
||||
AdditionalInfo []map[string]interface{} `json:"additionalInfo,omitempty"`
|
||||
// not all services conform to the OData v4 spec.
|
||||
// the following fields are where we've seen discrepancies
|
||||
|
||||
// spec calls for []map[string]interface{} but have seen map[string]interface{}
|
||||
Details interface{} `json:"details,omitempty"`
|
||||
|
||||
// spec calls for map[string]interface{} but have seen []map[string]interface{} and string
|
||||
InnerError interface{} `json:"innererror,omitempty"`
|
||||
}
|
||||
|
||||
type serviceError2 struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Target *string `json:"target"`
|
||||
Details map[string]interface{} `json:"details"`
|
||||
InnerError map[string]interface{} `json:"innererror"`
|
||||
AdditionalInfo []map[string]interface{} `json:"additionalInfo"`
|
||||
sei := serviceErrorInternal{}
|
||||
if err := json.Unmarshal(b, &sei); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
se1 := serviceError1{}
|
||||
err := json.Unmarshal(b, &se1)
|
||||
if err == nil {
|
||||
se.populate(se1.Code, se1.Message, se1.Target, se1.Details, se1.InnerError, se1.AdditionalInfo)
|
||||
return nil
|
||||
// copy the fields we know to be correct
|
||||
se.AdditionalInfo = sei.AdditionalInfo
|
||||
se.Code = sei.Code
|
||||
se.Message = sei.Message
|
||||
se.Target = sei.Target
|
||||
|
||||
// converts an []interface{} to []map[string]interface{}
|
||||
arrayOfObjs := func(v interface{}) ([]map[string]interface{}, bool) {
|
||||
arrayOf, ok := v.([]interface{})
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
final := []map[string]interface{}{}
|
||||
for _, item := range arrayOf {
|
||||
as, ok := item.(map[string]interface{})
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
final = append(final, as)
|
||||
}
|
||||
return final, true
|
||||
}
|
||||
|
||||
se2 := serviceError2{}
|
||||
err = json.Unmarshal(b, &se2)
|
||||
if err == nil {
|
||||
se.populate(se2.Code, se2.Message, se2.Target, nil, se2.InnerError, se2.AdditionalInfo)
|
||||
se.Details = append(se.Details, se2.Details)
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
// convert the remaining fields, falling back to raw JSON if necessary
|
||||
|
||||
func (se *ServiceError) populate(code, message string, target *string, details []map[string]interface{}, inner map[string]interface{}, additional []map[string]interface{}) {
|
||||
se.Code = code
|
||||
se.Message = message
|
||||
se.Target = target
|
||||
se.Details = details
|
||||
se.InnerError = inner
|
||||
se.AdditionalInfo = additional
|
||||
if c, ok := arrayOfObjs(sei.Details); ok {
|
||||
se.Details = c
|
||||
} else if c, ok := sei.Details.(map[string]interface{}); ok {
|
||||
se.Details = []map[string]interface{}{c}
|
||||
} else if sei.Details != nil {
|
||||
// stuff into Details
|
||||
se.Details = []map[string]interface{}{
|
||||
{"raw": sei.Details},
|
||||
}
|
||||
}
|
||||
|
||||
if c, ok := sei.InnerError.(map[string]interface{}); ok {
|
||||
se.InnerError = c
|
||||
} else if c, ok := arrayOfObjs(sei.InnerError); ok {
|
||||
// if there's only one error extract it
|
||||
if len(c) == 1 {
|
||||
se.InnerError = c[0]
|
||||
} else {
|
||||
// multiple errors, stuff them into the value
|
||||
se.InnerError = map[string]interface{}{
|
||||
"multi": c,
|
||||
}
|
||||
}
|
||||
} else if c, ok := sei.InnerError.(string); ok {
|
||||
se.InnerError = map[string]interface{}{"error": c}
|
||||
} else if sei.InnerError != nil {
|
||||
// stuff into InnerError
|
||||
se.InnerError = map[string]interface{}{
|
||||
"raw": sei.InnerError,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RequestError describes an error response returned by Azure service.
|
||||
|
|
@ -171,8 +205,13 @@ type Resource struct {
|
|||
ResourceName string
|
||||
}
|
||||
|
||||
// String function returns a string in form of azureResourceID
|
||||
func (r Resource) String() string {
|
||||
return fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/%s/%s/%s", r.SubscriptionID, r.ResourceGroup, r.Provider, r.ResourceType, r.ResourceName)
|
||||
}
|
||||
|
||||
// ParseResourceID parses a resource ID into a ResourceDetails struct.
|
||||
// See https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-template-functions-resource#return-value-4.
|
||||
// See https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/template-functions-resource?tabs=json#resourceid.
|
||||
func ParseResourceID(resourceID string) (Resource, error) {
|
||||
|
||||
const resourceIDPatternText = `(?i)subscriptions/(.+)/resourceGroups/(.+)/providers/(.+?)/(.+?)/(.+)`
|
||||
|
|
@ -302,16 +341,30 @@ func WithErrorUnlessStatusCode(codes ...int) autorest.RespondDecorator {
|
|||
// Check if error is unwrapped ServiceError
|
||||
decoder := autorest.NewDecoder(encodedAs, bytes.NewReader(b.Bytes()))
|
||||
if err := decoder.Decode(&e.ServiceError); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("autorest/azure: error response cannot be parsed: %q error: %v", b.String(), err)
|
||||
}
|
||||
|
||||
// for example, should the API return the literal value `null` as the response
|
||||
if e.ServiceError == nil {
|
||||
e.ServiceError = &ServiceError{
|
||||
Code: "Unknown",
|
||||
Message: "Unknown service error",
|
||||
Details: []map[string]interface{}{
|
||||
{
|
||||
"HttpResponse.Body": b.String(),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
if e.ServiceError.Message == "" {
|
||||
|
||||
if e.ServiceError != nil && e.ServiceError.Message == "" {
|
||||
// if we're here it means the returned error wasn't OData v4 compliant.
|
||||
// try to unmarshal the body in hopes of getting something.
|
||||
rawBody := map[string]interface{}{}
|
||||
decoder := autorest.NewDecoder(encodedAs, bytes.NewReader(b.Bytes()))
|
||||
if err := decoder.Decode(&rawBody); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("autorest/azure: error response cannot be parsed: %q error: %v", b.String(), err)
|
||||
}
|
||||
|
||||
e.ServiceError = &ServiceError{
|
||||
|
|
|
|||
59
vendor/github.com/Azure/go-autorest/autorest/azure/environments.go
generated
vendored
59
vendor/github.com/Azure/go-autorest/autorest/azure/environments.go
generated
vendored
|
|
@ -45,7 +45,10 @@ type ResourceIdentifier struct {
|
|||
Datalake string `json:"datalake"`
|
||||
Batch string `json:"batch"`
|
||||
OperationalInsights string `json:"operationalInsights"`
|
||||
OSSRDBMS string `json:"ossRDBMS"`
|
||||
Storage string `json:"storage"`
|
||||
Synapse string `json:"synapse"`
|
||||
ServiceBus string `json:"serviceBus"`
|
||||
}
|
||||
|
||||
// Environment represents a set of endpoints for each of Azure's Clouds.
|
||||
|
|
@ -62,6 +65,10 @@ type Environment struct {
|
|||
ServiceBusEndpoint string `json:"serviceBusEndpoint"`
|
||||
BatchManagementEndpoint string `json:"batchManagementEndpoint"`
|
||||
StorageEndpointSuffix string `json:"storageEndpointSuffix"`
|
||||
CosmosDBDNSSuffix string `json:"cosmosDBDNSSuffix"`
|
||||
MariaDBDNSSuffix string `json:"mariaDBDNSSuffix"`
|
||||
MySQLDatabaseDNSSuffix string `json:"mySqlDatabaseDNSSuffix"`
|
||||
PostgresqlDatabaseDNSSuffix string `json:"postgresqlDatabaseDNSSuffix"`
|
||||
SQLDatabaseDNSSuffix string `json:"sqlDatabaseDNSSuffix"`
|
||||
TrafficManagerDNSSuffix string `json:"trafficManagerDNSSuffix"`
|
||||
KeyVaultDNSSuffix string `json:"keyVaultDNSSuffix"`
|
||||
|
|
@ -69,8 +76,9 @@ type Environment struct {
|
|||
ServiceManagementVMDNSSuffix string `json:"serviceManagementVMDNSSuffix"`
|
||||
ResourceManagerVMDNSSuffix string `json:"resourceManagerVMDNSSuffix"`
|
||||
ContainerRegistryDNSSuffix string `json:"containerRegistryDNSSuffix"`
|
||||
CosmosDBDNSSuffix string `json:"cosmosDBDNSSuffix"`
|
||||
TokenAudience string `json:"tokenAudience"`
|
||||
APIManagementHostNameSuffix string `json:"apiManagementHostNameSuffix"`
|
||||
SynapseEndpointSuffix string `json:"synapseEndpointSuffix"`
|
||||
ResourceIdentifiers ResourceIdentifier `json:"resourceIdentifiers"`
|
||||
}
|
||||
|
||||
|
|
@ -89,6 +97,10 @@ var (
|
|||
ServiceBusEndpoint: "https://servicebus.windows.net/",
|
||||
BatchManagementEndpoint: "https://batch.core.windows.net/",
|
||||
StorageEndpointSuffix: "core.windows.net",
|
||||
CosmosDBDNSSuffix: "documents.azure.com",
|
||||
MariaDBDNSSuffix: "mariadb.database.azure.com",
|
||||
MySQLDatabaseDNSSuffix: "mysql.database.azure.com",
|
||||
PostgresqlDatabaseDNSSuffix: "postgres.database.azure.com",
|
||||
SQLDatabaseDNSSuffix: "database.windows.net",
|
||||
TrafficManagerDNSSuffix: "trafficmanager.net",
|
||||
KeyVaultDNSSuffix: "vault.azure.net",
|
||||
|
|
@ -96,15 +108,19 @@ var (
|
|||
ServiceManagementVMDNSSuffix: "cloudapp.net",
|
||||
ResourceManagerVMDNSSuffix: "cloudapp.azure.com",
|
||||
ContainerRegistryDNSSuffix: "azurecr.io",
|
||||
CosmosDBDNSSuffix: "documents.azure.com",
|
||||
TokenAudience: "https://management.azure.com/",
|
||||
APIManagementHostNameSuffix: "azure-api.net",
|
||||
SynapseEndpointSuffix: "dev.azuresynapse.net",
|
||||
ResourceIdentifiers: ResourceIdentifier{
|
||||
Graph: "https://graph.windows.net/",
|
||||
KeyVault: "https://vault.azure.net",
|
||||
Datalake: "https://datalake.azure.net/",
|
||||
Batch: "https://batch.core.windows.net/",
|
||||
OperationalInsights: "https://api.loganalytics.io",
|
||||
OSSRDBMS: "https://ossrdbms-aad.database.windows.net",
|
||||
Storage: "https://storage.azure.com/",
|
||||
Synapse: "https://dev.azuresynapse.net",
|
||||
ServiceBus: "https://servicebus.azure.net/",
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -122,22 +138,30 @@ var (
|
|||
ServiceBusEndpoint: "https://servicebus.usgovcloudapi.net/",
|
||||
BatchManagementEndpoint: "https://batch.core.usgovcloudapi.net/",
|
||||
StorageEndpointSuffix: "core.usgovcloudapi.net",
|
||||
CosmosDBDNSSuffix: "documents.azure.us",
|
||||
MariaDBDNSSuffix: "mariadb.database.usgovcloudapi.net",
|
||||
MySQLDatabaseDNSSuffix: "mysql.database.usgovcloudapi.net",
|
||||
PostgresqlDatabaseDNSSuffix: "postgres.database.usgovcloudapi.net",
|
||||
SQLDatabaseDNSSuffix: "database.usgovcloudapi.net",
|
||||
TrafficManagerDNSSuffix: "usgovtrafficmanager.net",
|
||||
KeyVaultDNSSuffix: "vault.usgovcloudapi.net",
|
||||
ServiceBusEndpointSuffix: "servicebus.usgovcloudapi.net",
|
||||
ServiceManagementVMDNSSuffix: "usgovcloudapp.net",
|
||||
ResourceManagerVMDNSSuffix: "cloudapp.windowsazure.us",
|
||||
ResourceManagerVMDNSSuffix: "cloudapp.usgovcloudapi.net",
|
||||
ContainerRegistryDNSSuffix: "azurecr.us",
|
||||
CosmosDBDNSSuffix: "documents.azure.us",
|
||||
TokenAudience: "https://management.usgovcloudapi.net/",
|
||||
APIManagementHostNameSuffix: "azure-api.us",
|
||||
SynapseEndpointSuffix: NotAvailable,
|
||||
ResourceIdentifiers: ResourceIdentifier{
|
||||
Graph: "https://graph.windows.net/",
|
||||
KeyVault: "https://vault.usgovcloudapi.net",
|
||||
Datalake: NotAvailable,
|
||||
Batch: "https://batch.core.usgovcloudapi.net/",
|
||||
OperationalInsights: "https://api.loganalytics.us",
|
||||
OSSRDBMS: "https://ossrdbms-aad.database.usgovcloudapi.net",
|
||||
Storage: "https://storage.azure.com/",
|
||||
Synapse: NotAvailable,
|
||||
ServiceBus: "https://servicebus.azure.net/",
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -155,22 +179,30 @@ var (
|
|||
ServiceBusEndpoint: "https://servicebus.chinacloudapi.cn/",
|
||||
BatchManagementEndpoint: "https://batch.chinacloudapi.cn/",
|
||||
StorageEndpointSuffix: "core.chinacloudapi.cn",
|
||||
CosmosDBDNSSuffix: "documents.azure.cn",
|
||||
MariaDBDNSSuffix: "mariadb.database.chinacloudapi.cn",
|
||||
MySQLDatabaseDNSSuffix: "mysql.database.chinacloudapi.cn",
|
||||
PostgresqlDatabaseDNSSuffix: "postgres.database.chinacloudapi.cn",
|
||||
SQLDatabaseDNSSuffix: "database.chinacloudapi.cn",
|
||||
TrafficManagerDNSSuffix: "trafficmanager.cn",
|
||||
KeyVaultDNSSuffix: "vault.azure.cn",
|
||||
ServiceBusEndpointSuffix: "servicebus.chinacloudapi.cn",
|
||||
ServiceManagementVMDNSSuffix: "chinacloudapp.cn",
|
||||
ResourceManagerVMDNSSuffix: "cloudapp.azure.cn",
|
||||
ResourceManagerVMDNSSuffix: "cloudapp.chinacloudapi.cn",
|
||||
ContainerRegistryDNSSuffix: "azurecr.cn",
|
||||
CosmosDBDNSSuffix: "documents.azure.cn",
|
||||
TokenAudience: "https://management.chinacloudapi.cn/",
|
||||
APIManagementHostNameSuffix: "azure-api.cn",
|
||||
SynapseEndpointSuffix: "dev.azuresynapse.azure.cn",
|
||||
ResourceIdentifiers: ResourceIdentifier{
|
||||
Graph: "https://graph.chinacloudapi.cn/",
|
||||
KeyVault: "https://vault.azure.cn",
|
||||
Datalake: NotAvailable,
|
||||
Batch: "https://batch.chinacloudapi.cn/",
|
||||
OperationalInsights: NotAvailable,
|
||||
OSSRDBMS: "https://ossrdbms-aad.database.chinacloudapi.cn",
|
||||
Storage: "https://storage.azure.com/",
|
||||
Synapse: "https://dev.azuresynapse.net",
|
||||
ServiceBus: "https://servicebus.azure.net/",
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -188,6 +220,10 @@ var (
|
|||
ServiceBusEndpoint: "https://servicebus.cloudapi.de/",
|
||||
BatchManagementEndpoint: "https://batch.cloudapi.de/",
|
||||
StorageEndpointSuffix: "core.cloudapi.de",
|
||||
CosmosDBDNSSuffix: "documents.microsoftazure.de",
|
||||
MariaDBDNSSuffix: "mariadb.database.cloudapi.de",
|
||||
MySQLDatabaseDNSSuffix: "mysql.database.cloudapi.de",
|
||||
PostgresqlDatabaseDNSSuffix: "postgres.database.cloudapi.de",
|
||||
SQLDatabaseDNSSuffix: "database.cloudapi.de",
|
||||
TrafficManagerDNSSuffix: "azuretrafficmanager.de",
|
||||
KeyVaultDNSSuffix: "vault.microsoftazure.de",
|
||||
|
|
@ -195,15 +231,19 @@ var (
|
|||
ServiceManagementVMDNSSuffix: "azurecloudapp.de",
|
||||
ResourceManagerVMDNSSuffix: "cloudapp.microsoftazure.de",
|
||||
ContainerRegistryDNSSuffix: NotAvailable,
|
||||
CosmosDBDNSSuffix: "documents.microsoftazure.de",
|
||||
TokenAudience: "https://management.microsoftazure.de/",
|
||||
APIManagementHostNameSuffix: NotAvailable,
|
||||
SynapseEndpointSuffix: NotAvailable,
|
||||
ResourceIdentifiers: ResourceIdentifier{
|
||||
Graph: "https://graph.cloudapi.de/",
|
||||
KeyVault: "https://vault.microsoftazure.de",
|
||||
Datalake: NotAvailable,
|
||||
Batch: "https://batch.cloudapi.de/",
|
||||
OperationalInsights: NotAvailable,
|
||||
OSSRDBMS: "https://ossrdbms-aad.database.cloudapi.de",
|
||||
Storage: "https://storage.azure.com/",
|
||||
Synapse: NotAvailable,
|
||||
ServiceBus: "https://servicebus.azure.net/",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
|
@ -242,3 +282,8 @@ func EnvironmentFromFile(location string) (unmarshaled Environment, err error) {
|
|||
|
||||
return
|
||||
}
|
||||
|
||||
// SetEnvironment updates the environment map with the specified values.
|
||||
func SetEnvironment(name string, env Environment) {
|
||||
environments[strings.ToUpper(name)] = env
|
||||
}
|
||||
|
|
|
|||
9
vendor/github.com/Azure/go-autorest/autorest/client.go
generated
vendored
9
vendor/github.com/Azure/go-autorest/autorest/client.go
generated
vendored
|
|
@ -17,6 +17,7 @@ package autorest
|
|||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
|
@ -30,7 +31,7 @@ import (
|
|||
|
||||
const (
|
||||
// DefaultPollingDelay is a reasonable delay between polling requests.
|
||||
DefaultPollingDelay = 60 * time.Second
|
||||
DefaultPollingDelay = 30 * time.Second
|
||||
|
||||
// DefaultPollingDuration is a reasonable total polling duration.
|
||||
DefaultPollingDuration = 15 * time.Minute
|
||||
|
|
@ -165,7 +166,8 @@ type Client struct {
|
|||
// Setting this to zero will use the provided context to control the duration.
|
||||
PollingDuration time.Duration
|
||||
|
||||
// RetryAttempts sets the default number of retry attempts for client.
|
||||
// RetryAttempts sets the total number of times the client will attempt to make an HTTP request.
|
||||
// Set the value to 1 to disable retries. DO NOT set the value to less than 1.
|
||||
RetryAttempts int
|
||||
|
||||
// RetryDuration sets the delay duration for retries.
|
||||
|
|
@ -259,6 +261,9 @@ func (c Client) Do(r *http.Request) (*http.Response, error) {
|
|||
},
|
||||
})
|
||||
resp, err := SendWithSender(c.sender(tls.RenegotiateNever), r)
|
||||
if resp == nil && err == nil {
|
||||
err = errors.New("autorest: received nil response and error")
|
||||
}
|
||||
logger.Instance.WriteResponse(resp, logger.Filter{})
|
||||
Respond(resp, c.ByInspecting())
|
||||
return resp, err
|
||||
|
|
|
|||
5
vendor/github.com/Azure/go-autorest/autorest/error.go
generated
vendored
5
vendor/github.com/Azure/go-autorest/autorest/error.go
generated
vendored
|
|
@ -96,3 +96,8 @@ func (e DetailedError) Error() string {
|
|||
}
|
||||
return fmt.Sprintf("%s#%s: %s: StatusCode=%d -- Original Error: %v", e.PackageType, e.Method, e.Message, e.StatusCode, e.Original)
|
||||
}
|
||||
|
||||
// Unwrap returns the original error.
|
||||
func (e DetailedError) Unwrap() error {
|
||||
return e.Original
|
||||
}
|
||||
|
|
|
|||
13
vendor/github.com/Azure/go-autorest/autorest/go.mod
generated
vendored
13
vendor/github.com/Azure/go-autorest/autorest/go.mod
generated
vendored
|
|
@ -1,11 +1,12 @@
|
|||
module github.com/Azure/go-autorest/autorest
|
||||
|
||||
go 1.12
|
||||
go 1.15
|
||||
|
||||
require (
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.2
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.3.0
|
||||
github.com/Azure/go-autorest/logger v0.1.0
|
||||
github.com/Azure/go-autorest/tracing v0.5.0
|
||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.13
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.1
|
||||
github.com/Azure/go-autorest/logger v0.2.1
|
||||
github.com/Azure/go-autorest/tracing v0.6.0
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0
|
||||
)
|
||||
|
|
|
|||
39
vendor/github.com/Azure/go-autorest/autorest/go.sum
generated
vendored
39
vendor/github.com/Azure/go-autorest/autorest/go.sum
generated
vendored
|
|
@ -1,28 +1,21 @@
|
|||
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.5.0 h1:q2gDruN08/guU9vAjuPWff0+QIrpH6ediguzdAzXAUU=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.2 h1:O1X4oexUxnZCaEUGsvMnr8ZGj8HI37tNezwY4npRqA0=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
|
||||
github.com/Azure/go-autorest/autorest/date v0.1.0 h1:YGrhWfrgtFs84+h0o46rJrlmsZtyZRg470CqAXTZaGM=
|
||||
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
|
||||
github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSWlm5Ew6bxipnr/tbM=
|
||||
github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.1.0 h1:Kx+AUU2Te+A3JIyYn6Dfs+cFgx5XorQKuIXrZGoq/SI=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.2.0 h1:Ww5g4zThfD/6cLb4z6xxgeyDa7QDkizMkJKe0ysZXp0=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM=
|
||||
github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY=
|
||||
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
|
||||
github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k=
|
||||
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.13 h1:Mp5hbtOePIzM8pJVRa3YLrWWmZtoxRXqUEzCfJt3+/Q=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M=
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw=
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.1 h1:K0laFcLE6VLTOwNgSxaGbUcLPuGXlNkbVvq4cW4nIHk=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
||||
github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg=
|
||||
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk=
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g=
|
||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 h1:hb9wdF1z5waM+dSIICn1l0DkLVDT3hqhhQsDNUmHPRE=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
|
|
|||
25
vendor/github.com/Azure/go-autorest/autorest/go_mod_tidy_hack.go
generated
vendored
Normal file
25
vendor/github.com/Azure/go-autorest/autorest/go_mod_tidy_hack.go
generated
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
//go:build modhack
|
||||
// +build modhack
|
||||
|
||||
package autorest
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// This file, and the github.com/Azure/go-autorest import, won't actually become part of
|
||||
// the resultant binary.
|
||||
|
||||
// Necessary for safely adding multi-module repo.
|
||||
// See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository
|
||||
import _ "github.com/Azure/go-autorest"
|
||||
29
vendor/github.com/Azure/go-autorest/autorest/preparer.go
generated
vendored
29
vendor/github.com/Azure/go-autorest/autorest/preparer.go
generated
vendored
|
|
@ -127,10 +127,7 @@ func WithHeader(header string, value string) PrepareDecorator {
|
|||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
||||
r, err := p.Prepare(r)
|
||||
if err == nil {
|
||||
if r.Header == nil {
|
||||
r.Header = make(http.Header)
|
||||
}
|
||||
r.Header.Set(http.CanonicalHeaderKey(header), value)
|
||||
setHeader(r, http.CanonicalHeaderKey(header), value)
|
||||
}
|
||||
return r, err
|
||||
})
|
||||
|
|
@ -230,7 +227,7 @@ func AsPost() PrepareDecorator { return WithMethod("POST") }
|
|||
func AsPut() PrepareDecorator { return WithMethod("PUT") }
|
||||
|
||||
// WithBaseURL returns a PrepareDecorator that populates the http.Request with a url.URL constructed
|
||||
// from the supplied baseUrl.
|
||||
// from the supplied baseUrl. Query parameters will be encoded as required.
|
||||
func WithBaseURL(baseURL string) PrepareDecorator {
|
||||
return func(p Preparer) Preparer {
|
||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
||||
|
|
@ -241,11 +238,16 @@ func WithBaseURL(baseURL string) PrepareDecorator {
|
|||
return r, err
|
||||
}
|
||||
if u.Scheme == "" {
|
||||
err = fmt.Errorf("autorest: No scheme detected in URL %s", baseURL)
|
||||
return r, fmt.Errorf("autorest: No scheme detected in URL %s", baseURL)
|
||||
}
|
||||
if err == nil {
|
||||
r.URL = u
|
||||
if u.RawQuery != "" {
|
||||
q, err := url.ParseQuery(u.RawQuery)
|
||||
if err != nil {
|
||||
return r, err
|
||||
}
|
||||
u.RawQuery = q.Encode()
|
||||
}
|
||||
r.URL = u
|
||||
}
|
||||
return r, err
|
||||
})
|
||||
|
|
@ -290,10 +292,7 @@ func WithFormData(v url.Values) PrepareDecorator {
|
|||
if err == nil {
|
||||
s := v.Encode()
|
||||
|
||||
if r.Header == nil {
|
||||
r.Header = make(http.Header)
|
||||
}
|
||||
r.Header.Set(http.CanonicalHeaderKey(headerContentType), mimeTypeFormPost)
|
||||
setHeader(r, http.CanonicalHeaderKey(headerContentType), mimeTypeFormPost)
|
||||
r.ContentLength = int64(len(s))
|
||||
r.Body = ioutil.NopCloser(strings.NewReader(s))
|
||||
}
|
||||
|
|
@ -329,10 +328,7 @@ func WithMultiPartFormData(formDataParameters map[string]interface{}) PrepareDec
|
|||
if err = writer.Close(); err != nil {
|
||||
return r, err
|
||||
}
|
||||
if r.Header == nil {
|
||||
r.Header = make(http.Header)
|
||||
}
|
||||
r.Header.Set(http.CanonicalHeaderKey(headerContentType), writer.FormDataContentType())
|
||||
setHeader(r, http.CanonicalHeaderKey(headerContentType), writer.FormDataContentType())
|
||||
r.Body = ioutil.NopCloser(bytes.NewReader(body.Bytes()))
|
||||
r.ContentLength = int64(body.Len())
|
||||
return r, err
|
||||
|
|
@ -437,6 +433,7 @@ func WithXML(v interface{}) PrepareDecorator {
|
|||
bytesWithHeader := []byte(withHeader)
|
||||
|
||||
r.ContentLength = int64(len(bytesWithHeader))
|
||||
setHeader(r, headerContentLength, fmt.Sprintf("%d", len(bytesWithHeader)))
|
||||
r.Body = ioutil.NopCloser(bytes.NewReader(bytesWithHeader))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
1
vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.7.go
generated
vendored
1
vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.7.go
generated
vendored
|
|
@ -1,3 +1,4 @@
|
|||
//go:build !go1.8
|
||||
// +build !go1.8
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
|
|
|
|||
1
vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.8.go
generated
vendored
1
vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.8.go
generated
vendored
|
|
@ -1,3 +1,4 @@
|
|||
//go:build go1.8
|
||||
// +build go1.8
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
|
|
|
|||
70
vendor/github.com/Azure/go-autorest/autorest/sender.go
generated
vendored
70
vendor/github.com/Azure/go-autorest/autorest/sender.go
generated
vendored
|
|
@ -23,11 +23,30 @@ import (
|
|||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/go-autorest/logger"
|
||||
"github.com/Azure/go-autorest/tracing"
|
||||
)
|
||||
|
||||
// there is one sender per TLS renegotiation type, i.e. count of tls.RenegotiationSupport enums
|
||||
const defaultSendersCount = 3
|
||||
|
||||
type defaultSender struct {
|
||||
sender Sender
|
||||
init *sync.Once
|
||||
}
|
||||
|
||||
// each type of sender will be created on demand in sender()
|
||||
var defaultSenders [defaultSendersCount]defaultSender
|
||||
|
||||
func init() {
|
||||
for i := 0; i < defaultSendersCount; i++ {
|
||||
defaultSenders[i].init = &sync.Once{}
|
||||
}
|
||||
}
|
||||
|
||||
// used as a key type in context.WithValue()
|
||||
type ctxSendDecorators struct{}
|
||||
|
||||
|
|
@ -107,26 +126,31 @@ func SendWithSender(s Sender, r *http.Request, decorators ...SendDecorator) (*ht
|
|||
}
|
||||
|
||||
func sender(renengotiation tls.RenegotiationSupport) Sender {
|
||||
// Use behaviour compatible with DefaultTransport, but require TLS minimum version.
|
||||
defaultTransport := http.DefaultTransport.(*http.Transport)
|
||||
transport := &http.Transport{
|
||||
Proxy: defaultTransport.Proxy,
|
||||
DialContext: defaultTransport.DialContext,
|
||||
MaxIdleConns: defaultTransport.MaxIdleConns,
|
||||
IdleConnTimeout: defaultTransport.IdleConnTimeout,
|
||||
TLSHandshakeTimeout: defaultTransport.TLSHandshakeTimeout,
|
||||
ExpectContinueTimeout: defaultTransport.ExpectContinueTimeout,
|
||||
TLSClientConfig: &tls.Config{
|
||||
MinVersion: tls.VersionTLS12,
|
||||
Renegotiation: renengotiation,
|
||||
},
|
||||
}
|
||||
var roundTripper http.RoundTripper = transport
|
||||
if tracing.IsEnabled() {
|
||||
roundTripper = tracing.NewTransport(transport)
|
||||
}
|
||||
j, _ := cookiejar.New(nil)
|
||||
return &http.Client{Jar: j, Transport: roundTripper}
|
||||
// note that we can't init defaultSenders in init() since it will
|
||||
// execute before calling code has had a chance to enable tracing
|
||||
defaultSenders[renengotiation].init.Do(func() {
|
||||
// Use behaviour compatible with DefaultTransport, but require TLS minimum version.
|
||||
defaultTransport := http.DefaultTransport.(*http.Transport)
|
||||
transport := &http.Transport{
|
||||
Proxy: defaultTransport.Proxy,
|
||||
DialContext: defaultTransport.DialContext,
|
||||
MaxIdleConns: defaultTransport.MaxIdleConns,
|
||||
IdleConnTimeout: defaultTransport.IdleConnTimeout,
|
||||
TLSHandshakeTimeout: defaultTransport.TLSHandshakeTimeout,
|
||||
ExpectContinueTimeout: defaultTransport.ExpectContinueTimeout,
|
||||
TLSClientConfig: &tls.Config{
|
||||
MinVersion: tls.VersionTLS12,
|
||||
Renegotiation: renengotiation,
|
||||
},
|
||||
}
|
||||
var roundTripper http.RoundTripper = transport
|
||||
if tracing.IsEnabled() {
|
||||
roundTripper = tracing.NewTransport(transport)
|
||||
}
|
||||
j, _ := cookiejar.New(nil)
|
||||
defaultSenders[renengotiation].sender = &http.Client{Jar: j, Transport: roundTripper}
|
||||
})
|
||||
return defaultSenders[renengotiation].sender
|
||||
}
|
||||
|
||||
// AfterDelay returns a SendDecorator that delays for the passed time.Duration before
|
||||
|
|
@ -248,6 +272,7 @@ func DoRetryForAttempts(attempts int, backoff time.Duration) SendDecorator {
|
|||
if err == nil {
|
||||
return resp, err
|
||||
}
|
||||
logger.Instance.Writef(logger.LogError, "DoRetryForAttempts: received error for attempt %d: %v\n", attempt+1, err)
|
||||
if !DelayForBackoff(backoff, attempt, r.Context().Done()) {
|
||||
return nil, r.Context().Err()
|
||||
}
|
||||
|
|
@ -302,6 +327,9 @@ func doRetryForStatusCodesImpl(s Sender, r *http.Request, count429 bool, attempt
|
|||
if err == nil && !ResponseHasStatusCode(resp, codes...) || IsTokenRefreshError(err) {
|
||||
return resp, err
|
||||
}
|
||||
if err != nil {
|
||||
logger.Instance.Writef(logger.LogError, "DoRetryForStatusCodes: received error for attempt %d: %v\n", attempt+1, err)
|
||||
}
|
||||
delayed := DelayWithRetryAfter(resp, r.Context().Done())
|
||||
// if this was a 429 set the delay cap as specified.
|
||||
// applicable only in the absence of a retry-after header.
|
||||
|
|
@ -368,6 +396,7 @@ func DoRetryForDuration(d time.Duration, backoff time.Duration) SendDecorator {
|
|||
if err == nil {
|
||||
return resp, err
|
||||
}
|
||||
logger.Instance.Writef(logger.LogError, "DoRetryForDuration: received error for attempt %d: %v\n", attempt+1, err)
|
||||
if !DelayForBackoff(backoff, attempt, r.Context().Done()) {
|
||||
return nil, r.Context().Err()
|
||||
}
|
||||
|
|
@ -415,6 +444,7 @@ func DelayForBackoffWithCap(backoff, cap time.Duration, attempt int, cancel <-ch
|
|||
if cap > 0 && d > cap {
|
||||
d = cap
|
||||
}
|
||||
logger.Instance.Writef(logger.LogInfo, "DelayForBackoffWithCap: sleeping for %s\n", d)
|
||||
select {
|
||||
case <-time.After(d):
|
||||
return true
|
||||
|
|
|
|||
21
vendor/github.com/Azure/go-autorest/autorest/utility.go
generated
vendored
21
vendor/github.com/Azure/go-autorest/autorest/utility.go
generated
vendored
|
|
@ -26,8 +26,6 @@ import (
|
|||
"net/url"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest/adal"
|
||||
)
|
||||
|
||||
// EncodedAs is a series of constants specifying various data encodings
|
||||
|
|
@ -207,18 +205,6 @@ func ChangeToGet(req *http.Request) *http.Request {
|
|||
return req
|
||||
}
|
||||
|
||||
// IsTokenRefreshError returns true if the specified error implements the TokenRefreshError
|
||||
// interface. If err is a DetailedError it will walk the chain of Original errors.
|
||||
func IsTokenRefreshError(err error) bool {
|
||||
if _, ok := err.(adal.TokenRefreshError); ok {
|
||||
return true
|
||||
}
|
||||
if de, ok := err.(DetailedError); ok {
|
||||
return IsTokenRefreshError(de.Original)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsTemporaryNetworkError returns true if the specified error is a temporary network error or false
|
||||
// if it's not. If the error doesn't implement the net.Error interface the return value is true.
|
||||
func IsTemporaryNetworkError(err error) bool {
|
||||
|
|
@ -237,3 +223,10 @@ func DrainResponseBody(resp *http.Response) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func setHeader(r *http.Request, key, value string) {
|
||||
if r.Header == nil {
|
||||
r.Header = make(http.Header)
|
||||
}
|
||||
r.Header.Set(key, value)
|
||||
}
|
||||
|
|
|
|||
30
vendor/github.com/Azure/go-autorest/autorest/utility_1.13.go
generated
vendored
Normal file
30
vendor/github.com/Azure/go-autorest/autorest/utility_1.13.go
generated
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
//go:build go1.13
|
||||
// +build go1.13
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package autorest
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest/adal"
|
||||
)
|
||||
|
||||
// IsTokenRefreshError returns true if the specified error implements the TokenRefreshError interface.
|
||||
func IsTokenRefreshError(err error) bool {
|
||||
var tre adal.TokenRefreshError
|
||||
return errors.As(err, &tre)
|
||||
}
|
||||
32
vendor/github.com/Azure/go-autorest/autorest/utility_legacy.go
generated
vendored
Normal file
32
vendor/github.com/Azure/go-autorest/autorest/utility_legacy.go
generated
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
//go:build !go1.13
|
||||
// +build !go1.13
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package autorest
|
||||
|
||||
import "github.com/Azure/go-autorest/autorest/adal"
|
||||
|
||||
// IsTokenRefreshError returns true if the specified error implements the TokenRefreshError
|
||||
// interface. If err is a DetailedError it will walk the chain of Original errors.
|
||||
func IsTokenRefreshError(err error) bool {
|
||||
if _, ok := err.(adal.TokenRefreshError); ok {
|
||||
return true
|
||||
}
|
||||
if de, ok := err.(DetailedError); ok {
|
||||
return IsTokenRefreshError(de.Original)
|
||||
}
|
||||
return false
|
||||
}
|
||||
2
vendor/github.com/Azure/go-autorest/autorest/version.go
generated
vendored
2
vendor/github.com/Azure/go-autorest/autorest/version.go
generated
vendored
|
|
@ -19,7 +19,7 @@ import (
|
|||
"runtime"
|
||||
)
|
||||
|
||||
const number = "v14.0.0"
|
||||
const number = "v14.2.1"
|
||||
|
||||
var (
|
||||
userAgent = fmt.Sprintf("Go/%s (%s-%s) go-autorest/%s",
|
||||
|
|
|
|||
2
vendor/github.com/Azure/go-autorest/logger/go.mod
generated
vendored
2
vendor/github.com/Azure/go-autorest/logger/go.mod
generated
vendored
|
|
@ -1,3 +1,5 @@
|
|||
module github.com/Azure/go-autorest/logger
|
||||
|
||||
go 1.12
|
||||
|
||||
require github.com/Azure/go-autorest v14.2.0+incompatible
|
||||
|
|
|
|||
2
vendor/github.com/Azure/go-autorest/logger/go.sum
generated
vendored
Normal file
2
vendor/github.com/Azure/go-autorest/logger/go.sum
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
24
vendor/github.com/Azure/go-autorest/logger/go_mod_tidy_hack.go
generated
vendored
Normal file
24
vendor/github.com/Azure/go-autorest/logger/go_mod_tidy_hack.go
generated
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
// +build modhack
|
||||
|
||||
package logger
|
||||
|
||||
// Copyright 2017 Microsoft Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// This file, and the github.com/Azure/go-autorest import, won't actually become part of
|
||||
// the resultant binary.
|
||||
|
||||
// Necessary for safely adding multi-module repo.
|
||||
// See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository
|
||||
import _ "github.com/Azure/go-autorest"
|
||||
9
vendor/github.com/Azure/go-autorest/logger/logger.go
generated
vendored
9
vendor/github.com/Azure/go-autorest/logger/logger.go
generated
vendored
|
|
@ -55,6 +55,10 @@ const (
|
|||
|
||||
// LogDebug tells a logger to log all LogDebug, LogInfo, LogWarning, LogError, LogPanic and LogFatal entries passed to it.
|
||||
LogDebug
|
||||
|
||||
// LogAuth is a special case of LogDebug, it tells a logger to also log the body of an authentication request and response.
|
||||
// NOTE: this can disclose sensitive information, use with care.
|
||||
LogAuth
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -65,6 +69,7 @@ const (
|
|||
logWarning = "WARNING"
|
||||
logInfo = "INFO"
|
||||
logDebug = "DEBUG"
|
||||
logAuth = "AUTH"
|
||||
logUnknown = "UNKNOWN"
|
||||
)
|
||||
|
||||
|
|
@ -83,6 +88,8 @@ func ParseLevel(s string) (lt LevelType, err error) {
|
|||
lt = LogInfo
|
||||
case logDebug:
|
||||
lt = LogDebug
|
||||
case logAuth:
|
||||
lt = LogAuth
|
||||
default:
|
||||
err = fmt.Errorf("bad log level '%s'", s)
|
||||
}
|
||||
|
|
@ -106,6 +113,8 @@ func (lt LevelType) String() string {
|
|||
return logInfo
|
||||
case LogDebug:
|
||||
return logDebug
|
||||
case LogAuth:
|
||||
return logAuth
|
||||
default:
|
||||
return logUnknown
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
.DS_Store
|
||||
bin
|
||||
.idea/
|
||||
|
||||
|
||||
|
|
@ -5,9 +5,8 @@ script:
|
|||
- go test -v ./...
|
||||
|
||||
go:
|
||||
- 1.3
|
||||
- 1.4
|
||||
- 1.5
|
||||
- 1.6
|
||||
- 1.7
|
||||
- 1.12
|
||||
- 1.13
|
||||
- 1.14
|
||||
- 1.15
|
||||
- tip
|
||||
|
|
@ -9,7 +9,7 @@ A [go](http://www.golang.org) (or 'golang' for search engine friendliness) imple
|
|||
|
||||
**SECURITY NOTICE:** Some older versions of Go have a security issue in the cryotp/elliptic. Recommendation is to upgrade to at least 1.8.3. See issue #216 for more detail.
|
||||
|
||||
**SECURITY NOTICE:** It's important that you [validate the `alg` presented is what you expect](https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/). This library attempts to make it easy to do the right thing by requiring key types match the expected alg, but you should take the extra step to verify it in your usage. See the examples provided.
|
||||
**SECURITY NOTICE:** It's important that you [validate the `alg` presented is what you expect](https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/). This library attempts to make it easy to do the right thing by requiring key types match the expected alg, but you should take the extra step to verify it in your usage. See the examples provided.
|
||||
|
||||
## What the heck is a JWT?
|
||||
|
||||
|
|
@ -19,7 +19,7 @@ In short, it's a signed JSON object that does something useful (for example, aut
|
|||
|
||||
The first part is called the header. It contains the necessary information for verifying the last part, the signature. For example, which encryption method was used for signing and what key was used.
|
||||
|
||||
The part in the middle is the interesting bit. It's called the Claims and contains the actual stuff you care about. Refer to [the RFC](http://self-issued.info/docs/draft-jones-json-web-token.html) for information about reserved keys and the proper way to add your own.
|
||||
The part in the middle is the interesting bit. It's called the Claims and contains the actual stuff you care about. Refer to [the RFC](http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html) for information about reserved keys and the proper way to add your own.
|
||||
|
||||
## What's in the box?
|
||||
|
||||
|
|
@ -37,7 +37,7 @@ See [the project documentation](https://godoc.org/github.com/dgrijalva/jwt-go) f
|
|||
|
||||
This library publishes all the necessary components for adding your own signing methods. Simply implement the `SigningMethod` interface and register a factory method using `RegisterSigningMethod`.
|
||||
|
||||
Here's an example of an extension that integrates with the Google App Engine signing tools: https://github.com/someone1/gcp-jwt-go
|
||||
Here's an example of an extension that integrates with multiple Google Cloud Platform signing tools (AppEngine, IAM API, Cloud KMS): https://github.com/someone1/gcp-jwt-go
|
||||
|
||||
## Compliance
|
||||
|
||||
|
|
@ -93,6 +93,10 @@ Without going too far down the rabbit hole, here's a description of the interact
|
|||
* OAuth defines several options for passing around authentication data. One popular method is called a "bearer token". A bearer token is simply a string that _should_ only be held by an authenticated user. Thus, simply presenting this token proves your identity. You can probably derive from here why a JWT might make a good bearer token.
|
||||
* Because bearer tokens are used for authentication, it's important they're kept secret. This is why transactions that use bearer tokens typically happen over SSL.
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
This library uses descriptive error messages whenever possible. If you are not getting the expected result, have a look at the errors. The most common place people get stuck is providing the correct type of key to the parser. See the above section on signing methods and key types.
|
||||
|
||||
## More
|
||||
|
||||
Documentation can be found [on godoc.org](http://godoc.org/github.com/dgrijalva/jwt-go).
|
||||
|
|
@ -16,7 +16,7 @@ type Claims interface {
|
|||
// https://tools.ietf.org/html/rfc7519#section-4.1
|
||||
// See examples for how to use this with your own claim types
|
||||
type StandardClaims struct {
|
||||
Audience string `json:"aud,omitempty"`
|
||||
Audience []string `json:"aud,omitempty"`
|
||||
ExpiresAt int64 `json:"exp,omitempty"`
|
||||
Id string `json:"jti,omitempty"`
|
||||
IssuedAt int64 `json:"iat,omitempty"`
|
||||
|
|
@ -90,15 +90,17 @@ func (c *StandardClaims) VerifyNotBefore(cmp int64, req bool) bool {
|
|||
|
||||
// ----- helpers
|
||||
|
||||
func verifyAud(aud string, cmp string, required bool) bool {
|
||||
if aud == "" {
|
||||
func verifyAud(aud []string, cmp string, required bool) bool {
|
||||
if len(aud) == 0 {
|
||||
return !required
|
||||
}
|
||||
if subtle.ConstantTimeCompare([]byte(aud), []byte(cmp)) != 0 {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
|
||||
for _, a := range aud {
|
||||
if subtle.ConstantTimeCompare([]byte(a), []byte(cmp)) != 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func verifyExp(exp int64, now int64, required bool) bool {
|
||||
|
|
@ -25,7 +25,9 @@ func ParseECPrivateKeyFromPEM(key []byte) (*ecdsa.PrivateKey, error) {
|
|||
// Parse the key
|
||||
var parsedKey interface{}
|
||||
if parsedKey, err = x509.ParseECPrivateKey(block.Bytes); err != nil {
|
||||
return nil, err
|
||||
if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var pkey *ecdsa.PrivateKey
|
||||
|
|
@ -13,7 +13,15 @@ type MapClaims map[string]interface{}
|
|||
// Compares the aud claim against cmp.
|
||||
// If required is false, this method will return true if the value matches or is unset
|
||||
func (m MapClaims) VerifyAudience(cmp string, req bool) bool {
|
||||
aud, _ := m["aud"].(string)
|
||||
aud, ok := m["aud"].([]string)
|
||||
if !ok {
|
||||
strAud, ok := m["aud"].(string)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
aud = append(aud, strAud)
|
||||
}
|
||||
|
||||
return verifyAud(aud, cmp, req)
|
||||
}
|
||||
|
||||
|
|
@ -12,9 +12,14 @@ import (
|
|||
type SigningMethodRSAPSS struct {
|
||||
*SigningMethodRSA
|
||||
Options *rsa.PSSOptions
|
||||
// VerifyOptions is optional. If set overrides Options for rsa.VerifyPPS.
|
||||
// Used to accept tokens signed with rsa.PSSSaltLengthAuto, what doesn't follow
|
||||
// https://tools.ietf.org/html/rfc7518#section-3.5 but was used previously.
|
||||
// See https://github.com/dgrijalva/jwt-go/issues/285#issuecomment-437451244 for details.
|
||||
VerifyOptions *rsa.PSSOptions
|
||||
}
|
||||
|
||||
// Specific instances for RS/PS and company
|
||||
// Specific instances for RS/PS and company.
|
||||
var (
|
||||
SigningMethodPS256 *SigningMethodRSAPSS
|
||||
SigningMethodPS384 *SigningMethodRSAPSS
|
||||
|
|
@ -24,13 +29,15 @@ var (
|
|||
func init() {
|
||||
// PS256
|
||||
SigningMethodPS256 = &SigningMethodRSAPSS{
|
||||
&SigningMethodRSA{
|
||||
SigningMethodRSA: &SigningMethodRSA{
|
||||
Name: "PS256",
|
||||
Hash: crypto.SHA256,
|
||||
},
|
||||
&rsa.PSSOptions{
|
||||
Options: &rsa.PSSOptions{
|
||||
SaltLength: rsa.PSSSaltLengthEqualsHash,
|
||||
},
|
||||
VerifyOptions: &rsa.PSSOptions{
|
||||
SaltLength: rsa.PSSSaltLengthAuto,
|
||||
Hash: crypto.SHA256,
|
||||
},
|
||||
}
|
||||
RegisterSigningMethod(SigningMethodPS256.Alg(), func() SigningMethod {
|
||||
|
|
@ -39,13 +46,15 @@ func init() {
|
|||
|
||||
// PS384
|
||||
SigningMethodPS384 = &SigningMethodRSAPSS{
|
||||
&SigningMethodRSA{
|
||||
SigningMethodRSA: &SigningMethodRSA{
|
||||
Name: "PS384",
|
||||
Hash: crypto.SHA384,
|
||||
},
|
||||
&rsa.PSSOptions{
|
||||
Options: &rsa.PSSOptions{
|
||||
SaltLength: rsa.PSSSaltLengthEqualsHash,
|
||||
},
|
||||
VerifyOptions: &rsa.PSSOptions{
|
||||
SaltLength: rsa.PSSSaltLengthAuto,
|
||||
Hash: crypto.SHA384,
|
||||
},
|
||||
}
|
||||
RegisterSigningMethod(SigningMethodPS384.Alg(), func() SigningMethod {
|
||||
|
|
@ -54,13 +63,15 @@ func init() {
|
|||
|
||||
// PS512
|
||||
SigningMethodPS512 = &SigningMethodRSAPSS{
|
||||
&SigningMethodRSA{
|
||||
SigningMethodRSA: &SigningMethodRSA{
|
||||
Name: "PS512",
|
||||
Hash: crypto.SHA512,
|
||||
},
|
||||
&rsa.PSSOptions{
|
||||
Options: &rsa.PSSOptions{
|
||||
SaltLength: rsa.PSSSaltLengthEqualsHash,
|
||||
},
|
||||
VerifyOptions: &rsa.PSSOptions{
|
||||
SaltLength: rsa.PSSSaltLengthAuto,
|
||||
Hash: crypto.SHA512,
|
||||
},
|
||||
}
|
||||
RegisterSigningMethod(SigningMethodPS512.Alg(), func() SigningMethod {
|
||||
|
|
@ -94,7 +105,12 @@ func (m *SigningMethodRSAPSS) Verify(signingString, signature string, key interf
|
|||
hasher := m.Hash.New()
|
||||
hasher.Write([]byte(signingString))
|
||||
|
||||
return rsa.VerifyPSS(rsaKey, m.Hash, hasher.Sum(nil), sig, m.Options)
|
||||
opts := m.Options
|
||||
if m.VerifyOptions != nil {
|
||||
opts = m.VerifyOptions
|
||||
}
|
||||
|
||||
return rsa.VerifyPSS(rsaKey, m.Hash, hasher.Sum(nil), sig, opts)
|
||||
}
|
||||
|
||||
// Implements the Sign method from SigningMethod
|
||||
|
|
@ -8,7 +8,7 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
ErrKeyMustBePEMEncoded = errors.New("Invalid Key: Key must be PEM encoded PKCS1 or PKCS8 private key")
|
||||
ErrKeyMustBePEMEncoded = errors.New("Invalid Key: Key must be a PEM encoded PKCS1 or PKCS8 key")
|
||||
ErrNotRSAPrivateKey = errors.New("Key is not a valid RSA private key")
|
||||
ErrNotRSAPublicKey = errors.New("Key is not a valid RSA public key")
|
||||
)
|
||||
10
vendor/modules.txt
vendored
10
vendor/modules.txt
vendored
|
|
@ -30,11 +30,11 @@ github.com/Azure/azure-sdk-for-go/version
|
|||
github.com/Azure/azure-storage-blob-go/azblob
|
||||
# github.com/Azure/go-autorest v14.2.0+incompatible
|
||||
github.com/Azure/go-autorest
|
||||
# github.com/Azure/go-autorest/autorest v0.10.0
|
||||
# github.com/Azure/go-autorest/autorest v0.11.20
|
||||
## explicit
|
||||
github.com/Azure/go-autorest/autorest
|
||||
github.com/Azure/go-autorest/autorest/azure
|
||||
# github.com/Azure/go-autorest/autorest/adal v0.9.2
|
||||
# github.com/Azure/go-autorest/autorest/adal v0.9.13
|
||||
github.com/Azure/go-autorest/autorest/adal
|
||||
# github.com/Azure/go-autorest/autorest/azure/auth v0.4.2
|
||||
## explicit
|
||||
|
|
@ -49,7 +49,7 @@ github.com/Azure/go-autorest/autorest/to
|
|||
# github.com/Azure/go-autorest/autorest/validation v0.2.0
|
||||
## explicit
|
||||
github.com/Azure/go-autorest/autorest/validation
|
||||
# github.com/Azure/go-autorest/logger v0.1.0
|
||||
# github.com/Azure/go-autorest/logger v0.2.1
|
||||
github.com/Azure/go-autorest/logger
|
||||
# github.com/Azure/go-autorest/tracing v0.6.0
|
||||
github.com/Azure/go-autorest/tracing
|
||||
|
|
@ -121,10 +121,10 @@ github.com/deepmap/oapi-codegen/pkg/codegen/templates
|
|||
github.com/deepmap/oapi-codegen/pkg/runtime
|
||||
github.com/deepmap/oapi-codegen/pkg/types
|
||||
github.com/deepmap/oapi-codegen/pkg/util
|
||||
# github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||
github.com/dgrijalva/jwt-go
|
||||
# github.com/dimchansky/utfbom v1.1.0
|
||||
github.com/dimchansky/utfbom
|
||||
# github.com/form3tech-oss/jwt-go v3.2.2+incompatible
|
||||
github.com/form3tech-oss/jwt-go
|
||||
# github.com/getkin/kin-openapi v0.13.0
|
||||
## explicit
|
||||
github.com/getkin/kin-openapi/jsoninfo
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue