Update github.com/xenolf/lego to 0.4.1
This commit is contained in:
parent
5042c5bf40
commit
e8d63b2a3b
105 changed files with 4299 additions and 2075 deletions
51
vendor/github.com/Azure/go-autorest/autorest/adal/config.go
generated
vendored
Normal file
51
vendor/github.com/Azure/go-autorest/autorest/adal/config.go
generated
vendored
Normal file
|
@ -0,0 +1,51 @@
|
|||
package adal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
const (
|
||||
activeDirectoryAPIVersion = "1.0"
|
||||
)
|
||||
|
||||
// OAuthConfig represents the endpoints needed
|
||||
// in OAuth operations
|
||||
type OAuthConfig struct {
|
||||
AuthorityEndpoint url.URL
|
||||
AuthorizeEndpoint url.URL
|
||||
TokenEndpoint url.URL
|
||||
DeviceCodeEndpoint url.URL
|
||||
}
|
||||
|
||||
// NewOAuthConfig returns an OAuthConfig with tenant specific urls
|
||||
func NewOAuthConfig(activeDirectoryEndpoint, tenantID string) (*OAuthConfig, error) {
|
||||
const activeDirectoryEndpointTemplate = "%s/oauth2/%s?api-version=%s"
|
||||
u, err := url.Parse(activeDirectoryEndpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
authorityURL, err := u.Parse(tenantID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
authorizeURL, err := u.Parse(fmt.Sprintf(activeDirectoryEndpointTemplate, tenantID, "authorize", activeDirectoryAPIVersion))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tokenURL, err := u.Parse(fmt.Sprintf(activeDirectoryEndpointTemplate, tenantID, "token", activeDirectoryAPIVersion))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
deviceCodeURL, err := u.Parse(fmt.Sprintf(activeDirectoryEndpointTemplate, tenantID, "devicecode", activeDirectoryAPIVersion))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &OAuthConfig{
|
||||
AuthorityEndpoint: *authorityURL,
|
||||
AuthorizeEndpoint: *authorizeURL,
|
||||
TokenEndpoint: *tokenURL,
|
||||
DeviceCodeEndpoint: *deviceCodeURL,
|
||||
}, nil
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package azure
|
||||
package adal
|
||||
|
||||
/*
|
||||
This file is largely based on rjw57/oauth2device's code, with the follow differences:
|
||||
|
@ -10,16 +10,17 @@ package azure
|
|||
*/
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
)
|
||||
|
||||
const (
|
||||
logPrefix = "autorest/azure/devicetoken:"
|
||||
logPrefix = "autorest/adal/devicetoken:"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -38,10 +39,17 @@ var (
|
|||
// ErrDeviceSlowDown represents the service telling us we're polling too often during device flow
|
||||
ErrDeviceSlowDown = fmt.Errorf("%s Error while retrieving OAuth token: Slow Down", logPrefix)
|
||||
|
||||
// ErrDeviceCodeEmpty represents an empty device code from the device endpoint while using device flow
|
||||
ErrDeviceCodeEmpty = fmt.Errorf("%s Error while retrieving device code: Device Code Empty", logPrefix)
|
||||
|
||||
// ErrOAuthTokenEmpty represents an empty OAuth token from the token endpoint when using device flow
|
||||
ErrOAuthTokenEmpty = fmt.Errorf("%s Error while retrieving OAuth token: Token Empty", logPrefix)
|
||||
|
||||
errCodeSendingFails = "Error occurred while sending request for Device Authorization Code"
|
||||
errCodeHandlingFails = "Error occurred while handling response from the Device Endpoint"
|
||||
errTokenSendingFails = "Error occurred while sending request with device code for a token"
|
||||
errTokenHandlingFails = "Error occurred while handling response from the Token Endpoint (during device flow)"
|
||||
errStatusNotOK = "Error HTTP status != 200"
|
||||
)
|
||||
|
||||
// DeviceCode is the object returned by the device auth endpoint
|
||||
|
@ -79,31 +87,45 @@ type deviceToken struct {
|
|||
|
||||
// InitiateDeviceAuth initiates a device auth flow. It returns a DeviceCode
|
||||
// that can be used with CheckForUserCompletion or WaitForUserCompletion.
|
||||
func InitiateDeviceAuth(client *autorest.Client, oauthConfig OAuthConfig, clientID, resource string) (*DeviceCode, error) {
|
||||
req, _ := autorest.Prepare(
|
||||
&http.Request{},
|
||||
autorest.AsPost(),
|
||||
autorest.AsFormURLEncoded(),
|
||||
autorest.WithBaseURL(oauthConfig.DeviceCodeEndpoint.String()),
|
||||
autorest.WithFormData(url.Values{
|
||||
"client_id": []string{clientID},
|
||||
"resource": []string{resource},
|
||||
}),
|
||||
)
|
||||
func InitiateDeviceAuth(sender Sender, oauthConfig OAuthConfig, clientID, resource string) (*DeviceCode, error) {
|
||||
v := url.Values{
|
||||
"client_id": []string{clientID},
|
||||
"resource": []string{resource},
|
||||
}
|
||||
|
||||
resp, err := autorest.SendWithSender(client, req)
|
||||
s := v.Encode()
|
||||
body := ioutil.NopCloser(strings.NewReader(s))
|
||||
|
||||
req, err := http.NewRequest(http.MethodPost, oauthConfig.DeviceCodeEndpoint.String(), body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeSendingFails, err)
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeSendingFails, err.Error())
|
||||
}
|
||||
|
||||
req.ContentLength = int64(len(s))
|
||||
req.Header.Set(contentType, mimeTypeFormPost)
|
||||
resp, err := sender.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeSendingFails, err.Error())
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
rb, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeHandlingFails, err.Error())
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeHandlingFails, errStatusNotOK)
|
||||
}
|
||||
|
||||
if len(strings.Trim(string(rb), " ")) == 0 {
|
||||
return nil, ErrDeviceCodeEmpty
|
||||
}
|
||||
|
||||
var code DeviceCode
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
autorest.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&code),
|
||||
autorest.ByClosing())
|
||||
err = json.Unmarshal(rb, &code)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeHandlingFails, err)
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeHandlingFails, err.Error())
|
||||
}
|
||||
|
||||
code.ClientID = clientID
|
||||
|
@ -115,33 +137,46 @@ func InitiateDeviceAuth(client *autorest.Client, oauthConfig OAuthConfig, client
|
|||
|
||||
// CheckForUserCompletion takes a DeviceCode and checks with the Azure AD OAuth endpoint
|
||||
// to see if the device flow has: been completed, timed out, or otherwise failed
|
||||
func CheckForUserCompletion(client *autorest.Client, code *DeviceCode) (*Token, error) {
|
||||
req, _ := autorest.Prepare(
|
||||
&http.Request{},
|
||||
autorest.AsPost(),
|
||||
autorest.AsFormURLEncoded(),
|
||||
autorest.WithBaseURL(code.OAuthConfig.TokenEndpoint.String()),
|
||||
autorest.WithFormData(url.Values{
|
||||
"client_id": []string{code.ClientID},
|
||||
"code": []string{*code.DeviceCode},
|
||||
"grant_type": []string{OAuthGrantTypeDeviceCode},
|
||||
"resource": []string{code.Resource},
|
||||
}),
|
||||
)
|
||||
func CheckForUserCompletion(sender Sender, code *DeviceCode) (*Token, error) {
|
||||
v := url.Values{
|
||||
"client_id": []string{code.ClientID},
|
||||
"code": []string{*code.DeviceCode},
|
||||
"grant_type": []string{OAuthGrantTypeDeviceCode},
|
||||
"resource": []string{code.Resource},
|
||||
}
|
||||
|
||||
resp, err := autorest.SendWithSender(client, req)
|
||||
s := v.Encode()
|
||||
body := ioutil.NopCloser(strings.NewReader(s))
|
||||
|
||||
req, err := http.NewRequest(http.MethodPost, code.OAuthConfig.TokenEndpoint.String(), body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenSendingFails, err)
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenSendingFails, err.Error())
|
||||
}
|
||||
|
||||
req.ContentLength = int64(len(s))
|
||||
req.Header.Set(contentType, mimeTypeFormPost)
|
||||
resp, err := sender.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenSendingFails, err.Error())
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
rb, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenHandlingFails, err.Error())
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK && len(strings.Trim(string(rb), " ")) == 0 {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenHandlingFails, errStatusNotOK)
|
||||
}
|
||||
if len(strings.Trim(string(rb), " ")) == 0 {
|
||||
return nil, ErrOAuthTokenEmpty
|
||||
}
|
||||
|
||||
var token deviceToken
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusBadRequest),
|
||||
autorest.ByUnmarshallingJSON(&token),
|
||||
autorest.ByClosing())
|
||||
err = json.Unmarshal(rb, &token)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenHandlingFails, err)
|
||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenHandlingFails, err.Error())
|
||||
}
|
||||
|
||||
if token.Error == nil {
|
||||
|
@ -164,12 +199,12 @@ func CheckForUserCompletion(client *autorest.Client, code *DeviceCode) (*Token,
|
|||
|
||||
// WaitForUserCompletion calls CheckForUserCompletion repeatedly until a token is granted or an error state occurs.
|
||||
// This prevents the user from looping and checking against 'ErrDeviceAuthorizationPending'.
|
||||
func WaitForUserCompletion(client *autorest.Client, code *DeviceCode) (*Token, error) {
|
||||
func WaitForUserCompletion(sender Sender, code *DeviceCode) (*Token, error) {
|
||||
intervalDuration := time.Duration(*code.Interval) * time.Second
|
||||
waitDuration := intervalDuration
|
||||
|
||||
for {
|
||||
token, err := CheckForUserCompletion(client, code)
|
||||
token, err := CheckForUserCompletion(sender, code)
|
||||
|
||||
if err == nil {
|
||||
return token, nil
|
6
vendor/github.com/Azure/go-autorest/autorest/adal/msi.go
generated
vendored
Normal file
6
vendor/github.com/Azure/go-autorest/autorest/adal/msi.go
generated
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
// +build !windows
|
||||
|
||||
package adal
|
||||
|
||||
// msiPath is the path to the MSI Extension settings file (to discover the endpoint)
|
||||
var msiPath = "/var/lib/waagent/ManagedIdentity-Settings"
|
11
vendor/github.com/Azure/go-autorest/autorest/adal/msi_windows.go
generated
vendored
Normal file
11
vendor/github.com/Azure/go-autorest/autorest/adal/msi_windows.go
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
// +build windows
|
||||
|
||||
package adal
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// msiPath is the path to the MSI Extension settings file (to discover the endpoint)
|
||||
var msiPath = strings.Join([]string{os.Getenv("SystemDrive"), "WindowsAzure/Config/ManagedIdentity-Settings"}, "/")
|
|
@ -1,4 +1,4 @@
|
|||
package azure
|
||||
package adal
|
||||
|
||||
import (
|
||||
"encoding/json"
|
46
vendor/github.com/Azure/go-autorest/autorest/adal/sender.go
generated
vendored
Normal file
46
vendor/github.com/Azure/go-autorest/autorest/adal/sender.go
generated
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
package adal
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
const (
|
||||
contentType = "Content-Type"
|
||||
mimeTypeFormPost = "application/x-www-form-urlencoded"
|
||||
)
|
||||
|
||||
// Sender is the interface that wraps the Do method to send HTTP requests.
|
||||
//
|
||||
// The standard http.Client conforms to this interface.
|
||||
type Sender interface {
|
||||
Do(*http.Request) (*http.Response, error)
|
||||
}
|
||||
|
||||
// SenderFunc is a method that implements the Sender interface.
|
||||
type SenderFunc func(*http.Request) (*http.Response, error)
|
||||
|
||||
// Do implements the Sender interface on SenderFunc.
|
||||
func (sf SenderFunc) Do(r *http.Request) (*http.Response, error) {
|
||||
return sf(r)
|
||||
}
|
||||
|
||||
// SendDecorator takes and possibily decorates, by wrapping, a Sender. Decorators may affect the
|
||||
// http.Request and pass it along or, first, pass the http.Request along then react to the
|
||||
// http.Response result.
|
||||
type SendDecorator func(Sender) Sender
|
||||
|
||||
// CreateSender creates, decorates, and returns, as a Sender, the default http.Client.
|
||||
func CreateSender(decorators ...SendDecorator) Sender {
|
||||
return DecorateSender(&http.Client{}, decorators...)
|
||||
}
|
||||
|
||||
// DecorateSender accepts a Sender and a, possibly empty, set of SendDecorators, which is applies to
|
||||
// the Sender. Decorators are applied in the order received, but their affect upon the request
|
||||
// depends on whether they are a pre-decorator (change the http.Request and then pass it along) or a
|
||||
// post-decorator (pass the http.Request along and react to the results in http.Response).
|
||||
func DecorateSender(s Sender, decorators ...SendDecorator) Sender {
|
||||
for _, decorate := range decorators {
|
||||
s = decorate(s)
|
||||
}
|
||||
return s
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package azure
|
||||
package adal
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
|
@ -6,19 +6,21 @@ import (
|
|||
"crypto/sha1"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/date"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultRefresh = 5 * time.Minute
|
||||
tokenBaseDate = "1970-01-01T00:00:00Z"
|
||||
|
||||
// OAuthGrantTypeDeviceCode is the "grant_type" identifier used in device flow
|
||||
OAuthGrantTypeDeviceCode = "device_code"
|
||||
|
@ -28,12 +30,21 @@ const (
|
|||
|
||||
// OAuthGrantTypeRefreshToken is the "grant_type" identifier used in refresh token flows
|
||||
OAuthGrantTypeRefreshToken = "refresh_token"
|
||||
|
||||
// metadataHeader is the header required by MSI extension
|
||||
metadataHeader = "Metadata"
|
||||
)
|
||||
|
||||
var expirationBase time.Time
|
||||
// OAuthTokenProvider is an interface which should be implemented by an access token retriever
|
||||
type OAuthTokenProvider interface {
|
||||
OAuthToken() string
|
||||
}
|
||||
|
||||
func init() {
|
||||
expirationBase, _ = time.Parse(time.RFC3339, tokenBaseDate)
|
||||
// Refresher is an interface for token refresh functionality
|
||||
type Refresher interface {
|
||||
Refresh() error
|
||||
RefreshExchange(resource string) error
|
||||
EnsureFresh() error
|
||||
}
|
||||
|
||||
// TokenRefreshCallback is the type representing callbacks that will be called after
|
||||
|
@ -59,7 +70,10 @@ func (t Token) Expires() time.Time {
|
|||
if err != nil {
|
||||
s = -3600
|
||||
}
|
||||
return expirationBase.Add(time.Duration(s) * time.Second).UTC()
|
||||
|
||||
expiration := date.NewUnixTimeFromSeconds(float64(s))
|
||||
|
||||
return time.Time(expiration).UTC()
|
||||
}
|
||||
|
||||
// IsExpired returns true if the Token is expired, false otherwise.
|
||||
|
@ -73,14 +87,9 @@ func (t Token) WillExpireIn(d time.Duration) bool {
|
|||
return !t.Expires().After(time.Now().Add(d))
|
||||
}
|
||||
|
||||
// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose
|
||||
// value is "Bearer " followed by the AccessToken of the Token.
|
||||
func (t *Token) WithAuthorization() autorest.PrepareDecorator {
|
||||
return func(p autorest.Preparer) autorest.Preparer {
|
||||
return autorest.PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
||||
return (autorest.WithBearerAuthorization(t.AccessToken)(p)).Prepare(r)
|
||||
})
|
||||
}
|
||||
//OAuthToken return the current access token
|
||||
func (t *Token) OAuthToken() string {
|
||||
return t.AccessToken
|
||||
}
|
||||
|
||||
// ServicePrincipalNoSecret represents a secret type that contains no secret
|
||||
|
@ -118,6 +127,15 @@ type ServicePrincipalCertificateSecret struct {
|
|||
PrivateKey *rsa.PrivateKey
|
||||
}
|
||||
|
||||
// ServicePrincipalMSISecret implements ServicePrincipalSecret for machines running the MSI Extension.
|
||||
type ServicePrincipalMSISecret struct {
|
||||
}
|
||||
|
||||
// SetAuthenticationValues is a method of the interface ServicePrincipalSecret.
|
||||
func (msiSecret *ServicePrincipalMSISecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SignJwt returns the JWT signed with the certificate's private key.
|
||||
func (secret *ServicePrincipalCertificateSecret) SignJwt(spt *ServicePrincipalToken) (string, error) {
|
||||
hasher := sha1.New()
|
||||
|
@ -173,7 +191,7 @@ type ServicePrincipalToken struct {
|
|||
resource string
|
||||
autoRefresh bool
|
||||
refreshWithin time.Duration
|
||||
sender autorest.Sender
|
||||
sender Sender
|
||||
|
||||
refreshCallbacks []TokenRefreshCallback
|
||||
}
|
||||
|
@ -238,10 +256,58 @@ func NewServicePrincipalTokenFromCertificate(oauthConfig OAuthConfig, clientID s
|
|||
)
|
||||
}
|
||||
|
||||
// GetMSIVMEndpoint gets the MSI endpoint on Virtual Machines.
|
||||
func GetMSIVMEndpoint() (string, error) {
|
||||
return getMSIVMEndpoint(msiPath)
|
||||
}
|
||||
|
||||
func getMSIVMEndpoint(path string) (string, error) {
|
||||
// Read MSI settings
|
||||
bytes, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
msiSettings := struct {
|
||||
URL string `json:"url"`
|
||||
}{}
|
||||
err = json.Unmarshal(bytes, &msiSettings)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return msiSettings.URL, nil
|
||||
}
|
||||
|
||||
// NewServicePrincipalTokenFromMSI creates a ServicePrincipalToken via the MSI VM Extension.
|
||||
func NewServicePrincipalTokenFromMSI(msiEndpoint, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
// We set the oauth config token endpoint to be MSI's endpoint
|
||||
msiEndpointURL, err := url.Parse(msiEndpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
oauthConfig, err := NewOAuthConfig(msiEndpointURL.String(), "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
spt := &ServicePrincipalToken{
|
||||
oauthConfig: *oauthConfig,
|
||||
secret: &ServicePrincipalMSISecret{},
|
||||
resource: resource,
|
||||
autoRefresh: true,
|
||||
refreshWithin: defaultRefresh,
|
||||
sender: &http.Client{},
|
||||
refreshCallbacks: callbacks,
|
||||
}
|
||||
|
||||
return spt, nil
|
||||
}
|
||||
|
||||
// EnsureFresh will refresh the token if it will expire within the refresh window (as set by
|
||||
// RefreshWithin).
|
||||
// RefreshWithin) and autoRefresh flag is on.
|
||||
func (spt *ServicePrincipalToken) EnsureFresh() error {
|
||||
if spt.WillExpireIn(spt.refreshWithin) {
|
||||
if spt.autoRefresh && spt.WillExpireIn(spt.refreshWithin) {
|
||||
return spt.Refresh()
|
||||
}
|
||||
return nil
|
||||
|
@ -253,8 +319,7 @@ func (spt *ServicePrincipalToken) InvokeRefreshCallbacks(token Token) error {
|
|||
for _, callback := range spt.refreshCallbacks {
|
||||
err := callback(spt.Token)
|
||||
if err != nil {
|
||||
return autorest.NewErrorWithError(err,
|
||||
"azure.ServicePrincipalToken", "InvokeRefreshCallbacks", nil, "A TokenRefreshCallback handler returned an error")
|
||||
return fmt.Errorf("adal: TokenRefreshCallback handler failed. Error = '%v'", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -287,39 +352,48 @@ func (spt *ServicePrincipalToken) refreshInternal(resource string) error {
|
|||
}
|
||||
}
|
||||
|
||||
req, _ := autorest.Prepare(&http.Request{},
|
||||
autorest.AsPost(),
|
||||
autorest.AsFormURLEncoded(),
|
||||
autorest.WithBaseURL(spt.oauthConfig.TokenEndpoint.String()),
|
||||
autorest.WithFormData(v))
|
||||
|
||||
resp, err := autorest.SendWithSender(spt.sender, req)
|
||||
s := v.Encode()
|
||||
body := ioutil.NopCloser(strings.NewReader(s))
|
||||
req, err := http.NewRequest(http.MethodPost, spt.oauthConfig.TokenEndpoint.String(), body)
|
||||
if err != nil {
|
||||
return autorest.NewErrorWithError(err,
|
||||
"azure.ServicePrincipalToken", "Refresh", resp, "Failure sending request for Service Principal %s",
|
||||
spt.clientID)
|
||||
return fmt.Errorf("adal: Failed to build the refresh request. Error = '%v'", err)
|
||||
}
|
||||
|
||||
var newToken Token
|
||||
err = autorest.Respond(resp,
|
||||
autorest.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&newToken),
|
||||
autorest.ByClosing())
|
||||
req.ContentLength = int64(len(s))
|
||||
req.Header.Set(contentType, mimeTypeFormPost)
|
||||
if _, ok := spt.secret.(*ServicePrincipalMSISecret); ok {
|
||||
req.Header.Set(metadataHeader, "true")
|
||||
}
|
||||
resp, err := spt.sender.Do(req)
|
||||
if err != nil {
|
||||
return autorest.NewErrorWithError(err,
|
||||
"azure.ServicePrincipalToken", "Refresh", resp, "Failure handling response to Service Principal %s request",
|
||||
spt.clientID)
|
||||
return fmt.Errorf("adal: Failed to execute the refresh request. Error = '%v'", err)
|
||||
}
|
||||
|
||||
spt.Token = newToken
|
||||
defer resp.Body.Close()
|
||||
rb, err := ioutil.ReadAll(resp.Body)
|
||||
|
||||
err = spt.InvokeRefreshCallbacks(newToken)
|
||||
if err != nil {
|
||||
// its already wrapped inside InvokeRefreshCallbacks
|
||||
return err
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
if err != nil {
|
||||
return fmt.Errorf("adal: Refresh request failed. Status Code = '%d'. Failed reading response body", resp.StatusCode)
|
||||
}
|
||||
return fmt.Errorf("adal: Refresh request failed. Status Code = '%d'. Response body: %s", resp.StatusCode, string(rb))
|
||||
}
|
||||
|
||||
return nil
|
||||
if err != nil {
|
||||
return fmt.Errorf("adal: Failed to read a new service principal token during refresh. Error = '%v'", err)
|
||||
}
|
||||
if len(strings.Trim(string(rb), " ")) == 0 {
|
||||
return fmt.Errorf("adal: Empty service principal token received during refresh")
|
||||
}
|
||||
var token Token
|
||||
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))
|
||||
}
|
||||
|
||||
spt.Token = token
|
||||
|
||||
return spt.InvokeRefreshCallbacks(token)
|
||||
}
|
||||
|
||||
// SetAutoRefresh enables or disables automatic refreshing of stale tokens.
|
||||
|
@ -334,30 +408,6 @@ func (spt *ServicePrincipalToken) SetRefreshWithin(d time.Duration) {
|
|||
return
|
||||
}
|
||||
|
||||
// SetSender sets the autorest.Sender used when obtaining the Service Principal token. An
|
||||
// SetSender sets the http.Client used when obtaining the Service Principal token. An
|
||||
// undecorated http.Client is used by default.
|
||||
func (spt *ServicePrincipalToken) SetSender(s autorest.Sender) {
|
||||
spt.sender = s
|
||||
}
|
||||
|
||||
// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose
|
||||
// value is "Bearer " followed by the AccessToken of the ServicePrincipalToken.
|
||||
//
|
||||
// By default, the token will automatically refresh if nearly expired (as determined by the
|
||||
// RefreshWithin interval). Use the AutoRefresh method to enable or disable automatically refreshing
|
||||
// tokens.
|
||||
func (spt *ServicePrincipalToken) WithAuthorization() autorest.PrepareDecorator {
|
||||
return func(p autorest.Preparer) autorest.Preparer {
|
||||
return autorest.PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
||||
if spt.autoRefresh {
|
||||
err := spt.EnsureFresh()
|
||||
if err != nil {
|
||||
return r, autorest.NewErrorWithError(err,
|
||||
"azure.ServicePrincipalToken", "WithAuthorization", nil, "Failed to refresh Service Principal Token for request to %s",
|
||||
r.URL)
|
||||
}
|
||||
}
|
||||
return (autorest.WithBearerAuthorization(spt.AccessToken)(p)).Prepare(r)
|
||||
})
|
||||
}
|
||||
}
|
||||
func (spt *ServicePrincipalToken) SetSender(s Sender) { spt.sender = s }
|
167
vendor/github.com/Azure/go-autorest/autorest/authorization.go
generated
vendored
Normal file
167
vendor/github.com/Azure/go-autorest/autorest/authorization.go
generated
vendored
Normal file
|
@ -0,0 +1,167 @@
|
|||
package autorest
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest/adal"
|
||||
)
|
||||
|
||||
const (
|
||||
bearerChallengeHeader = "Www-Authenticate"
|
||||
bearer = "Bearer"
|
||||
tenantID = "tenantID"
|
||||
)
|
||||
|
||||
// Authorizer is the interface that provides a PrepareDecorator used to supply request
|
||||
// authorization. Most often, the Authorizer decorator runs last so it has access to the full
|
||||
// state of the formed HTTP request.
|
||||
type Authorizer interface {
|
||||
WithAuthorization() PrepareDecorator
|
||||
}
|
||||
|
||||
// NullAuthorizer implements a default, "do nothing" Authorizer.
|
||||
type NullAuthorizer struct{}
|
||||
|
||||
// WithAuthorization returns a PrepareDecorator that does nothing.
|
||||
func (na NullAuthorizer) WithAuthorization() PrepareDecorator {
|
||||
return WithNothing()
|
||||
}
|
||||
|
||||
// BearerAuthorizer implements the bearer authorization
|
||||
type BearerAuthorizer struct {
|
||||
tokenProvider adal.OAuthTokenProvider
|
||||
}
|
||||
|
||||
// NewBearerAuthorizer crates a BearerAuthorizer using the given token provider
|
||||
func NewBearerAuthorizer(tp adal.OAuthTokenProvider) *BearerAuthorizer {
|
||||
return &BearerAuthorizer{tokenProvider: tp}
|
||||
}
|
||||
|
||||
func (ba *BearerAuthorizer) withBearerAuthorization() PrepareDecorator {
|
||||
return WithHeader(headerAuthorization, fmt.Sprintf("Bearer %s", ba.tokenProvider.OAuthToken()))
|
||||
}
|
||||
|
||||
// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose
|
||||
// value is "Bearer " followed by the token.
|
||||
//
|
||||
// By default, the token will be automatically refreshed through the Refresher interface.
|
||||
func (ba *BearerAuthorizer) WithAuthorization() PrepareDecorator {
|
||||
return func(p Preparer) Preparer {
|
||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
||||
refresher, ok := ba.tokenProvider.(adal.Refresher)
|
||||
if ok {
|
||||
err := refresher.EnsureFresh()
|
||||
if err != nil {
|
||||
return r, NewErrorWithError(err, "azure.BearerAuthorizer", "WithAuthorization", nil,
|
||||
"Failed to refresh the Token for request to %s", r.URL)
|
||||
}
|
||||
}
|
||||
return (ba.withBearerAuthorization()(p)).Prepare(r)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// BearerAuthorizerCallbackFunc is the authentication callback signature.
|
||||
type BearerAuthorizerCallbackFunc func(tenantID, resource string) (*BearerAuthorizer, error)
|
||||
|
||||
// BearerAuthorizerCallback implements bearer authorization via a callback.
|
||||
type BearerAuthorizerCallback struct {
|
||||
sender Sender
|
||||
callback BearerAuthorizerCallbackFunc
|
||||
}
|
||||
|
||||
// NewBearerAuthorizerCallback creates a bearer authorization callback. The callback
|
||||
// is invoked when the HTTP request is submitted.
|
||||
func NewBearerAuthorizerCallback(sender Sender, callback BearerAuthorizerCallbackFunc) *BearerAuthorizerCallback {
|
||||
if sender == nil {
|
||||
sender = &http.Client{}
|
||||
}
|
||||
return &BearerAuthorizerCallback{sender: sender, callback: callback}
|
||||
}
|
||||
|
||||
// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose value
|
||||
// is "Bearer " followed by the token. The BearerAuthorizer is obtained via a user-supplied callback.
|
||||
//
|
||||
// By default, the token will be automatically refreshed through the Refresher interface.
|
||||
func (bacb *BearerAuthorizerCallback) WithAuthorization() PrepareDecorator {
|
||||
return func(p Preparer) Preparer {
|
||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
||||
// make a copy of the request and remove the body as it's not
|
||||
// required and avoids us having to create a copy of it.
|
||||
rCopy := *r
|
||||
removeRequestBody(&rCopy)
|
||||
|
||||
resp, err := bacb.sender.Do(&rCopy)
|
||||
if err == nil && resp.StatusCode == 401 {
|
||||
defer resp.Body.Close()
|
||||
if hasBearerChallenge(resp) {
|
||||
bc, err := newBearerChallenge(resp)
|
||||
if err != nil {
|
||||
return r, err
|
||||
}
|
||||
if bacb.callback != nil {
|
||||
ba, err := bacb.callback(bc.values[tenantID], bc.values["resource"])
|
||||
if err != nil {
|
||||
return r, err
|
||||
}
|
||||
return ba.WithAuthorization()(p).Prepare(r)
|
||||
}
|
||||
}
|
||||
}
|
||||
return r, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// returns true if the HTTP response contains a bearer challenge
|
||||
func hasBearerChallenge(resp *http.Response) bool {
|
||||
authHeader := resp.Header.Get(bearerChallengeHeader)
|
||||
if len(authHeader) == 0 || strings.Index(authHeader, bearer) < 0 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
type bearerChallenge struct {
|
||||
values map[string]string
|
||||
}
|
||||
|
||||
func newBearerChallenge(resp *http.Response) (bc bearerChallenge, err error) {
|
||||
challenge := strings.TrimSpace(resp.Header.Get(bearerChallengeHeader))
|
||||
trimmedChallenge := challenge[len(bearer)+1:]
|
||||
|
||||
// challenge is a set of key=value pairs that are comma delimited
|
||||
pairs := strings.Split(trimmedChallenge, ",")
|
||||
if len(pairs) < 1 {
|
||||
err = fmt.Errorf("challenge '%s' contains no pairs", challenge)
|
||||
return bc, err
|
||||
}
|
||||
|
||||
bc.values = make(map[string]string)
|
||||
for i := range pairs {
|
||||
trimmedPair := strings.TrimSpace(pairs[i])
|
||||
pair := strings.Split(trimmedPair, "=")
|
||||
if len(pair) == 2 {
|
||||
// remove the enclosing quotes
|
||||
key := strings.Trim(pair[0], "\"")
|
||||
value := strings.Trim(pair[1], "\"")
|
||||
|
||||
switch key {
|
||||
case "authorization", "authorization_uri":
|
||||
// strip the tenant ID from the authorization URL
|
||||
asURL, err := url.Parse(value)
|
||||
if err != nil {
|
||||
return bc, err
|
||||
}
|
||||
bc.values[tenantID] = asURL.Path[1:]
|
||||
default:
|
||||
bc.values[key] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bc, err
|
||||
}
|
8
vendor/github.com/Azure/go-autorest/autorest/azure/async.go
generated
vendored
8
vendor/github.com/Azure/go-autorest/autorest/azure/async.go
generated
vendored
|
@ -17,12 +17,6 @@ const (
|
|||
)
|
||||
|
||||
const (
|
||||
methodDelete = "DELETE"
|
||||
methodPatch = "PATCH"
|
||||
methodPost = "POST"
|
||||
methodPut = "PUT"
|
||||
methodGet = "GET"
|
||||
|
||||
operationInProgress string = "InProgress"
|
||||
operationCanceled string = "Canceled"
|
||||
operationFailed string = "Failed"
|
||||
|
@ -226,7 +220,7 @@ func updatePollingState(resp *http.Response, ps *pollingState) error {
|
|||
// Lastly, requests against an existing resource, use the last request URI
|
||||
if ps.uri == "" {
|
||||
m := strings.ToUpper(req.Method)
|
||||
if m == methodPatch || m == methodPut || m == methodGet {
|
||||
if m == http.MethodPatch || m == http.MethodPut || m == http.MethodGet {
|
||||
ps.uri = req.URL.String()
|
||||
}
|
||||
}
|
||||
|
|
13
vendor/github.com/Azure/go-autorest/autorest/azure/config.go
generated
vendored
13
vendor/github.com/Azure/go-autorest/autorest/azure/config.go
generated
vendored
|
@ -1,13 +0,0 @@
|
|||
package azure
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// OAuthConfig represents the endpoints needed
|
||||
// in OAuth operations
|
||||
type OAuthConfig struct {
|
||||
AuthorizeEndpoint url.URL
|
||||
TokenEndpoint url.URL
|
||||
DeviceCodeEndpoint url.URL
|
||||
}
|
37
vendor/github.com/Azure/go-autorest/autorest/azure/environments.go
generated
vendored
37
vendor/github.com/Azure/go-autorest/autorest/azure/environments.go
generated
vendored
|
@ -2,14 +2,9 @@ package azure
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
activeDirectoryAPIVersion = "1.0"
|
||||
)
|
||||
|
||||
var environments = map[string]Environment{
|
||||
"AZURECHINACLOUD": ChinaCloud,
|
||||
"AZUREGERMANCLOUD": GermanCloud,
|
||||
|
@ -133,35 +128,3 @@ func EnvironmentFromName(name string) (Environment, error) {
|
|||
}
|
||||
return env, nil
|
||||
}
|
||||
|
||||
// OAuthConfigForTenant returns an OAuthConfig with tenant specific urls
|
||||
func (env Environment) OAuthConfigForTenant(tenantID string) (*OAuthConfig, error) {
|
||||
return OAuthConfigForTenant(env.ActiveDirectoryEndpoint, tenantID)
|
||||
}
|
||||
|
||||
// OAuthConfigForTenant returns an OAuthConfig with tenant specific urls for target cloud auth endpoint
|
||||
func OAuthConfigForTenant(activeDirectoryEndpoint, tenantID string) (*OAuthConfig, error) {
|
||||
template := "%s/oauth2/%s?api-version=%s"
|
||||
u, err := url.Parse(activeDirectoryEndpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
authorizeURL, err := u.Parse(fmt.Sprintf(template, tenantID, "authorize", activeDirectoryAPIVersion))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tokenURL, err := u.Parse(fmt.Sprintf(template, tenantID, "token", activeDirectoryAPIVersion))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
deviceCodeURL, err := u.Parse(fmt.Sprintf(template, tenantID, "devicecode", activeDirectoryAPIVersion))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &OAuthConfig{
|
||||
AuthorizeEndpoint: *authorizeURL,
|
||||
TokenEndpoint: *tokenURL,
|
||||
DeviceCodeEndpoint: *deviceCodeURL,
|
||||
}, nil
|
||||
}
|
||||
|
|
1
vendor/github.com/Azure/go-autorest/autorest/client.go
generated
vendored
1
vendor/github.com/Azure/go-autorest/autorest/client.go
generated
vendored
|
@ -35,6 +35,7 @@ var (
|
|||
|
||||
statusCodesForRetry = []int{
|
||||
http.StatusRequestTimeout, // 408
|
||||
http.StatusTooManyRequests, // 429
|
||||
http.StatusInternalServerError, // 500
|
||||
http.StatusBadGateway, // 502
|
||||
http.StatusServiceUnavailable, // 503
|
||||
|
|
109
vendor/github.com/Azure/go-autorest/autorest/date/unixtime.go
generated
vendored
Normal file
109
vendor/github.com/Azure/go-autorest/autorest/date/unixtime.go
generated
vendored
Normal file
|
@ -0,0 +1,109 @@
|
|||
package date
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"time"
|
||||
)
|
||||
|
||||
// unixEpoch is the moment in time that should be treated as timestamp 0.
|
||||
var unixEpoch = time.Date(1970, time.January, 1, 0, 0, 0, 0, time.UTC)
|
||||
|
||||
// UnixTime marshals and unmarshals a time that is represented as the number
|
||||
// of seconds (ignoring skip-seconds) since the Unix Epoch.
|
||||
type UnixTime time.Time
|
||||
|
||||
// Duration returns the time as a Duration since the UnixEpoch.
|
||||
func (t UnixTime) Duration() time.Duration {
|
||||
return time.Time(t).Sub(unixEpoch)
|
||||
}
|
||||
|
||||
// NewUnixTimeFromSeconds creates a UnixTime as a number of seconds from the UnixEpoch.
|
||||
func NewUnixTimeFromSeconds(seconds float64) UnixTime {
|
||||
return NewUnixTimeFromDuration(time.Duration(seconds * float64(time.Second)))
|
||||
}
|
||||
|
||||
// NewUnixTimeFromNanoseconds creates a UnixTime as a number of nanoseconds from the UnixEpoch.
|
||||
func NewUnixTimeFromNanoseconds(nanoseconds int64) UnixTime {
|
||||
return NewUnixTimeFromDuration(time.Duration(nanoseconds))
|
||||
}
|
||||
|
||||
// NewUnixTimeFromDuration creates a UnixTime as a duration of time since the UnixEpoch.
|
||||
func NewUnixTimeFromDuration(dur time.Duration) UnixTime {
|
||||
return UnixTime(unixEpoch.Add(dur))
|
||||
}
|
||||
|
||||
// UnixEpoch retreives the moment considered the Unix Epoch. I.e. The time represented by '0'
|
||||
func UnixEpoch() time.Time {
|
||||
return unixEpoch
|
||||
}
|
||||
|
||||
// MarshalJSON preserves the UnixTime as a JSON number conforming to Unix Timestamp requirements.
|
||||
// (i.e. the number of seconds since midnight January 1st, 1970 not considering leap seconds.)
|
||||
func (t UnixTime) MarshalJSON() ([]byte, error) {
|
||||
buffer := &bytes.Buffer{}
|
||||
enc := json.NewEncoder(buffer)
|
||||
err := enc.Encode(float64(time.Time(t).UnixNano()) / 1e9)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buffer.Bytes(), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON reconstitures a UnixTime saved as a JSON number of the number of seconds since
|
||||
// midnight January 1st, 1970.
|
||||
func (t *UnixTime) UnmarshalJSON(text []byte) error {
|
||||
dec := json.NewDecoder(bytes.NewReader(text))
|
||||
|
||||
var secondsSinceEpoch float64
|
||||
if err := dec.Decode(&secondsSinceEpoch); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*t = NewUnixTimeFromSeconds(secondsSinceEpoch)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalText stores the number of seconds since the Unix Epoch as a textual floating point number.
|
||||
func (t UnixTime) MarshalText() ([]byte, error) {
|
||||
cast := time.Time(t)
|
||||
return cast.MarshalText()
|
||||
}
|
||||
|
||||
// UnmarshalText populates a UnixTime with a value stored textually as a floating point number of seconds since the Unix Epoch.
|
||||
func (t *UnixTime) UnmarshalText(raw []byte) error {
|
||||
var unmarshaled time.Time
|
||||
|
||||
if err := unmarshaled.UnmarshalText(raw); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*t = UnixTime(unmarshaled)
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary converts a UnixTime into a binary.LittleEndian float64 of nanoseconds since the epoch.
|
||||
func (t UnixTime) MarshalBinary() ([]byte, error) {
|
||||
buf := &bytes.Buffer{}
|
||||
|
||||
payload := int64(t.Duration())
|
||||
|
||||
if err := binary.Write(buf, binary.LittleEndian, &payload); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
// UnmarshalBinary converts a from a binary.LittleEndian float64 of nanoseconds since the epoch into a UnixTime.
|
||||
func (t *UnixTime) UnmarshalBinary(raw []byte) error {
|
||||
var nanosecondsSinceEpoch int64
|
||||
|
||||
if err := binary.Read(bytes.NewReader(raw), binary.LittleEndian, &nanosecondsSinceEpoch); err != nil {
|
||||
return err
|
||||
}
|
||||
*t = NewUnixTimeFromNanoseconds(nanosecondsSinceEpoch)
|
||||
return nil
|
||||
}
|
4
vendor/github.com/Azure/go-autorest/autorest/error.go
generated
vendored
4
vendor/github.com/Azure/go-autorest/autorest/error.go
generated
vendored
|
@ -31,6 +31,9 @@ type DetailedError struct {
|
|||
|
||||
// Service Error is the response body of failed API in bytes
|
||||
ServiceError []byte
|
||||
|
||||
// Response is the response object that was returned during failure if applicable.
|
||||
Response *http.Response
|
||||
}
|
||||
|
||||
// NewError creates a new Error conforming object from the passed packageType, method, and
|
||||
|
@ -67,6 +70,7 @@ func NewErrorWithError(original error, packageType string, method string, resp *
|
|||
Method: method,
|
||||
StatusCode: statusCode,
|
||||
Message: fmt.Sprintf(message, args...),
|
||||
Response: resp,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
15
vendor/github.com/Azure/go-autorest/autorest/preparer.go
generated
vendored
15
vendor/github.com/Azure/go-autorest/autorest/preparer.go
generated
vendored
|
@ -426,18 +426,3 @@ func WithQueryParameters(queryParameters map[string]interface{}) PrepareDecorato
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Authorizer is the interface that provides a PrepareDecorator used to supply request
|
||||
// authorization. Most often, the Authorizer decorator runs last so it has access to the full
|
||||
// state of the formed HTTP request.
|
||||
type Authorizer interface {
|
||||
WithAuthorization() PrepareDecorator
|
||||
}
|
||||
|
||||
// NullAuthorizer implements a default, "do nothing" Authorizer.
|
||||
type NullAuthorizer struct{}
|
||||
|
||||
// WithAuthorization returns a PrepareDecorator that does nothing.
|
||||
func (na NullAuthorizer) WithAuthorization() PrepareDecorator {
|
||||
return WithNothing()
|
||||
}
|
||||
|
|
38
vendor/github.com/Azure/go-autorest/autorest/retriablerequest.go
generated
vendored
Normal file
38
vendor/github.com/Azure/go-autorest/autorest/retriablerequest.go
generated
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
package autorest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// NewRetriableRequest returns a wrapper around an HTTP request that support retry logic.
|
||||
func NewRetriableRequest(req *http.Request) *RetriableRequest {
|
||||
return &RetriableRequest{req: req}
|
||||
}
|
||||
|
||||
// Request returns the wrapped HTTP request.
|
||||
func (rr *RetriableRequest) Request() *http.Request {
|
||||
return rr.req
|
||||
}
|
||||
|
||||
func (rr *RetriableRequest) prepareFromByteReader() (err error) {
|
||||
// fall back to making a copy (only do this once)
|
||||
b := []byte{}
|
||||
if rr.req.ContentLength > 0 {
|
||||
b = make([]byte, rr.req.ContentLength)
|
||||
_, err = io.ReadFull(rr.req.Body, b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
b, err = ioutil.ReadAll(rr.req.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
rr.br = bytes.NewReader(b)
|
||||
rr.req.Body = ioutil.NopCloser(rr.br)
|
||||
return err
|
||||
}
|
44
vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.7.go
generated
vendored
Normal file
44
vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.7.go
generated
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
// +build !go1.8
|
||||
|
||||
package autorest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// RetriableRequest provides facilities for retrying an HTTP request.
|
||||
type RetriableRequest struct {
|
||||
req *http.Request
|
||||
br *bytes.Reader
|
||||
reset bool
|
||||
}
|
||||
|
||||
// Prepare signals that the request is about to be sent.
|
||||
func (rr *RetriableRequest) Prepare() (err error) {
|
||||
// preserve the request body; this is to support retry logic as
|
||||
// the underlying transport will always close the reqeust body
|
||||
if rr.req.Body != nil {
|
||||
if rr.reset {
|
||||
if rr.br != nil {
|
||||
_, err = rr.br.Seek(0, 0 /*io.SeekStart*/)
|
||||
}
|
||||
rr.reset = false
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if rr.br == nil {
|
||||
// fall back to making a copy (only do this once)
|
||||
err = rr.prepareFromByteReader()
|
||||
}
|
||||
// indicates that the request body needs to be reset
|
||||
rr.reset = true
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func removeRequestBody(req *http.Request) {
|
||||
req.Body = nil
|
||||
req.ContentLength = 0
|
||||
}
|
56
vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.8.go
generated
vendored
Normal file
56
vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.8.go
generated
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
// +build go1.8
|
||||
|
||||
package autorest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// RetriableRequest provides facilities for retrying an HTTP request.
|
||||
type RetriableRequest struct {
|
||||
req *http.Request
|
||||
rc io.ReadCloser
|
||||
br *bytes.Reader
|
||||
reset bool
|
||||
}
|
||||
|
||||
// Prepare signals that the request is about to be sent.
|
||||
func (rr *RetriableRequest) Prepare() (err error) {
|
||||
// preserve the request body; this is to support retry logic as
|
||||
// the underlying transport will always close the reqeust body
|
||||
if rr.req.Body != nil {
|
||||
if rr.reset {
|
||||
if rr.rc != nil {
|
||||
rr.req.Body = rr.rc
|
||||
} else if rr.br != nil {
|
||||
_, err = rr.br.Seek(0, io.SeekStart)
|
||||
}
|
||||
rr.reset = false
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if rr.req.GetBody != nil {
|
||||
// this will allow us to preserve the body without having to
|
||||
// make a copy. note we need to do this on each iteration
|
||||
rr.rc, err = rr.req.GetBody()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else if rr.br == nil {
|
||||
// fall back to making a copy (only do this once)
|
||||
err = rr.prepareFromByteReader()
|
||||
}
|
||||
// indicates that the request body needs to be reset
|
||||
rr.reset = true
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func removeRequestBody(req *http.Request) {
|
||||
req.Body = nil
|
||||
req.GetBody = nil
|
||||
req.ContentLength = 0
|
||||
}
|
53
vendor/github.com/Azure/go-autorest/autorest/sender.go
generated
vendored
53
vendor/github.com/Azure/go-autorest/autorest/sender.go
generated
vendored
|
@ -1,12 +1,11 @@
|
|||
package autorest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -175,8 +174,13 @@ func DoPollForStatusCodes(duration time.Duration, delay time.Duration, codes ...
|
|||
func DoRetryForAttempts(attempts int, backoff time.Duration) SendDecorator {
|
||||
return func(s Sender) Sender {
|
||||
return SenderFunc(func(r *http.Request) (resp *http.Response, err error) {
|
||||
rr := NewRetriableRequest(r)
|
||||
for attempt := 0; attempt < attempts; attempt++ {
|
||||
resp, err = s.Do(r)
|
||||
err = rr.Prepare()
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
resp, err = s.Do(rr.Request())
|
||||
if err == nil {
|
||||
return resp, err
|
||||
}
|
||||
|
@ -194,29 +198,43 @@ func DoRetryForAttempts(attempts int, backoff time.Duration) SendDecorator {
|
|||
func DoRetryForStatusCodes(attempts int, backoff time.Duration, codes ...int) SendDecorator {
|
||||
return func(s Sender) Sender {
|
||||
return SenderFunc(func(r *http.Request) (resp *http.Response, err error) {
|
||||
b := []byte{}
|
||||
if r.Body != nil {
|
||||
b, err = ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
}
|
||||
|
||||
rr := NewRetriableRequest(r)
|
||||
// Increment to add the first call (attempts denotes number of retries)
|
||||
attempts++
|
||||
for attempt := 0; attempt < attempts; attempt++ {
|
||||
r.Body = ioutil.NopCloser(bytes.NewBuffer(b))
|
||||
resp, err = s.Do(r)
|
||||
err = rr.Prepare()
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
resp, err = s.Do(rr.Request())
|
||||
if err != nil || !ResponseHasStatusCode(resp, codes...) {
|
||||
return resp, err
|
||||
}
|
||||
DelayForBackoff(backoff, attempt, r.Cancel)
|
||||
delayed := DelayWithRetryAfter(resp, r.Cancel)
|
||||
if !delayed {
|
||||
DelayForBackoff(backoff, attempt, r.Cancel)
|
||||
}
|
||||
}
|
||||
return resp, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// DelayWithRetryAfter invokes time.After for the duration specified in the "Retry-After" header in
|
||||
// responses with status code 429
|
||||
func DelayWithRetryAfter(resp *http.Response, cancel <-chan struct{}) bool {
|
||||
retryAfter, _ := strconv.Atoi(resp.Header.Get("Retry-After"))
|
||||
if resp.StatusCode == http.StatusTooManyRequests && retryAfter > 0 {
|
||||
select {
|
||||
case <-time.After(time.Duration(retryAfter) * time.Second):
|
||||
return true
|
||||
case <-cancel:
|
||||
return false
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// DoRetryForDuration returns a SendDecorator that retries the request until the total time is equal
|
||||
// to or greater than the specified duration, exponentially backing off between requests using the
|
||||
// supplied backoff time.Duration (which may be zero). Retrying may be canceled by closing the
|
||||
|
@ -224,9 +242,14 @@ func DoRetryForStatusCodes(attempts int, backoff time.Duration, codes ...int) Se
|
|||
func DoRetryForDuration(d time.Duration, backoff time.Duration) SendDecorator {
|
||||
return func(s Sender) Sender {
|
||||
return SenderFunc(func(r *http.Request) (resp *http.Response, err error) {
|
||||
rr := NewRetriableRequest(r)
|
||||
end := time.Now().Add(d)
|
||||
for attempt := 0; time.Now().Before(end); attempt++ {
|
||||
resp, err = s.Do(r)
|
||||
err = rr.Prepare()
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
resp, err = s.Do(rr.Request())
|
||||
if err == nil {
|
||||
return resp, err
|
||||
}
|
||||
|
|
24
vendor/github.com/Azure/go-autorest/autorest/version.go
generated
vendored
24
vendor/github.com/Azure/go-autorest/autorest/version.go
generated
vendored
|
@ -1,29 +1,35 @@
|
|||
package autorest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const (
|
||||
major = 7
|
||||
minor = 3
|
||||
patch = 1
|
||||
major = 8
|
||||
minor = 0
|
||||
patch = 0
|
||||
tag = ""
|
||||
)
|
||||
|
||||
var versionLock sync.Once
|
||||
var once sync.Once
|
||||
var version string
|
||||
|
||||
// Version returns the semantic version (see http://semver.org).
|
||||
func Version() string {
|
||||
versionLock.Do(func() {
|
||||
version = fmt.Sprintf("v%d.%d.%d", major, minor, patch)
|
||||
|
||||
if trimmed := strings.TrimPrefix(tag, "-"); trimmed != "" {
|
||||
version = fmt.Sprintf("%s-%s", version, trimmed)
|
||||
once.Do(func() {
|
||||
semver := fmt.Sprintf("%d.%d.%d", major, minor, patch)
|
||||
verBuilder := bytes.NewBufferString(semver)
|
||||
if tag != "" && tag != "-" {
|
||||
updated := strings.TrimPrefix(tag, "-")
|
||||
_, err := verBuilder.WriteString("-" + updated)
|
||||
if err == nil {
|
||||
verBuilder = bytes.NewBufferString(semver)
|
||||
}
|
||||
}
|
||||
version = verBuilder.String()
|
||||
})
|
||||
return version
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue